Search Linux Wireless

Re: [PATCH v6 2/5] mt76: mt76x02: split beaconing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/20/19 10:28 AM, Stanislaw Gruszka wrote:
> On Tue, Nov 19, 2019 at 04:47:43PM +0100, Markus Theil wrote:
>> Sending beacons to the hardware always happens in batches. In order to
>> speed up beacon processing on usb devices, this patch splits out common
>> code an calls it only once (mt76x02_mac_set_beacon_prepare,
>> mt76x02_mac_set_beacon_finish). Making this split breaks beacon
>> enabling/disabling per vif. This is fixed by adding a call to set the
>> bypass mask, if beaconing should be disabled for a vif. Otherwise the
>> beacon is send after the next beacon interval.
>>
>> The code is also adapted for the mmio part of the driver, but should not
>> have any performance implication there.
>>
>> Signed-off-by: Markus Theil <markus.theil@xxxxxxxxxxxxx>
>> ---
>>  .../wireless/mediatek/mt76/mt76x02_beacon.c   | 44 +++++++------------
>>  .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  1 +
>>  .../net/wireless/mediatek/mt76/mt76x02_mmio.c |  5 +++
>>  .../wireless/mediatek/mt76/mt76x02_usb_core.c |  5 +++
>>  4 files changed, 26 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>> index 403866496640..09013adae854 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>> @@ -47,10 +47,6 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
>>  	int beacon_len = dev->beacon_ops->slot_size;
>>  	int beacon_addr = MT_BEACON_BASE + (beacon_len * bcn_idx);
>>  	int ret = 0;
>> -	int i;
>> -
>> -	/* Prevent corrupt transmissions during update */
>> -	mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
>>  
>>  	if (skb) {
>>  		ret = mt76x02_write_beacon(dev, beacon_addr, skb);
>> @@ -60,41 +56,30 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
>>  		dev->beacon_data_mask &= ~BIT(bcn_idx);
>>  	}
>>  
>> -	mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
>> -
>>  	return ret;
>>  }
>>  
>> -int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
>> -			   struct sk_buff *skb)
>> +void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev)
>>  {
>> -	bool force_update = false;
>> -	int bcn_idx = 0;
>>  	int i;
>> +	int bcn_idx = 0;
>>  
>> -	for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
>> -		if (vif_idx == i) {
>> -			force_update = !!dev->beacons[i] ^ !!skb;
>> -			dev_kfree_skb(dev->beacons[i]);
>> -			dev->beacons[i] = skb;
>> -			__mt76x02_mac_set_beacon(dev, bcn_idx, skb);
>> -		} else if (force_update && dev->beacons[i]) {
>> -			__mt76x02_mac_set_beacon(dev, bcn_idx,
>> -						 dev->beacons[i]);
>> -		}
>> -
>> +	for (i = 0; i < hweight8(dev->mt76.beacon_mask); ++i)
>>  		bcn_idx += !!dev->beacons[i];
> This looks wrong since we do not calculate all beacons, only 
> up to hweight8(dev->mt76.beacon_mask).
>
> But since we need to calculate number of all beacons we can just
> use hweight8(dev->mt76.beacon_mask) directly.

You're right that I made a mistake here. Using
hweight8(dev->mt76.beacon_mask) would be wrong
for usb devices, which may setup buffered broadcast or multicast frames
as additional beacons.
My updated patch therefore uses hweight8(dev->mt76.beacon_data_mask)
directly.

>> -	}
>> -
>> -	for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
>> -		if (!(dev->beacon_data_mask & BIT(i)))
>> -			break;
>> -
>> -		__mt76x02_mac_set_beacon(dev, i, NULL);
>> -	}
>>  
>>  	mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
>>  		       bcn_idx - 1);
>> +
>> +	mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
> I'm not sure if this is correct for multi bss.
>
> In MT7620 manual BCM_BAYPASS_MASK is described as below:
>
> "
> Directly bypasses the Tx Beacon frame with the  specified 
> Beacon number. Bit0=Nth Beacon, bit1=(N- 1)th Beacon,... etc.
> N is the number of  Beacons defined in the  MULTI_BCN_NUM field in the 
> MAC_BSSID_DW1(offset: 0x1014) register.
> 0: Disable
> 1: Enable
> "
>
> Assuming manual is correct (it could be wrong) bypass mask should be
> calculated differently.
>
> Stanislaw
>
I tested the updated code with my usb nic and an mbss with 2 ap vifs.
Both beacons were transmitted. Maybe the manual is wrong in this place.

Markus  




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux