Re: [patch 29/50] zd1211rw: Call ieee80211_rx in tasklet
On Fri, Jan 05, 2007 at 06:28:22PM -0800, Chris Wright wrote: > -stable review patch. If anyone has any objections, please let us know. > -- > > From: Ulrich Kunitz <[EMAIL PROTECTED]> > > [PATCH] zd1211rw: Call ieee80211_rx in tasklet > > The driver called ieee80211_rx in hardware interrupt context. This has > been against the intention of the ieee80211_rx function. It caused a bug > in the crypto routines used by WPA. This patch calls ieee80211_rx in a > tasklet. > > Signed-off-by: Ulrich Kunitz <[EMAIL PROTECTED]> > Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> > Signed-off-by: John W. Linville <[EMAIL PROTECTED]> > Signed-off-by: Chris Wright <[EMAIL PROTECTED]> ACK -- John W. Linville [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 29/50] zd1211rw: Call ieee80211_rx in tasklet
On Fri, Jan 05, 2007 at 06:28:22PM -0800, Chris Wright wrote: -stable review patch. If anyone has any objections, please let us know. -- From: Ulrich Kunitz [EMAIL PROTECTED] [PATCH] zd1211rw: Call ieee80211_rx in tasklet The driver called ieee80211_rx in hardware interrupt context. This has been against the intention of the ieee80211_rx function. It caused a bug in the crypto routines used by WPA. This patch calls ieee80211_rx in a tasklet. Signed-off-by: Ulrich Kunitz [EMAIL PROTECTED] Signed-off-by: Andrew Morton [EMAIL PROTECTED] Signed-off-by: John W. Linville [EMAIL PROTECTED] Signed-off-by: Chris Wright [EMAIL PROTECTED] ACK -- John W. Linville [EMAIL PROTECTED] - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[patch 29/50] zd1211rw: Call ieee80211_rx in tasklet
-stable review patch. If anyone has any objections, please let us know. -- From: Ulrich Kunitz <[EMAIL PROTECTED]> [PATCH] zd1211rw: Call ieee80211_rx in tasklet The driver called ieee80211_rx in hardware interrupt context. This has been against the intention of the ieee80211_rx function. It caused a bug in the crypto routines used by WPA. This patch calls ieee80211_rx in a tasklet. Signed-off-by: Ulrich Kunitz <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: John W. Linville <[EMAIL PROTECTED]> Signed-off-by: Chris Wright <[EMAIL PROTECTED]> --- Date: Sun, 10 Dec 2006 19:13:12 +0000 (-0800) Subject: [patch 29/50] [PATCH] zd1211rw: Call ieee80211_rx in tasklet X-Git-Tag: v2.6.20-rc2 X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4d1feabcbf41f875447a392015acd0796f57baf6 drivers/net/wireless/zd1211rw/zd_mac.c | 91 - drivers/net/wireless/zd1211rw/zd_mac.h |6 +- drivers/net/wireless/zd1211rw/zd_usb.c |4 - 3 files changed, 75 insertions(+), 26 deletions(-) --- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_mac.c +++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_mac.c @@ -37,6 +37,8 @@ static void housekeeping_init(struct zd_ static void housekeeping_enable(struct zd_mac *mac); static void housekeeping_disable(struct zd_mac *mac); +static void do_rx(unsigned long mac_ptr); + int zd_mac_init(struct zd_mac *mac, struct net_device *netdev, struct usb_interface *intf) @@ -47,6 +49,10 @@ int zd_mac_init(struct zd_mac *mac, spin_lock_init(>lock); mac->netdev = netdev; + skb_queue_head_init(>rx_queue); + tasklet_init(>rx_tasklet, do_rx, (unsigned long)mac); + tasklet_disable(>rx_tasklet); + ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); zd_chip_init(>chip, netdev, intf); @@ -132,6 +138,8 @@ out: void zd_mac_clear(struct zd_mac *mac) { + skb_queue_purge(>rx_queue); + tasklet_kill(>rx_tasklet); zd_chip_clear(>chip); ZD_ASSERT(!spin_is_locked(>lock)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); @@ -160,6 +168,8 @@ int zd_mac_open(struct net_device *netde struct zd_chip *chip = >chip; int r; + tasklet_enable(>rx_tasklet); + r = zd_chip_enable_int(chip); if (r < 0) goto out; @@ -210,6 +220,8 @@ int zd_mac_stop(struct net_device *netde */ zd_chip_disable_rx(chip); + skb_queue_purge(>rx_queue); + tasklet_disable(>rx_tasklet); housekeeping_disable(mac); ieee80211softmac_stop(netdev); @@ -873,45 +885,78 @@ static int fill_rx_stats(struct ieee8021 return 0; } -int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) +static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) { int r; struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct ieee80211_rx_stats stats; const struct rx_status *status; - struct sk_buff *skb; - if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + -IEEE80211_FCS_LEN + sizeof(struct rx_status)) - return -EINVAL; + if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + + IEEE80211_FCS_LEN + sizeof(struct rx_status)) + { + dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", +skb->len); + goto free_skb; + } - r = fill_rx_stats(, , mac, buffer, length); - if (r) - return r; + r = fill_rx_stats(, , mac, skb->data, skb->len); + if (r) { + /* Only packets with rx errors are included here. */ + goto free_skb; + } - length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+ - sizeof(struct rx_status); - buffer += ZD_PLCP_HEADER_SIZE; + __skb_pull(skb, ZD_PLCP_HEADER_SIZE); + __skb_trim(skb, skb->len - + (IEEE80211_FCS_LEN + sizeof(struct rx_status))); - update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); + update_qual_rssi(mac, skb->data, skb->len, stats.signal, +status->signal_strength); - r = filter_rx(ieee, buffer, length, ); - if (r <= 0) - return r; - skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); - if (!skb) - return -ENOMEM; + r = filter_rx(ieee, skb->data, skb->len, ); + if (r <= 0) { + if (r < 0) + dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); + goto free_skb; + } + if (ieee->iw_mode == IW_MODE_MONITOR) -
[patch 29/50] zd1211rw: Call ieee80211_rx in tasklet
-stable review patch. If anyone has any objections, please let us know. -- From: Ulrich Kunitz [EMAIL PROTECTED] [PATCH] zd1211rw: Call ieee80211_rx in tasklet The driver called ieee80211_rx in hardware interrupt context. This has been against the intention of the ieee80211_rx function. It caused a bug in the crypto routines used by WPA. This patch calls ieee80211_rx in a tasklet. Signed-off-by: Ulrich Kunitz [EMAIL PROTECTED] Signed-off-by: Andrew Morton [EMAIL PROTECTED] Signed-off-by: John W. Linville [EMAIL PROTECTED] Signed-off-by: Chris Wright [EMAIL PROTECTED] --- Date: Sun, 10 Dec 2006 19:13:12 + (-0800) Subject: [patch 29/50] [PATCH] zd1211rw: Call ieee80211_rx in tasklet X-Git-Tag: v2.6.20-rc2 X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4d1feabcbf41f875447a392015acd0796f57baf6 drivers/net/wireless/zd1211rw/zd_mac.c | 91 - drivers/net/wireless/zd1211rw/zd_mac.h |6 +- drivers/net/wireless/zd1211rw/zd_usb.c |4 - 3 files changed, 75 insertions(+), 26 deletions(-) --- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_mac.c +++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_mac.c @@ -37,6 +37,8 @@ static void housekeeping_init(struct zd_ static void housekeeping_enable(struct zd_mac *mac); static void housekeeping_disable(struct zd_mac *mac); +static void do_rx(unsigned long mac_ptr); + int zd_mac_init(struct zd_mac *mac, struct net_device *netdev, struct usb_interface *intf) @@ -47,6 +49,10 @@ int zd_mac_init(struct zd_mac *mac, spin_lock_init(mac-lock); mac-netdev = netdev; + skb_queue_head_init(mac-rx_queue); + tasklet_init(mac-rx_tasklet, do_rx, (unsigned long)mac); + tasklet_disable(mac-rx_tasklet); + ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); zd_chip_init(mac-chip, netdev, intf); @@ -132,6 +138,8 @@ out: void zd_mac_clear(struct zd_mac *mac) { + skb_queue_purge(mac-rx_queue); + tasklet_kill(mac-rx_tasklet); zd_chip_clear(mac-chip); ZD_ASSERT(!spin_is_locked(mac-lock)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); @@ -160,6 +168,8 @@ int zd_mac_open(struct net_device *netde struct zd_chip *chip = mac-chip; int r; + tasklet_enable(mac-rx_tasklet); + r = zd_chip_enable_int(chip); if (r 0) goto out; @@ -210,6 +220,8 @@ int zd_mac_stop(struct net_device *netde */ zd_chip_disable_rx(chip); + skb_queue_purge(mac-rx_queue); + tasklet_disable(mac-rx_tasklet); housekeeping_disable(mac); ieee80211softmac_stop(netdev); @@ -873,45 +885,78 @@ static int fill_rx_stats(struct ieee8021 return 0; } -int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) +static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) { int r; struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct ieee80211_rx_stats stats; const struct rx_status *status; - struct sk_buff *skb; - if (length ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + -IEEE80211_FCS_LEN + sizeof(struct rx_status)) - return -EINVAL; + if (skb-len ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + + IEEE80211_FCS_LEN + sizeof(struct rx_status)) + { + dev_dbg_f(zd_mac_dev(mac), Packet with length %u to small.\n, +skb-len); + goto free_skb; + } - r = fill_rx_stats(stats, status, mac, buffer, length); - if (r) - return r; + r = fill_rx_stats(stats, status, mac, skb-data, skb-len); + if (r) { + /* Only packets with rx errors are included here. */ + goto free_skb; + } - length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+ - sizeof(struct rx_status); - buffer += ZD_PLCP_HEADER_SIZE; + __skb_pull(skb, ZD_PLCP_HEADER_SIZE); + __skb_trim(skb, skb-len - + (IEEE80211_FCS_LEN + sizeof(struct rx_status))); - update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); + update_qual_rssi(mac, skb-data, skb-len, stats.signal, +status-signal_strength); - r = filter_rx(ieee, buffer, length, stats); - if (r = 0) - return r; - skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); - if (!skb) - return -ENOMEM; + r = filter_rx(ieee, skb-data, skb-len, stats); + if (r = 0) { + if (r 0) + dev_dbg_f(zd_mac_dev(mac), Error in packet.\n); + goto free_skb; + } + if (ieee-iw_mode == IW_MODE_MONITOR) - fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac, + fill_rt_header(skb_push