diff mbox series

mac80211: enable QoS support for nl80211 ctrl port

Message ID 20201209225214.127548-1-markus.theil@tu-ilmenau.de (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series mac80211: enable QoS support for nl80211 ctrl port | expand

Commit Message

Markus Theil Dec. 9, 2020, 10:52 p.m. UTC
This patch unifies sending control port frames
over nl80211 and AF_PACKET sockets a little more.

Before this patch, EAPOL frames got QoS prioritization
only when using AF_PACKET sockets.

__ieee80211_select_queue only selects a QoS-enabled queue
for control port frames, when the control port protocol
is set correctly on the skb. For the AF_PACKET path this
works, but the nl80211 path used ETH_P_802_3.

Another check for injected frames in wme.c then prevented
the QoS TID to be copied in the frame.

In order to fix this, get rid of the frame injection marking
for nl80211 ctrl port and set the correct ethernet protocol.

Furthermore, this patch also checks and prevents frame
aggregation for control port frames in order to speed up
the initial connection setup a little.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 net/mac80211/status.c |  8 ++------
 net/mac80211/tx.c     | 15 +++++++--------
 2 files changed, 9 insertions(+), 14 deletions(-)

Comments

Dan Carpenter Dec. 10, 2020, 11:04 a.m. UTC | #1
Hi Markus,

url:    https://github.com/0day-ci/linux/commits/Markus-Theil/mac80211-enable-QoS-support-for-nl80211-ctrl-port/20201210-065717 
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git  master
config: x86_64-randconfig-s021-20201210 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-179-ga00755aa-dirty
        # https://github.com/0day-ci/linux/commit/514b314825e19f7075eb375b3effa93ff0f6a16e 
        git remote add linux-review https://github.com/0day-ci/linux 
        git fetch --no-tags linux-review Markus-Theil/mac80211-enable-QoS-support-for-nl80211-ctrl-port/20201210-065717
        git checkout 514b314825e19f7075eb375b3effa93ff0f6a16e
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

"sparse warnings: (new ones prefixed by >>)"
>> net/mac80211/tx.c:1206:26: sparse: sparse: dubious: !x & y

vim +1206 net/mac80211/tx.c

9ae54c8463691b Johannes Berg    2008-01-31  1162  static ieee80211_tx_result
3b8d81e020f77c Johannes Berg    2009-06-17  1163  ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
3b8d81e020f77c Johannes Berg    2009-06-17  1164  		     struct ieee80211_tx_data *tx,
7c10770f995820 Johannes Berg    2015-03-20  1165  		     struct sta_info *sta, struct sk_buff *skb)
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1166  {
3b8d81e020f77c Johannes Berg    2009-06-17  1167  	struct ieee80211_local *local = sdata->local;
58d4185e36913d Johannes Berg    2007-09-26  1168  	struct ieee80211_hdr *hdr;
e039fa4a4195ac Johannes Berg    2008-05-15  1169  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
68f2b517bcbd81 Johannes Berg    2011-10-07  1170  	int tid;
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1171  
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1172  	memset(tx, 0, sizeof(*tx));
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1173  	tx->skb = skb;
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1174  	tx->local = local;
3b8d81e020f77c Johannes Berg    2009-06-17  1175  	tx->sdata = sdata;
252b86c43225d0 Johannes Berg    2011-11-16  1176  	__skb_queue_head_init(&tx->skbs);
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1177  
cd8ffc800ce18e Johannes Berg    2009-03-23  1178  	/*
cd8ffc800ce18e Johannes Berg    2009-03-23  1179  	 * If this flag is set to true anywhere, and we get here,
cd8ffc800ce18e Johannes Berg    2009-03-23  1180  	 * we are doing the needed processing, so remove the flag
cd8ffc800ce18e Johannes Berg    2009-03-23  1181  	 * now.
cd8ffc800ce18e Johannes Berg    2009-03-23  1182  	 */
cc20ff2c6b5d3e Felix Fietkau    2020-09-08  1183  	info->control.flags &= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
cd8ffc800ce18e Johannes Berg    2009-03-23  1184  
58d4185e36913d Johannes Berg    2007-09-26  1185  	hdr = (struct ieee80211_hdr *) skb->data;
58d4185e36913d Johannes Berg    2007-09-26  1186  
7c10770f995820 Johannes Berg    2015-03-20  1187  	if (likely(sta)) {
7c10770f995820 Johannes Berg    2015-03-20  1188  		if (!IS_ERR(sta))
7c10770f995820 Johannes Berg    2015-03-20  1189  			tx->sta = sta;
7c10770f995820 Johannes Berg    2015-03-20  1190  	} else {
3f0e0b220f8007 Felix Fietkau    2010-01-08  1191  		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
f14543ee4d0681 Felix Fietkau    2009-11-10  1192  			tx->sta = rcu_dereference(sdata->u.vlan.sta);
7c10770f995820 Johannes Berg    2015-03-20  1193  			if (!tx->sta && sdata->wdev.use_4addr)
3f0e0b220f8007 Felix Fietkau    2010-01-08  1194  				return TX_DROP;
514b314825e19f Markus Theil     2020-12-09  1195  		} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
b4d57adb727ec7 Felix Fietkau    2010-01-31  1196  			tx->sta = sta_info_get_bss(sdata, hdr->addr1);
3f0e0b220f8007 Felix Fietkau    2010-01-08  1197  		}
9d6b106b54e02a Johannes Berg    2015-02-24  1198  		if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
abe60632f311d5 Johannes Berg    2009-11-25  1199  			tx->sta = sta_info_get(sdata, hdr->addr1);
7c10770f995820 Johannes Berg    2015-03-20  1200  	}
58d4185e36913d Johannes Berg    2007-09-26  1201  
cd8ffc800ce18e Johannes Berg    2009-03-23  1202  	if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
49a59543eb5a5d Johannes Berg    2011-09-29  1203  	    !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
30686bf7f5b3c3 Johannes Berg    2015-06-02  1204  	    ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
514b314825e19f Markus Theil     2020-12-09  1205  	    !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW) &&
514b314825e19f Markus Theil     2020-12-09 @1206  	    !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {

! has higher precedence than & so this is equivalent of
"if (!info->flags) {"  Presumably, it should be:

		!(info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) {

cd8ffc800ce18e Johannes Berg    2009-03-23  1207  		struct tid_ampdu_tx *tid_tx;
cd8ffc800ce18e Johannes Berg    2009-03-23  1208  
a1f2ba04cc9241 Sara Sharon      2018-02-19  1209  		tid = ieee80211_get_tid(hdr);
8b30b1fe368ab0 Sujith           2008-10-24  1210  
a622ab72b4dcfd Johannes Berg    2010-06-10  1211  		tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
a622ab72b4dcfd Johannes Berg    2010-06-10  1212  		if (tid_tx) {
a622ab72b4dcfd Johannes Berg    2010-06-10  1213  			bool queued;
a622ab72b4dcfd Johannes Berg    2010-06-10  1214  
a622ab72b4dcfd Johannes Berg    2010-06-10  1215  			queued = ieee80211_tx_prep_agg(tx, skb, info,
a622ab72b4dcfd Johannes Berg    2010-06-10  1216  						       tid_tx, tid);
cd8ffc800ce18e Johannes Berg    2009-03-23  1217  
cd8ffc800ce18e Johannes Berg    2009-03-23  1218  			if (unlikely(queued))
cd8ffc800ce18e Johannes Berg    2009-03-23  1219  				return TX_QUEUED;
8b30b1fe368ab0 Sujith           2008-10-24  1220  		}
a622ab72b4dcfd Johannes Berg    2010-06-10  1221  	}
8b30b1fe368ab0 Sujith           2008-10-24  1222  
badffb725c86cc Jiri Slaby       2007-08-28  1223  	if (is_multicast_ether_addr(hdr->addr1)) {
5cf121c3cdb955 Johannes Berg    2008-02-25  1224  		tx->flags &= ~IEEE80211_TX_UNICAST;
e039fa4a4195ac Johannes Berg    2008-05-15  1225  		info->flags |= IEEE80211_TX_CTL_NO_ACK;
6fd67e937ece53 Simon Wunderlich 2011-11-18  1226  	} else
5cf121c3cdb955 Johannes Berg    2008-02-25  1227  		tx->flags |= IEEE80211_TX_UNICAST;
58d4185e36913d Johannes Berg    2007-09-26  1228  
a26eb27ab43014 Johannes Berg    2011-10-07  1229  	if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) {
a26eb27ab43014 Johannes Berg    2011-10-07  1230  		if (!(tx->flags & IEEE80211_TX_UNICAST) ||
a26eb27ab43014 Johannes Berg    2011-10-07  1231  		    skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold ||
a26eb27ab43014 Johannes Berg    2011-10-07  1232  		    info->flags & IEEE80211_TX_CTL_AMPDU)
a26eb27ab43014 Johannes Berg    2011-10-07  1233  			info->flags |= IEEE80211_TX_CTL_DONTFRAG;
58d4185e36913d Johannes Berg    2007-09-26  1234  	}
58d4185e36913d Johannes Berg    2007-09-26  1235  
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1236  	if (!tx->sta)
e039fa4a4195ac Johannes Berg    2008-05-15  1237  		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
f7418bc10d8402 Felix Fietkau    2015-09-24  1238  	else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
e039fa4a4195ac Johannes Berg    2008-05-15  1239  		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
f7418bc10d8402 Felix Fietkau    2015-09-24  1240  		ieee80211_check_fast_xmit(tx->sta);
f7418bc10d8402 Felix Fietkau    2015-09-24  1241  	}
58d4185e36913d Johannes Berg    2007-09-26  1242  
e039fa4a4195ac Johannes Berg    2008-05-15  1243  	info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1244  
9ae54c8463691b Johannes Berg    2008-01-31  1245  	return TX_CONTINUE;
e2ebc74d7e3d71 Johannes Berg    2007-07-27  1246  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Johannes Berg Dec. 10, 2020, 1:59 p.m. UTC | #2
On Wed, 2020-12-09 at 23:52 +0100, Markus Theil wrote:
> 
> Furthermore, this patch also checks and prevents frame
> aggregation for control port frames in order to speed up
> the initial connection setup a little.
> 

