aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-10-18 13:34:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-10-18 13:34:56 -0400
commit8245d02369859cc5c87b71722b327396d7a3ae75 (patch)
tree7fb5dd94f9a540af69cd70736397e5cce6d36590
parent9612bd1ee3e3136e4748d7175bb6e7551482cc2e (diff)
parentf6b129527ca15bae29ffb9417ddaa1c9d99ffc5d (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c31
4 files changed, 43 insertions, 30 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index da442b81370a..1fef5240e6ad 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -433,27 +433,19 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
433 /* Copy MAC header from skb into command buffer */ 433 /* Copy MAC header from skb into command buffer */
434 memcpy(tx_cmd->hdr, hdr, hdr_len); 434 memcpy(tx_cmd->hdr, hdr, hdr_len);
435 435
436 txq_id = info->hw_queue;
437
436 if (is_agg) 438 if (is_agg)
437 txq_id = priv->tid_data[sta_id][tid].agg.txq_id; 439 txq_id = priv->tid_data[sta_id][tid].agg.txq_id;
438 else if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { 440 else if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
439 /* 441 /*
440 * Send this frame after DTIM -- there's a special queue
441 * reserved for this for contexts that support AP mode.
442 */
443 txq_id = ctx->mcast_queue;
444
445 /*
446 * The microcode will clear the more data 442 * The microcode will clear the more data
447 * bit in the last frame it transmits. 443 * bit in the last frame it transmits.
448 */ 444 */
449 hdr->frame_control |= 445 hdr->frame_control |=
450 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 446 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
451 } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) 447 }
452 txq_id = IWL_AUX_QUEUE;
453 else
454 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
455 448
456 WARN_ON_ONCE(!is_agg && txq_id != info->hw_queue);
457 WARN_ON_ONCE(is_agg && 449 WARN_ON_ONCE(is_agg &&
458 priv->queue_to_mac80211[txq_id] != info->hw_queue); 450 priv->queue_to_mac80211[txq_id] != info->hw_queue);
459 451
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 80b47508647c..c6bac7c90b00 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -601,7 +601,7 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
601{ 601{
602 int ret; 602 int ret;
603 603
604 if (trans->state != IWL_TRANS_FW_ALIVE) { 604 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
605 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); 605 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
606 return -EIO; 606 return -EIO;
607 } 607 }
@@ -640,8 +640,8 @@ static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
640static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, 640static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
641 struct iwl_device_cmd *dev_cmd, int queue) 641 struct iwl_device_cmd *dev_cmd, int queue)
642{ 642{
643 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 643 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
644 "%s bad state = %d", __func__, trans->state); 644 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
645 645
646 return trans->ops->tx(trans, skb, dev_cmd, queue); 646 return trans->ops->tx(trans, skb, dev_cmd, queue);
647} 647}
@@ -649,16 +649,16 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
649static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, 649static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
650 int ssn, struct sk_buff_head *skbs) 650 int ssn, struct sk_buff_head *skbs)
651{ 651{
652 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 652 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
653 "%s bad state = %d", __func__, trans->state); 653 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
654 654
655 trans->ops->reclaim(trans, queue, ssn, skbs); 655 trans->ops->reclaim(trans, queue, ssn, skbs);
656} 656}
657 657
658static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) 658static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue)
659{ 659{
660 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 660 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
661 "%s bad state = %d", __func__, trans->state); 661 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
662 662
663 trans->ops->txq_disable(trans, queue); 663 trans->ops->txq_disable(trans, queue);
664} 664}
@@ -669,8 +669,8 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
669{ 669{
670 might_sleep(); 670 might_sleep();
671 671
672 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 672 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
673 "%s bad state = %d", __func__, trans->state); 673 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
674 674
675 trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, 675 trans->ops->txq_enable(trans, queue, fifo, sta_id, tid,
676 frame_limit, ssn); 676 frame_limit, ssn);
@@ -685,8 +685,8 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
685 685
686static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) 686static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
687{ 687{
688 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 688 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
689 "%s bad state = %d", __func__, trans->state); 689 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
690 690
691 return trans->ops->wait_tx_queue_empty(trans); 691 return trans->ops->wait_tx_queue_empty(trans);
692} 692}
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 621fb71f282a..3a06832e8e90 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -93,10 +93,10 @@ static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif)
93 93
94static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) 94static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif)
95{ 95{
96 if (vif->bss_conf.assoc) 96 if (!vif->bss_conf.assoc)
97 return cpu_to_le32(vif->bss_conf.beacon_int);
98 else
99 return 0; 97 return 0;
98
99 return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
100} 100}
101 101
102static inline __le32 102static inline __le32
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 1424335163b9..80f1956b3be3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1465,7 +1465,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1465 spin_unlock_bh(&txq->lock); 1465 spin_unlock_bh(&txq->lock);
1466} 1466}
1467 1467
1468#define HOST_COMPLETE_TIMEOUT (2 * HZ) 1468#define HOST_COMPLETE_TIMEOUT (2 * HZ)
1469#define COMMAND_POKE_TIMEOUT (HZ / 10)
1469 1470
1470static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, 1471static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans,
1471 struct iwl_host_cmd *cmd) 1472 struct iwl_host_cmd *cmd)
@@ -1493,6 +1494,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1493 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1494 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1494 int cmd_idx; 1495 int cmd_idx;
1495 int ret; 1496 int ret;
1497 int timeout = HOST_COMPLETE_TIMEOUT;
1496 1498
1497 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", 1499 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
1498 get_cmd_string(trans_pcie, cmd->id)); 1500 get_cmd_string(trans_pcie, cmd->id));
@@ -1517,10 +1519,29 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1517 return ret; 1519 return ret;
1518 } 1520 }
1519 1521
1520 ret = wait_event_timeout(trans_pcie->wait_command_queue, 1522 while (timeout > 0) {
1521 !test_bit(STATUS_HCMD_ACTIVE, 1523 unsigned long flags;
1522 &trans_pcie->status), 1524
1523 HOST_COMPLETE_TIMEOUT); 1525 timeout -= COMMAND_POKE_TIMEOUT;
1526 ret = wait_event_timeout(trans_pcie->wait_command_queue,
1527 !test_bit(STATUS_HCMD_ACTIVE,
1528 &trans_pcie->status),
1529 COMMAND_POKE_TIMEOUT);
1530 if (ret)
1531 break;
1532 /* poke the device - it may have lost the command */
1533 if (iwl_trans_grab_nic_access(trans, true, &flags)) {
1534 iwl_trans_release_nic_access(trans, &flags);
1535 IWL_DEBUG_INFO(trans,
1536 "Tried to wake NIC for command %s\n",
1537 get_cmd_string(trans_pcie, cmd->id));
1538 } else {
1539 IWL_ERR(trans, "Failed to poke NIC for command %s\n",
1540 get_cmd_string(trans_pcie, cmd->id));
1541 break;
1542 }
1543 }
1544
1524 if (!ret) { 1545 if (!ret) {
1525 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { 1546 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
1526 struct iwl_txq *txq = 1547 struct iwl_txq *txq =