Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem

Conflicts:
	net/wireless/nl80211.c
This commit is contained in:
John W. Linville
2013-06-21 15:42:30 -04:00
210 changed files with 27591 additions and 2856 deletions

View File

@@ -3727,7 +3727,8 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 5. Setup HW Constants
* ********************/
/* Device-specific setup */
if (il3945_hw_set_hw_params(il)) {
err = il3945_hw_set_hw_params(il);
if (err) {
IL_ERR("failed to set hw settings\n");
goto out_eeprom_free;
}

View File

@@ -331,6 +331,19 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
return;
}
/*
* Firmware will not transmit frame on passive channel, if it not yet
* received some valid frame on that channel. When this error happen
* we have to wait until firmware will unblock itself i.e. when we
* note received beacon or other frame. We unblock queues in
* il3945_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
*/
if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
il->iw_mode == NL80211_IFTYPE_STATION) {
il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
D_INFO("Stopped queues - RX waiting on passive channel\n");
}
txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);
ieee80211_tx_info_clear_status(info);
@@ -488,6 +501,11 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
return;
}
if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {
il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
D_INFO("Woke queues - frame received on passive channel\n");
}
skb = dev_alloc_skb(128);
if (!skb) {
IL_ERR("dev_alloc_skb failed\n");

View File

@@ -588,6 +588,11 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
return;
}
if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {
il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
D_INFO("Woke queues - frame received on passive channel\n");
}
/* In case of HW accelerated crypto and bad decryption, drop */
if (!il->cfg->mod_params->sw_crypto &&
il_set_decrypted_flag(il, hdr, ampdu_status, stats))
@@ -2806,6 +2811,19 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
return;
}
/*
* Firmware will not transmit frame on passive channel, if it not yet
* received some valid frame on that channel. When this error happen
* we have to wait until firmware will unblock itself i.e. when we
* note received beacon or other frame. We unblock queues in
* il4965_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
*/
if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
il->iw_mode == NL80211_IFTYPE_STATION) {
il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
D_INFO("Stopped queues - RX waiting on passive channel\n");
}
spin_lock_irqsave(&il->sta_lock, flags);
if (txq->sched_retry) {
const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
@@ -5741,7 +5759,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
hw->flags =
IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT |
IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
if (il->cfg->sku & IL_SKU_N)
hw->flags |=
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |

View File

@@ -5306,6 +5306,17 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (changes & BSS_CHANGED_BSSID) {
D_MAC80211("BSSID %pM\n", bss_conf->bssid);
/*
* On passive channel we wait with blocked queues to see if
* there is traffic on that channel. If no frame will be
* received (what is very unlikely since scan detects AP on
* that channel, but theoretically possible), mac80211 associate
* procedure will time out and mac80211 will call us with NULL
* bssid. We have to unblock queues on such condition.
*/
if (is_zero_ether_addr(bss_conf->bssid))
il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
/*
* If there is currently a HW scan going on in the background,
* then we need to cancel it, otherwise sometimes we are not

View File

@@ -1299,6 +1299,8 @@ struct il_priv {
/* queue refcounts */
#define IL_MAX_HW_QUEUES 32
unsigned long queue_stopped[BITS_TO_LONGS(IL_MAX_HW_QUEUES)];
#define IL_STOP_REASON_PASSIVE 0
unsigned long stop_reason;
/* for each AC */
atomic_t queue_stop_count[4];
@@ -2256,6 +2258,19 @@ il_set_swq_id(struct il_tx_queue *txq, u8 ac, u8 hwq)
txq->swq_id = (hwq << 2) | ac;
}
static inline void
_il_wake_queue(struct il_priv *il, u8 ac)
{
if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(il->hw, ac);
}
static inline void
_il_stop_queue(struct il_priv *il, u8 ac)
{
if (atomic_inc_return(&il->queue_stop_count[ac]) > 0)
ieee80211_stop_queue(il->hw, ac);
}
static inline void
il_wake_queue(struct il_priv *il, struct il_tx_queue *txq)
{
@@ -2264,8 +2279,7 @@ il_wake_queue(struct il_priv *il, struct il_tx_queue *txq)
u8 hwq = (queue >> 2) & 0x1f;
if (test_and_clear_bit(hwq, il->queue_stopped))
if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(il->hw, ac);
_il_wake_queue(il, ac);
}
static inline void
@@ -2276,8 +2290,27 @@ il_stop_queue(struct il_priv *il, struct il_tx_queue *txq)
u8 hwq = (queue >> 2) & 0x1f;
if (!test_and_set_bit(hwq, il->queue_stopped))
if (atomic_inc_return(&il->queue_stop_count[ac]) > 0)
ieee80211_stop_queue(il->hw, ac);
_il_stop_queue(il, ac);
}
static inline void
il_wake_queues_by_reason(struct il_priv *il, int reason)
{
u8 ac;
if (test_and_clear_bit(reason, &il->stop_reason))
for (ac = 0; ac < 4; ac++)
_il_wake_queue(il, ac);
}
static inline void
il_stop_queues_by_reason(struct il_priv *il, int reason)
{
u8 ac;
if (!test_and_set_bit(reason, &il->stop_reason))
for (ac = 0; ac < 4; ac++)
_il_stop_queue(il, ac);
}
#ifdef ieee80211_stop_queue