That might make sense, but I really think it should be a separate patch.

Thanks,
johannes
kernel test robot Dec. 11, 2020, 3 a.m. UTC | #3
Hi Markus,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mac80211-next/master]
[also build test WARNING on mac80211/master v5.10-rc7 next-20201210]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Markus-Theil/mac80211-enable-QoS-support-for-nl80211-ctrl-port/20201210-065717
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
config: riscv-randconfig-r003-20201210 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 1968804ac726e7674d5de22bc2204b45857da344)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/514b314825e19f7075eb375b3effa93ff0f6a16e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Markus-Theil/mac80211-enable-QoS-support-for-nl80211-ctrl-port/20201210-065717
        git checkout 514b314825e19f7075eb375b3effa93ff0f6a16e
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:556:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return inb(addr);
                  ^~~~~~~~~
   arch/riscv/include/asm/io.h:55:76: note: expanded from macro 'inb'
   #define inb(c)          ({ u8  __v; __io_pbr(); __v = readb_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; })
                                                                           ~~~~~~~~~~ ^
   arch/riscv/include/asm/mmio.h:87:48: note: expanded from macro 'readb_cpu'
   #define readb_cpu(c)            ({ u8  __r = __raw_readb(c); __r; })
                                                            ^
   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:564:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return inw(addr);
                  ^~~~~~~~~
   arch/riscv/include/asm/io.h:56:76: note: expanded from macro 'inw'
   #define inw(c)          ({ u16 __v; __io_pbr(); __v = readw_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; })
                                                                           ~~~~~~~~~~ ^
   arch/riscv/include/asm/mmio.h:88:76: note: expanded from macro 'readw_cpu'
   #define readw_cpu(c)            ({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
                                                                                        ^
   include/uapi/linux/byteorder/little_endian.h:36:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:572:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return inl(addr);
                  ^~~~~~~~~
   arch/riscv/include/asm/io.h:57:76: note: expanded from macro 'inl'
   #define inl(c)          ({ u32 __v; __io_pbr(); __v = readl_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; })
                                                                           ~~~~~~~~~~ ^
   arch/riscv/include/asm/mmio.h:89:76: note: expanded from macro 'readl_cpu'
   #define readl_cpu(c)            ({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
                                                                                        ^
   include/uapi/linux/byteorder/little_endian.h:34:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:580:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           outb(value, addr);
           ^~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:59:68: note: expanded from macro 'outb'
   #define outb(v,c)       ({ __io_pbw(); writeb_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); })
                                                                 ~~~~~~~~~~ ^
   arch/riscv/include/asm/mmio.h:91:52: note: expanded from macro 'writeb_cpu'
   #define writeb_cpu(v, c)        ((void)__raw_writeb((v), (c)))
                                                             ^
   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:588:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           outw(value, addr);
           ^~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:60:68: note: expanded from macro 'outw'
   #define outw(v,c)       ({ __io_pbw(); writew_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); })
                                                                 ~~~~~~~~~~ ^
   arch/riscv/include/asm/mmio.h:92:76: note: expanded from macro 'writew_cpu'
   #define writew_cpu(v, c)        ((void)__raw_writew((__force u16)cpu_to_le16(v), (c)))
                                                                                     ^
   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:596:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           outl(value, addr);
           ^~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:61:68: note: expanded from macro 'outl'
   #define outl(v,c)       ({ __io_pbw(); writel_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); })
                                                                 ~~~~~~~~~~ ^
   arch/riscv/include/asm/mmio.h:93:76: note: expanded from macro 'writel_cpu'
   #define writel_cpu(v, c)        ((void)__raw_writel((__force u32)cpu_to_le32(v), (c)))
                                                                                     ^
   In file included from net/mac80211/tx.c:15:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:149:
   include/asm-generic/io.h:1005:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
                                                     ~~~~~~~~~~ ^
