* Re: [RFC 42/53] wireless-regdb: ID, Indonesia - enable 5 GHz and VHT80
From: Luis R. Rodriguez @ 2013-07-08 20:20 UTC (permalink / raw)
To: Krishna Chaitanya
Cc: Arend van Spriel, John W. Linville,
wireless-regdb@lists.infradead.org, linux-wireless
In-Reply-To: <CABPxzYLD3xp9vyTA42PsCdNo1qAm4+X4OrqFTN70-aGvO52FeQ@mail.gmail.com>
On Thu, Jul 4, 2013 at 12:29 PM, Krishna Chaitanya
<chaitanya.mgit@gmail.com> wrote:
> On Thu, Jul 4, 2013 at 11:53 PM, Arend van Spriel <arend@broadcom.com> wrote:
>>
>> On 07/04/2013 03:04 AM, Luis R. Rodriguez wrote:
>>>
>>> From: "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
>>>
>>> Pursuant to:
>>>
>>> http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf,
>>>
>>> provide a 5GHz rule for Indonesian regulatory domain. QCA has
>>> also verified VHT80 can be enabled. Patch originally posted by
>>> Paul Stewart <pstew@chromium.org>, I just modified to enable 80 MHz
>>> bandwidth.
>>
>>
>> Hi Luis,
>>
>> Is it just me or did you make a typo. Should '@ 20' be '@ 80' ?
Indeed, typo, I'll fix in my next iteration!
> But as per the document shared above the maximum BW allowed is 20MHz only, no?
> So is the VHT80 tested by QCA compliant to the reg rules?
Yes it is.
Luis
^ permalink raw reply
* Re: 3.9.5+: Crash in tcp_input.c:4810.
From: Ben Greear @ 2013-07-08 20:17 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, linux-wireless@vger.kernel.org
In-Reply-To: <1373314235.4979.121.camel@edumazet-glaptop>
On 07/08/2013 01:10 PM, Eric Dumazet wrote:
> On Mon, 2013-07-08 at 12:59 -0700, Ben Greear wrote:
>
>>> There is this thing in ath9k about aggregating two frags
>>>
>>> drivers/net/wireless/ath/ath9k/recv.c line 1298 contains :
>>>
>>> RX_STAT_INC(rx_frags);
>>>
>>> Could you check these stats (I do not know if they are reported by
>>> ethtool -S or another debugging facility) and check if rx_frags is ever
>>> increasing ?
>>
>> They are in debugfs, and they appear to increase fairly often, for
>> instance:
>>
>> [root@lec2010-ath9k-1 lanforge]# cat /debug/ieee80211/wiphy0/ath9k/recv|tail -5
>> RX-Pkts-All : 288009442
>> RX-Bytes-All : 4067932166
>> RX-Beacons : 14826735
>> RX-Frags : 3944
>> RX-Spectral : 0
>>
>> I don't have the stats from the system that reproduced the bug
>> (it has been rebooted), but if I do see the bug again, I'll
>> grab the rx-frags and other stats just in case it shows
>> some anomaly.
>>
>
> Reading this code again, I believe following patch is needed.
>
> Could you test it ?
Sure, will do. Adding the linux-wireless mailing list as well.
Thanks,
Ben
>
> Thanks
>
> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> index 8be2b5d..f642f04 100644
> --- a/drivers/net/wireless/ath/ath9k/recv.c
> +++ b/drivers/net/wireless/ath/ath9k/recv.c
> @@ -1317,7 +1317,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
> if (sc->rx.frag) {
> int space = skb->len - skb_tailroom(hdr_skb);
>
> - if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
> + if (space > 0 &&
> + pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
> dev_kfree_skb(skb);
> RX_STAT_INC(rx_oom_err);
> goto requeue_drop_frag;
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: wl127x: Unable to associate with a WPA2-PSK AP
From: Arik Nemtsov @ 2013-07-08 19:08 UTC (permalink / raw)
To: José Miguel Gonçalves; +Cc: linux-wireless, Luciano Coelho
In-Reply-To: <51DB0ACC.7050800@inov.pt>
Hey,
About the second issue - seems the following patch is missing from your tree:
http://permalink.gmane.org/gmane.linux.kernel.wireless.general/105449
So the warning is bogus. It will happen if you're working on a single
processor (UP) system.
To get the latest driver, you can use Luca's tree, which already
contains this patch:
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
Arik
On Mon, Jul 8, 2013 at 9:54 PM, José Miguel Gonçalves
<jose.goncalves@inov.pt> wrote:
> Hi,
>
> After solving some initial platform issues, I'm now blocked in two more
> issues using the wl127x driver with kernel 3.9.9 in a S3C2416 hardware based
> platform.
>
> The first one is that the command "iw wlan0 scan" does not scan all
> frequencies. I've seen a patch submitted to fix an issue in the driver for
> the 5 GHz band
> (http://permalink.gmane.org/gmane.linux.kernel.wireless.general/107771) but
> this is not my issue, because I can not see also several APs in the 2.4GHz
> band after a scan.
>
> The second issue is when I try to associate with an AP using WPA2-PSK with
> wpa_supplicant (only able to reach this point by setting "scan_freq" in
> wpa_supplicat.conf file to the frequency used by the AP, because of the
> inability to perform of a complete scan) I get an error in the driver, as
> shown in the log bellow:
>
>
> [root ~]$ wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf
> Successfully initialized wpa_supplicant
> [ 33.915000] wlcore: firmware booted (Rev 6.3.10.0.133)
> [ 34.280000] cfg80211: Calling CRDA for country: PT
> [ 34.290000] cfg80211: Regulatory domain changed to country: PT
> [ 34.290000] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 34.305000] cfg80211: (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 34.320000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 34.320000] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 34.330000] cfg80211: (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A,
> 2700 mBm)
> [ 34.340000] cfg80211: (57240000 KHz - 65880000 KHz @ 2160000 KHz),
> (N/A, 4000 mBm)
> wlan0: SME: Trying to authenticate with 88:43:e1:57:79:c0 (SSID='[
> 34.585000] wlan0: authenticate with 88:43:e1:57:79:c0
> A. Guidance' freq=2452 MHz)
> [ 34.595000] ------------[ cut here ]------------
> [ 34.595000] WARNING: at drivers/net/wireless/ti/wlcore/tx.c:1307
> wlcore_is_queue_stopped_by_reason_locked+0x98/0xb4 [wlcore]()
> [ 34.595000] Modules linked in: arc4 wl12xx wlcore mac80211 wlcore_sdio
> lm70
> [ 34.595000] Backtrace:
> [ 34.595000] [<c000b92c>] (dump_backtrace+0x0/0x10c) from [<c02ed4a4>]
> (dump_stack+0x18/0x1c)
> [ 34.595000] r6:bf05ddd8 r5:00000009 r4:00000000 r3:00000000
> [ 34.595000] [<c02ed48c>] (dump_stack+0x0/0x1c) from [<c0019ecc>]
> (warn_slowpath_common+0x54/0x70)
> [ 34.595000] [<c0019e78>] (warn_slowpath_common+0x0/0x70) from
> [<c0019f0c>] (warn_slowpath_null+0x24/0x2c)
> [ 34.595000] r8:c39e2acc r7:00000000 r6:c305b160 r5:bf06ca36 r4:00000002
> r3:00000009
> [ 34.595000] [<c0019ee8>] (warn_slowpath_null+0x0/0x2c) from [<bf05ddd8>]
> (wlcore_is_queue_stopped_by_reason_locked+0x98/0xb4 [wlcore])
> [ 34.595000] [<bf05dd40>]
> (wlcore_is_queue_stopped_by_reason_locked+0x0/0xb4 [wlcore]) from
> [<bf05de38>] (wlcore_is_queue_stopped_by_reason+0x44/0x7c [wlcore])
> [ 34.595000] r6:00000000 r5:c305b160 r4:80000013
> [ 34.595000] [<bf05ddf4>] (wlcore_is_queue_stopped_by_reason+0x0/0x7c
> [wlcore]) from [<bf05deb4>] (wl1271_handle_tx_low_watermark+0x44/0x94
> [wlcore])
> [ 34.595000] r8:c305b160 r7:c39e2acc r6:00000000 r5:c39e2acc r4:00000000
> r3:00000000
> [ 34.595000] [<bf05de70>] (wl1271_handle_tx_low_watermark+0x0/0x94
> [wlcore]) from [<bf05e050>] (wl1271_tx_reset_link_queues+0x14c/0x174
> [wlcore])
> [ 34.595000] [<bf05df04>] (wl1271_tx_reset_link_queues+0x0/0x174 [wlcore])
> from [<bf05970c>] (wl12xx_free_link+0xec/0x150 [wlcore])
> [ 34.595000] [<bf059620>] (wl12xx_free_link+0x0/0x150 [wlcore]) from
> [<bf059b50>] (wl12xx_cmd_role_stop_sta+0x98/0x100 [wlcore])
> [ 34.595000] r7:c305b160 r6:00000000 r5:c39e2acc r4:c3a89ac0
> [ 34.595000] [<bf059ab8>] (wl12xx_cmd_role_stop_sta+0x0/0x100 [wlcore])
> from [<bf0546d8>] (wl1271_bss_info_changed_sta+0x840/0x9a4 [wlcore])
> [ 34.595000] r7:c39e2acc r6:c305b160 r5:c39e2a10 r4:000000e0
> [ 34.595000] [<bf053e98>] (wl1271_bss_info_changed_sta+0x0/0x9a4 [wlcore])
> from [<bf054a0c>] (wl1271_op_bss_info_changed+0x1d0/0x46c [wlcore])
> [ 34.595000] [<bf05483c>] (wl1271_op_bss_info_changed+0x0/0x46c [wlcore])
> from [<bf009538>] (ieee80211_bss_info_change_notify+0x6c/0x10c [mac80211])
> [ 34.595000] [<bf0094cc>] (ieee80211_bss_info_change_notify+0x0/0x10c
> [mac80211]) from [<bf02bf1c>] (ieee80211_prep_connection+0x2dc/0x76c
> [mac80211])
> [ 34.595000] r7:00000fff r6:c39cfe48 r5:c305b8e4 r4:c39e2440
> [ 34.595000] [<bf02bc40>] (ieee80211_prep_connection+0x0/0x76c [mac80211])
> from [<bf030d70>] (ieee80211_mgd_auth+0x228/0x29c [mac80211])
> [ 34.595000] [<bf030b48>] (ieee80211_mgd_auth+0x0/0x29c [mac80211]) from
> [<bf01afd4>] (ieee80211_auth+0x18/0x1c [mac80211])
> [ 34.595000] [<bf01afbc>] (ieee80211_auth+0x0/0x1c [mac80211]) from
> [<c02e40a8>] (__cfg80211_mlme_auth+0x170/0x188)
> [ 34.595000] [<c02e3f38>] (__cfg80211_mlme_auth+0x0/0x188) from
> [<c02e4154>] (cfg80211_mlme_auth+0x94/0xb8)
> [ 34.595000] [<c02e40c0>] (cfg80211_mlme_auth+0x0/0xb8) from [<c02dffbc>]
> (nl80211_authenticate+0x258/0x27c)
> [ 34.595000] [<c02dfd64>] (nl80211_authenticate+0x0/0x27c) from
> [<c0260044>] (genl_rcv_msg+0x23c/0x274)
> [ 34.595000] [<c025fe08>] (genl_rcv_msg+0x0/0x274) from [<c025f458>]
> (netlink_rcv_skb+0xb4/0xc8)
> [ 34.595000] [<c025f3a4>] (netlink_rcv_skb+0x0/0xc8) from [<c025fdfc>]
> (genl_rcv+0x20/0x2c)
> [ 34.595000] r6:00000048 r5:c3a5b400 r4:c38c4bc0 r3:c025fddc
> [ 34.595000] [<c025fddc>] (genl_rcv+0x0/0x2c) from [<c025ee40>]
> (netlink_unicast+0x1b0/0x214)
> [ 34.595000] r4:c38c5e00 r3:c025fddc
> [ 34.595000] [<c025ec90>] (netlink_unicast+0x0/0x214) from [<c025f230>]
> (netlink_sendmsg+0x2e0/0x358)
> [ 34.595000] [<c025ef50>] (netlink_sendmsg+0x0/0x358) from [<c0230944>]
> (sock_sendmsg+0x88/0xa8)
> [ 34.595000] [<c02308bc>] (sock_sendmsg+0x0/0xa8) from [<c0230d64>]
> (___sys_sendmsg+0x2c8/0x2e0)
> [ 34.595000] [<c0230a9c>] (___sys_sendmsg+0x0/0x2e0) from [<c0232920>]
> (__sys_sendmsg+0x44/0x70)
> [ 34.595000] [<c02328dc>] (__sys_sendmsg+0x0/0x70) from [<c023295c>]
> (sys_sendmsg+0x10/0x14)
> [ 34.595000] r6:be94fa8c r5:017940a0 r4:00000000
> [ 34.595000] [<c023294c>] (sys_sendmsg+0x0/0x14) from [<c0009400>]
> (ret_fast_syscall+0x0/0x2c)
> [ 34.595000] ---[ end trace a2c5f3d5ef286154 ]---
> [ 34.605000] wlan0: send auth to 88:43:e1:57:79:c0 (try 1/3)
> [ 34.605000] ------------[ cut here ]------------
> [ 34.605000] WARNING: at drivers/net/wireless/ti/wlcore/tx.c:1316
> wlcore_is_queue_stopped_locked+0x74/0x8c [wlcore]()
> [ 34.605000] Modules linked in: arc4 wl12xx wlcore mac80211 wlcore_sdio
> lm70
> [ 34.605000] Backtrace:
> [ 34.605000] [<c000b92c>] (dump_backtrace+0x0/0x10c) from [<c02ed4a4>]
> (dump_stack+0x18/0x1c)
> [ 34.605000] r6:bf05f240 r5:00000009 r4:00000000 r3:00000000
> [ 34.605000] [<c02ed48c>] (dump_stack+0x0/0x1c) from [<c0019ecc>]
> (warn_slowpath_common+0x54/0x70)
> [ 34.605000] [<c0019e78>] (warn_slowpath_common+0x0/0x70) from
> [<c0019f0c>] (warn_slowpath_null+0x24/0x2c)
> [ 34.605000] r8:40000013 r7:c305b160 r6:c305b160 r5:bf06ca36 r4:00000000
> r3:00000009
> [ 34.605000] [<c0019ee8>] (warn_slowpath_null+0x0/0x2c) from [<bf05f240>]
> (wlcore_is_queue_stopped_locked+0x74/0x8c [wlcore])
> [ 34.605000] [<bf05f1cc>] (wlcore_is_queue_stopped_locked+0x0/0x8c
> [wlcore]) from [<bf05225c>] (wl1271_op_tx+0x104/0x290 [wlcore])
> [ 34.605000] r6:c39e2a10 r5:00000001 r4:c38c4a40 r3:00000003
> [ 34.605000] [<bf052158>] (wl1271_op_tx+0x0/0x290 [wlcore]) from
> [<bf023e64>] (__ieee80211_tx+0x134/0x384 [mac80211])
> [ 34.605000] [<bf023d30>] (__ieee80211_tx+0x0/0x384 [mac80211]) from
> [<bf024174>] (ieee80211_tx+0xc0/0xe8 [mac80211])
> [ 34.605000] [<bf0240b4>] (ieee80211_tx+0x0/0xe8 [mac80211]) from
> [<bf02474c>] (ieee80211_xmit+0x80/0x94 [mac80211])
> [ 34.605000] [<bf0246cc>] (ieee80211_xmit+0x0/0x94 [mac80211]) from
> [<bf025698>] (__ieee80211_tx_skb_tid_band+0x58/0x64 [mac80211])
> [ 34.605000] r8:00000000 r7:00000001 r6:00000000 r5:c39e2440 r4:c38c4a40
> r3:c3ae8000
> [ 34.605000] [<bf025640>] (__ieee80211_tx_skb_tid_band+0x0/0x64
> [mac80211]) from [<bf0286c4>] (ieee80211_send_auth+0x158/0x1e0 [mac80211])
> [ 34.605000] r6:c39e2440 r5:c38c4a40 r4:c3ac8b94 r3:00000000
> [ 34.605000] [<bf02856c>] (ieee80211_send_auth+0x0/0x1e0 [mac80211]) from
> [<bf02c550>] (ieee80211_probe_auth+0x174/0x2c8 [mac80211])
> [ 34.605000] [<bf02c3dc>] (ieee80211_probe_auth+0x0/0x2c8 [mac80211]) from
> [<bf030d80>] (ieee80211_mgd_auth+0x238/0x29c [mac80211])
> [ 34.605000] r8:c39e2798 r7:00000000 r6:c39e2440 r5:c3a72c20 r4:c3ae9af8
> [ 34.605000] [<bf030b48>] (ieee80211_mgd_auth+0x0/0x29c [mac80211]) from
> [<bf01afd4>] (ieee80211_auth+0x18/0x1c [mac80211])
> [ 34.605000] [<bf01afbc>] (ieee80211_auth+0x0/0x1c [mac80211]) from
> [<c02e40a8>] (__cfg80211_mlme_auth+0x170/0x188)
> [ 34.605000] [<c02e3f38>] (__cfg80211_mlme_auth+0x0/0x188) from
> [<c02e4154>] (cfg80211_mlme_auth+0x94/0xb8)
> [ 34.605000] [<c02e40c0>] (cfg80211_mlme_auth+0x0/0xb8) from [<c02dffbc>]
> (nl80211_authenticate+0x258/0x27c)
> [ 34.605000] [<c02dfd64>] (nl80211_authenticate+0x0/0x27c) from
> [<c0260044>] (genl_rcv_msg+0x23c/0x274)
> [ 34.605000] [<c025fe08>] (genl_rcv_msg+0x0/0x274) from [<c025f458>]
> (netlink_rcv_skb+0xb4/0xc8)
> [ 34.605000] [<c025f3a4>] (netlink_rcv_skb+0x0/0xc8) from [<c025fdfc>]
> (genl_rcv+0x20/0x2c)
> [ 34.605000] r6:00000048 r5:c3a5b400 r4:c38c4bc0 r3:c025fddc
> [ 34.605000] [<c025fddc>] (genl_rcv+0x0/0x2c) from [<c025ee40>]
> (netlink_unicast+0x1b0/0x214)
> [ 34.605000] r4:c38c5e00 r3:c025fddc
> [ 34.605000] [<c025ec90>] (netlink_unicast+0x0/0x214) from [<c025f230>]
> (netlink_sendmsg+0x2e0/0x358)
> [ 34.605000] [<c025ef50>] (netlink_sendmsg+0x0/0x358) from [<c0230944>]
> (sock_sendmsg+0x88/0xa8)
> [ 34.605000] [<c02308bc>] (sock_sendmsg+0x0/0xa8) from [<c0230d64>]
> (___sys_sendmsg+0x2c8/0x2e0)
> [ 34.605000] [<c0230a9c>] (___sys_sendmsg+0x0/0x2e0) from [<c0232920>]
> (__sys_sendmsg+0x44/0x70)
> [ 34.605000] [<c02328dc>] (__sys_sendmsg+0x0/0x70) from [<c023295c>]
> (sys_sendmsg+0x10/0x14)
> [ 34.605000] r6:be94fa8c r5:017940a0 r4:00000000
> [ 34.605000] [<c023294c>] (sys_sendmsg+0x0/0x14) from [<c0009400>]
> (ret_fast_syscall+0x0/0x2c)
> [ 34.605000] ---[ end trace a2c5f3d5ef286155 ]---
> [ 34.625000] wlan0: send auth to 88:43:e1:57:79:c0 (try 2/3)
> [ 34.640000] wlan0: send auth to 88:43:e1:57:79:c0 (try 3/3)
> [ 34.650000] wlan0: authentication with 88:43:e1:57:79:c0 timed out
> wlan0: SME: Trying to authenticate with 88:43:e1:57:79:c0 (SSID='[
> 34.875000] wlan0: authenticate with 88:43:e1:57:79:c0
> A. Guidance' freq=2452 MHz)
> [ 34.915000] wlan0: send auth to 88:43:e1:57:79:c0 (try 1/3)
> [ 34.920000] wlan0: authenticated
> wlan0: Trying to associate with 88:43:e1:57:79:c0 (SSID='A. Guidance'
> freq=2452 MHz)
> [ 34.995000] wlan0: associate with 88:43:e1:57:79:c0 (try 1/3)
> [ 35.015000] wlan0: associate with 88:43:e1:57:79:c0 (try 2/3)
> [ 35.035000] wlan0: associate with 88:43:e1:57:79:c0 (try 3/3)
> [ 35.060000] wlan0: association with 88:43:e1:57:79:c0 timed out
> wlan0: SME: Trying to authenticate with 88:43:e1:57:79:c0 (SSID='[
> 35.620000] wlan0: authenticate with 88:43:e1:57:79:c0
> A. Guidance' freq=2452 MHz)
> [ 35.660000] wlan0: send auth to 88:43:e1:57:79:c0 (try 1/3)
> [ 35.665000] wlan0: authenticated
> wlan0: Trying to associate with 88:43:e1:57:79:c0 (SSID='A. Guidance'
> freq=2452 MHz)
> [ 35.740000] wlan0: associate with 88:43:e1:57:79:c0 (try 1/3)
> [ 35.745000] wlan0: RX AssocResp from 88:43:e1:57:79:c0 (capab=0x431
> status=0 aid=2)
> [ 35.765000] wlan0: associated
> [ 35.770000] cfg80211: Calling CRDA for country: PT
> [ 35.780000] cfg80211: Regulatory domain changed to country: PT
> [ 35.780000] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 35.790000] cfg80211: (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 35.790000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 35.800000] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 35.800000] cfg80211: (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A,
> 2700 mBm)
> [ 35.810000] cfg80211: (57240000 KHz - 65880000 KHz @ 2160000 KHz),
> (N/A, 4000 mBm)
> wlan0: Associated with 88:43:e1:57:79:c0
> [ 37.585000] wlcore: Beacon loss detected. roles:0xff
> [ 39.250000] wlcore: Beacon loss detected. roles:0xff
> [ 40.935000] wlcore: Beacon loss detected. roles:0xff
> [ 42.400000] wlcore: Connection loss work (role_id: 0).
> [ 42.400000] wlan0: Connection to AP 88:43:e1:57:79:c0 lost
> [ 42.475000] cfg80211: Calling CRDA to update world regulatory domain
> [ 42.485000] cfg80211: World regulatory domain updated:
> [ 42.485000] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 42.500000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 42.500000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 42.515000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300
> mBi, 2000 mBm)
> [ 42.515000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 42.525000] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 42.525000] cfg80211: Calling CRDA for country: PT
> [ 42.540000] cfg80211: Regulatory domain changed to country: PT
> [ 42.540000] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 42.550000] cfg80211: (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 42.550000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 42.560000] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A,
> 2000 mBm)
> [ 42.560000] cfg80211: (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A,
> 2700 mBm)
> wlan0: CTRL-EVENT-DISCONNECTED bssid=88:43:e1:57:79:c0 reason=4 l[
> 42.575000] cfg80211: (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A,
> 4000 mBm)
> ocally_generated=1
> wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrect
> wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="A. Guidance" auth_failures=1
> duration=10
>
>
> Any ideas in what could be wrong?
>
> Best regards,
> José Gonçalves
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* wl127x: Unable to associate with a WPA2-PSK AP
From: José Miguel Gonçalves @ 2013-07-08 18:54 UTC (permalink / raw)
To: linux-wireless; +Cc: Luciano Coelho
Hi,
After solving some initial platform issues, I'm now blocked in two more issues
using the wl127x driver with kernel 3.9.9 in a S3C2416 hardware based platform.
The first one is that the command "iw wlan0 scan" does not scan all frequencies.
I've seen a patch submitted to fix an issue in the driver for the 5 GHz band
(http://permalink.gmane.org/gmane.linux.kernel.wireless.general/107771) but this
is not my issue, because I can not see also several APs in the 2.4GHz band after a
scan.
The second issue is when I try to associate with an AP using WPA2-PSK with
wpa_supplicant (only able to reach this point by setting "scan_freq" in
wpa_supplicat.conf file to the frequency used by the AP, because of the inability
to perform of a complete scan) I get an error in the driver, as shown in the log
bellow:
[root ~]$ wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf
Successfully initialized wpa_supplicant
[ 33.915000] wlcore: firmware booted (Rev 6.3.10.0.133)
[ 34.280000] cfg80211: Calling CRDA for country: PT
[ 34.290000] cfg80211: Regulatory domain changed to country: PT
[ 34.290000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain,
max_eirp)
[ 34.305000] cfg80211: (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 34.320000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 34.320000] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 34.330000] cfg80211: (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
[ 34.340000] cfg80211: (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000
mBm)
wlan0: SME: Trying to authenticate with 88:43:e1:57:79:c0 (SSID='[ 34.585000]
wlan0: authenticate with 88:43:e1:57:79:c0
A. Guidance' freq=2452 MHz)
[ 34.595000] ------------[ cut here ]------------
[ 34.595000] WARNING: at drivers/net/wireless/ti/wlcore/tx.c:1307
wlcore_is_queue_stopped_by_reason_locked+0x98/0xb4 [wlcore]()
[ 34.595000] Modules linked in: arc4 wl12xx wlcore mac80211 wlcore_sdio lm70
[ 34.595000] Backtrace:
[ 34.595000] [<c000b92c>] (dump_backtrace+0x0/0x10c) from [<c02ed4a4>]
(dump_stack+0x18/0x1c)
[ 34.595000] r6:bf05ddd8 r5:00000009 r4:00000000 r3:00000000
[ 34.595000] [<c02ed48c>] (dump_stack+0x0/0x1c) from [<c0019ecc>]
(warn_slowpath_common+0x54/0x70)
[ 34.595000] [<c0019e78>] (warn_slowpath_common+0x0/0x70) from [<c0019f0c>]
(warn_slowpath_null+0x24/0x2c)
[ 34.595000] r8:c39e2acc r7:00000000 r6:c305b160 r5:bf06ca36 r4:00000002
r3:00000009
[ 34.595000] [<c0019ee8>] (warn_slowpath_null+0x0/0x2c) from [<bf05ddd8>]
(wlcore_is_queue_stopped_by_reason_locked+0x98/0xb4 [wlcore])
[ 34.595000] [<bf05dd40>] (wlcore_is_queue_stopped_by_reason_locked+0x0/0xb4
[wlcore]) from [<bf05de38>] (wlcore_is_queue_stopped_by_reason+0x44/0x7c [wlcore])
[ 34.595000] r6:00000000 r5:c305b160 r4:80000013
[ 34.595000] [<bf05ddf4>] (wlcore_is_queue_stopped_by_reason+0x0/0x7c [wlcore])
from [<bf05deb4>] (wl1271_handle_tx_low_watermark+0x44/0x94 [wlcore])
[ 34.595000] r8:c305b160 r7:c39e2acc r6:00000000 r5:c39e2acc r4:00000000
r3:00000000
[ 34.595000] [<bf05de70>] (wl1271_handle_tx_low_watermark+0x0/0x94 [wlcore])
from [<bf05e050>] (wl1271_tx_reset_link_queues+0x14c/0x174 [wlcore])
[ 34.595000] [<bf05df04>] (wl1271_tx_reset_link_queues+0x0/0x174 [wlcore]) from
[<bf05970c>] (wl12xx_free_link+0xec/0x150 [wlcore])
[ 34.595000] [<bf059620>] (wl12xx_free_link+0x0/0x150 [wlcore]) from
[<bf059b50>] (wl12xx_cmd_role_stop_sta+0x98/0x100 [wlcore])
[ 34.595000] r7:c305b160 r6:00000000 r5:c39e2acc r4:c3a89ac0
[ 34.595000] [<bf059ab8>] (wl12xx_cmd_role_stop_sta+0x0/0x100 [wlcore]) from
[<bf0546d8>] (wl1271_bss_info_changed_sta+0x840/0x9a4 [wlcore])
[ 34.595000] r7:c39e2acc r6:c305b160 r5:c39e2a10 r4:000000e0
[ 34.595000] [<bf053e98>] (wl1271_bss_info_changed_sta+0x0/0x9a4 [wlcore]) from
[<bf054a0c>] (wl1271_op_bss_info_changed+0x1d0/0x46c [wlcore])
[ 34.595000] [<bf05483c>] (wl1271_op_bss_info_changed+0x0/0x46c [wlcore]) from
[<bf009538>] (ieee80211_bss_info_change_notify+0x6c/0x10c [mac80211])
[ 34.595000] [<bf0094cc>] (ieee80211_bss_info_change_notify+0x0/0x10c
[mac80211]) from [<bf02bf1c>] (ieee80211_prep_connection+0x2dc/0x76c [mac80211])
[ 34.595000] r7:00000fff r6:c39cfe48 r5:c305b8e4 r4:c39e2440
[ 34.595000] [<bf02bc40>] (ieee80211_prep_connection+0x0/0x76c [mac80211]) from
[<bf030d70>] (ieee80211_mgd_auth+0x228/0x29c [mac80211])
[ 34.595000] [<bf030b48>] (ieee80211_mgd_auth+0x0/0x29c [mac80211]) from
[<bf01afd4>] (ieee80211_auth+0x18/0x1c [mac80211])
[ 34.595000] [<bf01afbc>] (ieee80211_auth+0x0/0x1c [mac80211]) from [<c02e40a8>]
(__cfg80211_mlme_auth+0x170/0x188)
[ 34.595000] [<c02e3f38>] (__cfg80211_mlme_auth+0x0/0x188) from [<c02e4154>]
(cfg80211_mlme_auth+0x94/0xb8)
[ 34.595000] [<c02e40c0>] (cfg80211_mlme_auth+0x0/0xb8) from [<c02dffbc>]
(nl80211_authenticate+0x258/0x27c)
[ 34.595000] [<c02dfd64>] (nl80211_authenticate+0x0/0x27c) from [<c0260044>]
(genl_rcv_msg+0x23c/0x274)
[ 34.595000] [<c025fe08>] (genl_rcv_msg+0x0/0x274) from [<c025f458>]
(netlink_rcv_skb+0xb4/0xc8)
[ 34.595000] [<c025f3a4>] (netlink_rcv_skb+0x0/0xc8) from [<c025fdfc>]
(genl_rcv+0x20/0x2c)
[ 34.595000] r6:00000048 r5:c3a5b400 r4:c38c4bc0 r3:c025fddc
[ 34.595000] [<c025fddc>] (genl_rcv+0x0/0x2c) from [<c025ee40>]
(netlink_unicast+0x1b0/0x214)
[ 34.595000] r4:c38c5e00 r3:c025fddc
[ 34.595000] [<c025ec90>] (netlink_unicast+0x0/0x214) from [<c025f230>]
(netlink_sendmsg+0x2e0/0x358)
[ 34.595000] [<c025ef50>] (netlink_sendmsg+0x0/0x358) from [<c0230944>]
(sock_sendmsg+0x88/0xa8)
[ 34.595000] [<c02308bc>] (sock_sendmsg+0x0/0xa8) from [<c0230d64>]
(___sys_sendmsg+0x2c8/0x2e0)
[ 34.595000] [<c0230a9c>] (___sys_sendmsg+0x0/0x2e0) from [<c0232920>]
(__sys_sendmsg+0x44/0x70)
[ 34.595000] [<c02328dc>] (__sys_sendmsg+0x0/0x70) from [<c023295c>]
(sys_sendmsg+0x10/0x14)
[ 34.595000] r6:be94fa8c r5:017940a0 r4:00000000
[ 34.595000] [<c023294c>] (sys_sendmsg+0x0/0x14) from [<c0009400>]
(ret_fast_syscall+0x0/0x2c)
[ 34.595000] ---[ end trace a2c5f3d5ef286154 ]---
[ 34.605000] wlan0: send auth to 88:43:e1:57:79:c0 (try 1/3)
[ 34.605000] ------------[ cut here ]------------
[ 34.605000] WARNING: at drivers/net/wireless/ti/wlcore/tx.c:1316
wlcore_is_queue_stopped_locked+0x74/0x8c [wlcore]()
[ 34.605000] Modules linked in: arc4 wl12xx wlcore mac80211 wlcore_sdio lm70
[ 34.605000] Backtrace:
[ 34.605000] [<c000b92c>] (dump_backtrace+0x0/0x10c) from [<c02ed4a4>]
(dump_stack+0x18/0x1c)
[ 34.605000] r6:bf05f240 r5:00000009 r4:00000000 r3:00000000
[ 34.605000] [<c02ed48c>] (dump_stack+0x0/0x1c) from [<c0019ecc>]
(warn_slowpath_common+0x54/0x70)
[ 34.605000] [<c0019e78>] (warn_slowpath_common+0x0/0x70) from [<c0019f0c>]
(warn_slowpath_null+0x24/0x2c)
[ 34.605000] r8:40000013 r7:c305b160 r6:c305b160 r5:bf06ca36 r4:00000000
r3:00000009
[ 34.605000] [<c0019ee8>] (warn_slowpath_null+0x0/0x2c) from [<bf05f240>]
(wlcore_is_queue_stopped_locked+0x74/0x8c [wlcore])
[ 34.605000] [<bf05f1cc>] (wlcore_is_queue_stopped_locked+0x0/0x8c [wlcore])
from [<bf05225c>] (wl1271_op_tx+0x104/0x290 [wlcore])
[ 34.605000] r6:c39e2a10 r5:00000001 r4:c38c4a40 r3:00000003
[ 34.605000] [<bf052158>] (wl1271_op_tx+0x0/0x290 [wlcore]) from [<bf023e64>]
(__ieee80211_tx+0x134/0x384 [mac80211])
[ 34.605000] [<bf023d30>] (__ieee80211_tx+0x0/0x384 [mac80211]) from
[<bf024174>] (ieee80211_tx+0xc0/0xe8 [mac80211])
[ 34.605000] [<bf0240b4>] (ieee80211_tx+0x0/0xe8 [mac80211]) from [<bf02474c>]
(ieee80211_xmit+0x80/0x94 [mac80211])
[ 34.605000] [<bf0246cc>] (ieee80211_xmit+0x0/0x94 [mac80211]) from [<bf025698>]
(__ieee80211_tx_skb_tid_band+0x58/0x64 [mac80211])
[ 34.605000] r8:00000000 r7:00000001 r6:00000000 r5:c39e2440 r4:c38c4a40
r3:c3ae8000
[ 34.605000] [<bf025640>] (__ieee80211_tx_skb_tid_band+0x0/0x64 [mac80211]) from
[<bf0286c4>] (ieee80211_send_auth+0x158/0x1e0 [mac80211])
[ 34.605000] r6:c39e2440 r5:c38c4a40 r4:c3ac8b94 r3:00000000
[ 34.605000] [<bf02856c>] (ieee80211_send_auth+0x0/0x1e0 [mac80211]) from
[<bf02c550>] (ieee80211_probe_auth+0x174/0x2c8 [mac80211])
[ 34.605000] [<bf02c3dc>] (ieee80211_probe_auth+0x0/0x2c8 [mac80211]) from
[<bf030d80>] (ieee80211_mgd_auth+0x238/0x29c [mac80211])
[ 34.605000] r8:c39e2798 r7:00000000 r6:c39e2440 r5:c3a72c20 r4:c3ae9af8
[ 34.605000] [<bf030b48>] (ieee80211_mgd_auth+0x0/0x29c [mac80211]) from
[<bf01afd4>] (ieee80211_auth+0x18/0x1c [mac80211])
[ 34.605000] [<bf01afbc>] (ieee80211_auth+0x0/0x1c [mac80211]) from [<c02e40a8>]
(__cfg80211_mlme_auth+0x170/0x188)
[ 34.605000] [<c02e3f38>] (__cfg80211_mlme_auth+0x0/0x188) from [<c02e4154>]
(cfg80211_mlme_auth+0x94/0xb8)
[ 34.605000] [<c02e40c0>] (cfg80211_mlme_auth+0x0/0xb8) from [<c02dffbc>]
(nl80211_authenticate+0x258/0x27c)
[ 34.605000] [<c02dfd64>] (nl80211_authenticate+0x0/0x27c) from [<c0260044>]
(genl_rcv_msg+0x23c/0x274)
[ 34.605000] [<c025fe08>] (genl_rcv_msg+0x0/0x274) from [<c025f458>]
(netlink_rcv_skb+0xb4/0xc8)
[ 34.605000] [<c025f3a4>] (netlink_rcv_skb+0x0/0xc8) from [<c025fdfc>]
(genl_rcv+0x20/0x2c)
[ 34.605000] r6:00000048 r5:c3a5b400 r4:c38c4bc0 r3:c025fddc
[ 34.605000] [<c025fddc>] (genl_rcv+0x0/0x2c) from [<c025ee40>]
(netlink_unicast+0x1b0/0x214)
[ 34.605000] r4:c38c5e00 r3:c025fddc
[ 34.605000] [<c025ec90>] (netlink_unicast+0x0/0x214) from [<c025f230>]
(netlink_sendmsg+0x2e0/0x358)
[ 34.605000] [<c025ef50>] (netlink_sendmsg+0x0/0x358) from [<c0230944>]
(sock_sendmsg+0x88/0xa8)
[ 34.605000] [<c02308bc>] (sock_sendmsg+0x0/0xa8) from [<c0230d64>]
(___sys_sendmsg+0x2c8/0x2e0)
[ 34.605000] [<c0230a9c>] (___sys_sendmsg+0x0/0x2e0) from [<c0232920>]
(__sys_sendmsg+0x44/0x70)
[ 34.605000] [<c02328dc>] (__sys_sendmsg+0x0/0x70) from [<c023295c>]
(sys_sendmsg+0x10/0x14)
[ 34.605000] r6:be94fa8c r5:017940a0 r4:00000000
[ 34.605000] [<c023294c>] (sys_sendmsg+0x0/0x14) from [<c0009400>]
(ret_fast_syscall+0x0/0x2c)
[ 34.605000] ---[ end trace a2c5f3d5ef286155 ]---
[ 34.625000] wlan0: send auth to 88:43:e1:57:79:c0 (try 2/3)
[ 34.640000] wlan0: send auth to 88:43:e1:57:79:c0 (try 3/3)
[ 34.650000] wlan0: authentication with 88:43:e1:57:79:c0 timed out
wlan0: SME: Trying to authenticate with 88:43:e1:57:79:c0 (SSID='[ 34.875000]
wlan0: authenticate with 88:43:e1:57:79:c0
A. Guidance' freq=2452 MHz)
[ 34.915000] wlan0: send auth to 88:43:e1:57:79:c0 (try 1/3)
[ 34.920000] wlan0: authenticated
wlan0: Trying to associate with 88:43:e1:57:79:c0 (SSID='A. Guidance' freq=2452 MHz)
[ 34.995000] wlan0: associate with 88:43:e1:57:79:c0 (try 1/3)
[ 35.015000] wlan0: associate with 88:43:e1:57:79:c0 (try 2/3)
[ 35.035000] wlan0: associate with 88:43:e1:57:79:c0 (try 3/3)
[ 35.060000] wlan0: association with 88:43:e1:57:79:c0 timed out
wlan0: SME: Trying to authenticate with 88:43:e1:57:79:c0 (SSID='[ 35.620000]
wlan0: authenticate with 88:43:e1:57:79:c0
A. Guidance' freq=2452 MHz)
[ 35.660000] wlan0: send auth to 88:43:e1:57:79:c0 (try 1/3)
[ 35.665000] wlan0: authenticated
wlan0: Trying to associate with 88:43:e1:57:79:c0 (SSID='A. Guidance' freq=2452 MHz)
[ 35.740000] wlan0: associate with 88:43:e1:57:79:c0 (try 1/3)
[ 35.745000] wlan0: RX AssocResp from 88:43:e1:57:79:c0 (capab=0x431 status=0 aid=2)
[ 35.765000] wlan0: associated
[ 35.770000] cfg80211: Calling CRDA for country: PT
[ 35.780000] cfg80211: Regulatory domain changed to country: PT
[ 35.780000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain,
max_eirp)
[ 35.790000] cfg80211: (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 35.790000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 35.800000] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 35.800000] cfg80211: (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
[ 35.810000] cfg80211: (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000
mBm)
wlan0: Associated with 88:43:e1:57:79:c0
[ 37.585000] wlcore: Beacon loss detected. roles:0xff
[ 39.250000] wlcore: Beacon loss detected. roles:0xff
[ 40.935000] wlcore: Beacon loss detected. roles:0xff
[ 42.400000] wlcore: Connection loss work (role_id: 0).
[ 42.400000] wlan0: Connection to AP 88:43:e1:57:79:c0 lost
[ 42.475000] cfg80211: Calling CRDA to update world regulatory domain
[ 42.485000] cfg80211: World regulatory domain updated:
[ 42.485000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain,
max_eirp)
[ 42.500000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000
mBm)
[ 42.500000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (300 mBi, 2000
mBm)
[ 42.515000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000
mBm)
[ 42.515000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000
mBm)
[ 42.525000] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000
mBm)
[ 42.525000] cfg80211: Calling CRDA for country: PT
[ 42.540000] cfg80211: Regulatory domain changed to country: PT
[ 42.540000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain,
max_eirp)
[ 42.550000] cfg80211: (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 42.550000] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 42.560000] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 42.560000] cfg80211: (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
wlan0: CTRL-EVENT-DISCONNECTED bssid=88:43:e1:57:79:c0 reason=4 l[ 42.575000]
cfg80211: (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
ocally_generated=1
wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrect
wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="A. Guidance" auth_failures=1
duration=10
Any ideas in what could be wrong?
Best regards,
José Gonçalves
^ permalink raw reply
* Re: Replacement for local->hw.conf.channel
From: Ben Greear @ 2013-07-08 18:47 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1373308289.8312.17.camel@jlt4.sipsolutions.net>
On 07/08/2013 11:31 AM, Johannes Berg wrote:
> On Mon, 2013-07-08 at 11:20 -0700, Ben Greear wrote:
>> On 07/04/2013 12:27 AM, Johannes Berg wrote:
>>> On Wed, 2013-07-03 at 17:01 -0700, Ben Greear wrote:
>>>> I'm trying to port some patches forward to 3.10....
>>>>
>>>> I am trying to find the current channel for a radio. Since
>>>> hw.conf.channel no longer exists, what is the best way to
>>>> go about this?
>>>
>>> Well there's hw.conf.chandef.chan now I think, but that can be NULL and
>>> generic mac80211 code must not use it. There's no single current channel
>>> any more, you want vif->chanctx or so.
>>
>> From looking at the scanning code (line 542 or so), it appears
>>
>> local->_oper_chandef.chan
>>
>> might work?
>
> No, don't use that in any new code. It's purely for compatibility with
> drivers that aren't converted to channel contexts (yet).
>
>> In 3.9, ath9k_htc was giving me a null channel in the code below:
>>
>> chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
>> if (chanctx_conf)
>> channel = chanctx_conf->def.chan;
>> else
>> channel = NULL;
>
> Well that of course happens if the vif isn't bound to a channel context.
Any opinions on what to return in ethtool stats for frequency if
there is no channel context?
If there is a quick way to just return whatever the hardware is
currently using, I think that is best, but if there is not
a reliable way to do this then, some hard coded default
like 0 is probably best.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: Replacement for local->hw.conf.channel
From: Johannes Berg @ 2013-07-08 18:31 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <51DB0302.5050201@candelatech.com>
On Mon, 2013-07-08 at 11:20 -0700, Ben Greear wrote:
> On 07/04/2013 12:27 AM, Johannes Berg wrote:
> > On Wed, 2013-07-03 at 17:01 -0700, Ben Greear wrote:
> >> I'm trying to port some patches forward to 3.10....
> >>
> >> I am trying to find the current channel for a radio. Since
> >> hw.conf.channel no longer exists, what is the best way to
> >> go about this?
> >
> > Well there's hw.conf.chandef.chan now I think, but that can be NULL and
> > generic mac80211 code must not use it. There's no single current channel
> > any more, you want vif->chanctx or so.
>
> From looking at the scanning code (line 542 or so), it appears
>
> local->_oper_chandef.chan
>
> might work?
No, don't use that in any new code. It's purely for compatibility with
drivers that aren't converted to channel contexts (yet).
> In 3.9, ath9k_htc was giving me a null channel in the code below:
>
> chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
> if (chanctx_conf)
> channel = chanctx_conf->def.chan;
> else
> channel = NULL;
Well that of course happens if the vif isn't bound to a channel context.
johannes
^ permalink raw reply
* Re: Replacement for local->hw.conf.channel
From: Ben Greear @ 2013-07-08 18:20 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1372922870.8235.0.camel@jlt4.sipsolutions.net>
On 07/04/2013 12:27 AM, Johannes Berg wrote:
> On Wed, 2013-07-03 at 17:01 -0700, Ben Greear wrote:
>> I'm trying to port some patches forward to 3.10....
>>
>> I am trying to find the current channel for a radio. Since
>> hw.conf.channel no longer exists, what is the best way to
>> go about this?
>
> Well there's hw.conf.chandef.chan now I think, but that can be NULL and
> generic mac80211 code must not use it. There's no single current channel
> any more, you want vif->chanctx or so.
From looking at the scanning code (line 542 or so), it appears
local->_oper_chandef.chan
might work?
In 3.9, ath9k_htc was giving me a null channel in the code below:
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf)
channel = chanctx_conf->def.chan;
else
channel = NULL;
I haven't tried that yet in 3.10 or later, so maybe I don't need the
hw.conf.channel in new code anyway.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] iw: Add support for mesh peer link expiration.
From: Johannes Berg @ 2013-07-08 18:14 UTC (permalink / raw)
To: Colleen Twitty; +Cc: linux-wirelss, open80211s
In-Reply-To: <1373303058-4229-1-git-send-email-colleen@cozybit.com>
On Mon, 2013-07-08 at 10:04 -0700, Colleen Twitty wrote:
> User can configure the peer link expiration time with a
> new mesh parameter, mesh_plink_timeout. This parameter
> sets the expiration time, in seconds, for peer links.
> After this time, the peer link is expired. This means the
> inactive STA is removed from the list of peers and is not
> considered a peer again unless it re-peers.
Applied.
johannes
^ permalink raw reply
* [PATCH] iw: Add support for mesh peer link expiration.
From: Colleen Twitty @ 2013-07-08 17:04 UTC (permalink / raw)
To: linux-wirelss; +Cc: Johannes Berg, open80211s
User can configure the peer link expiration time with a
new mesh parameter, mesh_plink_timeout. This parameter
sets the expiration time, in seconds, for peer links.
After this time, the peer link is expired. This means the
inactive STA is removed from the list of peers and is not
considered a peer again unless it re-peers.
Signed-off-by: Colleen Twitty <colleen@cozybit.com>
---
mesh.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/mesh.c b/mesh.c
index 5a09b62..ca065bf 100644
--- a/mesh.c
+++ b/mesh.c
@@ -157,6 +157,11 @@ static void _print_u32_timeout(struct nlattr *a)
printf("%u milliseconds", nla_get_u32(a));
}
+static void _print_u32_in_seconds(struct nlattr *a)
+{
+ printf("%d seconds", nla_get_u32(a));
+}
+
static void _print_u32_in_TUs(struct nlattr *a)
{
printf("%d TUs", nla_get_u32(a));
@@ -258,6 +263,8 @@ const static struct mesh_param_descr _mesh_param_descrs[] =
_my_nla_put_u32, _parse_u32_power_mode, _print_u32_power_mode},
{"mesh_awake_window", NL80211_MESHCONF_AWAKE_WINDOW,
_my_nla_put_u16, _parse_u16, _print_u16_in_TUs},
+ {"mesh_plink_timeout", NL80211_MESHCONF_PLINK_TIMEOUT,
+ _my_nla_put_u32, _parse_u32, _print_u32_in_seconds},
};
static void print_all_mesh_param_descr(void)
--
1.7.9.5
^ permalink raw reply related
* Re: ath10k mailing list and new git tree
From: Kalle Valo @ 2013-07-08 15:10 UTC (permalink / raw)
To: sedat.dilek; +Cc: linux-wireless, ath9k-devel, LKML, ath10k
In-Reply-To: <CA+icZUU32347g48dpk-gVZZ1H9pvnjaSWpQ12B-5vOkLzs8Nbg@mail.gmail.com>
Sedat Dilek <sedat.dilek@gmail.com> writes:
> On Mon, Jul 8, 2013 at 4:17 PM, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Hi,
>>
>> we have a new mailing list for ath10k, please use that in the future
>> instead of ath9k-devel:
>>
>> http://lists.infradead.org/mailman/listinfo/ath10k
>>
>> As ath10k is now in wireless-next please use the new git tree which is
>> for both ath6kl and ath10k:
>>
>> https://github.com/kvalo/ath
>>
>> I have also updated the wiki accordingly:
>>
>> http://wireless.kernel.org/en/users/Drivers/ath10k
>>
>
> You have sent these new informations for MAINTAINERS file to upstream?
Good point. Actually MAINTAINERS entry for ath10k is completely missing,
I'll send a patch for that.
Thanks.
--
Kalle Valo
^ permalink raw reply
* Re: ath10k mailing list and new git tree
From: Sedat Dilek @ 2013-07-08 14:58 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless, ath9k-devel, LKML
In-Reply-To: <87r4f9cf0w.fsf@kamboji.qca.qualcomm.com>
On Mon, Jul 8, 2013 at 4:17 PM, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Hi,
>
> we have a new mailing list for ath10k, please use that in the future
> instead of ath9k-devel:
>
> http://lists.infradead.org/mailman/listinfo/ath10k
>
> As ath10k is now in wireless-next please use the new git tree which is
> for both ath6kl and ath10k:
>
> https://github.com/kvalo/ath
>
> I have also updated the wiki accordingly:
>
> http://wireless.kernel.org/en/users/Drivers/ath10k
>
You have sent these new informations for MAINTAINERS file to upstream?
- Sedat -
> --
> Kalle Valo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCHv6 14/18] ath9k: set 5/10 MHz supported channels and fix bitrate
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv4:
* remove unused divisor line in the rate control
---
drivers/net/wireless/ath/ath9k/init.c | 24 ++++++++++++++++--------
drivers/net/wireless/ath/ath9k/rc.c | 5 +++++
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 71aa5c9..bd909ba 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -146,14 +146,22 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
- RATE(60, 0x0b, 0),
- RATE(90, 0x0f, 0),
- RATE(120, 0x0a, 0),
- RATE(180, 0x0e, 0),
- RATE(240, 0x09, 0),
- RATE(360, 0x0d, 0),
- RATE(480, 0x08, 0),
- RATE(540, 0x0c, 0),
+ RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
+ RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ)),
};
#ifdef CONFIG_MAC80211_LEDS
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index e41f563..5a69d9b 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1282,9 +1282,14 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_rate_priv *ath_rc_priv = priv_sta;
int i, j = 0;
+ u32 rate_flags = ieee80211_chandef_rate_flags(&sc->hw->conf.chandef);
for (i = 0; i < sband->n_bitrates; i++) {
if (sta->supp_rates[sband->band] & BIT(i)) {
+ if ((rate_flags & sband->bitrates[i].flags)
+ != rate_flags)
+ continue;
+
ath_rc_priv->neg_rates.rs_rates[j]
= (sband->bitrates[i].bitrate * 2) / 10;
j++;
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 12/18] ath9k: use chandef instead of channel_type
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
To enable support for 5/10 MHz, some internal functions must be
converted from using the (old) channel_type to chandef. This is a good
chance to change all remaining occurences.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath9k/common.c | 67 +++++++++++++++----------
drivers/net/wireless/ath/ath9k/common.h | 3 +-
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 +-
drivers/net/wireless/ath/ath9k/init.c | 4 +-
drivers/net/wireless/ath/ath9k/main.c | 8 ++-
drivers/net/wireless/ath/ath9k/rc.c | 4 +-
6 files changed, 51 insertions(+), 40 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 344fdde..d3063c2 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -49,37 +49,40 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
}
EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
-static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type)
+static u32 ath9k_get_extchanmode(struct cfg80211_chan_def *chandef)
{
u32 chanmode = 0;
- switch (chan->band) {
+ switch (chandef->chan->band) {
case IEEE80211_BAND_2GHZ:
- switch (channel_type) {
- case NL80211_CHAN_NO_HT:
- case NL80211_CHAN_HT20:
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
chanmode = CHANNEL_G_HT20;
break;
- case NL80211_CHAN_HT40PLUS:
- chanmode = CHANNEL_G_HT40PLUS;
+ case NL80211_CHAN_WIDTH_40:
+ if (chandef->center_freq1 > chandef->chan->center_freq)
+ chanmode = CHANNEL_G_HT40PLUS;
+ else
+ chanmode = CHANNEL_G_HT40MINUS;
break;
- case NL80211_CHAN_HT40MINUS:
- chanmode = CHANNEL_G_HT40MINUS;
+ default:
break;
}
break;
case IEEE80211_BAND_5GHZ:
- switch (channel_type) {
- case NL80211_CHAN_NO_HT:
- case NL80211_CHAN_HT20:
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
chanmode = CHANNEL_A_HT20;
break;
- case NL80211_CHAN_HT40PLUS:
- chanmode = CHANNEL_A_HT40PLUS;
+ case NL80211_CHAN_WIDTH_40:
+ if (chandef->center_freq1 > chandef->chan->center_freq)
+ chanmode = CHANNEL_A_HT40PLUS;
+ else
+ chanmode = CHANNEL_A_HT40MINUS;
break;
- case NL80211_CHAN_HT40MINUS:
- chanmode = CHANNEL_A_HT40MINUS;
+ default:
break;
}
break;
@@ -94,13 +97,12 @@ static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
* Update internal channel flags.
*/
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type)
+ struct cfg80211_chan_def *chandef)
{
- ichan->channel = chan->center_freq;
- ichan->chan = chan;
+ ichan->channel = chandef->chan->center_freq;
+ ichan->chan = chandef->chan;
- if (chan->band == IEEE80211_BAND_2GHZ) {
+ if (chandef->chan->band == IEEE80211_BAND_2GHZ) {
ichan->chanmode = CHANNEL_G;
ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
} else {
@@ -108,8 +110,22 @@ void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
}
- if (channel_type != NL80211_CHAN_NO_HT)
- ichan->chanmode = ath9k_get_extchanmode(chan, channel_type);
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_5:
+ ichan->channelFlags |= CHANNEL_QUARTER;
+ break;
+ case NL80211_CHAN_WIDTH_10:
+ ichan->channelFlags |= CHANNEL_HALF;
+ break;
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ break;
+ case NL80211_CHAN_WIDTH_20:
+ case NL80211_CHAN_WIDTH_40:
+ ichan->chanmode = ath9k_get_extchanmode(chandef);
+ break;
+ default:
+ WARN_ON(1);
+ }
}
EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
@@ -125,8 +141,7 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
chan_idx = curchan->hw_value;
channel = &ah->channels[chan_idx];
- ath9k_cmn_update_ichannel(channel, curchan,
- cfg80211_get_chandef_type(&hw->conf.chandef));
+ ath9k_cmn_update_ichannel(channel, &hw->conf.chandef);
return channel;
}
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 207d069..e039bcb 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -44,8 +44,7 @@
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type);
+ struct cfg80211_chan_def *chandef);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 5c1bec1..d442581 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1203,16 +1203,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) {
struct ieee80211_channel *curchan = hw->conf.chandef.chan;
- enum nl80211_channel_type channel_type =
- cfg80211_get_chandef_type(&hw->conf.chandef);
int pos = curchan->hw_value;
ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
curchan->center_freq);
ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
- hw->conf.chandef.chan,
- channel_type);
+ &hw->conf.chandef);
if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
ath_err(common, "Unable to set channel\n");
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 16f8b20..71aa5c9 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -710,13 +710,15 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan;
struct ath_hw *ah = sc->sc_ah;
+ struct cfg80211_chan_def chandef;
int i;
sband = &sc->sbands[band];
for (i = 0; i < sband->n_channels; i++) {
chan = &sband->channels[i];
ah->curchan = &ah->channels[chan->hw_value];
- ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
+ ath9k_cmn_update_ichannel(ah->curchan, &chandef);
ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1737a3e..ff91f4a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1193,8 +1193,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
struct ieee80211_channel *curchan = hw->conf.chandef.chan;
- enum nl80211_channel_type channel_type =
- cfg80211_get_chandef_type(&conf->chandef);
int pos = curchan->hw_value;
int old_pos = -1;
unsigned long flags;
@@ -1202,8 +1200,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (ah->curchan)
old_pos = ah->curchan - &ah->channels[0];
- ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n",
- curchan->center_freq, channel_type);
+ ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
+ curchan->center_freq, hw->conf.chandef.width);
/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
@@ -1211,7 +1209,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
spin_unlock_irqrestore(&common->cc_lock, flags);
ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
- curchan, channel_type);
+ &conf->chandef);
/*
* If the operating channel changes, change the survey in-use flags
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index a3c4ca0..e41f563 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1326,8 +1326,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
ath_rc_init(sc, priv_sta);
ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
- "Operating HT Bandwidth changed to: %d\n",
- cfg80211_get_chandef_type(&sc->hw->conf.chandef));
+ "Operating Bandwidth changed to: %d\n",
+ &sc->hw->conf.chandef->width);
}
}
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 18/18] ath5k: enable support for 5 MHz and 10 MHz channels
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/base.c | 25 ++++++++++++++++++++++---
drivers/net/wireless/ath/ath5k/base.h | 2 +-
drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +-
4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 2d691b8..74bd54d 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -29,6 +29,7 @@
#include <linux/average.h>
#include <linux/leds.h>
#include <net/mac80211.h>
+#include <net/cfg80211.h>
/* RX/TX descriptor hw structs
* TODO: Driver part should only see sw structs */
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7c298af..48161ed 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -56,6 +56,7 @@
#include <linux/etherdevice.h>
#include <linux/nl80211.h>
+#include <net/cfg80211.h>
#include <net/ieee80211_radiotap.h>
#include <asm/unaligned.h>
@@ -443,11 +444,27 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
* Called with ah->lock.
*/
int
-ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan)
+ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef)
{
ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
"channel set, resetting (%u -> %u MHz)\n",
- ah->curchan->center_freq, chan->center_freq);
+ ah->curchan->center_freq, chandef->chan->center_freq);
+
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_20:
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
+ break;
+ case NL80211_CHAN_WIDTH_5:
+ ah->ah_bwmode = AR5K_BWMODE_5MHZ;
+ break;
+ case NL80211_CHAN_WIDTH_10:
+ ah->ah_bwmode = AR5K_BWMODE_10MHZ;
+ break;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
/*
* To switch channels clear any pending DMA operations;
@@ -455,7 +472,7 @@ ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan)
* hardware at the new frequency, and then re-enable
* the relevant bits of the h/w.
*/
- return ath5k_reset(ah, chan, true);
+ return ath5k_reset(ah, chandef->chan, true);
}
void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -2525,6 +2542,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
/* SW support for IBSS_RSN is provided by mac80211 */
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+ hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
+
/* both antennas can be configured as RX or TX */
hw->wiphy->available_antennas_tx = 0x3;
hw->wiphy->available_antennas_rx = 0x3;
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index ca9a83c..97469d0 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -101,7 +101,7 @@ void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
struct ieee80211_vif *vif);
-int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
+int ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef);
void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 81b686c..aa9d976 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -202,7 +202,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&ah->lock);
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- ret = ath5k_chan_set(ah, conf->chandef.chan);
+ ret = ath5k_chan_set(ah, &conf->chandef);
if (ret < 0)
goto unlock;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 13/18] ath9k: report 5/10 MHz channels
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath9k/recv.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 865e043..0b0bc9d 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -865,6 +865,17 @@ static int ath9k_process_rate(struct ath_common *common,
band = hw->conf.chandef.chan->band;
sband = hw->wiphy->bands[band];
+ switch (hw->conf.chandef.width) {
+ case NL80211_CHAN_WIDTH_5:
+ rxs->flag |= RX_FLAG_5MHZ;
+ break;
+ case NL80211_CHAN_WIDTH_10:
+ rxs->flag |= RX_FLAG_10MHZ;
+ break;
+ default:
+ break;
+ }
+
if (rx_stats->rs_rate & 0x80) {
/* HT rate */
rxs->flag |= RX_FLAG_HT;
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 15/18] ath9k: announce that ath9k supports 5/10 MHz
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath9k/init.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index bd909ba..85a5a87 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -844,6 +844,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+ hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
#ifdef CONFIG_PM_SLEEP
if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 11/18] ath9k: always use SIFS times from OFDM for 5/10 MHz
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
5/10 MHz channels should always use SIFS times as defined in IEEE
802.11-2012 18.4.4 (OFDM PHY characteristics). This makes it compatible
to ath5k, which does the same.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath9k/hw.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4ca0cb0..748f0b6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1069,7 +1069,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
tx_lat += 11;
- sifstime *= 2;
+ sifstime = 32;
ack_offset = 16;
slottime = 13;
} else if (IS_CHAN_QUARTER_RATE(chan)) {
@@ -1079,7 +1079,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
tx_lat += 22;
- sifstime *= 4;
+ sifstime = 64;
ack_offset = 32;
slottime = 21;
} else {
@@ -1116,7 +1116,6 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
ctstimeout += 48 - sifstime - ah->slottime;
}
-
ath9k_hw_set_sifs_time(ah, sifstime);
ath9k_hw_setslottime(ah, slottime);
ath9k_hw_set_ack_timeout(ah, acktimeout);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 17/18] ath5k: set 5/10 MHz supported channels and fix duration
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath5k/base.c | 24 ++++++++++++++++--------
drivers/net/wireless/ath/ath5k/pcu.c | 2 ++
drivers/net/wireless/ath/ath5k/qcu.c | 25 ++++++++++++++++++++++++-
3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 260a6fc..7c298af 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -165,28 +165,36 @@ static const struct ieee80211_rate ath5k_rates[] = {
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 60,
.hw_value = ATH5K_RATE_CODE_6M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 90,
.hw_value = ATH5K_RATE_CODE_9M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 120,
.hw_value = ATH5K_RATE_CODE_12M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 180,
.hw_value = ATH5K_RATE_CODE_18M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 240,
.hw_value = ATH5K_RATE_CODE_24M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 360,
.hw_value = ATH5K_RATE_CODE_36M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 480,
.hw_value = ATH5K_RATE_CODE_48M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
{ .bitrate = 540,
.hw_value = ATH5K_RATE_CODE_54M,
- .flags = 0 },
+ .flags = IEEE80211_RATE_SUPPORTS_5MHZ |
+ IEEE80211_RATE_SUPPORTS_10MHZ },
};
static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 1f16b42..c60d36a 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -144,11 +144,13 @@ ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum ieee80211_band band,
sifs = AR5K_INIT_SIFS_HALF_RATE;
preamble *= 2;
sym_time *= 2;
+ bitrate = DIV_ROUND_UP(bitrate, 2);
break;
case AR5K_BWMODE_5MHZ:
sifs = AR5K_INIT_SIFS_QUARTER_RATE;
preamble *= 4;
sym_time *= 4;
+ bitrate = DIV_ROUND_UP(bitrate, 4);
break;
default:
sifs = AR5K_INIT_SIFS_DEFAULT_BG;
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 65fe929..0583c69 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -566,9 +566,11 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
{
struct ieee80211_channel *channel = ah->ah_current_channel;
enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
struct ieee80211_rate *rate;
u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
+ u32 rate_flags, i;
if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
return -EINVAL;
@@ -605,7 +607,28 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
else
band = IEEE80211_BAND_2GHZ;
- rate = &ah->sbands[band].bitrates[0];
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_5MHZ:
+ rate_flags = IEEE80211_RATE_SUPPORTS_5MHZ;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ rate_flags = IEEE80211_RATE_SUPPORTS_10MHZ;
+ break;
+ default:
+ rate_flags = 0;
+ break;
+ }
+ sband = &ah->sbands[band];
+ rate = NULL;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ continue;
+ rate = &sband->bitrates[i];
+ break;
+ }
+ if (WARN_ON(!rate))
+ return -EINVAL;
+
ack_tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, false);
/* ack_tx_time includes an SIFS already */
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 10/18] nl80211: allow 5 and 10 MHz channels for IBSS
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Whether the wiphy supports it or not is already checked, so what is left
is to enable these channel types.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
net/wireless/nl80211.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3019748..1318b5a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6318,6 +6318,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
switch (ibss.chandef.width) {
+ case NL80211_CHAN_WIDTH_5:
+ case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_20_NOHT:
break;
case NL80211_CHAN_WIDTH_20:
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 06/18] cfg80211/mac80211: get mandatory rates based on scan width
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Mandatory rates for 5 and 10 MHz are different from the rates used for
20 MHz in 2.4 GHz mode, as they use OFDM only.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv4:
* it is now based on scan_width instead of rate flags
---
include/net/cfg80211.h | 4 +++-
net/mac80211/ibss.c | 19 +++++++++++++++----
net/wireless/mesh.c | 5 ++++-
net/wireless/util.c | 14 ++++++++++----
4 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1df4060..4ca16ab 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3069,11 +3069,13 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
/**
* ieee80211_mandatory_rates - get mandatory rates for a given band
* @sband: the band to look for rates in
+ * @scan_width: width of the control channel
*
* This function returns a bitmap of the mandatory rates for the given
* band, bits are set according to the rate position in the bitrates array.
*/
-u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband);
+u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
+ enum nl80211_bss_scan_width scan_width);
/*
* Radiotap parsing functions -- for controlled injection support
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index e9ec3e6..7fb0f2a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -367,6 +367,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
struct sta_info *sta;
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_supported_band *sband;
+ enum nl80211_bss_scan_width scan_width;
int band;
/*
@@ -395,6 +396,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
if (WARN_ON_ONCE(!chanctx_conf))
return NULL;
band = chanctx_conf->def.chan->band;
+ scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
rcu_read_unlock();
sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -408,7 +410,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
/* make sure mandatory rates are always added */
sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(sband);
+ ieee80211_mandatory_rates(sband, scan_width);
return ieee80211_ibss_finish_sta(sta);
}
@@ -472,6 +474,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
u64 beacon_timestamp, rx_timestamp;
u32 supp_rates = 0;
enum ieee80211_band band = rx_status->band;
+ enum nl80211_bss_scan_width scan_width;
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
bool rates_updated = false;
@@ -500,9 +503,15 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
prev_rates = sta->sta.supp_rates[band];
/* make sure mandatory rates are always added */
+ scan_width = NL80211_BSS_CHAN_WIDTH_20;
+ if (rx_status->flag & RX_FLAG_5MHZ)
+ scan_width = NL80211_BSS_CHAN_WIDTH_5;
+ if (rx_status->flag & RX_FLAG_10MHZ)
+ scan_width = NL80211_BSS_CHAN_WIDTH_10;
+
sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(sband);
-
+ ieee80211_mandatory_rates(sband,
+ scan_width);
if (sta->sta.supp_rates[band] != prev_rates) {
ibss_dbg(sdata,
"updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
@@ -636,6 +645,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_supported_band *sband;
+ enum nl80211_bss_scan_width scan_width;
int band;
/*
@@ -661,6 +671,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
return;
}
band = chanctx_conf->def.chan->band;
+ scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
rcu_read_unlock();
sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -672,7 +683,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
/* make sure mandatory rates are always added */
sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(sband);
+ ieee80211_mandatory_rates(sband, scan_width);
spin_lock(&ifibss->incomplete_lock);
list_add(&sta->list, &ifibss->incomplete_stations);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 30c4920..0553fd4 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -167,9 +167,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
* basic rates
*/
if (!setup->basic_rates) {
+ enum nl80211_bss_scan_width scan_width;
struct ieee80211_supported_band *sband =
rdev->wiphy.bands[setup->chandef.chan->band];
- setup->basic_rates = ieee80211_mandatory_rates(sband);
+ scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
+ setup->basic_rates = ieee80211_mandatory_rates(sband,
+ scan_width);
}
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 74458b7..ce090c1 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -33,7 +33,8 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
}
EXPORT_SYMBOL(ieee80211_get_response_rate);
-u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
+u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
+ enum nl80211_bss_scan_width scan_width)
{
struct ieee80211_rate *bitrates;
u32 mandatory_rates = 0;
@@ -43,10 +44,15 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
if (WARN_ON(!sband))
return 1;
- if (sband->band == IEEE80211_BAND_2GHZ)
- mandatory_flag = IEEE80211_RATE_MANDATORY_B;
- else
+ if (sband->band == IEEE80211_BAND_2GHZ) {
+ if (scan_width == NL80211_BSS_CHAN_WIDTH_5 ||
+ scan_width == NL80211_BSS_CHAN_WIDTH_10)
+ mandatory_flag = IEEE80211_RATE_MANDATORY_G;
+ else
+ mandatory_flag = IEEE80211_RATE_MANDATORY_B;
+ } else {
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
+ }
bitrates = sband->bitrates;
for (i = 0; i < sband->n_bitrates; i++)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 16/18] ath5k: report 5/10 MHz channels
From: Simon Wunderlich @ 2013-07-08 14:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
drivers/net/wireless/ath/ath5k/base.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index ce67ab7..260a6fc 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1400,6 +1400,16 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
rxs->rate_idx = ath5k_hw_to_driver_rix(ah, rs->rs_rate);
rxs->flag |= ath5k_rx_decrypted(ah, skb, rs);
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_5MHZ:
+ rxs->flag |= RX_FLAG_5MHZ;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ rxs->flag |= RX_FLAG_10MHZ;
+ break;
+ default:
+ break;
+ }
if (rxs->rate_idx >= 0 && rs->rs_rate ==
ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 09/18] mac80211: return if IBSS chandef can not be used
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
This was originally designed to fail when a 40+/40- mode can not be
used, but basic modes (such as 5/10/20 MHz) must be handled
with an error.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
net/mac80211/ibss.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b99d948..7941e8d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -85,6 +85,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
chandef = ifibss->chandef;
if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+ if (chandef.width == NL80211_CHAN_WIDTH_5 ||
+ chandef.width == NL80211_CHAN_WIDTH_10 ||
+ chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+ chandef.width == NL80211_CHAN_WIDTH_20) {
+ sdata_info(sdata,
+ "Failed to join IBSS, beacons forbidden\n");
+ return;
+ }
chandef.width = NL80211_CHAN_WIDTH_20;
chandef.center_freq1 = chan->center_freq;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 05/18] mac80211: select and adjust bitrates according to channel mode
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
The various components accessing the bitrates table must use consider
the used channel bandwidth to select only available rates or calculate
the bitrate correctly.
There are some rates in reduced bandwidth modes which can't be
represented as multiples of 500kbps, like 2.25 MBit/s in 5 MHz mode. The
standard suggests to round up to the next multiple of 500kbps, just do
that in mac80211 as well.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv5:
* fix useless whitespace addition
* remove left-over variable "local" in mesh.c, creating a warning
Changes to PATCHv4:
* change divisor to shift to avoid unnecesary integer divisions
Changes to PATCHv3:
* get divisor from flags in ieee80211_calculate_rx_timestamp
* use sdata instead of local for sta_get_rates
* don't access hw.conf (this would break chandef drivers)
* put similar bitrate parsing functions into ieee80211_parse_bitrates()
---
net/mac80211/cfg.c | 45 +++++--------
net/mac80211/ibss.c | 81 ++++++++++++++++------
net/mac80211/ieee80211_i.h | 7 +-
net/mac80211/mesh.c | 3 +-
net/mac80211/mesh_plink.c | 2 +-
net/mac80211/mlme.c | 95 ++++++++++++++------------
net/mac80211/rate.c | 50 +++++++-------
net/mac80211/rx.c | 7 +-
net/mac80211/scan.c | 27 +++++++-
net/mac80211/status.c | 17 +++--
net/mac80211/tx.c | 21 ++++--
net/mac80211/util.c | 159 +++++++++++++++++++++++++++++++++++---------
12 files changed, 353 insertions(+), 161 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 8184d12..b82fff6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -395,9 +395,13 @@ void sta_set_rate_info_tx(struct sta_info *sta,
rinfo->nss = ieee80211_rate_get_vht_nss(rate);
} else {
struct ieee80211_supported_band *sband;
+ int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
+ u16 brate;
+
sband = sta->local->hw.wiphy->bands[
ieee80211_get_sdata_band(sta->sdata)];
- rinfo->legacy = sband->bitrates[rate->idx].bitrate;
+ brate = sband->bitrates[rate->idx].bitrate;
+ rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
}
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
@@ -422,11 +426,13 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
rinfo->mcs = sta->last_rx_rate_idx;
} else {
struct ieee80211_supported_band *sband;
+ int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
+ u16 brate;
sband = sta->local->hw.wiphy->bands[
ieee80211_get_sdata_band(sta->sdata)];
- rinfo->legacy =
- sband->bitrates[sta->last_rx_rate_idx].bitrate;
+ brate = sband->bitrates[sta->last_rx_rate_idx].bitrate;
+ rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
}
if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
@@ -1190,8 +1196,6 @@ static int sta_apply_parameters(struct ieee80211_local *local,
struct station_parameters *params)
{
int ret = 0;
- u32 rates;
- int i, j;
struct ieee80211_supported_band *sband;
struct ieee80211_sub_if_data *sdata = sta->sdata;
enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
@@ -1284,16 +1288,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
sta->listen_interval = params->listen_interval;
if (params->supported_rates) {
- rates = 0;
-
- for (i = 0; i < params->supported_rates_len; i++) {
- int rate = (params->supported_rates[i] & 0x7f) * 5;
- for (j = 0; j < sband->n_bitrates; j++) {
- if (sband->bitrates[j].bitrate == rate)
- rates |= BIT(j);
- }
- }
- sta->sta.supp_rates[band] = rates;
+ ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
+ sband, params->supported_rates,
+ params->supported_rates_len,
+ &sta->sta.supp_rates[band]);
}
if (params->ht_capa)
@@ -1956,18 +1954,11 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
}
if (params->basic_rates) {
- int i, j;
- u32 rates = 0;
- struct ieee80211_supported_band *sband = wiphy->bands[band];
-
- for (i = 0; i < params->basic_rates_len; i++) {
- int rate = (params->basic_rates[i] & 0x7f) * 5;
- for (j = 0; j < sband->n_bitrates; j++) {
- if (sband->bitrates[j].bitrate == rate)
- rates |= BIT(j);
- }
- }
- sdata->vif.bss_conf.basic_rates = rates;
+ ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
+ wiphy->bands[band],
+ params->basic_rates,
+ params->basic_rates_len,
+ &sdata->vif.bss_conf.basic_rates);
changed |= BSS_CHANGED_BASIC_RATES;
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index ea7b9c2..e9ec3e6 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -43,16 +43,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
- int rates, i;
+ int rates_n = 0, i, ri;
struct ieee80211_mgmt *mgmt;
u8 *pos;
struct ieee80211_supported_band *sband;
struct cfg80211_bss *bss;
- u32 bss_change;
+ u32 bss_change, rate_flags, rates = 0, rates_added = 0;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
struct cfg80211_chan_def chandef;
struct beacon_data *presp;
int frame_len;
+ int shift;
sdata_assert_lock(sdata);
@@ -99,6 +100,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
memcpy(ifibss->bssid, bssid, ETH_ALEN);
sband = local->hw.wiphy->bands[chan->band];
+ shift = ieee80211_vif_get_shift(&sdata->vif);
/* Build IBSS probe response */
frame_len = sizeof(struct ieee80211_hdr_3addr) +
@@ -134,15 +136,29 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
memcpy(pos, ifibss->ssid, ifibss->ssid_len);
pos += ifibss->ssid_len;
- rates = min_t(int, 8, sband->n_bitrates);
+ rate_flags = ieee80211_chandef_rate_flags(&chandef);
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ continue;
+
+ rates |= BIT(i);
+ rates_n++;
+ }
+
*pos++ = WLAN_EID_SUPP_RATES;
- *pos++ = rates;
- for (i = 0; i < rates; i++) {
- int rate = sband->bitrates[i].bitrate;
+ *pos++ = min_t(int, 8, rates_n);
+ for (ri = 0; ri < sband->n_bitrates; ri++) {
+ int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
+ 5 * (1 << shift));
u8 basic = 0;
- if (basic_rates & BIT(i))
+ if (!(rates & BIT(ri)))
+ continue;
+
+ if (basic_rates & BIT(ri))
basic = 0x80;
- *pos++ = basic | (u8) (rate / 5);
+ *pos++ = basic | (u8) rate;
+ if (++rates_added == 8)
+ break;
}
if (sband->band == IEEE80211_BAND_2GHZ) {
@@ -157,15 +173,20 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
*pos++ = 0;
*pos++ = 0;
- if (sband->n_bitrates > 8) {
+ /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */
+ if (rates_n > 8) {
*pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos++ = sband->n_bitrates - 8;
- for (i = 8; i < sband->n_bitrates; i++) {
- int rate = sband->bitrates[i].bitrate;
+ *pos++ = rates_n - 8;
+ for (; ri < sband->n_bitrates; ri++) {
+ int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
+ 5 * (1 << shift));
u8 basic = 0;
- if (basic_rates & BIT(i))
+ if (!(rates & BIT(ri)))
+ continue;
+
+ if (basic_rates & BIT(ri))
basic = 0x80;
- *pos++ = basic | (u8) (rate / 5);
+ *pos++ = basic | (u8) rate;
}
}
@@ -240,7 +261,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.ibss_creator = creator;
ieee80211_bss_info_change_notify(sdata, bss_change);
- ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
+ ieee80211_sta_def_wmm_params(sdata, rates, supp_rates);
ifibss->state = IEEE80211_IBSS_MLME_JOINED;
mod_timer(&ifibss->timer,
@@ -264,6 +285,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
u16 beacon_int = cbss->beacon_interval;
const struct cfg80211_bss_ies *ies;
u64 tsf;
+ u32 rate_flags;
+ int shift;
sdata_assert_lock(sdata);
@@ -271,15 +294,24 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
beacon_int = 10;
sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
+ rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef);
+ shift = ieee80211_vif_get_shift(&sdata->vif);
basic_rates = 0;
for (i = 0; i < bss->supp_rates_len; i++) {
- int rate = (bss->supp_rates[i] & 0x7f) * 5;
+ int rate = bss->supp_rates[i] & 0x7f;
bool is_basic = !!(bss->supp_rates[i] & 0x80);
for (j = 0; j < sband->n_bitrates; j++) {
- if (sband->bitrates[j].bitrate == rate) {
+ int brate;
+ if ((rate_flags & sband->bitrates[j].flags)
+ != rate_flags)
+ continue;
+
+ brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
+ 5 * (1 << shift));
+ if (brate == rate) {
if (is_basic)
basic_rates |= BIT(j);
break;
@@ -461,7 +493,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, mgmt->sa);
if (elems->supp_rates) {
- supp_rates = ieee80211_sta_get_rates(local, elems,
+ supp_rates = ieee80211_sta_get_rates(sdata, elems,
band, NULL);
if (sta) {
u32 prev_rates;
@@ -585,7 +617,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
"beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n",
mgmt->bssid);
ieee80211_sta_join_ibss(sdata, bss);
- supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);
+ supp_rates = ieee80211_sta_get_rates(sdata, elems, band, NULL);
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
supp_rates);
rcu_read_unlock();
@@ -1020,6 +1052,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct cfg80211_ibss_params *params)
{
u32 changed = 0;
+ u32 rate_flags;
+ struct ieee80211_supported_band *sband;
+ int i;
if (params->bssid) {
memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
@@ -1030,6 +1065,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.privacy = params->privacy;
sdata->u.ibss.control_port = params->control_port;
sdata->u.ibss.basic_rates = params->basic_rates;
+
+ /* fix basic_rates if channel does not support these rates */
+ rate_flags = ieee80211_chandef_rate_flags(¶ms->chandef);
+ sband = sdata->local->hw.wiphy->bands[params->chandef.chan->band];
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ sdata->u.ibss.basic_rates &= ~BIT(i);
+ }
memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
sizeof(params->mcast_rate));
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d0bd15d..55d57f9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1598,7 +1598,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
size_t buffer_len, const u8 *ie, size_t ie_len,
enum ieee80211_band band, u32 rate_mask,
- u8 channel);
+ struct cfg80211_chan_def *chandef);
struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
u8 *dst, u32 ratemask,
struct ieee80211_channel *chan,
@@ -1614,7 +1614,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
const size_t supp_rates_len,
const u8 *supp_rates);
-u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
+u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems,
enum ieee80211_band band, u32 *basic_rates);
int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
@@ -1631,6 +1631,9 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
u16 prot_mode);
u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u32 cap);
+int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
+ const struct ieee80211_supported_band *sband,
+ const u8 *srates, int srates_len, u32 *rates);
int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, bool need_basic,
enum ieee80211_band band);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 447f41b..e536f22 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -62,7 +62,6 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *ie)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- struct ieee80211_local *local = sdata->local;
u32 basic_rates = 0;
struct cfg80211_chan_def sta_chan_def;
@@ -85,7 +84,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
(ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
return false;
- ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata),
+ ieee80211_sta_get_rates(sdata, ie, ieee80211_get_sdata_band(sdata),
&basic_rates);
if (sdata->vif.bss_conf.basic_rates != basic_rates)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 02c05fa..6b65d50 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -379,7 +379,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
u32 rates, basic_rates = 0, changed = 0;
sband = local->hw.wiphy->bands[band];
- rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates);
+ rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
spin_lock_bh(&sta->lock);
sta->last_rx = jiffies;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ae31968..f7552c2 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -478,27 +478,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
/* frame sending functions */
-static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
- struct ieee80211_supported_band *sband,
- u32 *rates)
-{
- int i, j, count;
- *rates = 0;
- count = 0;
- for (i = 0; i < supp_rates_len; i++) {
- int rate = (supp_rates[i] & 0x7F) * 5;
-
- for (j = 0; j < sband->n_bitrates; j++)
- if (sband->bitrates[j].bitrate == rate) {
- *rates |= BIT(j);
- count++;
- break;
- }
- }
-
- return count;
-}
-
static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, u8 ap_ht_param,
struct ieee80211_supported_band *sband,
@@ -617,12 +596,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
struct ieee80211_mgmt *mgmt;
u8 *pos, qos_info;
size_t offset = 0, noffset;
- int i, count, rates_len, supp_rates_len;
+ int i, count, rates_len, supp_rates_len, shift;
u16 capab;
struct ieee80211_supported_band *sband;
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_channel *chan;
- u32 rates = 0;
+ u32 rate_flags, rates = 0;
sdata_assert_lock(sdata);
@@ -633,8 +612,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
return;
}
chan = chanctx_conf->def.chan;
+ rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
rcu_read_unlock();
sband = local->hw.wiphy->bands[chan->band];
+ shift = ieee80211_vif_get_shift(&sdata->vif);
if (assoc_data->supp_rates_len) {
/*
@@ -643,17 +624,24 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
* in the association request (e.g. D-Link DAP 1353 in
* b-only mode)...
*/
- rates_len = ieee80211_compatible_rates(assoc_data->supp_rates,
- assoc_data->supp_rates_len,
- sband, &rates);
+ rates_len = ieee80211_parse_bitrates(&chanctx_conf->def, sband,
+ assoc_data->supp_rates,
+ assoc_data->supp_rates_len,
+ &rates);
} else {
/*
* In case AP not provide any supported rates information
* before association, we send information element(s) with
* all rates that we support.
*/
- rates = ~0;
- rates_len = sband->n_bitrates;
+ rates_len = 0;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((rate_flags & sband->bitrates[i].flags)
+ != rate_flags)
+ continue;
+ rates |= BIT(i);
+ rates_len++;
+ }
}
skb = alloc_skb(local->hw.extra_tx_headroom +
@@ -730,8 +718,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
count = 0;
for (i = 0; i < sband->n_bitrates; i++) {
if (BIT(i) & rates) {
- int rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
+ int rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
+ 5 * (1 << shift));
+ *pos++ = (u8) rate;
if (++count == 8)
break;
}
@@ -744,8 +733,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
for (i++; i < sband->n_bitrates; i++) {
if (BIT(i) & rates) {
- int rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
+ int rate;
+ rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
+ 5 * (1 << shift));
+ *pos++ = (u8) rate;
}
}
}
@@ -2432,15 +2423,16 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
u8 *supp_rates, unsigned int supp_rates_len,
u32 *rates, u32 *basic_rates,
bool *have_higher_than_11mbit,
- int *min_rate, int *min_rate_index)
+ int *min_rate, int *min_rate_index,
+ int shift, u32 rate_flags)
{
int i, j;
for (i = 0; i < supp_rates_len; i++) {
- int rate = (supp_rates[i] & 0x7f) * 5;
+ int rate = supp_rates[i] & 0x7f;
bool is_basic = !!(supp_rates[i] & 0x80);
- if (rate > 110)
+ if ((rate * 5 * (1 << shift)) > 110)
*have_higher_than_11mbit = true;
/*
@@ -2456,12 +2448,20 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
continue;
for (j = 0; j < sband->n_bitrates; j++) {
- if (sband->bitrates[j].bitrate == rate) {
+ struct ieee80211_rate *br;
+ int brate;
+
+ br = &sband->bitrates[j];
+ if ((rate_flags & br->flags) != rate_flags)
+ continue;
+
+ brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
+ if (brate == rate) {
*rates |= BIT(j);
if (is_basic)
*basic_rates |= BIT(j);
- if (rate < *min_rate) {
- *min_rate = rate;
+ if ((rate * 5) < *min_rate) {
+ *min_rate = rate * 5;
*min_rate_index = j;
}
break;
@@ -3884,27 +3884,40 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
if (!new_sta)
return -ENOMEM;
}
-
if (new_sta) {
u32 rates = 0, basic_rates = 0;
bool have_higher_than_11mbit;
int min_rate = INT_MAX, min_rate_index = -1;
+ struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_supported_band *sband;
const struct cfg80211_bss_ies *ies;
+ int shift;
+ u32 rate_flags;
sband = local->hw.wiphy->bands[cbss->channel->band];
err = ieee80211_prep_channel(sdata, cbss);
if (err) {
sta_info_free(local, new_sta);
- return err;
+ return -EINVAL;
}
+ shift = ieee80211_vif_get_shift(&sdata->vif);
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ rcu_read_unlock();
+ return -EINVAL;
+ }
+ rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
+ rcu_read_unlock();
ieee80211_get_rates(sband, bss->supp_rates,
bss->supp_rates_len,
&rates, &basic_rates,
&have_higher_than_11mbit,
- &min_rate, &min_rate_index);
+ &min_rate, &min_rate_index,
+ shift, rate_flags);
/*
* This used to be a workaround for basic rates missing
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 30d58d2..ba63ac8 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -232,37 +232,28 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
/* could not find a basic rate; use original selection */
}
-static inline s8
-rate_lowest_non_cck_index(struct ieee80211_supported_band *sband,
- struct ieee80211_sta *sta)
-{
- int i;
-
- for (i = 0; i < sband->n_bitrates; i++) {
- struct ieee80211_rate *srate = &sband->bitrates[i];
- if ((srate->bitrate == 10) || (srate->bitrate == 20) ||
- (srate->bitrate == 55) || (srate->bitrate == 110))
- continue;
-
- if (rate_supported(sta, sband->band, i))
- return i;
- }
-
- /* No matching rate found */
- return 0;
-}
-
static void __rate_control_send_low(struct ieee80211_hw *hw,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta,
struct ieee80211_tx_info *info)
{
- if ((sband->band != IEEE80211_BAND_2GHZ) ||
- !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
- else
- info->control.rates[0].idx =
- rate_lowest_non_cck_index(sband, sta);
+ int i;
+ u32 rate_flags =
+ ieee80211_chandef_rate_flags(&hw->conf.chandef);
+
+ if ((sband->band == IEEE80211_BAND_2GHZ) &&
+ (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
+ rate_flags |= IEEE80211_RATE_ERP_G;
+
+ info->control.rates[0].idx = 0;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if (!rate_supported(sta, sband->band, i))
+ continue;
+
+ info->control.rates[0].idx = i;
+ break;
+ }
+ WARN_ON_ONCE(i == sband->n_bitrates);
info->control.rates[0].count =
(info->flags & IEEE80211_TX_CTL_NO_ACK) ?
@@ -585,6 +576,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
bool has_mcs_mask;
u32 mask;
+ u32 rate_flags;
int i;
/*
@@ -594,6 +586,12 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
*/
mask = sdata->rc_rateidx_mask[info->band];
has_mcs_mask = sdata->rc_has_mcs_mask[info->band];
+ rate_flags =
+ ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
+ for (i = 0; i < sband->n_bitrates; i++)
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ mask &= ~BIT(i);
+
if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask)
return;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5f02aba..e62aca1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -208,8 +208,13 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
*/
*pos = 0;
} else {
+ int shift = 0;
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
- *pos = rate->bitrate / 5;
+ if (status->flag & RX_FLAG_10MHZ)
+ shift = 1;
+ else if (status->flag & RX_FLAG_5MHZ)
+ shift = 2;
+ *pos = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
}
pos++;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 1b122a7..819d095 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -204,10 +204,29 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
ieee80211_rx_bss_put(local, bss);
}
+static void
+ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef,
+ enum nl80211_bss_scan_width scan_width)
+{
+ memset(chandef, 0, sizeof(*chandef));
+ switch (scan_width) {
+ case NL80211_BSS_CHAN_WIDTH_5:
+ chandef->width = NL80211_CHAN_WIDTH_5;
+ break;
+ case NL80211_BSS_CHAN_WIDTH_10:
+ chandef->width = NL80211_CHAN_WIDTH_10;
+ break;
+ default:
+ chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
+ break;
+ }
+}
+
/* return false if no more work */
static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
{
struct cfg80211_scan_request *req = local->scan_req;
+ struct cfg80211_chan_def chandef;
enum ieee80211_band band;
int i, ielen, n_chans;
@@ -229,11 +248,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
} while (!n_chans);
local->hw_scan_req->n_channels = n_chans;
+ ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
local->hw_scan_ies_bufsize,
req->ie, req->ie_len, band,
- req->rates[band], 0);
+ req->rates[band], &chandef);
local->hw_scan_req->ie_len = ielen;
local->hw_scan_req->no_cck = req->no_cck;
@@ -912,6 +932,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_sched_scan_ies sched_scan_ies = {};
+ struct cfg80211_chan_def chandef;
int ret, i, iebufsz;
iebufsz = 2 + IEEE80211_MAX_SSID_LEN +
@@ -939,10 +960,12 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
goto out_free;
}
+ ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
+
sched_scan_ies.len[i] =
ieee80211_build_preq_ies(local, sched_scan_ies.ie[i],
iebufsz, req->ie, req->ie_len,
- i, (u32) -1, 0);
+ i, (u32) -1, &chandef);
}
ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 4343920..a449664 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -252,9 +252,11 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
return len;
}
-static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
- *sband, struct sk_buff *skb,
- int retry_count, int rtap_len)
+static void
+ieee80211_add_tx_radiotap_header(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
+ struct sk_buff *skb, int retry_count,
+ int rtap_len)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -280,8 +282,12 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
/* IEEE80211_RADIOTAP_RATE */
if (info->status.rates[0].idx >= 0 &&
!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
+ int shift = ieee80211_vif_get_shift(&sdata->vif);
+ int rate;
+
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
- *pos = sband->bitrates[info->status.rates[0].idx].bitrate / 5;
+ rate = sband->bitrates[info->status.rates[0].idx].bitrate;
+ *pos = DIV_ROUND_UP(rate, 5 * (1 << shift));
/* padding for tx flags */
pos += 2;
}
@@ -624,7 +630,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb(skb);
return;
}
- ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len);
+ ieee80211_add_tx_radiotap_header(sdata, sband, skb, retry_count,
+ rtap_len);
/* XXX: is this sufficient for BPF? */
skb_set_mac_header(skb, 0);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3523daa..f82301b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -40,12 +40,22 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
struct sk_buff *skb, int group_addr,
int next_frag_len)
{
- int rate, mrate, erp, dur, i, shift;
+ int rate, mrate, erp, dur, i, shift = 0;
struct ieee80211_rate *txrate;
struct ieee80211_local *local = tx->local;
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ u32 rate_flags = 0;
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf);
+ if (chanctx_conf) {
+ shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
+ rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
+ }
+ rcu_read_unlock();
/* assume HW handles this */
if (tx->rate.flags & IEEE80211_TX_RC_MCS)
@@ -122,8 +132,11 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
if (r->bitrate > txrate->bitrate)
break;
+ if ((rate_flags & r->flags) != rate_flags)
+ continue;
+
if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
- rate = r->bitrate;
+ rate = DIV_ROUND_UP(r->bitrate, 1 << shift);
switch (sband->band) {
case IEEE80211_BAND_2GHZ: {
@@ -150,11 +163,9 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
if (rate == -1) {
/* No matching basic rate found; use highest suitable mandatory
* PHY rate */
- rate = mrate;
+ rate = DIV_ROUND_UP(mrate, 1 << shift);
}
- shift = ieee80211_vif_get_shift(&tx->sdata->vif);
-
/* Don't calculate ACKs for QoS Frames with NoAck Policy set */
if (ieee80211_is_data_qos(hdr->frame_control) &&
*(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 61856e1..1e45891c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -141,14 +141,18 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
dur = 16; /* SIFS + signal ext */
dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */
- dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
- 4 * rate); /* T_SYM x N_SYM */
/* IEEE 802.11-2012 18.3.2.4: all values above are:
* * times 4 for 5 MHz
* * times 2 for 10 MHz
*/
dur *= 1 << shift;
+
+ /* rates should already consider the channel bandwidth,
+ * don't apply divisor again.
+ */
+ dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
+ 4 * rate); /* T_SYM x N_SYM */
} else {
/*
* 802.11b or 802.11g with 802.11b compatibility:
@@ -205,7 +209,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata;
bool short_preamble;
- int erp, shift = 0;
+ int erp, shift = 0, bitrate;
u16 dur;
struct ieee80211_supported_band *sband;
@@ -224,14 +228,16 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
shift = ieee80211_vif_get_shift(vif);
}
+ bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
+
/* CTS duration */
- dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate,
+ dur = ieee80211_frame_duration(sband->band, 10, bitrate,
erp, short_preamble, shift);
/* Data frame duration */
- dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate,
+ dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
erp, short_preamble, shift);
/* ACK duration */
- dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate,
+ dur += ieee80211_frame_duration(sband->band, 10, bitrate,
erp, short_preamble, shift);
return cpu_to_le16(dur);
@@ -247,7 +253,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata;
bool short_preamble;
- int erp, shift = 0;
+ int erp, shift = 0, bitrate;
u16 dur;
struct ieee80211_supported_band *sband;
@@ -265,12 +271,14 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
shift = ieee80211_vif_get_shift(vif);
}
+ bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
+
/* Data frame duration */
- dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate,
+ dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
erp, short_preamble, shift);
if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
/* ACK duration */
- dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate,
+ dur += ieee80211_frame_duration(sband->band, 10, bitrate,
erp, short_preamble, shift);
}
@@ -1175,7 +1183,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
size_t buffer_len, const u8 *ie, size_t ie_len,
enum ieee80211_band band, u32 rate_mask,
- u8 channel)
+ struct cfg80211_chan_def *chandef)
{
struct ieee80211_supported_band *sband;
u8 *pos = buffer, *end = buffer + buffer_len;
@@ -1184,16 +1192,26 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
u8 rates[32];
int num_rates;
int ext_rates_len;
+ int shift;
+ u32 rate_flags;
sband = local->hw.wiphy->bands[band];
if (WARN_ON_ONCE(!sband))
return 0;
+ rate_flags = ieee80211_chandef_rate_flags(chandef);
+ shift = ieee80211_chandef_get_shift(chandef);
+
num_rates = 0;
for (i = 0; i < sband->n_bitrates; i++) {
if ((BIT(i) & rate_mask) == 0)
continue; /* skip rate */
- rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5);
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ continue;
+
+ rates[num_rates++] =
+ (u8) DIV_ROUND_UP(sband->bitrates[i].bitrate,
+ (1 << shift) * 5);
}
supp_rates_len = min_t(int, num_rates, 8);
@@ -1233,12 +1251,13 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
pos += ext_rates_len;
}
- if (channel && sband->band == IEEE80211_BAND_2GHZ) {
+ if (chandef->chan && sband->band == IEEE80211_BAND_2GHZ) {
if (end - pos < 3)
goto out_err;
*pos++ = WLAN_EID_DS_PARAMS;
*pos++ = 1;
- *pos++ = channel;
+ *pos++ = ieee80211_frequency_to_channel(
+ chandef->chan->center_freq);
}
/* insert custom IEs that go before HT */
@@ -1303,9 +1322,9 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
bool directed)
{
struct ieee80211_local *local = sdata->local;
+ struct cfg80211_chan_def chandef;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
- u8 chan_no;
int ies_len;
/*
@@ -1313,10 +1332,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
* in order to maximize the chance that we get a response. Some
* badly-behaved APs don't respond when this parameter is included.
*/
+ chandef.width = sdata->vif.bss_conf.chandef.width;
if (directed)
- chan_no = 0;
+ chandef.chan = NULL;
else
- chan_no = ieee80211_frequency_to_channel(chan->center_freq);
+ chandef.chan = chan;
skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
ssid, ssid_len, 100 + ie_len);
@@ -1326,7 +1346,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
skb_tailroom(skb),
ie, ie_len, chan->band,
- ratemask, chan_no);
+ ratemask, &chandef);
skb_put(skb, ies_len);
if (dst) {
@@ -1360,16 +1380,19 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
}
}
-u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
+u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems,
enum ieee80211_band band, u32 *basic_rates)
{
struct ieee80211_supported_band *sband;
struct ieee80211_rate *bitrates;
size_t num_rates;
- u32 supp_rates;
- int i, j;
- sband = local->hw.wiphy->bands[band];
+ u32 supp_rates, rate_flags;
+ int i, j, shift;
+ sband = sdata->local->hw.wiphy->bands[band];
+
+ rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
+ shift = ieee80211_vif_get_shift(&sdata->vif);
if (WARN_ON(!sband))
return 1;
@@ -1394,7 +1417,15 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
continue;
for (j = 0; j < num_rates; j++) {
- if (bitrates[j].bitrate == own_rate) {
+ int brate;
+ if ((rate_flags & sband->bitrates[j].flags)
+ != rate_flags)
+ continue;
+
+ brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
+ 1 << shift);
+
+ if (brate == own_rate) {
supp_rates |= BIT(j);
if (basic_rates && is_basic)
*basic_rates |= BIT(j);
@@ -2017,18 +2048,56 @@ void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
cfg80211_chandef_create(chandef, control_chan, channel_type);
}
+int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
+ const struct ieee80211_supported_band *sband,
+ const u8 *srates, int srates_len, u32 *rates)
+{
+ u32 rate_flags = ieee80211_chandef_rate_flags(chandef);
+ int shift = ieee80211_chandef_get_shift(chandef);
+ struct ieee80211_rate *br;
+ int brate, rate, i, j, count = 0;
+
+ *rates = 0;
+
+ for (i = 0; i < srates_len; i++) {
+ rate = srates[i] & 0x7f;
+
+ for (j = 0; j < sband->n_bitrates; j++) {
+ br = &sband->bitrates[j];
+ if ((rate_flags & br->flags) != rate_flags)
+ continue;
+
+ brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
+ if (brate == rate) {
+ *rates |= BIT(j);
+ count++;
+ break;
+ }
+ }
+ }
+ return count;
+}
+
int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, bool need_basic,
enum ieee80211_band band)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband;
- int rate;
+ int rate, shift;
u8 i, rates, *pos;
u32 basic_rates = sdata->vif.bss_conf.basic_rates;
+ u32 rate_flags;
+ shift = ieee80211_vif_get_shift(&sdata->vif);
+ rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
sband = local->hw.wiphy->bands[band];
- rates = sband->n_bitrates;
+ rates = 0;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ continue;
+ rates++;
+ }
if (rates > 8)
rates = 8;
@@ -2040,10 +2109,15 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
*pos++ = rates;
for (i = 0; i < rates; i++) {
u8 basic = 0;
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ continue;
+
if (need_basic && basic_rates & BIT(i))
basic = 0x80;
rate = sband->bitrates[i].bitrate;
- *pos++ = basic | (u8) (rate / 5);
+ rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
+ 5 * (1 << shift));
+ *pos++ = basic | (u8) rate;
}
return 0;
@@ -2055,12 +2129,22 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband;
- int rate;
+ int rate, skip, shift;
u8 i, exrates, *pos;
u32 basic_rates = sdata->vif.bss_conf.basic_rates;
+ u32 rate_flags;
+
+ rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
+ shift = ieee80211_vif_get_shift(&sdata->vif);
sband = local->hw.wiphy->bands[band];
- exrates = sband->n_bitrates;
+ exrates = 0;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+ continue;
+ exrates++;
+ }
+
if (exrates > 8)
exrates -= 8;
else
@@ -2073,12 +2157,19 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
pos = skb_put(skb, exrates + 2);
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos++ = exrates;
+ skip = 0;
for (i = 8; i < sband->n_bitrates; i++) {
u8 basic = 0;
+ if ((rate_flags & sband->bitrates[i].flags)
+ != rate_flags)
+ continue;
+ if (skip++ < 8)
+ continue;
if (need_basic && basic_rates & BIT(i))
basic = 0x80;
- rate = sband->bitrates[i].bitrate;
- *pos++ = basic | (u8) (rate / 5);
+ rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
+ 5 * (1 << shift));
+ *pos++ = basic | (u8) rate;
}
}
return 0;
@@ -2162,9 +2253,17 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
} else {
struct ieee80211_supported_band *sband;
+ int shift = 0;
+ int bitrate;
+
+ if (status->flag & RX_FLAG_10MHZ)
+ shift = 1;
+ if (status->flag & RX_FLAG_5MHZ)
+ shift = 2;
sband = local->hw.wiphy->bands[status->band];
- ri.legacy = sband->bitrates[status->rate_idx].bitrate;
+ bitrate = sband->bitrates[status->rate_idx].bitrate;
+ ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
}
rate = cfg80211_calculate_bitrate(&ri);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 08/18] mac80211: allow scanning for 5/10 MHz channels in IBSS
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Use a chandef instead of just the channel for scanning, and enable
5/10 Mhz scanning for IBSS mode. Also reporting is changed to the new
inform_bss functions.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv4:
* fix comments
---
net/mac80211/ibss.c | 16 ++++++++++++----
net/mac80211/ieee80211_i.h | 5 +++--
net/mac80211/main.c | 13 ++-----------
net/mac80211/scan.c | 45 ++++++++++++++++++++++++++++++++++++++------
4 files changed, 56 insertions(+), 23 deletions(-)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 7fb0f2a..b99d948 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -51,6 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
u32 bss_change, rate_flags, rates = 0, rates_added = 0;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
struct cfg80211_chan_def chandef;
+ enum nl80211_bss_scan_width scan_width;
struct beacon_data *presp;
int frame_len;
int shift;
@@ -267,8 +268,10 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
mod_timer(&ifibss->timer,
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
- bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan,
- mgmt, presp->head_len, 0, GFP_KERNEL);
+ scan_width = cfg80211_chandef_to_scan_width(&chandef);
+ bss = cfg80211_inform_bss_width_frame(local->hw.wiphy, chan,
+ scan_width, mgmt,
+ presp->head_len, 0, GFP_KERNEL);
cfg80211_put_bss(local->hw.wiphy, bss);
netif_carrier_on(sdata->dev);
cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
@@ -722,6 +725,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+ enum nl80211_bss_scan_width scan_width;
sdata_assert_lock(sdata);
@@ -743,8 +747,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
sdata_info(sdata,
"No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
+ scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
- NULL);
+ NULL, scan_width);
}
static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -794,6 +799,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
struct cfg80211_bss *cbss;
struct ieee80211_channel *chan = NULL;
const u8 *bssid = NULL;
+ enum nl80211_bss_scan_width scan_width;
int active_ibss;
u16 capability;
@@ -842,8 +848,10 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
IEEE80211_SCAN_INTERVAL)) {
sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
+ scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
ieee80211_request_ibss_scan(sdata, ifibss->ssid,
- ifibss->ssid_len, chan);
+ ifibss->ssid_len, chan,
+ scan_width);
} else {
int interval = IEEE80211_SCAN_INTERVAL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 55d57f9..0aea73f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1054,7 +1054,7 @@ struct ieee80211_local {
struct cfg80211_ssid scan_ssid;
struct cfg80211_scan_request *int_scan_req;
struct cfg80211_scan_request *scan_req, *hw_scan_req;
- struct ieee80211_channel *scan_channel;
+ struct cfg80211_chan_def scan_chandef;
enum ieee80211_band hw_scan_band;
int scan_channel_idx;
int scan_ies_len;
@@ -1334,7 +1334,8 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
void ieee80211_scan_work(struct work_struct *work);
int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
const u8 *ssid, u8 ssid_len,
- struct ieee80211_channel *chan);
+ struct ieee80211_channel *chan,
+ enum nl80211_bss_scan_width scan_width);
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
struct cfg80211_scan_request *req);
void ieee80211_scan_cancel(struct ieee80211_local *local);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a1d51af..3e00871 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -102,17 +102,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
- if (local->scan_channel) {
- chandef.chan = local->scan_channel;
- /* If scanning on oper channel, use whatever channel-type
- * is currently in use.
- */
- if (chandef.chan == local->_oper_chandef.chan) {
- chandef = local->_oper_chandef;
- } else {
- chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
- chandef.center_freq1 = chandef.chan->center_freq;
- }
+ if (local->scan_chandef.chan) {
+ chandef = local->scan_chandef;
} else if (local->tmp_channel) {
chandef.chan = local->tmp_channel;
chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 819d095..08afe74 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -66,6 +66,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
struct cfg80211_bss *cbss;
struct ieee80211_bss *bss;
int clen, srlen;
+ enum nl80211_bss_scan_width scan_width;
s32 signal = 0;
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
@@ -73,8 +74,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
signal = (rx_status->signal * 100) / local->hw.max_signal;
- cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
- mgmt, len, signal, GFP_ATOMIC);
+ scan_width = NL80211_BSS_CHAN_WIDTH_20;
+ if (rx_status->flag & RX_FLAG_5MHZ)
+ scan_width = NL80211_BSS_CHAN_WIDTH_5;
+ if (rx_status->flag & RX_FLAG_10MHZ)
+ scan_width = NL80211_BSS_CHAN_WIDTH_10;
+
+ cbss = cfg80211_inform_bss_width_frame(local->hw.wiphy, channel,
+ scan_width, mgmt, len, signal,
+ GFP_ATOMIC);
if (!cbss)
return NULL;
@@ -300,7 +308,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
rcu_assign_pointer(local->scan_sdata, NULL);
local->scanning = 0;
- local->scan_channel = NULL;
+ local->scan_chandef.chan = NULL;
/* Set power back to normal operating levels. */
ieee80211_hw_config(local, 0);
@@ -635,11 +643,34 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
{
int skip;
struct ieee80211_channel *chan;
+ enum nl80211_bss_scan_width oper_scan_width;
skip = 0;
chan = local->scan_req->channels[local->scan_channel_idx];
- local->scan_channel = chan;
+ local->scan_chandef.chan = chan;
+ local->scan_chandef.center_freq1 = chan->center_freq;
+ local->scan_chandef.center_freq2 = 0;
+ switch (local->scan_req->scan_width) {
+ case NL80211_BSS_CHAN_WIDTH_5:
+ local->scan_chandef.width = NL80211_CHAN_WIDTH_5;
+ break;
+ case NL80211_BSS_CHAN_WIDTH_10:
+ local->scan_chandef.width = NL80211_CHAN_WIDTH_10;
+ break;
+ case NL80211_BSS_CHAN_WIDTH_20:
+ /* If scanning on oper channel, use whatever channel-type
+ * is currently in use.
+ */
+ oper_scan_width = cfg80211_chandef_to_scan_width(
+ &local->_oper_chandef);
+ if (chan == local->_oper_chandef.chan &&
+ oper_scan_width == local->scan_req->scan_width)
+ local->scan_chandef = local->_oper_chandef;
+ else
+ local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
+ break;
+ }
if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
skip = 1;
@@ -679,7 +710,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
unsigned long *next_delay)
{
/* switch back to the operating channel */
- local->scan_channel = NULL;
+ local->scan_chandef.chan = NULL;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
/* disable PS */
@@ -821,7 +852,8 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
const u8 *ssid, u8 ssid_len,
- struct ieee80211_channel *chan)
+ struct ieee80211_channel *chan,
+ enum nl80211_bss_scan_width scan_width)
{
struct ieee80211_local *local = sdata->local;
int ret = -EBUSY;
@@ -871,6 +903,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
local->int_scan_req->ssids = &local->scan_ssid;
local->int_scan_req->n_ssids = 1;
+ local->int_scan_req->scan_width = scan_width;
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
local->int_scan_req->ssids[0].ssid_len = ssid_len;
--
1.7.10.4
^ permalink raw reply related
* [PATCHv6 07/18] cfg80211/mac80211: use reduced txpower for 5 and 10 MHz
From: Simon Wunderlich @ 2013-07-08 14:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373295366-12823-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Some regulations (like germany, but also FCC) express their transmission
power limit in dBm/MHz or mW/MHz. To cope with that and be on the safe
side, reduce the maximum power to half (10 MHz) or quarter (5 MHz)
when operating on these reduced bandwidth channels.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv3:
* consider max_reg_power, max_power might contain the hardware limit
---
include/net/cfg80211.h | 27 +++++++++++++++++++++++++++
net/mac80211/iface.c | 2 +-
net/mac80211/main.c | 2 +-
net/mac80211/mlme.c | 3 ++-
4 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4ca16ab..75471ee 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -461,6 +461,33 @@ ieee80211_chandef_rate_flags(struct cfg80211_chan_def *chandef)
}
/**
+ * ieee80211_chandef_max_power - maximum transmission power for the chandef
+ *
+ * In some regulations, the transmit power may depend on the configured channel
+ * bandwidth which may be defined as dBm/MHz. This function returns the actual
+ * max_power for non-standard (20 MHz) channels.
+ *
+ * @chandef: channel definition for the channel
+ *
+ * Returns: maximum allowed transmission power in dBm for the chandef
+ */
+static inline int
+ieee80211_chandef_max_power(struct cfg80211_chan_def *chandef)
+{
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_5:
+ return min(chandef->chan->max_reg_power - 6,
+ chandef->chan->max_power);
+ case NL80211_CHAN_WIDTH_10:
+ return min(chandef->chan->max_reg_power - 3,
+ chandef->chan->max_power);
+ default:
+ break;
+ }
+ return chandef->chan->max_power;
+}
+
+/**
* enum survey_info_flags - survey information flags
*
* @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index a2a8250..093c34a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -54,7 +54,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
return false;
}
- power = chanctx_conf->def.chan->max_power;
+ power = ieee80211_chandef_max_power(&chanctx_conf->def);
rcu_read_unlock();
if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 626c83c..a1d51af 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -151,7 +151,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
changed |= IEEE80211_CONF_CHANGE_SMPS;
}
- power = chandef.chan->max_power;
+ power = ieee80211_chandef_max_power(&chandef);
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f7552c2..211246b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -747,7 +747,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
*pos++ = WLAN_EID_PWR_CAPABILITY;
*pos++ = 2;
*pos++ = 0; /* min tx power */
- *pos++ = chan->max_power; /* max tx power */
+ /* max tx power */
+ *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def);
/* 2. supported channels */
/* TODO: get this in reg domain format */
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox