* Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j
From: Brian Prodoehl @ 2011-01-08 13:08 UTC (permalink / raw)
To: Bruno Randolf; +Cc: johannes, linville, linux-wireless
In-Reply-To: <201101081243.56629.br1@einfach.org>
On Fri, Jan 7, 2011 at 10:43 PM, Bruno Randolf <br1@einfach.org> wrote:
> On Friday 07 January 2011 21:53:25 Brian Prodoehl wrote:
>> > Do all drivers still build with this patch? I applied the previous
>> > RFC version of this patch to a late-December cut of compat-wireless,
>> > and had to touch the receive-handling code in a half-dozen or so
>> > drivers due to the API changes.
>
> I have to confess, I didn't check the drivers. Just tested with ath5k. Before
> this gets merged we have to fix all drivers which use these functions, true. I
> will try to do that next week...
>
>> Ah, I see. All the driver changes I needed were because
>> ieee80211_channel_to_frequency() changed with the RFC patch, and this
>> patch keeps ieee80211_channel_to_frequency() the same. Good stuff.
>
> Uh? This patch also changes ieee80211_channel_to_frequency(). Bad stuff. ;)
>
> bruno
I guess I saw what I wanted to see when I took a second look at the
re-posted patch. Here are compile-fixes to all the affected drivers.
The following drivers are affected: mwl8k, iwlwifi, iwmc3200wifi,
libertas, rt2x00, wl1251 and wl12xx. So I guess these driver fixes
need to be split into seven patches. I don't use any of these
drivers, so I can't really vouch for if I'm pulling the band the
correct way for each. I'm happy to split and submit, but I wouldn't
mind another set of eyes on these changes.
Index: compat-wireless-2011-01-07/drivers/net/wireless/mwl8k.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/mwl8k.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/mwl8k.c 2011-01-08
07:51:23.843290770 -0500
@@ -834,7 +834,7 @@
} else {
status->band = IEEE80211_BAND_2GHZ;
}
- status->freq = ieee80211_channel_to_frequency(rxd->channel);
+ status->freq = ieee80211_channel_to_frequency(rxd->channel, status->band);
*qos = rxd->qos_control;
@@ -931,7 +931,7 @@
} else {
status->band = IEEE80211_BAND_2GHZ;
}
- status->freq = ieee80211_channel_to_frequency(rxd->channel);
+ status->freq = ieee80211_channel_to_frequency(rxd->channel, status->band);
*qos = rxd->qos_control;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-3945.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-3945.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-3945.c 2011-01-08
07:51:23.867290769 -0500
@@ -594,10 +594,10 @@
rx_status.flag = 0;
rx_status.mactime = le64_to_cpu(rx_end->timestamp);
- rx_status.freq =
- ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ rx_status.freq =
+ ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), rx_status.band);
rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
if (rx_status.band == IEEE80211_BAND_5GHZ)
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-agn-lib.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-agn-lib.c 2011-01-08
07:51:23.883290769 -0500
@@ -1157,10 +1157,10 @@
/* rx_status carries information about the packet to mac80211 */
rx_status.mactime = le64_to_cpu(phy_res->timestamp);
- rx_status.freq =
- ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ rx_status.freq =
+ ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
rx_status.band);
rx_status.rate_idx =
iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
rx_status.flag = 0;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-core.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-core.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-core.c 2011-01-08
07:51:23.903290769 -0500
@@ -227,7 +227,10 @@
geo_ch = &sband->channels[sband->n_channels++];
geo_ch->center_freq =
- ieee80211_channel_to_frequency(ch->channel);
+ ieee80211_channel_to_frequency(ch->channel,
+ is_channel_a_band(ch) ?
+ IEEE80211_BAND_5GHZ :
+ IEEE80211_BAND_2GHZ);
geo_ch->max_power = ch->max_power_avg;
geo_ch->max_antenna_gain = 0xff;
geo_ch->hw_value = ch->channel;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwmc3200wifi/rx.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/rx.c 2011-01-08
07:51:23.919290769 -0500
@@ -536,6 +536,7 @@
struct ieee80211_channel *chan;
struct iwm_umac_notif_assoc_complete *complete =
(struct iwm_umac_notif_assoc_complete *)buf;
+ u8 band = complete->band;
IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
complete->bssid, complete->status);
@@ -543,7 +544,9 @@
switch (le32_to_cpu(complete->status)) {
case UMAC_ASSOC_COMPLETE_SUCCESS:
chan = ieee80211_get_channel(wiphy,
- ieee80211_channel_to_frequency(complete->channel));
+ ieee80211_channel_to_frequency(complete->channel,
+ (band == UMAC_BAND_2GHZ) ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
/* Associated to a unallowed channel, disassociate. */
__iwm_invalidate_mlme_profile(iwm);
@@ -841,7 +844,9 @@
goto err;
}
- freq = ieee80211_channel_to_frequency(umac_bss->channel);
+ freq = ieee80211_channel_to_frequency(umac_bss->channel,
+ umac_bss->band == UMAC_BAND_2GHZ ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
channel = ieee80211_get_channel(wiphy, freq);
signal = umac_bss->rssi * 100;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/cfg80211.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwmc3200wifi/cfg80211.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/cfg80211.c 2011-01-08
07:51:23.927290769 -0500
@@ -287,7 +287,9 @@
return -EINVAL;
}
- freq = ieee80211_channel_to_frequency(umac_bss->channel);
+ freq = ieee80211_channel_to_frequency(umac_bss->channel,
+ umac_bss->band == UMAC_BAND_2GHZ ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
channel = ieee80211_get_channel(wiphy, freq);
signal = umac_bss->rssi * 100;
Index: compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c 2011-01-08
07:51:23.947290769 -0500
@@ -607,7 +607,8 @@
/* No channel, no luck */
if (chan_no != -1) {
struct wiphy *wiphy = priv->wdev->wiphy;
- int freq = ieee80211_channel_to_frequency(chan_no);
+ int freq = ieee80211_channel_to_frequency(chan_no,
+ chan_no <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
struct ieee80211_channel *channel =
ieee80211_get_channel(wiphy, freq);
@@ -1597,7 +1598,8 @@
lbs_deb_enter(LBS_DEB_CFG80211);
survey->channel = ieee80211_get_channel(wiphy,
- ieee80211_channel_to_frequency(priv->channel));
+ ieee80211_channel_to_frequency(priv->channel,
+ priv->channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));
ret = lbs_get_rssi(priv, &signal, &noise);
if (ret == 0) {
Index: compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/rt2x00/rt2x00dev.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c 2011-01-08
07:51:23.971290769 -0500
@@ -649,7 +649,8 @@
const int channel, const int tx_power,
const int value)
{
- entry->center_freq = ieee80211_channel_to_frequency(channel);
+ entry->center_freq = ieee80211_channel_to_frequency(channel,
+ channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
entry->hw_value = value;
entry->max_power = tx_power;
entry->max_antenna_gain = 0xff;
Index: compat-wireless-2011-01-07/drivers/net/wireless/wl1251/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/wl1251/rx.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/wl1251/rx.c 2011-01-08
07:51:23.987290769 -0500
@@ -78,7 +78,7 @@
*/
wl->noise = desc->rssi - desc->snr / 2;
- status->freq = ieee80211_channel_to_frequency(desc->channel);
+ status->freq = ieee80211_channel_to_frequency(desc->channel, status->band);
status->flag |= RX_FLAG_TSFT;
Index: compat-wireless-2011-01-07/drivers/net/wireless/wl12xx/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/wl12xx/rx.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/wl12xx/rx.c 2011-01-08
07:51:24.003290769 -0500
@@ -76,7 +76,7 @@
*/
wl->noise = desc->rssi - (desc->snr >> 1);
- status->freq = ieee80211_channel_to_frequency(desc->channel);
+ status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band);
if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
^ permalink raw reply
* Re: hwcrypt issue with rt73usb
From: Helmut Schaa @ 2011-01-08 13:02 UTC (permalink / raw)
To: Andre Kuehne; +Cc: linux-wireless
In-Reply-To: <4D2850B8.7080107@gmx.net>
Am Samstag, 8. Januar 2011 schrieb Andre Kuehne:
> On #linux-wireless it was suggested to test with nohwcrypt and indeed after
>
> modprobe rt73usb nohwcrypt=1
>
> the connection worked fine again under kernel26-2.6.36.
Known issue. Please have a look at [1].
Helmut
[1] http://thread.gmane.org/gmane.linux.kernel.wireless.general
^ permalink raw reply
* hwcrypt issue with rt73usb
From: Andre Kuehne @ 2011-01-08 11:55 UTC (permalink / raw)
To: linux-wireless
Hi
I use a USB WLAN Stick (model: TP-LINK TL-WN321G) with hostapd.
With kernel26-2.6.36 this setup is not working anymore.
The interface is up and if I try to connect with another client
WPA handshake also seems to work, but the IP configuration via DHCP fails.
After downgrading to kernel26-2.6.35 the connection works fine again.
On #linux-wireless it was suggested to test with nohwcrypt and indeed after
modprobe rt73usb nohwcrypt=1
the connection worked fine again under kernel26-2.6.36.
> lsusb
...
Bus 001 Device 003: ID 148f:2573 Ralink Technology, Corp. RT2501/RT2573 Wireless Adapter
...
> lsmod
...
rt73usb 21779 0
rt2500usb 17334 0
rt2x00usb 7597 2 rt73usb,rt2500usb
rt2x00lib 25013 3 rt73usb,rt2500usb,rt2x00usb
mac80211 189270 2 rt2x00usb,rt2x00lib
cfg80211 144231 2 rt2x00lib,mac80211
...
> cat /etc/hostapd/hostapd.conf
...
interface=wlan0
bridge=br0
driver=nl80211
country_code=DE
ieee80211d=1
hw_mode=g
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
...
> grep hostap /var/log/messages.log
... authenticated
... associated (aid 1)
... RADIUS: starting accounting session 4CFD0763-000001A0
... WPA: pairwise key handshake completed (RSN)
...
Please let me know if you are interested in more details or if I could otherwise help in testing etc.
Best regards
Andre
^ permalink raw reply
* [PATCH] ipw2200: Check for -1 INTA in tasklet too.
From: Indan Zupancic @ 2011-01-08 11:17 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
This is an attempt to fix a long standing open bug:
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=1334
The interrupt handler checks for INTA being -1, apparently that means that the
hardware is gone. But the interrupt handler defers actual interrupt processing
to a tasklet. By the time the tasklet is run and checks INTA again, the
hardware might be gone and INTA be -1, which confuses the driver because all
event bits are set.
The patch applies to 2.6.37.
Signed-off-by: Indan Zupancic <indan@nul.nu>
---
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c
b/drivers/net/wireless/ipw2x00/ipw2200.c
index 8d6ed5f..ae438ed 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -1973,6 +1973,13 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
inta = ipw_read32(priv, IPW_INTA_RW);
inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
+
+ if (inta == 0xFFFFFFFF) {
+ /* Hardware disappeared */
+ IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n");
+ /* Only handle the cached INTA values */
+ inta = 0;
+ }
inta &= (IPW_INTA_MASK_ALL & inta_mask);
/* Add any cached INTA values that need to be handled */
^ permalink raw reply related
* Re: Kernel Panic wlc_mac80211.c Line 6093
From: Jamie Kitson @ 2011-01-08 10:44 UTC (permalink / raw)
To: Brett Rudley; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <7A94256FD72B884D9E7C55586C3CBCEE13CD2B113F@SJEXCHCCR01.corp.ad.broadcom.com>
> Hmm, haven't seen this type of crash before. Any special setup you are using?
Not that I can think of. I still have the Broadcom STA compiled wl
driver installed but disabled. I installed the brcm80211 driver from
Arch's AUR repository:
http://aur.archlinux.org/packages.php?ID=42670
I have recently been fiddling about with laptop-mode, but I don't
think that has caused it as that doesn't reproduce it and there's been
no obvious acpi event when it's crashed.
Cheers, Jamie
^ permalink raw reply
* Re: [rt2x00-users] Linksys WUSB600N v1 disconnecting from AP
From: Helmut Schaa @ 2011-01-08 9:47 UTC (permalink / raw)
To: Aleksandar Milivojevic
Cc: Luis R. Rodriguez, Luis Rodriguez, linux-wireless@vger.kernel.org,
Wolfgang Kufner, Luis Correia, users@rt2x00.serialmonkey.com
In-Reply-To: <AANLkTintU_vSt5eWoma4_d9tNCxPpOfpGZMq7XXppjpP@mail.gmail.com>
Am Samstag, 8. Januar 2011 schrieb Aleksandar Milivojevic:
> Running 'iw event -t' shows a lot of disassociation due to inactivity.
> This happens even if there is regular flow of traffic (for example, I
> start ping to my AP and leave it running, or I leave Pandora streaming
> music in the browser).
>
> Below is example of output of 'iw event -t' (these lines repeat in the
> output at irregularl intervals):
>
> 1294464037.037450: wlan0 (phy #0): deauth 00:1c:10:ea:2a:cb ->
> 00:1e:52:79:e9:ff reason 4: Disassociated due to inactivity
> 1294464037.037538: wlan0 (phy #0): disconnected (local request)
Aha, so it's not the AP disassociating you but it's your client disconnecting
on its own. Mind to provide the wpa_supplicant log for the same situation when
run with "-ddt"?
Helmut
^ permalink raw reply
* Re: [rt2x00-users] Linksys WUSB600N v1 disconnecting from AP
From: Aleksandar Milivojevic @ 2011-01-08 6:14 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Helmut Schaa, Luis Rodriguez, linux-wireless@vger.kernel.org,
Wolfgang Kufner, Luis Correia, users@rt2x00.serialmonkey.com
In-Reply-To: <20110107202224.GI21588@tux>
On Fri, Jan 7, 2011 at 12:22 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> You may want to try checing the 'iw event -t' output while the issue happens.
Running 'iw event -t' shows a lot of disassociation due to inactivity.
This happens even if there is regular flow of traffic (for example, I
start ping to my AP and leave it running, or I leave Pandora streaming
music in the browser).
Below is example of output of 'iw event -t' (these lines repeat in the
output at irregularl intervals):
1294464037.037450: wlan0 (phy #0): deauth 00:1c:10:ea:2a:cb ->
00:1e:52:79:e9:ff reason 4: Disassociated due to inactivity
1294464037.037538: wlan0 (phy #0): disconnected (local request)
1294464037.051747: phy #0: regulatory domain change: set to world
roaming by the wireless core upon initialization request
1294464037.143040: wlan0 (phy #0): scan started
1294464040.158920: wlan0 (phy #0): scan finished: 2412 2417 2422 2427
2432 2437 2442 2447 2452 2457 2462 2467 2472 2484 5180 5190 5200 5220
5230 5240 5745 5755 5765 5785 5795 5805 5825, ""
1294464041.799682: wlan0 (phy #0): auth 00:1e:52:79:e9:ff ->
00:1c:10:ea:2a:cb status: 0: Successful
1294464041.811304: wlan0: new station 00:1e:52:79:e9:ff
1294464041.841934: wlan0 (phy #0): assoc 00:1e:52:79:e9:ff ->
00:1c:10:ea:2a:cb status: 0: Successful
1294464041.842021: wlan0 (phy #0): connected to 00:1e:52:79:e9:ff
1294464041.877275: phy #0: regulatory domain change: set to US by a
country IE request on phy0
I also noticed that from time to time there would be periods when ping
round trip times would become very irregular, ranging from 3ms to 3-4
seconds (normally, they would be consistently in approximately 3-4ms
range). These periods of high ping latencies do not seem to coincide
with connection drops between wireless card and AP. The periods of
high ping latency would sometime last for few seconds, sometimes for
few minutes. For example (an shorter one):
64 bytes from 192.168.0.1: icmp_req=600 ttl=255 time=3.37 ms
64 bytes from 192.168.0.1: icmp_req=601 ttl=255 time=3.36 ms
64 bytes from 192.168.0.1: icmp_req=602 ttl=255 time=3.37 ms
64 bytes from 192.168.0.1: icmp_req=603 ttl=255 time=7.38 ms
64 bytes from 192.168.0.1: icmp_req=604 ttl=255 time=3.23 ms
64 bytes from 192.168.0.1: icmp_req=605 ttl=255 time=3.73 ms
64 bytes from 192.168.0.1: icmp_req=606 ttl=255 time=3.26 ms
64 bytes from 192.168.0.1: icmp_req=607 ttl=255 time=2665 ms
64 bytes from 192.168.0.1: icmp_req=608 ttl=255 time=1658 ms
64 bytes from 192.168.0.1: icmp_req=609 ttl=255 time=650 ms
64 bytes from 192.168.0.1: icmp_req=610 ttl=255 time=1538 ms
64 bytes from 192.168.0.1: icmp_req=611 ttl=255 time=530 ms
64 bytes from 192.168.0.1: icmp_req=612 ttl=255 time=1417 ms
64 bytes from 192.168.0.1: icmp_req=613 ttl=255 time=409 ms
64 bytes from 192.168.0.1: icmp_req=614 ttl=255 time=1298 ms
64 bytes from 192.168.0.1: icmp_req=615 ttl=255 time=290 ms
64 bytes from 192.168.0.1: icmp_req=616 ttl=255 time=1172 ms
64 bytes from 192.168.0.1: icmp_req=617 ttl=255 time=164 ms
64 bytes from 192.168.0.1: icmp_req=618 ttl=255 time=1046 ms
64 bytes from 192.168.0.1: icmp_req=619 ttl=255 time=41.0 ms
64 bytes from 192.168.0.1: icmp_req=620 ttl=255 time=923 ms
64 bytes from 192.168.0.1: icmp_req=621 ttl=255 time=0.561 ms
64 bytes from 192.168.0.1: icmp_req=622 ttl=255 time=44.8 ms
64 bytes from 192.168.0.1: icmp_req=623 ttl=255 time=26.9 ms
64 bytes from 192.168.0.1: icmp_req=624 ttl=255 time=1609 ms
64 bytes from 192.168.0.1: icmp_req=625 ttl=255 time=610 ms
64 bytes from 192.168.0.1: icmp_req=626 ttl=255 time=1494 ms
64 bytes from 192.168.0.1: icmp_req=627 ttl=255 time=488 ms
64 bytes from 192.168.0.1: icmp_req=628 ttl=255 time=1391 ms
64 bytes from 192.168.0.1: icmp_req=629 ttl=255 time=383 ms
64 bytes from 192.168.0.1: icmp_req=630 ttl=255 time=3.42 ms
64 bytes from 192.168.0.1: icmp_req=631 ttl=255 time=3.43 ms
64 bytes from 192.168.0.1: icmp_req=632 ttl=255 time=3.20 ms
64 bytes from 192.168.0.1: icmp_req=633 ttl=255 time=3.91 ms
64 bytes from 192.168.0.1: icmp_req=634 ttl=255 time=3.24 ms
64 bytes from 192.168.0.1: icmp_req=635 ttl=255 time=3.74 ms
64 bytes from 192.168.0.1: icmp_req=636 ttl=255 time=3.36 ms
64 bytes from 192.168.0.1: icmp_req=637 ttl=255 time=3.39 ms
^ permalink raw reply
* Re: [PATCH 1/4] iw: survey: Mark frequency in use
From: Bruno Randolf @ 2011-01-08 3:44 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, nbd, linux-wireless
In-Reply-To: <1294398021.3467.2.camel@jlt3.sipsolutions.net>
On Friday 07 January 2011 20:00:21 Johannes Berg wrote:
> On Fri, 2011-01-07 at 15:00 +0900, Bruno Randolf wrote:
> > Survey: Mark frequency in use according to NL80211_SURVEY_INFO_IN_USE.
> >
> > This patch comes from OpenWRT. Original author: Felix Fietkau
>
> Can you please resend with From: so I can apply them with the proper
> author?
Allright. Will do that next Tuesday.
bruno
^ permalink raw reply
* Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j
From: Bruno Randolf @ 2011-01-08 3:43 UTC (permalink / raw)
To: Brian Prodoehl; +Cc: johannes, linville, linux-wireless
In-Reply-To: <AANLkTimesMqYthXLSU2RBF=9=5bDXv3QtnOZapCjCquG@mail.gmail.com>
On Friday 07 January 2011 21:53:25 Brian Prodoehl wrote:
> > Do all drivers still build with this patch? I applied the previous
> > RFC version of this patch to a late-December cut of compat-wireless,
> > and had to touch the receive-handling code in a half-dozen or so
> > drivers due to the API changes.
I have to confess, I didn't check the drivers. Just tested with ath5k. Before
this gets merged we have to fix all drivers which use these functions, true. I
will try to do that next week...
> Ah, I see. All the driver changes I needed were because
> ieee80211_channel_to_frequency() changed with the RFC patch, and this
> patch keeps ieee80211_channel_to_frequency() the same. Good stuff.
Uh? This patch also changes ieee80211_channel_to_frequency(). Bad stuff. ;)
bruno
^ permalink raw reply
* RE: Kernel Panic wlc_mac80211.c Line 6093
From: Brett Rudley @ 2011-01-08 2:52 UTC (permalink / raw)
To: Jamie Kitson, linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTikam0zcxe00UCT4BDQMmrJcPKf1Hbt6=PBokpga@mail.gmail.com>
> -----Original Message-----
> From: linux-wireless-owner@vger.kernel.org [mailto:linux-wireless-
> owner@vger.kernel.org] On Behalf Of Jamie Kitson
> Sent: Friday, January 07, 2011 4:38 PM
> To: linux-wireless@vger.kernel.org
> Subject: Kernel Panic wlc_mac80211.c Line 6093
>
> Hello,
>
> I've received the following kernel panic twice in two days since I
> started using the brcm80211 driver:
>
> http://farm6.static.flickr.com/5202/5334637544_a0dacd5edd_b.jpg
>
> I have a Dell M101z with:
>
> 03:00.0 Network controller: Broadcom Corporation BCM4313 802.11b/g/n
> Wireless LAN Controller (rev 01)
Hmm, haven't seen this type of crash before. Any special setup you are using?
Thanks
Brett
^ permalink raw reply
* [PATCH] mwifiex: remove linked list implementation
From: Bing Zhao @ 2011-01-08 1:10 UTC (permalink / raw)
To: linux-wireless
Cc: John W. Linville, Johannes Berg, Amitkumar Karwar, Kiran Divekar,
Frank Huang, Bing Zhao
From: Amitkumar Karwar <akarwar@marvell.com>
Use linked list functions available in include/linux/list.h
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
drivers/net/wireless/mwifiex/11n.c | 102 ++++---
drivers/net/wireless/mwifiex/11n.h | 13 +-
drivers/net/wireless/mwifiex/11n_aggr.c | 116 +++++---
drivers/net/wireless/mwifiex/11n_rxreorder.c | 47 ++-
drivers/net/wireless/mwifiex/cmdevt.c | 227 +++++++++-------
drivers/net/wireless/mwifiex/decl.h | 2 +-
drivers/net/wireless/mwifiex/init.c | 107 ++++---
drivers/net/wireless/mwifiex/main.c | 32 ++-
drivers/net/wireless/mwifiex/main.h | 51 ++--
drivers/net/wireless/mwifiex/scan.c | 32 ++-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 20 +-
drivers/net/wireless/mwifiex/sta_tx.c | 2 +-
drivers/net/wireless/mwifiex/util.c | 141 ---------
drivers/net/wireless/mwifiex/util.h | 46 ---
drivers/net/wireless/mwifiex/wmm.c | 395 ++++++++++++++------------
drivers/net/wireless/mwifiex/wmm.h | 25 ++-
16 files changed, 692 insertions(+), 666 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index e4a0314..7cbe241 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -1073,14 +1073,11 @@ mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- false);
- if (!tx_ba_tsr_tbl) {
- LEAVE();
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr))
return false;
- }
+ tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
while (tx_ba_tsr_tbl !=
(struct mwifiex_tx_ba_stream_tbl *)
&priv->tx_ba_stream_tbl_ptr) {
@@ -1088,7 +1085,6 @@ mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
LEAVE();
return true;
}
-
tx_ba_tsr_tbl = tx_ba_tsr_tbl->next;
}
@@ -1110,7 +1106,7 @@ mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
ENTER();
- spin_lock_irqsave(&priv->tx_ba_stream_tbl_ptr.lock, flags);
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
if (!tx_ba_tsr_tbl &&
mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
@@ -1119,13 +1115,12 @@ mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
PRINTM(MINFO, "tx_ba_stream_tbl_ptr %p\n", tx_ba_tsr_tbl);
- mwifiex_util_unlink_list(&priv->tx_ba_stream_tbl_ptr,
- (struct mwifiex_linked_list *) tx_ba_tsr_tbl, false);
+ list_del((struct list_head *) tx_ba_tsr_tbl);
kfree(tx_ba_tsr_tbl);
exit:
- spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_ptr.lock, flags);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
}
@@ -1138,15 +1133,24 @@ mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
{
int i;
struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr;
+ unsigned long flags;
ENTER();
- while ((del_tbl_ptr = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr, true)))
+ while (1) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+ flags);
+ break;
+ }
+ del_tbl_ptr = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr);
+ }
- mwifiex_util_init_list((struct mwifiex_linked_list *) &priv->
- tx_ba_stream_tbl_ptr);
+ INIT_LIST_HEAD((struct list_head *) &priv->tx_ba_stream_tbl_ptr);
for (i = 0; i < MAX_NUM_TID; ++i) {
priv->aggr_prio_tbl[i].ampdu_ap =
@@ -1165,16 +1169,19 @@ mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
enum mwifiex_ba_status ba_status)
{
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return NULL;
}
+ tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
while (tx_ba_tsr_tbl !=
(struct mwifiex_tx_ba_stream_tbl *)
@@ -1200,16 +1207,19 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
int tid, u8 *ra)
{
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return NULL;
}
+ tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
while (tx_ba_tsr_tbl !=
(struct mwifiex_tx_ba_stream_tbl *)
@@ -1243,6 +1253,7 @@ mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
enum mwifiex_ba_status ba_status)
{
struct mwifiex_tx_ba_stream_tbl *new_node;
+ unsigned long flags;
ENTER();
@@ -1258,15 +1269,16 @@ mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
goto exit;
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) new_node);
+ INIT_LIST_HEAD((struct list_head *) new_node);
new_node->tid = tid;
new_node->ba_status = ba_status;
memcpy(new_node->ra, ra, MWIFIEX_MAC_ADDR_LENGTH);
- mwifiex_util_enqueue_list_tail(&priv->tx_ba_stream_tbl_ptr,
- (struct mwifiex_linked_list *)
- new_node, true);
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_add_tail((struct list_head *) new_node,
+ &priv->tx_ba_stream_tbl_ptr);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
}
exit:
@@ -1376,16 +1388,19 @@ mwifiex_11n_update_addba_request(struct mwifiex_private *priv)
{
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return;
}
+ tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
while (tx_ba_tsr_tbl !=
(struct mwifiex_tx_ba_stream_tbl *)
@@ -1410,14 +1425,20 @@ mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf;
struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr;
int count = 0;
+ unsigned long flags;
+
ENTER();
- rx_reorder_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
- mwifiex_util_peek_list(&priv->rx_reorder_tbl_ptr,
- true);
- if (!rx_reorder_tbl_ptr) {
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ if (list_empty(&priv->rx_reorder_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
LEAVE();
return count;
}
+ rx_reorder_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
+ priv->rx_reorder_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
while (rx_reorder_tbl_ptr !=
(struct mwifiex_rx_reorder_tbl *) &priv->rx_reorder_tbl_ptr) {
rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid;
@@ -1452,16 +1473,19 @@ mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf;
int count = 0;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return count;
}
+ tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
while (tx_ba_tsr_tbl !=
(struct mwifiex_tx_ba_stream_tbl *)
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 65f9ae8..8786a98 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -129,7 +129,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv)
if (pmpriv)
ba_stream_num +=
mwifiex_wmm_list_len(priv->adapter,
- (struct mwifiex_list_head
+ (struct list_head
*) &pmpriv->
tx_ba_stream_tbl_ptr);
}
@@ -151,16 +151,19 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv,
int tid;
u8 ret = false;
struct mwifiex_tx_ba_stream_tbl *tx_tbl;
+ unsigned long flags;
ENTER();
- tx_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_tbl) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return ret;
}
+ tx_tbl = (struct mwifiex_tx_ba_stream_tbl *)
+ priv->tx_ba_stream_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index ca24d54..1e44d23 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -306,7 +306,7 @@ done:
int
mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *pra_list, int headroom,
- int ptrindex, unsigned long flags)
+ int ptrindex, unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock)
{
int pkt_size = 0;
@@ -318,53 +318,67 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
struct timeval tstamp;
struct mwifiex_tx_param tx_param;
struct txpd *ptx_pd = NULL;
+ unsigned long ra_list_tbl_flags;
ENTER();
PRINTM(MDAT_D, "Handling Aggr packet\n");
- mbuf_src = (struct mwifiex_buffer *)
- mwifiex_util_peek_list(&pra_list->buf_head,
- true);
- if (mbuf_src) {
- mbuf_aggr = mwifiex_alloc_buffer(adapter->tx_buf_size);
- if (!mbuf_aggr) {
- PRINTM(MERROR,
- "Error allocating struct mwifiex_buffer\n");
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- return MWIFIEX_STATUS_FAILURE;
- }
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock, ra_list_tbl_flags);
+ if (list_empty(&pra_list->buf_head)) {
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ goto exit;
+ }
+ mbuf_src = (struct mwifiex_buffer *) pra_list->buf_head.next;
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock, ra_list_tbl_flags);
+
+ mbuf_aggr = mwifiex_alloc_buffer(adapter->tx_buf_size);
+ if (!mbuf_aggr) {
+ PRINTM(MERROR,
+ "Error allocating struct mwifiex_buffer\n");
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return MWIFIEX_STATUS_FAILURE;
+ }
- data = mbuf_aggr->buffer + headroom;
+ data = mbuf_aggr->buffer + headroom;
- mbuf_aggr->bss_index = mbuf_src->bss_index;
- mbuf_aggr->buf_type = mbuf_src->buf_type;
- mbuf_aggr->priority = mbuf_src->priority;
+ mbuf_aggr->bss_index = mbuf_src->bss_index;
+ mbuf_aggr->buf_type = mbuf_src->buf_type;
+ mbuf_aggr->priority = mbuf_src->priority;
- mbuf_aggr->buffer = data;
- mbuf_aggr->data_offset = 0;
+ mbuf_aggr->buffer = data;
+ mbuf_aggr->data_offset = 0;
- /* Form AMSDU */
- mwifiex_11n_form_amsdu_txpd(priv, mbuf_aggr);
- pkt_size = sizeof(struct txpd);
- if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
- ptx_pd = (struct txpd *)mbuf_aggr->buffer;
- } else {
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- goto exit;
- }
+ /* Form AMSDU */
+ mwifiex_11n_form_amsdu_txpd(priv, mbuf_aggr);
+ pkt_size = sizeof(struct txpd);
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+ ptx_pd = (struct txpd *)mbuf_aggr->buffer;
while (mbuf_src && ((pkt_size + (mbuf_src->data_len + LLC_SNAP_LEN)
+ headroom)
<= adapter->tx_buf_size)) {
- mbuf_src = (struct mwifiex_buffer *)
- mwifiex_util_dequeue_list(&pra_list->buf_head, true);
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ if (!list_empty(&pra_list->buf_head)) {
+ mbuf_src = (struct mwifiex_buffer *)
+ pra_list->buf_head.next;
+ list_del((struct list_head *)mbuf_src);
+ } else {
+ mbuf_src = NULL;
+ }
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
pra_list->total_pkts_size -= mbuf_src->data_len;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
pkt_size += mwifiex_11n_form_amsdu_pkt(adapter,
(data + pkt_size),
mbuf_src->buffer +
@@ -377,21 +391,27 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mwifiex_write_data_complete(adapter, mbuf_src,
MWIFIEX_STATUS_SUCCESS);
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
+ ra_list_flags);
LEAVE();
return MWIFIEX_STATUS_FAILURE;
}
- mbuf_src =
- (struct mwifiex_buffer *)
- mwifiex_util_peek_list(&pra_list->buf_head, true);
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ if (!list_empty(&pra_list->buf_head))
+ mbuf_src = (struct mwifiex_buffer *)
+ pra_list->buf_head.next;
+ else
+ mbuf_src = NULL;
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
}
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
/* Last AMSDU packet does not need padding */
pkt_size -= pad;
@@ -408,11 +428,10 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mbuf_aggr, &tx_param);
switch (ret) {
case MWIFIEX_STATUS_RESOURCE:
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
-
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
+ ra_list_flags);
mwifiex_write_data_complete(adapter, mbuf_aggr,
MWIFIEX_STATUS_FAILURE);
LEAVE();
@@ -424,14 +443,18 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
priv->adapter->tx_lock_flag = false;
ptx_pd->flags = 0;
}
- mwifiex_util_enqueue_list_head(&pra_list->buf_head,
- (struct mwifiex_linked_list *)
- mbuf_aggr, true);
+
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ list_add((struct list_head *) mbuf_aggr, &pra_list->buf_head);
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
pra_list->total_pkts_size += mbuf_aggr->data_len;
mbuf_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
PRINTM(MDATA, "MWIFIEX_STATUS_RESOURCE is returned\n");
break;
case MWIFIEX_STATUS_FAILURE:
@@ -451,7 +474,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
break;
}
if (ret != MWIFIEX_STATUS_RESOURCE) {
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
priv->wmm.packets_out[ptrindex]++;
priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
@@ -459,7 +482,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
adapter->bss_prio_tbl[priv->bss_priority]
.bss_prio_cur->next;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
}
do_gettimeofday(&tstamp);
PRINTM(MDATA, "%lu.%lu : Data => kernel\n",
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index dcfcb99..c689408 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -158,6 +158,8 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
struct mwifiex_rx_reorder_tbl
*rx_reor_tbl_ptr)
{
+ unsigned long flags;
+
ENTER();
if (!rx_reor_tbl_ptr) {
@@ -173,9 +175,10 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
del_timer(&rx_reor_tbl_ptr->timer_context.timer);
PRINTM(MDAT_D, "Delete rx_reor_tbl_ptr: %p\n", rx_reor_tbl_ptr);
- mwifiex_util_unlink_list(&priv->rx_reorder_tbl_ptr,
- (struct mwifiex_linked_list *) rx_reor_tbl_ptr,
- true);
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_del((struct list_head *) rx_reor_tbl_ptr);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
kfree(rx_reor_tbl_ptr);
@@ -191,16 +194,19 @@ static struct mwifiex_rx_reorder_tbl *
mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
{
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ unsigned long flags;
ENTER();
- rx_reor_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
- mwifiex_util_peek_list(&priv->rx_reorder_tbl_ptr,
- true);
- if (!rx_reor_tbl_ptr) {
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ if (list_empty(&priv->rx_reorder_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
LEAVE();
return NULL;
}
+ rx_reor_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
+ priv->rx_reorder_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
while (rx_reor_tbl_ptr !=
(struct mwifiex_rx_reorder_tbl *) &priv->rx_reorder_tbl_ptr) {
@@ -276,6 +282,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
int i;
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
u16 last_seq = 0;
+ unsigned long flags;
ENTER();
@@ -301,7 +308,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
goto exit;
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) new_node);
+ INIT_LIST_HEAD((struct list_head *) new_node);
new_node->tid = tid;
memcpy(new_node->ta, ta, MWIFIEX_MAC_ADDR_LENGTH);
new_node->start_win = seq_num;
@@ -342,9 +349,10 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
for (i = 0; i < win_size; ++i)
new_node->rx_reorder_ptr[i] = NULL;
- mwifiex_util_enqueue_list_tail(&priv->rx_reorder_tbl_ptr,
- (struct mwifiex_linked_list *)
- new_node, true);
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_add_tail((struct list_head *)new_node,
+ &priv->rx_reorder_tbl_ptr);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
}
exit:
@@ -748,16 +756,25 @@ void
mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
{
struct mwifiex_rx_reorder_tbl *del_tbl_ptr;
+ unsigned long flags;
ENTER();
- while ((del_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
- mwifiex_util_peek_list(&priv->rx_reorder_tbl_ptr, true))) {
+ while (1) {
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ if (list_empty(&priv->rx_reorder_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ flags);
+ break;
+ }
+ del_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
+ priv->rx_reorder_tbl_ptr.next;
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) &priv->
- rx_reorder_tbl_ptr);
+ INIT_LIST_HEAD((struct list_head *) &priv->rx_reorder_tbl_ptr);
memset(priv->rx_seq, 0, sizeof(priv->rx_seq));
LEAVE();
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index dee8550..5e6ae2e 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -70,6 +70,7 @@ static struct cmd_ctrl_node *
mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
{
struct cmd_ctrl_node *cmd_node;
+ unsigned long flags;
ENTER();
@@ -78,15 +79,16 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
return NULL;
}
- if (mwifiex_util_peek_list(&adapter->cmd_free_q, true)) {
- cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_dequeue_list(&adapter->cmd_free_q, true);
- } else {
+ spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+ if (list_empty(&adapter->cmd_free_q)) {
PRINTM(MERROR,
"GET_CMD_NODE: struct cmd_ctrl_node is not available\n");
- cmd_node = NULL;
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+ return NULL;
}
+ cmd_node = (struct cmd_ctrl_node *) adapter->cmd_free_q.next;
+ list_del((struct list_head *)cmd_node);
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
LEAVE();
return cmd_node;
@@ -137,17 +139,20 @@ static struct cmd_ctrl_node *
mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter,
struct mwifiex_ioctl_req *ioctl_req)
{
- struct cmd_ctrl_node *cmd_node = NULL;
+ unsigned long flags;
+ struct cmd_ctrl_node *cmd_node;
ENTER();
- cmd_node = (struct cmd_ctrl_node *)
- mwifiex_util_peek_list(&adapter->cmd_pending_q,
- true);
- if (!cmd_node) {
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ if (list_empty(&adapter->cmd_pending_q)) {
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
LEAVE();
return NULL;
}
+ cmd_node = (struct cmd_ctrl_node *) adapter->cmd_pending_q.next;
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
while (cmd_node != (struct cmd_ctrl_node *) &adapter->cmd_pending_q) {
if (cmd_node->ioctl_buf == ioctl_req) {
LEAVE();
@@ -673,6 +678,8 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
struct cmd_ctrl_node *cmd_node)
{
struct mwifiex_ioctl_req *ioctl_req = NULL;
+ unsigned long flags;
+
ENTER();
if (cmd_node == NULL)
@@ -692,9 +699,10 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
mwifiex_clean_cmd_node(adapter, cmd_node);
/* Insert node into cmd_free_q */
- mwifiex_util_enqueue_list_tail(&adapter->cmd_free_q,
- (struct mwifiex_linked_list *) cmd_node,
- true);
+ spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+ list_add_tail((struct list_head *) cmd_node, &adapter->cmd_free_q);
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+
done:
LEAVE();
}
@@ -712,6 +720,7 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
{
struct host_cmd_ds_command *host_cmd = NULL;
u16 command;
+ unsigned long flags;
ENTER();
@@ -740,15 +749,14 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
}
}
- if (add_tail) {
- mwifiex_util_enqueue_list_tail(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
- } else {
- mwifiex_util_enqueue_list_head(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
- }
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ if (add_tail)
+ list_add_tail((struct list_head *) cmd_node,
+ &adapter->cmd_pending_q);
+ else
+ list_add((struct list_head *) cmd_node,
+ &adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x is queued\n", command);
@@ -775,7 +783,8 @@ mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
struct cmd_ctrl_node *cmd_node = NULL;
enum mwifiex_status ret = MWIFIEX_STATUS_SUCCESS;
struct host_cmd_ds_command *host_cmd;
- unsigned long flags;
+ unsigned long cmd_flags;
+ unsigned long cmd_pending_q_flags;
ENTER();
@@ -793,51 +802,54 @@ mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
goto done;
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
/* Check if any command is pending */
- cmd_node =
- (struct cmd_ctrl_node *) mwifiex_util_peek_list(&adapter->
- cmd_pending_q,
- true);
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+ if (list_empty(&adapter->cmd_pending_q)) {
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ ret = MWIFIEX_STATUS_SUCCESS;
+ goto done;
+ }
+ cmd_node = (struct cmd_ctrl_node *) adapter->cmd_pending_q.next;
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
- if (cmd_node) {
- host_cmd = (struct host_cmd_ds_command *)
- (cmd_node->cmd_buf->buffer +
- cmd_node->cmd_buf->data_offset);
- priv = cmd_node->priv;
-
- if (adapter->ps_state != PS_STATE_AWAKE) {
- PRINTM(MERROR, "Cannot send command in sleep state"
- ", this should not happen\n");
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
- flags);
- goto done;
- }
+ host_cmd = (struct host_cmd_ds_command *)
+ (cmd_node->cmd_buf->buffer +
+ cmd_node->cmd_buf->data_offset);
+ priv = cmd_node->priv;
- mwifiex_util_unlink_list(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
- ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
- priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
- /* Any command sent to the firmware when host is in sleep
- mode, should
- de-configure host sleep */
- /* We should skip the host sleep configuration command
- itself though */
- if (priv &&
- (host_cmd->command !=
- cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
- if (adapter->hs_activated) {
- adapter->is_hs_configured = false;
- mwifiex_hs_activated_event(priv, false);
- }
- }
+ if (adapter->ps_state != PS_STATE_AWAKE) {
+ PRINTM(MERROR, "Cannot send command in sleep state"
+ ", this should not happen\n");
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
+ cmd_flags);
goto done;
- } else {
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
}
- ret = MWIFIEX_STATUS_SUCCESS;
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ /* Any command sent to the firmware when host is in sleep
+ * mode should de-configure host sleep. We should skip the
+ * host sleep configuration command itself though
+ */
+ if (priv &&
+ (host_cmd->command !=
+ cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
+ if (adapter->hs_activated) {
+ adapter->is_hs_configured = false;
+ mwifiex_hs_activated_event(priv, false);
+ }
+ }
+
done:
LEAVE();
return ret;
@@ -1113,13 +1125,18 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
MWIFIEX_STATUS_FAILURE);
}
/* Cancel all pending command */
- while ((cmd_node =
- (struct cmd_ctrl_node *) mwifiex_util_peek_list(&adapter->
- cmd_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ while (1) {
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ if (list_empty(&adapter->cmd_pending_q)) {
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ flags);
+ break;
+ }
+ cmd_node = (struct cmd_ctrl_node *)
+ adapter->cmd_pending_q.next;
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
if (cmd_node->ioctl_buf) {
ioctl_buf =
(struct mwifiex_ioctl_req *) cmd_node->
@@ -1132,13 +1149,18 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
/* Cancel all pending scan command */
- while ((cmd_node =
- (struct cmd_ctrl_node *) mwifiex_util_peek_list(&adapter->
- scan_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ while (1) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+ break;
+ }
+ cmd_node = (struct cmd_ctrl_node *)
+ adapter->scan_pending_q.next;
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
@@ -1162,7 +1184,9 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
struct mwifiex_ioctl_req *ioctl_req)
{
struct cmd_ctrl_node *cmd_node = NULL;
- unsigned long flags;
+ unsigned long cmd_flags;
+ unsigned long cmd_pending_q_flags;
+ unsigned long scan_pending_q_flags;
ENTER();
@@ -1172,38 +1196,49 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
if ((adapter->curr_cmd) &&
(adapter->curr_cmd->ioctl_buf == ioctl_req)) {
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
cmd_node = adapter->curr_cmd;
cmd_node->ioctl_buf = NULL;
cmd_node->cmd_flag |= CMD_F_CANCELED;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
while ((cmd_node =
mwifiex_get_pending_ioctl_cmd(adapter, ioctl_req)) != NULL) {
- mwifiex_util_unlink_list(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
if (ioctl_req->req_id == MWIFIEX_IOCTL_SCAN) {
/* Cancel all pending scan command */
- while ((cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_peek_list(&adapter->scan_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ while (1) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(
+ &adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+ break;
+ }
+ cmd_node = (struct cmd_ctrl_node *)
+ adapter->scan_pending_q.next;
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
adapter->scan_processing = false;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
}
ioctl_req->status_code = MWIFIEX_ERROR_CMD_CANCEL;
mwifiex_ioctl_complete(adapter, ioctl_req, MWIFIEX_STATUS_FAILURE);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 30d66c0..5ba9cc9 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -150,8 +150,8 @@ struct mwifiex_ioctl_req {
};
struct mwifiex_buffer {
- struct mwifiex_buffer *prev;
struct mwifiex_buffer *next;
+ struct mwifiex_buffer *prev;
u32 status_code;
u32 flags;
u32 bss_index;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 7b0b10c..5fa5de6 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -38,6 +38,7 @@ mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_bss_prio_node *bss_prio;
enum mwifiex_status status = MWIFIEX_STATUS_SUCCESS;
+ unsigned long flags;
ENTER();
@@ -49,18 +50,18 @@ mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
}
bss_prio->priv = priv;
-
- mwifiex_util_init_list((struct mwifiex_linked_list *) bss_prio);
-
+ INIT_LIST_HEAD((struct list_head *) bss_prio);
if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
bss_prio;
- mwifiex_util_enqueue_list_tail(&adapter->
- bss_prio_tbl[priv->bss_priority].
- bss_prio_head,
- (struct mwifiex_linked_list *) bss_prio,
- true);
+ spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_lock, flags);
+ list_add_tail((struct list_head *) bss_prio,
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_lock, flags);
exit:
LEAVE();
@@ -366,6 +367,9 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
mwifiex_free_buffer(adapter->sleep_cfm);
+ /* Free lock variables */
+ mwifiex_free_lock_list(adapter);
+
LEAVE();
return;
}
@@ -397,28 +401,36 @@ enum mwifiex_status wlan_init_lock_list(struct mwifiex_adapter *adapter)
}
/* Initialize cmd_free_q */
- mwifiex_util_init_list_head(&adapter->cmd_free_q, true);
+ INIT_LIST_HEAD(&adapter->cmd_free_q);
/* Initialize cmd_pending_q */
- mwifiex_util_init_list_head(&adapter->cmd_pending_q, true);
+ INIT_LIST_HEAD(&adapter->cmd_pending_q);
/* Initialize scan_pending_q */
- mwifiex_util_init_list_head(&adapter->scan_pending_q, true);
+ INIT_LIST_HEAD(&adapter->scan_pending_q);
+
+ spin_lock_init(&adapter->cmd_free_q_lock);
+ spin_lock_init(&adapter->cmd_pending_q_lock);
+ spin_lock_init(&adapter->scan_pending_q_lock);
for (i = 0; i < adapter->priv_num; ++i) {
- mwifiex_util_init_list_head(&adapter->bss_prio_tbl[i]
- .bss_prio_head, true);
+ INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
+ spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
}
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
priv = adapter->priv[i];
- for (j = 0; j < MAX_NUM_TID; ++j)
- mwifiex_util_init_list_head(&priv->wmm
- .tid_tbl_ptr[j].ra_list, true);
- mwifiex_util_init_list_head(&priv->tx_ba_stream_tbl_ptr,
- true);
- mwifiex_util_init_list_head(&priv->rx_reorder_tbl_ptr,
- true);
+ for (j = 0; j < MAX_NUM_TID; ++j) {
+ INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j]
+ .ra_list);
+ spin_lock_init(&priv->wmm.tid_tbl_ptr[j]
+ .tid_tbl_lock);
+ }
+ INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
+
+ spin_lock_init(&priv->tx_ba_stream_tbl_lock);
+ spin_lock_init(&priv->rx_reorder_tbl_lock);
}
}
@@ -430,7 +442,7 @@ enum mwifiex_status wlan_init_lock_list(struct mwifiex_adapter *adapter)
* This function releases the lock variables and frees the locks and
* associated locks.
*/
-void wlan_free_lock_list(struct mwifiex_adapter *adapter)
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
{
struct mwifiex_private *priv = NULL;
s32 i = 0;
@@ -439,25 +451,20 @@ void wlan_free_lock_list(struct mwifiex_adapter *adapter)
ENTER();
/* Free lists */
- mwifiex_util_free_list_head(&adapter->cmd_free_q);
-
- mwifiex_util_free_list_head(&adapter->cmd_pending_q);
-
- mwifiex_util_free_list_head(&adapter->scan_pending_q);
+ list_del(&adapter->cmd_free_q);
+ list_del(&adapter->cmd_pending_q);
+ list_del(&adapter->scan_pending_q);
for (i = 0; i < adapter->priv_num; i++)
- mwifiex_util_free_list_head(&adapter->bss_prio_tbl[i]
- .bss_prio_head);
+ list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
priv = adapter->priv[i];
for (j = 0; j < MAX_NUM_TID; ++j)
- mwifiex_util_free_list_head(&priv->wmm
- .tid_tbl_ptr[j].ra_list);
- mwifiex_util_free_list_head(
- &priv->tx_ba_stream_tbl_ptr);
- mwifiex_util_free_list_head(&priv->rx_reorder_tbl_ptr);
+ list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
+ list_del(&priv->tx_ba_stream_tbl_ptr);
+ list_del(&priv->rx_reorder_tbl_ptr);
}
}
@@ -483,6 +490,8 @@ mwifiex_init_fw(struct mwifiex_adapter *adapter)
struct mwifiex_private *priv = NULL;
u8 i = 0;
u8 first_sta = true;
+ int is_cmd_pend_q_empty;
+ unsigned long flags;
ENTER();
@@ -521,7 +530,10 @@ mwifiex_init_fw(struct mwifiex_adapter *adapter)
}
}
- if (mwifiex_util_peek_list(&adapter->cmd_pending_q, true)) {
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+ if (!is_cmd_pend_q_empty) {
/* Send the first command in queue and return */
if (mwifiex_main_process(adapter) != MWIFIEX_STATUS_FAILURE)
ret = MWIFIEX_STATUS_PENDING;
@@ -672,34 +684,41 @@ mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_bss_prio_node *bssprio_node = NULL, *tmp_node = NULL,
**cur = NULL;
- struct mwifiex_list_head *head;
+ struct list_head *head;
+ spinlock_t *lock;
+ unsigned long flags;
ENTER();
for (i = 0; i < adapter->priv_num; ++i) {
head = &adapter->bss_prio_tbl[i].bss_prio_head;
cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
+ lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
PRINTM(MINFO, "Delete BSS priority table, index = %d, i = %d, "
"head = %p, cur = %p\n",
priv->bss_index, i, head, *cur);
if (*cur) {
+ spin_lock_irqsave(lock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(lock, flags);
+ continue;
+ }
bssprio_node = (struct mwifiex_bss_prio_node *)
- mwifiex_util_peek_list(head, true);
+ head->next;
+ spin_unlock_irqrestore(lock, flags);
+
while (bssprio_node
- && ((struct mwifiex_list_head *) bssprio_node !=
+ && ((struct list_head *) bssprio_node !=
head)) {
tmp_node = bssprio_node->next;
if (bssprio_node->priv == priv) {
PRINTM(MINFO, "Delete node, node = %p,"
" next = %p\n",
bssprio_node, tmp_node);
- mwifiex_util_unlink_list(head,
- (struct
- mwifiex_linked_list
- *)
- bssprio_node,
- true);
-
+ spin_lock_irqsave(lock, flags);
+ list_del((struct list_head *)
+ bssprio_node);
+ spin_unlock_irqrestore(lock, flags);
kfree(bssprio_node);
}
bssprio_node = tmp_node;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 36bb35d..0f26068 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -160,7 +160,7 @@ error:
PRINTM(MINFO, "Leave mwifiex_register with error\n");
/* Free lock variables */
- wlan_free_lock_list(adapter);
+ mwifiex_free_lock_list(adapter);
for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++)
kfree(adapter->priv[i]);
kfree(adapter);
@@ -177,7 +177,6 @@ exit_register:
*
* The following cleanup operations are performed -
* - Free the timers
- * - Free the locks
* - Free beacon buffers
* - Free private structures
* - Free adapter structure
@@ -191,9 +190,6 @@ mwifiex_unregister(struct mwifiex_adapter *adapter)
del_timer(&adapter->cmd_timer);
- /* Free lock variables */
- wlan_free_lock_list(adapter);
-
/* Free private structures */
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
@@ -258,7 +254,7 @@ process_start:
if ((adapter->ps_state == PS_STATE_SLEEP) &&
(adapter->pm_wakeup_card_req &&
!adapter->pm_wakeup_fw_try) &&
- (mwifiex_util_peek_list(&adapter->cmd_pending_q, true)
+ (is_command_pending(adapter)
|| !mwifiex_wmm_lists_empty(adapter))) {
adapter->pm_wakeup_fw_try = true;
adapter->if_ops.wakeup(adapter);
@@ -280,8 +276,7 @@ process_start:
|| mwifiex_wmm_lists_empty(adapter)) {
if (adapter->cmd_sent || adapter->curr_cmd
||
- (!mwifiex_util_peek_list
- (&adapter->cmd_pending_q, true)))
+ (!is_command_pending(adapter)))
break;
}
}
@@ -341,7 +336,7 @@ process_start:
}
if (adapter->delay_null_pkt && !adapter->cmd_sent &&
- !adapter->curr_cmd && !IS_COMMAND_PENDING(adapter)
+ !adapter->curr_cmd && !is_command_pending(adapter)
&& mwifiex_wmm_lists_empty(adapter)) {
if (mwifiex_send_null_packet
(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
@@ -424,8 +419,8 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex)
/*
* This function frees the adapter structure.
*
- * Additionally, this closes the netlink socket, frees the timers,
- * locks and private structures.
+ * Additionally, this closes the netlink socket, frees the timers
+ * and private structures.
*/
static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
{
@@ -1080,6 +1075,21 @@ void mwifiex_mac2u8(u8 *mac_addr, char *buf)
}
/*
+ * This function check if command is pending.
+ */
+int is_command_pending(struct mwifiex_adapter *adapter)
+{
+ unsigned long flags;
+ int is_cmd_pend_q_empty;
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+ return !is_cmd_pend_q_empty;
+}
+
+/*
* This function returns the correct private structure pointer based
* upon the BSS number.
*/
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 5b1d557..79db630 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -217,16 +217,21 @@ struct mwifiex_tx_aggr {
};
struct mwifiex_ra_list_tbl {
- struct mwifiex_ra_list_tbl *prev;
struct mwifiex_ra_list_tbl *next;
- struct mwifiex_list_head buf_head;
+ struct mwifiex_ra_list_tbl *prev;
+ struct list_head buf_head;
+ /* spin lock for ra list table */
+ spinlock_t ra_list_tbl_lock;
+
u8 ra[MWIFIEX_MAC_ADDR_LENGTH];
u32 total_pkts_size;
u32 is_11n_enabled;
};
struct mwifiex_tid_tbl {
- struct mwifiex_list_head ra_list;
+ struct list_head ra_list;
+ /* spin lock for tid table */
+ spinlock_t tid_tbl_lock;
struct mwifiex_ra_list_tbl *ra_list_curr;
};
@@ -383,12 +388,16 @@ struct mwifiex_private {
u8 wmm_enabled;
u8 wmm_qosinfo;
struct mwifiex_wmm_desc wmm;
- struct mwifiex_list_head tx_ba_stream_tbl_ptr;
+ struct list_head tx_ba_stream_tbl_ptr;
+ /* spin lock for tx_ba_stream_tbl_ptr queue */
+ spinlock_t tx_ba_stream_tbl_lock;
struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID];
u8 addba_reject[MAX_NUM_TID];
struct mwifiex_add_ba_param add_ba_param;
u16 rx_seq[MAX_NUM_TID];
- struct mwifiex_list_head rx_reorder_tbl_ptr;
+ struct list_head rx_reorder_tbl_ptr;
+ /* spin lock for rx_reorder_tbl_ptr queue */
+ spinlock_t rx_reorder_tbl_lock;
/* spin lock for Rx packets */
spinlock_t rx_pkt_lock;
@@ -451,8 +460,8 @@ enum mwifiex_ba_status {
};
struct mwifiex_tx_ba_stream_tbl {
- struct mwifiex_tx_ba_stream_tbl *prev;
struct mwifiex_tx_ba_stream_tbl *next;
+ struct mwifiex_tx_ba_stream_tbl *prev;
int tid;
u8 ra[MWIFIEX_MAC_ADDR_LENGTH];
enum mwifiex_ba_status ba_status;
@@ -467,8 +476,8 @@ struct reorder_tmr_cnxt {
};
struct mwifiex_rx_reorder_tbl {
- struct mwifiex_rx_reorder_tbl *prev;
struct mwifiex_rx_reorder_tbl *next;
+ struct mwifiex_rx_reorder_tbl *prev;
int tid;
u8 ta[MWIFIEX_MAC_ADDR_LENGTH];
int start_win;
@@ -478,19 +487,21 @@ struct mwifiex_rx_reorder_tbl {
};
struct mwifiex_bss_prio_node {
- struct mwifiex_bss_prio_node *prev;
struct mwifiex_bss_prio_node *next;
+ struct mwifiex_bss_prio_node *prev;
struct mwifiex_private *priv;
};
struct mwifiex_bss_prio_tbl {
- struct mwifiex_list_head bss_prio_head;
+ struct list_head bss_prio_head;
+ /* spin lock for bss priority */
+ spinlock_t bss_prio_lock;
struct mwifiex_bss_prio_node *bss_prio_cur;
};
struct cmd_ctrl_node {
- struct cmd_ctrl_node *prev;
struct cmd_ctrl_node *next;
+ struct cmd_ctrl_node *prev;
struct mwifiex_private *priv;
u32 cmd_oid;
u32 cmd_flag;
@@ -575,9 +586,15 @@ struct mwifiex_adapter {
u32 num_cmd_timeout;
u16 last_init_cmd;
struct timer_list cmd_timer;
- struct mwifiex_list_head cmd_free_q;
- struct mwifiex_list_head cmd_pending_q;
- struct mwifiex_list_head scan_pending_q;
+ struct list_head cmd_free_q;
+ /* spin lock for cmd_free_q */
+ spinlock_t cmd_free_q_lock;
+ struct list_head cmd_pending_q;
+ /* spin lock for cmd_pending_q */
+ spinlock_t cmd_pending_q_lock;
+ struct list_head scan_pending_q;
+ /* spin lock for scan_pending_q */
+ spinlock_t scan_pending_q_lock;
u32 scan_processing;
u16 region_code;
struct mwifiex_802_11d_domain_reg domain_reg;
@@ -633,7 +650,7 @@ struct mwifiex_adapter {
};
enum mwifiex_status wlan_init_lock_list(struct mwifiex_adapter *adapter);
-void wlan_free_lock_list(struct mwifiex_adapter *adapter);
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter);
enum mwifiex_status mwifiex_init_fw(struct mwifiex_adapter *adapter);
@@ -869,6 +886,7 @@ enum mwifiex_status mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
enum mwifiex_status mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp,
void *ioctl_buf);
+int is_command_pending(struct mwifiex_adapter *adapter);
/*
* This function checks if the queuing is RA based or not.
@@ -904,11 +922,6 @@ mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len)
return pos;
}
-
-#define IS_COMMAND_PENDING(adapter) ((struct cmd_ctrl_node *)\
- mwifiex_util_peek_list( \
- &adapter->cmd_pending_q, true))
-
/*
* This function returns the correct private structure pointer based
* upon the BSS type and BSS number.
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 83e466e..4026ff3 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -2589,16 +2589,23 @@ mwifiex_scan_networks(struct mwifiex_private *priv,
/* Get scan command from scan_pending_q and put to cmd_pending_q */
if (ret == MWIFIEX_STATUS_SUCCESS) {
- if (mwifiex_util_peek_list(&adapter->scan_pending_q, true)) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (!list_empty(&adapter->scan_pending_q)) {
cmd_node = (struct cmd_ctrl_node *)
- mwifiex_util_dequeue_list(&adapter->
- scan_pending_q, true);
+ adapter->scan_pending_q.next;
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = true;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
flags);
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
true);
+ } else {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
}
}
@@ -2919,7 +2926,9 @@ mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
/* Update the total number of BSSIDs in the scan table */
adapter->num_in_scan_table = num_in_table;
- if (!mwifiex_util_peek_list(&adapter->scan_pending_q, true)) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
@@ -2950,10 +2959,10 @@ mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
} else {
/* Get scan command from scan_pending_q and put to
cmd_pending_q */
- cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_dequeue_list(&adapter->scan_pending_q,
- true);
+ cmd_node = (struct cmd_ctrl_node *)
+ adapter->scan_pending_q.next;
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
}
@@ -3149,15 +3158,16 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
struct cmd_ctrl_node *cmd_node)
{
struct mwifiex_adapter *adapter = priv->adapter;
+ unsigned long flags;
ENTER();
if (cmd_node == NULL)
goto done;
- mwifiex_util_enqueue_list_tail(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *) cmd_node,
- true);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_add_tail((struct list_head *) cmd_node, &adapter->scan_pending_q);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
done:
LEAVE();
}
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index a83c72a..2da40ce 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -77,13 +77,19 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
break;
case HostCmd_CMD_802_11_SCAN:
/* Cancel all pending scan command */
- while ((cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_peek_list(&adapter->scan_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ while (1) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(
+ &adapter->scan_pending_q_lock, flags);
+ break;
+ }
+ cmd_node = (struct cmd_ctrl_node *)
+ adapter->scan_pending_q.next;
+ list_del((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index b80d245..c4385ef 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -234,7 +234,7 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv)
}
if (ret && !adapter->cmd_sent && !adapter->curr_cmd
- && !IS_COMMAND_PENDING(adapter)) {
+ && !is_command_pending(adapter)) {
adapter->delay_null_pkt = false;
ret = true;
} else {
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 55d912d..7e1bc9b 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -63,147 +63,6 @@ mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
}
/*
- * This function peeks into a list.
- *
- * A pointer to the next node in the list is returned, but the node
- * is not dequeued.
- */
-struct mwifiex_linked_list *
-mwifiex_util_peek_list(struct mwifiex_list_head *head, u8 lock_required)
-{
- struct mwifiex_linked_list *node = NULL;
- unsigned long flags;
-
- if (lock_required) {
- spin_lock_irqsave(&head->lock, flags);
- if (head->next != (struct mwifiex_linked_list *) head)
- node = head->next;
- spin_unlock_irqrestore(&head->lock, flags);
- } else {
- if (head->next != (struct mwifiex_linked_list *) head)
- node = head->next;
- }
-
- return node;
-}
-
-/*
- * This function initializes a list.
- *
- * It also initializes the associated lock if required.
- */
-inline void
-mwifiex_util_init_list_head(struct mwifiex_list_head *head, u8 lock_required)
-{
- mwifiex_util_init_list((struct mwifiex_linked_list *) head);
- if (lock_required)
- spin_lock_init(&head->lock);
-}
-
-/*
- * This function queues a new node at the list tail.
- */
-inline void
-mwifiex_util_enqueue_list_tail(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required)
-{
- struct mwifiex_linked_list *old_last;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- old_last = head->prev;
- node->prev = old_last;
- node->next = (struct mwifiex_linked_list *) head;
-
- old_last->next = node;
- head->prev = old_last->next;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-}
-
-/*
- * This function queues a new node at the list head.
- */
-inline void
-mwifiex_util_enqueue_list_head(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required)
-{
- struct mwifiex_linked_list *old_first;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- old_first = head->next;
- node->prev = (struct mwifiex_linked_list *) head;
- node->next = old_first;
-
- old_first->prev = node;
- head->next = old_first->prev;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-}
-
-/*
- * This function removes a node from the list.
- *
- * The node can be removed from any location within the list,
- * the other node pointers are adjusted accordingly.
- */
-inline void
-mwifiex_util_unlink_list(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node, u8 lock_required)
-{
- struct mwifiex_linked_list *my_prev;
- struct mwifiex_linked_list *my_next;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- my_prev = node->prev;
- my_next = node->next;
- my_next->prev = my_prev;
- my_prev->next = my_next;
-
- node->prev = NULL;
- node->next = node->prev;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-}
-
-/*
- * This function dequeues a node from the list.
- */
-inline struct mwifiex_linked_list *
-mwifiex_util_dequeue_list(struct mwifiex_list_head *head, u8 lock_required)
-{
- struct mwifiex_linked_list *node;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- node = head->next;
- if (node != (struct mwifiex_linked_list *) head)
- mwifiex_util_unlink_list(head, node, false);
- else
- node = NULL;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-
- return node;
-}
-
-/*
* IOCTL request handler to send a host command to firmware.
*
* This function prepares the correct firmware command and
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index 12ba9f9..eaf4b06 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -103,50 +103,4 @@ do { \
mwifiex_print(MHEX_DUMP | MINFO, x, y, z); \
} while (0)
-struct mwifiex_linked_list {
- struct mwifiex_linked_list *prev;
- struct mwifiex_linked_list *next;
-};
-
-struct mwifiex_list_head {
- struct mwifiex_linked_list *prev;
- struct mwifiex_linked_list *next;
- /* spin lock used for linked list operations */
- spinlock_t lock;
-};
-
-void mwifiex_util_init_list_head(struct mwifiex_list_head *head,
- u8 lock_required);
-void mwifiex_util_enqueue_list_tail(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required);
-void mwifiex_util_unlink_list(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node, u8 lock_required);
-void mwifiex_util_enqueue_list_head(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required);
-struct mwifiex_linked_list *mwifiex_util_dequeue_list(struct mwifiex_list_head
- *head, u8 lock_required);
-struct mwifiex_linked_list *mwifiex_util_peek_list(struct mwifiex_list_head
- *head, u8 lock_required);
-
-/*
- * This function initializes a list without locking.
- */
-static inline void
-mwifiex_util_init_list(struct mwifiex_linked_list *head)
-{
- head->next = (struct mwifiex_linked_list *) head;
- head->prev = head->next;
-}
-
-/*
- * This function frees a list and the associated lock.
- */
-static inline void
-mwifiex_util_free_list_head(struct mwifiex_list_head *head)
-{
- head->next = NULL;
- head->prev = head->next;
-}
#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 2a403ae..4b43a79 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -121,8 +121,9 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
PRINTM(MERROR, "%s: failed to alloc ra_list\n", __func__);
goto done;
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) ra_list);
- mwifiex_util_init_list_head(&ra_list->buf_head, false);
+ INIT_LIST_HEAD((struct list_head *) ra_list);
+ INIT_LIST_HEAD(&ra_list->buf_head);
+ spin_lock_init(&ra_list->ra_list_tbl_lock);
memcpy(ra_list->ra, ra, MWIFIEX_MAC_ADDR_LENGTH);
@@ -196,10 +197,8 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
PRINTM(MDATA, "ralist %p: is_11n_enabled=%d\n", ra_list,
ra_list->is_11n_enabled);
- mwifiex_util_enqueue_list_tail(&priv->wmm.tid_tbl_ptr[i].
- ra_list,
- (struct mwifiex_linked_list *)
- ra_list, false);
+ list_add_tail((struct list_head *)ra_list,
+ &priv->wmm.tid_tbl_ptr[i].ra_list);
if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
@@ -553,18 +552,13 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
ENTER();
- while ((mbuf =
- (struct mwifiex_buffer *) mwifiex_util_peek_list(&ra_list->
- buf_head,
- false))) {
- mwifiex_util_unlink_list(&ra_list->buf_head,
- (struct mwifiex_linked_list *) mbuf,
- false);
-
+ while (!list_empty(&ra_list->buf_head)) {
+ mbuf = (struct mwifiex_buffer *) ra_list->buf_head.next;
+ list_del((struct list_head *) mbuf);
mwifiex_write_data_complete(adapter, mbuf,
- MWIFIEX_STATUS_FAILURE);
+ MWIFIEX_STATUS_FAILURE);
}
- mwifiex_util_free_list_head(&ra_list->buf_head);
+ list_del(&ra_list->buf_head);
LEAVE();
}
@@ -577,15 +571,16 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
*/
static void
mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv,
- struct mwifiex_list_head *ra_list_head)
+ struct list_head *ra_list_head)
{
struct mwifiex_ra_list_tbl *ra_list;
ENTER();
- ra_list =
- (struct mwifiex_ra_list_tbl *)
- mwifiex_util_peek_list(ra_list_head, false);
+ if (list_empty(ra_list_head))
+ return;
+
+ ra_list = (struct mwifiex_ra_list_tbl *) ra_list_head->next;
while (ra_list
&& ra_list != (struct mwifiex_ra_list_tbl *) ra_list_head) {
@@ -629,20 +624,17 @@ mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
for (i = 0; i < MAX_NUM_TID; ++i) {
PRINTM(MINFO, "RAList: Freeing buffers for TID %d\n", i);
- while ((ra_list =
- (struct mwifiex_ra_list_tbl *)
- mwifiex_util_peek_list(&priv->wmm.tid_tbl_ptr[i].
- ra_list, false))) {
- mwifiex_util_unlink_list(&priv->wmm.tid_tbl_ptr[i].
- ra_list,
- (struct mwifiex_linked_list *)
- ra_list, false);
-
+ while (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) {
+ ra_list = (struct mwifiex_ra_list_tbl *)
+ priv->wmm.tid_tbl_ptr[i]
+ .ra_list.next;
+ list_del((struct list_head *)ra_list);
kfree(ra_list);
}
- mwifiex_util_init_list((struct mwifiex_linked_list *)
- &priv->wmm.tid_tbl_ptr[i].ra_list);
+ INIT_LIST_HEAD((struct list_head *) &priv->wmm.tid_tbl_ptr[i]
+ .ra_list);
+
priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
}
@@ -658,14 +650,16 @@ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
u8 *ra_addr)
{
struct mwifiex_ra_list_tbl *ra_list;
+
ENTER();
- ra_list =
- (struct mwifiex_ra_list_tbl *) mwifiex_util_peek_list(&priv->
- wmm.
- tid_tbl_ptr
- [tid].
- ra_list,
- false);
+
+ if (list_empty(&priv->wmm.tid_tbl_ptr[tid].ra_list))
+ return NULL;
+
+ ra_list = (struct mwifiex_ra_list_tbl *)
+ priv->wmm.tid_tbl_ptr[tid]
+ .ra_list.next;
+
while (ra_list && (ra_list != (struct mwifiex_ra_list_tbl *)
&priv->wmm.tid_tbl_ptr[tid].ra_list)) {
if (!memcmp(ra_list->ra, ra_addr, MWIFIEX_MAC_ADDR_LENGTH)) {
@@ -714,15 +708,15 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv,
{
struct mwifiex_ra_list_tbl *rlist;
- rlist = (struct mwifiex_ra_list_tbl *) mwifiex_util_peek_list(&priv->
- wmm.
- tid_tbl_ptr
- [ptr_index].
- ra_list,
- false);
+ if (list_empty(&priv->wmm.tid_tbl_ptr[ptr_index].ra_list))
+ return false;
+
+ rlist = (struct mwifiex_ra_list_tbl *)
+ priv->wmm.tid_tbl_ptr[ptr_index]
+ .ra_list.next;
while (rlist && (rlist != (struct mwifiex_ra_list_tbl *)
- &priv->wmm.tid_tbl_ptr[ptr_index].ra_list)) {
+ &priv->wmm.tid_tbl_ptr[ptr_index].ra_list)) {
if (rlist == ra_list)
return true;
@@ -773,10 +767,12 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
association we just don't have to call get_queue_raptr, we will
have only 1 raptr for a tid in case of infra */
if (!mwifiex_queuing_ra_based(priv)) {
- ra_list =
- (struct mwifiex_ra_list_tbl *)
- mwifiex_util_peek_list(&priv->wmm.tid_tbl_ptr[tid_down].
- ra_list, false);
+ if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
+ ra_list = (struct mwifiex_ra_list_tbl *)
+ priv->wmm.tid_tbl_ptr[tid_down]
+ .ra_list.next;
+ else
+ ra_list = NULL;
} else {
memcpy(ra, mbuf->buffer + mbuf->data_offset,
MWIFIEX_MAC_ADDR_LENGTH);
@@ -792,9 +788,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
}
PRINTM(MDAT_D, "Adding pkt to ra_list %p %p\n", ra_list, mbuf);
- mwifiex_util_enqueue_list_tail(&ra_list->buf_head,
- (struct mwifiex_linked_list *) mbuf,
- false);
+ list_add_tail((struct list_head *) mbuf, &ra_list->buf_head);
ra_list->total_pkts_size += mbuf->data_len;
@@ -1016,15 +1010,21 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
struct mwifiex_ra_list_tbl *ptr, *head;
struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
struct mwifiex_tid_tbl *tid_ptr;
+ int is_list_empty;
+ unsigned long flags;
int i, j;
ENTER();
PRINTM(MDAT_D, "POP\n");
for (j = adapter->priv_num - 1; j >= 0; --j) {
- if (!
- (mwifiex_util_peek_list
- (&adapter->bss_prio_tbl[j].bss_prio_head, true)))
+ spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
+ flags);
+ is_list_empty = list_empty(&adapter->bss_prio_tbl[j]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
+ flags);
+ if (is_list_empty)
continue;
if (adapter->bss_prio_tbl[j].bss_prio_cur ==
@@ -1047,8 +1047,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
tid_ptr =
&(priv_tmp)->wmm.
tid_tbl_ptr[tos_to_tid[i]];
- if (!mwifiex_util_peek_list
- (&tid_ptr->ra_list, true))
+
+ spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
+ flags);
+ is_list_empty =
+ list_empty(&adapter->bss_prio_tbl[j]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock,
+ flags);
+ if (is_list_empty)
continue;
/*
@@ -1065,8 +1072,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
}
do {
- if (mwifiex_util_peek_list
- (&ptr->buf_head, true)) {
+ spin_lock_irqsave(
+ &ptr->ra_list_tbl_lock,
+ flags);
+ is_list_empty =
+ list_empty(&ptr->buf_head);
+ spin_unlock_irqrestore(
+ &ptr->ra_list_tbl_lock,
+ flags);
+ if (!is_list_empty) {
*priv = priv_tmp;
*tid = tos_to_tid[i];
LEAVE();
@@ -1126,7 +1140,7 @@ mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
static void
mwifiex_send_single_packet(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *ptr, int ptr_index,
- unsigned long flags)
+ unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock)
{
struct mwifiex_buffer *mbuf;
@@ -1134,65 +1148,77 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
struct mwifiex_tx_param tx_param;
struct mwifiex_adapter *adapter = priv->adapter;
enum mwifiex_status status = MWIFIEX_STATUS_SUCCESS;
+ unsigned long ra_list_tbl_flags;
ENTER();
- mbuf = (struct mwifiex_buffer *)
- mwifiex_util_dequeue_list(&ptr->buf_head, true);
- if (mbuf) {
- PRINTM(MDATA, "Dequeuing the packet %p %p\n", ptr, mbuf);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ if (list_empty(&ptr->buf_head)) {
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ PRINTM(MDATA, "Nothing to send\n");
+ return;
+ }
+ mbuf = (struct mwifiex_buffer *) ptr->buf_head.next;
+ list_del((struct list_head *)mbuf);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+
+ PRINTM(MDATA, "Dequeuing the packet %p %p\n", ptr, mbuf);
+
+ ptr->total_pkts_size -= mbuf->data_len;
+
+ if (!list_empty(&ptr->buf_head))
+ mbuf_next = (struct mwifiex_buffer *)
+ ptr->buf_head.next;
+ else
+ mbuf_next = NULL;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ tx_param.next_pkt_len =
+ ((mbuf_next) ? mbuf_next->data_len +
+ sizeof(struct txpd) : 0);
+ status = mwifiex_process_tx(priv, mbuf, &tx_param);
+
+ if (status == MWIFIEX_STATUS_RESOURCE) {
+ /** Queue the packet back at the head */
+ PRINTM(MDAT_D, "Queuing pkt back to raList %p %p\n",
+ ptr, mbuf);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(
+ &priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, mbuf,
+ MWIFIEX_STATUS_FAILURE);
+ LEAVE();
+ return;
+ }
- ptr->total_pkts_size -= mbuf->data_len;
- mbuf_next =
- (struct mwifiex_buffer *) mwifiex_util_peek_list(&ptr->
- buf_head,
- false);
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ list_add((struct list_head *) mbuf, &ptr->buf_head);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
- tx_param.next_pkt_len =
- ((mbuf_next) ? mbuf_next->data_len +
- sizeof(struct txpd) : 0);
- status = mwifiex_process_tx(priv, mbuf, &tx_param);
-
- if (status == MWIFIEX_STATUS_RESOURCE) {
- /** Queue the packet back at the head */
- PRINTM(MDAT_D, "Queuing pkt back to raList %p %p\n",
- ptr, mbuf);
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
-
- if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- spin_unlock_irqrestore(
- &priv->wmm.ra_list_spinlock,
- flags);
- mwifiex_write_data_complete(adapter, mbuf,
- MWIFIEX_STATUS_FAILURE);
- LEAVE();
- return;
- }
- mwifiex_util_enqueue_list_head(&ptr->buf_head,
- (struct mwifiex_linked_list *)
- mbuf, true);
-
- ptr->total_pkts_size += mbuf->data_len;
- mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- } else {
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
- if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- priv->wmm.packets_out[ptr_index]++;
- priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
- ptr;
- }
- adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
- adapter->bss_prio_tbl[priv->bss_priority].
- bss_prio_cur->next;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- }
+ ptr->total_pkts_size += mbuf->data_len;
+ mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
} else {
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- PRINTM(MDATA, "Nothing to send\n");
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ priv->wmm.packets_out[ptr_index]++;
+ priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
+ ptr;
+ }
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ adapter->bss_prio_tbl[priv->bss_priority].
+ bss_prio_cur->next;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
}
LEAVE();
@@ -1208,9 +1234,12 @@ mwifiex_is_ptr_processed(struct mwifiex_private *priv,
{
struct mwifiex_buffer *mbuf;
- mbuf = (struct mwifiex_buffer *)
- mwifiex_util_peek_list(&ptr->buf_head, false);
- if (mbuf && (mbuf->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT))
+ if (list_empty(&ptr->buf_head))
+ return false;
+
+ mbuf = (struct mwifiex_buffer *) ptr->buf_head.next;
+
+ if (mbuf->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT)
return true;
return false;
@@ -1223,7 +1252,7 @@ mwifiex_is_ptr_processed(struct mwifiex_private *priv,
static void
mwifiex_send_processed_packet(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *ptr, int ptr_index,
- unsigned long flags)
+ unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock)
{
struct mwifiex_buffer *mbuf_next;
@@ -1231,72 +1260,84 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
struct mwifiex_buffer *mbuf;
struct mwifiex_adapter *adapter = priv->adapter;
enum mwifiex_status ret = MWIFIEX_STATUS_FAILURE;
+ unsigned long ra_list_tbl_flags;
ENTER();
- mbuf = (struct mwifiex_buffer *)
- mwifiex_util_dequeue_list(&ptr->buf_head, true);
- if (mbuf) {
- mbuf_next =
- (struct mwifiex_buffer *) mwifiex_util_peek_list(&ptr->
- buf_head,
- false);
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- tx_param.next_pkt_len =
- ((mbuf_next) ? mbuf_next->data_len +
- sizeof(struct txpd) : 0);
- ret = adapter->if_ops.host_to_card(adapter,
- MWIFIEX_TYPE_DATA, mbuf,
- &tx_param);
- switch (ret) {
- case MWIFIEX_STATUS_RESOURCE:
- PRINTM(MDATA, "MWIFIEX_STATUS_RESOURCE is returned\n");
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
-
- if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- spin_unlock_irqrestore(
- &priv->wmm.ra_list_spinlock,
- flags);
- mwifiex_write_data_complete(adapter, mbuf,
- MWIFIEX_STATUS_FAILURE);
- LEAVE();
- return;
- }
- mwifiex_util_enqueue_list_head(&ptr->buf_head,
- (struct mwifiex_linked_list *)
- mbuf, true);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ if (list_empty(&ptr->buf_head)) {
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return;
+ }
- mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- break;
- case MWIFIEX_STATUS_FAILURE:
- adapter->data_sent = false;
- PRINTM(MERROR,
- "Error: mwifiex_write_data failed: 0x%X\n", ret);
- adapter->dbg.num_tx_host_to_card_failure++;
- mwifiex_write_data_complete(adapter, mbuf, ret);
- break;
- case MWIFIEX_STATUS_PENDING:
- adapter->data_sent = false;
- default:
- break;
+ mbuf = (struct mwifiex_buffer *) &ptr->buf_head.next;
+ list_del((struct list_head *)mbuf);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+
+ if (!list_empty(&ptr->buf_head))
+ mbuf_next = (struct mwifiex_buffer *)
+ ptr->buf_head.next;
+ else
+ mbuf_next = NULL;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ tx_param.next_pkt_len =
+ ((mbuf_next) ? mbuf_next->data_len +
+ sizeof(struct txpd) : 0);
+ ret = adapter->if_ops.host_to_card(adapter,
+ MWIFIEX_TYPE_DATA, mbuf,
+ &tx_param);
+ switch (ret) {
+ case MWIFIEX_STATUS_RESOURCE:
+ PRINTM(MDATA, "MWIFIEX_STATUS_RESOURCE is returned\n");
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(
+ &priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, mbuf,
+ MWIFIEX_STATUS_FAILURE);
+ LEAVE();
+ return;
}
- if (ret != MWIFIEX_STATUS_RESOURCE) {
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
- if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- priv->wmm.packets_out[ptr_index]++;
- priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
- ptr;
- }
- adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
- adapter->bss_prio_tbl[priv->bss_priority].
- bss_prio_cur->next;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
+
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ list_add((struct list_head *) mbuf, &ptr->buf_head);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+
+ mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ break;
+ case MWIFIEX_STATUS_FAILURE:
+ adapter->data_sent = false;
+ PRINTM(MERROR,
+ "Error: mwifiex_write_data failed: 0x%X\n", ret);
+ adapter->dbg.num_tx_host_to_card_failure++;
+ mwifiex_write_data_complete(adapter, mbuf, ret);
+ break;
+ case MWIFIEX_STATUS_PENDING:
+ adapter->data_sent = false;
+ default:
+ break;
+ }
+ if (ret != MWIFIEX_STATUS_RESOURCE) {
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ priv->wmm.packets_out[ptr_index]++;
+ priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
+ ptr;
}
- } else {
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ adapter->bss_prio_tbl[priv->bss_priority].
+ bss_prio_cur->next;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
}
LEAVE();
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 88f4480..d6fe0a2 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -28,11 +28,17 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter,
struct mwifiex_ra_list_tbl *ptr)
{
struct mwifiex_buffer *mbuf;
+ unsigned long flags;
ENTER();
- mbuf = (struct mwifiex_buffer *) mwifiex_util_peek_list(&ptr->buf_head,
- true);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, flags);
+ if (list_empty(&ptr->buf_head)) {
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, flags);
+ return 0;
+ }
+ mbuf = (struct mwifiex_buffer *) ptr->buf_head.next;
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, flags);
LEAVE();
return mbuf->priority;
@@ -43,16 +49,16 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter,
*/
static inline int
mwifiex_wmm_list_len(struct mwifiex_adapter *adapter,
- struct mwifiex_list_head *head)
+ struct list_head *head)
{
- struct mwifiex_linked_list *pos;
+ struct list_head *pos;
int count = 0;
ENTER();
pos = head->next;
- while (pos != (struct mwifiex_linked_list *) head) {
+ while (pos != (struct list_head *) head) {
++count;
pos = pos->next;
}
@@ -66,14 +72,19 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter,
*/
static inline u8
mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter,
- struct mwifiex_list_head *ra_list_hhead)
+ struct list_head *ra_list_hhead)
{
struct mwifiex_ra_list_tbl *ra_list;
+ int is_list_empty;
+ unsigned long flags;
ra_list = (struct mwifiex_ra_list_tbl *) ra_list_hhead->next;
while (ra_list != (struct mwifiex_ra_list_tbl *) ra_list_hhead) {
- if (mwifiex_util_peek_list(&ra_list->buf_head, true))
+ spin_lock_irqsave(&ra_list->ra_list_tbl_lock, flags);
+ is_list_empty = list_empty(&ra_list->buf_head);
+ spin_unlock_irqrestore(&ra_list->ra_list_tbl_lock, flags);
+ if (!is_list_empty)
return false;
ra_list = (struct mwifiex_ra_list_tbl *) ra_list->next;
--
1.7.0.2
^ permalink raw reply related
* Kernel Panic wlc_mac80211.c Line 6093
From: Jamie Kitson @ 2011-01-08 0:37 UTC (permalink / raw)
To: linux-wireless
Hello,
I've received the following kernel panic twice in two days since I
started using the brcm80211 driver:
http://farm6.static.flickr.com/5202/5334637544_a0dacd5edd_b.jpg
I have a Dell M101z with:
03:00.0 Network controller: Broadcom Corporation BCM4313 802.11b/g/n
Wireless LAN Controller (rev 01)
I am running:
Linux jamie-laptop 2.6.36-ARCH #1 SMP PREEMPT Fri Dec 10 20:32:37 CET
2010 x86_64 AMD Athlon(tm) II Neo K325 Dual-Core Processor
AuthenticAMD GNU/Linux
Cheers, Jamie
^ permalink raw reply
* [RFC] ath9k: Try all queues when looking for next packet to send.
From: greearb @ 2011-01-08 0:27 UTC (permalink / raw)
To: linux-wireless; +Cc: ath9k-devel, Ben Greear
From: Ben Greear <greearb@candelatech.com>
There can be multiple struct ath_atx_ac entries for each
txq, so if the first one doesn't have any packets to send
now, try the rest of them. This should help keep xmit
going when using multiple stations, especially with AMPDU
enabled.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 e63de71... a7a8f8f... M drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/ath9k/xmit.c | 99 ++++++++++++++++++++-------------
1 files changed, 60 insertions(+), 39 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index e63de71..a7a8f8f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -54,8 +54,8 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
struct ath_tx_status *ts, int txok, int sendbar);
-static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
- struct list_head *head);
+static int ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+ struct list_head *head);
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
int nframes, int nbad, int txok, bool update_rc);
@@ -789,18 +789,21 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
#undef PADBYTES
}
-static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid)
+/* Return number of buffers set up for transmit. */
+static int ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid)
{
struct ath_buf *bf;
enum ATH_AGGR_STATUS status;
struct ath_frame_info *fi;
struct list_head bf_q;
int aggr_len;
+ int cnt = 0;
+ int rv;
do {
if (list_empty(&tid->buf_q))
- return;
+ return cnt;
INIT_LIST_HEAD(&bf_q);
@@ -811,7 +814,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
* block-ack window is not open.
*/
if (list_empty(&bf_q))
- break;
+ return cnt;
bf = list_first_entry(&bf_q, struct ath_buf, list);
bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
@@ -823,7 +826,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
bf->bf_state.bf_type &= ~BUF_AGGR;
ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
ath_buf_set_rate(sc, bf, fi->framelen);
- ath_tx_txqaddbuf(sc, txq, &bf_q);
+ rv = ath_tx_txqaddbuf(sc, txq, &bf_q);
+ if (rv > 0) {
+ TX_STAT_INC(txq->axq_qnum, a_aggr);
+ cnt += rv;
+ }
continue;
}
@@ -835,11 +842,15 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
/* anchor last desc of aggregate */
ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
- ath_tx_txqaddbuf(sc, txq, &bf_q);
- TX_STAT_INC(txq->axq_qnum, a_aggr);
+ rv = ath_tx_txqaddbuf(sc, txq, &bf_q);
+ if (rv > 0) {
+ TX_STAT_INC(txq->axq_qnum, a_aggr);
+ cnt += rv;
+ }
} while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
status != ATH_AGGR_BAW_CLOSED);
+ return rv;
}
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1218,46 +1229,54 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
}
+/** For each axq_acq entry, for each tid, if we can transmit
+ * one, do so and break out.
+ */
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
{
- struct ath_atx_ac *ac;
+ struct ath_atx_ac *ac, *ac_tmp, *last;
struct ath_atx_tid *tid;
+ bool did_one = false;
if (list_empty(&txq->axq_acq))
return;
+
+ last = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
+ list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+ list_del(&ac->list);
+ ac->sched = false;
- ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
- list_del(&ac->list);
- ac->sched = false;
-
- do {
- if (list_empty(&ac->tid_q))
- return;
+ while (!list_empty(&ac->tid_q)) {
- tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
- list_del(&tid->list);
- tid->sched = false;
+ tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+ list_del(&tid->list);
+ tid->sched = false;
- if (tid->paused)
- continue;
+ if (tid->paused)
+ continue;
- ath_tx_sched_aggr(sc, txq, tid);
+ if (ath_tx_sched_aggr(sc, txq, tid) > 0)
+ did_one = true;
- /*
- * add tid to round-robin queue if more frames
- * are pending for the tid
- */
- if (!list_empty(&tid->buf_q))
- ath_tx_queue_tid(txq, tid);
+ /*
+ * add tid to round-robin queue if more frames
+ * are pending for the tid
+ */
+ if (!list_empty(&tid->buf_q))
+ ath_tx_queue_tid(txq, tid);
- break;
- } while (!list_empty(&ac->tid_q));
+ break;
+ }
- if (!list_empty(&ac->tid_q)) {
- if (!ac->sched) {
- ac->sched = true;
- list_add_tail(&ac->list, &txq->axq_acq);
+ if (!list_empty(&ac->tid_q)) {
+ if (!ac->sched) {
+ ac->sched = true;
+ list_add_tail(&ac->list, &txq->axq_acq);
+ }
}
+
+ if (did_one || (ac == last))
+ return;
}
}
@@ -1268,9 +1287,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
/*
* Insert a chain of ath_buf (descriptors) on a txq and
* assume the descriptors are already chained together by caller.
+ * Return number of buffers sent to DMA.
*/
-static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
- struct list_head *head)
+static int ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+ struct list_head *head)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
@@ -1282,7 +1302,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
*/
if (list_empty(head))
- return;
+ return 0;
bf = list_first_entry(head, struct ath_buf, list);
@@ -1292,7 +1312,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
list_splice_tail_init(head, &txq->txq_fifo_pending);
- return;
+ return 0;
}
if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
ath_dbg(common, ATH_DBG_XMIT,
@@ -1326,6 +1346,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
txq->axq_depth++;
if (bf_is_ampdu_not_probing(bf))
txq->axq_ampdu_depth++;
+ return 1;
}
static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
--
1.7.2.3
^ permalink raw reply related
* Re: [ath9k-devel] ath9k tx lockup, ath: received PCI FATAL interrupt
From: Peter Stuge @ 2011-01-07 23:42 UTC (permalink / raw)
To: ath9k-devel, linux-wireless
In-Reply-To: <1294441714.12213.75.camel@jm-desktop>
Jouni Malinen wrote:
> > Only ath9k (ie. neither ipw2200 nor ath5k) has ever made a
> > difference between wpa_supplicant running or not.
>
> You won't need wpa_supplicant for an open network that has only a
> single AP and if you never get disconnected (which could happen,
> e.g., if you leave the range for a moment).
Thanks for confirming this!
> mac80211 will not be reconnecting to the network on its own
> automatically, so you need something like wpa_supplicant to do it
> for you.
Right, I had understood that to also be the case. I may not agree but
in any case that's a different topic.
However, since neither laptop nor AP is moving around much I also do
not expect to get disconnected. Let's see how life with master-2011-01-05
turns out!
> > 1. ath: received PCI FATAL interrupt
> >
> > How can I find out more about the reason for this?
>
> Have you looked at enabling debugging in ath9k?
Yes, and I dug around adding some code last year when I first got
started with ath9k. Unfortunately I forgot to pass debug when
loading the driver today.
> For the PCI fatal interrupt, it would be useful to have at least
> interrupt and fatal levels included.
Hold on.. OK, reloaded now with debug=0x410.
> If the output is still readable (i.e., you can still find the PCI
> fatal message), enabling more of these could end up providing more
> details, too.
ATH_DBG_INTERRUPT is spamming the kernel log with a disable/enable
IER at least every 100ms but usually much more often. A snippet:
[10654.729417] ath: disable IER
[10654.729430] ath: AR_IMR 0x918414b0 IER 0x1
[10654.729452] ath: enable IER
[10654.729462] ath: AR_IMR 0x918414b0 IER 0x1
[10654.729581] ath: disable IER
[10654.729601] ath: enable IER
[10654.729619] ath: disable IER
[10654.729633] ath: AR_IMR 0x918414b0 IER 0x1
[10654.729665] ath: enable IER
[10654.729676] ath: AR_IMR 0x918414b0 IER 0x1
[10654.729729] ath: disable IER
[10654.729749] ath: enable IER
[10654.729760] ath: AR_IMR 0x918414b0 IER 0x1
[10654.735625] ath: disable IER
[10654.735662] ath: enable IER
[10654.735674] ath: AR_IMR 0x918414b0 IER 0x1
[10654.829084] ath: disable IER
[10654.829103] ath: enable IER
[10654.829115] ath: AR_IMR 0x918414b0 IER 0x1
[10654.829176] ath: disable IER
[10654.829203] ath: enable IER
[10654.829214] ath: AR_IMR 0x918414b0 IER 0x1
[10654.829237] ath: 0xf4041171 => 0xf4041171
[10654.829244] ath: new IMR 0x918414b0
[10654.829252] ath: enable IER
[10654.829263] ath: AR_IMR 0x918414b0 IER 0x1
[10654.837973] ath: disable IER
[10654.838010] ath: enable IER
[10654.838021] ath: AR_IMR 0x918414b0 IER 0x1
[10654.940330] ath: disable IER
[10654.940374] ath: enable IER
[10654.940386] ath: AR_IMR 0x918414b0 IER 0x1
[10655.042682] ath: disable IER
[10655.042724] ath: enable IER
[10655.042737] ath: AR_IMR 0x918414b0 IER 0x1
So now my dmesg is only some 6000 lines of this, going back 30
seconds or so. Would it make sense to bump the kernel log size
significantly to have maybe several minutes?
> Have you happened to test that WLAN card in any other system or
> with any other driver?
No.
> It could be useful to make sure it is known to be working reliably
> before spending huge amount of work trying to figure out why it
> doesn't work properly with ath9k..
True. The card was brand new in ESD bag when I installed it. It comes
out of a batch of cards that ship as part of a commercial product
running in AP mode with good performance.
Your point is solid, but I have no easy way to test something else.
Would FreeBSD be a useful data point, or is some Windows the only
reliable reference in this case?
> > 2. Unworking association without wpa_supplicant after power cycle
> >
> > How can I find out more about the reason for this?
>
> The part where the dmesg output had "direct probe to <BSSID> timed out"
> could potentially be caused by card RX not working properly.
Hm? This message is in log2_after_wpa_supplicant_4x_trying_to_auth.txt
which is dmesg following the PCI FATAL interrupt and then running
wpa_supplicant, but before the power cycle. The issue above is rather
what can be seen in log4..log5, and going away in log6..log7 when I
try iw connect again *with* wpa_supplicant running.
> I've seen that happen in some cases (with rmmod + modprobe ath9k
> being one way of recovering from that state). Looking at the RX
> interrupt counters in ath9k debugfs and checking whether they
> increment could be of use here. In general, verifying RX registers
> (filter, descriptors) would likely follow in getting more details.
Thanks for the pointers! When I first had problems about a year ago I
did look at and post (only to ath9k-devel) interrupt counter values,
but no obvious problem showed. (Rather, there were no comments.)
I'll remember to also instrument debugfs if/when next problem hits.
//Peter
^ permalink raw reply
* Re: [rt2x00-users] Linksys WUSB600N v1 disconnecting from AP
From: Jouni Malinen @ 2011-01-07 23:26 UTC (permalink / raw)
To: Luis R. Rodriguez, Aleksandar Milivojevic,
linux-wireless@vger.kernel.org, users@rt2x00.serialmonkey.com,
Luis Rodriguez
In-Reply-To: <20110107221305.6484.qmail@stuge.se>
On Fri, Jan 07, 2011 at 11:13:05PM +0100, Peter Stuge wrote:
> Luis R. Rodriguez wrote:
> > bgscan="simple:30:-45:300"
> ..
> > No Linux distributions today uses this other than ChromeOS, but
> > they should all change to use it.
>
> Maybe wpa_supplicant should be changed to use it by default?
It probably should at some point. I did not want to do it during early
development part of bgscan, but it could now be a reasonable change in
the current development branch (obviously only if the build is
configured to include bgscan). Though, that signal level value is a bit
hardware specific, so -45 may not be ideal for everything. In addition,
the bgscan learn module could be better for many networks.
Though, there is a drawback involved with this, too. In case of a
networks with only a single AP, this would be adding unnecessary
background scanning every 30 or 300 seconds based on signal strength. As
such, enabling the functionality by default is a bit problematic if
there is no mechanism for the user to disable it.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [ath9k-devel] [PATCH v2 3/3] ath9k: Keep track of stations for debugfs.
From: Felix Fietkau @ 2011-01-07 23:24 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: greearb@candelatech.com, linux-wireless@vger.kernel.org,
ath9k-devel@venema.h4ckr.net
In-Reply-To: <20110107201204.GG21588@tux>
On 2011-01-07 1:12 PM, Luis R. Rodriguez wrote:
> On Thu, Jan 06, 2011 at 08:49:12PM -0800, greearb@candelatech.com wrote:
>> From: Ben Greear<greearb@candelatech.com>
>>
>> The stations hold the ath_node, which holds the tid
>> and other xmit logic structures. In order to debug
>> stuck xmit logic, we need a way to print out the tid
>> state for the stations.
>>
>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>> ---
>>
>> v1 -> v2: Use linked list instead of array. Protect with spinlock.
>
> Again, see my comments about the # STAs limit. I think this can go in
> as a cfg80211 driver limitation which can be exposed. If you want to go
> over the supported number (known to work, safe, call it what you want)
> then a kconfig option can be used.
I disagree with putting in an essentially arbitrary restriction based on
what has been tested, unless we can actually point at a *specific*
limitation that makes the limit necessary.
If ath9k gets unstable with too many STA interfaces, then we should
identify the underlying cause or fix it.
- Felix
^ permalink raw reply
* Re: Compat-wireless as is on ChromeOS head 2011-01-07 for ath9k
From: Luis R. Rodriguez @ 2011-01-07 23:11 UTC (permalink / raw)
To: linux-wireless; +Cc: Paul Stewart, Nael Atallah
In-Reply-To: <AANLkTingv5Ur6UHeZoKhfYpTUw6wGMK7ULPm7V49UfPn@mail.gmail.com>
On Fri, Jan 7, 2011 at 2:54 PM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.36/mods/compat-wireless-2.6.36-5-spn-google-2011-01-07.tar.bz2
> sha1sum: 8cd9e5eb74292d23c511cddbf0cb2d26f0451d9a
For a release that actually compiles and is load tested:
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.36/mods/compat-wireless-2.6.36-5-spn-chromium-kernel-2011-01-07.tar.bz2
sha1sum: 8c9ebaa0bf83404bc9f70bd7fc10ae75865cf3b2
I had forgotten to also update include/ directory.
Luis
^ permalink raw reply
* Re: [ath9k-devel] ath9k tx lockup, ath: received PCI FATAL interrupt
From: Jouni Malinen @ 2011-01-07 23:08 UTC (permalink / raw)
To: Peter Stuge; +Cc: ath9k-devel@lists.ath9k.org, linux-wireless@vger.kernel.org
In-Reply-To: <20110107215549.4053.qmail@stuge.se>
On Fri, 2011-01-07 at 13:55 -0800, Peter Stuge wrote:
> I normally never use wpa_supplicant. I don't accept that it would be
> required for a working connection and so far noone has really
> explained why that would be the case. Only ath9k (ie. neither ipw2200
> nor ath5k) has ever made a difference between wpa_supplicant running
> or not.
You won't need wpa_supplicant for an open network that has only a single
AP and if you never get disconnected (which could happen, e.g., if you
leave the range for a moment). mac80211 will not be reconnecting to the
network on its own automatically, so you need something like
wpa_supplicant to do it for you.
> The above identifies at least two issues:
>
> 1. ath: received PCI FATAL interrupt
>
> How can I find out more about the reason for this?
Have you looked at enabling debugging in ath9k? This is described at
http://wireless.kernel.org/en/users/Drivers/ath9k/debug
For the PCI fatal interrupt, it would be useful to have at least
interrupt and fatal levels included. If the output is still readable
(i.e., you can still find the PCI fatal message), enabling more of these
could end up providing more details, too.
Have you happened to test that WLAN card in any other system or with any
other driver? It could be useful to make sure it is known to be working
reliably before spending huge amount of work trying to figure out why it
doesn't work properly with ath9k..
> 2. Unworking association without wpa_supplicant after power cycle
>
> How can I find out more about the reason for this?
The part where the dmesg output had "direct probe to <BSSID> timed out"
could potentially be caused by card RX not working properly. I've seen
that happen in some cases (with rmmod + modprobe ath9k being one way of
recovering from that state). Looking at the RX interrupt counters in
ath9k debugfs and checking whether they increment could be of use here.
In general, verifying RX registers (filter, descriptors) would likely
follow in getting more details.
- Jouni
^ permalink raw reply
* Re: [rt2x00-users] Linksys WUSB600N v1 disconnecting from AP
From: Peter Stuge @ 2011-01-07 23:00 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Aleksandar Milivojevic, linux-wireless@vger.kernel.org,
users@rt2x00.serialmonkey.com, Luis Rodriguez
In-Reply-To: <AANLkTikL0ONLAd7qncZtafRpxQh1jBG9_xs5xPjTgAxT@mail.gmail.com>
Luis R. Rodriguez wrote:
> >> bgscan="simple:30:-45:300"
> > ..
> >> No Linux distributions today uses this other than ChromeOS, but
> >> they should all change to use it.
> >
> > Maybe wpa_supplicant should be changed to use it by default?
>
> The supplicant is configured by dbus,
In some realities, this is true. In many others it is not.
> so its not up to the supplicant by design.
It has a default value. If there is another, more correct, value to
use as default then maybe it should be changed?
> What has to change is Network Manager and connman needs to change
> to use bgscan by default.
That's also true.
But the correct place for sane defaults is not the top layer of a
stack, it is of course *every* layer of the stack.
//Peter
^ permalink raw reply
* Compat-wireless as is on ChromeOS head 2011-01-07 for ath9k
From: Luis R. Rodriguez @ 2011-01-07 22:54 UTC (permalink / raw)
To: linux-wireless; +Cc: Paul Stewart, Nael Atallah
FWIW I've taken a snapshot of today's ChromeOS kernel.git tree and
sucked out any delta from the original compat-wireless-v2.6.36-5-spn
used there on:
net/wireless
net/mac80211/
drivers/net/wireless/ath/
and put it back into a vanilla compat-wireless-v2.6.36-5-spn with
ath9k selected already for driver-select. I figured others might want
to test this for some other reasons so here is the code:
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.36/mods/compat-wireless-2.6.36-5-spn-google-2011-01-07.tar.bz2
sha1sum: 8cd9e5eb74292d23c511cddbf0cb2d26f0451d9a
The hope is the delta + anything else we need for the future will go
into a vanilla -6 release.
Luis
^ permalink raw reply
* Re: [rt2x00-users] Linksys WUSB600N v1 disconnecting from AP
From: Aleksandar Milivojevic @ 2011-01-07 22:54 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Helmut Schaa, Luis Rodriguez, linux-wireless@vger.kernel.org,
Wolfgang Kufner, Luis Correia, users@rt2x00.serialmonkey.com
In-Reply-To: <20110107202224.GI21588@tux>
On Fri, Jan 7, 2011 at 12:22 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> You may want to try checing the 'iw event -t' output while the issue happens.
> Maybe it is due to a roaming issue, if you are using a large BSS and roam
> in between you may want to try using wpa_supplicant with nl80211 and use
> the new bgscan module from wpa_supplicant to trigger you to only switch
> based on triggered events from nl80211 like signal rssi changes.
>
> Here is an example supplicant conf that uses the bgscan module:
>
> # WPA-PSK/TKIP
>
> ctrl_interface=/var/run/wpa_supplicant
>
> network={
> ssid="my-corp-cool-bss"
> bgscan="simple:30:-45:300"
> key_mgmt=WPA-PSK
> proto=RSN
> pairwise=CCMP
> group=CCMP
> psk="foobar_is_great"
> }
>
> No Linux distributions today uses this other than ChromeOS, but they should
> all change to use it.
I doubt it would help in this case, since things are very static.
There's only single AP (typical home network environment). The
wireless card is plugged into (and sits directly on top of) an
desktop, so its position in space is rather static (if I wanted to
make a bad attempt at being funny, I'd add "relative to the AP").
I'll check out what "iw event -t" has to say over the weekend.
^ permalink raw reply
* Re: [ath9k-devel] ath9k tx lockup, ath: received PCI FATAL interrupt
From: Peter Stuge @ 2011-01-07 22:47 UTC (permalink / raw)
To: ath9k-devel, linux-wireless
In-Reply-To: <AANLkTikb2bAeB6EqVoRSVvQUWqY70F4fO5d1cWKHgbRO@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1313 bytes --]
Brian Prodoehl wrote:
> Out of curiosity, what's your AP?
July 2006 Linux 2.6.17.6 madwifi-ng Mini PCI AR5212.
wlan: 0.8.4.2 (svn 1531)
ath_hal: module license 'Proprietary' taints kernel.
ath_hal: 0.9.16.16 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413)
ath_rate_sample: 1.2 (svn 1531)
ath_pci: 0.9.4.5 (svn 1531)
..
wifi0: mac 5.9 phy 4.3 radio 3.6
..
wifi0: Atheros 5212: mem=0xa0010000, irq=11
> I've never seen those "detected beacon loss from AP" messages.
I fully expect that this AP is not behaving perfectly, but that is of
course irrelevant in the scope of ath9k when ipw2200 ath5k orinoco_cs
can deal. If anything, the AP is valuable for debugging ath9k, which
is also why I prefer not to change the AP until it seems like all
issues have been solved.
(But I've had plenty of problems with ath9k also on various other
APs, just no logs from anything else today.)
> If you bring up a monitor-mode interface,
Then I got some new suspect messages in the kernel log. But internet
and monitor both work.
dmesg output in log8_after_iw_dev_eth1_interface_add_wmon0.txt
> do you see beacons at a sane, regular interval?
100ms, with some missing ones. (3 missing in 327 received, second
test 13 missing in 819 received over 93 seconds. Seems to match the
beacon loss messages.)
//Peter
[-- Attachment #2: log8_after_iw_dev_eth1_interface_add_wmon0.txt --]
[-- Type: text/plain, Size: 3674 bytes --]
[ 6454.002053] eth1: detected beacon loss from AP - sending probe request
[ 6456.004646] eth1: detected beacon loss from AP - sending probe request
[ 6456.077272] eth1: cancelling probereq poll due to a received beacon
[ 6467.002036] eth1: detected beacon loss from AP - sending probe request
[ 6467.029043] eth1: cancelling probereq poll due to a received beacon
[ 6471.002043] eth1: detected beacon loss from AP - sending probe request
[ 6471.123295] eth1: cancelling probereq poll due to a received beacon
[ 6479.002039] eth1: detected beacon loss from AP - sending probe request
[ 6479.415183] eth1: cancelling probereq poll due to a received beacon
[ 6484.004933] eth1: detected beacon loss from AP - sending probe request
[ 6484.429046] eth1: cancelling probereq poll due to a received beacon
[ 6499.002036] eth1: detected beacon loss from AP - sending probe request
[ 6505.004023] eth1: detected beacon loss from AP - sending probe request
[ 6505.411352] eth1: cancelling probereq poll due to a received beacon
[ 6517.002038] eth1: detected beacon loss from AP - sending probe request
[ 6519.002038] eth1: detected beacon loss from AP - sending probe request
[ 6521.004032] eth1: detected beacon loss from AP - sending probe request
[ 6523.004046] eth1: detected beacon loss from AP - sending probe request
[ 6526.004664] eth1: detected beacon loss from AP - sending probe request
[ 6528.004664] eth1: detected beacon loss from AP - sending probe request
[ 6530.004659] eth1: detected beacon loss from AP - sending probe request
[ 6532.004659] eth1: detected beacon loss from AP - sending probe request
[ 6534.002031] eth1: detected beacon loss from AP - sending probe request
[ 6538.002035] eth1: detected beacon loss from AP - sending probe request
[ 6538.060097] eth1: cancelling probereq poll due to a received beacon
[ 6539.002032] eth1: detected beacon loss from AP - sending probe request
[ 6539.083602] eth1: cancelling probereq poll due to a received beacon
[ 6563.004041] eth1: detected beacon loss from AP - sending probe request
[ 6584.002040] eth1: detected beacon loss from AP - sending probe request
[ 6590.004666] eth1: detected beacon loss from AP - sending probe request
[ 6590.363990] eth1: cancelling probereq poll due to a received beacon
[ 6594.004665] eth1: detected beacon loss from AP - sending probe request
[ 6596.004659] eth1: detected beacon loss from AP - sending probe request
[ 6596.196543] eth1: cancelling probereq poll due to a received beacon
[ 6603.002037] eth1: detected beacon loss from AP - sending probe request
[ 6603.055257] eth1: cancelling probereq poll due to a received beacon
[ 6611.004043] eth1: detected beacon loss from AP - sending probe request
[ 6611.343697] eth1: cancelling probereq poll due to a received beacon
[ 6621.002035] eth1: detected beacon loss from AP - sending probe request
[ 6621.476484] eth1: cancelling probereq poll due to a received beacon
[ 6625.004032] eth1: detected beacon loss from AP - sending probe request
[ 6630.004657] eth1: detected beacon loss from AP - sending probe request
[ 6630.073998] eth1: cancelling probereq poll due to a received beacon
[ 6636.004675] eth1: detected beacon loss from AP - sending probe request
[ 6636.112735] eth1: cancelling probereq poll due to a received beacon
[ 6644.002030] eth1: detected beacon loss from AP - sending probe request
[ 6644.198491] eth1: cancelling probereq poll due to a received beacon
[ 6673.144321] ath: Failed to stop TX DMA in 100 msec after killing last frame
[ 6673.144357] ath: Failed to stop TX DMA!
[ 6676.541321] ath: Failed to stop TX DMA in 100 msec after killing last frame
[ 6676.541357] ath: Failed to stop TX DMA!
^ permalink raw reply
* Re: [ath9k-devel] [PATCH 1/3] ath9k: Decrease skb size to fit into one page.
From: Ben Greear @ 2011-01-07 22:46 UTC (permalink / raw)
To: Eric Dumazet
Cc: Luis R. Rodriguez, Johannes Berg, ath9k-devel@venema.h4ckr.net,
linux-wireless@vger.kernel.org
In-Reply-To: <1294439171.2709.6.camel@edumazet-laptop>
On 01/07/2011 02:26 PM, Eric Dumazet wrote:
> Le vendredi 07 janvier 2011 à 14:20 -0800, Ben Greear a écrit :
>> On 0
>>> Using skb_copy() is wrong then, since it makes a copy (order-1
>>> allocations)
>>>
>>> It should use :
>>> skb_alloc( actual_size_of_frame not the 3840 thing ...)
>>> copy(data)
>>
>> We need the extra stuff copied too I think (like skb->cb).
>>
>> If you could provide a bit more complete example code, I'll be happy
>> to test it...
>
> take a random drivers/net using copybreak ... say ... tg3.c
>
> lines 4785
>
> len = length_of_the_current_frame
> copy_skb = netdev_alloc_skb(..., len);
> // allocates exact required size not a byte more....
> ...
> skb_copy_from_linear_data(skb, copy_skb->data, len);
> ...
> skb_put(skb, len);
> ...
That seems fine for drivers, but I'm guessing something different
would be needed in the mac80211/rx.c code:
I figure doing the fix here might be a nice quick fix,
and would help with all funky drivers. Later, can fix the
ath9k to do the skb copying as soon as DMA is done?
/*
* This function returns whether or not the SKB
* was destined for RX processing or not, which,
* if consume is true, is equivalent to whether
* or not the skb was consumed.
*/
static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
struct sk_buff *skb, bool consume)
{
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
int prepares;
rx->skb = skb;
status->rx_flags |= IEEE80211_RX_RA_MATCH;
prepares = prepare_for_handlers(rx, hdr);
if (!prepares)
return false;
if (status->flag & RX_FLAG_MMIC_ERROR) {
if (status->rx_flags & IEEE80211_RX_RA_MATCH)
ieee80211_rx_michael_mic_report(hdr, rx);
return false;
}
if (!consume) {
skb = skb_copy(skb, GFP_ATOMIC);
if (!skb) {
if (net_ratelimit()) {
printk("failed skb_copy, skb->len: %i\n", skb->len);
wiphy_debug(local->hw.wiphy,
"failed to copy skb for %s\n",
sdata->name);
}
return true;
}
rx->skb = skb;
}
ieee80211_invoke_rx_handlers(rx);
return true;
}
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [ath9k-devel] [PATCH 1/3] ath9k: Decrease skb size to fit into one page.
From: Eric Dumazet @ 2011-01-07 22:26 UTC (permalink / raw)
To: Ben Greear
Cc: Luis R. Rodriguez, Johannes Berg, ath9k-devel@venema.h4ckr.net,
linux-wireless@vger.kernel.org
In-Reply-To: <4D2791BD.7050502@candelatech.com>
Le vendredi 07 janvier 2011 à 14:20 -0800, Ben Greear a écrit :
> On 0
> > Using skb_copy() is wrong then, since it makes a copy (order-1
> > allocations)
> >
> > It should use :
> > skb_alloc( actual_size_of_frame not the 3840 thing ...)
> > copy(data)
>
> We need the extra stuff copied too I think (like skb->cb).
>
> If you could provide a bit more complete example code, I'll be happy
> to test it...
take a random drivers/net using copybreak ... say ... tg3.c
lines 4785
len = length_of_the_current_frame
copy_skb = netdev_alloc_skb(..., len);
// allocates exact required size not a byte more....
...
skb_copy_from_linear_data(skb, copy_skb->data, len);
...
skb_put(skb, len);
...
^ permalink raw reply
* Re: [ath9k-devel] [PATCH 1/3] ath9k: Decrease skb size to fit into one page.
From: Ben Greear @ 2011-01-07 22:20 UTC (permalink / raw)
To: Eric Dumazet
Cc: Luis R. Rodriguez, Johannes Berg, ath9k-devel@venema.h4ckr.net,
linux-wireless@vger.kernel.org
In-Reply-To: <1294432018.2709.2.camel@edumazet-laptop>
On 01/07/2011 12:26 PM, Eric Dumazet wrote:
> Le vendredi 07 janvier 2011 à 12:09 -0800, Luis R. Rodriguez a écrit :
>> On Fri, Jan 07, 2011 at 10:34:52AM -0800, Ben Greear wrote:
>>> On 01/07/2011 02:58 AM, Johannes Berg wrote:
>>>> On Thu, 2011-01-06 at 16:46 -0800, greearb@candelatech.com wrote:
>>>>> From: Ben Greear<greearb@candelatech.com>
>>>>>
>>>>> Patch is from Eric Dumazet, as described here:
>>>>> https://patchwork.kernel.org/patch/104271/
>>>>>
>>>>> Reported-by: Michael Guntsche<mike@it-loops.com>
>>>>> Signed-off-by: Eric Dumazet<eric.dumazet@gmail.com>
>>>>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>>>>> ---
>>>>>
>>>>> NOTE: This needs review by ath9k and/or other informed
>>>>> people.
>>>>
>>>> This doesn't make sense. It might help, but it'll probably lead to not
>>>> being able to receive all frames off the air.
>>>>
>>>> If this is an issue, ath9k should do paged RX like iwlwifi.
>>>
>>> Ok, I backed this out..but now I'm back to getting buffer allocation
>>> failures (and this is on a system with 2GB RAM).
>>>
>>> Seems it's coming from mac80211 instead of ath9k, at least most of
>>> the time (I'm using 60 stations, so it probably needs to make lots of
>>> copies in the rx path). The traffic I'm generating/receiving is 1024 byte UDP
>>> payloads.
>>>
>>> Does this mean I really received a packet that was 3872 bytes long,
>>> or is the skb_copy allocating/copying empty data?
>>
>> Good question. The buffer we setup for DMA should be large since we
>> need to support AMSDU RX up to a certain bytes of RX data for the frame.
>> Harwdware should tell us the right size for the RX'd data and the skb
>> should be set with that size, respectively. Following this logic,
>> skb_copy() should only allocate on the order of the required skb->len.
>>
>> Remember that trick we did to force the older memory leak issues by
>> forcing an skb_copy() on every RX'd frame and then just discarding that
>> buffer immediately? You can try to do the same and print the skb->len
>> there, just to check what's going on.
>
>
> Using skb_copy() is wrong then, since it makes a copy (order-1
> allocations)
>
> It should use :
> skb_alloc( actual_size_of_frame not the 3840 thing ...)
> copy(data)
We need the extra stuff copied too I think (like skb->cb).
If you could provide a bit more complete example code, I'll be happy
to test it...
Thanks,
Ben
>
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
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