>> net/mac80211/tx.c:1206:6: warning: logical not is only applied to the left hand side of this bitwise operator [-Wlogical-not-parentheses]
               !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
               ^            ~
   net/mac80211/tx.c:1206:6: note: add parentheses after the '!' to evaluate the bitwise operator first
               !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
               ^
                (                                              )
   net/mac80211/tx.c:1206:6: note: add parentheses around left hand side expression to silence this warning
               !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
               ^
               (           )
   8 warnings generated.
   /tmp/tx-d90b1d.s: Assembler messages:
   /tmp/tx-d90b1d.s:1816: Error: unrecognized opcode `zext.b a1,s11'
   /tmp/tx-d90b1d.s:1847: Error: unrecognized opcode `zext.b a3,a3'
   /tmp/tx-d90b1d.s:2975: Error: unrecognized opcode `zext.b a1,s5'
   /tmp/tx-d90b1d.s:3936: Error: unrecognized opcode `zext.b a2,a0'
   /tmp/tx-d90b1d.s:4278: Error: unrecognized opcode `zext.b a0,a0'
   /tmp/tx-d90b1d.s:4557: Error: unrecognized opcode `zext.b a1,a1'
   /tmp/tx-d90b1d.s:5316: Error: unrecognized opcode `zext.b a0,a0'
   /tmp/tx-d90b1d.s:9203: Error: unrecognized opcode `zext.b a0,s1'
   /tmp/tx-d90b1d.s:9251: Error: unrecognized opcode `zext.b a0,s1'
   /tmp/tx-d90b1d.s:9912: Error: unrecognized opcode `zext.b a1,a0'
   /tmp/tx-d90b1d.s:9985: Error: unrecognized opcode `zext.b a1,a0'
   clang-12: error: assembler command failed with exit code 1 (use -v to see invocation)

vim +1206 net/mac80211/tx.c

  1156	
  1157	/*
  1158	 * initialises @tx
  1159	 * pass %NULL for the station if unknown, a valid pointer if known
  1160	 * or an ERR_PTR() if the station is known not to exist
  1161	 */
  1162	static ieee80211_tx_result
  1163	ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
  1164			     struct ieee80211_tx_data *tx,
  1165			     struct sta_info *sta, struct sk_buff *skb)
  1166	{
  1167		struct ieee80211_local *local = sdata->local;
  1168		struct ieee80211_hdr *hdr;
  1169		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  1170		int tid;
  1171	
  1172		memset(tx, 0, sizeof(*tx));
  1173		tx->skb = skb;
  1174		tx->local = local;
  1175		tx->sdata = sdata;
  1176		__skb_queue_head_init(&tx->skbs);
  1177	
  1178		/*
  1179		 * If this flag is set to true anywhere, and we get here,
  1180		 * we are doing the needed processing, so remove the flag
  1181		 * now.
  1182		 */
  1183		info->control.flags &= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
  1184	
  1185		hdr = (struct ieee80211_hdr *) skb->data;
  1186	
  1187		if (likely(sta)) {
  1188			if (!IS_ERR(sta))
  1189				tx->sta = sta;
  1190		} else {
  1191			if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
  1192				tx->sta = rcu_dereference(sdata->u.vlan.sta);
  1193				if (!tx->sta && sdata->wdev.use_4addr)
  1194					return TX_DROP;
  1195			} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
  1196				tx->sta = sta_info_get_bss(sdata, hdr->addr1);
  1197			}
  1198			if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
  1199				tx->sta = sta_info_get(sdata, hdr->addr1);
  1200		}
  1201	
  1202		if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
  1203		    !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
  1204		    ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
  1205		    !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW) &&
> 1206		    !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
  1207			struct tid_ampdu_tx *tid_tx;
  1208	
  1209			tid = ieee80211_get_tid(hdr);
  1210	
  1211			tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
  1212			if (tid_tx) {
  1213				bool queued;
  1214	
  1215				queued = ieee80211_tx_prep_agg(tx, skb, info,
  1216							       tid_tx, tid);
  1217	
  1218				if (unlikely(queued))
  1219					return TX_QUEUED;
  1220			}
  1221		}
  1222	
  1223		if (is_multicast_ether_addr(hdr->addr1)) {
  1224			tx->flags &= ~IEEE80211_TX_UNICAST;
  1225			info->flags |= IEEE80211_TX_CTL_NO_ACK;
  1226		} else
  1227			tx->flags |= IEEE80211_TX_UNICAST;
  1228	
  1229		if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) {
  1230			if (!(tx->flags & IEEE80211_TX_UNICAST) ||
  1231			    skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold ||
  1232			    info->flags & IEEE80211_TX_CTL_AMPDU)
  1233				info->flags |= IEEE80211_TX_CTL_DONTFRAG;
  1234		}
  1235	
  1236		if (!tx->sta)
  1237			info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
  1238		else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
  1239			info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
  1240			ieee80211_check_fast_xmit(tx->sta);
  1241		}
  1242	
  1243		info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
  1244	
  1245		return TX_CONTINUE;
  1246	}
  1247	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Markus Theil Dec. 12, 2020, 10:53 a.m. UTC | #4
On 10/12/2020 12:04, Dan Carpenter wrote:
> Hi Markus,
>
> url:    https://github.com/0day-ci/linux/commits/Markus-Theil/mac80211-enable-QoS-support-for-nl80211-ctrl-port/20201210-065717 
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git  master
> config: x86_64-randconfig-s021-20201210 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
> reproduce:
>         # apt-get install sparse
>         # sparse version: v0.6.3-179-ga00755aa-dirty
>         # https://github.com/0day-ci/linux/commit/514b314825e19f7075eb375b3effa93ff0f6a16e 
>         git remote add linux-review https://github.com/0day-ci/linux 
>         git fetch --no-tags linux-review Markus-Theil/mac80211-enable-QoS-support-for-nl80211-ctrl-port/20201210-065717
>         git checkout 514b314825e19f7075eb375b3effa93ff0f6a16e
>         # save the attached .config to linux build tree
>         make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> "sparse warnings: (new ones prefixed by >>)"
>>> net/mac80211/tx.c:1206:26: sparse: sparse: dubious: !x & y
> vim +1206 net/mac80211/tx.c
>
> 9ae54c8463691b Johannes Berg    2008-01-31  1162  static ieee80211_tx_result
> 3b8d81e020f77c Johannes Berg    2009-06-17  1163  ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
> 3b8d81e020f77c Johannes Berg    2009-06-17  1164  		     struct ieee80211_tx_data *tx,
> 7c10770f995820 Johannes Berg    2015-03-20  1165  		     struct sta_info *sta, struct sk_buff *skb)
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1166  {
> 3b8d81e020f77c Johannes Berg    2009-06-17  1167  	struct ieee80211_local *local = sdata->local;
> 58d4185e36913d Johannes Berg    2007-09-26  1168  	struct ieee80211_hdr *hdr;
> e039fa4a4195ac Johannes Berg    2008-05-15  1169  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
> 68f2b517bcbd81 Johannes Berg    2011-10-07  1170  	int tid;
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1171  
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1172  	memset(tx, 0, sizeof(*tx));
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1173  	tx->skb = skb;
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1174  	tx->local = local;
> 3b8d81e020f77c Johannes Berg    2009-06-17  1175  	tx->sdata = sdata;
> 252b86c43225d0 Johannes Berg    2011-11-16  1176  	__skb_queue_head_init(&tx->skbs);
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1177  
> cd8ffc800ce18e Johannes Berg    2009-03-23  1178  	/*
> cd8ffc800ce18e Johannes Berg    2009-03-23  1179  	 * If this flag is set to true anywhere, and we get here,
> cd8ffc800ce18e Johannes Berg    2009-03-23  1180  	 * we are doing the needed processing, so remove the flag
> cd8ffc800ce18e Johannes Berg    2009-03-23  1181  	 * now.
> cd8ffc800ce18e Johannes Berg    2009-03-23  1182  	 */
> cc20ff2c6b5d3e Felix Fietkau    2020-09-08  1183  	info->control.flags &= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
> cd8ffc800ce18e Johannes Berg    2009-03-23  1184  
> 58d4185e36913d Johannes Berg    2007-09-26  1185  	hdr = (struct ieee80211_hdr *) skb->data;
> 58d4185e36913d Johannes Berg    2007-09-26  1186  
> 7c10770f995820 Johannes Berg    2015-03-20  1187  	if (likely(sta)) {
> 7c10770f995820 Johannes Berg    2015-03-20  1188  		if (!IS_ERR(sta))
> 7c10770f995820 Johannes Berg    2015-03-20  1189  			tx->sta = sta;
> 7c10770f995820 Johannes Berg    2015-03-20  1190  	} else {
> 3f0e0b220f8007 Felix Fietkau    2010-01-08  1191  		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
> f14543ee4d0681 Felix Fietkau    2009-11-10  1192  			tx->sta = rcu_dereference(sdata->u.vlan.sta);
> 7c10770f995820 Johannes Berg    2015-03-20  1193  			if (!tx->sta && sdata->wdev.use_4addr)
> 3f0e0b220f8007 Felix Fietkau    2010-01-08  1194  				return TX_DROP;
> 514b314825e19f Markus Theil     2020-12-09  1195  		} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
> b4d57adb727ec7 Felix Fietkau    2010-01-31  1196  			tx->sta = sta_info_get_bss(sdata, hdr->addr1);
> 3f0e0b220f8007 Felix Fietkau    2010-01-08  1197  		}
> 9d6b106b54e02a Johannes Berg    2015-02-24  1198  		if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
> abe60632f311d5 Johannes Berg    2009-11-25  1199  			tx->sta = sta_info_get(sdata, hdr->addr1);
> 7c10770f995820 Johannes Berg    2015-03-20  1200  	}
> 58d4185e36913d Johannes Berg    2007-09-26  1201  
> cd8ffc800ce18e Johannes Berg    2009-03-23  1202  	if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
> 49a59543eb5a5d Johannes Berg    2011-09-29  1203  	    !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
> 30686bf7f5b3c3 Johannes Berg    2015-06-02  1204  	    ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
> 514b314825e19f Markus Theil     2020-12-09  1205  	    !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW) &&
> 514b314825e19f Markus Theil     2020-12-09 @1206  	    !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
>
> ! has higher precedence than & so this is equivalent of
> "if (!info->flags) {"  Presumably, it should be:
>
> 		!(info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) {

After fixing my syntax mistake, I ran into connectivity issues with my
older test NIC (Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74)

and therefore removed the aggregation bypass for control port frames. My
current working assumption: sending aggregated and non-aggregated
data traffic on the same TID is buggy in firmware. Please correct my
assumption, if for example the 802.11 standard already speaks a word
against doing this.
I already sent an updated v2.

Markus

> cd8ffc800ce18e Johannes Berg    2009-03-23  1207  		struct tid_ampdu_tx *tid_tx;
> cd8ffc800ce18e Johannes Berg    2009-03-23  1208  
> a1f2ba04cc9241 Sara Sharon      2018-02-19  1209  		tid = ieee80211_get_tid(hdr);
> 8b30b1fe368ab0 Sujith           2008-10-24  1210  
> a622ab72b4dcfd Johannes Berg    2010-06-10  1211  		tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
> a622ab72b4dcfd Johannes Berg    2010-06-10  1212  		if (tid_tx) {
> a622ab72b4dcfd Johannes Berg    2010-06-10  1213  			bool queued;
> a622ab72b4dcfd Johannes Berg    2010-06-10  1214  
> a622ab72b4dcfd Johannes Berg    2010-06-10  1215  			queued = ieee80211_tx_prep_agg(tx, skb, info,
> a622ab72b4dcfd Johannes Berg    2010-06-10  1216  						       tid_tx, tid);
> cd8ffc800ce18e Johannes Berg    2009-03-23  1217  
> cd8ffc800ce18e Johannes Berg    2009-03-23  1218  			if (unlikely(queued))
> cd8ffc800ce18e Johannes Berg    2009-03-23  1219  				return TX_QUEUED;
> 8b30b1fe368ab0 Sujith           2008-10-24  1220  		}
> a622ab72b4dcfd Johannes Berg    2010-06-10  1221  	}
> 8b30b1fe368ab0 Sujith           2008-10-24  1222  
> badffb725c86cc Jiri Slaby       2007-08-28  1223  	if (is_multicast_ether_addr(hdr->addr1)) {
> 5cf121c3cdb955 Johannes Berg    2008-02-25  1224  		tx->flags &= ~IEEE80211_TX_UNICAST;
> e039fa4a4195ac Johannes Berg    2008-05-15  1225  		info->flags |= IEEE80211_TX_CTL_NO_ACK;
> 6fd67e937ece53 Simon Wunderlich 2011-11-18  1226  	} else
> 5cf121c3cdb955 Johannes Berg    2008-02-25  1227  		tx->flags |= IEEE80211_TX_UNICAST;
> 58d4185e36913d Johannes Berg    2007-09-26  1228  
> a26eb27ab43014 Johannes Berg    2011-10-07  1229  	if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) {
> a26eb27ab43014 Johannes Berg    2011-10-07  1230  		if (!(tx->flags & IEEE80211_TX_UNICAST) ||
> a26eb27ab43014 Johannes Berg    2011-10-07  1231  		    skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold ||
> a26eb27ab43014 Johannes Berg    2011-10-07  1232  		    info->flags & IEEE80211_TX_CTL_AMPDU)
> a26eb27ab43014 Johannes Berg    2011-10-07  1233  			info->flags |= IEEE80211_TX_CTL_DONTFRAG;
> 58d4185e36913d Johannes Berg    2007-09-26  1234  	}
> 58d4185e36913d Johannes Berg    2007-09-26  1235  
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1236  	if (!tx->sta)
> e039fa4a4195ac Johannes Berg    2008-05-15  1237  		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
> f7418bc10d8402 Felix Fietkau    2015-09-24  1238  	else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
> e039fa4a4195ac Johannes Berg    2008-05-15  1239  		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
> f7418bc10d8402 Felix Fietkau    2015-09-24  1240  		ieee80211_check_fast_xmit(tx->sta);
> f7418bc10d8402 Felix Fietkau    2015-09-24  1241  	}
> 58d4185e36913d Johannes Berg    2007-09-26  1242  
> e039fa4a4195ac Johannes Berg    2008-05-15  1243  	info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1244  
> 9ae54c8463691b Johannes Berg    2008-01-31  1245  	return TX_CONTINUE;
> e2ebc74d7e3d71 Johannes Berg    2007-07-27  1246  }
>
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org 
>
> _______________________________________________
> kbuild mailing list -- kbuild@lists.01.org
> To unsubscribe send an email to kbuild-leave@lists.01.org
diff mbox series

Patch

diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 6feb45135..265c1d13b 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -627,16 +627,12 @@  static void ieee80211_report_ack_skb(struct ieee80211_local *local,
 		u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie;
 		struct ieee80211_sub_if_data *sdata;
 		struct ieee80211_hdr *hdr = (void *)skb->data;
-		__be16 ethertype = 0;
-
-		if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3))
-			skb_copy_bits(skb, 2 * ETH_ALEN, &ethertype, ETH_TLEN);
 
 		rcu_read_lock();
 		sdata = ieee80211_sdata_from_skb(local, skb);
 		if (sdata) {
-			if (ethertype == sdata->control_port_protocol ||
-			    ethertype == cpu_to_be16(ETH_P_PREAUTH))
+			if (skb->protocol == sdata->control_port_protocol ||
+			    skb->protocol == cpu_to_be16(ETH_P_PREAUTH))
 				cfg80211_control_port_tx_status(&sdata->wdev,
 								cookie,
 								skb->data,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 01eb08527..4dae5aa7f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1192,9 +1192,7 @@  ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 			tx->sta = rcu_dereference(sdata->u.vlan.sta);
 			if (!tx->sta && sdata->wdev.use_4addr)
 				return TX_DROP;
-		} else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
-					  IEEE80211_TX_CTL_INJECTED) ||
-			   tx->sdata->control_port_protocol == tx->skb->protocol) {
+		} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
 			tx->sta = sta_info_get_bss(sdata, hdr->addr1);
 		}
 		if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
@@ -1204,7 +1202,8 @@  ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 	if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
 	    !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
 	    ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
-	    !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
+	    !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW) &&
+	    !info->flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
 		struct tid_ampdu_tx *tid_tx;
 
 		tid = ieee80211_get_tid(hdr);
@@ -3944,7 +3943,8 @@  void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 	if (IS_ERR(sta))
 		sta = NULL;
 
-	if (local->ops->wake_tx_queue) {
+	if (local->ops->wake_tx_queue ||
+	    skb->protocol == sdata->control_port_protocol) {
 		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
 		skb_set_queue_mapping(skb, queue);
 		skb_get_hash(skb);
@@ -5440,8 +5440,7 @@  int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
 	if (cookie)
 		ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 
-	flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
-		 IEEE80211_TX_CTL_INJECTED;
+	flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
 
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
 			    sizeof(struct ethhdr) + len);
@@ -5458,7 +5457,7 @@  int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
 	ehdr->h_proto = proto;
 
 	skb->dev = dev;
-	skb->protocol = htons(ETH_P_802_3);
+	skb->protocol = proto;
 	skb_reset_network_header(skb);
 	skb_reset_mac_header(skb);