From 88149db4948ef90cf6220d76e34955e46c2ff9f9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 26 Sep 2011 14:19:47 +0200 Subject: Bluetooth: rfcomm: Fix sleep in invalid context in rfcomm_security_cfm This was triggered by turning off encryption on ACL link when rfcomm was using high security. rfcomm_security_cfm (which is called from rx task) was closing DLC and this involves sending disconnect message (and locking socket). Move closing DLC to rfcomm_process_dlcs and only flag DLC for closure in rfcomm_security_cfm. BUG: sleeping function called from invalid context at net/core/sock.c:2032 in_atomic(): 1, irqs_disabled(): 0, pid: 1788, name: kworker/0:3 [] (unwind_backtrace+0x0/0x108) from [] (dump_stack+0x20/0x24) [] (dump_stack+0x20/0x24) from [] (__might_sleep+0x110/0x12c) [] (__might_sleep+0x110/0x12c) from [] (lock_sock_nested+0x2c/0x64) [] (lock_sock_nested+0x2c/0x64) from [] (l2cap_sock_sendmsg+0x58/0xcc) [] (l2cap_sock_sendmsg+0x58/0xcc) from [] (sock_sendmsg+0xb0/0xd0) [] (sock_sendmsg+0xb0/0xd0) from [] (kernel_sendmsg+0x3c/0x44) [] (kernel_sendmsg+0x3c/0x44) from [] (rfcomm_send_frame+0x50/0x58) [] (rfcomm_send_frame+0x50/0x58) from [] (rfcomm_send_disc+0x78/0x80) [] (rfcomm_send_disc+0x78/0x80) from [] (__rfcomm_dlc_close+0x2d0/0x2fc) [] (__rfcomm_dlc_close+0x2d0/0x2fc) from [] (rfcomm_security_cfm+0x140/0x1e0) [] (rfcomm_security_cfm+0x140/0x1e0) from [] (hci_event_packet+0x1ce8/0x4d84) [] (hci_event_packet+0x1ce8/0x4d84) from [] (hci_rx_task+0x1d0/0x2d0) [] (hci_rx_task+0x1d0/0x2d0) from [] (tasklet_action+0x138/0x1e4) [] (tasklet_action+0x138/0x1e4) from [] (__do_softirq+0xcc/0x274) [] (__do_softirq+0xcc/0x274) from [] (do_softirq+0x60/0x6c) [] (do_softirq+0x60/0x6c) from [] (local_bh_enable_ip+0xc8/0xd4) [] (local_bh_enable_ip+0xc8/0xd4) from [] (_raw_spin_unlock_bh+0x48/0x4c) [] (_raw_spin_unlock_bh+0x48/0x4c) from [] (data_from_chip+0xf4/0xaec) [] (data_from_chip+0xf4/0xaec) from [] (send_skb_to_core+0x40/0x178) [] (send_skb_to_core+0x40/0x178) from [] (cg2900_hu_receive+0x15c/0x2d0) [] (cg2900_hu_receive+0x15c/0x2d0) from [] (hci_uart_tty_receive+0x74/0xa0) [] (hci_uart_tty_receive+0x74/0xa0) from [] (flush_to_ldisc+0x188/0x198) [] (flush_to_ldisc+0x188/0x198) from [] (process_one_work+0x144/0x4b8) [] (process_one_work+0x144/0x4b8) from [] (worker_thread+0x198/0x468) [] (worker_thread+0x198/0x468) from [] (kthread+0x98/0xa0) [] (kthread+0x98/0xa0) from [] (kernel_thread_exit+0x0/0x8) Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/rfcomm.h | 1 + net/bluetooth/rfcomm/core.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index d5eee2093b1e..e2e3ecad1008 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -211,6 +211,7 @@ struct rfcomm_dlc { #define RFCOMM_AUTH_ACCEPT 6 #define RFCOMM_AUTH_REJECT 7 #define RFCOMM_DEFER_SETUP 8 +#define RFCOMM_ENC_DROP 9 /* Scheduling flags and events */ #define RFCOMM_SCHED_WAKEUP 31 diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5ba3f6df665c..71ef2581c60f 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1802,6 +1802,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) continue; } + if (test_bit(RFCOMM_ENC_DROP, &d->flags)) { + __rfcomm_dlc_close(d, ECONNREFUSED); + continue; + } + if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { rfcomm_dlc_clear_timer(d); if (d->out) { @@ -2074,7 +2079,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) { rfcomm_dlc_clear_timer(d); if (status || encrypt == 0x00) { - __rfcomm_dlc_close(d, ECONNREFUSED); + set_bit(RFCOMM_ENC_DROP, &d->flags); continue; } } @@ -2085,7 +2090,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); continue; } else if (d->sec_level == BT_SECURITY_HIGH) { - __rfcomm_dlc_close(d, ECONNREFUSED); + set_bit(RFCOMM_ENC_DROP, &d->flags); continue; } } -- cgit v1.2.3 From e1b6eb3ccb0c2a34302a9fd87dd15d7b86337f23 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 17 Oct 2011 23:05:49 +0200 Subject: Bluetooth: Increase HCI reset timeout in hci_dev_do_close I've noticed that my CSR usb dongle was not working if it was plugged in when PC was booting. It looks like I get two HCI reset command complete events (see hcidump logs below). The root cause is reset called from off_timer. Timeout for this reset to complete is set to 250ms and my bt dongle requires more time for replying with command complete event. After that, chip seems to reply with reset command complete event for next non-reset command. Attached patch increase mentioned timeout to HCI_INIT_TIMEOUT, this value is already used for timeouting hci_reset_req in hci_dev_reset(). This might also be related to BT not working after suspend that was reported here some time ago. Hcidump log: 2011-09-12 23:13:27.379465 < HCI Command: Reset (0x03|0x0003) plen 0 2011-09-12 23:13:27.380797 > HCI Event: Command Complete (0x0e) plen 4 Reset (0x03|0x0003) ncmd 1 status 0x00 2011-09-12 23:13:27.380859 < HCI Command: Read Local Supported Features (0x04|0x000 3) plen 0 2011-09-12 23:13:27.760789 > HCI Event: Command Complete (0x0e) plen 4 Reset (0x03|0x0003) ncmd 1 status 0x00 2011-09-12 23:13:27.760831 < HCI Command: Read Local Version Information (0x04|0x00 01) plen 0 2011-09-12 23:13:27.764780 > HCI Event: Command Complete (0x0e) plen 12 Read Local Version Information (0x04|0x0001) ncmd 1 status 0x00 HCI Version: 1.1 (0x1) HCI Revision: 0x36f LMP Version: 1.1 (0x1) LMP Subversion: 0x36f Manufacturer: Cambridge Silicon Radio (10) Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 56943add45cc..44fb4a7e5c7d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -613,7 +613,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) if (!test_bit(HCI_RAW, &hdev->flags)) { set_bit(HCI_INIT, &hdev->flags); __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(250)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); clear_bit(HCI_INIT, &hdev->flags); } -- cgit v1.2.3 From dafbde395ed560ddc3695df40f61d91c47433228 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 24 Oct 2011 22:36:26 +0200 Subject: Bluetooth: Set HCI_MGMT flag only in read_controller_info The HCI_MGMT flag should only be set when user space requests the full controller information. This way we avoid potential issues with setting change events ariving before the actual read_controller_info command finishes. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 53e109eb043e..99251d19bf6f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -147,8 +147,6 @@ static int read_index_list(struct sock *sk) hci_del_off_timer(d); - set_bit(HCI_MGMT, &d->flags); - if (test_bit(HCI_SETUP, &d->flags)) continue; -- cgit v1.2.3 From 0ba22bb258341783939ed07bf7e7a9d92f3b0edf Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 25 Oct 2011 12:09:52 +0200 Subject: Bluetooth: ath3k: Use GFP_KERNEL instead of GFP_ATOMIC We are allowed to sleep here so no need to use GFP_ATOMIC. The caller (ath3k_probe) calls request_firmware() which definitely sleeps. Hence, we should avoid using GFP_ATOMIC. Signed-off-by: David Herrmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index db7cb8111fbe..106beb194f3c 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev, pipe = usb_sndctrlpipe(udev, 0); - send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); + send_buf = kmalloc(BULK_SIZE, GFP_KERNEL); if (!send_buf) { BT_ERR("Can't allocate memory chunk for firmware"); return -ENOMEM; @@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev, count = firmware->size; - send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); + send_buf = kmalloc(BULK_SIZE, GFP_KERNEL); if (!send_buf) { BT_ERR("Can't allocate memory chunk for firmware"); return -ENOMEM; -- cgit v1.2.3 From fc501ad7a10a356819505b1e526079d47fdebc2c Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 26 Oct 2011 11:13:13 +0200 Subject: Bluetooth: bcm203x: Fix race condition on disconnect When disconnecting a bcm203x device we kill and destroy the usb-urb, however, there might still be a pending work-structure which resubmits the now invalid urb. To avoid this race condition, we simply set a shutdown-flag and synchronously kill the worker first. This also adds a comment to all schedule_work()s, as it is really not clear that they are used as replacement for short timers (which can be seen in the git history). Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/bcm203x.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 8b1b643a519b..ec743c2ddf9d 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -65,6 +66,7 @@ struct bcm203x_data { unsigned long state; struct work_struct work; + atomic_t shutdown; struct urb *urb; unsigned char *buffer; @@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb) data->state = BCM203X_SELECT_MEMORY; + /* use workqueue to have a small delay */ schedule_work(&data->work); break; @@ -155,6 +158,9 @@ static void bcm203x_work(struct work_struct *work) struct bcm203x_data *data = container_of(work, struct bcm203x_data, work); + if (atomic_read(&data->shutdown)) + return; + if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); } @@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id usb_set_intfdata(intf, data); + /* use workqueue to have a small delay */ schedule_work(&data->work); return 0; @@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf) BT_DBG("intf %p", intf); + atomic_inc(&data->shutdown); + cancel_work_sync(&data->work); + usb_kill_urb(data->urb); usb_set_intfdata(intf, NULL); -- cgit v1.2.3 From b91a4e3e3a16085623d47f03b338d9b74954ac67 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 25 Oct 2011 21:13:36 +0200 Subject: Bluetooth: bcm203x: Use GFP_KERNEL in workqueue A workqueue is allowed to sleep so we can safely use GFP_KERNEL instead of GFP_ATOMIC. This is still legacy code when the driver used timer BHs and not a worqueue. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/bcm203x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index ec743c2ddf9d..54952ab800b8 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c @@ -161,7 +161,7 @@ static void bcm203x_work(struct work_struct *work) if (atomic_read(&data->shutdown)) return; - if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) + if (usb_submit_urb(data->urb, GFP_KERNEL) < 0) BT_ERR("Can't submit URB"); } -- cgit v1.2.3 From 6b441fab28ea1cbbf3da75dcd1e7438e6cba704c Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 26 Oct 2011 11:22:46 +0200 Subject: Bluetooth: bfusb: Fix error path on firmware load When loading the usb-configuration we do not signal the end of configuration on memory allocation error. This patch moves the memory allocation to the top so every error path uses "goto error" now to correctly send the usb-ctrl message when detecting some error. This also replaces GFP_ATOMIC with GFP_KERNEL as we are allowed to sleep here. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/bfusb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 005919ab043c..61b591470a90 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c @@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data, BT_INFO("BlueFRITZ! USB loading firmware"); + buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL); + if (!buf) { + BT_ERR("Can't allocate memory chunk for firmware"); + return -ENOMEM; + } + pipe = usb_sndctrlpipe(data->udev, 0); if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) { BT_ERR("Can't change to loading configuration"); + kfree(buf); return -EBUSY; } data->udev->toggle[0] = data->udev->toggle[1] = 0; - buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC); - if (!buf) { - BT_ERR("Can't allocate memory chunk for firmware"); - return -ENOMEM; - } - pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); while (count) { -- cgit v1.2.3 From cda4ee3f2e6907e89baf7a12e02e02fa208c0625 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 14 Oct 2011 12:54:47 -0700 Subject: iwlagn: fix the race in the unmapping of the HCMD As Stanislaw pointed out, my patch iwlagn: fix a race in the unmapping of the TFDs solved only part of the problem. The race still exists for TFDs of the host commands. Fix that too. Reported-by: Stanislaw Gruszka Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 8e8c75c997ee..da3411057afc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -407,6 +407,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) struct iwl_queue *q = &txq->q; enum dma_data_direction dma_dir; unsigned long flags; + spinlock_t *lock; if (!q->n_bd) return; @@ -414,19 +415,22 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) /* In the command queue, all the TBs are mapped as BIDI * so unmap them as such. */ - if (txq_id == trans->shrd->cmd_queue) + if (txq_id == trans->shrd->cmd_queue) { dma_dir = DMA_BIDIRECTIONAL; - else + lock = &trans->hcmd_lock; + } else { dma_dir = DMA_TO_DEVICE; + lock = &trans->shrd->sta_lock; + } - spin_lock_irqsave(&trans->shrd->sta_lock, flags); + spin_lock_irqsave(lock, flags); while (q->write_ptr != q->read_ptr) { /* The read_ptr needs to bound by q->n_window */ iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } - spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); + spin_unlock_irqrestore(lock, flags); } /** -- cgit v1.2.3 From 52d6d4ef5e6d1517688e27c11c01ab303ec681dd Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 20 Oct 2011 14:22:43 +0530 Subject: ath9k_hw: Fix regression of register offset for AR9003 chips My recent commits (3782c69d, 324c74a) introduced regression for register offset selection that based on the macversion. Not using parentheses in proper manner for ternary operator leads to select wrong offset for the registers. This issue was observed with AR9462 chip that immediate disconnect after the association with the following message ieee80211 phy3: wlan0: Failed to send nullfunc to AP 00:23:69:12:ea:47 after 500ms, disconnecting. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 2f4023e66081..70e01031714f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -572,14 +572,14 @@ #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) -#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ - 0x3c4 : 0x444) -#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \ - 0x3c8 : 0x448) -#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \ - 0x3c4 : 0x440) -#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ - 0x3f0 : 0x48c) +#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \ + 0x3c4 : 0x444)) +#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + (AR_SREV_9485(ah) ? \ + 0x3c8 : 0x448)) +#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + (AR_SREV_9485(ah) ? \ + 0x3c4 : 0x440)) +#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \ + 0x3f0 : 0x48c)) #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ (AR_SREV_9485(ah) ? \ 0x3d0 : 0x450) + ((_i) << 2)) @@ -931,10 +931,10 @@ #define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0) #define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4) -#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + (i) ? \ - AR_SM1_BASE : AR_SM_BASE) -#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + (i) ? \ - AR_SM1_BASE : AR_SM_BASE) +#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + ((i) ? \ + AR_SM1_BASE : AR_SM_BASE)) +#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + ((i) ? \ + AR_SM1_BASE : AR_SM_BASE)) /* * Channel 2 Register Map */ -- cgit v1.2.3 From 91ae4d02913808fc4056168766185d1a3bd63f65 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 20 Oct 2011 14:29:38 +0530 Subject: ath9k_hw: Fix radio retention for AR9462 IQ calibration during fast channel change sometimes failed with RTT. And also restoring invalid radio retention readings during init cal could cause failure to set the channel properly. This patch counts the valid rtt history readings and clears rtt mask. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 16851cb109a6..a4cd1617092b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -908,12 +908,15 @@ static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) int i; bool restore; - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT) || !ah->caldata) + if (!ah->caldata) return false; hist = &ah->caldata->rtt_hist; + if (!hist->num_readings) + return false; + ar9003_hw_rtt_enable(ah); - ar9003_hw_rtt_set_mask(ah, 0x10); + ar9003_hw_rtt_set_mask(ah, 0x00); for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (!(ah->rxchainmask & (1 << i))) continue; @@ -1070,6 +1073,7 @@ skip_tx_iqcal: if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { u32 *table; + hist->num_readings++; for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (!(ah->rxchainmask & (1 << i))) continue; -- cgit v1.2.3 From eaa7af2ae582c9a8c51b374c48d5970b748a5ce2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 20 Oct 2011 19:05:49 +0200 Subject: mac80211: fix remain_off_channel regression The offchannel code is currently broken - we should remain_off_channel if the work was started, and the work's channel and channel_type are the same as local->tmp_channel and local->tmp_channel_type. However, if wk->chan_type and local->tmp_channel_type coexist (e.g. have the same channel type), we won't remain_off_channel. This behavior was introduced by commit da2fd1f ("mac80211: Allow work items to use existing channel type.") Tested-by: Ben Greear Signed-off-by: Eliad Peller Cc: stable@kernel.org # 2.6.39+ Signed-off-by: John W. Linville --- net/mac80211/work.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 94472eb34d76..bf5be22a977c 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -1084,8 +1084,8 @@ static void ieee80211_work_work(struct work_struct *work) continue; if (wk->chan != local->tmp_channel) continue; - if (ieee80211_work_ct_coexists(wk->chan_type, - local->tmp_channel_type)) + if (!ieee80211_work_ct_coexists(wk->chan_type, + local->tmp_channel_type)) continue; remain_off_channel = true; } -- cgit v1.2.3 From 6911bf0453e0d6ea8eb694a4ce67a68d071c538e Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 20 Oct 2011 19:05:50 +0200 Subject: mac80211: config hw when going back on-channel When going back on-channel, we should reconfigure the hw iff the hardware is not already configured to the operational channel. Signed-off-by: Eliad Peller Cc: stable@kernel.org # 2.6.39+ Signed-off-by: John W. Linville --- net/mac80211/work.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/mac80211/work.c b/net/mac80211/work.c index bf5be22a977c..6c53b6d1002b 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -1091,7 +1091,6 @@ static void ieee80211_work_work(struct work_struct *work) } if (!remain_off_channel && local->tmp_channel) { - bool on_oper_chan = ieee80211_cfg_on_oper_channel(local); local->tmp_channel = NULL; /* If tmp_channel wasn't operating channel, then * we need to go back on-channel. @@ -1101,7 +1100,7 @@ static void ieee80211_work_work(struct work_struct *work) * we still need to do a hardware config. Currently, * we cannot be here while scanning, however. */ - if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan) + if (!ieee80211_cfg_on_oper_channel(local)) ieee80211_hw_config(local, 0); /* At the least, we need to disable offchannel_ps, -- cgit v1.2.3 From fd26981cf53ee91951a92fae53416e4ce639164c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 21 Oct 2011 12:53:51 +0530 Subject: ath9k_hw: Fix regression of register offset of AR9330/AR9340 The commit ce407afc10 introduced regression for AR9330/AR9340 register offsets. Some of the register offsets are common for AR9330/AR9340/AR9485 except AR9380. Fix that. Cc: stable@kernel.org [3.1.0+] Cc: Senthil Balasubramanian Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 70e01031714f..4114fe752c6b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -651,7 +651,7 @@ #define AR_SWITCH_TABLE_ALL_S (0) #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ - (AR_SREV_9485(ah) ? 0x1628c : 0x16294)) + (AR_SREV_9462(ah) ? 0x16294 : 0x1628c)) #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 @@ -668,12 +668,12 @@ #define AR_PHY_65NM_CH2_RXTX2 0x16904 #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ - (AR_SREV_9485(ah) ? 0x16284 : 0x16290)) + (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) #define AR_CH0_TOP2_XPABIASLVL 0xf000 #define AR_CH0_TOP2_XPABIASLVL_S 12 #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ - (AR_SREV_9485(ah) ? 0x16290 : 0x16298)) + (AR_SREV_9462(ah) ? 0x16298 : 0x16290)) #define AR_CH0_XTAL_CAPINDAC 0x7f000000 #define AR_CH0_XTAL_CAPINDAC_S 24 #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 @@ -908,8 +908,8 @@ #define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) #define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) -#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9300(ah) ? \ - 0x240 : 0x280)) +#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \ + 0x280 : 0x240)) #define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) #define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff #define AR_PHY_TPC_19_B1_ALPHA_THERM_S 0 -- cgit v1.2.3 From 94d55d62bd757611f07a9122e5e07ce929b8d38d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 21 Oct 2011 18:38:56 +0200 Subject: carl9170: fix AMPDU TX_CTL_REQ_TX_STATUS handling Previously the driver did not care if TX_CTL_REQ_TX_STATUS was set on aggregated frames or not and it would silently drop successfully sent frames if possible [much like: "no news is good news!"]. But, TX_CTL_REQ_TX_STATUS was invented for a reason and no tx status report should ever be dropped if it is set. Reported-by: Johannes Berg Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index d20946939cd8..59472e1605cd 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -296,7 +296,8 @@ static void carl9170_tx_release(struct kref *ref) super = (void *)skb->data; txinfo->status.ampdu_len = super->s.rix; txinfo->status.ampdu_ack_len = super->s.cnt; - } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { + } else if ((txinfo->flags & IEEE80211_TX_STAT_ACK) && + !(txinfo->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { /* * drop redundant tx_status reports: * @@ -308,15 +309,17 @@ static void carl9170_tx_release(struct kref *ref) * * 3. minstrel_ht is picky, it only accepts * reports of frames with the TX_STATUS_AMPDU flag. + * + * 4. mac80211 is not particularly interested in + * feedback either [CTL_REQ_TX_STATUS not set] */ dev_kfree_skb_any(skb); return; } else { /* - * Frame has failed, but we want to keep it in - * case it was lost due to a power-state - * transition. + * Either the frame transmission has failed or + * mac80211 requested tx status. */ } } -- cgit v1.2.3 From e3a4cc2f073739c9c9c2e97efc774703061f034a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 23 Oct 2011 22:36:04 +0300 Subject: mac80211: Fix TDLS support validation in add_station handler We need to verify whether the command is successful before allocating the station entry to avoid extra processing. This also fixes a memory leak on the error path. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ebd7fb101fbf..d06c65fa5526 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -832,6 +832,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, if (is_multicast_ether_addr(mac)) return -EINVAL; + /* Only TDLS-supporting stations can add TDLS peers */ + if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) && + !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) && + sdata->vif.type == NL80211_IFTYPE_STATION)) + return -ENOTSUPP; + sta = sta_info_alloc(sdata, mac, GFP_KERNEL); if (!sta) return -ENOMEM; @@ -841,12 +847,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, sta_apply_parameters(local, sta, params); - /* Only TDLS-supporting stations can add TDLS peers */ - if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && - !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) && - sdata->vif.type == NL80211_IFTYPE_STATION)) - return -ENOTSUPP; - rate_control_rate_init(sta); layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || -- cgit v1.2.3 From 98fb2cc115b4ef1ea0a2d87a170c183bd395dd6c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 24 Oct 2011 18:13:40 +0530 Subject: ath9k_hw: Update AR9485 initvals to fix system hang issue This patch fixes system hang when resuming from S3 state and lower rate sens failure issue. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 611ea6ce8508..d16d029f81a9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -521,7 +521,7 @@ static const u32 ar9485_1_1_radio_postamble[][2] = { {0x000160ac, 0x24611800}, {0x000160b0, 0x03284f3e}, {0x0001610c, 0x00170000}, - {0x00016140, 0x10804008}, + {0x00016140, 0x50804008}, }; static const u32 ar9485_1_1_mac_postamble[][5] = { @@ -603,7 +603,7 @@ static const u32 ar9485_1_1_radio_core[][2] = { static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x10052e5e}, + {0x00018c00, 0x18052e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; @@ -776,7 +776,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x10013e5e}, + {0x00018c00, 0x18013e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; @@ -882,7 +882,7 @@ static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x10012e5e}, + {0x00018c00, 0x18012e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; @@ -1021,7 +1021,7 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x10053e5e}, + {0x00018c00, 0x18053e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; -- cgit v1.2.3 From 93348928f2c980718434b1bc42f9d7638d665db4 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 25 Oct 2011 16:47:36 +0530 Subject: ath9k_hw: Fix noise floor calibration timeout on fast channel change During the fast channel change noise floor values are being loaded twice at init_cal and after channel_change. The commit "ath9k_hw: Improve fast channel change for AR9003 chips" overlooked it that caused failure to load nf while doing bgscan. This patch performs noise floor calibration after the fast and full reset. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 4 ---- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 3 --- drivers/net/wireless/ath/ath9k/hw.c | 3 +++ 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index e0ab0657cc3a..88279e325dca 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -868,10 +868,6 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) /* Do PA Calibration */ ar9002_hw_pa_cal(ah, true); - /* Do NF Calibration after DC offset and other calibrations */ - ath9k_hw_loadnf(ah, chan); - ath9k_hw_start_nfcal(ah, true); - if (ah->caldata) ah->caldata->nfcal_pending = true; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index a4cd1617092b..12a730dcb500 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -1085,9 +1085,6 @@ skip_tx_iqcal: ar9003_hw_rtt_disable(ah); } - ath9k_hw_loadnf(ah, chan); - ath9k_hw_start_nfcal(ah, true); - /* Initialize list pointers */ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; ah->supp_cals = IQ_MISMATCH_CAL; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f16d2033081f..b479160dc262 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1724,6 +1724,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ath9k_hw_init_cal(ah, chan)) return -EIO; + ath9k_hw_loadnf(ah, chan); + ath9k_hw_start_nfcal(ah, true); + ENABLE_REGWRITE_BUFFER(ah); ath9k_hw_restore_chainmask(ah); -- cgit v1.2.3 From 3209e061ad04465b3999091f315049c95ac6cbcb Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Wed, 26 Oct 2011 10:19:26 -0700 Subject: libertas: ensure we clean up a scan request properly Commit 2e30168b ("libertas: terminate scan when stopping interface") adds cleanup code to lbs_eth_stop to call cfg80211_scan_done if there's an outstanding cfg80211_scan_request. However, it assumes that the scan request was allocated via the cfg80211 stack. Libertas has its own internal allocation method, kept track of with priv->internal_scan. This doesn't set scan_req->wiphy, amongst other things, which results in hitting a BUG() when we call cfg80211_scan_done on the request. This provides a function to take care of the low-level scan_req cleanup details. We simply call that to deal with finishing up scan requests. The bug we were hitting was: [ 964.321495] kernel BUG at net/wireless/core.h:87! [ 964.329970] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 964.341963] pgd = dcf80000 ... [ 964.849998] 9fe0: 00000000 beb417b8 4018e280 401e822c 60000010 00000004 00000000 00000000 [ 964.865007] [] (__bug+0x1c/0x28) from [] (cfg80211_scan_done+0x54/0x6c) [ 964.895324] [] (cfg80211_scan_done+0x54/0x6c) from [] (lbs_eth_stop+0x10c/0x188 [libertas]) [ 964.895324] [] (lbs_eth_stop+0x10c/0x188 [libertas]) from [] (__dev_close_many+0x94/0xc4) [ 964.918995] [] (__dev_close_many+0x94/0xc4) from [] (dev_close_many+0x78/0xe0) Signed-off-by: Andres Salomon Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 25 +++++++++++++++++-------- drivers/net/wireless/libertas/cfg.h | 1 + drivers/net/wireless/libertas/main.c | 6 ++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index ff6378276ff0..4fcd653bddc4 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -728,15 +728,9 @@ static void lbs_scan_worker(struct work_struct *work) le16_to_cpu(scan_cmd->hdr.size), lbs_ret_scan, 0); - if (priv->scan_channel >= priv->scan_req->n_channels) { + if (priv->scan_channel >= priv->scan_req->n_channels) /* Mark scan done */ - if (priv->internal_scan) - kfree(priv->scan_req); - else - cfg80211_scan_done(priv->scan_req, false); - - priv->scan_req = NULL; - } + lbs_scan_done(priv); /* Restart network */ if (carrier) @@ -774,6 +768,21 @@ static void _internal_start_scan(struct lbs_private *priv, bool internal, lbs_deb_leave(LBS_DEB_CFG80211); } +/* + * Clean up priv->scan_req. Should be used to handle the allocation details. + */ +void lbs_scan_done(struct lbs_private *priv) +{ + WARN_ON(!priv->scan_req); + + if (priv->internal_scan) + kfree(priv->scan_req); + else + cfg80211_scan_done(priv->scan_req, false); + + priv->scan_req = NULL; +} + static int lbs_cfg_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h index a02ee151710e..558168ce634d 100644 --- a/drivers/net/wireless/libertas/cfg.h +++ b/drivers/net/wireless/libertas/cfg.h @@ -16,6 +16,7 @@ int lbs_reg_notifier(struct wiphy *wiphy, void lbs_send_disconnect_notification(struct lbs_private *priv); void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); +void lbs_scan_done(struct lbs_private *priv); void lbs_scan_deinit(struct lbs_private *priv); int lbs_disconnect(struct lbs_private *priv, u16 reason); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index b03779bcd547..39a6a7a40244 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -255,10 +255,8 @@ static int lbs_eth_stop(struct net_device *dev) lbs_update_mcast(priv); cancel_delayed_work_sync(&priv->scan_work); - if (priv->scan_req) { - cfg80211_scan_done(priv->scan_req, false); - priv->scan_req = NULL; - } + if (priv->scan_req) + lbs_scan_done(priv); netif_carrier_off(priv->dev); -- cgit v1.2.3 From 8a39ef8ba0fa0410d71db8e981e887fe4fdeca88 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 27 Oct 2011 17:19:39 -0700 Subject: iwlwifi: allow pci_enable_msi fail Continue the init process even fail to enable msi out_iounmap is no longer used, remove it Reported-by: werner Tested-by: werner Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 3b6cc66365e5..19cc6a81da57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -445,10 +445,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); err = pci_enable_msi(pdev); - if (err) { - dev_printk(KERN_ERR, &pdev->dev, "pci_enable_msi failed"); - goto out_iounmap; - } + if (err) + dev_printk(KERN_ERR, &pdev->dev, + "pci_enable_msi failed(0X%x)", err); /* TODO: Move this away, not needed if not MSI */ /* enable rfkill interrupt: hw bug w/a */ @@ -469,7 +468,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) out_disable_msi: pci_disable_msi(pdev); -out_iounmap: pci_iounmap(pdev, pci_bus->hw_base); out_pci_release_regions: pci_set_drvdata(pdev, NULL); -- cgit v1.2.3 From 05cb91085760ca378f28fc274fbf77fc4fd9886c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 28 Oct 2011 11:59:47 +0200 Subject: mac80211: disable powersave for broken APs Only AID values 1-2007 are valid, but some APs have been found to send random bogus values, in the reported case an AP that was sending the AID field value 0xffff, an AID of 0x3fff (16383). There isn't much we can do but disable powersave since there's no way it can work properly in this case. Cc: stable@vger.kernel.org Reported-by: Bill C Riemers Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4c3d1f591bec..ea10a51babda 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -389,6 +389,7 @@ struct ieee80211_if_managed { unsigned long timers_running; /* used for quiesce/restart */ bool powersave; /* powersave requested for this iface */ + bool broken_ap; /* AP is broken -- turn off powersave */ enum ieee80211_smps_mode req_smps, /* requested smps mode */ ap_smps, /* smps mode AP thinks we're in */ driver_smps_mode; /* smps mode request */ diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ba2da11a997b..17258feaab9b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -637,6 +637,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) if (!mgd->powersave) return false; + if (mgd->broken_ap) + return false; + if (!mgd->associated) return false; @@ -1489,10 +1492,21 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " - "set\n", sdata->name, aid); + printk(KERN_DEBUG + "%s: invalid AID value 0x%x; bits 15:14 not set\n", + sdata->name, aid); aid &= ~(BIT(15) | BIT(14)); + ifmgd->broken_ap = false; + + if (aid == 0 || aid > IEEE80211_MAX_AID) { + printk(KERN_DEBUG + "%s: invalid AID value %d (out of range), turn off PS\n", + sdata->name, aid); + aid = 0; + ifmgd->broken_ap = true; + } + pos = mgmt->u.assoc_resp.variable; ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); -- cgit v1.2.3 From addc98519207fb8ca0609da720469e415f784d0c Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 28 Oct 2011 12:17:49 -0500 Subject: b43: Remove unneeded message The driver can spam the logs with "RX: Packet dropped" messages. These drops originate from 1. a correpted PLCP, 2. decryption errors, and 3. packet size underruns. Condition #3 logs a separate message, thus no dropped message is needed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43/xmit.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index c73e8600d218..58ea0e5fabfd 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -827,7 +827,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) #endif return; drop: - b43dbg(dev->wl, "RX: Packet dropped\n"); dev_kfree_skb_any(skb); } -- cgit v1.2.3 From f956c34e2a665a1c457d0af7db7604b22f5acb19 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 29 Oct 2011 23:15:15 -0700 Subject: iwlwifi: don't perform "echo test" when cmd queue stuck Perform "echo test" when cmd queue stuck detected, somethime it will cause calltrace. I am not sure how to fix it yet, just remove the action now until find a better way to handle it. Reported-by: Reinette Chatre Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b247a56d5135..001fdf140abb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1755,16 +1755,6 @@ static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq) { if (iwl_trans_check_stuck_queue(trans(priv), txq)) { int ret; - if (txq == priv->shrd->cmd_queue) { - /* - * validate command queue still working - * by sending "ECHO" command - */ - if (!iwl_cmd_echo_test(priv)) - return 0; - else - IWL_DEBUG_HC(priv, "echo testing fail\n"); - } ret = iwl_force_reset(priv, IWL_FW_RESET, false); return (ret == -EAGAIN) ? 0 : 1; } -- cgit v1.2.3 From 54d5026e7c173edae8a27c293c286f1783d21ae8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Nov 2011 18:07:43 +0100 Subject: mac80211: warn only once about not finding a rate The warning really shouldn't happen, but until we find the reason why it does don't spew it all the time, just once is enough to know we've hit it. Reported-by: Linus Torvalds Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index dc1123aa8181..72eddd1b410b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3567,8 +3567,9 @@ rate_lowest_index(struct ieee80211_supported_band *sband, return i; /* warn when we cannot find a rate. */ - WARN_ON(1); + WARN_ON_ONCE(1); + /* and return 0 (the lowest index) */ return 0; } -- cgit v1.2.3 From 78f94dc7b10d98cf4cf8498d98581500d910c6b7 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:14:58 +0000 Subject: tg3: Fix APE mutex init and use APE mutex register blocks are shared by all ports of multiport devices. For some mutexing purposes, each function is assigned their own register. For other cases, each function is assigned its own request and grant bits of a single register. For the latter cases, the tg3 driver is incorrectly allowing each function to use the same set of grant / request bits. This patch fixes the code so that each function uses the appropriate bitset. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 44 +++++++++++++++++++------------------ drivers/net/ethernet/broadcom/tg3.h | 10 ++++++--- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 161cbbb4814a..35901630a65c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -628,19 +628,23 @@ static void tg3_ape_lock_init(struct tg3 *tp) regbase = TG3_APE_PER_LOCK_GRANT; /* Make sure the driver hasn't any stale locks. */ - for (i = 0; i < 8; i++) { - if (i == TG3_APE_LOCK_GPIO) - continue; - tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER); + for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) { + switch (i) { + case TG3_APE_LOCK_PHY0: + case TG3_APE_LOCK_PHY1: + case TG3_APE_LOCK_PHY2: + case TG3_APE_LOCK_PHY3: + bit = APE_LOCK_GRANT_DRIVER; + break; + default: + if (!tp->pci_fn) + bit = APE_LOCK_GRANT_DRIVER; + else + bit = 1 << tp->pci_fn; + } + tg3_ape_write32(tp, regbase + 4 * i, bit); } - /* Clear the correct bit of the GPIO lock too. */ - if (!tp->pci_fn) - bit = APE_LOCK_GRANT_DRIVER; - else - bit = 1 << tp->pci_fn; - - tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit); } static int tg3_ape_lock(struct tg3 *tp, int locknum) @@ -658,6 +662,10 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) return 0; case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_MEM: + if (!tp->pci_fn) + bit = APE_LOCK_REQ_DRIVER; + else + bit = 1 << tp->pci_fn; break; default: return -EINVAL; @@ -673,11 +681,6 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) off = 4 * locknum; - if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn) - bit = APE_LOCK_REQ_DRIVER; - else - bit = 1 << tp->pci_fn; - tg3_ape_write32(tp, req + off, bit); /* Wait for up to 1 millisecond to acquire lock. */ @@ -710,6 +713,10 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) return; case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_MEM: + if (!tp->pci_fn) + bit = APE_LOCK_GRANT_DRIVER; + else + bit = 1 << tp->pci_fn; break; default: return; @@ -720,11 +727,6 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) else gnt = TG3_APE_PER_LOCK_GRANT; - if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn) - bit = APE_LOCK_GRANT_DRIVER; - else - bit = 1 << tp->pci_fn; - tg3_ape_write32(tp, gnt + 4 * locknum, bit); } diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index f32f288134c7..03fab8cadd86 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -2344,9 +2344,13 @@ #define APE_PER_LOCK_GRANT_DRIVER 0x00001000 /* APE convenience enumerations. */ -#define TG3_APE_LOCK_GRC 1 -#define TG3_APE_LOCK_MEM 4 -#define TG3_APE_LOCK_GPIO 7 +#define TG3_APE_LOCK_PHY0 0 +#define TG3_APE_LOCK_GRC 1 +#define TG3_APE_LOCK_PHY1 2 +#define TG3_APE_LOCK_PHY2 3 +#define TG3_APE_LOCK_MEM 4 +#define TG3_APE_LOCK_PHY3 5 +#define TG3_APE_LOCK_GPIO 7 #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 -- cgit v1.2.3 From b9e454826f22e17d1945bd282834c87aef8d0f95 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:14:59 +0000 Subject: tg3: Fix 4k tx bd segmentation code The new 4k tx bd segmentation code had a bug in the error cleanup path. If the driver did not map all the physical fragments, the abort path would wind up advancing the producer index beyond the point where the setup code stopped. This would ultimately turn into a tx recovery error where the driver would expect the skb pointer to be set when it isn't. This patch fixes the problem, and then makes the code a little easier to understand. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 47 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 35901630a65c..507b73b979fe 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6444,31 +6444,26 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, hwbug = 1; if (tg3_flag(tp, 4K_FIFO_LIMIT)) { + u32 prvidx = *entry; u32 tmp_flag = flags & ~TXD_FLAG_END; - while (len > TG3_TX_BD_DMA_MAX) { + while (len > TG3_TX_BD_DMA_MAX && *budget) { u32 frag_len = TG3_TX_BD_DMA_MAX; len -= TG3_TX_BD_DMA_MAX; - if (len) { - tnapi->tx_buffers[*entry].fragmented = true; - /* Avoid the 8byte DMA problem */ - if (len <= 8) { - len += TG3_TX_BD_DMA_MAX / 2; - frag_len = TG3_TX_BD_DMA_MAX / 2; - } - } else - tmp_flag = flags; - - if (*budget) { - tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, - frag_len, tmp_flag, mss, vlan); - (*budget)--; - *entry = NEXT_TX(*entry); - } else { - hwbug = 1; - break; + /* Avoid the 8byte DMA problem */ + if (len <= 8) { + len += TG3_TX_BD_DMA_MAX / 2; + frag_len = TG3_TX_BD_DMA_MAX / 2; } + tnapi->tx_buffers[*entry].fragmented = true; + + tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, + frag_len, tmp_flag, mss, vlan); + *budget -= 1; + prvidx = *entry; + *entry = NEXT_TX(*entry); + map += frag_len; } @@ -6476,10 +6471,11 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, if (*budget) { tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, len, flags, mss, vlan); - (*budget)--; + *budget -= 1; *entry = NEXT_TX(*entry); } else { hwbug = 1; + tnapi->tx_buffers[prvidx].fragmented = false; } } } else { @@ -6561,6 +6557,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, dev_kfree_skb(new_skb); ret = -1; } else { + u32 save_entry = *entry; + base_flags |= TXD_FLAG_END; tnapi->tx_buffers[*entry].skb = new_skb; @@ -6570,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, new_skb->len, base_flags, mss, vlan)) { - tg3_tx_skb_unmap(tnapi, *entry, 0); + tg3_tx_skb_unmap(tnapi, save_entry, 0); dev_kfree_skb(new_skb); ret = -1; } @@ -6786,11 +6784,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) if (dma_mapping_error(&tp->pdev->dev, mapping)) goto dma_error; - if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, + if (!budget || + tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags | ((i == last) ? TXD_FLAG_END : 0), - tmp_mss, vlan)) + tmp_mss, vlan)) { would_hit_hwbug = 1; + break; + } } } -- cgit v1.2.3 From ba1142e4fb291c7bf124d93596351dca8d226a0f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:15:00 +0000 Subject: tg3: Fix 4k skb error recovery path On the error recovery resource unwind path, it is possible for the driver to attempt to unmap a fragment that hadn't been mapped. This patch fixes the problem by correcting the "last" parameter supplied. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 507b73b979fe..3a7517910eed 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6507,7 +6507,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) txb = &tnapi->tx_buffers[entry]; } - for (i = 0; i < last; i++) { + for (i = 0; i <= last; i++) { const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; entry = NEXT_TX(entry); @@ -6568,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, new_skb->len, base_flags, mss, vlan)) { - tg3_tx_skb_unmap(tnapi, save_entry, 0); + tg3_tx_skb_unmap(tnapi, save_entry, -1); dev_kfree_skb(new_skb); ret = -1; } @@ -6758,11 +6758,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags | ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), - mss, vlan)) + mss, vlan)) { would_hit_hwbug = 1; - /* Now loop through additional data fragments, and queue them. */ - if (skb_shinfo(skb)->nr_frags > 0) { + } else if (skb_shinfo(skb)->nr_frags > 0) { u32 tmp_mss = mss; if (!tg3_flag(tp, HW_TSO_1) && @@ -6831,7 +6830,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; dma_error: - tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); + tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i); tnapi->tx_buffers[tnapi->tx_prod].skb = NULL; drop: dev_kfree_skb(skb); @@ -7284,7 +7283,8 @@ static void tg3_free_rings(struct tg3 *tp) if (!skb) continue; - tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags); + tg3_tx_skb_unmap(tnapi, i, + skb_shinfo(skb)->nr_frags - 1); dev_kfree_skb_any(skb); } @@ -11523,7 +11523,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) break; } - tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0); + tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, -1); dev_kfree_skb(skb); if (tx_idx != tnapi->tx_prod) -- cgit v1.2.3 From 5bc09186deba2a016b60aa3923fc0e42838ce877 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:15:01 +0000 Subject: tg3: Fix irq alloc error cleanup path This patch fixes a bug where the irq error cleanup path did not free all the resources it allocated. Signed-off-by: Matt Carlson Signed-off-by: Ben Li Signed-off-by: Akinobu Mita Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 3a7517910eed..0413e1e85641 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -9677,15 +9677,14 @@ static int tg3_open(struct net_device *dev) struct tg3_napi *tnapi = &tp->napi[i]; err = tg3_request_irq(tp, i); if (err) { - for (i--; i >= 0; i--) + for (i--; i >= 0; i--) { + tnapi = &tp->napi[i]; free_irq(tnapi->irq_vec, tnapi); - break; + } + goto err_out2; } } - if (err) - goto err_out2; - tg3_full_lock(tp, 0); err = tg3_init_hw(tp, 1); -- cgit v1.2.3 From 9dc5e342703948ea7b086d063c85c0e79dac8149 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:15:02 +0000 Subject: tg3: Obtain PCI function number from device This patch adds code to attempt to obtain the PCI function number from the device rather than accept the number handed by the kernel. In pass-through scenarios, the function number handed by the kernel may not reflect the true function of the device. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 30 ++++++++++++++++++++++++------ drivers/net/ethernet/broadcom/tg3.h | 9 +++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 0413e1e85641..6973d01ae85a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -14230,12 +14230,30 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) val = tr32(MEMARB_MODE); tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); - if (tg3_flag(tp, PCIX_MODE)) { - pci_read_config_dword(tp->pdev, - tp->pcix_cap + PCI_X_STATUS, &val); - tp->pci_fn = val & 0x7; - } else { - tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3; + tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + tg3_flag(tp, 5780_CLASS)) { + if (tg3_flag(tp, PCIX_MODE)) { + pci_read_config_dword(tp->pdev, + tp->pcix_cap + PCI_X_STATUS, + &val); + tp->pci_fn = val & 0x7; + } + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { + tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val); + if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) == + NIC_SRAM_CPMUSTAT_SIG) { + tp->pci_fn = val & TG3_CPMU_STATUS_FMSK_5717; + tp->pci_fn = tp->pci_fn ? 1 : 0; + } + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val); + if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) == + NIC_SRAM_CPMUSTAT_SIG) { + tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5719) >> + TG3_CPMU_STATUS_FSHFT_5719; + } } /* Get eeprom hw config before calling tg3_set_power_state(). diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 03fab8cadd86..acfa265733ad 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -1095,6 +1095,11 @@ #define TG3_CPMU_CLCK_ORIDE 0x00003624 #define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000 +#define TG3_CPMU_STATUS 0x0000362c +#define TG3_CPMU_STATUS_FMSK_5717 0x20000000 +#define TG3_CPMU_STATUS_FMSK_5719 0xc0000000 +#define TG3_CPMU_STATUS_FSHFT_5719 30 + #define TG3_CPMU_CLCK_STAT 0x00003630 #define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000 #define CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000 @@ -2128,6 +2133,10 @@ #define NIC_SRAM_RGMII_EXT_IBND_RX_EN 0x00000008 #define NIC_SRAM_RGMII_EXT_IBND_TX_EN 0x00000010 +#define NIC_SRAM_CPMU_STATUS 0x00000e00 +#define NIC_SRAM_CPMUSTAT_SIG 0x0000362c +#define NIC_SRAM_CPMUSTAT_SIG_MSK 0x0000ffff + #define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000 #define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000 -- cgit v1.2.3 From db21997379906fe7657d360674e1106d80b020a4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:15:03 +0000 Subject: tg3: Schedule at most one tg3_reset_task run It is possible for multiple threads in the tg3 driver to each attempt to schedule a run of tg3_reset_task(). The multiple tg3_reset_task executions could all wind up on the same queue (and execute serially) or wind up on the queues of another processor (which could execute in parallel). Either scenario is not what was truly desired. This patch adds a new flag, TG3_FLAG_RESET_TASK_PENDING, and uses it to determine whether or not to schedule another run of tg3_reset_task(). With the new flag comes two new functions to facilitate scheduling and descheduling of tg3_reset_task(). Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 33 ++++++++++++++++++++++++--------- drivers/net/ethernet/broadcom/tg3.h | 1 + 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 6973d01ae85a..d4a85b795344 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -5929,6 +5929,18 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) return work_done; } +static inline void tg3_reset_task_schedule(struct tg3 *tp) +{ + if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags)) + schedule_work(&tp->reset_task); +} + +static inline void tg3_reset_task_cancel(struct tg3 *tp) +{ + cancel_work_sync(&tp->reset_task); + tg3_flag_clear(tp, RESET_TASK_PENDING); +} + static int tg3_poll_msix(struct napi_struct *napi, int budget) { struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi); @@ -5969,7 +5981,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) tx_recovery: /* work_done is guaranteed to be less than budget. */ napi_complete(napi); - schedule_work(&tp->reset_task); + tg3_reset_task_schedule(tp); return work_done; } @@ -6004,7 +6016,7 @@ static void tg3_process_error(struct tg3 *tp) tg3_dump_state(tp); tg3_flag_set(tp, ERROR_PROCESSED); - schedule_work(&tp->reset_task); + tg3_reset_task_schedule(tp); } static int tg3_poll(struct napi_struct *napi, int budget) @@ -6051,7 +6063,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) tx_recovery: /* work_done is guaranteed to be less than budget. */ napi_complete(napi); - schedule_work(&tp->reset_task); + tg3_reset_task_schedule(tp); return work_done; } @@ -6345,6 +6357,7 @@ static void tg3_reset_task(struct work_struct *work) tg3_full_lock(tp, 0); if (!netif_running(tp->dev)) { + tg3_flag_clear(tp, RESET_TASK_PENDING); tg3_full_unlock(tp); return; } @@ -6382,6 +6395,8 @@ out: if (!err) tg3_phy_start(tp); + + tg3_flag_clear(tp, RESET_TASK_PENDING); } static void tg3_tx_timeout(struct net_device *dev) @@ -6393,7 +6408,7 @@ static void tg3_tx_timeout(struct net_device *dev) tg3_dump_state(tp); } - schedule_work(&tp->reset_task); + tg3_reset_task_schedule(tp); } /* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */ @@ -9228,7 +9243,7 @@ static void tg3_timer(unsigned long __opaque) if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { tg3_flag_set(tp, RESTART_TIMER); spin_unlock(&tp->lock); - schedule_work(&tp->reset_task); + tg3_reset_task_schedule(tp); return; } } @@ -9785,7 +9800,7 @@ static int tg3_close(struct net_device *dev) struct tg3 *tp = netdev_priv(dev); tg3_napi_disable(tp); - cancel_work_sync(&tp->reset_task); + tg3_reset_task_cancel(tp); netif_tx_stop_all_queues(dev); @@ -15685,7 +15700,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) if (tp->fw) release_firmware(tp->fw); - cancel_work_sync(&tp->reset_task); + tg3_reset_task_cancel(tp); if (tg3_flag(tp, USE_PHYLIB)) { tg3_phy_fini(tp); @@ -15719,7 +15734,7 @@ static int tg3_suspend(struct device *device) if (!netif_running(dev)) return 0; - flush_work_sync(&tp->reset_task); + tg3_reset_task_cancel(tp); tg3_phy_stop(tp); tg3_netif_stop(tp); @@ -15835,7 +15850,7 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, tg3_flag_clear(tp, RESTART_TIMER); /* Want to make sure that the reset task doesn't run */ - cancel_work_sync(&tp->reset_task); + tg3_reset_task_cancel(tp); tg3_flag_clear(tp, TX_RECOVERY_PENDING); tg3_flag_clear(tp, RESTART_TIMER); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index acfa265733ad..610fd84cc60f 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -2922,6 +2922,7 @@ enum TG3_FLAGS { TG3_FLAG_APE_HAS_NCSI, TG3_FLAG_5717_PLUS, TG3_FLAG_4K_FIFO_LIMIT, + TG3_FLAG_RESET_TASK_PENDING, /* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */ TG3_FLAG_NUMBER_OF_FLAGS, /* Last entry in enum TG3_FLAGS */ -- cgit v1.2.3 From 5b1906241905d9bd1abe920854b3d43c2b9c85e1 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:15:04 +0000 Subject: tg3: Eliminate timer race with reset_task During shutdown, it is impossible to reliably disable the timer and reset_task threads. Each thread can schedule the other, which leads to shutdown code that chases its tail. To fix the problem, this patch removes the ability of tg3_reset_task to schedule a new timer thread. To support this change, tg3_timer no longer terminates itself, but rather goes into a polling mode. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 14 ++------------ drivers/net/ethernet/broadcom/tg3.h | 1 - 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index d4a85b795344..cc7349fd7fcd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6352,7 +6352,6 @@ static void tg3_reset_task(struct work_struct *work) { struct tg3 *tp = container_of(work, struct tg3, reset_task); int err; - unsigned int restart_timer; tg3_full_lock(tp, 0); @@ -6370,9 +6369,6 @@ static void tg3_reset_task(struct work_struct *work) tg3_full_lock(tp, 1); - restart_timer = tg3_flag(tp, RESTART_TIMER); - tg3_flag_clear(tp, RESTART_TIMER); - if (tg3_flag(tp, TX_RECOVERY_PENDING)) { tp->write32_tx_mbox = tg3_write32_tx_mbox; tp->write32_rx_mbox = tg3_write_flush_reg32; @@ -6387,9 +6383,6 @@ static void tg3_reset_task(struct work_struct *work) tg3_netif_start(tp); - if (restart_timer) - mod_timer(&tp->timer, jiffies + 1); - out: tg3_full_unlock(tp); @@ -9218,7 +9211,7 @@ static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; - if (tp->irq_sync) + if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) goto restart_timer; spin_lock(&tp->lock); @@ -9241,10 +9234,9 @@ static void tg3_timer(unsigned long __opaque) } if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - tg3_flag_set(tp, RESTART_TIMER); spin_unlock(&tp->lock); tg3_reset_task_schedule(tp); - return; + goto restart_timer; } } @@ -15847,12 +15839,10 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, tg3_netif_stop(tp); del_timer_sync(&tp->timer); - tg3_flag_clear(tp, RESTART_TIMER); /* Want to make sure that the reset task doesn't run */ tg3_reset_task_cancel(tp); tg3_flag_clear(tp, TX_RECOVERY_PENDING); - tg3_flag_clear(tp, RESTART_TIMER); netif_device_detach(netdev); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 610fd84cc60f..94b4bd049a33 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -2879,7 +2879,6 @@ enum TG3_FLAGS { TG3_FLAG_JUMBO_CAPABLE, TG3_FLAG_CHIP_RESETTING, TG3_FLAG_INIT_COMPLETE, - TG3_FLAG_RESTART_TIMER, TG3_FLAG_TSO_BUG, TG3_FLAG_IS_5788, TG3_FLAG_MAX_RXPEND_64, -- cgit v1.2.3 From 5ae7fa06bb90421bc63f1f1e56ab241b49bc7b91 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 4 Nov 2011 09:15:05 +0000 Subject: tg3: Update version to 3.121 This patch updates the tg3 version to 3.121. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index cc7349fd7fcd..bf4074167d6a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -89,10 +89,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 120 +#define TG3_MIN_NUM 121 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "August 18, 2011" +#define DRV_MODULE_RELDATE "November 2, 2011" #define RESET_KIND_SHUTDOWN 0 #define RESET_KIND_INIT 1 -- cgit v1.2.3 From 729e72a10930ef765c11a5a35031ba47f18221c4 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 2 Nov 2011 12:11:53 +0000 Subject: macvlan: receive multicast with local address When implementing VRRP v2 using macvlan several problems were discovered. VRRP is weird in that all routers participating in a redundant group use the same virtual MAC address. Macvlan is a natural driver to use for this but it doesn't work. The problem is that packets with a macvlan device's source address are not received. The problem is actually a regression that date back almost 2 years now. The original problems started with: commit 618e1b7482f7a8a4c6c6e8ccbe140e4c331df4e9 Author: Arnd Bergmann Date: Thu Nov 26 06:07:10 2009 +0000 macvlan: implement bridge, VEPA and private mode This patches restores the original 2.6.32 behavior. Allowing multicast packets received with the VRRP source address to be received. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index a3ce3d4561ed..74134970b709 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -192,6 +192,13 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) */ macvlan_broadcast(skb, port, src->dev, MACVLAN_MODE_VEPA); + else { + /* forward to original port. */ + vlan = src; + ret = macvlan_broadcast_one(skb, vlan, eth, 0); + goto out; + } + return RX_HANDLER_PASS; } -- cgit v1.2.3 From 433aee04a447fb2e769c4570f327d9c2a956117b Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Wed, 2 Nov 2011 00:30:52 +0000 Subject: i825xx:xscale:8390:freescale: Fix Kconfig dependancies i825xx and xscale are "sub" Kconfigs to NET_VENDOR_INTEL, so NET_VENDOR_INTEL should contain ALL the dependencies of the "sub" Kconfigs. Same with 8390 is a "sub" Kconfig to NET_VENDOR_NATSEMI, so NET_VENDOR_NATSEMI needs to contains ALL the dependencies. Freescale Kconfig only had fs_enet as a sub Kconfig, and already contained the needed dependencies, just cleaned up the dependencies. Reported-by: Geert Uytterhoeven Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/Kconfig | 3 +-- drivers/net/ethernet/intel/Kconfig | 6 +++++- drivers/net/ethernet/natsemi/Kconfig | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index 1cf671643d1f..c520cfd3b298 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig @@ -7,8 +7,7 @@ config NET_VENDOR_FREESCALE default y depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \ M523x || M527x || M5272 || M528x || M520x || M532x || \ - ARCH_MXC || ARCH_MXS || \ - (PPC_MPC52xx && PPC_BESTCOMM) + ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 61029dc7fa6f..76213162fbe3 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -5,7 +5,11 @@ config NET_VENDOR_INTEL bool "Intel devices" default y - depends on PCI || PCI_MSI + depends on PCI || PCI_MSI || ISA || ISA_DMA_API || ARM || \ + ARCH_ACORN || MCA || MCA_LEGACY || SNI_RM || SUN3 || \ + GSC || BVME6000 || MVME16x || ARCH_ENP2611 || \ + (ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR) || \ + EXPERIMENTAL ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig index 4a6b9fd073b6..eb836f770f50 100644 --- a/drivers/net/ethernet/natsemi/Kconfig +++ b/drivers/net/ethernet/natsemi/Kconfig @@ -5,7 +5,10 @@ config NET_VENDOR_NATSEMI bool "National Semi-conductor devices" default y - depends on MCA || MAC || MACH_JAZZ || PCI || XTENSA_PLATFORM_XT2000 + depends on AMIGA_PCMCIA || ARM || EISA || EXPERIMENTAL || H8300 || \ + ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MCA || \ + MCA_LEGACY || MIPS || PCI || PCMCIA || SUPERH || \ + XTENSA_PLATFORM_XT2000 || ZORRO ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from -- cgit v1.2.3 From c30bc94758ae2a38a5eb31767c1985c0aae0950b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 Nov 2011 00:07:32 +0000 Subject: netlink: validate NLA_MSECS length L2TP for example uses NLA_MSECS like this: policy: [L2TP_ATTR_RECV_TIMEOUT] = { .type = NLA_MSECS, }, code: if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); As nla_get_msecs() is essentially nla_get_u64() plus the conversion to a HZ-based value, this will not properly reject attributes from userspace that aren't long enough and might overrun the message. Add NLA_MSECS to the attribute minlen array to check the size properly. Cc: Thomas Graf Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- lib/nlattr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/nlattr.c b/lib/nlattr.c index ac09f2226dc7..a8408b6cacdf 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -20,6 +20,7 @@ static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_U16] = sizeof(u16), [NLA_U32] = sizeof(u32), [NLA_U64] = sizeof(u64), + [NLA_MSECS] = sizeof(u64), [NLA_NESTED] = NLA_HDRLEN, }; -- cgit v1.2.3 From 4b6cc7284ddc9a54910f111085ebf0143ef3f5bd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 Nov 2011 00:10:05 +0000 Subject: netlink: clarify attribute length check documentation The documentation for how the length of attributes is checked is wrong ("Exact length" isn't true, the policy checks are for "minimum length") and a bit misleading. Make it more complete and explain what really happens. Cc: Thomas Graf Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- include/net/netlink.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 98c185441bee..cb1f3504687f 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -192,8 +192,15 @@ enum { * NLA_NUL_STRING Maximum length of string (excluding NUL) * NLA_FLAG Unused * NLA_BINARY Maximum length of attribute payload - * NLA_NESTED_COMPAT Exact length of structure payload - * All other Exact length of attribute payload + * NLA_NESTED Don't use `len' field -- length verification is + * done by checking len of nested header (or empty) + * NLA_NESTED_COMPAT Minimum length of structure payload + * NLA_U8, NLA_U16, + * NLA_U32, NLA_U64, + * NLA_MSECS Leaving the length field zero will verify the + * given type fits, using it verifies minimum length + * just like "All other" + * All other Minimum length of attribute payload * * Example: * static const struct nla_policy my_policy[ATTR_MAX+1] = { -- cgit v1.2.3 From 27d240fdae2808d727ad9ce48ec029731a457524 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 4 Nov 2011 12:17:17 +0000 Subject: sky2: fix regression on Yukon Optima Changes to support other Optima types, introduced an accidental regression that caused 88E8059 to come up in 10Mbit/sec. The Yukon Optima supports a reverse auto-negotiation feature that was incorrectly setup, and not needed. The feature could be used to allow wake-on-lan at higher speeds. But doing it correctly would require other changes to initialization. Reported-by: Pavel Mateja Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/sky2.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index cbd026f3bc57..fdc6c394c683 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -366,17 +366,6 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec); } } else { - if (hw->chip_id >= CHIP_ID_YUKON_OPT) { - u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2); - - /* enable PHY Reverse Auto-Negotiation */ - ctrl2 |= 1u << 13; - - /* Write PHY changes (SW-reset must follow) */ - gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2); - } - - /* disable energy detect */ ctrl &= ~PHY_M_PC_EN_DET_MSK; -- cgit v1.2.3 From 589665f5a6008dbce1d0af2cb93e94a80bf78151 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 4 Nov 2011 08:21:38 +0000 Subject: bonding: comparing a u8 with -1 is always false slave->duplex is a u8 type so the in bond_info_show_slave() when we check "if (slave->duplex == -1)", it's always false. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/bonding/bond_procfs.c | 4 ++-- include/linux/ethtool.h | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b2b9109b6712..b0c577256487 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave) u32 slave_speed; int res; - slave->speed = -1; - slave->duplex = -1; + slave->speed = SPEED_UNKNOWN; + slave->duplex = DUPLEX_UNKNOWN; res = __ethtool_get_settings(slave_dev, &ecmd); if (res < 0) diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index d2ff52e63cbb..17206da2fab7 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -157,12 +157,12 @@ static void bond_info_show_slave(struct seq_file *seq, seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); seq_printf(seq, "MII Status: %s\n", (slave->link == BOND_LINK_UP) ? "up" : "down"); - if (slave->speed == -1) + if (slave->speed == SPEED_UNKNOWN) seq_printf(seq, "Speed: %s\n", "Unknown"); else seq_printf(seq, "Speed: %d Mbps\n", slave->speed); - if (slave->duplex == -1) + if (slave->duplex == DUPLEX_UNKNOWN) seq_printf(seq, "Duplex: %s\n", "Unknown"); else seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 45f00b61c096..de33de1e2052 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -1097,10 +1097,12 @@ struct ethtool_ops { #define SPEED_1000 1000 #define SPEED_2500 2500 #define SPEED_10000 10000 +#define SPEED_UNKNOWN -1 /* Duplex, half or full. */ #define DUPLEX_HALF 0x00 #define DUPLEX_FULL 0x01 +#define DUPLEX_UNKNOWN 0xff /* Which connector port. */ #define PORT_TP 0x00 -- cgit v1.2.3 From 1a6422f67fbf691cf8721076619aeead9183403d Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 4 Nov 2011 12:58:41 +0000 Subject: etherh: Add MAINTAINERS entry for etherh During the re-organization of Ethernet drivers, the MAINTAINERS entry for etherh got dropped accidentally. CC: Russell King CC: Joe Perches Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index a6afe342f0fc..ecb2299a1601 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1032,6 +1032,7 @@ F: arch/arm/include/asm/hardware/ioc.h F: arch/arm/include/asm/hardware/iomd.h F: arch/arm/include/asm/hardware/memc.h F: arch/arm/mach-rpc/ +F: drivers/net/ethernet/8390/etherh.c F: drivers/net/ethernet/i825xx/ether1* F: drivers/net/ethernet/seeq/ether3* F: drivers/scsi/arm/ -- cgit v1.2.3 From 012641082b34433dac3cbb452e0a6ceccfd4643f Mon Sep 17 00:00:00 2001 From: "Rose, Gregory V" Date: Mon, 7 Nov 2011 07:44:17 +0000 Subject: ixgbe: Fix compile for kernel without CONFIG_PCI_IOV defined Fix compiler errors and warnings with CONFIG_PCI_IOV defined and not defined. Signed-off-by: Greg Rose Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 2 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index db95731863d7..00fcd39ad666 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -442,12 +442,14 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter, int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter) { +#ifdef CONFIG_PCI_IOV int i; for (i = 0; i < adapter->num_vfs; i++) { if (adapter->vfinfo[i].vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) return true; } +#endif return false; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h index 4a5d8897faab..df04f1a3857c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h @@ -42,11 +42,11 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); int ixgbe_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi); void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); -#ifdef CONFIG_PCI_IOV void ixgbe_disable_sriov(struct ixgbe_adapter *adapter); +int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter); +#ifdef CONFIG_PCI_IOV void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, const struct ixgbe_info *ii); -int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter); #endif -- cgit v1.2.3 From 23ba07991dad5a96a024c1b45cb602eef5f83df8 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Mon, 7 Nov 2011 05:54:58 +0000 Subject: usbnet: fix oops in usbnet_start_xmit This patch fixes the bug added in commit v3.1-rc7-1055-gf9b491e SKB can be NULL at this point, at least for cdc-ncm. Signed-off-by: Konstantin Khlebnikov Acked-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 7d6082160bcc..fae0fbd8bc88 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1057,7 +1057,8 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, unsigned long flags; int retval; - skb_tx_timestamp(skb); + if (skb) + skb_tx_timestamp(skb); // some devices want funky USB-level framing, for // win32 driver (usually) and/or hardware quirks -- cgit v1.2.3 From 039c811cb0e6c5696086072794bb79fc7011c765 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 7 Nov 2011 13:27:30 -0500 Subject: wanrouter: Remove kernel_lock annotations The BKL is gone, these annotations are useless. Signed-off-by: Richard Weinberger Signed-off-by: David S. Miller --- net/wanrouter/wanproc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index f346395314ba..c43612ee96bb 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -81,7 +81,6 @@ static struct proc_dir_entry *proc_router; * Iterator */ static void *r_start(struct seq_file *m, loff_t *pos) - __acquires(kernel_lock) { struct wan_device *wandev; loff_t l = *pos; @@ -103,7 +102,6 @@ static void *r_next(struct seq_file *m, void *v, loff_t *pos) } static void r_stop(struct seq_file *m, void *v) - __releases(kernel_lock) { mutex_unlock(&config_mutex); } -- cgit v1.2.3 From dd1294c4ed25725d13a6cb3d93ca0eb5fee14963 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Mon, 7 Nov 2011 13:28:20 -0500 Subject: MAINTAINERS/rds: update maintainer update for the actual maintainer Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ecb2299a1601..237c9ab22804 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5471,7 +5471,7 @@ S: Maintained F: drivers/net/ethernet/rdc/r6040.c RDS - RELIABLE DATAGRAM SOCKETS -M: Andy Grover +M: Venkat Venkatsubra L: rds-devel@oss.oracle.com (moderated for non-subscribers) S: Supported F: net/rds/ -- cgit v1.2.3 From f9c4082df59e43c6667db197a4fb3eb3286f3fc1 Mon Sep 17 00:00:00 2001 From: david decotigny Date: Sat, 5 Nov 2011 14:38:20 +0000 Subject: forcedeth: fix race when unloading module When forcedeth module is unloaded, there exists a path that can lead to mod_timer() after del_timer_sync(), causing an oops. This patch short-circuits this unneeded path, which originates in nv_get_ethtool_stats(). Tested: x86_64 16-way + 3 ethtool -S infinite loops + 100Mbps incoming traffic + rmmod/modprobe/ifconfig in a loop Initial-Author: Salman Qazi Discussion: http://patchwork.ozlabs.org/patch/123548/ Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/ethernet/nvidia/forcedeth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 1e37eb98c4e2..344cb5fa512d 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -4566,7 +4566,7 @@ static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *e struct fe_priv *np = netdev_priv(dev); /* update stats */ - nv_do_stats_poll((unsigned long)dev); + nv_get_hw_stats(dev); memcpy(buffer, &np->estats, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64)); } -- cgit v1.2.3 From 2a4e7a085fb44369c450c92cf8bd53b91f874a57 Mon Sep 17 00:00:00 2001 From: Mike Ditto Date: Sat, 5 Nov 2011 14:38:21 +0000 Subject: forcedeth: Acknowledge only interrupts that are being processed This is to avoid a race, accidentally acknowledging an interrupt that we didn't notice and won't immediately process. This is based solely on code inspection; it is not known if there was an actual bug here. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/ethernet/nvidia/forcedeth.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 344cb5fa512d..b7cf4b6e15ec 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -3398,7 +3398,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; - writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); + writel(events, base + NvRegMSIXIrqStatus); + netdev_dbg(dev, "tx irq events: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3509,7 +3510,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; - writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); + writel(events, base + NvRegMSIXIrqStatus); + netdev_dbg(dev, "rx irq events: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3553,7 +3555,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) for (i = 0;; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; - writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); + writel(events, base + NvRegMSIXIrqStatus); + netdev_dbg(dev, "irq events: %08x\n", events); if (!(events & np->irqmask)) break; @@ -3617,10 +3620,10 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) if (!(np->msi_flags & NV_MSI_X_ENABLED)) { events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; - writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus); + writel(events & NVREG_IRQ_TIMER, base + NvRegIrqStatus); } else { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; - writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); + writel(events & NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); } pci_push(base); if (!(events & NVREG_IRQ_TIMER)) -- cgit v1.2.3 From 4687f3f364a1d5b2df815a8c58a763cab57724e8 Mon Sep 17 00:00:00 2001 From: david decotigny Date: Sat, 5 Nov 2011 14:38:22 +0000 Subject: forcedeth: remove unneeded stats updates Function ndo_get_stats() updates most of the stats from hardware registers, making the manual updates un-needed. This change removes these manual updates. Main exception is rx_missed_errors which needs manual update. Another exception is rx_packets, still updated manually in this commit to make sure this patch doesn't change behavior of driver. This will be addressed by a future patch. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/ethernet/nvidia/forcedeth.c | 35 +-------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index b7cf4b6e15ec..2f1eaee5cf00 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -2374,16 +2374,8 @@ static int nv_tx_done(struct net_device *dev, int limit) if (np->desc_ver == DESC_VER_1) { if (flags & NV_TX_LASTPACKET) { if (flags & NV_TX_ERROR) { - if (flags & NV_TX_UNDERFLOW) - dev->stats.tx_fifo_errors++; - if (flags & NV_TX_CARRIERLOST) - dev->stats.tx_carrier_errors++; if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK)) nv_legacybackoff_reseed(dev); - dev->stats.tx_errors++; - } else { - dev->stats.tx_packets++; - dev->stats.tx_bytes += np->get_tx_ctx->skb->len; } dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; @@ -2392,16 +2384,8 @@ static int nv_tx_done(struct net_device *dev, int limit) } else { if (flags & NV_TX2_LASTPACKET) { if (flags & NV_TX2_ERROR) { - if (flags & NV_TX2_UNDERFLOW) - dev->stats.tx_fifo_errors++; - if (flags & NV_TX2_CARRIERLOST) - dev->stats.tx_carrier_errors++; if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) nv_legacybackoff_reseed(dev); - dev->stats.tx_errors++; - } else { - dev->stats.tx_packets++; - dev->stats.tx_bytes += np->get_tx_ctx->skb->len; } dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; @@ -2434,9 +2418,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) nv_unmap_txskb(np, np->get_tx_ctx); if (flags & NV_TX2_LASTPACKET) { - if (!(flags & NV_TX2_ERROR)) - dev->stats.tx_packets++; - else { + if (flags & NV_TX2_ERROR) { if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) { if (np->driver_data & DEV_HAS_GEAR_MODE) nv_gear_backoff_reseed(dev); @@ -2636,7 +2618,6 @@ static int nv_rx_process(struct net_device *dev, int limit) if ((flags & NV_RX_ERROR_MASK) == NV_RX_ERROR4) { len = nv_getlen(dev, skb->data, len); if (len < 0) { - dev->stats.rx_errors++; dev_kfree_skb(skb); goto next_pkt; } @@ -2650,11 +2631,6 @@ static int nv_rx_process(struct net_device *dev, int limit) else { if (flags & NV_RX_MISSEDFRAME) dev->stats.rx_missed_errors++; - if (flags & NV_RX_CRCERR) - dev->stats.rx_crc_errors++; - if (flags & NV_RX_OVERFLOW) - dev->stats.rx_over_errors++; - dev->stats.rx_errors++; dev_kfree_skb(skb); goto next_pkt; } @@ -2670,7 +2646,6 @@ static int nv_rx_process(struct net_device *dev, int limit) if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_ERROR4) { len = nv_getlen(dev, skb->data, len); if (len < 0) { - dev->stats.rx_errors++; dev_kfree_skb(skb); goto next_pkt; } @@ -2682,11 +2657,6 @@ static int nv_rx_process(struct net_device *dev, int limit) } /* the rest are hard errors */ else { - if (flags & NV_RX2_CRCERR) - dev->stats.rx_crc_errors++; - if (flags & NV_RX2_OVERFLOW) - dev->stats.rx_over_errors++; - dev->stats.rx_errors++; dev_kfree_skb(skb); goto next_pkt; } @@ -2704,7 +2674,6 @@ static int nv_rx_process(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; - dev->stats.rx_bytes += len; next_pkt: if (unlikely(np->get_rx.orig++ == np->last_rx.orig)) np->get_rx.orig = np->first_rx.orig; @@ -2787,9 +2756,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) __vlan_hwaccel_put_tag(skb, vid); } napi_gro_receive(&np->napi, skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += len; } else { dev_kfree_skb(skb); } -- cgit v1.2.3 From 0bdfea8ba856826f5901fda608013f323c87f661 Mon Sep 17 00:00:00 2001 From: Mandeep Baines Date: Sat, 5 Nov 2011 14:38:23 +0000 Subject: forcedeth: Improve stats counters Rx byte count was off; instead use the hardware's count. Tx packet count was counting pre-TSO packets; instead count on-the-wire packets. Report hardware dropped frame count as rx_fifo_errors. - The count of transmitted packets reported by the forcedeth driver reports pre-TSO (TCP Segmentation Offload) packet counts and not the count of the number of packets sent on the wire. This change fixes the forcedeth driver to report the correct count. Fixed the code by copying the count stored in the NIC H/W to the value reported by the driver. - Count rx_drop_frame errors as rx_fifo_errors: We see a lot of rx_drop_frame errors if we disable the rx bottom-halves for too long. Normally, rx_fifo_errors would be counted in this case. The rx_drop_frame error count is private to forcedeth and is not reported by ifconfig or sysfs. The rx_fifo_errors count is currently unused in the forcedeth driver. It is reported by ifconfig as overruns. This change reports rx_drop_frame errors as rx_fifo_errors. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/ethernet/nvidia/forcedeth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 2f1eaee5cf00..0c10ff700cbc 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -1682,6 +1682,7 @@ static void nv_get_hw_stats(struct net_device *dev) np->estats.tx_pause += readl(base + NvRegTxPause); np->estats.rx_pause += readl(base + NvRegRxPause); np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame); + np->estats.rx_errors_total += np->estats.rx_drop_frame; } if (np->driver_data & DEV_HAS_STATISTICS_V3) { @@ -1706,11 +1707,14 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev) nv_get_hw_stats(dev); /* copy to net_device stats */ + dev->stats.tx_packets = np->estats.tx_packets; + dev->stats.rx_bytes = np->estats.rx_bytes; dev->stats.tx_bytes = np->estats.tx_bytes; dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors; dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors; dev->stats.rx_crc_errors = np->estats.rx_crc_errors; dev->stats.rx_over_errors = np->estats.rx_over_errors; + dev->stats.rx_fifo_errors = np->estats.rx_drop_frame; dev->stats.rx_errors = np->estats.rx_errors_total; dev->stats.tx_errors = np->estats.tx_errors_total; } -- cgit v1.2.3 From e45a618753d5a8bc9086382f73bbc2d6a3399250 Mon Sep 17 00:00:00 2001 From: david decotigny Date: Sat, 5 Nov 2011 14:38:24 +0000 Subject: forcedeth: fix a few sparse warnings (variable shadowing) This fixes the following sparse warnings: drivers/net/ethernet/nvidia/forcedeth.c:2113:7: warning: symbol 'size' shadows an earlier one drivers/net/ethernet/nvidia/forcedeth.c:2102:6: originally declared here drivers/net/ethernet/nvidia/forcedeth.c:2155:7: warning: symbol 'size' shadows an earlier one drivers/net/ethernet/nvidia/forcedeth.c:2102:6: originally declared here drivers/net/ethernet/nvidia/forcedeth.c:2227:7: warning: symbol 'size' shadows an earlier one drivers/net/ethernet/nvidia/forcedeth.c:2215:6: originally declared here drivers/net/ethernet/nvidia/forcedeth.c:2271:7: warning: symbol 'size' shadows an earlier one drivers/net/ethernet/nvidia/forcedeth.c:2215:6: originally declared here drivers/net/ethernet/nvidia/forcedeth.c:2986:20: warning: symbol 'addr' shadows an earlier one drivers/net/ethernet/nvidia/forcedeth.c:2963:6: originally declared here Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/ethernet/nvidia/forcedeth.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 0c10ff700cbc..1dca57013cb2 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -2103,10 +2103,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* add fragments to entries count */ for (i = 0; i < fragments; i++) { - u32 size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + u32 frag_size = skb_frag_size(&skb_shinfo(skb)->frags[i]); - entries += (size >> NV_TX2_TSO_MAX_SHIFT) + - ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); + entries += (frag_size >> NV_TX2_TSO_MAX_SHIFT) + + ((frag_size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } spin_lock_irqsave(&np->lock, flags); @@ -2145,13 +2145,13 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* setup the fragments */ for (i = 0; i < fragments; i++) { const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - u32 size = skb_frag_size(frag); + u32 frag_size = skb_frag_size(frag); offset = 0; do { prev_tx = put_tx; prev_tx_ctx = np->put_tx_ctx; - bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; + bcnt = (frag_size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : frag_size; np->put_tx_ctx->dma = skb_frag_dma_map( &np->pci_dev->dev, frag, offset, @@ -2163,12 +2163,12 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); offset += bcnt; - size -= bcnt; + frag_size -= bcnt; if (unlikely(put_tx++ == np->last_tx.orig)) put_tx = np->first_tx.orig; if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) np->put_tx_ctx = np->first_tx_ctx; - } while (size); + } while (frag_size); } /* set last fragment flag */ @@ -2217,10 +2217,10 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, /* add fragments to entries count */ for (i = 0; i < fragments; i++) { - u32 size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + u32 frag_size = skb_frag_size(&skb_shinfo(skb)->frags[i]); - entries += (size >> NV_TX2_TSO_MAX_SHIFT) + - ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); + entries += (frag_size >> NV_TX2_TSO_MAX_SHIFT) + + ((frag_size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } spin_lock_irqsave(&np->lock, flags); @@ -2261,13 +2261,13 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, /* setup the fragments */ for (i = 0; i < fragments; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - u32 size = skb_frag_size(frag); + u32 frag_size = skb_frag_size(frag); offset = 0; do { prev_tx = put_tx; prev_tx_ctx = np->put_tx_ctx; - bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; + bcnt = (frag_size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : frag_size; np->put_tx_ctx->dma = skb_frag_dma_map( &np->pci_dev->dev, frag, offset, @@ -2280,12 +2280,12 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); offset += bcnt; - size -= bcnt; + frag_size -= bcnt; if (unlikely(put_tx++ == np->last_tx.ex)) put_tx = np->first_tx.ex; if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) np->put_tx_ctx = np->first_tx_ctx; - } while (size); + } while (frag_size); } /* set last fragment flag */ @@ -2933,11 +2933,11 @@ static void nv_set_multicast(struct net_device *dev) struct netdev_hw_addr *ha; netdev_for_each_mc_addr(ha, dev) { - unsigned char *addr = ha->addr; + unsigned char *hw_addr = ha->addr; u32 a, b; - a = le32_to_cpu(*(__le32 *) addr); - b = le16_to_cpu(*(__le16 *) (&addr[4])); + a = le32_to_cpu(*(__le32 *) hw_addr); + b = le16_to_cpu(*(__le16 *) (&hw_addr[4])); alwaysOn[0] &= a; alwaysOff[0] &= ~a; alwaysOn[1] &= b; -- cgit v1.2.3