* [PATCH 1/7] wireless: update top level wireless driver entry
From: Luis R. Rodriguez @ 2009-09-01 15:22 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1251818566-9264-1-git-send-email-lrodriguez@atheros.com>
Change it to a menuconfig to give it some documentation, to
refer users to our wireless wiki for extra resources and
documentation. It seems our wiki is still obscure to some.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/Kconfig | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index dda7cc2..1e45444 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -2,8 +2,17 @@
# Wireless LAN device configuration
#
-menu "Wireless LAN"
+menuconfig WLAN
+ bool "IEEE 802.11 - Wireless LAN"
depends on !S390
+ ---help---
+ This section contains all the pre 802.11 and 802.11 wireless
+ device drivers. For a complete list of drivers and documentation
+ on them refer to the wireless wiki:
+
+ http://wireless.kernel.org/en/users/Drivers
+
+if WLAN
menuconfig WLAN_PRE80211
bool "Wireless LAN (pre-802.11)"
@@ -506,4 +515,4 @@ source "drivers/net/wireless/orinoco/Kconfig"
source "drivers/net/wireless/wl12xx/Kconfig"
source "drivers/net/wireless/iwmc3200wifi/Kconfig"
-endmenu
+endif # WLAN
--
1.6.3.3
^ permalink raw reply related
* [PATCH 0/7] wireless: few kconfig updates
From: Luis R. Rodriguez @ 2009-09-01 15:22 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
Since it seems the organizational changes on kconfig for wireless
drivers did not go through I am sending now only the net/wireless and
net/mac80211 wireless kconfig updates. This updates the description of
the wireless options to reflect better with our documentation on
wireless.kernel.org and we also provide pointers for further
documentation.
Luis R. Rodriguez (7):
wireless: update top level wireless driver entry
wireless: update wireless kconfig description
wireless: update cfg80211 kconfig entry
wireless: update reg debug kconfig entry
wireless: update WIRELESS_EXT kconfig entry
wireless: update mac80211 kconfig entry
wireless: remove mac80211 rate selection extra menu
drivers/net/wireless/Kconfig | 13 +++++++++++--
net/Kconfig | 8 +++++++-
net/mac80211/Kconfig | 24 ++++++++++++++++++------
net/wireless/Kconfig | 27 ++++++++++++++++++++++++---
4 files changed, 60 insertions(+), 12 deletions(-)
^ permalink raw reply
* Re: Ath5k and proprietary extensions
From: Jouni Malinen @ 2009-09-01 14:37 UTC (permalink / raw)
To: Nick Kossifidis
Cc: John W. Linville, Luis R. Rodriguez, Bob Copeland, proski,
ath5k-devel, linux-wireless, ic.felix, Felix Fietkau
In-Reply-To: <40f31dec0908282151t245912f0ye79684d4a519f3c9@mail.gmail.com>
On Sat, Aug 29, 2009 at 07:51:29AM +0300, Nick Kossifidis wrote:
> Since we started the discussion about ath5k and proprietary features i
> started a new thread to continue.
> a) X.R.: eXtended Range is a set of proprietary rates and some extra
> techniques (various hw tweaks etc) to enable long distance, low
> bandwidth links. This feature was never really supported on MadWiFi
> (some code for sta mode is there but i don't think anyone used it) and
> it's ugly (sends beacons on both 1Mbit and 250Kbit, has some sort of
> polling mechanism etc). We should remove XR stuff since we all agree
> that we won't support it + even if we want we don't have anything to
> work with anyway, 5/10MHz channels should be enough for long distance
> links. Just leave XR rate code definitions there for reference (in
> case we get any of these from the card -normally we shouldn't but it's
> good to know all hw rate code values).
Agreed, I see no place for this in neither ath5k (or ath9k for that
matter) nor mac80211 (please note that it does require changes that
would fit into the mac80211/hostapd areas in our design and neither of
those are going to accept these changes even if the driver were.. ;-).
> b) OFDM-only g settings for AR5211: AR5211 chips have support for
> draft-g (eg. no dynamic CCK/OFDM modulation, only OFDM). I don't know
> if we want to support it or not, removing the settings will save us
> some space and since it's a draft g implementation i don't think there
> are many compatible APs out there. Is there any possibility to support
> draft-g on mac80211/cfg80211 ? If not we can just drop it else it's
> just some extra data, no big deal.
I don't see why we would want to support this at this point. I don't
really think there is much use for this and I see no point in making
mac80211/cfg80211 more complex for such a corner case.
> c) Half/quarter rate channels (10/5MHz width) and turbo mode (double
> rate - 40MHz width): Hw can transmit with different channel width
> allowing us to operate on half, quarter or double rate (also called
> turbo mode). Half and quarter rates are straight forward (just
> re-program pll/clock and tweak various phy/rf settings) and most chips
> support it, turbo mode on the other hand has some extra parameters and
> is supported only on super ag enabled (non-lite) chips
> (5212,2414,5414,5424 etc). First we want to use it only on "middle"
> channels so that we don't get outside band boundaries when changing
> channel width, so we have to limit the available channels we can use
> (check out super ag white paper), second we have the opportunity to
> support both 20MHz and 40MHz at the same time by using "dynamic turbo"
> feature on hw so if we are an AP we can deal both with turbo-enabled
> clients and normal clients. I was thinking if we are going to have an
> API to set channel width to 10 and 5 MHz for half and quarter rate
> channels, we can use the same API to set channel width to 40MHz width
> for double rate channels on cards that support it and when we are on
> AP mode use the "dynamic turbo" stuff. We don't even have to call it
> turbo mode, it's just double rate + some tweaks.
I consider this c item to be three different cases:
(1) standard-defined 5/10 MHz width channels
(2) proprietary channel binding (static 40 MHz turbo)
(3) proprietary dynamic 20/40 MHz turbo
As far as (1) is concerned, I see some value in supporting it. However,
at this point I would probably not enable those channels by default
(i.e., I do not want to see them making scan take any more time than it
already does).
(3) is on a not-going-to-happen list as far as I'm concerned since it
requires changes both in mac80211 and hostapd, too, and good luck trying
to get this in there.. ;-)
(2) is somewhat of a corner case. It would probably be possible to
somehow support it as a driver specific hack. While I would personally
prefer not to see this, I would probably be fine with it being there as
long as these channels are not enabled by default (the same comment as
for 5/10 MHz channels and scan).
> d) Fast frames: Hw can tx/rx jumbo frames of 3kbytes+ so fast frame
> aggregation is a way to make use of that hw feature by sending 2
> frames together (for more infos check out super ag white paper). On
> FreeBSD fast frames aggregation is implemented on the protocol stack
> (net80211) so that any hw that can tx/rx such jumbo frames can use
> fast frame aggregation
> (http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/net80211/ieee80211_superg.c?rev=1.7;content-type=text%2Fx-cvsweb-markup;sortby=rev)
> but it still maintains atheros's format to be compatible with
> commercial Atheros APs. We have talked about this and it seems no one
> is willing to support fast frames aggregation so on ath5k we only use
> single tx/rx descriptors and there is no related code for handling
> multiple descriptors.
I don't see how this would get added to mac80211. If someone really
wants to spend time on this type of feature, I would suggest adding
support for A-MSDU aggregation (the TX side of it) into mac80211 and
making it usable with non-HT cases, too. That should result in something
quite similar to fast frames, but with a format that is actually defined
by IEEE. Sure, this would not be compatible with legacy Super A/G APs,
but could be used between two mac80211-based devices.
> e) Compression: Hw can do on-chip compression/decompression using
> standard Lempel Ziv algorithm per tx queue, MadWiFi implements this
> and uses a vendor IE to let others know that it supports this feature
> (same IE is used for all capabilities, fast frames, XR etc). I guess
> this can also work for other cards by doing compression/decompression
> on software since it's a standard algorithm (and i think kernel
> already has code for it) but it's way outside cfg80211/mac80211's
> scope. I think we can just use NL80211_CMD_TESTMODE to enable/disable
> this on all data queues and skip the IE stuff (user will have to
> enable it on both sides to make it work). There is no related code on
> ath5k for compression/decompression at the moment.
Even compression needs some negotiation support (i.e., mac80211/hostapd
are actually in scope) and there are some ugly corner cases showing up
issues with it.. I don't see much point in supporting this either.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [PATCH 18/19] wireless: convert drivers to netdev_tx_t
From: John W. Linville @ 2009-09-01 13:18 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev, linux-wireless
In-Reply-To: <20090901055130.266010870@vyatta.com>
On Mon, Aug 31, 2009 at 10:50:57PM -0700, Stephen Hemminger wrote:
> Mostly just simple conversions:
> * ray_cs had bogus return of NET_TX_LOCKED but driver
> was not using NETIF_F_LLTX
> * hostap and ipw2x00 had some code that returned value
> from a called function that also had to change to return netdev_tx_t
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
ACK
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: rtl8187b Problem with tx level
From: John W. Linville @ 2009-09-01 13:13 UTC (permalink / raw)
To: Hin-Tak Leung
Cc: Larry Finger, Gábor Stefanik, Luis R. Rodriguez,
Tobias Schlemmer, linux-wireless, greg
In-Reply-To: <3ace41890908311616k4040d59fub051d21e822604d0@mail.gmail.com>
On Tue, Sep 01, 2009 at 12:16:04AM +0100, Hin-Tak Leung wrote:
> 2009/8/31 Larry Finger <Larry.Finger@lwfinger.net>:
> > Gábor Stefanik wrote:
> >>
> >> The driver is not actually closed-source; they just don't provide any
> >> drivers on their site anymore, instead they send their reference
> >> drivers to OEMs, expecting the OEMs to release their own versions
> >> (with sources - most vendors who do release Linux drivers in fact only
> >> release sources, without binaries). The reason for this appears to be
> >> that Realtek now encourages vendors to sell RTL81xx wireless chips
> >> with modified USB IDs. (Or are you seeing a binary-only driver on
> >> realtek.com.tw? That would definitely be a GPL violation, given that
> >> they use a modified version of the GPLed libipw stack.)
> >
> >
> > No driver at all. I looked at the Toshiba site, but found only Windows
> > drivers. Which OEM has the driver available?
> >
> > Larry
>
> The r8187 is distributed from OEMs - stand to reason, as realtek don't
> really sell their own brand on high-street shops? We got one release
> e-mailed to us, and there are a few floating around on the internet
> under some laptop or usb hardware vendors. It is available under this,
> for example: http://service.one.de/index.php?&direction=0&order=&directory=NOTEBOOKS/ONE_A1XX/LINUX/Source-code/Wireless
> r8187mesh is the one in the mesh directory.
*sigh*
So Realtek is actually going backwards in their level of support?
Wonderful.
Anyone have any real-life contacts at Realtek? We really need to
get them on-board with the drivers in the kernel.
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* [PATCH 9/9] iwmc3200wifi: Add a last_fw_err debugfs entry
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
In order to check what was the last fw error we got accross resets, we add
this debugfs entry. It displays the complete ASSERT information.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/debug.h | 2 +
drivers/net/wireless/iwmc3200wifi/debugfs.c | 105 ++++++++++++++++++++++++++-
drivers/net/wireless/iwmc3200wifi/iwm.h | 2 +
drivers/net/wireless/iwmc3200wifi/main.c | 6 ++
drivers/net/wireless/iwmc3200wifi/rx.c | 2 +
5 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h
index 8fbb42d..e35c9b6 100644
--- a/drivers/net/wireless/iwmc3200wifi/debug.h
+++ b/drivers/net/wireless/iwmc3200wifi/debug.h
@@ -108,6 +108,8 @@ struct iwm_debugfs {
struct dentry *txq_dentry;
struct dentry *tx_credit_dentry;
struct dentry *rx_ticket_dentry;
+
+ struct dentry *fw_err_dentry;
};
#ifdef CONFIG_IWM_DEBUG
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index 0fa7b91..1465379 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -98,7 +98,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules,
iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write,
"%llu\n");
-static int iwm_txrx_open(struct inode *inode, struct file *filp)
+static int iwm_generic_open(struct inode *inode, struct file *filp)
{
filp->private_data = inode->i_private;
return 0;
@@ -289,25 +289,111 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
return ret;
}
+static ssize_t iwm_debugfs_fw_err_read(struct file *filp,
+ char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+
+ struct iwm_priv *iwm = filp->private_data;
+ char buf[512];
+ int buf_len = 512;
+ size_t len = 0;
+
+ if (*ppos != 0)
+ return 0;
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ if (!iwm->last_fw_err)
+ return -ENOMEM;
+
+ if (iwm->last_fw_err->line_num == 0)
+ goto out;
+
+ len += snprintf(buf + len, buf_len - len, "%cMAC FW ERROR:\n",
+ (le32_to_cpu(iwm->last_fw_err->category) == UMAC_SYS_ERR_CAT_LMAC)
+ ? 'L' : 'U');
+ len += snprintf(buf + len, buf_len - len,
+ "\tCategory: %d\n",
+ le32_to_cpu(iwm->last_fw_err->category));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tStatus: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->status));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tPC: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->pc));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tblink1: %d\n",
+ le32_to_cpu(iwm->last_fw_err->blink1));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tblink2: %d\n",
+ le32_to_cpu(iwm->last_fw_err->blink2));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tilink1: %d\n",
+ le32_to_cpu(iwm->last_fw_err->ilink1));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tilink2: %d\n",
+ le32_to_cpu(iwm->last_fw_err->ilink2));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tData1: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->data1));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tData2: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->data2));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tLine number: %d\n",
+ le32_to_cpu(iwm->last_fw_err->line_num));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tUMAC status: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->umac_status));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tLMAC status: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->lmac_status));
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tSDIO status: 0x%x\n",
+ le32_to_cpu(iwm->last_fw_err->sdio_status));
+
+out:
+
+ return simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+}
static const struct file_operations iwm_debugfs_txq_fops = {
.owner = THIS_MODULE,
- .open = iwm_txrx_open,
+ .open = iwm_generic_open,
.read = iwm_debugfs_txq_read,
};
static const struct file_operations iwm_debugfs_tx_credit_fops = {
.owner = THIS_MODULE,
- .open = iwm_txrx_open,
+ .open = iwm_generic_open,
.read = iwm_debugfs_tx_credit_read,
};
static const struct file_operations iwm_debugfs_rx_ticket_fops = {
.owner = THIS_MODULE,
- .open = iwm_txrx_open,
+ .open = iwm_generic_open,
.read = iwm_debugfs_rx_ticket_read,
};
+static const struct file_operations iwm_debugfs_fw_err_fops = {
+ .owner = THIS_MODULE,
+ .open = iwm_generic_open,
+ .read = iwm_debugfs_fw_err_read,
+};
+
int iwm_debugfs_init(struct iwm_priv *iwm)
{
int i, result;
@@ -423,6 +509,16 @@ int iwm_debugfs_init(struct iwm_priv *iwm)
goto error;
}
+ iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200,
+ iwm->dbg.dbgdir, iwm,
+ &iwm_debugfs_fw_err_fops);
+ result = PTR_ERR(iwm->dbg.fw_err_dentry);
+ if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result);
+ goto error;
+ }
+
+
return 0;
error:
@@ -441,6 +537,7 @@ void iwm_debugfs_exit(struct iwm_priv *iwm)
debugfs_remove(iwm->dbg.txq_dentry);
debugfs_remove(iwm->dbg.tx_credit_dentry);
debugfs_remove(iwm->dbg.rx_ticket_dentry);
+ debugfs_remove(iwm->dbg.fw_err_dentry);
if (iwm->bus_ops->debugfs_exit)
iwm->bus_ops->debugfs_exit(iwm);
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index f5c2d6f..1b02a4e 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -289,6 +289,8 @@ struct iwm_priv {
u8 *resp_ie;
int resp_ie_len;
+ struct iwm_fw_error_hdr *last_fw_err;
+
char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 6a5b76a..d668e47 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -260,6 +260,11 @@ int iwm_priv_init(struct iwm_priv *iwm)
iwm->watchdog.data = (unsigned long)iwm;
mutex_init(&iwm->mutex);
+ iwm->last_fw_err = kzalloc(sizeof(struct iwm_fw_error_hdr),
+ GFP_KERNEL);
+ if (iwm->last_fw_err == NULL)
+ return -ENOMEM;
+
return 0;
}
@@ -271,6 +276,7 @@ void iwm_priv_deinit(struct iwm_priv *iwm)
destroy_workqueue(iwm->txq[i].wq);
destroy_workqueue(iwm->rx_wq);
+ kfree(iwm->last_fw_err);
}
/*
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 14950b1..40dbcbc 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -102,6 +102,8 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
error = (struct iwm_umac_notif_error *)buf;
fw_err = &error->err;
+ memcpy(iwm->last_fw_err, fw_err, sizeof(struct iwm_fw_error_hdr));
+
IWM_ERR(iwm, "%cMAC FW ERROR:\n",
(le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U');
IWM_ERR(iwm, "\tCategory: %d\n", le32_to_cpu(fw_err->category));
--
1.6.3.3
^ permalink raw reply related
* [PATCH 8/9] iwmc3200wifi: Handle UMAC stalls and UMAC assert properly
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
When UMAC stalls or asserts, we want to reset the device. But when we're
associated, the current reset worker will end up calling
cfg80211_connect_result() with the cfg80211 sme layer knowing that we're
reassociating. That ends up with some ugly warnings.
With this patch we're telling the upper layer that we've roamed if
reassociation succeeds, and that we're disconnected if it fails.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/iwm.h | 2 ++
drivers/net/wireless/iwmc3200wifi/main.c | 18 +++++++++++++++---
drivers/net/wireless/iwmc3200wifi/rx.c | 29 +++++++++++++++++++++++------
3 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 74964ee..f5c2d6f 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -178,6 +178,7 @@ struct iwm_key {
#define IWM_STATUS_SCAN_ABORTING 2
#define IWM_STATUS_SME_CONNECTING 3
#define IWM_STATUS_ASSOCIATED 4
+#define IWM_STATUS_RESETTING 5
struct iwm_tx_queue {
int id;
@@ -317,6 +318,7 @@ int iwm_mode_to_nl80211_iftype(int mode);
int iwm_priv_init(struct iwm_priv *iwm);
void iwm_priv_deinit(struct iwm_priv *iwm);
void iwm_reset(struct iwm_priv *iwm);
+void iwm_resetting(struct iwm_priv *iwm);
void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
struct iwm_umac_notif_alive *alive);
int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb);
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index fc7fce4..6a5b76a 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -187,7 +187,8 @@ static void iwm_reset_worker(struct work_struct *work)
memcpy(iwm->umac_profile, profile, sizeof(*profile));
iwm_send_mlme_profile(iwm);
kfree(profile);
- }
+ } else
+ clear_bit(IWM_STATUS_RESETTING, &iwm->status);
out:
mutex_unlock(&iwm->mutex);
@@ -200,7 +201,7 @@ static void iwm_watchdog(unsigned long data)
IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
if (modparam_reset)
- schedule_work(&iwm->reset_worker);
+ iwm_resetting(iwm);
}
int iwm_priv_init(struct iwm_priv *iwm)
@@ -284,7 +285,11 @@ void iwm_reset(struct iwm_priv *iwm)
if (test_bit(IWM_STATUS_READY, &iwm->status))
iwm_target_reset(iwm);
- iwm->status = 0;
+ if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) {
+ iwm->status = 0;
+ set_bit(IWM_STATUS_RESETTING, &iwm->status);
+ } else
+ iwm->status = 0;
iwm->scan_id = 1;
list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
@@ -300,6 +305,13 @@ void iwm_reset(struct iwm_priv *iwm)
iwm_link_off(iwm);
}
+void iwm_resetting(struct iwm_priv *iwm)
+{
+ set_bit(IWM_STATUS_RESETTING, &iwm->status);
+
+ schedule_work(&iwm->reset_worker);
+}
+
/*
* Notification code:
*
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 2daa586..14950b1 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -118,6 +118,8 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status));
IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status));
+ iwm_resetting(iwm);
+
return 0;
}
@@ -528,11 +530,19 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
if (iwm->conf.mode == UMAC_MODE_IBSS)
goto ibss;
- cfg80211_connect_result(iwm_to_ndev(iwm),
+ if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
+ cfg80211_connect_result(iwm_to_ndev(iwm),
+ complete->bssid,
+ iwm->req_ie, iwm->req_ie_len,
+ iwm->resp_ie, iwm->resp_ie_len,
+ WLAN_STATUS_SUCCESS,
+ GFP_KERNEL);
+ else
+ cfg80211_roamed(iwm_to_ndev(iwm),
complete->bssid,
iwm->req_ie, iwm->req_ie_len,
iwm->resp_ie, iwm->resp_ie_len,
- WLAN_STATUS_SUCCESS, GFP_KERNEL);
+ GFP_KERNEL);
break;
case UMAC_ASSOC_COMPLETE_FAILURE:
clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
@@ -551,19 +561,26 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
if (iwm->conf.mode == UMAC_MODE_IBSS)
goto ibss;
- cfg80211_connect_result(iwm_to_ndev(iwm), complete->bssid,
- NULL, 0, NULL, 0,
- WLAN_STATUS_UNSPECIFIED_FAILURE,
- GFP_KERNEL);
+ if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
+ cfg80211_connect_result(iwm_to_ndev(iwm),
+ complete->bssid,
+ NULL, 0, NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ else
+ cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
+ GFP_KERNEL);
break;
default:
break;
}
+ clear_bit(IWM_STATUS_RESETTING, &iwm->status);
return 0;
ibss:
cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
+ clear_bit(IWM_STATUS_RESETTING, &iwm->status);
return 0;
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 6/9] iwmc3200wifi: fix misuse of le16_to_cpu
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
From: Zhu Yi <yi.zhu@intel.com>
Also mark some functions static.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/main.c | 8 ++++----
drivers/net/wireless/iwmc3200wifi/rx.c | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index c41fa8c..6cf2f0c 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -128,8 +128,8 @@ static void iwm_disconnect_work(struct work_struct *work)
cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
}
-int __iwm_up(struct iwm_priv *iwm);
-int __iwm_down(struct iwm_priv *iwm);
+static int __iwm_up(struct iwm_priv *iwm);
+static int __iwm_down(struct iwm_priv *iwm);
static void iwm_reset_worker(struct work_struct *work)
{
@@ -559,7 +559,7 @@ static int iwm_channels_init(struct iwm_priv *iwm)
return 0;
}
-int __iwm_up(struct iwm_priv *iwm)
+static int __iwm_up(struct iwm_priv *iwm)
{
int ret;
struct iwm_notif *notif_reboot, *notif_ack = NULL;
@@ -693,7 +693,7 @@ int iwm_up(struct iwm_priv *iwm)
return ret;
}
-int __iwm_down(struct iwm_priv *iwm)
+static int __iwm_down(struct iwm_priv *iwm)
{
int ret;
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 4d9793e..2daa586 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -850,7 +850,7 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
iwm->resp_ie_len, GFP_KERNEL);
} else {
IWM_ERR(iwm, "Unsupported management frame: 0x%x",
- cpu_to_le16(mgt->frame_control));
+ le16_to_cpu(mgt->frame_control));
return 0;
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 7/9] iwmc3200wifi: New initial LMAC calibration
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
The LMAC calibration API got broken mostly by having a configuration bitmap
being different than the result one.
This patch tries to address that issue by correctly running calibrations with
the newest firmwares, and keeping a backward compatibility fallback path for
older firmwares, where the configuration and result bitmaps were identical.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/fw.c | 56 +++++++++++++++++++++---------
drivers/net/wireless/iwmc3200wifi/iwm.h | 1 +
drivers/net/wireless/iwmc3200wifi/lmac.h | 15 ++++++++
drivers/net/wireless/iwmc3200wifi/main.c | 7 +++-
4 files changed, 61 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index 0f32cab..6b0bcad 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -261,6 +261,33 @@ static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0);
}
+static int iwm_init_calib(struct iwm_priv *iwm, unsigned long cfg_bitmap,
+ unsigned long expected_bitmap, u8 rx_iq_cmd)
+{
+ /* Read RX IQ calibration result from EEPROM */
+ if (test_bit(rx_iq_cmd, &cfg_bitmap)) {
+ iwm_store_rxiq_calib_result(iwm);
+ set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
+ }
+
+ iwm_send_prio_table(iwm);
+ iwm_send_init_calib_cfg(iwm, cfg_bitmap);
+
+ while (iwm->calib_done_map != expected_bitmap) {
+ if (iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
+ IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT)) {
+ IWM_DBG_FW(iwm, DBG, "Initial calibration timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
+ "0x%lx, expected calibrations: 0x%lx\n",
+ iwm->calib_done_map, expected_bitmap);
+ }
+
+ return 0;
+}
+
/*
* We currently have to load 3 FWs:
* 1) The UMAC (Upper MAC).
@@ -276,6 +303,7 @@ static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
int iwm_load_fw(struct iwm_priv *iwm)
{
unsigned long init_calib_map, periodic_calib_map;
+ unsigned long expected_calib_map;
int ret;
/* We first start downloading the UMAC */
@@ -317,27 +345,21 @@ int iwm_load_fw(struct iwm_priv *iwm)
}
init_calib_map = iwm->conf.calib_map & IWM_CALIB_MAP_INIT_MSK;
+ expected_calib_map = iwm->conf.expected_calib_map &
+ IWM_CALIB_MAP_INIT_MSK;
periodic_calib_map = IWM_CALIB_MAP_PER_LMAC(iwm->conf.calib_map);
- /* Read RX IQ calibration result from EEPROM */
- if (test_bit(PHY_CALIBRATE_RX_IQ_CMD, &init_calib_map)) {
- iwm_store_rxiq_calib_result(iwm);
- set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
- }
-
- iwm_send_prio_table(iwm);
- iwm_send_init_calib_cfg(iwm, init_calib_map);
-
- while (iwm->calib_done_map != init_calib_map) {
- ret = iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
- IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
- if (ret) {
- IWM_ERR(iwm, "Wait for calibration result timeout\n");
+ ret = iwm_init_calib(iwm, init_calib_map, expected_calib_map,
+ CALIB_CFG_RX_IQ_IDX);
+ if (ret < 0) {
+ /* Let's try the old way */
+ ret = iwm_init_calib(iwm, expected_calib_map,
+ expected_calib_map,
+ PHY_CALIBRATE_RX_IQ_CMD);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Calibration result timeout\n");
goto out;
}
- IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
- "0x%lx, requested calibrations: 0x%lx\n",
- iwm->calib_done_map, init_calib_map);
}
/* Handle LMAC CALIBRATION_COMPLETE notification */
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index da49df6..74964ee 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -64,6 +64,7 @@
struct iwm_conf {
u32 sdio_ior_timeout;
unsigned long calib_map;
+ unsigned long expected_calib_map;
bool reset_on_fatal_err;
bool auto_connect;
bool wimax_not_present;
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
index 19213e1..6c1a14c 100644
--- a/drivers/net/wireless/iwmc3200wifi/lmac.h
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -396,9 +396,24 @@ enum {
CALIBRATION_CMD_NUM,
};
+enum {
+ CALIB_CFG_RX_BB_IDX = 0,
+ CALIB_CFG_DC_IDX = 1,
+ CALIB_CFG_LO_IDX = 2,
+ CALIB_CFG_TX_IQ_IDX = 3,
+ CALIB_CFG_RX_IQ_IDX = 4,
+ CALIB_CFG_NOISE_IDX = 5,
+ CALIB_CFG_CRYSTAL_IDX = 6,
+ CALIB_CFG_TEMPERATURE_IDX = 7,
+ CALIB_CFG_PAPD_IDX = 8,
+ CALIB_CFG_LAST_IDX = CALIB_CFG_PAPD_IDX,
+ CALIB_CFG_MODULE_NUM,
+};
+
#define IWM_CALIB_MAP_INIT_MSK 0xFFFF
#define IWM_CALIB_MAP_PER_LMAC(m) ((m & 0xFF0000) >> 16)
#define IWM_CALIB_MAP_PER_UMAC(m) ((m & 0xFF000000) >> 24)
+#define IWM_CALIB_OPCODE_TO_INDEX(op) (op - PHY_CALIBRATE_OPCODES_NUM)
struct iwm_lmac_calib_hdr {
u8 opcode;
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 6cf2f0c..fc7fce4 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -53,7 +53,12 @@
static struct iwm_conf def_iwm_conf = {
.sdio_ior_timeout = 5000,
- .calib_map = BIT(PHY_CALIBRATE_DC_CMD) |
+ .calib_map = BIT(CALIB_CFG_DC_IDX) |
+ BIT(CALIB_CFG_LO_IDX) |
+ BIT(CALIB_CFG_TX_IQ_IDX) |
+ BIT(CALIB_CFG_RX_IQ_IDX) |
+ BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
+ .expected_calib_map = BIT(PHY_CALIBRATE_DC_CMD) |
BIT(PHY_CALIBRATE_LO_CMD) |
BIT(PHY_CALIBRATE_TX_IQ_CMD) |
BIT(PHY_CALIBRATE_RX_IQ_CMD) |
--
1.6.3.3
^ permalink raw reply related
* [PATCH 5/9] iwmc3200wifi: add disconnect work
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
From: Zhu Yi <yi.zhu@intel.com>
When the driver receives "connection terminated" event from device,
it could be caused by 2 reasons: the firmware is roaming or the
connection is lost (AP disappears). For the former, an association
complete event is supposed to come within 3 seconds. For the latter,
the driver won't receive any event except the connection terminated.
So we kick a delayed work (5*HZ) when we receive the connection
terminated event. It will be canceled if it turns out to be a roaming
event later. Otherwise we notify SME and userspace the disconnection.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/iwm.h | 1 +
drivers/net/wireless/iwmc3200wifi/main.c | 21 +++++++++++++++++++
drivers/net/wireless/iwmc3200wifi/rx.c | 32 +++++++++++++++++++++++++----
3 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index f054cc8..da49df6 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -273,6 +273,7 @@ struct iwm_priv {
struct iw_statistics wstats;
struct delayed_work stats_request;
+ struct delayed_work disconnect;
struct iwm_debugfs dbg;
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index cf25744..c41fa8c 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -108,6 +108,26 @@ static void iwm_statistics_request(struct work_struct *work)
iwm_send_umac_stats_req(iwm, 0);
}
+static void iwm_disconnect_work(struct work_struct *work)
+{
+ struct iwm_priv *iwm =
+ container_of(work, struct iwm_priv, disconnect.work);
+
+ if (iwm->umac_profile_active)
+ iwm_invalidate_mlme_profile(iwm);
+
+ clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+ iwm->umac_profile_active = 0;
+ memset(iwm->bssid, 0, ETH_ALEN);
+ iwm->channel = 0;
+
+ iwm_link_off(iwm);
+
+ wake_up_interruptible(&iwm->mlme_queue);
+
+ cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
+}
+
int __iwm_up(struct iwm_priv *iwm);
int __iwm_down(struct iwm_priv *iwm);
@@ -198,6 +218,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
spin_lock_init(&iwm->cmd_lock);
iwm->scan_id = 1;
INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
+ INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
INIT_LIST_HEAD(&iwm->bss_list);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 9e6f2cd..4d9793e 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -514,6 +514,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
/* Internal roaming state, avoid notifying SME. */
if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
&& iwm->conf.mode == UMAC_MODE_BSS) {
+ cancel_delayed_work(&iwm->disconnect);
cfg80211_roamed(iwm_to_ndev(iwm),
complete->bssid,
iwm->req_ie, iwm->req_ie_len,
@@ -540,8 +541,10 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
/* Internal roaming state, avoid notifying SME. */
if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
- && iwm->conf.mode == UMAC_MODE_BSS)
+ && iwm->conf.mode == UMAC_MODE_BSS) {
+ cancel_delayed_work(&iwm->disconnect);
break;
+ }
iwm_link_off(iwm);
@@ -569,11 +572,18 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
struct iwm_wifi_cmd *cmd)
{
struct iwm_umac_notif_profile_invalidate *invalid;
+ u32 reason;
invalid = (struct iwm_umac_notif_profile_invalidate *)buf;
+ reason = le32_to_cpu(invalid->reason);
+
+ IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n", reason);
- IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n",
- le32_to_cpu(invalid->reason));
+ if (reason != UMAC_PROFILE_INVALID_REQUEST &&
+ test_bit(IWM_STATUS_SME_CONNECTING, &iwm->status))
+ cfg80211_connect_result(iwm_to_ndev(iwm), NULL, NULL, 0, NULL,
+ 0, WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
@@ -589,6 +599,19 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
return 0;
}
+#define IWM_DISCONNECT_INTERVAL (5 * HZ)
+
+static int iwm_mlme_connection_terminated(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
+
+ schedule_delayed_work(&iwm->disconnect, IWM_DISCONNECT_INTERVAL);
+
+ return 0;
+}
+
static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf,
unsigned long buf_size,
struct iwm_wifi_cmd *cmd)
@@ -848,8 +871,7 @@ static int iwm_ntf_mlme(struct iwm_priv *iwm, u8 *buf,
case WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE:
return iwm_mlme_profile_invalidate(iwm, buf, buf_size, cmd);
case WIFI_IF_NTFY_CONNECTION_TERMINATED:
- IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
- break;
+ return iwm_mlme_connection_terminated(iwm, buf, buf_size, cmd);
case WIFI_IF_NTFY_SCAN_COMPLETE:
return iwm_mlme_scan_complete(iwm, buf, buf_size, cmd);
case WIFI_IF_NTFY_STA_TABLE_CHANGE:
--
1.6.3.3
^ permalink raw reply related
* [PATCH 0/9] iwmc3200wifi updates
From: Samuel Ortiz @ 2009-09-01 13:13 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
Hi John,
This 9 patches serie is the latest iwmc3200wifi update.
All of them are targeted for a wireless-testing inclusion, hoping it's not too
late to make it to the next merge window.
Samuel Ortiz (5):
iwmc3200wifi: Set WEP key from connect
iwmc3200wifi: Fix sparse warning
iwmc3200wifi: New initial LMAC calibration
iwmc3200wifi: Handle UMAC stalls and UMAC assert properly
iwmc3200wifi: Add a last_fw_err debugfs entry
Zhu Yi (4):
iwmc3200wifi: invalidate profile when necessary before connect
iwmc3200wifi: use cfg80211_roamed to send roam event
iwmc3200wifi: add disconnect work
iwmc3200wifi: fix misuse of le16_to_cpu
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 66 ++++++++++++++--
drivers/net/wireless/iwmc3200wifi/commands.c | 1 +
drivers/net/wireless/iwmc3200wifi/debug.h | 2 +
drivers/net/wireless/iwmc3200wifi/debugfs.c | 105 +++++++++++++++++++++++++-
drivers/net/wireless/iwmc3200wifi/fw.c | 56 ++++++++++----
drivers/net/wireless/iwmc3200wifi/iwm.h | 8 ++-
drivers/net/wireless/iwmc3200wifi/lmac.h | 15 ++++
drivers/net/wireless/iwmc3200wifi/main.c | 60 +++++++++++++--
drivers/net/wireless/iwmc3200wifi/rx.c | 87 +++++++++++++++++----
9 files changed, 345 insertions(+), 55 deletions(-)
^ permalink raw reply
* [PATCH 1/9] iwmc3200wifi: invalidate profile when necessary before connect
From: Samuel Ortiz @ 2009-09-01 13:13 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
From: Zhu Yi <yi.zhu@intel.com>
If cfg80211 requests to connect when we have already had an active
profile, invalidate the current profile first before sending a new
profile to UMAC.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index a6e852f..789ef5c 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -326,11 +326,8 @@ static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
- if (iwm->umac_profile_active) {
- int ret = iwm_invalidate_mlme_profile(iwm);
- if (ret < 0)
- IWM_ERR(iwm, "Couldn't invalidate profile\n");
- }
+ if (iwm->umac_profile_active)
+ iwm_invalidate_mlme_profile(iwm);
return 0;
}
@@ -573,6 +570,14 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (!sme->ssid)
return -EINVAL;
+ if (iwm->umac_profile_active) {
+ ret = iwm_invalidate_mlme_profile(iwm);
+ if (ret) {
+ IWM_ERR(iwm, "Couldn't invalidate profile\n");
+ return ret;
+ }
+ }
+
if (chan)
iwm->channel =
ieee80211_frequency_to_channel(chan->center_freq);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 4/9] iwmc3200wifi: use cfg80211_roamed to send roam event
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
From: Zhu Yi <yi.zhu@intel.com>
The device sends connection terminated and [re]association success
(or failure) events when roaming occours. The patch uses
cfg80211_roamed instead of cfg80211_connect_result to notify SME
for roaming.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 2 +-
drivers/net/wireless/iwmc3200wifi/commands.c | 1 +
drivers/net/wireless/iwmc3200wifi/iwm.h | 2 +-
drivers/net/wireless/iwmc3200wifi/rx.c | 26 ++++++++++++++++++++------
4 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 2784b08..a56a2b0 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -673,7 +673,7 @@ static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
if (iwm->umac_profile_active)
- return iwm_invalidate_mlme_profile(iwm);
+ iwm_invalidate_mlme_profile(iwm);
return 0;
}
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index a68a2af..23b52fa 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -756,6 +756,7 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
return ret;
}
+ set_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
return 0;
}
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 7a51bc3..f054cc8 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -175,7 +175,7 @@ struct iwm_key {
#define IWM_STATUS_READY 0
#define IWM_STATUS_SCANNING 1
#define IWM_STATUS_SCAN_ABORTING 2
-#define IWM_STATUS_ASSOCIATING 3
+#define IWM_STATUS_SME_CONNECTING 3
#define IWM_STATUS_ASSOCIATED 4
struct iwm_tx_queue {
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 86079a1..9e6f2cd 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -487,8 +487,6 @@ static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
start = (struct iwm_umac_notif_assoc_start *)buf;
- set_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
-
IWM_DBG_MLME(iwm, INFO, "Association with %pM Started, reason: %d\n",
start->bssid, le32_to_cpu(start->roam_reason));
@@ -507,14 +505,23 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
complete->bssid, complete->status);
- clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
-
switch (le32_to_cpu(complete->status)) {
case UMAC_ASSOC_COMPLETE_SUCCESS:
set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
iwm->channel = complete->channel;
+ /* Internal roaming state, avoid notifying SME. */
+ if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
+ && iwm->conf.mode == UMAC_MODE_BSS) {
+ cfg80211_roamed(iwm_to_ndev(iwm),
+ complete->bssid,
+ iwm->req_ie, iwm->req_ie_len,
+ iwm->resp_ie, iwm->resp_ie_len,
+ GFP_KERNEL);
+ break;
+ }
+
iwm_link_on(iwm);
if (iwm->conf.mode == UMAC_MODE_IBSS)
@@ -531,6 +538,11 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
memset(iwm->bssid, 0, ETH_ALEN);
iwm->channel = 0;
+ /* Internal roaming state, avoid notifying SME. */
+ if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
+ && iwm->conf.mode == UMAC_MODE_BSS)
+ break;
+
iwm_link_off(iwm);
if (iwm->conf.mode == UMAC_MODE_IBSS)
@@ -540,6 +552,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
+ break;
default:
break;
}
@@ -562,7 +575,7 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n",
le32_to_cpu(invalid->reason));
- clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+ clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
iwm->umac_profile_active = 0;
@@ -813,7 +826,8 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
iwm->resp_ie_len, GFP_KERNEL);
} else {
- IWM_ERR(iwm, "Unsupported management frame");
+ IWM_ERR(iwm, "Unsupported management frame: 0x%x",
+ cpu_to_le16(mgt->frame_control));
return 0;
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 3/9] iwmc3200wifi: Fix sparse warning
From: Samuel Ortiz @ 2009-09-01 13:14 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
iwm_cfg80211_get_station() should be static.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index d8bb723..2784b08 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -238,8 +238,9 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
return iwm_set_tx_key(iwm, key_index);
}
-int iwm_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
- u8 *mac, struct station_info *sinfo)
+static int iwm_cfg80211_get_station(struct wiphy *wiphy,
+ struct net_device *ndev,
+ u8 *mac, struct station_info *sinfo)
{
struct iwm_priv *iwm = ndev_to_iwm(ndev);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/9] iwmc3200wifi: Set WEP key from connect
From: Samuel Ortiz @ 2009-09-01 13:13 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Zhu Yi, Samuel Ortiz
In-Reply-To: <cover.1251809163.git.sameo@linux.intel.com>
When connect is called with the LEGACY_PSK authentication type set, and a
proper sme->key, we need to set the WEP key straight after setting the
profile otherwise the authentication will never start.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 44 +++++++++++++++++++++++++-
1 files changed, 43 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 789ef5c..d8bb723 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -562,6 +562,7 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
{
struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
struct ieee80211_channel *chan = sme->channel;
+ struct key_params key_param;
int ret;
if (!test_bit(IWM_STATUS_READY, &iwm->status))
@@ -619,7 +620,48 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return ret;
}
- return iwm_send_mlme_profile(iwm);
+ /*
+ * We save the WEP key in case we want to do shared authentication.
+ * We have to do it so because UMAC will assert whenever it gets a
+ * key before a profile.
+ */
+ if (sme->key) {
+ key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
+ if (key_param.key == NULL)
+ return -ENOMEM;
+ key_param.key_len = sme->key_len;
+ key_param.seq_len = 0;
+ key_param.cipher = sme->crypto.ciphers_pairwise[0];
+
+ ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
+ NULL, &key_param);
+ kfree(key_param.key);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Invalid key_params\n");
+ return ret;
+ }
+
+ iwm->default_key = sme->key_idx;
+ }
+
+ ret = iwm_send_mlme_profile(iwm);
+
+ if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
+ sme->key == NULL)
+ return ret;
+
+ /*
+ * We want to do shared auth.
+ * We need to actually set the key we previously cached,
+ * and then tell the UMAC it's the default one.
+ * That will trigger the auth+assoc UMAC machinery, and again,
+ * this must be done after setting the profile.
+ */
+ ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
+ if (ret < 0)
+ return ret;
+
+ return iwm_set_tx_key(iwm, iwm->default_key);
}
static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
--
1.6.3.3
^ permalink raw reply related
* Re: zd1211rw on ppc (iBook G4)
From: Michael Buesch @ 2009-09-01 12:56 UTC (permalink / raw)
To: Hin-Tak Leung; +Cc: Leonardo H. Souza Hamada, linux-wireless
In-Reply-To: <3ace41890908311235i62ab0510neb8b2021c3f2945e@mail.gmail.com>
On Monday 31 August 2009 21:35:31 Hin-Tak Leung wrote:
> On Mon, Aug 31, 2009 at 8:27 PM, Michael Buesch<mb@bu3sch.de> wrote:
> > On Monday 31 August 2009 20:26:22 Hin-Tak Leung wrote:
> >> It would appear that the rw driver's ieee80211->mac80211 conversion
> >> has broken big- endian platforms, at a first guess.
> >
> > Last time I tested the device worked fine on my powerbook with zd1211rw/mac80211.
> > But that's maybe two or three release cycles in the past.
> >
> > --
> > Greetings, Michael.
> >
>
> The rw ieee80211->mac80211 conversion happens in 2.6.27->26.28 ...
> Iguess the question is whether it was 2.6.28 or 2.6.27 you had success
> with? That's unfortunately two *and* three cycles in the past,
> respectively :-).
>
>
I certainly used zd1211rw/mac80211 and it worked.
--
Greetings, Michael.
^ permalink raw reply
* Re: [PATCH v2] b43: LP-PHY: Begin implementing calibration & software RFKILL support
From: Michael Buesch @ 2009-09-01 12:55 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John W. Linville, Larry Finger, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <69e28c910908311238r51222506j7bd21e3b7af5b4ad@mail.gmail.com>
On Monday 31 August 2009 21:38:28 Gábor Stefanik wrote:
> On Mon, Aug 31, 2009 at 9:17 PM, Michael Buesch<mb@bu3sch.de> wrote:
> > On Monday 31 August 2009 19:53:31 John W. Linville wrote:
> >> On Sun, Aug 30, 2009 at 05:55:40PM +0200, Michael Buesch wrote:
> >> > On Sunday 30 August 2009 17:10:23 Larry Finger wrote:
> >> > > Michael Buesch wrote:
> >> > > > On Sunday 30 August 2009 02:15:55 Gábor Stefanik wrote:
> >> > > >> static void lpphy_pr41573_workaround(struct b43_wldev *dev)
> >> > > >> {
> >> > > >> struct b43_phy_lp *lpphy = dev->phy.lp;
> >> > > >> @@ -1357,28 +1488,440 @@ static void lpphy_pr41573_workaround(struct b43_wldev *dev)
> >> > > >> b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
> >> > > >> saved_tab_size, saved_tab);
> >> > > >> }
> >> > > >> + b43_put_phy_into_reset(dev);
> >> > > >
> >> > > > Are you sure you really want this?
> >> > > > This function completely disables the PHY on the backplane and keeps the physical
> >> > > > PHY reset pin asserted (even after return from the function).
> >> > > > So the PHY will physically be powered down from this point on. The following
> >> > > > PHY accesses could even hang the machine, because the PHY won't respond to
> >> > > > register accesses anymore.
> >> > > >
> >> > > > We currently only use this function on A/G Multi-PHY devices to permanently
> >> > > > hard-disable the PHY that's not used.
> >> > >
> >> > > The PHY reset routine in
> >> > > http://bcm-v4.sipsolutions.net/802.11/PHY/Reset, which I just updated
> >> > > for the latest N PHY changes, appears to be a different routine than
> >> > > b43_put_phy_into_reset(). The names are confusing.
> >> >
> >> > b43_put_phy_into_reset() is opencoded in the specifications in various init
> >> > routines. There's no separate specs page for that function.
> >> > But I think the code is straightforward and easy to understand.
> >>
> >> So is this patch right or not? Should I hold onto it for 2.6.33
> >> (i.e. after the 2.6.32 merge window)?
> >
> > I'm pretty sure it's incorrect.
> >
> > --
> > Greetings, Michael.
> >
>
> Do we have the correct reset routine implemented somewhere, or is it a
> new routine to add?
>
We opencode something similar (N stuff and so on not included) in wireless_core_reset.
So we should probably implement http://bcm-v4.sipsolutions.net/802.11/PHY/Reset
in a separate function and also call that from wireless_core_reset (and your workaround
code).
--
Greetings, Michael.
^ permalink raw reply
* [PATCH 4/4] rndis_wlan: remove 'select WIRELESS_EXT' in Kconfig
From: Jussi Kivilinna @ 2009-09-01 12:33 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
In-Reply-To: <20090901123255.9213.57970.stgit@fate.lan>
Since rndis_wlan is now converted to cfg80211, WIRELESS_EXT isn't
required anymore.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/Kconfig | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index dda7cc2..623897f 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -337,7 +337,6 @@ config USB_NET_RNDIS_WLAN
select USB_USBNET
select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST
- select WIRELESS_EXT
---help---
This is a driver for wireless RNDIS devices.
These are USB based adapters found in devices such as:
^ permalink raw reply related
* [PATCH 3/4] rndis_wlan: fix sparse endianess warnings
From: Jussi Kivilinna @ 2009-09-01 12:33 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
In-Reply-To: <20090901123255.9213.57970.stgit@fate.lan>
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index add2eb8..54175b6 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -253,8 +253,8 @@ struct ndis_80211_pmkid_cand_list {
struct ndis_80211_status_indication {
__le32 status_type;
union {
- enum ndis_80211_media_stream_mode media_stream_mode;
- enum ndis_80211_radio_status radio_status;
+ __le32 media_stream_mode;
+ __le32 radio_status;
struct ndis_80211_auth_request auth_request[0];
struct ndis_80211_pmkid_cand_list cand_list;
} u;
@@ -1296,7 +1296,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
int index, const u8 *addr, const u8 *rx_seq,
- int seq_len, u32 cipher, int flags)
+ int seq_len, u32 cipher, __le32 flags)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct ndis_80211_key ndis_key;
@@ -2023,7 +2023,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev;
- int flags;
+ __le32 flags;
devdbg(usbdev, "rndis_add_key(%i, %pM, %08x)", key_index, mac_addr,
params->cipher);
^ permalink raw reply related
* [PATCH 2/4] rndis_wlan: cleanup
From: Jussi Kivilinna @ 2009-09-01 12:33 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
In-Reply-To: <20090901123255.9213.57970.stgit@fate.lan>
- remove double newlines between functions
- remove commented out function (rndis_set_config_parameter_u32())
- coding style fix in rndis_set_config_parameter_str()
- add comment banners between function sections
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 62 ++++---------------------------------
1 files changed, 7 insertions(+), 55 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index dc2804f..add2eb8 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -560,7 +560,6 @@ static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
return (struct rndis_wlan_private *)dev->driver_priv;
}
-
static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
{
switch (priv->param_power_output) {
@@ -576,7 +575,6 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
}
}
-
static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
{
int cipher = priv->encr_keys[idx].cipher;
@@ -585,7 +583,6 @@ static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
cipher == WLAN_CIPHER_SUITE_TKIP);
}
-
static int rndis_cipher_to_alg(u32 cipher)
{
switch (cipher) {
@@ -613,7 +610,6 @@ static int rndis_akm_suite_to_key_mgmt(u32 akm_suite)
}
}
-
#ifdef DEBUG
static const char *oid_to_string(__le32 oid)
{
@@ -675,7 +671,6 @@ static const char *oid_to_string(__le32 oid)
}
#endif
-
/* translate error code */
static int rndis_error_status(__le32 rndis_status)
{
@@ -699,7 +694,6 @@ static int rndis_error_status(__le32 rndis_status)
return ret;
}
-
static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -758,7 +752,6 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
return ret;
}
-
static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -817,7 +810,6 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
return ret;
}
-
static int rndis_reset(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -840,7 +832,6 @@ static int rndis_reset(struct usbnet *usbdev)
return 0;
}
-
/*
* Specs say that we can only set config parameters only soon after device
* initialization.
@@ -927,16 +918,9 @@ static int rndis_set_config_parameter(struct usbnet *dev, char *param,
static int rndis_set_config_parameter_str(struct usbnet *dev,
char *param, char *value)
{
- return(rndis_set_config_parameter(dev, param, 2, value));
+ return rndis_set_config_parameter(dev, param, 2, value);
}
-/*static int rndis_set_config_parameter_u32(struct usbnet *dev,
- char *param, u32 value)
-{
- return(rndis_set_config_parameter(dev, param, 0, &value));
-}*/
-
-
/*
* data conversion functions
*/
@@ -946,7 +930,6 @@ static int level_to_qual(int level)
return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
}
-
/*
* common functions
*/
@@ -1027,7 +1010,6 @@ static bool is_associated(struct usbnet *usbdev)
return (ret == 0 && !is_zero_ether_addr(bssid));
}
-
static int disassociate(struct usbnet *usbdev, bool reset_ssid)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1064,7 +1046,6 @@ static int disassociate(struct usbnet *usbdev, bool reset_ssid)
return ret;
}
-
static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
enum nl80211_auth_type auth_type, int keymgmt)
{
@@ -1109,7 +1090,6 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
return 0;
}
-
static int set_priv_filter(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1127,7 +1107,6 @@ static int set_priv_filter(struct usbnet *usbdev)
sizeof(tmp));
}
-
static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1163,7 +1142,6 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
return 0;
}
-
static int set_infra_mode(struct usbnet *usbdev, int mode)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1189,7 +1167,6 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
return 0;
}
-
static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
{
__le32 tmp;
@@ -1204,7 +1181,6 @@ static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
sizeof(tmp));
}
-
static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
{
__le32 tmp;
@@ -1219,7 +1195,6 @@ static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
sizeof(tmp));
}
-
static void set_default_iw_params(struct usbnet *usbdev)
{
set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
@@ -1229,7 +1204,6 @@ static void set_default_iw_params(struct usbnet *usbdev)
set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE);
}
-
static int deauthenticate(struct usbnet *usbdev)
{
int ret;
@@ -1239,7 +1213,6 @@ static int deauthenticate(struct usbnet *usbdev)
return ret;
}
-
static int set_channel(struct usbnet *usbdev, int channel)
{
struct ndis_80211_conf config;
@@ -1270,7 +1243,6 @@ static int set_channel(struct usbnet *usbdev, int channel)
return ret;
}
-
/* index must be 0 - N, as per NDIS */
static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
int index)
@@ -1322,7 +1294,6 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
return 0;
}
-
static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
int index, const u8 *addr, const u8 *rx_seq,
int seq_len, u32 cipher, int flags)
@@ -1417,7 +1388,6 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
return 0;
}
-
static int restore_key(struct usbnet *usbdev, int key_idx)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1436,7 +1406,6 @@ static int restore_key(struct usbnet *usbdev, int key_idx)
return add_wep_key(usbdev, key.material, key.len, key_idx);
}
-
static void restore_keys(struct usbnet *usbdev)
{
int i;
@@ -1445,13 +1414,11 @@ static void restore_keys(struct usbnet *usbdev)
restore_key(usbdev, i);
}
-
static void clear_key(struct rndis_wlan_private *priv, int idx)
{
memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
}
-
/* remove_key is for both wep and wpa */
static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
{
@@ -1508,7 +1475,6 @@ static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
return 0;
}
-
static void set_multicast_list(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1568,7 +1534,6 @@ static void set_multicast_list(struct usbnet *usbdev)
le32_to_cpu(filter), ret);
}
-
/*
* cfg80211 ops
*/
@@ -1597,7 +1562,6 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy,
return set_infra_mode(usbdev, mode);
}
-
static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
@@ -1619,7 +1583,6 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return 0;
}
-
static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
int dbm)
{
@@ -1642,7 +1605,6 @@ static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
return -ENOTSUPP;
}
-
static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
@@ -1655,7 +1617,6 @@ static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
return 0;
}
-
#define SCAN_DELAY_JIFFIES (6 * HZ)
static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request)
@@ -1692,7 +1653,6 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
return ret;
}
-
static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
struct ndis_80211_bssid_ex *bssid)
{
@@ -1741,7 +1701,6 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
GFP_KERNEL);
}
-
static int rndis_check_bssid_list(struct usbnet *usbdev)
{
void *buf = NULL;
@@ -1790,7 +1749,6 @@ out:
return ret;
}
-
static void rndis_get_scan_results(struct work_struct *work)
{
struct rndis_wlan_private *priv =
@@ -2175,7 +2133,9 @@ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
-
+/*
+ * workers, indication handlers, device poller
+ */
static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2293,7 +2253,6 @@ static void rndis_wlan_set_multicast_list(struct net_device *dev)
queue_work(priv->workqueue, &priv->work);
}
-
static void rndis_wlan_auth_indication(struct usbnet *usbdev,
struct ndis_80211_status_indication *indication,
int len)
@@ -2476,7 +2435,6 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
}
}
-
static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2523,7 +2481,6 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
}
}
-
static int rndis_wlan_get_caps(struct usbnet *usbdev)
{
struct {
@@ -2560,7 +2517,6 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev)
return retval;
}
-
#define DEVICE_POLLER_JIFFIES (HZ)
static void rndis_device_poller(struct work_struct *work)
{
@@ -2632,7 +2588,9 @@ end:
update_jiffies);
}
-
+/*
+ * driver/device initialization
+ */
static int bcm4320a_early_init(struct usbnet *usbdev)
{
/* bcm4320a doesn't handle configuration parameters well. Try
@@ -2642,7 +2600,6 @@ static int bcm4320a_early_init(struct usbnet *usbdev)
return 0;
}
-
static int bcm4320b_early_init(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2721,7 +2678,6 @@ static const struct net_device_ops rndis_wlan_netdev_ops = {
.ndo_set_multicast_list = rndis_wlan_set_multicast_list,
};
-
static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
{
struct wiphy *wiphy;
@@ -2840,7 +2796,6 @@ fail:
return retval;
}
-
static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2863,7 +2818,6 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
wiphy_free(priv->wdev.wiphy);
}
-
static int rndis_wlan_reset(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2885,7 +2839,6 @@ static int rndis_wlan_reset(struct usbnet *usbdev)
return deauthenticate(usbdev);
}
-
static int rndis_wlan_stop(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2916,7 +2869,6 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
return retval;
}
-
static const struct driver_info bcm4320b_info = {
.description = "Wireless RNDIS device, BCM4320b based",
.flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
^ permalink raw reply related
* [PATCH 1/4] rndis_wlan: use bool for on/off switches
From: Jussi Kivilinna @ 2009-09-01 12:32 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 402d367..dc2804f 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -466,7 +466,7 @@ struct rndis_wlan_private {
u32 param_workaround_interval;
/* hardware state */
- int radio_on;
+ bool radio_on;
int infra_mode;
bool connected;
u8 bssid[ETH_ALEN];
@@ -966,8 +966,8 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
}
if (ret == 0) {
memcpy(&priv->essid, ssid, sizeof(priv->essid));
- priv->radio_on = 1;
- devdbg(usbdev, "set_essid: radio_on = 1");
+ priv->radio_on = true;
+ devdbg(usbdev, "set_essid: radio_on = true");
}
return ret;
@@ -1028,7 +1028,7 @@ static bool is_associated(struct usbnet *usbdev)
}
-static int disassociate(struct usbnet *usbdev, int reset_ssid)
+static int disassociate(struct usbnet *usbdev, bool reset_ssid)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct ndis_80211_ssid ssid;
@@ -1037,8 +1037,8 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
if (priv->radio_on) {
ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
if (ret == 0) {
- priv->radio_on = 0;
- devdbg(usbdev, "disassociate: radio_on = 0");
+ priv->radio_on = false;
+ devdbg(usbdev, "disassociate: radio_on = false");
if (reset_ssid)
msleep(100);
@@ -1234,7 +1234,7 @@ static int deauthenticate(struct usbnet *usbdev)
{
int ret;
- ret = disassociate(usbdev, 1);
+ ret = disassociate(usbdev, true);
set_default_iw_params(usbdev);
return ret;
}
@@ -1634,7 +1634,7 @@ static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
*/
if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) {
if (!priv->radio_on)
- disassociate(usbdev, 1); /* turn on radio */
+ disassociate(usbdev, true); /* turn on radio */
return 0;
}
@@ -1923,7 +1923,7 @@ static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
return ret;
err_turn_radio_on:
- disassociate(usbdev, 1);
+ disassociate(usbdev, true);
return ret;
}
@@ -2031,7 +2031,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
return ret;
err_turn_radio_on:
- disassociate(usbdev, 1);
+ disassociate(usbdev, true);
return ret;
}
@@ -2823,8 +2823,8 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD);
/* turn radio on */
- priv->radio_on = 1;
- disassociate(usbdev, 1);
+ priv->radio_on = true;
+ disassociate(usbdev, true);
netif_carrier_off(usbdev->net);
return 0;
@@ -2846,7 +2846,7 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
/* turn radio off */
- disassociate(usbdev, 0);
+ disassociate(usbdev, false);
cancel_delayed_work_sync(&priv->dev_poller_work);
cancel_delayed_work_sync(&priv->scan_work);
@@ -2894,7 +2894,7 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
devdbg(usbdev, "rndis_wlan_stop");
- retval = disassociate(usbdev, 0);
+ retval = disassociate(usbdev, false);
priv->work_pending = 0;
cancel_delayed_work_sync(&priv->dev_poller_work);
^ permalink raw reply related
* [PATCH 2/2] ath9k: Call spin_lock_bh() on btcoex_lock
From: Vasanthakumar Thiagarajan @ 2009-09-01 12:16 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis.Rodriguez, Jouni.Malinen, ath9k-devel
In-Reply-To: <1251807393-8262-1-git-send-email-vasanth@atheros.com>
As generic hw timer interrupt handler is moved to tasklet,
we no more need to call spin_lock_irqsave().
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 8fb3567..e8bfb01 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -84,15 +84,14 @@ static void ath_btcoex_period_timer(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *) data;
struct ath_btcoex_info *btinfo = &sc->btcoex_info;
- unsigned long flags;
ath_detect_bt_priority(sc);
- spin_lock_irqsave(&btinfo->btcoex_lock, flags);
+ spin_lock_bh(&btinfo->btcoex_lock);
ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
- spin_unlock_irqrestore(&btinfo->btcoex_lock, flags);
+ spin_unlock_bh(&btinfo->btcoex_lock);
if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) {
if (btinfo->hw_timer_enabled)
@@ -119,18 +118,17 @@ static void ath_btcoex_no_stomp_timer(void *arg)
{
struct ath_softc *sc = (struct ath_softc *)arg;
struct ath_btcoex_info *btinfo = &sc->btcoex_info;
- unsigned long flags;
DPRINTF(sc, ATH_DBG_BTCOEX, "no stomp timer running \n");
- spin_lock_irqsave(&btinfo->btcoex_lock, flags);
+ spin_lock_bh(&btinfo->btcoex_lock);
if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
- spin_unlock_irqrestore(&btinfo->btcoex_lock, flags);
+ spin_unlock_bh(&btinfo->btcoex_lock);
}
static int ath_init_btcoex_info(struct ath_hw *hw,
--
1.5.5.1
^ permalink raw reply related
* [PATCH 1/2] ath9k: Move generic hw timer intr handler to bottom-half
From: Vasanthakumar Thiagarajan @ 2009-09-01 12:16 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis.Rodriguez, Jouni.Malinen, ath9k-devel
There is no point handling this in hard irq, move it to
tasklet.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/main.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4fae699..efee193 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -506,6 +506,10 @@ static void ath9k_tasklet(unsigned long data)
sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
}
+ if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+ if (status & ATH9K_INT_GENTIMER)
+ ath_gen_timer_isr(sc->sc_ah);
+
/* re-enable hardware interrupt */
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
ath9k_ps_restore(sc);
@@ -521,7 +525,8 @@ irqreturn_t ath_isr(int irq, void *dev)
ATH9K_INT_TX | \
ATH9K_INT_BMISS | \
ATH9K_INT_CST | \
- ATH9K_INT_TSFOOR)
+ ATH9K_INT_TSFOOR | \
+ ATH9K_INT_GENTIMER)
struct ath_softc *sc = dev;
struct ath_hw *ah = sc->sc_ah;
@@ -602,10 +607,6 @@ irqreturn_t ath_isr(int irq, void *dev)
sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
}
- if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
- if (status & ATH9K_INT_GENTIMER)
- ath_gen_timer_isr(ah);
-
chip_reset:
ath_debug_stat_interrupt(sc, status);
--
1.5.5.1
^ permalink raw reply related
* soft lockup in cfg80211 find_ie()
From: Bob Copeland @ 2009-09-01 12:17 UTC (permalink / raw)
To: linux-wireless
Hi,
My laptop was on all night and at some point got stuck in a loop.
Unfortunately I don't know exactly what happened since dmesg buffer
filled up and there was nothing incriminating in /var/log, but
here's my interpretation:
EIP points to line 146:
while (len > 2 && ies[0] != num) ...
ECX holds len, which is negative (unfortunately size_t is unsigned)
EDX holds ies, looks like a valid pointer
EBX holds num, which is 0.
This looks like this is a DoS-able bug if there are any malformed
packets, no? I think we should change 'len' to int here.
[38442.105007] BUG: soft lockup - CPU#0 stuck for 61s! [phy0:2230]
[38442.105007] Modules linked in: aes_i586 aes_generic fuse af_packet ipt_REJECT xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 xt_state iptable_filter ip_tables x_tables acpi_cpufreq binfmt_misc dm_mirror dm_region_hash dm_log dm_multipath dm_mod kvm_intel kvm uinput i915 arc4 ecb drm snd_hda_codec_idt ath5k snd_hda_intel hid_apple mac80211 usbhid appletouch snd_hda_codec snd_pcm ath cfg80211 snd_timer i2c_algo_bit ohci1394 video snd processor ieee1394 rfkill ehci_hcd sg sky2 backlight snd_page_alloc uhci_hcd joydev output ac thermal button battery sr_mod applesmc cdrom input_polldev evdev unix [last unloaded: scsi_wait_scan]
[38442.105007] irq event stamp: 2044208759
[38442.105007] hardirqs last enabled at (2044208758): [<c1002ffc>] restore_all_notrace+0x0/0x18
[38442.105007] hardirqs last disabled at (2044208759): [<c10038f4>] apic_timer_interrupt+0x28/0x34
[38442.105007] softirqs last enabled at (92950144): [<c103ab48>] __do_softirq+0x108/0x210
[38442.105007] softirqs last disabled at (92950274): [<c1348e74>] _spin_lock_bh+0x14/0x80
[38442.105007]
[38442.105007] Pid: 2230, comm: phy0 Tainted: G W (2.6.31-rc7-wl #8) MacBook1,1
[38442.105007] EIP: 0060:[<f8ea2d50>] EFLAGS: 00010292 CPU: 0
[38442.105007] EIP is at cmp_ies+0x30/0x180 [cfg80211]
[38442.105007] EAX: 00000082 EBX: 00000000 ECX: ffffffc1 EDX: d8efd014
[38442.105007] ESI: ffffff7c EDI: 0000004d EBP: eee2dc50 ESP: eee2dc3c
[38442.105007] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[38442.105007] CR0: 8005003b CR2: d8efd014 CR3: 01694000 CR4: 000026d0
[38442.105007] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[38442.105007] DR6: ffff0ff0 DR7: 00000400
[38442.105007] Call Trace:
[38442.105007] [<f8ea2f8d>] cmp_bss+0xed/0x100 [cfg80211]
[38442.105007] [<f8ea33e4>] cfg80211_bss_update+0x84/0x410 [cfg80211]
[38442.105007] [<f8ea3884>] cfg80211_inform_bss_frame+0x114/0x180 [cfg80211]
[38442.105007] [<f97255ff>] ieee80211_bss_info_update+0x4f/0x180 [mac80211]
[38442.105007] [<f972b118>] ieee80211_rx_bss_info+0x88/0xf0 [mac80211]
[38442.105007] [<f9739297>] ? ieee802_11_parse_elems+0x27/0x30 [mac80211]
[38442.105007] [<f972b224>] ieee80211_rx_mgmt_probe_resp+0xa4/0x1c0 [mac80211]
[38442.105007] [<f972bc59>] ieee80211_sta_rx_queued_mgmt+0x919/0xc50 [mac80211]
[38442.105007] [<c1009707>] ? sched_clock+0x27/0xa0
[38442.105007] [<c1009707>] ? sched_clock+0x27/0xa0
[38442.105007] [<c105ffd0>] ? mark_held_locks+0x60/0x80
[38442.105007] [<c1348be5>] ? _spin_unlock_irqrestore+0x55/0x70
[38442.105007] [<c134baa5>] ? sub_preempt_count+0x85/0xc0
[38442.105007] [<c1348bce>] ? _spin_unlock_irqrestore+0x3e/0x70
[38442.105007] [<c12c1c0f>] ? skb_dequeue+0x4f/0x70
[38442.105007] [<f972c021>] ieee80211_sta_work+0x91/0xb80 [mac80211]
[38442.105007] [<c1009707>] ? sched_clock+0x27/0xa0
[38442.105007] [<c134baa5>] ? sub_preempt_count+0x85/0xc0
[38442.105007] [<c10479af>] worker_thread+0x18f/0x320
[38442.105007] [<c104794e>] ? worker_thread+0x12e/0x320
[38442.105007] [<c1348be5>] ? _spin_unlock_irqrestore+0x55/0x70
[38442.105007] [<f972bf90>] ? ieee80211_sta_work+0x0/0xb80 [mac80211]
[38442.105007] [<c104cbb0>] ? autoremove_wake_function+0x0/0x50
[38442.105007] [<c1047820>] ? worker_thread+0x0/0x320
[38442.105007] [<c104c854>] kthread+0x84/0x90
[38442.105007] [<c104c7d0>] ? kthread+0x0/0x90
[38442.105007] [<c1003ab7>] kernel_thread_helper+0x7/0x10
[38507.604007] BUG: soft lockup - CPU#0 stuck for 61s! [phy0:2230]
[38507.604007] Modules linked in: aes_i586 aes_generic fuse af_packet ipt_REJECT xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 xt_state iptable_filter ip_tables x_tables acpi_cpufreq binfmt_misc dm_mirror dm_region_hash dm_log dm_multipath dm_mod kvm_intel kvm uinput i915 arc4 ecb drm snd_hda_codec_idt ath5k snd_hda_intel hid_apple mac80211 usbhid appletouch snd_hda_codec snd_pcm ath cfg80211 snd_timer i2c_algo_bit ohci1394 video snd processor ieee1394 rfkill ehci_hcd sg sky2 backlight snd_page_alloc uhci_hcd joydev output ac thermal button battery sr_mod applesmc cdrom input_polldev evdev unix [last unloaded: scsi_wait_scan]
[38507.604007] irq event stamp: 2295973181
[38507.604007] hardirqs last enabled at (2295973180): [<c1002ffc>] restore_all_notrace+0x0/0x18
[38507.604007] hardirqs last disabled at (2295973181): [<c10038f4>] apic_timer_interrupt+0x28/0x34
[38507.604007] softirqs last enabled at (92950144): [<c103ab48>] __do_softirq+0x108/0x210
[38507.604007] softirqs last disabled at (92950274): [<c1348e74>] _spin_lock_bh+0x14/0x80
[38507.604007]
[38507.604007] Pid: 2230, comm: phy0 Tainted: G W (2.6.31-rc7-wl #8) MacBook1,1
[38507.604007] EIP: 0060:[<f8ea2d50>] EFLAGS: 00010292 CPU: 0
[38507.604007] EIP is at cmp_ies+0x30/0x180 [cfg80211]
[38507.604007] EAX: 00000082 EBX: 00000000 ECX: ffffffc1 EDX: d8efd014
[38507.604007] ESI: ffffff7c EDI: 0000004d EBP: eee2dc50 ESP: eee2dc3c
[38507.604007] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[38507.604007] CR0: 8005003b CR2: d8efd014 CR3: 01694000 CR4: 000026d0
[38507.604007] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[38507.604007] DR6: ffff0ff0 DR7: 00000400
[38507.604007] Call Trace:
[38507.604007] [<f8ea2f8d>] cmp_bss+0xed/0x100 [cfg80211]
[38507.604007] [<f8ea33e4>] cfg80211_bss_update+0x84/0x410 [cfg80211]
[38507.604007] [<f8ea3884>] cfg80211_inform_bss_frame+0x114/0x180 [cfg80211]
[38507.604007] [<f97255ff>] ieee80211_bss_info_update+0x4f/0x180 [mac80211]
[38507.604007] [<f972b118>] ieee80211_rx_bss_info+0x88/0xf0 [mac80211]
[38507.604007] [<f9739297>] ? ieee802_11_parse_elems+0x27/0x30 [mac80211]
[38507.604007] [<f972b224>] ieee80211_rx_mgmt_probe_resp+0xa4/0x1c0 [mac80211]
[38507.604007] [<f972bc59>] ieee80211_sta_rx_queued_mgmt+0x919/0xc50 [mac80211]
[38507.604007] [<c1009707>] ? sched_clock+0x27/0xa0
[38507.604007] [<c1009707>] ? sched_clock+0x27/0xa0
[38507.604007] [<c105ffd0>] ? mark_held_locks+0x60/0x80
[38507.604007] [<c1348be5>] ? _spin_unlock_irqrestore+0x55/0x70
[38507.604007] [<c134baa5>] ? sub_preempt_count+0x85/0xc0
[38507.604007] [<c1348bce>] ? _spin_unlock_irqrestore+0x3e/0x70
[38507.604007] [<c12c1c0f>] ? skb_dequeue+0x4f/0x70
[38507.604007] [<f972c021>] ieee80211_sta_work+0x91/0xb80 [mac80211]
[38507.604007] [<c1009707>] ? sched_clock+0x27/0xa0
[38507.604007] [<c134baa5>] ? sub_preempt_count+0x85/0xc0
[38507.604007] [<c10479af>] worker_thread+0x18f/0x320
[38507.604007] [<c104794e>] ? worker_thread+0x12e/0x320
[38507.604007] [<c1348be5>] ? _spin_unlock_irqrestore+0x55/0x70
[38507.604007] [<f972bf90>] ? ieee80211_sta_work+0x0/0xb80 [mac80211]
[38507.604007] [<c104cbb0>] ? autoremove_wake_function+0x0/0x50
[38507.604007] [<c1047820>] ? worker_thread+0x0/0x320
[38507.604007] [<c104c854>] kthread+0x84/0x90
[38507.604007] [<c104c7d0>] ? kthread+0x0/0x90
[38507.604007] [<c1003ab7>] kernel_thread_helper+0x7/0x10
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* Re: [PATCH v2] mac80211: Fix output of minstrels rc_stats
From: Arnd Hannemann @ 2009-09-01 8:05 UTC (permalink / raw)
To: Julian Calaby
Cc: Arnd Hannemann, linux-wireless@vger.kernel.org, joe@perches.com,
proski@gnu.org
In-Reply-To: <646765f40908311754l7bd16185pe21182cdba6e6ac8@mail.gmail.com>
Julian Calaby wrote:
> On Tue, Aug 25, 2009 at 04:51, Arnd
> Hannemann<hannemann@nets.rwth-aachen.de> wrote:
>> An integer overflow in the minstrel debug code prevented the
>> throughput to be displayed correctly. This patch fixes that,
>> by permutating operations like proposed by Pavel Roskin.
>>
>> Signed-off-by: Arnd Hannemann <hannemann@nets.rwth-aachen.de>
>> ---
>> net/mac80211/rc80211_minstrel_debugfs.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
>> index 98f4807..3d72ec5 100644
>> --- a/net/mac80211/rc80211_minstrel_debugfs.c
>> +++ b/net/mac80211/rc80211_minstrel_debugfs.c
>> @@ -83,7 +83,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
>> p += sprintf(p, "%3u%s", mr->bitrate / 2,
>> (mr->bitrate & 1 ? ".5" : " "));
>>
>> - tp = ((mr->cur_tp * 96) / 18000) >> 10;
>> + tp = mr->cur_tp / ((18000 << 10) / 96);
>
> Sorry about being so late, but wouldn't:
>
> tp = ((mr->cur_tp * 2) / 375) >> 10;
>
> also work? (Assuming that the numbers in the constant aren't important)
I needed a while to figure out why those constants are used, but finally
they made some sense, so I think its best to preserve them.
mr->cur_tp is the time to send one 1200 byte packet (9600 bits),
the loss probelity is scaled between 0-18000 to reduce rounding error.
>
> or even:
>
> tp = (mr->cur_tp / 375) >> 9;
See above.
Best regards,
Arnd
^ 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