* Re: A file to print the release of loaded compat-wireless stuff
From: Luis R. Rodriguez @ 2010-05-04 21:51 UTC (permalink / raw)
To: Pavel Roskin; +Cc: linux-wireless
In-Reply-To: <1273007509.12618.1.camel@mj>
On Tue, May 4, 2010 at 2:11 PM, Pavel Roskin <proski@gnu.org> wrote:
> On Tue, 2010-05-04 at 13:44 -0700, Luis R. Rodriguez wrote:
>> It seems there is a reasonable need to find out what version of
>> compat-wireless you have running. This will be a dated thing when
>> based on linux-next but more importantly it will contain the 2.6.3x.y
>> release the release was based on for the stable releases. Any ideas of
>> what filesystem API to use for this, I was thinking maybe a simple
>> sysfs entry for the compat module. Thoughts, preferences?
>
> We could use a read-only parameter of the compat module. Then the
> version would be in /sys/module/compat/parameters/version
>
> Module parameters are visible in sysfs even if the code is compiled into
> the kernel.
Neat trick thanks for the tip, will give that a shot.
Luis
^ permalink raw reply
* orinoco_usb: support wpa
From: David Kilroy @ 2010-05-04 21:54 UTC (permalink / raw)
To: linux-wireless; +Cc: orinoco-devel, linville, David Kilroy
The following patches enable WPA for the orinoco_usb cards. The first
patch contains all the code required to use WPA. The second patch
neatens things up but doesn't work so well, since it relies on having
spare tailroom in the SKB to store the MIC.
In order to use WPA with these cards, the following is required:
* Agere firmware 9.42 or better (as with other orinoco cards)
* compatible bridge firmware
The bridge firmware currently extracted by the orinoco-fwutils scripts
is not compatible with WPA. Instead you'll need to find the v7.82
Agere driver containing the WPA-enabled USB driver (containing the
appropriate bridge firmware and Agere fw 9.42). I'm not sure if there
is still a reliable source on the net. Further details about
extracting the firmware below.
John: 1st patch should be OK for w-t if there are no objections. I'm
expecting to redo or drop the second, depending on feedback.
Regards,
Dave.
The bridge firmware is in WLAGS51.SYS. The firmware will be 6976 bytes
long, starting with the bytes 0x02 0x10 at an offset around 0x028480.
I used the following command to extract it (you may need to modify
this if you get something different from what I have):
dd if=WLAGS51.SYS of=orinoco_ezusb_fw skip=10312 count=436 bs=16
---
David Kilroy (2):
orinoco: refactor xmit path
orinoco: use SKB tail for MIC
drivers/net/wireless/orinoco/main.c | 175 ++++++++++++++++------------
drivers/net/wireless/orinoco/orinoco.h | 5 +
drivers/net/wireless/orinoco/orinoco_usb.c | 77 +++++--------
3 files changed, 135 insertions(+), 122 deletions(-)
^ permalink raw reply
* [PATCH] orinoco: refactor xmit path
From: David Kilroy @ 2010-05-04 21:54 UTC (permalink / raw)
To: linux-wireless; +Cc: orinoco-devel, linville, David Kilroy
In-Reply-To: <1273010082-15871-1-git-send-email-kilroyd@googlemail.com>
... so orinoco_usb can share some common functionality.
Handle 802.2 encapsulation and MIC calculation in that function.
The 802.3 header is prepended to the SKB. The calculated MIC is written
to a specified buffer. Also modify the transmit control word that will
be passed onto the hardware to specify whether the MIC is present, and
the key used.
Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
drivers/net/wireless/orinoco/main.c | 169 +++++++++++++++++----------
drivers/net/wireless/orinoco/orinoco.h | 6 +
drivers/net/wireless/orinoco/orinoco_usb.c | 91 +++++++--------
3 files changed, 155 insertions(+), 111 deletions(-)
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 1d60c7e..3b9a5fb 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -340,18 +340,109 @@ EXPORT_SYMBOL(orinoco_change_mtu);
/* Tx path */
/********************************************************************/
+/* Add encapsulation and MIC to the existing SKB.
+ * The main xmit routine will then send the whole lot to the card.
+ * Need 8 bytes headroom
+ * Need 8 bytes tailroom
+ *
+ * With encapsulated ethernet II frame
+ * --------
+ * 803.3 header (14 bytes)
+ * dst[6]
+ * -------- src[6]
+ * 803.3 header (14 bytes) len[2]
+ * dst[6] 803.2 header (8 bytes)
+ * src[6] encaps[6]
+ * len[2] <- leave alone -> len[2]
+ * -------- -------- <-- 0
+ * Payload Payload
+ * ... ...
+ *
+ * -------- --------
+ * MIC (8 bytes)
+ * --------
+ *
+ * returns 0 on success, -ENOMEM on error.
+ */
+int orinoco_process_xmit_skb(struct sk_buff *skb,
+ struct net_device *dev,
+ struct orinoco_private *priv,
+ int *tx_control,
+ u8 *mic_buf)
+{
+ struct orinoco_tkip_key *key;
+ struct ethhdr *eh;
+ int do_mic;
+
+ key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
+
+ do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
+ (key != NULL));
+
+ if (do_mic)
+ *tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
+ HERMES_TXCTRL_MIC;
+
+ eh = (struct ethhdr *)skb->data;
+
+ /* Encapsulate Ethernet-II frames */
+ if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
+ struct header_struct {
+ struct ethhdr eth; /* 802.3 header */
+ u8 encap[6]; /* 802.2 header */
+ } __attribute__ ((packed)) hdr;
+ int len = skb->len + sizeof(encaps_hdr) - (2 * ETH_ALEN);
+
+ if (skb_headroom(skb) < ENCAPS_OVERHEAD) {
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "%s: Not enough headroom for 802.2 headers %d\n",
+ dev->name, skb_headroom(skb));
+ return -ENOMEM;
+ }
+
+ /* Fill in new header */
+ memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
+ hdr.eth.h_proto = htons(len);
+ memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
+
+ /* Make room for the new header, and copy it in */
+ eh = (struct ethhdr *) skb_push(skb, ENCAPS_OVERHEAD);
+ memcpy(eh, &hdr, sizeof(hdr));
+ }
+
+ /* Calculate Michael MIC */
+ if (do_mic) {
+ size_t len = skb->len - ETH_HLEN;
+ u8 *mic = &mic_buf[0];
+
+ /* Have to write to an even address, so copy the spare
+ * byte across */
+ if (skb->len % 2) {
+ *mic = skb->data[skb->len - 1];
+ mic++;
+ }
+
+ orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
+ eh->h_dest, eh->h_source, 0 /* priority */,
+ skb->data + ETH_HLEN,
+ len, mic);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(orinoco_process_xmit_skb);
+
static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct orinoco_private *priv = ndev_priv(dev);
struct net_device_stats *stats = &priv->stats;
- struct orinoco_tkip_key *key;
hermes_t *hw = &priv->hw;
int err = 0;
u16 txfid = priv->txfid;
- struct ethhdr *eh;
int tx_control;
unsigned long flags;
- int do_mic;
+ u8 mic_buf[MICHAEL_MIC_LEN+1];
if (!netif_running(dev)) {
printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -383,16 +474,12 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->len < ETH_HLEN)
goto drop;
- key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
-
- do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
- (key != NULL));
-
tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
- if (do_mic)
- tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
- HERMES_TXCTRL_MIC;
+ err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
+ &mic_buf[0]);
+ if (err)
+ goto drop;
if (priv->has_alt_txcntl) {
/* WPA enabled firmwares have tx_cntl at the end of
@@ -435,34 +522,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
}
- eh = (struct ethhdr *)skb->data;
-
- /* Encapsulate Ethernet-II frames */
- if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
- struct header_struct {
- struct ethhdr eth; /* 802.3 header */
- u8 encap[6]; /* 802.2 header */
- } __attribute__ ((packed)) hdr;
-
- /* Strip destination and source from the data */
- skb_pull(skb, 2 * ETH_ALEN);
-
- /* And move them to a separate header */
- memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
- hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
- memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
-
- /* Insert the SNAP header */
- if (skb_headroom(skb) < sizeof(hdr)) {
- printk(KERN_ERR
- "%s: Not enough headroom for 802.2 headers %d\n",
- dev->name, skb_headroom(skb));
- goto drop;
- }
- eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
- memcpy(eh, &hdr, sizeof(hdr));
- }
-
err = hw->ops->bap_pwrite(hw, USER_BAP, skb->data, skb->len,
txfid, HERMES_802_3_OFFSET);
if (err) {
@@ -471,32 +530,16 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
goto busy;
}
- /* Calculate Michael MIC */
- if (do_mic) {
- u8 mic_buf[MICHAEL_MIC_LEN + 1];
- u8 *mic;
- size_t offset;
- size_t len;
+ if (tx_control & HERMES_TXCTRL_MIC) {
+ size_t offset = HERMES_802_3_OFFSET + skb->len;
+ size_t len = MICHAEL_MIC_LEN;
- if (skb->len % 2) {
- /* MIC start is on an odd boundary */
- mic_buf[0] = skb->data[skb->len - 1];
- mic = &mic_buf[1];
- offset = skb->len - 1;
- len = MICHAEL_MIC_LEN + 1;
- } else {
- mic = &mic_buf[0];
- offset = skb->len;
- len = MICHAEL_MIC_LEN;
+ if (offset % 2) {
+ offset--;
+ len++;
}
-
- orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
- eh->h_dest, eh->h_source, 0 /* priority */,
- skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
-
- /* Write the MIC */
err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
- txfid, HERMES_802_3_OFFSET + offset);
+ txfid, offset);
if (err) {
printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
dev->name, err);
@@ -2235,7 +2278,7 @@ int orinoco_if_add(struct orinoco_private *priv,
/* we use the default eth_mac_addr for setting the MAC addr */
/* Reserve space in skb for the SNAP header */
- dev->hard_header_len += ENCAPS_OVERHEAD;
+ dev->needed_headroom = ENCAPS_OVERHEAD;
netif_carrier_off(dev);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index e9f415a..a6da86e 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -200,6 +200,12 @@ extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
extern void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
+int orinoco_process_xmit_skb(struct sk_buff *skb,
+ struct net_device *dev,
+ struct orinoco_private *priv,
+ int *tx_control,
+ u8 *mic);
+
/* Common ndo functions exported for reuse by orinoco_usb */
int orinoco_open(struct net_device *dev);
int orinoco_stop(struct net_device *dev);
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index e220933..78f089b 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -67,6 +67,7 @@
#include <linux/wireless.h>
#include <linux/firmware.h>
+#include "mic.h"
#include "orinoco.h"
#ifndef URB_ASYNC_UNLINK
@@ -1198,11 +1199,9 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
struct orinoco_private *priv = ndev_priv(dev);
struct net_device_stats *stats = &priv->stats;
struct ezusb_priv *upriv = priv->card;
+ u8 mic[MICHAEL_MIC_LEN+1];
int err = 0;
- char *p;
- struct ethhdr *eh;
- int len, data_len, data_off;
- __le16 tx_control;
+ int tx_control;
unsigned long flags;
struct request_context *ctx;
u8 *buf;
@@ -1222,7 +1221,7 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
if (orinoco_lock(priv, &flags) != 0) {
printk(KERN_ERR
- "%s: orinoco_xmit() called while hw_unavailable\n",
+ "%s: ezusb_xmit() called while hw_unavailable\n",
dev->name);
return NETDEV_TX_BUSY;
}
@@ -1232,53 +1231,46 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
/* Oops, the firmware hasn't established a connection,
silently drop the packet (this seems to be the
safest approach). */
- stats->tx_errors++;
- orinoco_unlock(priv, &flags);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+ goto drop;
}
+ /* Check packet length */
+ if (skb->len < ETH_HLEN)
+ goto drop;
+
ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0);
if (!ctx)
- goto fail;
+ goto busy;
memset(ctx->buf, 0, BULK_BUF_SIZE);
buf = ctx->buf->data;
- /* Length of the packet body */
- /* FIXME: what if the skb is smaller than this? */
- len = max_t(int, skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
-
- eh = (struct ethhdr *) skb->data;
-
- tx_control = cpu_to_le16(0);
- memcpy(buf, &tx_control, sizeof(tx_control));
- buf += sizeof(tx_control);
- /* Encapsulate Ethernet-II frames */
- if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
- struct header_struct *hdr = (void *) buf;
- buf += sizeof(*hdr);
- data_len = len;
- data_off = sizeof(tx_control) + sizeof(*hdr);
- p = skb->data + ETH_HLEN;
-
- /* 802.3 header */
- memcpy(hdr->dest, eh->h_dest, ETH_ALEN);
- memcpy(hdr->src, eh->h_source, ETH_ALEN);
- hdr->len = htons(data_len + ENCAPS_OVERHEAD);
-
- /* 802.2 header */
- memcpy(&hdr->dsap, &encaps_hdr, sizeof(encaps_hdr));
-
- hdr->ethertype = eh->h_proto;
- } else { /* IEEE 802.3 frame */
- data_len = len + ETH_HLEN;
- data_off = sizeof(tx_control);
- p = skb->data;
+ tx_control = 0;
+
+ err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
+ &mic[0]);
+ if (err)
+ goto drop;
+
+ {
+ __le16 *tx_cntl = (__le16 *)buf;
+ *tx_cntl = cpu_to_le16(tx_control);
+ buf += sizeof(*tx_cntl);
}
- memcpy(buf, p, data_len);
- buf += data_len;
+ memcpy(buf, skb->data, skb->len);
+ buf += skb->len;
+
+ if (tx_control & HERMES_TXCTRL_MIC) {
+ u8 *m = mic;
+ /* Mic has been offset so it can be copied to an even
+ * address. We're copying eveything anyway, so we
+ * don't need to copy that first byte. */
+ if (skb->len % 2)
+ m++;
+ memcpy(buf, m, MICHAEL_MIC_LEN);
+ buf += MICHAEL_MIC_LEN;
+ }
/* Finally, we actually initiate the send */
netif_stop_queue(dev);
@@ -1294,20 +1286,23 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
if (net_ratelimit())
printk(KERN_ERR "%s: Error %d transmitting packet\n",
dev->name, err);
- stats->tx_errors++;
- goto fail;
+ goto busy;
}
dev->trans_start = jiffies;
- stats->tx_bytes += data_off + data_len;
+ stats->tx_bytes += skb->len;
+ goto ok;
- orinoco_unlock(priv, &flags);
+ drop:
+ stats->tx_errors++;
+ stats->tx_dropped++;
+ ok:
+ orinoco_unlock(priv, &flags);
dev_kfree_skb(skb);
-
return NETDEV_TX_OK;
- fail:
+ busy:
orinoco_unlock(priv, &flags);
return NETDEV_TX_BUSY;
}
--
1.6.4.4
^ permalink raw reply related
* [RFC] orinoco: use SKB tail for MIC
From: David Kilroy @ 2010-05-04 21:54 UTC (permalink / raw)
To: linux-wireless; +Cc: orinoco-devel, linville, David Kilroy
In-Reply-To: <1273010082-15871-1-git-send-email-kilroyd@googlemail.com>
The interface is much neater if we can append the calculated MIC to
the SKB which gets blatted to the hardware wholesale.
Unfortunately, this doesn't work very well. Without spare padding, we
never seem to have any tailroom, and even we ask for extra tailroom
it's not guaranteed.
We could probably call pskb_expand_skb or something to get the tailroom.
But should we really be doing that on the majority of packets?
Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
drivers/net/wireless/orinoco/main.c | 42 ++++++++-------------------
drivers/net/wireless/orinoco/orinoco.h | 3 +-
drivers/net/wireless/orinoco/orinoco_usb.c | 16 +----------
3 files changed, 15 insertions(+), 46 deletions(-)
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 3b9a5fb..95e9edb 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -367,8 +367,7 @@ EXPORT_SYMBOL(orinoco_change_mtu);
int orinoco_process_xmit_skb(struct sk_buff *skb,
struct net_device *dev,
struct orinoco_private *priv,
- int *tx_control,
- u8 *mic_buf)
+ int *tx_control)
{
struct orinoco_tkip_key *key;
struct ethhdr *eh;
@@ -414,15 +413,18 @@ int orinoco_process_xmit_skb(struct sk_buff *skb,
/* Calculate Michael MIC */
if (do_mic) {
size_t len = skb->len - ETH_HLEN;
- u8 *mic = &mic_buf[0];
+ u8 *mic;
- /* Have to write to an even address, so copy the spare
- * byte across */
- if (skb->len % 2) {
- *mic = skb->data[skb->len - 1];
- mic++;
+ if (skb_tailroom(skb) < MICHAEL_MIC_LEN) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Insufficient tailroom (%d) for MIC (%d)\n",
+ dev->name,
+ skb_tailroom(skb), MICHAEL_MIC_LEN);
+ return -ENOMEM;
}
+ mic = skb_put(skb, MICHAEL_MIC_LEN);
+
orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
eh->h_dest, eh->h_source, 0 /* priority */,
skb->data + ETH_HLEN,
@@ -442,7 +444,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
u16 txfid = priv->txfid;
int tx_control;
unsigned long flags;
- u8 mic_buf[MICHAEL_MIC_LEN+1];
if (!netif_running(dev)) {
printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -476,8 +477,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
- err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
- &mic_buf[0]);
+ err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control);
if (err)
goto drop;
@@ -530,23 +530,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
goto busy;
}
- if (tx_control & HERMES_TXCTRL_MIC) {
- size_t offset = HERMES_802_3_OFFSET + skb->len;
- size_t len = MICHAEL_MIC_LEN;
-
- if (offset % 2) {
- offset--;
- len++;
- }
- err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
- txfid, offset);
- if (err) {
- printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
- dev->name, err);
- goto busy;
- }
- }
-
/* Finally, we actually initiate the send */
netif_stop_queue(dev);
@@ -2277,8 +2260,9 @@ int orinoco_if_add(struct orinoco_private *priv,
/* we use the default eth_mac_addr for setting the MAC addr */
- /* Reserve space in skb for the SNAP header */
+ /* Reserve space in skb for the SNAP header, and MIC */
dev->needed_headroom = ENCAPS_OVERHEAD;
+ dev->needed_tailroom = MICHAEL_MIC_LEN;
netif_carrier_off(dev);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index a6da86e..5ea3de8 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -203,8 +203,7 @@ extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
int orinoco_process_xmit_skb(struct sk_buff *skb,
struct net_device *dev,
struct orinoco_private *priv,
- int *tx_control,
- u8 *mic);
+ int *tx_control);
/* Common ndo functions exported for reuse by orinoco_usb */
int orinoco_open(struct net_device *dev);
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index 78f089b..dabea30 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -67,7 +67,6 @@
#include <linux/wireless.h>
#include <linux/firmware.h>
-#include "mic.h"
#include "orinoco.h"
#ifndef URB_ASYNC_UNLINK
@@ -1199,7 +1198,6 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
struct orinoco_private *priv = ndev_priv(dev);
struct net_device_stats *stats = &priv->stats;
struct ezusb_priv *upriv = priv->card;
- u8 mic[MICHAEL_MIC_LEN+1];
int err = 0;
int tx_control;
unsigned long flags;
@@ -1247,8 +1245,7 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
tx_control = 0;
- err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
- &mic[0]);
+ err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control);
if (err)
goto drop;
@@ -1261,17 +1258,6 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(buf, skb->data, skb->len);
buf += skb->len;
- if (tx_control & HERMES_TXCTRL_MIC) {
- u8 *m = mic;
- /* Mic has been offset so it can be copied to an even
- * address. We're copying eveything anyway, so we
- * don't need to copy that first byte. */
- if (skb->len % 2)
- m++;
- memcpy(buf, m, MICHAEL_MIC_LEN);
- buf += MICHAEL_MIC_LEN;
- }
-
/* Finally, we actually initiate the send */
netif_stop_queue(dev);
--
1.6.4.4
^ permalink raw reply related
* [PATCH] compat: backport orinoco updates
From: Hauke Mehrtens @ 2010-05-04 22:40 UTC (permalink / raw)
To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
include/linux/compat-2.6.29.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/linux/compat-2.6.29.h b/include/linux/compat-2.6.29.h
index c3572a2..2709953 100644
--- a/include/linux/compat-2.6.29.h
+++ b/include/linux/compat-2.6.29.h
@@ -61,6 +61,8 @@ extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
extern int eth_mac_addr(struct net_device *dev, void *p);
+#define orinoco_if_add(priv, base_addr, irq, ops) orinoco_if_add(priv, base_addr, irq)
+
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */
#endif /* LINUX_26_29_COMPAT_H */
--
1.7.0.4
^ permalink raw reply related
* [PATCH] compat-wireless: updates for orinoco
From: Hauke Mehrtens @ 2010-05-04 22:40 UTC (permalink / raw)
To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens
* Make all the patches apply again.
* rename read_pda to avoid conflicts with definitions in kernel <= 2.6.29
* add orinoco usb
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
config.mk | 2 +
patches/01-netdev.patch | 51 +++++++++++++++++++++-----
patches/24-pcmcia.patch | 10 +++---
patches/27-hermes-read-pda-conflict.patch | 56 +++++++++++++++++++++++++++++
4 files changed, 104 insertions(+), 15 deletions(-)
create mode 100644 patches/27-hermes-read-pda-conflict.patch
diff --git a/config.mk b/config.mk
index 6a7c5c9..176c0af 100644
--- a/config.mk
+++ b/config.mk
@@ -388,6 +388,8 @@ CONFIG_LIBERTAS_USB=m
NEED_LIBERTAS=y
endif
+CONFIG_ORINOCO_USB=m
+
endif # end of USB driver list
ifneq ($(CONFIG_SPI_MASTER),)
diff --git a/patches/01-netdev.patch b/patches/01-netdev.patch
index 01dbbce..51d12c4 100644
--- a/patches/01-netdev.patch
+++ b/patches/01-netdev.patch
@@ -575,7 +575,7 @@ without creating a headache on maintenance of the pathes.
dev->tx_queue_len = 0;
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
-@@ -2078,6 +2078,7 @@ int orinoco_init(struct orinoco_private
+@@ -2087,6 +2087,7 @@ int orinoco_init(struct orinoco_private
}
EXPORT_SYMBOL(orinoco_init);
@@ -583,7 +583,7 @@ without creating a headache on maintenance of the pathes.
static const struct net_device_ops orinoco_netdev_ops = {
.ndo_open = orinoco_open,
.ndo_stop = orinoco_stop,
-@@ -2089,6 +2090,7 @@ static const struct net_device_ops orino
+@@ -2098,6 +2099,7 @@ static const struct net_device_ops orino
.ndo_tx_timeout = orinoco_tx_timeout,
.ndo_get_stats = orinoco_get_stats,
};
@@ -591,12 +591,15 @@ without creating a headache on maintenance of the pathes.
/* Allocate private data.
*
-@@ -2211,7 +2213,18 @@ int orinoco_if_add(struct orinoco_privat
-
- /* Setup / override net_device fields */
- dev->ieee80211_ptr = wdev;
+@@ -2227,10 +2229,21 @@ int orinoco_if_add(struct orinoco_privat
+ dev->wireless_data = &priv->wireless_data;
+ #endif
+ /* Default to standard ops if not set */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
- dev->netdev_ops = &orinoco_netdev_ops;
+ if (ops)
+ dev->netdev_ops = ops;
+ else
+ dev->netdev_ops = &orinoco_netdev_ops;
+#else
+ dev->open = orinoco_open;
+ dev->stop = orinoco_stop;
@@ -607,9 +610,37 @@ without creating a headache on maintenance of the pathes.
+ dev->tx_timeout = orinoco_tx_timeout;
+ dev->get_stats = orinoco_get_stats;
+#endif
- dev->watchdog_timeo = HZ; /* 1 second timeout */
- dev->wireless_handlers = &orinoco_handler_def;
- #ifdef WIRELESS_SPY
+
+ /* we use the default eth_mac_addr for setting the MAC addr */
+
+--- a/drivers/net/wireless/orinoco/orinoco_usb.c
++++ b/drivers/net/wireless/orinoco/orinoco_usb.c
+@@ -1566,6 +1566,7 @@ static const struct hermes_ops ezusb_ops
+ .unlock_irq = ezusb_unlock_irq,
+ };
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+ static const struct net_device_ops ezusb_netdev_ops = {
+ .ndo_open = orinoco_open,
+ .ndo_stop = orinoco_stop,
+@@ -1577,6 +1578,7 @@ static const struct net_device_ops ezusb
+ .ndo_tx_timeout = orinoco_tx_timeout,
+ .ndo_get_stats = orinoco_get_stats,
+ };
++#endif
+
+ static int ezusb_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+@@ -1722,6 +1724,9 @@ static int ezusb_probe(struct usb_interf
+ err("%s: orinoco_if_add() failed", __func__);
+ goto error;
+ }
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
++ priv->ndev->hard_start_xmit = ezusb_xmit;
++#endif
+ upriv->dev = priv->ndev;
+
+ goto exit;
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -168,8 +168,12 @@ static inline int bnep_net_proto_filter(
diff --git a/patches/24-pcmcia.patch b/patches/24-pcmcia.patch
index 283b30d..3bc395d 100644
--- a/patches/24-pcmcia.patch
+++ b/patches/24-pcmcia.patch
@@ -251,9 +251,9 @@
/* Register an interface with the stack */
if (orinoco_if_add(priv, link->io.BasePort1,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- link->irq) != 0) {
+ link->irq, NULL) != 0) {
+#else
-+ link->irq.AssignedIRQ) != 0) {
++ link->irq.AssignedIRQ, NULL) != 0) {
+#endif
printk(KERN_ERR PFX "orinoco_if_add() failed\n");
goto failed;
@@ -285,14 +285,14 @@
if (ret)
goto failed;
-@@ -359,7 +369,11 @@ spectrum_cs_config(struct pcmcia_device
+@@ -360,7 +370,11 @@ spectrum_cs_config(struct pcmcia_device
/* Register an interface with the stack */
if (orinoco_if_add(priv, link->io.BasePort1,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- link->irq) != 0) {
+ link->irq, NULL) != 0) {
+#else
-+ link->irq.AssignedIRQ) != 0) {
++ link->irq.AssignedIRQ, NULL) != 0) {
+#endif
printk(KERN_ERR PFX "orinoco_if_add() failed\n");
goto failed;
diff --git a/patches/27-hermes-read-pda-conflict.patch b/patches/27-hermes-read-pda-conflict.patch
new file mode 100644
index 0000000..fe6b181
--- /dev/null
+++ b/patches/27-hermes-read-pda-conflict.patch
@@ -0,0 +1,56 @@
+Rename read_pda to something else because this symbol is used in a
+define for something else in arch/um/include/asm/pda.h on older kernels.
+
+--- a/drivers/net/wireless/orinoco/fw.c
++++ b/drivers/net/wireless/orinoco/fw.c
+@@ -122,7 +122,7 @@ orinoco_dl_firmware(struct orinoco_priva
+ dev_dbg(dev, "Attempting to download firmware %s\n", firmware);
+
+ /* Read current plug data */
+- err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
++ err = hw->ops->read_pda_h(hw, pda, fw->pda_addr, fw->pda_size);
+ dev_dbg(dev, "Read PDA returned %d\n", err);
+ if (err)
+ goto free;
+@@ -224,7 +224,7 @@ symbol_dl_image(struct orinoco_private *
+ if (!pda)
+ return -ENOMEM;
+
+- ret = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
++ ret = hw->ops->read_pda_h(hw, pda, fw->pda_addr, fw->pda_size);
+ if (ret)
+ goto free;
+ }
+--- a/drivers/net/wireless/orinoco/hermes.c
++++ b/drivers/net/wireless/orinoco/hermes.c
+@@ -765,7 +765,7 @@ static const struct hermes_ops hermes_op
+ .write_ltv = hermes_write_ltv,
+ .bap_pread = hermes_bap_pread,
+ .bap_pwrite = hermes_bap_pwrite,
+- .read_pda = hermes_read_pda,
++ .read_pda_h = hermes_read_pda,
+ .program_init = hermesi_program_init,
+ .program_end = hermesi_program_end,
+ .program = hermes_program_bytes,
+--- a/drivers/net/wireless/orinoco/hermes.h
++++ b/drivers/net/wireless/orinoco/hermes.h
+@@ -393,7 +393,7 @@ struct hermes_ops {
+ u16 id, u16 offset);
+ int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf,
+ int len, u16 id, u16 offset);
+- int (*read_pda)(struct hermes *hw, __le16 *pda,
++ int (*read_pda_h)(struct hermes *hw, __le16 *pda,
+ u32 pda_addr, u16 pda_len);
+ int (*program_init)(struct hermes *hw, u32 entry_point);
+ int (*program_end)(struct hermes *hw);
+--- a/drivers/net/wireless/orinoco/orinoco_usb.c
++++ b/drivers/net/wireless/orinoco/orinoco_usb.c
+@@ -1556,7 +1556,7 @@ static const struct hermes_ops ezusb_ops
+ .read_ltv = ezusb_read_ltv,
+ .write_ltv = ezusb_write_ltv,
+ .bap_pread = ezusb_bap_pread,
+- .read_pda = ezusb_read_pda,
++ .read_pda_h = ezusb_read_pda,
+ .program_init = ezusb_program_init,
+ .program_end = ezusb_program_end,
+ .program = ezusb_program,
--
1.7.0.4
^ permalink raw reply related
* [PATCH] mac80211: remove association work when processing deauth request
From: Reinette Chatre @ 2010-05-04 23:04 UTC (permalink / raw)
To: johannes, linville; +Cc: linux-wireless, Reinette Chatre
From: Reinette Chatre <reinette.chatre@intel.com>
In https://bugzilla.kernel.org/show_bug.cgi?id=15794 a user encountered the
following:
[18967.469098] wlan0: authenticated
[18967.472527] wlan0: associate with 00:1c:10:b8:e3:ea (try 1)
[18967.472585] wlan0: deauthenticating from 00:1c:10:b8:e3:ea by local choice (reason=3)
[18967.672057] wlan0: associate with 00:1c:10:b8:e3:ea (try 2)
[18967.872357] wlan0: associate with 00:1c:10:b8:e3:ea (try 3)
[18968.072960] wlan0: association with 00:1c:10:b8:e3:ea timed out
[18968.076890] ------------[ cut here ]------------
[18968.076898] WARNING: at net/wireless/mlme.c:341 cfg80211_send_assoc_timeout+0xa8/0x140()
[18968.076900] Hardware name: GX628
[18968.076924] Pid: 1408, comm: phy0 Not tainted 2.6.34-rc4-00082-g250541f-dirty #3
[18968.076926] Call Trace:
[18968.076931] [<ffffffff8103459e>] ? warn_slowpath_common+0x6e/0xb0
[18968.076934] [<ffffffff8157c2d8>] ? cfg80211_send_assoc_timeout+0xa8/0x140
[18968.076937] [<ffffffff8103ff8b>] ? mod_timer+0x10b/0x180
[18968.076940] [<ffffffff8158f0fc>] ? ieee80211_assoc_done+0xbc/0xc0
[18968.076943] [<ffffffff81590d53>] ? ieee80211_work_work+0x553/0x11c0
[18968.076945] [<ffffffff8102d931>] ? finish_task_switch+0x41/0xb0
[18968.076948] [<ffffffff81590800>] ? ieee80211_work_work+0x0/0x11c0
[18968.076951] [<ffffffff810476fb>] ? worker_thread+0x13b/0x210
[18968.076954] [<ffffffff8104b6b0>] ? autoremove_wake_function+0x0/0x30
[18968.076956] [<ffffffff810475c0>] ? worker_thread+0x0/0x210
[18968.076959] [<ffffffff8104b21e>] ? kthread+0x8e/0xa0
[18968.076962] [<ffffffff810031f4>] ? kernel_thread_helper+0x4/0x10
[18968.076964] [<ffffffff8104b190>] ? kthread+0x0/0xa0
[18968.076966] [<ffffffff810031f0>] ? kernel_thread_helper+0x0/0x10
[18968.076968] ---[ end trace 8aa6265f4b1adfe0 ]---
As explained by Johannes Berg <johannes@sipsolutions.net>:
We authenticate successfully, and then userspace requests association.
Then we start that process, but the AP doesn't respond. While we're
still waiting for an AP response, userspace asks for a deauth. We do
the deauth, but don't abort the association work. Then once the
association work times out we tell cfg80211, but it no longer wants
to know since for all it is concerned we accepted the deauth that
also kills the association attempt.
Fix this by, upon receipt of deauth request, removing the association work
and continuing to send the deauth.
Unfortunately the user reporting the issue is not able to reproduce this
problem anymore and cannot verify this fix. This seems like a well understood
issue though and I thus present the patch.
Bug-identified-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
net/mac80211/mlme.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 358226f..890510c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2176,7 +2176,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
continue;
if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
- wk->type != IEEE80211_WORK_AUTH)
+ wk->type != IEEE80211_WORK_AUTH &&
+ wk->type != IEEE80211_WORK_ASSOC)
continue;
if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] mac80211: remove association work when processing deauth request
From: reinette chatre @ 2010-05-04 23:11 UTC (permalink / raw)
To: johannes@sipsolutions.net
Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org
In-Reply-To: <1273014289-21765-1-git-send-email-reinette.chatre@intel.com>
On Tue, 2010-05-04 at 16:04 -0700, Chatre, Reinette wrote:
> From: Reinette Chatre <reinette.chatre@intel.com>
>
> In https://bugzilla.kernel.org/show_bug.cgi?id=15794 a user encountered the
> following:
>
> [18967.469098] wlan0: authenticated
> [18967.472527] wlan0: associate with 00:1c:10:b8:e3:ea (try 1)
> [18967.472585] wlan0: deauthenticating from 00:1c:10:b8:e3:ea by local choice (reason=3)
> [18967.672057] wlan0: associate with 00:1c:10:b8:e3:ea (try 2)
> [18967.872357] wlan0: associate with 00:1c:10:b8:e3:ea (try 3)
> [18968.072960] wlan0: association with 00:1c:10:b8:e3:ea timed out
> [18968.076890] ------------[ cut here ]------------
> [18968.076898] WARNING: at net/wireless/mlme.c:341 cfg80211_send_assoc_timeout+0xa8/0x140()
> [18968.076900] Hardware name: GX628
> [18968.076924] Pid: 1408, comm: phy0 Not tainted 2.6.34-rc4-00082-g250541f-dirty #3
> [18968.076926] Call Trace:
> [18968.076931] [<ffffffff8103459e>] ? warn_slowpath_common+0x6e/0xb0
> [18968.076934] [<ffffffff8157c2d8>] ? cfg80211_send_assoc_timeout+0xa8/0x140
> [18968.076937] [<ffffffff8103ff8b>] ? mod_timer+0x10b/0x180
> [18968.076940] [<ffffffff8158f0fc>] ? ieee80211_assoc_done+0xbc/0xc0
> [18968.076943] [<ffffffff81590d53>] ? ieee80211_work_work+0x553/0x11c0
> [18968.076945] [<ffffffff8102d931>] ? finish_task_switch+0x41/0xb0
> [18968.076948] [<ffffffff81590800>] ? ieee80211_work_work+0x0/0x11c0
> [18968.076951] [<ffffffff810476fb>] ? worker_thread+0x13b/0x210
> [18968.076954] [<ffffffff8104b6b0>] ? autoremove_wake_function+0x0/0x30
> [18968.076956] [<ffffffff810475c0>] ? worker_thread+0x0/0x210
> [18968.076959] [<ffffffff8104b21e>] ? kthread+0x8e/0xa0
> [18968.076962] [<ffffffff810031f4>] ? kernel_thread_helper+0x4/0x10
> [18968.076964] [<ffffffff8104b190>] ? kthread+0x0/0xa0
> [18968.076966] [<ffffffff810031f0>] ? kernel_thread_helper+0x0/0x10
> [18968.076968] ---[ end trace 8aa6265f4b1adfe0 ]---
>
> As explained by Johannes Berg <johannes@sipsolutions.net>:
>
> We authenticate successfully, and then userspace requests association.
> Then we start that process, but the AP doesn't respond. While we're
> still waiting for an AP response, userspace asks for a deauth. We do
> the deauth, but don't abort the association work. Then once the
> association work times out we tell cfg80211, but it no longer wants
> to know since for all it is concerned we accepted the deauth that
> also kills the association attempt.
>
> Fix this by, upon receipt of deauth request, removing the association work
> and continuing to send the deauth.
>
> Unfortunately the user reporting the issue is not able to reproduce this
> problem anymore and cannot verify this fix. This seems like a well understood
> issue though and I thus present the patch.
>
> Bug-identified-by: Johannes Berg <johannes@sipsolutions.net>
> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
> ---
Please also consider this patch for wireless-2.6 - it applies cleanly.
Reinette
^ permalink raw reply
* Re: [PATCH] compat-wireless: updates for orinoco
From: Luis R. Rodriguez @ 2010-05-04 23:26 UTC (permalink / raw)
To: Hauke Mehrtens, Stephen Hemminger, David Miller
Cc: linux-wireless, mcgrof, netdev
In-Reply-To: <1273012850-8359-1-git-send-email-hauke@hauke-m.de>
First of all, thanks a lot! Some comments below.
On Tue, May 4, 2010 at 3:40 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> * Make all the patches apply again.
> * rename read_pda to avoid conflicts with definitions in kernel <= 2.6.29
I'm going to apply these two changes, if you get time can you send a
patch to rename read_pda upstream as well, that way we don't have to
carry this?
> * add orinoco usb
Thanks for this but I've grown tired of updating these netdev ops and
I think we can do better. I'll add a netdev_attach_ops() which would
simply do all the backport stuff for us, this way for backporting
purposes all we have to do is replace the old lines with a
netdev_attach_ops() call. In fact if we *really* wanted to we could
add a dummy netdev_attach_ops() upstream and just backport that on
older kernels, this would mean 0 line changes to backport a newer
driver.
Something like this maybe on the generic compat module, it builds for
me, will commit soon.
/*
* Expand this as drivers require more ops, for now this
* only sets the ones we need.
*/
void netdev_attach_ops(struct net_device *dev,
const struct net_device_ops *ops)
{
#define SET_NETDEVOP(_op) (_op ? _op : NULL)
dev->open = SET_NETDEVOP(ops->ndo_open);
dev->stop = SET_NETDEVOP(ops->ndo_stop);
dev->hard_start_xmit = SET_NETDEVOP(ops->ndo_start_xmit);
dev->set_multicast_list = SET_NETDEVOP(ops->ndo_set_multicast_list);
dev->change_mtu = SET_NETDEVOP(ops->ndo_change_mtu);
dev->set_mac_address = SET_NETDEVOP(ops->ndo_set_mac_address);
dev->tx_timeout = SET_NETDEVOP(ops->ndo_tx_timeout);
dev->get_stats = SET_NETDEVOP(ops->ndo_get_stats);
#undef SET_NETDEVOP
}
EXPORT_SYMBOL(netdev_attach_ops);
For newer kernels then this would just be:
static inline void netdev_attach_ops(struct net_device *dev,
const struct net_device_ops *ops)
{
dev->netdev_ops = ops;
}
Stephen, would the above be acceptable upstream on netdevice.h ? It
would eliminate all needs from having to #ifdef network drivers when
backporting. If so I can send a respective patch and spatch all the
setters I think. An example of the nasty ifdef crap we have to do for
the current backport of netdevop'able drivers is below.
Luis
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
> config.mk | 2 +
> patches/01-netdev.patch | 51 +++++++++++++++++++++-----
> patches/24-pcmcia.patch | 10 +++---
> patches/27-hermes-read-pda-conflict.patch | 56 +++++++++++++++++++++++++++++
> 4 files changed, 104 insertions(+), 15 deletions(-)
> create mode 100644 patches/27-hermes-read-pda-conflict.patch
>
> diff --git a/config.mk b/config.mk
> index 6a7c5c9..176c0af 100644
> --- a/config.mk
> +++ b/config.mk
> @@ -388,6 +388,8 @@ CONFIG_LIBERTAS_USB=m
> NEED_LIBERTAS=y
> endif
>
> +CONFIG_ORINOCO_USB=m
> +
> endif # end of USB driver list
>
> ifneq ($(CONFIG_SPI_MASTER),)
> diff --git a/patches/01-netdev.patch b/patches/01-netdev.patch
> index 01dbbce..51d12c4 100644
> --- a/patches/01-netdev.patch
> +++ b/patches/01-netdev.patch
> @@ -575,7 +575,7 @@ without creating a headache on maintenance of the pathes.
> dev->tx_queue_len = 0;
> --- a/drivers/net/wireless/orinoco/main.c
> +++ b/drivers/net/wireless/orinoco/main.c
> -@@ -2078,6 +2078,7 @@ int orinoco_init(struct orinoco_private
> +@@ -2087,6 +2087,7 @@ int orinoco_init(struct orinoco_private
> }
> EXPORT_SYMBOL(orinoco_init);
>
> @@ -583,7 +583,7 @@ without creating a headache on maintenance of the pathes.
> static const struct net_device_ops orinoco_netdev_ops = {
> .ndo_open = orinoco_open,
> .ndo_stop = orinoco_stop,
> -@@ -2089,6 +2090,7 @@ static const struct net_device_ops orino
> +@@ -2098,6 +2099,7 @@ static const struct net_device_ops orino
> .ndo_tx_timeout = orinoco_tx_timeout,
> .ndo_get_stats = orinoco_get_stats,
> };
> @@ -591,12 +591,15 @@ without creating a headache on maintenance of the pathes.
>
> /* Allocate private data.
> *
> -@@ -2211,7 +2213,18 @@ int orinoco_if_add(struct orinoco_privat
> -
> - /* Setup / override net_device fields */
> - dev->ieee80211_ptr = wdev;
> +@@ -2227,10 +2229,21 @@ int orinoco_if_add(struct orinoco_privat
> + dev->wireless_data = &priv->wireless_data;
> + #endif
> + /* Default to standard ops if not set */
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
> - dev->netdev_ops = &orinoco_netdev_ops;
> + if (ops)
> + dev->netdev_ops = ops;
> + else
> + dev->netdev_ops = &orinoco_netdev_ops;
> +#else
> + dev->open = orinoco_open;
> + dev->stop = orinoco_stop;
> @@ -607,9 +610,37 @@ without creating a headache on maintenance of the pathes.
> + dev->tx_timeout = orinoco_tx_timeout;
> + dev->get_stats = orinoco_get_stats;
> +#endif
> - dev->watchdog_timeo = HZ; /* 1 second timeout */
> - dev->wireless_handlers = &orinoco_handler_def;
> - #ifdef WIRELESS_SPY
> +
> + /* we use the default eth_mac_addr for setting the MAC addr */
> +
> +--- a/drivers/net/wireless/orinoco/orinoco_usb.c
> ++++ b/drivers/net/wireless/orinoco/orinoco_usb.c
> +@@ -1566,6 +1566,7 @@ static const struct hermes_ops ezusb_ops
> + .unlock_irq = ezusb_unlock_irq,
> + };
> +
> ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
> + static const struct net_device_ops ezusb_netdev_ops = {
> + .ndo_open = orinoco_open,
> + .ndo_stop = orinoco_stop,
> +@@ -1577,6 +1578,7 @@ static const struct net_device_ops ezusb
> + .ndo_tx_timeout = orinoco_tx_timeout,
> + .ndo_get_stats = orinoco_get_stats,
> + };
> ++#endif
> +
> + static int ezusb_probe(struct usb_interface *interface,
> + const struct usb_device_id *id)
> +@@ -1722,6 +1724,9 @@ static int ezusb_probe(struct usb_interf
> + err("%s: orinoco_if_add() failed", __func__);
> + goto error;
> + }
> ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
> ++ priv->ndev->hard_start_xmit = ezusb_xmit;
> ++#endif
> + upriv->dev = priv->ndev;
> +
> + goto exit;
> --- a/net/bluetooth/bnep/netdev.c
> +++ b/net/bluetooth/bnep/netdev.c
> @@ -168,8 +168,12 @@ static inline int bnep_net_proto_filter(
> diff --git a/patches/24-pcmcia.patch b/patches/24-pcmcia.patch
> index 283b30d..3bc395d 100644
> --- a/patches/24-pcmcia.patch
> +++ b/patches/24-pcmcia.patch
> @@ -251,9 +251,9 @@
> /* Register an interface with the stack */
> if (orinoco_if_add(priv, link->io.BasePort1,
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
> - link->irq) != 0) {
> + link->irq, NULL) != 0) {
> +#else
> -+ link->irq.AssignedIRQ) != 0) {
> ++ link->irq.AssignedIRQ, NULL) != 0) {
> +#endif
> printk(KERN_ERR PFX "orinoco_if_add() failed\n");
> goto failed;
> @@ -285,14 +285,14 @@
> if (ret)
> goto failed;
>
> -@@ -359,7 +369,11 @@ spectrum_cs_config(struct pcmcia_device
> +@@ -360,7 +370,11 @@ spectrum_cs_config(struct pcmcia_device
>
> /* Register an interface with the stack */
> if (orinoco_if_add(priv, link->io.BasePort1,
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
> - link->irq) != 0) {
> + link->irq, NULL) != 0) {
> +#else
> -+ link->irq.AssignedIRQ) != 0) {
> ++ link->irq.AssignedIRQ, NULL) != 0) {
> +#endif
> printk(KERN_ERR PFX "orinoco_if_add() failed\n");
> goto failed;
> diff --git a/patches/27-hermes-read-pda-conflict.patch b/patches/27-hermes-read-pda-conflict.patch
> new file mode 100644
> index 0000000..fe6b181
> --- /dev/null
> +++ b/patches/27-hermes-read-pda-conflict.patch
> @@ -0,0 +1,56 @@
> +Rename read_pda to something else because this symbol is used in a
> +define for something else in arch/um/include/asm/pda.h on older kernels.
> +
> +--- a/drivers/net/wireless/orinoco/fw.c
> ++++ b/drivers/net/wireless/orinoco/fw.c
> +@@ -122,7 +122,7 @@ orinoco_dl_firmware(struct orinoco_priva
> + dev_dbg(dev, "Attempting to download firmware %s\n", firmware);
> +
> + /* Read current plug data */
> +- err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
> ++ err = hw->ops->read_pda_h(hw, pda, fw->pda_addr, fw->pda_size);
> + dev_dbg(dev, "Read PDA returned %d\n", err);
> + if (err)
> + goto free;
> +@@ -224,7 +224,7 @@ symbol_dl_image(struct orinoco_private *
> + if (!pda)
> + return -ENOMEM;
> +
> +- ret = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
> ++ ret = hw->ops->read_pda_h(hw, pda, fw->pda_addr, fw->pda_size);
> + if (ret)
> + goto free;
> + }
> +--- a/drivers/net/wireless/orinoco/hermes.c
> ++++ b/drivers/net/wireless/orinoco/hermes.c
> +@@ -765,7 +765,7 @@ static const struct hermes_ops hermes_op
> + .write_ltv = hermes_write_ltv,
> + .bap_pread = hermes_bap_pread,
> + .bap_pwrite = hermes_bap_pwrite,
> +- .read_pda = hermes_read_pda,
> ++ .read_pda_h = hermes_read_pda,
> + .program_init = hermesi_program_init,
> + .program_end = hermesi_program_end,
> + .program = hermes_program_bytes,
> +--- a/drivers/net/wireless/orinoco/hermes.h
> ++++ b/drivers/net/wireless/orinoco/hermes.h
> +@@ -393,7 +393,7 @@ struct hermes_ops {
> + u16 id, u16 offset);
> + int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf,
> + int len, u16 id, u16 offset);
> +- int (*read_pda)(struct hermes *hw, __le16 *pda,
> ++ int (*read_pda_h)(struct hermes *hw, __le16 *pda,
> + u32 pda_addr, u16 pda_len);
> + int (*program_init)(struct hermes *hw, u32 entry_point);
> + int (*program_end)(struct hermes *hw);
> +--- a/drivers/net/wireless/orinoco/orinoco_usb.c
> ++++ b/drivers/net/wireless/orinoco/orinoco_usb.c
> +@@ -1556,7 +1556,7 @@ static const struct hermes_ops ezusb_ops
> + .read_ltv = ezusb_read_ltv,
> + .write_ltv = ezusb_write_ltv,
> + .bap_pread = ezusb_bap_pread,
> +- .read_pda = ezusb_read_pda,
> ++ .read_pda_h = ezusb_read_pda,
> + .program_init = ezusb_program_init,
> + .program_end = ezusb_program_end,
> + .program = ezusb_program,
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] compat: backport orinoco updates
From: Luis R. Rodriguez @ 2010-05-04 23:29 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-wireless, mcgrof
In-Reply-To: <1273012837-8325-1-git-send-email-hauke@hauke-m.de>
On Tue, May 4, 2010 at 3:40 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
> include/linux/compat-2.6.29.h | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/compat-2.6.29.h b/include/linux/compat-2.6.29.h
> index c3572a2..2709953 100644
> --- a/include/linux/compat-2.6.29.h
> +++ b/include/linux/compat-2.6.29.h
> @@ -61,6 +61,8 @@ extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
>
> extern int eth_mac_addr(struct net_device *dev, void *p);
>
> +#define orinoco_if_add(priv, base_addr, irq, ops) orinoco_if_add(priv, base_addr, irq)
> +
> #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */
Since we're going to have the netdevice ops available on older kernels
I'll skip this patch and first try by just backporting the netdevice
ops a bit differently. Thanks though.
Luis
^ permalink raw reply
* Re: 2.6.34-rc6-git2: Reported regressions from 2.6.33
From: Linus Torvalds @ 2010-05-05 0:00 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux Kernel Mailing List, Maciej Rutecki, Andrew Morton,
Kernel Testers List, Network Development, Linux ACPI,
Linux PM List, Linux SCSI List, Linux Wireless List, DRI
In-Reply-To: <JzEGxUyyQHG.A.ZtH.YHJ4LB@chimera>
On Tue, 4 May 2010, Rafael J. Wysocki wrote:
>
> Unresolved regressions
> ----------------------
>
> Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=15880
> Subject : Very bad regression from 2.6.33 as of 1600f9def
> Submitter : Alex Elsayed <eternaleye@gmail.com>
> Date : 2010-04-29 2:28 (6 days old)
> Message-ID : <loom.20100429T041908-663@post.gmane.org>
> References : http://marc.info/?l=linux-kernel&m=127250825306178&w=2
This looks like it wasn't a regression, but some other compile/install
issue. See
http://marc.info/?l=linux-kernel&m=127274294422719&w=2
where he reports that his self-compiled 2.6.33 doesn't boot either.
There's some confusion about .config, but it might well be an install
problem too (in fact, that sounds more likely - the original bug-report
seems to reboot before the kernel has really even booted - it apparently
hasn't done the graphics mode switch by the early bootloader)
Linus
^ permalink raw reply
* Re: [PATCH] compat-wireless: updates for orinoco
From: Stephen Hemminger @ 2010-05-05 0:04 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Hauke Mehrtens, David Miller, linux-wireless, mcgrof, netdev
In-Reply-To: <v2u43e72e891005041626n14deaca5z284f2472e909c923@mail.gmail.com>
On Tue, 4 May 2010 16:26:53 -0700
"Luis R. Rodriguez" <lrodriguez@atheros.com> wrote:
> First of all, thanks a lot! Some comments below.
>
> On Tue, May 4, 2010 at 3:40 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> > * Make all the patches apply again.
> > * rename read_pda to avoid conflicts with definitions in kernel <= 2.6.29
>
> I'm going to apply these two changes, if you get time can you send a
> patch to rename read_pda upstream as well, that way we don't have to
> carry this?
>
> > * add orinoco usb
>
> Thanks for this but I've grown tired of updating these netdev ops and
> I think we can do better. I'll add a netdev_attach_ops() which would
> simply do all the backport stuff for us, this way for backporting
> purposes all we have to do is replace the old lines with a
> netdev_attach_ops() call. In fact if we *really* wanted to we could
> add a dummy netdev_attach_ops() upstream and just backport that on
> older kernels, this would mean 0 line changes to backport a newer
> driver.
>
> Something like this maybe on the generic compat module, it builds for
> me, will commit soon.
>
> /*
> * Expand this as drivers require more ops, for now this
> * only sets the ones we need.
> */
> void netdev_attach_ops(struct net_device *dev,
> const struct net_device_ops *ops)
> {
> #define SET_NETDEVOP(_op) (_op ? _op : NULL)
> dev->open = SET_NETDEVOP(ops->ndo_open);
> dev->stop = SET_NETDEVOP(ops->ndo_stop);
> dev->hard_start_xmit = SET_NETDEVOP(ops->ndo_start_xmit);
> dev->set_multicast_list = SET_NETDEVOP(ops->ndo_set_multicast_list);
> dev->change_mtu = SET_NETDEVOP(ops->ndo_change_mtu);
> dev->set_mac_address = SET_NETDEVOP(ops->ndo_set_mac_address);
> dev->tx_timeout = SET_NETDEVOP(ops->ndo_tx_timeout);
> dev->get_stats = SET_NETDEVOP(ops->ndo_get_stats);
> #undef SET_NETDEVOP
> }
> EXPORT_SYMBOL(netdev_attach_ops);
>
> For newer kernels then this would just be:
>
> static inline void netdev_attach_ops(struct net_device *dev,
> const struct net_device_ops *ops)
> {
> dev->netdev_ops = ops;
> }
>
> Stephen, would the above be acceptable upstream on netdevice.h ? It
> would eliminate all needs from having to #ifdef network drivers when
> backporting. If so I can send a respective patch and spatch all the
> setters I think. An example of the nasty ifdef crap we have to do for
> the current backport of netdevop'able drivers is below.
>
No. supporting backporting is not part of the upstream kernel
mission. Honestly, we try for forward compatibility but intentionally
ignore carrying extra backport baggage.
^ permalink raw reply
* Re: [PATCH] compat-wireless: updates for orinoco
From: Luis R. Rodriguez @ 2010-05-05 0:18 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Luis Rodriguez, Hauke Mehrtens, David Miller,
linux-wireless@vger.kernel.org, mcgrof@kernel.org,
netdev@vger.kernel.org
In-Reply-To: <20100504170409.46914a88@nehalam>
On Tue, May 04, 2010 at 05:04:09PM -0700, Stephen Hemminger wrote:
> On Tue, 4 May 2010 16:26:53 -0700
> "Luis R. Rodriguez" <lrodriguez@atheros.com> wrote:
>
> > First of all, thanks a lot! Some comments below.
> >
> > On Tue, May 4, 2010 at 3:40 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> > > * Make all the patches apply again.
> > > * rename read_pda to avoid conflicts with definitions in kernel <= 2.6.29
> >
> > I'm going to apply these two changes, if you get time can you send a
> > patch to rename read_pda upstream as well, that way we don't have to
> > carry this?
> >
> > > * add orinoco usb
> >
> > Thanks for this but I've grown tired of updating these netdev ops and
> > I think we can do better. I'll add a netdev_attach_ops() which would
> > simply do all the backport stuff for us, this way for backporting
> > purposes all we have to do is replace the old lines with a
> > netdev_attach_ops() call. In fact if we *really* wanted to we could
> > add a dummy netdev_attach_ops() upstream and just backport that on
> > older kernels, this would mean 0 line changes to backport a newer
> > driver.
> >
> > Something like this maybe on the generic compat module, it builds for
> > me, will commit soon.
> >
> > /*
> > * Expand this as drivers require more ops, for now this
> > * only sets the ones we need.
> > */
> > void netdev_attach_ops(struct net_device *dev,
> > const struct net_device_ops *ops)
> > {
> > #define SET_NETDEVOP(_op) (_op ? _op : NULL)
> > dev->open = SET_NETDEVOP(ops->ndo_open);
> > dev->stop = SET_NETDEVOP(ops->ndo_stop);
> > dev->hard_start_xmit = SET_NETDEVOP(ops->ndo_start_xmit);
> > dev->set_multicast_list = SET_NETDEVOP(ops->ndo_set_multicast_list);
> > dev->change_mtu = SET_NETDEVOP(ops->ndo_change_mtu);
> > dev->set_mac_address = SET_NETDEVOP(ops->ndo_set_mac_address);
> > dev->tx_timeout = SET_NETDEVOP(ops->ndo_tx_timeout);
> > dev->get_stats = SET_NETDEVOP(ops->ndo_get_stats);
> > #undef SET_NETDEVOP
> > }
> > EXPORT_SYMBOL(netdev_attach_ops);
> >
> > For newer kernels then this would just be:
> >
> > static inline void netdev_attach_ops(struct net_device *dev,
> > const struct net_device_ops *ops)
> > {
> > dev->netdev_ops = ops;
> > }
> >
> > Stephen, would the above be acceptable upstream on netdevice.h ? It
> > would eliminate all needs from having to #ifdef network drivers when
> > backporting. If so I can send a respective patch and spatch all the
> > setters I think. An example of the nasty ifdef crap we have to do for
> > the current backport of netdevop'able drivers is below.
> >
>
> No. supporting backporting is not part of the upstream kernel
> mission. Honestly, we try for forward compatibility but intentionally
> ignore carrying extra backport baggage.
Sure, understood, just had to try :), if only I could find a *good*
non-backport reason to have the netdev_attach_ops()...
Luis
^ permalink raw reply
* Re: [PATCH] compat-wireless: updates for orinoco
From: Luis R. Rodriguez @ 2010-05-05 1:47 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Luis Rodriguez, Hauke Mehrtens, David Miller,
linux-wireless@vger.kernel.org, mcgrof@kernel.org,
netdev@vger.kernel.org
In-Reply-To: <20100505001830.GO2624@tux>
On Tue, May 4, 2010 at 5:18 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Tue, May 04, 2010 at 05:04:09PM -0700, Stephen Hemminger wrote:
>> On Tue, 4 May 2010 16:26:53 -0700
>> "Luis R. Rodriguez" <lrodriguez@atheros.com> wrote:
>>
>> > First of all, thanks a lot! Some comments below.
>> >
>> > On Tue, May 4, 2010 at 3:40 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>> > > * Make all the patches apply again.
>> > > * rename read_pda to avoid conflicts with definitions in kernel <= 2.6.29
>> >
>> > I'm going to apply these two changes, if you get time can you send a
>> > patch to rename read_pda upstream as well, that way we don't have to
>> > carry this?
>> >
>> > > * add orinoco usb
>> >
>> > Thanks for this but I've grown tired of updating these netdev ops and
>> > I think we can do better. I'll add a netdev_attach_ops() which would
>> > simply do all the backport stuff for us, this way for backporting
>> > purposes all we have to do is replace the old lines with a
>> > netdev_attach_ops() call. In fact if we *really* wanted to we could
>> > add a dummy netdev_attach_ops() upstream and just backport that on
>> > older kernels, this would mean 0 line changes to backport a newer
>> > driver.
>> >
>> > Something like this maybe on the generic compat module, it builds for
>> > me, will commit soon.
>> >
>> > /*
>> > * Expand this as drivers require more ops, for now this
>> > * only sets the ones we need.
>> > */
>> > void netdev_attach_ops(struct net_device *dev,
>> > const struct net_device_ops *ops)
>> > {
>> > #define SET_NETDEVOP(_op) (_op ? _op : NULL)
>> > dev->open = SET_NETDEVOP(ops->ndo_open);
>> > dev->stop = SET_NETDEVOP(ops->ndo_stop);
>> > dev->hard_start_xmit = SET_NETDEVOP(ops->ndo_start_xmit);
>> > dev->set_multicast_list = SET_NETDEVOP(ops->ndo_set_multicast_list);
>> > dev->change_mtu = SET_NETDEVOP(ops->ndo_change_mtu);
>> > dev->set_mac_address = SET_NETDEVOP(ops->ndo_set_mac_address);
>> > dev->tx_timeout = SET_NETDEVOP(ops->ndo_tx_timeout);
>> > dev->get_stats = SET_NETDEVOP(ops->ndo_get_stats);
>> > #undef SET_NETDEVOP
>> > }
>> > EXPORT_SYMBOL(netdev_attach_ops);
>> >
>> > For newer kernels then this would just be:
>> >
>> > static inline void netdev_attach_ops(struct net_device *dev,
>> > const struct net_device_ops *ops)
>> > {
>> > dev->netdev_ops = ops;
>> > }
>> >
>> > Stephen, would the above be acceptable upstream on netdevice.h ? It
>> > would eliminate all needs from having to #ifdef network drivers when
>> > backporting. If so I can send a respective patch and spatch all the
>> > setters I think. An example of the nasty ifdef crap we have to do for
>> > the current backport of netdevop'able drivers is below.
>> >
>>
>> No. supporting backporting is not part of the upstream kernel
>> mission. Honestly, we try for forward compatibility but intentionally
>> ignore carrying extra backport baggage.
>
> Sure, understood, just had to try :), if only I could find a *good*
> non-backport reason to have the netdev_attach_ops()...
FWIW, it helped a lot, porting an Ethernet driver for example consists
of a 1 line change to the driver, this goes down to 2.6.21 even. With
a netdev_attach_ops() upstream this would require 0 lines of code
changes. But --- I understand, I'll try to find a real value for it on
existing kernels.
patches/01-netdev.patch | 625 ++++++-----------------------------------------
1 files changed, 75 insertions(+), 550 deletions(-)
Luis
^ permalink raw reply
* Re: [PATCH] ath9k: fix another source of corrupt frames
From: Luis R. Rodriguez @ 2010-05-05 5:25 UTC (permalink / raw)
To: Felix Fietkau; +Cc: Luis Rodriguez, linux-wireless, John W. Linville
In-Reply-To: <20100504195500.GH2624@tux>
On Tue, May 4, 2010 at 12:55 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> ath9k_rx_accept
So this guys is called only within ath9k_cmn_rx_skb_preprocess() and
that is only called by ath9k.. so yeah ath9k_htc no longer uses this
stuff. The patch is fine, please do merge John.
Luis
^ permalink raw reply
* Re: [PATCH] cfg80211: Check for channel HT capabilities in an IBSS
From: Benoit Papillault @ 2010-05-05 6:28 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: johannes, linux-wireless
In-Reply-To: <o2h43e72e891005041114sb04fbfcbl7e1f144826a02479@mail.gmail.com>
Le 04/05/2010 20:14, Luis R. Rodriguez a écrit :
> On Mon, May 3, 2010 at 11:47 PM, Benoit Papillault
> <benoit.papillault@free.fr> wrote:
>> When configuring an HT IBSS, we need to check if the specified channel
>> is capable of ht40+, ht40- or ht20.
>>
>> Signed-off-by: Benoit Papillault<benoit.papillault@free.fr>
>> ---
>> net/wireless/nl80211.c | 8 ++++----
>> 1 files changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
>> index 8da9823..0a82623 100644
>> --- a/net/wireless/nl80211.c
>> +++ b/net/wireless/nl80211.c
>> @@ -3858,11 +3858,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
>> ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
>> }
>>
>> - ibss.channel = ieee80211_get_channel(wiphy,
>> - nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
>> + ibss.channel = rdev_freq_to_chan(rdev,
>> + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
>> + channel_type);
>> if (!ibss.channel ||
>> - ibss.channel->flags& IEEE80211_CHAN_NO_IBSS ||
>> - ibss.channel->flags& IEEE80211_CHAN_DISABLED) {
>> + ibss.channel->flags& IEEE80211_CHAN_NO_IBSS) {
>> err = -EINVAL;
>
> Why is the disabled channel check being removed here?
>
> Luis
>
Hi Luis,
It's because the check is already done in rdev_freq_to_chan.
Regards,
Benoit
^ permalink raw reply
* Re: [PATCH] cfg80211: Check for channel HT capabilities in an IBSS
From: Benoit Papillault @ 2010-05-05 6:29 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1272961391.3673.3.camel@jlt3.sipsolutions.net>
Le 04/05/2010 10:23, Johannes Berg a écrit :
> On Tue, 2010-05-04 at 08:47 +0200, Benoit Papillault wrote:
>> When configuring an HT IBSS, we need to check if the specified channel
>> is capable of ht40+, ht40- or ht20.
>
> These first two patches cannot be separate.
>
> johannes
>
>
Right. Will repost a single patch including both.
Regards,
Benoit
^ permalink raw reply
* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
From: Benoit Papillault @ 2010-05-05 6:37 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1272961608.3673.7.camel@jlt3.sipsolutions.net>
Le 04/05/2010 10:26, Johannes Berg a écrit :
>
>> @@ -118,7 +119,10 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
>> *pos++ = basic | (u8) (rate / 5);
>> }
>>
>> - /* Build IBSS probe response */
>> + /*
>> + * Build IBSS probe response template (also used for beacon template
>> + * in ieee80211_beacon_get_tim())
>> + */
>
> That change is wrong -- no way beacon code can call into IBSS code.
I meant the skb that is produced here and stored in ifibss->presp is
then used both for sending beacons in ieee80211_beacon_get_tim and for
sending probe response in ieee80211_rx_mgmt_probe_req
>
> I think you meant to say "I need to create a common helper function that
> I call here and in the beacon code."
You are right : I will add a helper function to create HT Capability IE.
>
>> --- a/net/mac80211/util.c
>> +++ b/net/mac80211/util.c
>> @@ -967,7 +967,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
>>
>> if (sband->ht_cap.ht_supported) {
>> u16 cap = sband->ht_cap.cap;
>> - __le16 tmp;
>> + struct ieee80211_ht_cap ht_cap;
>>
>> if (ieee80211_disable_40mhz_24ghz&&
>> sband->band == IEEE80211_BAND_2GHZ) {
>> @@ -975,18 +975,19 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
>> cap&= ~IEEE80211_HT_CAP_SGI_40;
>> }
>>
>> + ht_cap.cap_info = cpu_to_le16(cap);
>> + ht_cap.ampdu_params_info = sband->ht_cap.ampdu_factor |
>> + (sband->ht_cap.ampdu_density<<
>> + IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
>> + ht_cap.mcs = sband->ht_cap.mcs;
>> + ht_cap.extended_ht_cap_info = cpu_to_le16(0);
>> + ht_cap.tx_BF_cap_info = cpu_to_le32(0);
>> + ht_cap.antenna_selection_info = 0;
>> +
>> *pos++ = WLAN_EID_HT_CAPABILITY;
>> *pos++ = sizeof(struct ieee80211_ht_cap);
>> - memset(pos, 0, sizeof(struct ieee80211_ht_cap));
>> - tmp = cpu_to_le16(cap);
>> - memcpy(pos,&tmp, sizeof(u16));
>> - pos += sizeof(u16);
>> - *pos++ = sband->ht_cap.ampdu_factor |
>> - (sband->ht_cap.ampdu_density<<
>> - IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
>> - memcpy(pos,&sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
>> - pos += sizeof(sband->ht_cap.mcs);
>> - pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
>> + memcpy(pos,&ht_cap, sizeof(struct ieee80211_ht_cap));
>> + pos += sizeof(struct ieee80211_ht_cap);
>
> And this is an unrelated change that doesn't belong into this patch at
> all.
>
> johannes
>
>
Regards,
Benoit
^ permalink raw reply
* Re: [PATCH] compat-wireless: updates for orinoco
From: Johannes Berg @ 2010-05-05 6:45 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: Hauke Mehrtens, linux-wireless
In-Reply-To: <v2u43e72e891005041626n14deaca5z284f2472e909c923@mail.gmail.com>
On Tue, 2010-05-04 at 16:26 -0700, Luis R. Rodriguez wrote:
> void netdev_attach_ops(struct net_device *dev,
> const struct net_device_ops *ops)
> {
> #define SET_NETDEVOP(_op) (_op ? _op : NULL)
isn't that like the dumbest macro ever?
johannes
^ permalink raw reply
* [PATCH] mac80211: fix BSS info reconfiguration
From: Johannes Berg @ 2010-05-05 7:44 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Reinette Chatre
When reconfiguring an interface due to a previous
hardware restart, mac80211 will currently include
the new IBSS flag on non-IBSS interfaces which may
confuse drivers.
Instead of doing the ~0 trick, simply spell out
which things are going to be reconfigured.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/mac80211.h | 2 ++
net/mac80211/util.c | 25 ++++++++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
--- wireless-testing.orig/include/net/mac80211.h 2010-05-01 08:47:54.000000000 +0200
+++ wireless-testing/include/net/mac80211.h 2010-05-05 09:41:46.000000000 +0200
@@ -160,6 +160,8 @@ enum ieee80211_bss_change {
BSS_CHANGED_BEACON_ENABLED = 1<<9,
BSS_CHANGED_CQM = 1<<10,
BSS_CHANGED_IBSS = 1<<11,
+
+ /* when adding here, make sure to change ieee80211_reconfig */
};
/**
--- wireless-testing.orig/net/mac80211/util.c 2010-04-09 11:46:46.000000000 +0200
+++ wireless-testing/net/mac80211/util.c 2010-05-05 09:41:46.000000000 +0200
@@ -1160,18 +1160,33 @@ int ieee80211_reconfig(struct ieee80211_
/* Finally also reconfigure all the BSS information */
list_for_each_entry(sdata, &local->interfaces, list) {
- u32 changed = ~0;
+ u32 changed;
+
if (!ieee80211_sdata_running(sdata))
continue;
+
+ /* common change flags for all interface types */
+ changed = BSS_CHANGED_ERP_CTS_PROT |
+ BSS_CHANGED_ERP_PREAMBLE |
+ BSS_CHANGED_ERP_SLOT |
+ BSS_CHANGED_HT |
+ BSS_CHANGED_BASIC_RATES |
+ BSS_CHANGED_BEACON_INT |
+ BSS_CHANGED_BSSID |
+ BSS_CHANGED_CQM;
+
switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
- /* disable beacon change bits */
- changed &= ~(BSS_CHANGED_BEACON |
- BSS_CHANGED_BEACON_ENABLED);
- /* fall through */
+ changed |= BSS_CHANGED_ASSOC;
+ ieee80211_bss_info_change_notify(sdata, changed);
+ break;
case NL80211_IFTYPE_ADHOC:
+ changed |= BSS_CHANGED_IBSS;
+ /* fall through */
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
+ changed |= BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_ENABLED;
ieee80211_bss_info_change_notify(sdata, changed);
break;
case NL80211_IFTYPE_WDS:
^ permalink raw reply
* Re: [PATCH] mac80211: fix BSS info reconfiguration
From: Johannes Berg @ 2010-05-05 7:47 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Reinette Chatre
In-Reply-To: <1273045442.3728.1.camel@jlt3.sipsolutions.net>
On Wed, 2010-05-05 at 09:44 +0200, Johannes Berg wrote:
> When reconfiguring an interface due to a previous
> hardware restart, mac80211 will currently include
> the new IBSS flag on non-IBSS interfaces which may
> confuse drivers.
>
> Instead of doing the ~0 trick, simply spell out
> which things are going to be reconfigured.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Oops, that might get confusing.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
though I'm still me either way I think.
> ---
> include/net/mac80211.h | 2 ++
> net/mac80211/util.c | 25 ++++++++++++++++++++-----
> 2 files changed, 22 insertions(+), 5 deletions(-)
>
> --- wireless-testing.orig/include/net/mac80211.h 2010-05-01 08:47:54.000000000 +0200
> +++ wireless-testing/include/net/mac80211.h 2010-05-05 09:41:46.000000000 +0200
> @@ -160,6 +160,8 @@ enum ieee80211_bss_change {
> BSS_CHANGED_BEACON_ENABLED = 1<<9,
> BSS_CHANGED_CQM = 1<<10,
> BSS_CHANGED_IBSS = 1<<11,
> +
> + /* when adding here, make sure to change ieee80211_reconfig */
> };
>
> /**
> --- wireless-testing.orig/net/mac80211/util.c 2010-04-09 11:46:46.000000000 +0200
> +++ wireless-testing/net/mac80211/util.c 2010-05-05 09:41:46.000000000 +0200
> @@ -1160,18 +1160,33 @@ int ieee80211_reconfig(struct ieee80211_
>
> /* Finally also reconfigure all the BSS information */
> list_for_each_entry(sdata, &local->interfaces, list) {
> - u32 changed = ~0;
> + u32 changed;
> +
> if (!ieee80211_sdata_running(sdata))
> continue;
> +
> + /* common change flags for all interface types */
> + changed = BSS_CHANGED_ERP_CTS_PROT |
> + BSS_CHANGED_ERP_PREAMBLE |
> + BSS_CHANGED_ERP_SLOT |
> + BSS_CHANGED_HT |
> + BSS_CHANGED_BASIC_RATES |
> + BSS_CHANGED_BEACON_INT |
> + BSS_CHANGED_BSSID |
> + BSS_CHANGED_CQM;
> +
> switch (sdata->vif.type) {
> case NL80211_IFTYPE_STATION:
> - /* disable beacon change bits */
> - changed &= ~(BSS_CHANGED_BEACON |
> - BSS_CHANGED_BEACON_ENABLED);
> - /* fall through */
> + changed |= BSS_CHANGED_ASSOC;
> + ieee80211_bss_info_change_notify(sdata, changed);
> + break;
> case NL80211_IFTYPE_ADHOC:
> + changed |= BSS_CHANGED_IBSS;
> + /* fall through */
> case NL80211_IFTYPE_AP:
> case NL80211_IFTYPE_MESH_POINT:
> + changed |= BSS_CHANGED_BEACON |
> + BSS_CHANGED_BEACON_ENABLED;
> ieee80211_bss_info_change_notify(sdata, changed);
> break;
> case NL80211_IFTYPE_WDS:
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH] compat-wireless: rt2x00 added to driver-select
From: Walter Goldens @ 2010-05-05 9:44 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, users
Signed-off-by: Walter Goldens <goldenstranger@yahoo.com>
---
With the ever expanding and improving rt2x00 supporting myriad of devices, I think its about time we enabled faster compilation via scripts/driver-select.
--- a/scripts/driver-select 2010-05-05 12:02:23.000000000 +0300
+++ b/scripts/driver-select 2010-05-05 12:02:01.000000000 +0300
@@ -7,6 +7,7 @@
DRIVERS_MAKEFILE="drivers/net/wireless/Makefile"
ATH_MAKEFILE="drivers/net/wireless/ath/Makefile"
ATH9K_MAKEFILE="drivers/net/wireless/ath/ath9k/Makefile"
+RT2X00_MAKEFILE="drivers/net/wireless/rt2x00/Makefile"
NET_WIRELESS_MAKEFILE="net/wireless/Makefile"
EEPROM_MAKEFILE="drivers/misc/eeprom/Makefile"
DRIVERS_NET="drivers/net/Makefile"
@@ -29,7 +30,7 @@ PURPLE="\033[35m"
CYAN="\033[36m"
UNDERLINE="\033[02m"
-SUPPORTED_DRIVERS="ath5k ath9k ath9k_htc ar9170 b43 zd1211rw"
+SUPPORTED_DRIVERS="ath5k ath9k ath9k_htc ar9170 b43 zd1211rw rt2x00"
function usage {
echo -e "${GREEN}Usage${NORMAL}: ${CYAN}$0${NORMAL} [ ${PURPLE}<driver-name>${NORMAL} | ${PURPLE}<driver-group-name>${NORMAL} | ${GREEN}restore${NORMAL} ]"
@@ -293,6 +294,10 @@ case $1 in
disable_var_03
select_driver CONFIG_B43
;;
+ rt2x00)
+ select_driver CONFIG_RT2X00
+ disable_var_02
+ ;;
*)
echo "Unsupported driver"
exit
^ permalink raw reply
* 2.6.33.2: Turn tx power off/on for Atheros card
From: Yegor Yefremov @ 2010-05-05 10:26 UTC (permalink / raw)
To: linux-wireless
I'm using kernel 2.6.33.2 with AR2413 WLAN card. Issuing
iwconfig wlan0 txpower off
turns txpower off. I can see this status by iwconfig wlan0 and the
communication with AP terminates. But when I turn the txpower on
iwconfig wlan0 txpower on
nothing happens. Though iwconfig shows the previous tx power value.
Only ifconfig wlan0 down and then up recovers the transmission.
Is it a known bug or I'm doing something wrong?
Regards,
Yegor
^ permalink raw reply
* [PATCH] cfg80211/mac80211: better channel handling
From: Johannes Berg @ 2010-05-05 10:36 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Currently (all tested with hwsim) you can do stupid
things like setting up an AP on a certain channel,
then adding another virtual interface and making
that associate on another channel -- this will make
the beaconing to move channel but obviously without
the necessary IEs data update.
In order to improve this situation, first make the
configuration APIs (cfg80211 and nl80211) aware of
multi-channel operation -- we'll eventually need
that in the future anyway. There's one userland API
change and one API addition. The API change is that
now SET_WIPHY must be called with virtual interface
index rather than only wiphy index in order to take
effect for that interface -- luckily all current
users (hostapd) do that. For monitor interfaces, the
old setting is preserved, but monitors are always
slaved to other devices anyway so no guarantees.
The second userland API change is the introduction
of a per virtual interface SET_CHANNEL command, that
hostapd should use going forward to make it easier
to understand what's going on (it can automatically
detect a kernel with this command).
Other than mac80211, no existing cfg80211 drivers
are affected by this change because they only allow
a single virtual interface.
mac80211, however, now needs to be aware that the
channel settings are per interface now, and needs
to disallow (for now) real multi-channel operation,
which is another important part of this patch.
One of the immediate benefits is that you can now
start hostapd to operate on a hardware that already
has a connection on another virtual interface, as
long as you specify the same channel.
Note that two things are left unhandled (this is an
improvement -- not a complete fix):
* different HT/no-HT modes
currently you could start an HT AP and then
connect to a non-HT network on the same channel
which would configure the hardware for no HT;
that can be fixed fairly easily
* CSA
An AP we're connected to on a virtual interface
might indicate switching channels, and in that
case we would follow it, regardless of how many
other interfaces are operating; this requires
more effort to fix but is pretty rare after all
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/libertas/cfg.c | 1
drivers/net/wireless/orinoco/cfg.c | 1
drivers/net/wireless/rndis_wlan.c | 4
include/linux/nl80211.h | 13 ++
include/net/cfg80211.h | 11 +-
net/mac80211/Makefile | 3
net/mac80211/cfg.c | 41 +++++++++
net/mac80211/chan.c | 57 ++++++++++++
net/mac80211/ieee80211_i.h | 11 ++
net/wireless/chan.c | 56 +++---------
net/wireless/core.h | 12 --
net/wireless/ibss.c | 5 -
net/wireless/nl80211.c | 164 +++++++++++++++++++++++++++---------
net/wireless/sme.c | 5 -
net/wireless/wext-compat.c | 15 ++-
net/wireless/wext-sme.c | 2
16 files changed, 292 insertions(+), 109 deletions(-)
--- wireless-testing.orig/include/linux/nl80211.h 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h 2010-05-02 17:47:51.000000000 +0200
@@ -52,6 +52,8 @@
* %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
* %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
* and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
+ * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
+ * instead, the support here is for backward compatibility only.
* @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
* or rename notification. Has attributes %NL80211_ATTR_WIPHY and
* %NL80211_ATTR_WIPHY_NAME.
@@ -329,6 +331,15 @@
* @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This
* command is used as an event to indicate the that a trigger level was
* reached.
+ * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
+ * and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed
+ * by %NL80211_ATTR_IFINDEX) shall operate on.
+ * In case multiple channels are supported by the device, the mechanism
+ * with which it switches channels is implementation-defined.
+ * When a monitor interface is given, it can only switch channel while
+ * no other interfaces are operating to avoid disturbing the operation
+ * of any other interfaces, and other interfaces will again take
+ * precedence when they are used.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
@@ -428,6 +439,8 @@ enum nl80211_commands {
NL80211_CMD_SET_CQM,
NL80211_CMD_NOTIFY_CQM,
+ NL80211_CMD_SET_CHANNEL,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- wireless-testing.orig/net/wireless/nl80211.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c 2010-05-03 08:55:32.000000000 +0200
@@ -589,6 +589,7 @@ static int nl80211_send_wiphy(struct sk_
i++;
NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
}
+ CMD(set_channel, SET_CHANNEL);
#undef CMD
@@ -689,10 +690,90 @@ static int parse_txq_params(struct nlatt
return 0;
}
+static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
+{
+ /*
+ * You can only set the channel explicitly for AP, mesh
+ * and WDS type interfaces; all others have their channel
+ * managed via their respective "establish a connection"
+ * command (connect, join, ...)
+ *
+ * Monitors are special as they are normally slaved to
+ * whatever else is going on, so they behave as though
+ * you tried setting the wiphy channel itself.
+ */
+ return !wdev ||
+ wdev->iftype == NL80211_IFTYPE_AP ||
+ wdev->iftype == NL80211_IFTYPE_WDS ||
+ wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
+ wdev->iftype == NL80211_IFTYPE_MONITOR;
+}
+
+static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ struct genl_info *info)
+{
+ enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+ u32 freq;
+ int result;
+
+ if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
+ return -EINVAL;
+
+ if (!nl80211_can_set_dev_channel(wdev))
+ return -EOPNOTSUPP;
+
+ if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+ channel_type = nla_get_u32(info->attrs[
+ NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+ if (channel_type != NL80211_CHAN_NO_HT &&
+ channel_type != NL80211_CHAN_HT20 &&
+ channel_type != NL80211_CHAN_HT40PLUS &&
+ channel_type != NL80211_CHAN_HT40MINUS)
+ return -EINVAL;
+ }
+
+ freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
+
+ mutex_lock(&rdev->devlist_mtx);
+ if (wdev) {
+ wdev_lock(wdev);
+ result = cfg80211_set_freq(rdev, wdev, freq, channel_type);
+ wdev_unlock(wdev);
+ } else {
+ result = cfg80211_set_freq(rdev, NULL, freq, channel_type);
+ }
+ mutex_unlock(&rdev->devlist_mtx);
+
+ return result;
+}
+
+static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev;
+ struct net_device *netdev;
+ int result;
+
+ rtnl_lock();
+
+ result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev);
+ if (result)
+ goto unlock;
+
+ result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
+
+ unlock:
+ rtnl_unlock();
+
+ return result;
+}
+
static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev;
- int result = 0, rem_txq_params = 0;
+ struct net_device *netdev;
+ struct wireless_dev *wdev;
+ int result, rem_txq_params = 0;
struct nlattr *nl_txq_params;
u32 changed;
u8 retry_short = 0, retry_long = 0;
@@ -701,16 +782,41 @@ static int nl80211_set_wiphy(struct sk_b
rtnl_lock();
+ /*
+ * Try to find the wiphy and netdev. Normally this
+ * function shouldn't need the netdev, but this is
+ * done for backward compatibility -- previously
+ * setting the channel was done per wiphy, but now
+ * it is per netdev. Previous userland like hostapd
+ * also passed a netdev to set_wiphy, so that it is
+ * possible to let that go to the right netdev!
+ */
+ result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev);
+
mutex_lock(&cfg80211_mutex);
+ if (result) {
+ rdev = __cfg80211_rdev_from_info(info);
+ if (IS_ERR(rdev)) {
+ mutex_unlock(&cfg80211_mutex);
+ result = PTR_ERR(rdev);
+ goto unlock;
+ }
+ wdev = NULL;
+ netdev = NULL;
+ result = 0;
+
+ mutex_lock(&rdev->mtx);
+ } else if (netif_running(netdev) &&
+ nl80211_can_set_dev_channel(netdev->ieee80211_ptr))
+ wdev = netdev->ieee80211_ptr;
+ else
+ wdev = NULL;
- rdev = __cfg80211_rdev_from_info(info);
- if (IS_ERR(rdev)) {
- mutex_unlock(&cfg80211_mutex);
- result = PTR_ERR(rdev);
- goto unlock;
- }
+ /*
+ * end workaround code, by now the rdev is available
+ * and locked, and wdev may or may not be NULL
+ */
- mutex_lock(&rdev->mtx);
if (info->attrs[NL80211_ATTR_WIPHY_NAME])
result = cfg80211_dev_rename(
@@ -749,26 +855,7 @@ static int nl80211_set_wiphy(struct sk_b
}
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
- enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
- u32 freq;
-
- result = -EINVAL;
-
- if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
- channel_type = nla_get_u32(info->attrs[
- NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
- if (channel_type != NL80211_CHAN_NO_HT &&
- channel_type != NL80211_CHAN_HT20 &&
- channel_type != NL80211_CHAN_HT40PLUS &&
- channel_type != NL80211_CHAN_HT40MINUS)
- goto bad_res;
- }
-
- freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
-
- mutex_lock(&rdev->devlist_mtx);
- result = rdev_set_freq(rdev, NULL, freq, channel_type);
- mutex_unlock(&rdev->devlist_mtx);
+ result = __nl80211_set_channel(rdev, wdev, info);
if (result)
goto bad_res;
}
@@ -865,6 +952,8 @@ static int nl80211_set_wiphy(struct sk_b
bad_res:
mutex_unlock(&rdev->mtx);
+ if (netdev)
+ dev_put(netdev);
unlock:
rtnl_unlock();
return result;
@@ -3562,9 +3651,8 @@ static int nl80211_associate(struct sk_b
{
struct cfg80211_registered_device *rdev;
struct net_device *dev;
- struct wireless_dev *wdev;
struct cfg80211_crypto_settings crypto;
- struct ieee80211_channel *chan, *fixedchan;
+ struct ieee80211_channel *chan;
const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
int err, ssid_len, ie_len = 0;
bool use_mfp = false;
@@ -3607,16 +3695,6 @@ static int nl80211_associate(struct sk_b
goto out;
}
- mutex_lock(&rdev->devlist_mtx);
- wdev = dev->ieee80211_ptr;
- fixedchan = rdev_fixed_channel(rdev, wdev);
- if (fixedchan && chan != fixedchan) {
- err = -EBUSY;
- mutex_unlock(&rdev->devlist_mtx);
- goto out;
- }
- mutex_unlock(&rdev->devlist_mtx);
-
ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -5186,6 +5264,12 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
+ {
+ .cmd = NL80211_CMD_SET_CHANNEL,
+ .doit = nl80211_set_channel,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
--- wireless-testing.orig/include/net/cfg80211.h 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h 2010-05-02 17:47:51.000000000 +0200
@@ -966,7 +966,11 @@ struct cfg80211_pmksa {
*
* @set_txq_params: Set TX queue parameters
*
- * @set_channel: Set channel
+ * @set_channel: Set channel for a given wireless interface. Some devices
+ * may support multi-channel operation (by channel hopping) so cfg80211
+ * doesn't verify much. Note, however, that the passed netdev may be
+ * %NULL as well if the user requested changing the channel for the
+ * device itself, or for a monitor interface.
*
* @scan: Request to do a scan. If returning zero, the scan request is given
* the driver, and will be valid until passed to cfg80211_scan_done().
@@ -1095,7 +1099,7 @@ struct cfg80211_ops {
int (*set_txq_params)(struct wiphy *wiphy,
struct ieee80211_txq_params *params);
- int (*set_channel)(struct wiphy *wiphy,
+ int (*set_channel)(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type);
@@ -1461,6 +1465,8 @@ struct cfg80211_cached_keys;
* @list: (private) Used to collect the interfaces
* @netdev: (private) Used to reference back to the netdev
* @current_bss: (private) Used by the internal configuration code
+ * @channel: (private) Used by the internal configuration code to track
+ * user-set AP, monitor and WDS channels for wireless extensions
* @bssid: (private) Used by the internal configuration code
* @ssid: (private) Used by the internal configuration code
* @ssid_len: (private) Used by the internal configuration code
@@ -1507,6 +1513,7 @@ struct wireless_dev {
struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
struct cfg80211_internal_bss *current_bss; /* associated / joined */
+ struct ieee80211_channel *channel;
bool ps;
int ps_timeout;
--- wireless-testing.orig/net/wireless/chan.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/chan.c 2010-05-02 17:47:51.000000000 +0200
@@ -10,38 +10,6 @@
#include "core.h"
struct ieee80211_channel *
-rdev_fixed_channel(struct cfg80211_registered_device *rdev,
- struct wireless_dev *for_wdev)
-{
- struct wireless_dev *wdev;
- struct ieee80211_channel *result = NULL;
-
- WARN_ON(!mutex_is_locked(&rdev->devlist_mtx));
-
- list_for_each_entry(wdev, &rdev->netdev_list, list) {
- if (wdev == for_wdev)
- continue;
-
- /*
- * Lock manually to tell lockdep about allowed
- * nesting here if for_wdev->mtx is held already.
- * This is ok as it's all under the rdev devlist
- * mutex and as such can only be done once at any
- * given time.
- */
- mutex_lock_nested(&wdev->mtx, SINGLE_DEPTH_NESTING);
- if (wdev->current_bss)
- result = wdev->current_bss->pub.channel;
- wdev_unlock(wdev);
-
- if (result)
- break;
- }
-
- return result;
-}
-
-struct ieee80211_channel *
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
int freq, enum nl80211_channel_type channel_type)
{
@@ -75,15 +43,22 @@ rdev_freq_to_chan(struct cfg80211_regist
return chan;
}
-int rdev_set_freq(struct cfg80211_registered_device *rdev,
- struct wireless_dev *for_wdev,
- int freq, enum nl80211_channel_type channel_type)
+int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev, int freq,
+ enum nl80211_channel_type channel_type)
{
struct ieee80211_channel *chan;
int result;
- if (rdev_fixed_channel(rdev, for_wdev))
- return -EBUSY;
+ if (wdev->iftype == NL80211_IFTYPE_MONITOR)
+ wdev = NULL;
+
+ if (wdev) {
+ ASSERT_WDEV_LOCK(wdev);
+
+ if (!netif_running(wdev->netdev))
+ return -ENETDOWN;
+ }
if (!rdev->ops->set_channel)
return -EOPNOTSUPP;
@@ -92,11 +67,14 @@ int rdev_set_freq(struct cfg80211_regist
if (!chan)
return -EINVAL;
- result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type);
+ result = rdev->ops->set_channel(&rdev->wiphy,
+ wdev ? wdev->netdev : NULL,
+ chan, channel_type);
if (result)
return result;
- rdev->channel = chan;
+ if (wdev)
+ wdev->channel = chan;
return 0;
}
--- wireless-testing.orig/net/wireless/core.h 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/core.h 2010-05-02 17:47:51.000000000 +0200
@@ -70,9 +70,6 @@ struct cfg80211_registered_device {
struct work_struct conn_work;
struct work_struct event_work;
- /* current channel */
- struct ieee80211_channel *channel;
-
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -388,14 +385,11 @@ int cfg80211_change_iface(struct cfg8021
void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
struct ieee80211_channel *
-rdev_fixed_channel(struct cfg80211_registered_device *rdev,
- struct wireless_dev *for_wdev);
-struct ieee80211_channel *
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
int freq, enum nl80211_channel_type channel_type);
-int rdev_set_freq(struct cfg80211_registered_device *rdev,
- struct wireless_dev *for_wdev,
- int freq, enum nl80211_channel_type channel_type);
+int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev, int freq,
+ enum nl80211_channel_type channel_type);
u16 cfg80211_calculate_bitrate(struct rate_info *rate);
--- wireless-testing.orig/net/wireless/wext-compat.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c 2010-05-02 17:47:51.000000000 +0200
@@ -782,16 +782,22 @@ int cfg80211_wext_siwfreq(struct net_dev
return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
case NL80211_IFTYPE_ADHOC:
return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
- default:
+ case NL80211_IFTYPE_MONITOR:
+ case NL80211_IFTYPE_WDS:
+ case NL80211_IFTYPE_MESH_POINT:
freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
if (freq < 0)
return freq;
if (freq == 0)
return -EINVAL;
+ wdev_lock(wdev);
mutex_lock(&rdev->devlist_mtx);
- err = rdev_set_freq(rdev, NULL, freq, NL80211_CHAN_NO_HT);
+ err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
mutex_unlock(&rdev->devlist_mtx);
+ wdev_unlock(wdev);
return err;
+ default:
+ return -EOPNOTSUPP;
}
}
EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
@@ -801,7 +807,6 @@ int cfg80211_wext_giwfreq(struct net_dev
struct iw_freq *freq, char *extra)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
switch (wdev->iftype) {
case NL80211_IFTYPE_STATION:
@@ -809,9 +814,9 @@ int cfg80211_wext_giwfreq(struct net_dev
case NL80211_IFTYPE_ADHOC:
return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
default:
- if (!rdev->channel)
+ if (!wdev->channel)
return -EINVAL;
- freq->m = rdev->channel->center_freq;
+ freq->m = wdev->channel->center_freq;
freq->e = 6;
return 0;
}
--- wireless-testing.orig/net/wireless/wext-sme.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c 2010-05-02 17:47:51.000000000 +0200
@@ -108,7 +108,7 @@ int cfg80211_mgd_wext_siwfreq(struct net
/* SSID is not set, we just want to switch channel */
if (chan && !wdev->wext.connect.ssid_len) {
- err = rdev_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
+ err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
goto out;
}
--- wireless-testing.orig/net/wireless/ibss.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c 2010-05-02 17:47:51.000000000 +0200
@@ -81,15 +81,10 @@ int __cfg80211_join_ibss(struct cfg80211
struct cfg80211_cached_keys *connkeys)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct ieee80211_channel *chan;
int err;
ASSERT_WDEV_LOCK(wdev);
- chan = rdev_fixed_channel(rdev, wdev);
- if (chan && chan != params->channel)
- return -EBUSY;
-
if (wdev->ssid_len)
return -EALREADY;
--- wireless-testing.orig/net/wireless/sme.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/wireless/sme.c 2010-05-02 17:47:51.000000000 +0200
@@ -741,7 +741,6 @@ int __cfg80211_connect(struct cfg80211_r
const u8 *prev_bssid)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct ieee80211_channel *chan;
struct cfg80211_bss *bss = NULL;
int err;
@@ -750,10 +749,6 @@ int __cfg80211_connect(struct cfg80211_r
if (wdev->sme_state != CFG80211_SME_IDLE)
return -EALREADY;
- chan = rdev_fixed_channel(rdev, wdev);
- if (chan && chan != connect->channel)
- return -EBUSY;
-
if (WARN_ON(wdev->connect_keys)) {
kfree(wdev->connect_keys);
wdev->connect_keys = NULL;
--- wireless-testing.orig/drivers/net/wireless/libertas/cfg.c 2010-05-02 17:47:48.000000000 +0200
+++ wireless-testing/drivers/net/wireless/libertas/cfg.c 2010-05-02 17:47:51.000000000 +0200
@@ -79,6 +79,7 @@ static const u32 cipher_suites[] = {
static int lbs_cfg_set_channel(struct wiphy *wiphy,
+ struct net_device *netdev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
--- wireless-testing.orig/drivers/net/wireless/orinoco/cfg.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/drivers/net/wireless/orinoco/cfg.c 2010-05-02 17:47:51.000000000 +0200
@@ -159,6 +159,7 @@ static int orinoco_scan(struct wiphy *wi
}
static int orinoco_set_channel(struct wiphy *wiphy,
+ struct net_device *netdev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
--- wireless-testing.orig/drivers/net/wireless/rndis_wlan.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/drivers/net/wireless/rndis_wlan.c 2010-05-02 17:47:51.000000000 +0200
@@ -535,7 +535,7 @@ static int rndis_join_ibss(struct wiphy
static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
-static int rndis_set_channel(struct wiphy *wiphy,
+static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
@@ -2291,7 +2291,7 @@ static int rndis_leave_ibss(struct wiphy
return deauthenticate(usbdev);
}
-static int rndis_set_channel(struct wiphy *wiphy,
+static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
--- wireless-testing.orig/net/mac80211/cfg.c 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c 2010-05-02 17:47:51.000000000 +0200
@@ -1162,11 +1162,24 @@ static int ieee80211_set_txq_params(stru
}
static int ieee80211_set_channel(struct wiphy *wiphy,
+ struct net_device *netdev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
+ switch (ieee80211_get_channel_mode(local, NULL)) {
+ case CHAN_MODE_HOPPING:
+ return -EBUSY;
+ case CHAN_MODE_FIXED:
+ if (local->oper_channel == chan &&
+ local->oper_channel_type == channel_type)
+ return 0;
+ return -EBUSY;
+ case CHAN_MODE_UNDEFINED:
+ break;
+ }
+
local->oper_channel = chan;
local->oper_channel_type = channel_type;
@@ -1214,6 +1227,20 @@ static int ieee80211_auth(struct wiphy *
static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_assoc_request *req)
{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ switch (ieee80211_get_channel_mode(local, sdata)) {
+ case CHAN_MODE_HOPPING:
+ return -EBUSY;
+ case CHAN_MODE_FIXED:
+ if (local->oper_channel == req->bss->channel)
+ break;
+ return -EBUSY;
+ case CHAN_MODE_UNDEFINED:
+ break;
+ }
+
return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
}
@@ -1236,8 +1263,22 @@ static int ieee80211_disassoc(struct wip
static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ibss_params *params)
{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ switch (ieee80211_get_channel_mode(local, sdata)) {
+ case CHAN_MODE_HOPPING:
+ return -EBUSY;
+ case CHAN_MODE_FIXED:
+ if (!params->channel_fixed)
+ return -EBUSY;
+ if (local->oper_channel == params->channel)
+ break;
+ return -EBUSY;
+ case CHAN_MODE_UNDEFINED:
+ break;
+ }
+
return ieee80211_ibss_join(sdata, params);
}
--- wireless-testing.orig/net/mac80211/Makefile 2010-05-02 17:47:47.000000000 +0200
+++ wireless-testing/net/mac80211/Makefile 2010-05-02 17:47:51.000000000 +0200
@@ -23,7 +23,8 @@ mac80211-y := \
key.o \
util.o \
wme.o \
- event.o
+ event.o \
+ chan.o
mac80211-$(CONFIG_MAC80211_LEDS) += led.o
mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/mac80211/chan.c 2010-05-02 17:47:51.000000000 +0200
@@ -0,0 +1,57 @@
+/*
+ * mac80211 - channel management
+ */
+
+#include "ieee80211_i.h"
+
+enum ieee80211_chan_mode
+__ieee80211_get_channel_mode(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *ignore)
+{
+ struct ieee80211_sub_if_data *sdata;
+
+ WARN_ON(!mutex_is_locked(&local->iflist_mtx));
+
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata == ignore)
+ continue;
+
+ if (!ieee80211_sdata_running(sdata))
+ continue;
+
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+ continue;
+
+ if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+ !sdata->u.mgd.associated)
+ continue;
+
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (!sdata->u.ibss.ssid_len)
+ continue;
+ if (!sdata->u.ibss.fixed_channel)
+ return CHAN_MODE_HOPPING;
+ }
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP &&
+ !sdata->u.ap.beacon)
+ continue;
+
+ return CHAN_MODE_FIXED;
+ }
+
+ return CHAN_MODE_UNDEFINED;
+}
+
+enum ieee80211_chan_mode
+ieee80211_get_channel_mode(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *ignore)
+{
+ enum ieee80211_chan_mode mode;
+
+ mutex_lock(&local->iflist_mtx);
+ mode = __ieee80211_get_channel_mode(local, ignore);
+ mutex_unlock(&local->iflist_mtx);
+
+ return mode;
+}
--- wireless-testing.orig/net/mac80211/ieee80211_i.h 2010-05-02 17:47:50.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h 2010-05-02 17:47:51.000000000 +0200
@@ -1229,6 +1229,17 @@ int ieee80211_wk_remain_on_channel(struc
int ieee80211_wk_cancel_remain_on_channel(
struct ieee80211_sub_if_data *sdata, u64 cookie);
+/* channel management */
+enum ieee80211_chan_mode {
+ CHAN_MODE_UNDEFINED,
+ CHAN_MODE_HOPPING,
+ CHAN_MODE_FIXED,
+};
+
+enum ieee80211_chan_mode
+ieee80211_get_channel_mode(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *ignore);
+
#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
#else
^ permalink raw reply
* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
From: Johannes Berg @ 2010-05-05 11:46 UTC (permalink / raw)
To: Benoit Papillault; +Cc: linux-wireless
In-Reply-To: <1272955622-6987-3-git-send-email-benoit.papillault@free.fr>
On Tue, 2010-05-04 at 08:47 +0200, Benoit Papillault wrote:
> When an HT IBSS is configured, we add HT Information and HT Capabilities
> IE to beacon & probe responses. This is done according to channel_type
> transmitted by iw/cfg80211.
Just noticed something else -- this allows creating an HT40 IBSS on an
invalid channel pair -- do we want to catch that?
johannse
^ 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