From 192b775cc811b0e9e0d174ffdd5a814794392482 Mon Sep 17 00:00:00 2001 From: Maxime Austruy Date: Mon, 29 Jan 2007 00:59:51 +0000 Subject: [PATCH] zd1211rw: fix potential leak in usb_init usb_init should call destroy_workqueue when usb_register fails. Signed-off-by: Maxime Austruy Signed-off-by: Ulrich Kunitz Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/zd1211rw') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 605e96e7405..2468ad662d3 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1128,6 +1128,7 @@ static int __init usb_init(void) r = usb_register(&driver); if (r) { + destroy_workqueue(zd_workqueue); printk(KERN_ERR "%s usb_register() failed. Error number %d\n", driver.name, r); return r; -- cgit v1.2.3 From 6e3632f66110b144183d53d550a51cbbbabc178f Mon Sep 17 00:00:00 2001 From: Ulrich Kunitz Date: Mon, 29 Jan 2007 00:59:28 +0000 Subject: [PATCH] zd1211rw: Reset device in the probe call This resets the device in the probe call. It does work with 2.6.19.2 including the softmac patches. It might fix the reboot/reset problems a lot of people reported. Signed-off-by: Ulrich Kunitz Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/wireless/zd1211rw') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 2468ad662d3..3ac308af24a 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1027,6 +1027,8 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; } + usb_reset_device(interface_to_usbdev(intf)); + netdev = zd_netdev_alloc(intf); if (netdev == NULL) { r = -ENOMEM; -- cgit v1.2.3 From fa8e29cff748efc7118c66b51f1241a927d86b98 Mon Sep 17 00:00:00 2001 From: Ulrich Kunitz Date: Mon, 29 Jan 2007 00:59:40 +0000 Subject: [PATCH] zd1211rw: Fixed array size issue in reset_mode Andy Green found this issue. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/zd1211rw') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index a08524191b5..1379c91a84a 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -156,7 +156,7 @@ void zd_mac_clear(struct zd_mac *mac) static int reset_mode(struct zd_mac *mac) { struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - struct zd_ioreq32 ioreqs[3] = { + struct zd_ioreq32 ioreqs[] = { { CR_RX_FILTER, STA_RX_FILTER }, { CR_SNIFFER_ON, 0U }, }; @@ -164,10 +164,9 @@ static int reset_mode(struct zd_mac *mac) if (ieee->iw_mode == IW_MODE_MONITOR) { ioreqs[0].value = 0xffffffff; ioreqs[1].value = 0x1; - ioreqs[2].value = ENC_SNIFFER; } - return zd_iowrite32a(&mac->chip, ioreqs, 3); + return zd_iowrite32a(&mac->chip, ioreqs, ARRAY_SIZE(ioreqs)); } int zd_mac_open(struct net_device *netdev) -- cgit v1.2.3 From 22d3405f62c1cef6661ced96a64458235f9c5fe5 Mon Sep 17 00:00:00 2001 From: Ulrich Kunitz Date: Mon, 29 Jan 2007 01:00:03 +0000 Subject: [PATCH] zd1211rw: Added error stats update Added update of network device error statistics. Based on earlier work by Maxime Austruy. Signed-off-by: Ulrich Kunitz Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 37 +++++++++++++++++++++++++++++----- drivers/net/wireless/zd1211rw/zd_usb.c | 9 +++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/zd1211rw') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 1379c91a84a..70707816db3 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -903,16 +903,21 @@ static int fill_ctrlset(struct zd_mac *mac, static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) { int i, r; + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); for (i = 0; i < txb->nr_frags; i++) { struct sk_buff *skb = txb->fragments[i]; r = fill_ctrlset(mac, txb, i); - if (r) + if (r) { + ieee->stats.tx_dropped++; return r; + } r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len); - if (r) + if (r) { + ieee->stats.tx_dropped++; return r; + } } /* FIXME: shouldn't this be handled by the upper layers? */ @@ -1062,9 +1067,23 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, *pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status)); if (status->frame_status & ZD_RX_ERROR) { - /* FIXME: update? */ + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + ieee->stats.rx_errors++; + if (status->frame_status & ZD_RX_TIMEOUT_ERROR) + ieee->stats.rx_missed_errors++; + else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) + ieee->stats.rx_fifo_errors++; + else if (status->frame_status & ZD_RX_DECRYPTION_ERROR) + ieee->ieee_stats.rx_discards_undecryptable++; + else if (status->frame_status & ZD_RX_CRC32_ERROR) { + ieee->stats.rx_crc_errors++; + ieee->ieee_stats.rx_fcs_errors++; + } + else if (status->frame_status & ZD_RX_CRC16_ERROR) + ieee->stats.rx_crc_errors++; return -EINVAL; } + memset(stats, 0, sizeof(struct ieee80211_rx_stats)); stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN + + sizeof(struct rx_status)); @@ -1093,6 +1112,8 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + IEEE80211_FCS_LEN + sizeof(struct rx_status)) { + ieee->stats.rx_errors++; + ieee->stats.rx_length_errors++; dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", skb->len); goto free_skb; @@ -1100,7 +1121,9 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); if (r) { - /* Only packets with rx errors are included here. */ + /* Only packets with rx errors are included here. + * The error stats have already been set in fill_rx_stats. + */ goto free_skb; } @@ -1113,8 +1136,10 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) r = filter_rx(ieee, skb->data, skb->len, &stats); if (r <= 0) { - if (r < 0) + if (r < 0) { + ieee->stats.rx_errors++; dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); + } goto free_skb; } @@ -1145,7 +1170,9 @@ int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); if (!skb) { + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); + ieee->stats.rx_dropped++; return -ENOMEM; } skb_reserve(skb, sizeof(struct zd_rt_hdr)); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 3ac308af24a..a3217a8d37c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -401,6 +401,12 @@ out: static inline void handle_retry_failed_int(struct urb *urb) { + struct zd_usb *usb = urb->context; + struct zd_mac *mac = zd_usb_to_mac(usb); + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + + ieee->stats.tx_errors++; + ieee->ieee_stats.tx_retry_limit_exceeded++; dev_dbg_f(urb_dev(urb), "retry failed interrupt\n"); } @@ -575,6 +581,9 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, if (length < sizeof(struct rx_length_info)) { /* It's not a complete packet anyhow. */ + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + ieee->stats.rx_errors++; + ieee->stats.rx_length_errors++; return; } length_info = (struct rx_length_info *) -- cgit v1.2.3 From 48f33c95291e429963dcd2dfe625d189d83e3925 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 29 Jan 2007 01:00:30 +0000 Subject: [PATCH] zd1211rw: Remove noisy debug message This causes a lot of uninteresting output in noisy environments, and doesn't really serve any purpose. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/wireless/zd1211rw') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 70707816db3..4c5f78eac34 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -1114,8 +1114,6 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) { ieee->stats.rx_errors++; ieee->stats.rx_length_errors++; - dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", - skb->len); goto free_skb; } -- cgit v1.2.3