aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-03-20 15:19:32 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-20 15:19:32 -0400
commitf379fb991b9f958be2c89df8dc0e446d67f657e4 (patch)
tree71da3004964f6dd11fbdc906cf9a99caec9f7bdf /drivers/net
parent9d73adf431e093b23fb4990f1ade11283cb67a98 (diff)
parentb9d5319041999401d29e7efcd5d15664edfaad2e (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
John W. Linville says: ==================== I present to you another batch of fixes intended for the 3.9 stream... On the bluetooth bits, Gustavo says: "I put together 3 fixes intended for 3.9, there are support for two new devices and a NULL dereference fix in the SCO code." Amitkumar Karwar fixes a command queueing race in mwifiex. Bing Zhao provides a pair of mwifiex related to cleaning-up before a shutdown. Felix Fietkau provides an ath9k fix for a regression caused by an earlier calibration fix, and another ath9k fix to avoid race conditions that unnecessarily lead to chip resets. Jussi Kivilinna prevents and skbuff leak in rtlwifi. Stanislaw Gruszka corrects a length paramater for a DMA buffer mapping operation in iwlegacy. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c26
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c22
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c22
-rw-r--r--drivers/net/wireless/mwifiex/init.c8
-rw-r--r--drivers/net/wireless/mwifiex/main.h4
-rw-r--r--drivers/net/wireless/mwifiex/scan.c8
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c10
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c1
9 files changed, 62 insertions, 43 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 4cc13940c895..f76c3ca07a45 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
1023 AR_PHY_AGC_CONTROL_FLTR_CAL | 1023 AR_PHY_AGC_CONTROL_FLTR_CAL |
1024 AR_PHY_AGC_CONTROL_PKDET_CAL; 1024 AR_PHY_AGC_CONTROL_PKDET_CAL;
1025 1025
1026 /* Use chip chainmask only for calibration */
1026 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); 1027 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1027 1028
1028 if (rtt) { 1029 if (rtt) {
@@ -1150,6 +1151,9 @@ skip_tx_iqcal:
1150 ar9003_hw_rtt_disable(ah); 1151 ar9003_hw_rtt_disable(ah);
1151 } 1152 }
1152 1153
1154 /* Revert chainmask to runtime parameters */
1155 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1156
1153 /* Initialize list pointers */ 1157 /* Initialize list pointers */
1154 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; 1158 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1155 1159
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index ade3afb21f91..39c84ecf6a42 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work)
28 int i; 28 int i;
29 bool needreset = false; 29 bool needreset = false;
30 30
31 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) 31 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
32 if (ATH_TXQ_SETUP(sc, i)) { 32 txq = sc->tx.txq_map[i];
33 txq = &sc->tx.txq[i]; 33
34 ath_txq_lock(sc, txq); 34 ath_txq_lock(sc, txq);
35 if (txq->axq_depth) { 35 if (txq->axq_depth) {
36 if (txq->axq_tx_inprogress) { 36 if (txq->axq_tx_inprogress) {
37 needreset = true; 37 needreset = true;
38 ath_txq_unlock(sc, txq); 38 ath_txq_unlock(sc, txq);
39 break; 39 break;
40 } else { 40 } else {
41 txq->axq_tx_inprogress = true; 41 txq->axq_tx_inprogress = true;
42 }
43 } 42 }
44 ath_txq_unlock_complete(sc, txq);
45 } 43 }
44 ath_txq_unlock_complete(sc, txq);
45 }
46 46
47 if (needreset) { 47 if (needreset) {
48 ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, 48 ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index 3630a41df50d..c353b5f19c8c 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -475,6 +475,7 @@ il3945_tx_skb(struct il_priv *il,
475 dma_addr_t txcmd_phys; 475 dma_addr_t txcmd_phys;
476 int txq_id = skb_get_queue_mapping(skb); 476 int txq_id = skb_get_queue_mapping(skb);
477 u16 len, idx, hdr_len; 477 u16 len, idx, hdr_len;
478 u16 firstlen, secondlen;
478 u8 id; 479 u8 id;
479 u8 unicast; 480 u8 unicast;
480 u8 sta_id; 481 u8 sta_id;
@@ -589,21 +590,22 @@ il3945_tx_skb(struct il_priv *il,
589 len = 590 len =
590 sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) + 591 sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) +
591 hdr_len; 592 hdr_len;
592 len = (len + 3) & ~3; 593 firstlen = (len + 3) & ~3;
593 594
594 /* Physical address of this Tx command's header (not MAC header!), 595 /* Physical address of this Tx command's header (not MAC header!),
595 * within command buffer array. */ 596 * within command buffer array. */
596 txcmd_phys = 597 txcmd_phys =
597 pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE); 598 pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen,
599 PCI_DMA_TODEVICE);
598 if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys))) 600 if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys)))
599 goto drop_unlock; 601 goto drop_unlock;
600 602
601 /* Set up TFD's 2nd entry to point directly to remainder of skb, 603 /* Set up TFD's 2nd entry to point directly to remainder of skb,
602 * if any (802.11 null frames have no payload). */ 604 * if any (802.11 null frames have no payload). */
603 len = skb->len - hdr_len; 605 secondlen = skb->len - hdr_len;
604 if (len) { 606 if (secondlen > 0) {
605 phys_addr = 607 phys_addr =
606 pci_map_single(il->pci_dev, skb->data + hdr_len, len, 608 pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
607 PCI_DMA_TODEVICE); 609 PCI_DMA_TODEVICE);
608 if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) 610 if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr)))
609 goto drop_unlock; 611 goto drop_unlock;
@@ -611,12 +613,12 @@ il3945_tx_skb(struct il_priv *il,
611 613
612 /* Add buffer containing Tx command and MAC(!) header to TFD's 614 /* Add buffer containing Tx command and MAC(!) header to TFD's
613 * first entry */ 615 * first entry */
614 il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); 616 il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
615 dma_unmap_addr_set(out_meta, mapping, txcmd_phys); 617 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
616 dma_unmap_len_set(out_meta, len, len); 618 dma_unmap_len_set(out_meta, len, firstlen);
617 if (len) 619 if (secondlen > 0)
618 il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, 620 il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0,
619 U32_PAD(len)); 621 U32_PAD(secondlen));
620 622
621 if (!ieee80211_has_morefrags(hdr->frame_control)) { 623 if (!ieee80211_has_morefrags(hdr->frame_control)) {
622 txq->need_update = 1; 624 txq->need_update = 1;
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 20a6c5555873..b5c8b962ce12 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -157,6 +157,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
157 return -1; 157 return -1;
158 } 158 }
159 159
160 cmd_code = le16_to_cpu(host_cmd->command);
161 cmd_size = le16_to_cpu(host_cmd->size);
162
163 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET &&
164 cmd_code != HostCmd_CMD_FUNC_SHUTDOWN &&
165 cmd_code != HostCmd_CMD_FUNC_INIT) {
166 dev_err(adapter->dev,
167 "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
168 cmd_code);
169 mwifiex_complete_cmd(adapter, cmd_node);
170 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
171 return -1;
172 }
173
160 /* Set command sequence number */ 174 /* Set command sequence number */
161 adapter->seq_num++; 175 adapter->seq_num++;
162 host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO 176 host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
@@ -168,9 +182,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
168 adapter->curr_cmd = cmd_node; 182 adapter->curr_cmd = cmd_node;
169 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 183 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
170 184
171 cmd_code = le16_to_cpu(host_cmd->command);
172 cmd_size = le16_to_cpu(host_cmd->size);
173
174 /* Adjust skb length */ 185 /* Adjust skb length */
175 if (cmd_node->cmd_skb->len > cmd_size) 186 if (cmd_node->cmd_skb->len > cmd_size)
176 /* 187 /*
@@ -484,8 +495,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
484 495
485 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, 496 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
486 data_buf); 497 data_buf);
487 if (!ret)
488 ret = mwifiex_wait_queue_complete(adapter);
489 498
490 return ret; 499 return ret;
491} 500}
@@ -588,9 +597,10 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
588 if (cmd_no == HostCmd_CMD_802_11_SCAN) { 597 if (cmd_no == HostCmd_CMD_802_11_SCAN) {
589 mwifiex_queue_scan_cmd(priv, cmd_node); 598 mwifiex_queue_scan_cmd(priv, cmd_node);
590 } else { 599 } else {
591 adapter->cmd_queued = cmd_node;
592 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); 600 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
593 queue_work(adapter->workqueue, &adapter->main_work); 601 queue_work(adapter->workqueue, &adapter->main_work);
602 if (cmd_node->wait_q_enabled)
603 ret = mwifiex_wait_queue_complete(adapter, cmd_node);
594 } 604 }
595 605
596 return ret; 606 return ret;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e38aa9b3663d..0ff4c37ab42a 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -709,6 +709,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
709 return ret; 709 return ret;
710 } 710 }
711 711
712 /* cancel current command */
713 if (adapter->curr_cmd) {
714 dev_warn(adapter->dev, "curr_cmd is still in processing\n");
715 del_timer(&adapter->cmd_timer);
716 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
717 adapter->curr_cmd = NULL;
718 }
719
712 /* shut down mwifiex */ 720 /* shut down mwifiex */
713 dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); 721 dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
714 722
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 553adfb0aa81..7035ade9af74 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -723,7 +723,6 @@ struct mwifiex_adapter {
723 u16 cmd_wait_q_required; 723 u16 cmd_wait_q_required;
724 struct mwifiex_wait_queue cmd_wait_q; 724 struct mwifiex_wait_queue cmd_wait_q;
725 u8 scan_wait_q_woken; 725 u8 scan_wait_q_woken;
726 struct cmd_ctrl_node *cmd_queued;
727 spinlock_t queue_lock; /* lock for tx queues */ 726 spinlock_t queue_lock; /* lock for tx queues */
728 struct completion fw_load; 727 struct completion fw_load;
729 u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; 728 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
@@ -1018,7 +1017,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
1018 struct mwifiex_multicast_list *mcast_list); 1017 struct mwifiex_multicast_list *mcast_list);
1019int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, 1018int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
1020 struct net_device *dev); 1019 struct net_device *dev);
1021int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); 1020int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
1021 struct cmd_ctrl_node *cmd_queued);
1022int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, 1022int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
1023 struct cfg80211_ssid *req_ssid); 1023 struct cfg80211_ssid *req_ssid);
1024int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); 1024int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index bb60c2754a97..d215b4d3c51b 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1388,10 +1388,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1388 list_del(&cmd_node->list); 1388 list_del(&cmd_node->list);
1389 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1389 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1390 flags); 1390 flags);
1391 adapter->cmd_queued = cmd_node;
1392 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, 1391 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1393 true); 1392 true);
1394 queue_work(adapter->workqueue, &adapter->main_work); 1393 queue_work(adapter->workqueue, &adapter->main_work);
1394
1395 /* Perform internal scan synchronously */
1396 if (!priv->scan_request)
1397 mwifiex_wait_queue_complete(adapter, cmd_node);
1395 } else { 1398 } else {
1396 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1399 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1397 flags); 1400 flags);
@@ -1946,9 +1949,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
1946 /* Normal scan */ 1949 /* Normal scan */
1947 ret = mwifiex_scan_networks(priv, NULL); 1950 ret = mwifiex_scan_networks(priv, NULL);
1948 1951
1949 if (!ret)
1950 ret = mwifiex_wait_queue_complete(priv->adapter);
1951
1952 up(&priv->async_sem); 1952 up(&priv->async_sem);
1953 1953
1954 return ret; 1954 return ret;
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 9f33c92c90f5..13100f8de3db 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -54,16 +54,10 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
54 * This function waits on a cmd wait queue. It also cancels the pending 54 * This function waits on a cmd wait queue. It also cancels the pending
55 * request after waking up, in case of errors. 55 * request after waking up, in case of errors.
56 */ 56 */
57int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) 57int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
58 struct cmd_ctrl_node *cmd_queued)
58{ 59{
59 int status; 60 int status;
60 struct cmd_ctrl_node *cmd_queued;
61
62 if (!adapter->cmd_queued)
63 return 0;
64
65 cmd_queued = adapter->cmd_queued;
66 adapter->cmd_queued = NULL;
67 61
68 dev_dbg(adapter->dev, "cmd pending\n"); 62 dev_dbg(adapter->dev, "cmd pending\n");
69 atomic_inc(&adapter->cmd_pending); 63 atomic_inc(&adapter->cmd_pending);
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 156b52732f3d..5847d6d0881e 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -851,6 +851,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
851 if (unlikely(!_urb)) { 851 if (unlikely(!_urb)) {
852 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 852 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
853 "Can't allocate urb. Drop skb!\n"); 853 "Can't allocate urb. Drop skb!\n");
854 kfree_skb(skb);
854 return; 855 return;
855 } 856 }
856 _rtl_submit_tx_urb(hw, _urb); 857 _rtl_submit_tx_urb(hw, _urb);