* Re: [PATCH 3/3] ath9k: Implement an algorithm for Antenna diversity and combining
From: Vasanthakumar Thiagarajan @ 2010-07-30 5:36 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Vasanth Thiagarajan, linville@tuxdriver.com,
linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTimiQZj7Gh5g+W0pcuWYFejt4EGQVCEQQ1aNvsk5@mail.gmail.com>
On Thu, Jul 29, 2010 at 08:09:35PM +0530, Luis R. Rodriguez wrote:
> On Thu, Jul 29, 2010 at 5:56 AM, Vasanthakumar Thiagarajan
> <vasanth@atheros.com> wrote:
> > This algorithm chooses the best main and alt lna out of
> > LNA1, LNA2, LNA1+LNA2 and LNA1-LNA2 to improve rx for single
> > chain chips(AR9285). This would greatly improve rx when there
> > is only one antenna is connected with AR9285.
> >
> > Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
>
> > diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
> > index 243c177..8b4e4a6 100644
> > --- a/drivers/net/wireless/ath/ath9k/init.c
> > +++ b/drivers/net/wireless/ath/ath9k/init.c
> > @@ -531,6 +531,11 @@ static void ath9k_init_misc(struct ath_softc *sc)
> > sc->beacon.bslot[i] = NULL;
> > sc->beacon.bslot_aphy[i] = NULL;
> > }
> > +
> > + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
> > + memset(&sc->ant_comb, 0, sizeof(struct ath_ant_comb));
>
> I do not believe this memset is required since we kzalloc()'d the ah struct.
that,s true. thanks.
>
> Wow this routine is pretty large. Could you split this up into a few
> helpers which describe what they do ?
right, this one is pretty large, let me see if I can split things
up.
> Also notice how this ended up calling ath9k_hw_antdiv_comb_conf_get()
> and ath9k_hw_antdiv_comb_conf_set(), the only callers of those
> routines, and this itself is done when:
>
> > +
> > int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
> > {
> > struct ath_buf *bf;
> > @@ -1210,6 +1738,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
> > PS_WAIT_FOR_PSPOLL_DATA))))
> > ath_rx_ps(sc, skb);
> >
> > + if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
> > + ath_ant_comb_scan(sc, &rs);
> > +
> > ath_rx_send_to_mac80211(hw, sc, skb, rxs);
> >
> > requeue:
>
> So the call currently really does not require to be abstracted away
> unless we expect another 1x1 device where it will have its own set of
> calls, eventually.
hm, i actually planned not to abstract, not sure how I ended up
doing this one. I'll send the next version of this series. thanks.
Vasanth
^ permalink raw reply
* [wt PATCH 5/5] libertas: scan before assocation if no BSSID was given
From: Dan Williams @ 2010-07-30 6:18 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280470034.14523.4.camel@dcbw.foobar.com>
Fix this leftover TODO from the cfg80211 conversion by doing a scan
if cfg80211 didn't pass in the BSSID for us. Since the scan code
uses so much of the cfg80211_scan_request structure to build up the
firmware command, we just fake one when the scan request is triggered
internally. But we need to make sure that internal 'fake' cfg82011
scan request does get back to cfg82011 via cfg80211_scan_done().
Signed-off-by: Dan Williams <dcbw@redhat.com>
---
drivers/net/wireless/libertas/cfg.c | 148 ++++++++++++++++++++++++++--------
drivers/net/wireless/libertas/dev.h | 5 +
drivers/net/wireless/libertas/main.c | 1 +
3 files changed, 121 insertions(+), 33 deletions(-)
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index a8c0126..623b81e 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -715,8 +715,13 @@ static void lbs_scan_worker(struct work_struct *work)
if (priv->scan_channel >= priv->scan_req->n_channels) {
/* Mark scan done */
- cfg80211_scan_done(priv->scan_req, false);
+ if (priv->internal_scan)
+ kfree(priv->scan_req);
+ else
+ cfg80211_scan_done(priv->scan_req, false);
+
priv->scan_req = NULL;
+ priv->last_scan = jiffies;
}
/* Restart network */
@@ -727,10 +732,33 @@ static void lbs_scan_worker(struct work_struct *work)
kfree(scan_cmd);
+ /* Wake up anything waiting on scan completion */
+ if (priv->scan_req == NULL) {
+ lbs_deb_scan("scan: waking up waiters\n");
+ wake_up_all(&priv->scan_q);
+ }
+
out_no_scan_cmd:
lbs_deb_leave(LBS_DEB_SCAN);
}
+static void _internal_start_scan(struct lbs_private *priv, bool internal,
+ struct cfg80211_scan_request *request)
+{
+ lbs_deb_enter(LBS_DEB_CFG80211);
+
+ lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
+ request->n_ssids, request->n_channels, request->ie_len);
+
+ priv->scan_channel = 0;
+ queue_delayed_work(priv->work_thread, &priv->scan_work,
+ msecs_to_jiffies(50));
+
+ priv->scan_req = request;
+ priv->internal_scan = internal;
+
+ lbs_deb_leave(LBS_DEB_CFG80211);
+}
static int lbs_cfg_scan(struct wiphy *wiphy,
struct net_device *dev,
@@ -747,18 +775,11 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
goto out;
}
- lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
- request->n_ssids, request->n_channels, request->ie_len);
-
- priv->scan_channel = 0;
- queue_delayed_work(priv->work_thread, &priv->scan_work,
- msecs_to_jiffies(50));
+ _internal_start_scan(priv, false, request);
if (priv->surpriseremoved)
ret = -EIO;
- priv->scan_req = request;
-
out:
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
@@ -1193,7 +1214,62 @@ done:
return ret;
}
+static struct cfg80211_scan_request *
+_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
+{
+ struct cfg80211_scan_request *creq = NULL;
+ int i, n_channels = 0;
+ enum ieee80211_band band;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ if (wiphy->bands[band])
+ n_channels += wiphy->bands[band]->n_channels;
+ }
+
+ creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
+ n_channels * sizeof(void *),
+ GFP_ATOMIC);
+ if (!creq)
+ return NULL;
+
+ /* SSIDs come after channels */
+ creq->ssids = (void *)&creq->channels[n_channels];
+ creq->n_channels = n_channels;
+ creq->n_ssids = 1;
+
+ /* Scan all available channels */
+ i = 0;
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ int j;
+
+ if (!wiphy->bands[band])
+ continue;
+
+ for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ /* ignore disabled channels */
+ if (wiphy->bands[band]->channels[j].flags &
+ IEEE80211_CHAN_DISABLED)
+ continue;
+
+ creq->channels[i] = &wiphy->bands[band]->channels[j];
+ i++;
+ }
+ }
+ if (i) {
+ /* Set real number of channels specified in creq->channels[] */
+ creq->n_channels = i;
+
+ /* Scan for the SSID we're going to connect to */
+ memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len);
+ creq->ssids[0].ssid_len = sme->ssid_len;
+ } else {
+ /* No channels found... */
+ kfree(creq);
+ creq = NULL;
+ }
+ return creq;
+}
static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
@@ -1205,37 +1281,43 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
lbs_deb_enter(LBS_DEB_CFG80211);
- if (sme->bssid) {
- bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
- sme->ssid, sme->ssid_len,
- WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
- } else {
- /*
- * Here we have an impedance mismatch. The firmware command
- * CMD_802_11_ASSOCIATE always needs a BSSID, it cannot
- * connect otherwise. However, for the connect-API of
- * cfg80211 the bssid is purely optional. We don't get one,
- * except the user specifies one on the "iw" command line.
- *
- * If we don't got one, we could initiate a scan and look
- * for the best matching cfg80211_bss entry.
- *
- * Or, better yet, net/wireless/sme.c get's rewritten into
- * something more generally useful.
+ if (!sme->bssid) {
+ /* Run a scan if one isn't in-progress already and if the last
+ * scan was done more than 2 seconds ago.
*/
- lbs_pr_err("TODO: no BSS specified\n");
- ret = -ENOTSUPP;
- goto done;
- }
+ if (priv->scan_req == NULL &&
+ time_after(jiffies, priv->last_scan + (2 * HZ))) {
+ struct cfg80211_scan_request *creq;
+ creq = _new_connect_scan_req(wiphy, sme);
+ if (!creq) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ lbs_deb_assoc("assoc: scanning for compatible AP\n");
+ _internal_start_scan(priv, true, creq);
+ }
+
+ /* Wait for any in-progress scan to complete */
+ lbs_deb_assoc("assoc: waiting for scan to complete\n");
+ wait_event_interruptible_timeout(priv->scan_q,
+ (priv->scan_req == NULL),
+ (15 * HZ));
+ lbs_deb_assoc("assoc: scanning competed\n");
+ }
+ /* Find the BSS we want using available scan results */
+ bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
+ sme->ssid, sme->ssid_len,
+ WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!bss) {
- lbs_pr_err("assicate: bss %pM not in scan results\n",
+ lbs_pr_err("assoc: bss %pM not in scan results\n",
sme->bssid);
ret = -ENOENT;
goto done;
}
- lbs_deb_assoc("trying %pM", sme->bssid);
+ lbs_deb_assoc("trying %pM\n", bss->bssid);
lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
sme->crypto.cipher_group,
sme->key_idx, sme->key_len);
@@ -1298,7 +1380,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
lbs_set_radio(priv, preamble, 1);
/* Do the actual association */
- lbs_associate(priv, bss, sme);
+ ret = lbs_associate(priv, bss, sme);
done:
if (bss)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 3c7e255..f062ed5 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -161,6 +161,11 @@ struct lbs_private {
/** Scanning */
struct delayed_work scan_work;
int scan_channel;
+ /* Queue of things waiting for scan completion */
+ wait_queue_head_t scan_q;
+ /* Whether the scan was initiated internally and not by cfg80211 */
+ bool internal_scan;
+ unsigned long last_scan;
};
extern struct cmd_confirm_sleep confirm_sleep;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 2589671..24958a8 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -719,6 +719,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
priv->deep_sleep_required = 0;
priv->wakeup_dev_required = 0;
init_waitqueue_head(&priv->ds_awake_q);
+ init_waitqueue_head(&priv->scan_q);
priv->authtype_auto = 1;
priv->is_host_sleep_configured = 0;
priv->is_host_sleep_activated = 0;
--
1.7.2
^ permalink raw reply related
* [wt PATCH 4/5] libertas: fix association with some APs by using extended rates
From: Dan Williams @ 2010-07-30 6:16 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280470034.14523.4.camel@dcbw.foobar.com>
Some APs get pissy if you don't send the firmware the extended rates
in the association request's rates TLV. Found this on a Linksys
WRT54G v2; it denies association with status code 18 unless you
add the extended rates too. The old driver did this, but it got
lost in the cfg80211 conversion.
Signed-off-by: Dan Williams <dcbw@redhat.com>
---
drivers/net/wireless/libertas/cfg.c | 56 +++++++++++++++++++++++++----------
1 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index a9647e6..a8c0126 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -257,6 +257,29 @@ static int lbs_add_supported_rates_tlv(u8 *tlv)
return sizeof(rate_tlv->header) + i;
}
+/* Add common rates from a TLV and return the new end of the TLV */
+static u8 *
+add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
+{
+ int hw, ap, ap_max = ie[1];
+ u8 hw_rate;
+
+ /* Advance past IE header */
+ ie += 2;
+
+ lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
+
+ for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
+ hw_rate = lbs_rates[hw].bitrate / 5;
+ for (ap = 0; ap < ap_max; ap++) {
+ if (hw_rate == (ie[ap] & 0x7f)) {
+ *tlv++ = ie[ap];
+ *nrates = *nrates + 1;
+ }
+ }
+ }
+ return tlv;
+}
/*
* Adds a TLV with all rates the hardware *and* BSS supports.
@@ -264,8 +287,11 @@ static int lbs_add_supported_rates_tlv(u8 *tlv)
static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
{
struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
- const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
- int n;
+ const u8 *rates_eid, *ext_rates_eid;
+ int n = 0;
+
+ rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
+ ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
/*
* 01 00 TLV_TYPE_RATES
@@ -275,26 +301,21 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
tlv += sizeof(rate_tlv->header);
- if (!rates_eid) {
+ /* Add basic rates */
+ if (rates_eid) {
+ tlv = add_ie_rates(tlv, rates_eid, &n);
+
+ /* Add extended rates, if any */
+ if (ext_rates_eid)
+ tlv = add_ie_rates(tlv, ext_rates_eid, &n);
+ } else {
+ lbs_deb_assoc("assoc: bss had no basic rate IE\n");
/* Fallback: add basic 802.11b rates */
*tlv++ = 0x82;
*tlv++ = 0x84;
*tlv++ = 0x8b;
*tlv++ = 0x96;
n = 4;
- } else {
- int hw, ap;
- u8 ap_max = rates_eid[1];
- n = 0;
- for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
- u8 hw_rate = lbs_rates[hw].bitrate / 5;
- for (ap = 0; ap < ap_max; ap++) {
- if (hw_rate == (rates_eid[ap+2] & 0x7f)) {
- *tlv++ = rates_eid[ap+2];
- n++;
- }
- }
- }
}
rate_tlv->header.len = cpu_to_le16(n);
@@ -1024,6 +1045,7 @@ static int lbs_associate(struct lbs_private *priv,
int status;
int ret;
u8 *pos = &(cmd->iebuf[0]);
+ u8 *tmp;
lbs_deb_enter(LBS_DEB_CFG80211);
@@ -1068,7 +1090,9 @@ static int lbs_associate(struct lbs_private *priv,
pos += lbs_add_cf_param_tlv(pos);
/* add rates TLV */
+ tmp = pos + 4; /* skip Marvell IE header */
pos += lbs_add_common_rates_tlv(pos, bss);
+ lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
/* add auth type TLV */
if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 9)
--
1.7.2
^ permalink raw reply related
* [wt PATCH 3/5] libertas: better association request debugging
From: Dan Williams @ 2010-07-30 6:14 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280470034.14523.4.camel@dcbw.foobar.com>
Bring back the comment about FW v5 status codes from the pre-cfg80211
driver, and let through status codes that aren't remapped by the
firmware.
Signed-off-by: Dan Williams <dcbw@redhat.com>
---
drivers/net/wireless/libertas/cfg.c | 37 +++++++++++++++++++++++++++-------
1 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index c7da6c0..a9647e6 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1071,7 +1071,7 @@ static int lbs_associate(struct lbs_private *priv,
pos += lbs_add_common_rates_tlv(pos, bss);
/* add auth type TLV */
- if (priv->fwrelease >= 0x09000000)
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
/* add WPA/WPA2 TLV */
@@ -1082,6 +1082,9 @@ static int lbs_associate(struct lbs_private *priv,
(u16)(pos - (u8 *) &cmd->iebuf);
cmd->hdr.size = cpu_to_le16(len);
+ lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
+ le16_to_cpu(cmd->hdr.size));
+
/* store for later use */
memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
@@ -1089,14 +1092,28 @@ static int lbs_associate(struct lbs_private *priv,
if (ret)
goto done;
-
/* generate connect message to cfg80211 */
resp = (void *) cmd; /* recast for easier field access */
status = le16_to_cpu(resp->statuscode);
- /* Convert statis code of old firmware */
- if (priv->fwrelease < 0x09000000)
+ /* Older FW versions map the IEEE 802.11 Status Code in the association
+ * response to the following values returned in resp->statuscode:
+ *
+ * IEEE Status Code Marvell Status Code
+ * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
+ * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * others -> 0x0003 ASSOC_RESULT_REFUSED
+ *
+ * Other response codes:
+ * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
+ * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
+ * association response from the AP)
+ */
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
switch (status) {
case 0:
break;
@@ -1118,11 +1135,16 @@ static int lbs_associate(struct lbs_private *priv,
break;
default:
lbs_deb_assoc("association failure %d\n", status);
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ /* v5 OLPC firmware does return the AP status code if
+ * it's not one of the values above. Let that through.
+ */
+ break;
+ }
}
- lbs_deb_assoc("status %d, capability 0x%04x\n", status,
- le16_to_cpu(resp->capability));
+ lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
+ "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
+ le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
resp_ie_len = le16_to_cpu(resp->hdr.size)
- sizeof(resp->hdr)
@@ -1142,7 +1164,6 @@ static int lbs_associate(struct lbs_private *priv,
netif_tx_wake_all_queues(priv->dev);
}
-
done:
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
--
1.7.2
^ permalink raw reply related
* [wt PATCH 2/5] libertas: better scan response debugging
From: Dan Williams @ 2010-07-30 6:12 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280470034.14523.4.camel@dcbw.foobar.com>
Make it a bit easier to debug scan results in the future.
Signed-off-by: Dan Williams <dcbw@redhat.com>
---
drivers/net/wireless/libertas/cfg.c | 24 ++++++++++++++++++++----
1 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index b60f661..c7da6c0 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -502,20 +502,31 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
pos = scanresp->bssdesc_and_tlvbuffer;
+ lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
+ scanresp->bssdescriptsize);
+
tsfdesc = pos + bsssize;
tsfsize = 4 + 8 * scanresp->nr_sets;
+ lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
/* Validity check: we expect a Marvell-Local TLV */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
- if (i != TLV_TYPE_TSFTIMESTAMP)
+ if (i != TLV_TYPE_TSFTIMESTAMP) {
+ lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
goto done;
+ }
+
/* Validity check: the TLV holds TSF values with 8 bytes each, so
* the size in the TLV must match the nr_sets value */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
- if (i / 8 != scanresp->nr_sets)
+ if (i / 8 != scanresp->nr_sets) {
+ lbs_deb_scan("scan response: invalid number of TSF timestamp "
+ "sets (expected %d got %d)\n", scanresp->nr_sets,
+ i / 8);
goto done;
+ }
for (i = 0; i < scanresp->nr_sets; i++) {
const u8 *bssid;
@@ -557,8 +568,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
id = *pos++;
elen = *pos++;
left -= 2;
- if (elen > left || elen == 0)
+ if (elen > left || elen == 0) {
+ lbs_deb_scan("scan response: invalid IE fmt\n");
goto done;
+ }
+
if (id == WLAN_EID_DS_PARAMS)
chan_no = *pos;
if (id == WLAN_EID_SSID) {
@@ -589,7 +603,9 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
capa, intvl, ie, ielen,
LBS_SCAN_RSSI_TO_MBM(rssi),
GFP_KERNEL);
- }
+ } else
+ lbs_deb_scan("scan response: missing BSS channel IE\n");
+
tsfdesc += 8;
}
ret = 0;
--
1.7.2
^ permalink raw reply related
* [wt PATCH 1/5] libertas: get the right # of scanned BSSes
From: Dan Williams @ 2010-07-30 6:11 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280470034.14523.4.camel@dcbw.foobar.com>
Let's actually check the right field in the command response; and
if there aren't any reported BSSes, exit early with success.
Signed-off-by: Dan Williams <dcbw@redhat.com>
---
drivers/net/wireless/libertas/cfg.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 25f9027..b60f661 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -465,7 +465,15 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
lbs_deb_enter(LBS_DEB_CFG80211);
bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
- nr_sets = le16_to_cpu(resp->size);
+ nr_sets = le16_to_cpu(scanresp->nr_sets);
+
+ lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
+ nr_sets, bsssize, le16_to_cpu(resp->size));
+
+ if (nr_sets == 0) {
+ ret = 0;
+ goto done;
+ }
/*
* The general layout of the scan response is described in chapter
--
1.7.2
^ permalink raw reply related
* [wt PATCH 0/5] libertas: make association work again
From: Dan Williams @ 2010-07-30 6:07 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
This series makes libertas actually associate with APs after the
cfg80211 conversion. There was a pretty big TODO where if cfg80211
didn't pass in the BSSID of the AP to associate with, then libertas
would fail because the firmware really, really, really wants a BSSID.
So lets do a scan to find that BSSID. The other notable change is
a fix to make sure all supported rates are included in the firmware's
association request, lack of which caused some APs to deny the attempt.
Dan Williams (5):
libertas: get the right # of scanned BSSes
libertas: better scan response debugging
libertas: better association request debugging
libertas: fix association with some APs by using extended rates
libertas: scan before assocation if no BSSID was given
drivers/net/wireless/libertas/cfg.c | 275 ++++++++++++++++++++++++++--------
drivers/net/wireless/libertas/dev.h | 5 +
drivers/net/wireless/libertas/main.c | 1 +
3 files changed, 219 insertions(+), 62 deletions(-)
^ permalink raw reply
* Re: [PATCH] rtl8187: consolidate MSR writes in rtl8187_bss_info_changed
From: Hin-Tak Leung @ 2010-07-30 3:22 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Herton Ronaldo Krzesinski, Larry Finger
In-Reply-To: <1280455044-26073-1-git-send-email-linville@tuxdriver.com>
John W. Linville wrote:
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Thanks for looking this over. I wondered how the code came to be like this, so I
went to look it up - the reason was that we used to have more lines between the
{}'s and they were gradually removed. The full list of defines for the
RTL818X_MSR_* are :
#define RTL818X_MSR_NO_LINK (0 << 2)
#define RTL818X_MSR_ADHOC (1 << 2)
#define RTL818X_MSR_INFRA (2 << 2)
#define RTL818X_MSR_MASTER (3 << 2)
#define RTL818X_MSR_ENEDCA (4 << 2)
but we only use 3 at the moment (not _AHOC nor _MASTER).
Hin-Tak
> ---
> drivers/net/wireless/rtl818x/rtl8187_dev.c | 9 ++++-----
> 1 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
> index 5738a55..0801c1d 100644
> --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
> +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
> @@ -1176,13 +1176,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
> else
> reg = 0;
>
> - if (is_valid_ether_addr(info->bssid)) {
> + if (is_valid_ether_addr(info->bssid))
> reg |= RTL818X_MSR_INFRA;
> - rtl818x_iowrite8(priv, &priv->map->MSR, reg);
> - } else {
> + else
> reg |= RTL818X_MSR_NO_LINK;
> - rtl818x_iowrite8(priv, &priv->map->MSR, reg);
> - }
> +
> + rtl818x_iowrite8(priv, &priv->map->MSR, reg);
>
> mutex_unlock(&priv->conf_mutex);
> }
^ permalink raw reply
* Re: [PATCH] rtl8187: consolidate MSR writes in rtl8187_bss_info_changed
From: Larry Finger @ 2010-07-30 3:14 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Herton Ronaldo Krzesinski, Hin-Tak Leung
In-Reply-To: <1280455044-26073-1-git-send-email-linville@tuxdriver.com>
On 07/29/2010 08:57 PM, John W. Linville wrote:
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
> ---
ACK.
Larry
^ permalink raw reply
* [PATCH] ath9k: add fastcc to debug print for channel change
From: Luis R. Rodriguez @ 2010-07-30 2:56 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
This helps us debug channel changes better.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/main.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0429dda..5999a61 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -195,9 +195,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
fastcc = false;
ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
+ "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
sc->sc_ah->curchan->channel,
- channel->center_freq, conf_is_ht40(conf));
+ channel->center_freq, conf_is_ht40(conf),
+ fastcc);
spin_lock_bh(&sc->sc_resetlock);
--
1.7.0.4
^ permalink raw reply related
* [PATCH] rtl8187: consolidate MSR writes in rtl8187_bss_info_changed
From: John W. Linville @ 2010-07-30 1:57 UTC (permalink / raw)
To: linux-wireless
Cc: Herton Ronaldo Krzesinski, Hin-Tak Leung, Larry Finger,
John W. Linville
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/rtl818x/rtl8187_dev.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 5738a55..0801c1d 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1176,13 +1176,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
else
reg = 0;
- if (is_valid_ether_addr(info->bssid)) {
+ if (is_valid_ether_addr(info->bssid))
reg |= RTL818X_MSR_INFRA;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- } else {
+ else
reg |= RTL818X_MSR_NO_LINK;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- }
+
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
mutex_unlock(&priv->conf_mutex);
}
--
1.7.1.1
^ permalink raw reply related
* [PATCH] rtl8180: use RTL818X_MSR_ADHOC for IBSS connection
From: John W. Linville @ 2010-07-30 1:56 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/rtl818x/rtl8180_dev.c | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index c879660..2c44753 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -788,6 +788,7 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_vif *vif_priv;
int i;
+ u8 reg;
vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
@@ -796,12 +797,14 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
rtl818x_iowrite8(priv, &priv->map->BSSID[i],
info->bssid[i]);
- if (is_valid_ether_addr(info->bssid))
- rtl818x_iowrite8(priv, &priv->map->MSR,
- RTL818X_MSR_INFRA);
- else
- rtl818x_iowrite8(priv, &priv->map->MSR,
- RTL818X_MSR_NO_LINK);
+ if (is_valid_ether_addr(info->bssid)) {
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ reg = RTL818X_MSR_ADHOC;
+ else
+ reg = RTL818X_MSR_INFRA;
+ } else
+ reg = RTL818X_MSR_NO_LINK;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
}
if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
--
1.7.1.1
^ permalink raw reply related
* Re: [stable] [PATCH 1/4 2.6.33.y] mac80211: explicitly disable/enable QoS
From: Greg KH @ 2010-07-29 21:48 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: linux-wireless, Ben Hutchings, stable
In-Reply-To: <20100728085007.349b2c22@dhcp-lab-109.englab.brq.redhat.com>
On Wed, Jul 28, 2010 at 08:50:07AM +0200, Stanislaw Gruszka wrote:
> On Tue, 27 Jul 2010 16:54:51 -0700
> Greg KH <greg@kroah.com> wrote:
>
> > On Wed, Jul 28, 2010 at 12:15:25AM +0100, Ben Hutchings wrote:
> > > On Tue, 2010-07-27 at 15:40 -0700, Greg KH wrote:
> > > > On Mon, Jun 07, 2010 at 12:00:24PM +0200, Stanislaw Gruszka wrote:
> > > > > commit e1b3ec1a2a336c328c336cfa5485a5f0484cc90d upstream.
> > > > >
> > > > > Add interface to disable/enable QoS (aka WMM or WME). Currently drivers
> > > > > enable it explicitly when ->conf_tx method is called, and newer disable.
> > > > > Disabling is needed for some APs, which do not support QoS, such
> > > > > we should send QoS frames to them.
> > > >
> > > > Why is this a patch for a -stable tree? It looks like it adds a new api
> > > > for a new feature, right?
> > > [...]
> > >
> > > It extends the interface between the 802.11 stack and drivers so that
> > > drivers can avoid sending QoS frames to APs that don't support them.
> > > There is no new interface to userland. My understanding is that iwlwifi
> > > becomes unable to communicate with non-QoS-capable APs after having once
> > > associated with a QoS-capable AP, without this and the following change
> > > in iwlwifi itself.
> >
> > Is this really true? And is it a bug that people are hitting?
>
> Yes, without that patch iwlwifi devices are not able to connect with some
> old APs. I had only two Fedora bug reports about that, so do not think
> this is something critical. Fill free to drop that patch (together with
> "iwlwifi: manage QoS by mac stack" which is part of the fix and do not have
> sense alone), or apply only to 2.6.34.
Ok, I'm going to drop both of these.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v2 2/2] rtl8180: use NAPI for bottom-half processing
From: John W. Linville @ 2010-07-29 21:14 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg, John W. Linville
In-Reply-To: <1280435978.3823.20.camel@jlt3.sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
v2 -> hide napi_struct as suggested by johill
drivers/net/wireless/rtl818x/rtl8180_dev.c | 128 +++++++++++++++-------------
1 files changed, 69 insertions(+), 59 deletions(-)
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 1d81785..c879660 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -99,19 +99,66 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
}
}
-static void rtl8180_handle_rx(struct ieee80211_hw *dev)
+static void rtl8180_handle_tx(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
- unsigned int count = 32;
+ struct rtl8180_tx_ring *ring;
+ int prio;
+
+ spin_lock(&priv->lock);
+
+ for (prio = 3; prio >= 0; prio--) {
+ ring = &priv->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ u32 flags = le32_to_cpu(entry->flags);
+
+ if (flags & RTL818X_TX_DESC_FLAG_OWN)
+ break;
+
+ ring->idx = (ring->idx + 1) % ring->entries;
+ skb = __skb_dequeue(&ring->queue);
+ pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
+ skb->len, PCI_DMA_TODEVICE);
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (flags & RTL818X_TX_DESC_FLAG_TX_OK))
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
+ info->status.rates[0].count = (flags & 0xFF) + 1;
+ info->status.rates[1].idx = -1;
+
+ ieee80211_tx_status(dev, skb);
+ if (ring->entries - skb_queue_len(&ring->queue) == 2)
+ ieee80211_wake_queue(dev, prio);
+ }
+ }
+
+ spin_unlock(&priv->lock);
+}
+
+static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ unsigned int count = 0;
u8 signal, agc, sq;
- while (count--) {
+ /* handle pending Tx queue cleanup */
+ rtl8180_handle_tx(dev);
+
+ while (count++ < budget) {
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
u32 flags = le32_to_cpu(entry->flags);
if (flags & RTL818X_RX_DESC_FLAG_OWN)
- return;
+ break;
if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
RTL818X_RX_DESC_FLAG_FOF |
@@ -151,7 +198,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
- ieee80211_rx_irqsafe(dev, skb);
+ ieee80211_rx(dev, skb);
skb = new_skb;
priv->rx_buf[priv->rx_idx] = skb;
@@ -168,41 +215,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
priv->rx_idx = (priv->rx_idx + 1) % 32;
}
-}
-
-static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
-{
- struct rtl8180_priv *priv = dev->priv;
- struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
-
- while (skb_queue_len(&ring->queue)) {
- struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
- u32 flags = le32_to_cpu(entry->flags);
-
- if (flags & RTL818X_TX_DESC_FLAG_OWN)
- return;
-
- ring->idx = (ring->idx + 1) % ring->entries;
- skb = __skb_dequeue(&ring->queue);
- pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
- skb->len, PCI_DMA_TODEVICE);
-
- info = IEEE80211_SKB_CB(skb);
- ieee80211_tx_info_clear_status(info);
-
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (flags & RTL818X_TX_DESC_FLAG_TX_OK))
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.rates[0].count = (flags & 0xFF) + 1;
- info->status.rates[1].idx = -1;
+ if (count < budget) {
+ /* disable polling */
+ ieee80211_napi_complete(dev);
- ieee80211_tx_status_irqsafe(dev, skb);
- if (ring->entries - skb_queue_len(&ring->queue) == 2)
- ieee80211_wake_queue(dev, prio);
+ /* enable interrupts */
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
}
+
+ return count;
}
static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
@@ -211,31 +233,17 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
struct rtl8180_priv *priv = dev->priv;
u16 reg;
- spin_lock(&priv->lock);
reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
- if (unlikely(reg == 0xFFFF)) {
- spin_unlock(&priv->lock);
+ if (unlikely(reg == 0xFFFF))
return IRQ_HANDLED;
- }
rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
- if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
- rtl8180_handle_tx(dev, 3);
-
- if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
- rtl8180_handle_tx(dev, 2);
-
- if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
- rtl8180_handle_tx(dev, 1);
-
- if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
- rtl8180_handle_tx(dev, 0);
-
- if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
- rtl8180_handle_rx(dev);
+ /* disable interrupts */
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
- spin_unlock(&priv->lock);
+ /* enable polling */
+ ieee80211_napi_schedule(dev);
return IRQ_HANDLED;
}
@@ -247,7 +255,6 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_tx_ring *ring;
struct rtl8180_tx_desc *entry;
- unsigned long flags;
unsigned int idx, prio;
dma_addr_t mapping;
u32 tx_flags;
@@ -294,7 +301,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
plcp_len |= 1 << 15;
}
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
@@ -318,7 +325,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
if (ring->entries - skb_queue_len(&ring->queue) < 2)
ieee80211_stop_queue(dev, prio);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
@@ -859,6 +866,7 @@ static const struct ieee80211_ops rtl8180_ops = {
.prepare_multicast = rtl8180_prepare_multicast,
.configure_filter = rtl8180_configure_filter,
.get_tsf = rtl8180_get_tsf,
+ .napi_poll = rtl8180_poll,
};
static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -990,6 +998,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
dev->queues = 1;
dev->max_signal = 65;
+ dev->napi_weight = 64;
+
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
reg &= RTL818X_TX_CONF_HWVER_MASK;
switch (reg) {
--
1.7.1.1
^ permalink raw reply related
* [PATCH v2 1/2] mac80211: support use of NAPI for bottom-half processing
From: John W. Linville @ 2010-07-29 21:14 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg, John W. Linville
In-Reply-To: <1280435978.3823.20.camel@jlt3.sipsolutions.net>
This patch implement basic infrastructure to support use of NAPI by
mac80211-based hardware drivers.
Because mac80211 devices can support multiple netdevs, a dummy netdev
is used for interfacing with the NAPI code in the core of the network
stack. That structure is hidden from the hardware drivers, but the
actual napi_struct is exposed in the ieee80211_hw structure so that the
poll routines in drivers can retrieve that structure. Hardware drivers
can also specify their own weight value for NAPI polling.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
v2 -> hide napi_struct as suggested by johill
include/net/mac80211.h | 24 ++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 5 +++++
net/mac80211/iface.c | 4 ++++
net/mac80211/main.c | 30 ++++++++++++++++++++++++++++++
4 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f85fc8a..64171c1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1102,6 +1102,10 @@ enum ieee80211_hw_flags {
*
* @max_rates: maximum number of alternate rate retry stages
* @max_rate_tries: maximum number of tries for each stage
+ *
+ * @napi_weight: weight used for NAPI polling. You must specify an
+ * appropriate value here if a napi_poll operation is provided
+ * by your driver.
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -1113,6 +1117,7 @@ struct ieee80211_hw {
int channel_change_time;
int vif_data_size;
int sta_data_size;
+ int napi_weight;
u16 queues;
u16 max_listen_interval;
s8 max_signal;
@@ -1687,6 +1692,8 @@ enum ieee80211_ampdu_mlme_action {
* switch operation for CSAs received from the AP may implement this
* callback. They must then call ieee80211_chswitch_done() to indicate
* completion of the channel switch.
+ *
+ * @napi_poll: Poll Rx queue for incoming data frames.
*/
struct ieee80211_ops {
int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1752,6 +1759,7 @@ struct ieee80211_ops {
void (*flush)(struct ieee80211_hw *hw, bool drop);
void (*channel_switch)(struct ieee80211_hw *hw,
struct ieee80211_channel_switch *ch_switch);
+ int (*napi_poll)(struct ieee80211_hw *hw, int budget);
};
/**
@@ -1897,6 +1905,22 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
*/
void ieee80211_restart_hw(struct ieee80211_hw *hw);
+/** ieee80211_napi_schedule - schedule NAPI poll
+ *
+ * Use this function to schedule NAPI polling on a device.
+ *
+ * @hw: the hardware to start polling
+ */
+void ieee80211_napi_schedule(struct ieee80211_hw *hw);
+
+/** ieee80211_napi_complete - complete NAPI polling
+ *
+ * Use this function to finish NAPI polling on a device.
+ *
+ * @hw: the hardware to stop polling
+ */
+void ieee80211_napi_complete(struct ieee80211_hw *hw);
+
/**
* ieee80211_rx - receive frame
*
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 65e0ed6..79d5645 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -870,6 +870,11 @@ struct ieee80211_local {
struct dentry *keys;
} debugfs;
#endif
+
+ /* dummy netdev for use w/ NAPI */
+ struct net_device napi_dev;
+
+ struct napi_struct napi;
};
static inline struct ieee80211_sub_if_data *
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ebbe264..c1008a9 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -187,6 +187,8 @@ static int ieee80211_open(struct net_device *dev)
res = drv_start(local);
if (res)
goto err_del_bss;
+ if (local->ops->napi_poll)
+ napi_enable(&local->napi);
/* we're brought up, everything changes */
hw_reconf_flags = ~0;
ieee80211_led_radio(local, true);
@@ -519,6 +521,8 @@ static int ieee80211_stop(struct net_device *dev)
ieee80211_recalc_ps(local, -1);
if (local->open_count == 0) {
+ if (local->ops->napi_poll)
+ napi_disable(&local->napi);
ieee80211_clear_tx_pending(local);
ieee80211_stop_device(local);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 7cc4f91..98bb5c0 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -390,6 +390,30 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
}
#endif
+static int ieee80211_napi_poll(struct napi_struct *napi, int budget)
+{
+ struct ieee80211_local *local =
+ container_of(napi, struct ieee80211_local, napi);
+
+ return local->ops->napi_poll(&local->hw, budget);
+}
+
+void ieee80211_napi_schedule(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ napi_schedule(&local->napi);
+}
+EXPORT_SYMBOL(ieee80211_napi_schedule);
+
+void ieee80211_napi_complete(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ napi_complete(&local->napi);
+}
+EXPORT_SYMBOL(ieee80211_napi_complete);
+
struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
const struct ieee80211_ops *ops)
{
@@ -494,6 +518,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
skb_queue_head_init(&local->skb_queue);
skb_queue_head_init(&local->skb_queue_unreliable);
+ /* init dummy netdev for use w/ NAPI */
+ init_dummy_netdev(&local->napi_dev);
+
return local_to_hw(local);
}
EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -683,6 +710,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto fail_ifa;
#endif
+ netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll,
+ local->hw.napi_weight);
+
return 0;
fail_ifa:
--
1.7.1.1
^ permalink raw reply related
* Re: [ath9k-devel] [PATCH 4/5] mac80211: add WoW support
From: Luis R. Rodriguez @ 2010-07-29 20:56 UTC (permalink / raw)
To: Luis Rodriguez
Cc: Simsek, Burak, David Quan, Amod Bodas, Stephen Chen,
Christian Lamparter, linux-wireless
In-Reply-To: <20100729153117.GB4925@tux>
On Thu, Jul 29, 2010 at 08:31:17AM -0700, Luis Rodriguez wrote:
> On Thu, Jul 29, 2010 at 06:31:02AM -0700, Simsek, Burak wrote:
> > Hi Luis,
> >
> > we tried your patches on the old version as described in your patch file.
> >
> > As you wrote the first issue was about the getting the right hardware. We
> > first wanted to use RS71-USB from ubiquity and it has AR9280. However, we
> > then realized that the implementation was for pci. We had assumed that RS71
> > would use ath9k but it used AR9170 driver. First question: do you think that
> > we can do similar patch for usb without much effort?
>
> Well, ar9170 uses Atheros radios but uses an old Zydas MAC so the programming
> would be different and I am not sure if ar9170 ever supported WoW. Stephen
> and Christian would know best at this point, whom I have CC'd.
I checked and ar9170 does not support WoW in hardware but since the firmware is
open (GPLv2) a WoW solution might be possible through software. You'd just have
to implement it. May want to look at carl9170.
Luis
^ permalink raw reply
* Re: [PATCH 2.6.34] rtl8187: ad-hoc mode support
From: Hin-Tak Leung @ 2010-07-29 20:52 UTC (permalink / raw)
To: Larry Finger
Cc: John W. Linville, Kirill Zut, linux-wireless,
Herton Ronaldo Krzesinski
In-Reply-To: <4C51D096.7090607@lwfinger.net>
Larry Finger wrote:
> On 07/29/2010 01:04 PM, John W. Linville wrote:
>> Don't you need something to make it beacon?
>
> Indeed he does. This code allows the user to set ad-hoc mode, but I could not
> establish a connection. The setup that I used worked for a b43 - b43 link, but
> failed if either end used rtl8187. NACK.
I supposed I need to withdrawn my "Ached-by:" - I was using it in the minimal
sense of "I have seen the patch and aware of its existence".
Is the beacon code driver-specific, or is it back to my older question, some
part of mac80211 need to have some generic support for it? or both? My
impression is that master mode for mac80211-based drivers - if it is ever going
to happen - requires some substantial changes to both mac80211 and hostapd and
is not happening any time soon.
OTOH, I have the impression that the windows driver claims to support Ad-Hoc
mode but I could be wrong - it has been a long time since I looked at the
options and choices under windows.
Hin-Tak
^ permalink raw reply
* Re: [PATCH 1/2] mac80211: support use of NAPI for bottom-half processing
From: Johannes Berg @ 2010-07-29 20:42 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280435978.3823.20.camel@jlt3.sipsolutions.net>
On Thu, 2010-07-29 at 22:39 +0200, Johannes Berg wrote:
> > + int (*napi_poll)(struct napi_struct *napi, int budget);
>
> I'd prefer passing the hw here and having mac80211 wrap it in a simple
> function that does the container_of magic? Anything preventing that?
> Then the napi struct can be hidden from drivers.
Ok actually that requires wrapping napi_complete() too, that doesn't
seem worth it. Can you wrap the container_of() in an inline though and
maybe do "struct napi_struct _napi;" and document it shouldn't really be
touched or something?
johannes
^ permalink raw reply
* Re: [PATCH 1/2] mac80211: support use of NAPI for bottom-half processing
From: Johannes Berg @ 2010-07-29 20:39 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1280434454-3597-1-git-send-email-linville@tuxdriver.com>
On Thu, 2010-07-29 at 16:14 -0400, John W. Linville wrote:
> + struct napi_struct napi;
> + int napi_weight;
Why is the napi struct visible to drivers? Ok .. I see later.
> @@ -1679,6 +1684,8 @@ enum ieee80211_ampdu_mlme_action {
> * switch operation for CSAs received from the AP may implement this
> * callback. They must then call ieee80211_chswitch_done() to indicate
> * completion of the channel switch.
> + *
> + * @napi_poll: Poll Rx queue for incoming data frames.
should this document that napi_weight must be set?
> + int (*napi_poll)(struct napi_struct *napi, int budget);
I'd prefer passing the hw here and having mac80211 wrap it in a simple
function that does the container_of magic? Anything preventing that?
Then the napi struct can be hidden from drivers.
johannes
^ permalink raw reply
* [PATCH 2/2] rtl8180: use NAPI for bottom-half processing
From: John W. Linville @ 2010-07-29 20:14 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
In-Reply-To: <1280434454-3597-1-git-send-email-linville@tuxdriver.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/rtl818x/rtl8180_dev.c | 130 +++++++++++++++-------------
1 files changed, 71 insertions(+), 59 deletions(-)
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index d8b186a..b89daec 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -99,19 +99,68 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
}
}
-static void rtl8180_handle_rx(struct ieee80211_hw *dev)
+static void rtl8180_handle_tx(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
- unsigned int count = 32;
+ struct rtl8180_tx_ring *ring;
+ int prio;
+
+ spin_lock(&priv->lock);
+
+ for (prio = 3; prio >= 0; prio--) {
+ ring = &priv->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ u32 flags = le32_to_cpu(entry->flags);
+
+ if (flags & RTL818X_TX_DESC_FLAG_OWN)
+ break;
+
+ ring->idx = (ring->idx + 1) % ring->entries;
+ skb = __skb_dequeue(&ring->queue);
+ pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
+ skb->len, PCI_DMA_TODEVICE);
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (flags & RTL818X_TX_DESC_FLAG_TX_OK))
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
+ info->status.rates[0].count = (flags & 0xFF) + 1;
+ info->status.rates[1].idx = -1;
+
+ ieee80211_tx_status(dev, skb);
+ if (ring->entries - skb_queue_len(&ring->queue) == 2)
+ ieee80211_wake_queue(dev, prio);
+ }
+ }
+
+ spin_unlock(&priv->lock);
+}
+
+static int rtl8180_poll(struct napi_struct *napi, int budget)
+{
+ struct ieee80211_hw *dev =
+ container_of(napi, struct ieee80211_hw, napi);
+ struct rtl8180_priv *priv = dev->priv;
+ unsigned int count = 0;
u8 signal, agc, sq;
- while (count--) {
+ /* handle pending Tx queue cleanup */
+ rtl8180_handle_tx(dev);
+
+ while (count++ < budget) {
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
u32 flags = le32_to_cpu(entry->flags);
if (flags & RTL818X_RX_DESC_FLAG_OWN)
- return;
+ break;
if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
RTL818X_RX_DESC_FLAG_FOF |
@@ -151,7 +200,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
- ieee80211_rx_irqsafe(dev, skb);
+ ieee80211_rx(dev, skb);
skb = new_skb;
priv->rx_buf[priv->rx_idx] = skb;
@@ -168,41 +217,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
priv->rx_idx = (priv->rx_idx + 1) % 32;
}
-}
-
-static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
-{
- struct rtl8180_priv *priv = dev->priv;
- struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
-
- while (skb_queue_len(&ring->queue)) {
- struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
- u32 flags = le32_to_cpu(entry->flags);
-
- if (flags & RTL818X_TX_DESC_FLAG_OWN)
- return;
-
- ring->idx = (ring->idx + 1) % ring->entries;
- skb = __skb_dequeue(&ring->queue);
- pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
- skb->len, PCI_DMA_TODEVICE);
-
- info = IEEE80211_SKB_CB(skb);
- ieee80211_tx_info_clear_status(info);
-
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (flags & RTL818X_TX_DESC_FLAG_TX_OK))
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.rates[0].count = (flags & 0xFF) + 1;
- info->status.rates[1].idx = -1;
+ if (count < budget) {
+ /* disable polling */
+ napi_complete(napi);
- ieee80211_tx_status_irqsafe(dev, skb);
- if (ring->entries - skb_queue_len(&ring->queue) == 2)
- ieee80211_wake_queue(dev, prio);
+ /* enable interrupts */
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
}
+
+ return count;
}
static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
@@ -211,31 +235,17 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
struct rtl8180_priv *priv = dev->priv;
u16 reg;
- spin_lock(&priv->lock);
reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
- if (unlikely(reg == 0xFFFF)) {
- spin_unlock(&priv->lock);
+ if (unlikely(reg == 0xFFFF))
return IRQ_HANDLED;
- }
rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
- if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
- rtl8180_handle_tx(dev, 3);
-
- if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
- rtl8180_handle_tx(dev, 2);
-
- if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
- rtl8180_handle_tx(dev, 1);
-
- if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
- rtl8180_handle_tx(dev, 0);
-
- if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
- rtl8180_handle_rx(dev);
+ /* disable interrupts */
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
- spin_unlock(&priv->lock);
+ /* enable polling */
+ napi_schedule(&dev->napi);
return IRQ_HANDLED;
}
@@ -247,7 +257,6 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_tx_ring *ring;
struct rtl8180_tx_desc *entry;
- unsigned long flags;
unsigned int idx, prio;
dma_addr_t mapping;
u32 tx_flags;
@@ -294,7 +303,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
plcp_len |= 1 << 15;
}
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
@@ -318,7 +327,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
if (ring->entries - skb_queue_len(&ring->queue) < 2)
ieee80211_stop_queue(dev, prio);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
@@ -861,6 +870,7 @@ static const struct ieee80211_ops rtl8180_ops = {
.prepare_multicast = rtl8180_prepare_multicast,
.configure_filter = rtl8180_configure_filter,
.get_tsf = rtl8180_get_tsf,
+ .napi_poll = rtl8180_poll,
};
static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -992,6 +1002,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
dev->queues = 1;
dev->max_signal = 65;
+ dev->napi_weight = 64;
+
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
reg &= RTL818X_TX_CONF_HWVER_MASK;
switch (reg) {
--
1.7.1.1
^ permalink raw reply related
* [PATCH 1/2] mac80211: support use of NAPI for bottom-half processing
From: John W. Linville @ 2010-07-29 20:14 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
This patch implement basic infrastructure to support use of NAPI by
mac80211-based hardware drivers.
Because mac80211 devices can support multiple netdevs, a dummy netdev
is used for interfacing with the NAPI code in the core of the network
stack. That structure is hidden from the hardware drivers, but the
actual napi_struct is exposed in the ieee80211_hw structure so that the
poll routines in drivers can retrieve that structure. Hardware drivers
can also specify their own weight value for NAPI polling.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
include/net/mac80211.h | 8 ++++++++
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/iface.c | 4 ++++
net/mac80211/main.c | 6 ++++++
4 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 20d372e..88223b4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1094,6 +1094,9 @@ enum ieee80211_hw_flags {
*
* @max_rates: maximum number of alternate rate retry stages
* @max_rate_tries: maximum number of tries for each stage
+ *
+ * @napi: NAPI control structure
+ * @napi_weight: weight used for NAPI polling
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -1105,6 +1108,8 @@ struct ieee80211_hw {
int channel_change_time;
int vif_data_size;
int sta_data_size;
+ struct napi_struct napi;
+ int napi_weight;
u16 queues;
u16 max_listen_interval;
s8 max_signal;
@@ -1679,6 +1684,8 @@ enum ieee80211_ampdu_mlme_action {
* switch operation for CSAs received from the AP may implement this
* callback. They must then call ieee80211_chswitch_done() to indicate
* completion of the channel switch.
+ *
+ * @napi_poll: Poll Rx queue for incoming data frames.
*/
struct ieee80211_ops {
int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1744,6 +1751,7 @@ struct ieee80211_ops {
void (*flush)(struct ieee80211_hw *hw, bool drop);
void (*channel_switch)(struct ieee80211_hw *hw,
struct ieee80211_channel_switch *ch_switch);
+ int (*napi_poll)(struct napi_struct *napi, int budget);
};
/**
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c6b5c2d..2c6ac97 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -869,6 +869,9 @@ struct ieee80211_local {
struct dentry *keys;
} debugfs;
#endif
+
+ /* dummy netdev for use w/ NAPI */
+ struct net_device napi_dev;
};
static inline struct ieee80211_sub_if_data *
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ebbe264..827f25d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -187,6 +187,8 @@ static int ieee80211_open(struct net_device *dev)
res = drv_start(local);
if (res)
goto err_del_bss;
+ if (local->ops->napi_poll)
+ napi_enable(&local->hw.napi);
/* we're brought up, everything changes */
hw_reconf_flags = ~0;
ieee80211_led_radio(local, true);
@@ -519,6 +521,8 @@ static int ieee80211_stop(struct net_device *dev)
ieee80211_recalc_ps(local, -1);
if (local->open_count == 0) {
+ if (local->ops->napi_poll)
+ napi_disable(&local->hw.napi);
ieee80211_clear_tx_pending(local);
ieee80211_stop_device(local);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0e95c75..79ca2ba 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -491,6 +491,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
skb_queue_head_init(&local->skb_queue);
skb_queue_head_init(&local->skb_queue_unreliable);
+ /* init dummy netdev for use w/ NAPI */
+ init_dummy_netdev(&local->napi_dev);
+
return local_to_hw(local);
}
EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -680,6 +683,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto fail_ifa;
#endif
+ netif_napi_add(&local->napi_dev, &local->hw.napi, local->ops->napi_poll,
+ local->hw.napi_weight);
+
return 0;
fail_ifa:
--
1.7.1.1
^ permalink raw reply related
* Re: [PATCH] rt2x00: update fw version info in wiphy struct
From: Ivo Van Doorn @ 2010-07-29 19:58 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Gertjan van Wingerde
In-Reply-To: <1280425899-20943-1-git-send-email-linville@tuxdriver.com>
On Thu, Jul 29, 2010 at 7:51 PM, John W. Linville
<linville@tuxdriver.com> wrote:
> This makes the information available through ethtool...
>
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
> ---
> drivers/net/wireless/rt2x00/rt2x00firmware.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
> index b818a43..f0e1eb7 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
> @@ -63,6 +63,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
>
> INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
> fw->data[fw->size - 4], fw->data[fw->size - 3]);
> + snprintf(rt2x00dev->hw->wiphy->fw_version,
> + sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d",
> + fw->data[fw->size - 4], fw->data[fw->size - 3]);
>
> retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
> switch (retval) {
> --
> 1.7.1.1
>
>
^ permalink raw reply
* pull request: wireless-next-2.6 2010-07-29
From: John W. Linville @ 2010-07-29 19:12 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
Dave,
Yet another slew of changes intended for 2.6.36...
For the first time, this pull request includes a batch of bluetooth
stuff by way of Marcel. Some upcoming developments are likely to
require more extensive integration between 802.11 and Bluetooth bits, so
Marcel's tree will be feeding wireless-next-2.6 for a while.
The rest is the usual stuff from the usual suspects -- mostly driver
updates with the usual strong showings from ath9k and iwlwifi, this time
joined by libertas in particular.
This is a "for-davem" branch, so hopefully there will be no pain for you
to pull this time. :-)
Please let me know if there are problems!
John
---
The following changes since commit 7f3e01fee41a322747db2d7574516d9fbd3785c0:
net: bnx2x_cmn.c needs net/ip6_checksum.h for csum_ipv6_magic (2010-07-28 22:20:34 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git for-davem
Amitkumar Karwar (1):
Bluetooth: Process interrupt in main thread of btmrvl driver as well
Christian Lamparter (1):
cfg80211: fix dev <-> wiphy typo
Cyril Lacoux (1):
Bluetooth: Added support for controller shipped with iMac i5
Dan Carpenter (6):
ath9k: snprintf() returns largish values
ath5k: snprintf() returns largish values
mac80211: freeing the wrong variable
wireless: remove unneeded variable from regulatory_hint_11d()
libertas: precedence bug
Bluetooth: Fix kfree() => kfree_skb() in hci_ath.c
Dan Williams (16):
libertas: clean up MONITOR_MODE command
libertas: clean up RSSI command
libertas: convert 11D_DOMAIN_INFO to a direct command
libertas: remove unused indirect TPC_CFG command leftovers
libertas: remove unused Automatic Frequency Control command
libertas: remove Beacon Control
libertas: convert LED_GPIO_CTRL to a direct command
libertas: convert register access to direct commands
libertas: convert Mesh Blinding Table access to a direct command
libertas: convert CMD_FWT_ACCESS to a direct command
libertas: remove unused indirect command response handler
libertas: convert PS_MODE to a direct command
libertas: convert DEEP_SLEEP timer to a direct command
libertas: kill unused lbs_prepare_and_send_command()
libertas: rename lbs_get_cmd_ctrl_node() to lbs_get_free_cmd_node()
libertas: remove unused cmd_pending waitq
Felix Fietkau (5):
ath9k: fix yet another buffer leak in the tx aggregation code
ath9k_hw: fix invalid extension channel noisefloor readings in HT20
ath9k_hw: fix a small typo in the noisefloor calibration debug code
ath9k_hw: simplify noisefloor calibration chainmask calculation
mac80211: inform drivers about the off-channel status on channel changes
Gustavo F. Padovan (44):
Bluetooth: Remove max_tx and tx_window module paramenters from L2CAP
Bluetooth: Remove L2CAP Extended Features from Kconfig
Bluetooth: Fix drop of packets with invalid req_seq/tx_seq
Bluetooth: Fix bug with ERTM vars increment
Bluetooth: Only check SAR bits if frame is an I-frame
Bluetooth: Fix bug in l2cap_ertm_send() behavior
Bluetooth: Proper shutdown ERTM when closing the channel
Bluetooth: Fix L2CAP control bit field corruption
Bluetooth: Stop ack_timer if ERTM enters in Local Busy or SREJ_SENT
Bluetooth: Update buffer_seq before retransmit frames
Bluetooth: Fix handle of received P-bit
Bluetooth: Check the tx_window size on setsockopt
Bluetooth: Check packet FCS earlier
Bluetooth: Fix missing retransmission action with RR(P=1)
Bluetooth: Fix ERTM error reporting to the userspace
Bluetooth: Add debug output to ERTM code
Bluetooth: Tweaks to l2cap_send_i_or_rr_or_rnr() flow
Bluetooth: Change the way we set ERTM mode as mandatory
Bluetooth: Disconnect the channel if we don't want the proposed mode
Bluetooth: Prefer Basic Mode on receipt of ConfigReq
Bluetooth: Actively send request for Basic Mode
Bluetooth: Refuse ConfigRsp with different mode
Bluetooth: Remove check for supported mode
Bluetooth: Disconnect early if mode is not supported
Bluetooth: Don't accept ConfigReq if we aren't in the BT_CONFIG state
Bluetooth: Remove the send_lock spinlock from ERTM
Bluetooth: Add backlog queue to ERTM code
Bluetooth: Improve ERTM local busy handling
Bluetooth: Send ConfigReq after send a ConnectionRsp
Bluetooth: Fix bug in kzalloc allocation size
Bluetooth: Keep code under column 80
Bluetooth: Add Copyright notice to L2CAP
Bluetooth: Update L2CAP version information
Bluetooth: Add Google's copyright to L2CAP
Bluetooth: Move bit-field variable in USB driver to data->flags
Bluetooth: Fix typo in hci_event.c
Bluetooth: Enable L2CAP Extended features by default
Bluetooth: Use __packed annotation
Bluetooth: Use __packed annotation for drivers
Bluetooth: Fix permission of hci_ath.c
Bluetooth: Test 'count' value before enter the loop
Bluetooth: Use hci_recv_stream_fragment() in UART driver
Bluetooth: Add __init and __exit marks to UART drivers
Bluetooth: Add __init and __exit marks to RFCOMM
Ivo van Doorn (1):
rt2x00: Fix regression for rt2500pci
Joe Perches (5):
Bluetooth: Remove unnecessary casts of private_data in drivers
include/net/cfg80211.h: Add wiphy_<level> printk equivalents
drivers/net/wireless: Use wiphy_<level>
drivers/net/wireless/at76c50x-usb.c: Neaten macros
wireless: Convert wiphy_debug macro to function
Johan Hedberg (4):
Bluetooth: Add blacklist support for incoming connections
Bluetooth: Add debugfs support for showing the blacklist
Bluetooth: Add missing HCIUARTGETDEVICE ioctl to compat_ioctl.c
Bluetooth: Add HCIUARTSETFLAGS and HCIUARTGETFLAGS ioctls
Johannes Berg (8):
iwlagn: fix firmware loading TLV error path
iwlwifi: make iwl_mac_beacon_update static
iwlwifi: reduce beacon fill conditions
iwlwifi: remove spurious semicolons
mac80211: remove bogus rcu_read_lock()
cfg80211: fix IBSS default management key
mac80211: fix sta assignment
mac80211: allow drivers to request DTIM period
John W. Linville (24):
iwlagn: use __packed on new structure definitions
wl1251: fix sparse-generated warnings
rtl8180: improve signal reporting for actual rtl8180 hardware
rtl8180: silence "dubious: x | !y" sparse warning
MAINTAINERS: mark prism54 obsolete
MAINTAINERS: orphan the raylink wireless driver
MAINTAINERS: orphan the zd1201 wireless driver
MAINTAINERS: remove entry for wavelan
iwlwifi: assume vif is NULL for internal scans and non-NULL otherwise
minstrel_ht: remove unnecessary NULL check in minstrel_ht_update_caps
minstrel: don't complain about feedback for unrequested rates
lib80211: remove unused host_build_iv option
Merge branch 'master' of git://git.kernel.org/.../holtmann/bluetooth-next-2.6
p54: Added get_survey callback in order to get channel noise
Merge branch 'master' of git://git.kernel.org/.../holtmann/bluetooth-next-2.6
ath9k: enable serialize_regmode for non-PCIE AR9160
mwl8k: add get_survey callback in order to get channel noise
ar9170: add get_survey callback in order to get channel noise
wl1251: add get_survey callback in order to get channel noise
libertas_tf: add get_survey callback in order to get channel noise
wl1271: add get_survey callback in order to get channel noise
wl1251: update hw/fw version info in wiphy struct
wl1271: update hw/fw version info in wiphy struct
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6 into for-davem
Jouni Malinen (1):
mac80211: Fix key freeing to handle unlinked keys
João Paulo Rechi Vita (8):
Bluetooth: Fix SREJ_QUEUE corruption in L2CAP
Bluetooth: Fix l2cap_sock_connect error return.
Bluetooth: Make l2cap_streaming_send() void.
Bluetooth: Fix error return value on sendmsg.
Bluetooth: Fix error return value on sendmsg.
Bluetooth: Fix error return for l2cap_connect_rsp().
Bluetooth: Fix error value for wrong FCS.
Bluetooth: Fix error return on L2CAP-HCI interface.
Julia Lawall (3):
Bluetooth: Use kmemdup for drivers
Bluetooth: Use kzalloc for drivers
drivers/net/wireless/wl12xx: Use kmemdup
Justin P. Mattock (1):
Bluetooth: Fix warning: variable 'tty' set but not used
Kulikov Vasiliy (1):
Bluetooth: Silence warning in btmrvl SDIO driver
Lennert Buytenhek (1):
mwl8k: change maintenance status
Luis R. Rodriguez (2):
ath9k: remove the two wiphys scanning at the same time message
Revert "mac80211: fix sw scan bracketing"
Marcel Holtmann (1):
Bluetooth: Defer SCO setup if mode change is pending
Nathan Holstein (1):
Bluetooth: Fix bug with ERTM minimum packet length
Ron Shaffer (2):
Bluetooth: Remove extraneous white space
Bluetooth: Reassigned copyright to Code Aurora Forum
Senthil Balasubramanian (4):
ath9k: Introduce bit masks for valid and valid_single_stream.
ath9k: Add three stream rate control support for AR938X.
ath9k: Fix incorrect user ratekbs of MCS15 ShortGI
ath9k: remove unused base_index from rate table.
Stanislaw Gruszka (4):
rt2500usb: write keys to proper registers
rt2500usb: truly disable encryption when initialize
rt2500usb: disallow to set WEP key with non zero index
iwlwifi: fix scan abort
Sujith (1):
mac80211: Don't set per-BSS QoS for monitor interfaces
Suraj Sumangala (5):
Bluetooth: Add one more buffer for HCI stream reassembly
Bluetooth: Implement hci_reassembly helper to reassemble RX packets
Bluetooth: Modified hci_recv_fragment() to use hci_reassembly helper
Bluetooth: Implemented HCI frame reassembly for RX from stream
Bluetooth: Support for Atheros AR300x serial chip
Vasanthakumar Thiagarajan (1):
ath9k: Fix inconsistency between txq->stopped and the actual queue state
Wey-Yi Guy (6):
iwlagn: add statistic notification structure for WiFi/BT devices
iwlagn: add .cfg flag to idenfity the need for bt statistics
iwlagn: Add support for bluetooth statistics notification
iwlagn: add bluetooth stats to debugfs
iwlwifi: add TLV to specify the size of phy calibration table
iwlwifi: read multiple MAC addresses
Yuri Ershov (3):
mac80211: Put some code under MESH macro
nl80211: Fix memory leaks
cfg80211: Update of regulatory request initiator handling
MAINTAINERS | 20 +-
drivers/bluetooth/Kconfig | 12 +
drivers/bluetooth/Makefile | 1 +
drivers/bluetooth/bcm203x.c | 3 +-
drivers/bluetooth/bpa10x.c | 2 +-
drivers/bluetooth/btmrvl_debugfs.c | 2 +-
drivers/bluetooth/btmrvl_drv.h | 5 +-
drivers/bluetooth/btmrvl_main.c | 5 +-
drivers/bluetooth/btmrvl_sdio.c | 111 ++--
drivers/bluetooth/btusb.c | 13 +-
drivers/bluetooth/dtl1_cs.c | 2 +-
drivers/bluetooth/hci_ath.c | 235 ++++++++
drivers/bluetooth/hci_bcsp.c | 4 +-
drivers/bluetooth/hci_h4.c | 107 +----
drivers/bluetooth/hci_ldisc.c | 20 +-
drivers/bluetooth/hci_ll.c | 6 +-
drivers/bluetooth/hci_uart.h | 15 +-
drivers/net/wireless/adm8211.c | 53 +-
drivers/net/wireless/at76c50x-usb.c | 168 +++---
drivers/net/wireless/ath/ar9170/cmd.c | 7 +-
drivers/net/wireless/ath/ar9170/led.c | 4 +-
drivers/net/wireless/ath/ar9170/main.c | 191 ++++---
drivers/net/wireless/ath/ar9170/phy.c | 8 +-
drivers/net/wireless/ath/ath5k/debug.c | 18 +
drivers/net/wireless/ath/ath9k/ahb.c | 7 +-
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 3 +
drivers/net/wireless/ath/ath9k/ar9002_phy.c | 6 +-
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 3 +
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +-
drivers/net/wireless/ath/ath9k/calib.c | 21 +-
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 9 +
drivers/net/wireless/ath/ath9k/hw.c | 3 +-
drivers/net/wireless/ath/ath9k/main.c | 13 +-
drivers/net/wireless/ath/ath9k/pci.c | 7 +-
drivers/net/wireless/ath/ath9k/rc.c | 601 ++++++++++++--------
drivers/net/wireless/ath/ath9k/rc.h | 89 +++-
drivers/net/wireless/ath/ath9k/virtual.c | 6 +-
drivers/net/wireless/ath/ath9k/xmit.c | 20 +-
drivers/net/wireless/ipw2x00/libipw.h | 1 -
drivers/net/wireless/ipw2x00/libipw_tx.c | 16 +-
drivers/net/wireless/ipw2x00/libipw_wx.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-1000.c | 1 +
drivers/net/wireless/iwlwifi/iwl-4965.c | 5 +-
drivers/net/wireless/iwlwifi/iwl-5000.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 7 +
drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 64 ++-
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 225 ++++++--
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h | 7 +
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 7 +-
drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 167 ++++--
drivers/net/wireless/iwlwifi/iwl-agn.c | 141 +++--
drivers/net/wireless/iwlwifi/iwl-calib.h | 6 +-
drivers/net/wireless/iwlwifi/iwl-commands.h | 55 ++-
drivers/net/wireless/iwlwifi/iwl-core.c | 65 +--
drivers/net/wireless/iwlwifi/iwl-core.h | 4 +-
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 13 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 16 +
drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 +
drivers/net/wireless/iwlwifi/iwl-scan.c | 18 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 22 +-
drivers/net/wireless/libertas/cfg.c | 197 +------
drivers/net/wireless/libertas/cfg.h | 6 -
drivers/net/wireless/libertas/cmd.c | 718 ++++++++++--------------
drivers/net/wireless/libertas/cmd.h | 25 +-
drivers/net/wireless/libertas/cmdresp.c | 179 +------
drivers/net/wireless/libertas/debugfs.c | 67 +--
drivers/net/wireless/libertas/decl.h | 5 -
drivers/net/wireless/libertas/defs.h | 18 -
drivers/net/wireless/libertas/dev.h | 6 -
drivers/net/wireless/libertas/host.h | 142 ++---
drivers/net/wireless/libertas/if_usb.c | 4 +-
drivers/net/wireless/libertas/main.c | 35 +-
drivers/net/wireless/libertas/mesh.c | 216 ++++++--
drivers/net/wireless/libertas/mesh.h | 14 +-
drivers/net/wireless/libertas/tx.c | 2 +-
drivers/net/wireless/libertas_tf/libertas_tf.h | 3 +
drivers/net/wireless/libertas_tf/main.c | 18 +
drivers/net/wireless/mac80211_hwsim.c | 99 ++--
drivers/net/wireless/mwl8k.c | 154 +++---
drivers/net/wireless/orinoco/cfg.c | 5 +-
drivers/net/wireless/p54/eeprom.c | 76 ++--
drivers/net/wireless/p54/fwio.c | 53 +-
drivers/net/wireless/p54/led.c | 8 +-
drivers/net/wireless/p54/main.c | 17 +
drivers/net/wireless/p54/p54pci.c | 3 +-
drivers/net/wireless/p54/txrx.c | 36 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 11 +-
drivers/net/wireless/rt2x00/rt2x00mac.c | 19 +-
drivers/net/wireless/rtl818x/rtl8180_dev.c | 35 +-
drivers/net/wireless/rtl818x/rtl8180_grf5101.c | 12 +-
drivers/net/wireless/rtl818x/rtl8180_max2820.c | 19 +-
drivers/net/wireless/rtl818x/rtl8180_rtl8225.c | 5 +-
drivers/net/wireless/rtl818x/rtl8180_sa2400.c | 28 +-
drivers/net/wireless/rtl818x/rtl8187_dev.c | 11 +-
drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | 8 +-
drivers/net/wireless/rtl818x/rtl818x.h | 1 +
drivers/net/wireless/wl12xx/wl1251.h | 3 +
drivers/net/wireless/wl12xx/wl1251_boot.c | 8 +-
drivers/net/wireless/wl12xx/wl1251_cmd.h | 12 +-
drivers/net/wireless/wl12xx/wl1251_main.c | 22 +
drivers/net/wireless/wl12xx/wl1251_rx.c | 6 +
drivers/net/wireless/wl12xx/wl1251_tx.c | 10 +-
drivers/net/wireless/wl12xx/wl1251_tx.h | 8 +-
drivers/net/wireless/wl12xx/wl1271.h | 3 +
drivers/net/wireless/wl12xx/wl1271_main.c | 32 +-
drivers/net/wireless/wl12xx/wl1271_rx.c | 7 +
fs/compat_ioctl.c | 9 +-
include/net/bluetooth/bluetooth.h | 3 +-
include/net/bluetooth/hci.h | 187 ++++---
include/net/bluetooth/hci_core.h | 30 +-
include/net/bluetooth/l2cap.h | 34 +-
include/net/bluetooth/rfcomm.h | 14 +-
include/net/cfg80211.h | 65 +++-
include/net/lib80211.h | 3 -
include/net/mac80211.h | 12 +-
net/bluetooth/Kconfig | 13 -
net/bluetooth/hci_conn.c | 34 +-
net/bluetooth/hci_core.c | 204 +++++--
net/bluetooth/hci_event.c | 39 +-
net/bluetooth/hci_sock.c | 90 +++
net/bluetooth/hci_sysfs.c | 38 ++
net/bluetooth/l2cap.c | 669 ++++++++++++++---------
net/bluetooth/rfcomm/sock.c | 2 +-
net/bluetooth/rfcomm/tty.c | 4 +-
net/mac80211/cfg.c | 13 +-
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/key.c | 13 +-
net/mac80211/key.h | 3 +-
net/mac80211/main.c | 3 +
net/mac80211/mlme.c | 32 +-
net/mac80211/rc80211_minstrel.c | 1 -
net/mac80211/rc80211_minstrel_ht.c | 4 +-
net/mac80211/scan.c | 8 +-
net/mac80211/sta_info.c | 2 +-
net/mac80211/tx.c | 19 +-
net/mac80211/util.c | 8 +-
net/mac80211/work.c | 43 ++
net/wireless/core.c | 49 ++
net/wireless/ibss.c | 4 +-
net/wireless/lib80211_crypt_ccmp.c | 1 -
net/wireless/lib80211_crypt_tkip.c | 1 -
net/wireless/lib80211_crypt_wep.c | 1 -
net/wireless/nl80211.c | 2 +
net/wireless/reg.c | 8 +-
145 files changed, 3858 insertions(+), 2826 deletions(-)
create mode 100644 drivers/bluetooth/hci_ath.c
Omnibus patch is available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2010-07-29.patch.bz2
--
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
* Compat-wireless release for 2010-07-29 is baked
From: Compat-wireless cronjob account @ 2010-07-29 19:04 UTC (permalink / raw)
To: linux-wireless
>From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
54ebee1..6194650 history -> origin/history
+ 1068a69...144d058 master -> origin/master (forced update)
* [new tag] next-20100729 -> next-20100729
compat-wireless code metrics
494000 - Total upstream lines of code being pulled
1447 - backport code changes
1211 - backport code additions
236 - backport code deletions
5764 - backport from compat module
7211 - total backport code
1.4597 - % of code consists of backport work
1218 - Crap changes not yet posted
1179 - Crap additions not yet posted
39 - Crap deletions not yet posted
0.2466 - % of crap code
Base tree: linux-next.git
Base tree version: next-20100729
compat-wireless release: compat-wireless-2010-07-13-4-g04898a5
^ permalink raw reply
* Re: [PATCH 2.6.34] rtl8187: ad-hoc mode support
From: Larry Finger @ 2010-07-29 19:03 UTC (permalink / raw)
To: John W. Linville
Cc: Kirill Zut, linux-wireless, Hin-Tak Leung,
Herton Ronaldo Krzesinski
In-Reply-To: <20100729180426.GC2424@tuxdriver.com>
On 07/29/2010 01:04 PM, John W. Linville wrote:
> Don't you need something to make it beacon?
Indeed he does. This code allows the user to set ad-hoc mode, but I could not
establish a connection. The setup that I used worked for a b43 - b43 link, but
failed if either end used rtl8187. NACK.
Larry
^ 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