Commit 81a07128 authored by David S. Miller's avatar David S. Miller

Merge tag 'wireless-drivers-for-davem-2015-01-09' of...

Merge tag 'wireless-drivers-for-davem-2015-01-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers

* rtlwifi: fix a regression in large skb allocation failure

iwlwifi:

* fix for 7265D NVM check
* fixes for scan: fix long scanning times and network discovery
* new firmware API for iwlmvm supported devices
* fixes in rate control
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2bd82218 c702674f
...@@ -69,8 +69,8 @@ ...@@ -69,8 +69,8 @@
#include "iwl-agn-hw.h" #include "iwl-agn-hw.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL7260_UCODE_API_MAX 10 #define IWL7260_UCODE_API_MAX 12
#define IWL3160_UCODE_API_MAX 10 #define IWL3160_UCODE_API_MAX 12
/* Oldest version we won't warn about */ /* Oldest version we won't warn about */
#define IWL7260_UCODE_API_OK 10 #define IWL7260_UCODE_API_OK 10
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
#define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
#define IWL7265D_FW_PRE "iwlwifi-7265D-" #define IWL7265D_FW_PRE "iwlwifi-7265D-"
#define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" #define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode"
#define NVM_HW_SECTION_NUM_FAMILY_7000 0 #define NVM_HW_SECTION_NUM_FAMILY_7000 0
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
#include "iwl-agn-hw.h" #include "iwl-agn-hw.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL8000_UCODE_API_MAX 10 #define IWL8000_UCODE_API_MAX 12
/* Oldest version we won't warn about */ /* Oldest version we won't warn about */
#define IWL8000_UCODE_API_OK 10 #define IWL8000_UCODE_API_OK 10
......
...@@ -243,6 +243,9 @@ enum iwl_ucode_tlv_flag { ...@@ -243,6 +243,9 @@ enum iwl_ucode_tlv_flag {
* @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
* @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
* longer than the passive one, which is essential for fragmented scan. * longer than the passive one, which is essential for fragmented scan.
* @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
* regardless of the band or the number of the probes. FW will calculate
* the actual dwell time.
*/ */
enum iwl_ucode_tlv_api { enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
...@@ -253,6 +256,7 @@ enum iwl_ucode_tlv_api { ...@@ -253,6 +256,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13),
}; };
/** /**
......
...@@ -672,6 +672,7 @@ struct iwl_scan_channel_opt { ...@@ -672,6 +672,7 @@ struct iwl_scan_channel_opt {
* @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
* @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report
* and DS parameter set IEs into probe requests. * and DS parameter set IEs into probe requests.
* @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches
*/ */
enum iwl_mvm_lmac_scan_flags { enum iwl_mvm_lmac_scan_flags {
IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0), IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0),
...@@ -681,6 +682,7 @@ enum iwl_mvm_lmac_scan_flags { ...@@ -681,6 +682,7 @@ enum iwl_mvm_lmac_scan_flags {
IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4), IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4),
IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5), IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5),
IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6), IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6),
IWL_MVM_LMAC_SCAN_FLAG_MATCH = BIT(9),
}; };
enum iwl_scan_priority { enum iwl_scan_priority {
......
...@@ -171,15 +171,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid, ...@@ -171,15 +171,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
* already included in the probe template, so we need to set only * already included in the probe template, so we need to set only
* req->n_ssids - 1 bits in addition to the first bit. * req->n_ssids - 1 bits in addition to the first bit.
*/ */
static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm,
enum ieee80211_band band, int n_ssids)
{ {
if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
return 10;
if (band == IEEE80211_BAND_2GHZ) if (band == IEEE80211_BAND_2GHZ)
return 20 + 3 * (n_ssids + 1); return 20 + 3 * (n_ssids + 1);
return 10 + 2 * (n_ssids + 1); return 10 + 2 * (n_ssids + 1);
} }
static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm,
enum ieee80211_band band)
{ {
if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
return 110;
return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
} }
...@@ -331,7 +337,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, ...@@ -331,7 +337,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
*/ */
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
u32 passive_dwell = u32 passive_dwell =
iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); iwl_mvm_get_passive_dwell(mvm,
IEEE80211_BAND_2GHZ);
params->max_out_time = passive_dwell; params->max_out_time = passive_dwell;
} else { } else {
params->passive_fragmented = true; params->passive_fragmented = true;
...@@ -348,8 +355,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, ...@@ -348,8 +355,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
params->dwell[band].passive = frag_passive_dwell; params->dwell[band].passive = frag_passive_dwell;
else else
params->dwell[band].passive = params->dwell[band].passive =
iwl_mvm_get_passive_dwell(band); iwl_mvm_get_passive_dwell(mvm, band);
params->dwell[band].active = iwl_mvm_get_active_dwell(band, params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,
n_ssids); n_ssids);
} }
} }
...@@ -1448,6 +1455,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, ...@@ -1448,6 +1455,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
if (iwl_mvm_scan_pass_all(mvm, req)) if (iwl_mvm_scan_pass_all(mvm, req))
flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
else
flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;
if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)
flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
......
...@@ -108,8 +108,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -108,8 +108,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
tx_flags &= ~TX_CMD_FLG_SEQ_CTL; tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
} }
/* tid_tspec will default to 0 = BE when QOS isn't enabled */ /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */
ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT)
ac = tid_to_mac80211_ac[tx_cmd->tid_tspec];
else
ac = tid_to_mac80211_ac[0];
tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) << tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) <<
TX_CMD_FLG_BT_PRIO_POS; TX_CMD_FLG_BT_PRIO_POS;
......
...@@ -665,7 +665,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm) ...@@ -665,7 +665,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
if (num_of_ant(mvm->fw->valid_rx_ant) == 1) if (num_of_ant(mvm->fw->valid_rx_ant) == 1)
return false; return false;
if (!mvm->cfg->rx_with_siso_diversity) if (mvm->cfg->rx_with_siso_diversity)
return false; return false;
ieee80211_iterate_active_interfaces_atomic( ieee80211_iterate_active_interfaces_atomic(
......
...@@ -527,8 +527,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -527,8 +527,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
else if (cfg == &iwl7265_n_cfg) else if (cfg == &iwl7265_n_cfg)
cfg_7265d = &iwl7265d_n_cfg; cfg_7265d = &iwl7265d_n_cfg;
if (cfg_7265d && if (cfg_7265d &&
(iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) {
cfg = cfg_7265d; cfg = cfg_7265d;
iwl_trans->cfg = cfg_7265d;
}
#endif #endif
pci_set_drvdata(pdev, iwl_trans); pci_set_drvdata(pdev, iwl_trans);
......
...@@ -666,7 +666,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) ...@@ -666,7 +666,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
} }
static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
u8 *entry, int rxring_idx, int desc_idx) struct sk_buff *new_skb, u8 *entry,
int rxring_idx, int desc_idx)
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
...@@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, ...@@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
u8 tmp_one = 1; u8 tmp_one = 1;
struct sk_buff *skb; struct sk_buff *skb;
if (likely(new_skb)) {
skb = new_skb;
goto remap;
}
skb = dev_alloc_skb(rtlpci->rxbuffersize); skb = dev_alloc_skb(rtlpci->rxbuffersize);
if (!skb) if (!skb)
return 0; return 0;
rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
remap:
/* just set skb->cb to mapping addr for pci_unmap_single use */ /* just set skb->cb to mapping addr for pci_unmap_single use */
*((dma_addr_t *)skb->cb) = *((dma_addr_t *)skb->cb) =
pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
...@@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, ...@@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
bufferaddress = *((dma_addr_t *)skb->cb); bufferaddress = *((dma_addr_t *)skb->cb);
if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
return 0; return 0;
rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
if (rtlpriv->use_new_trx_flow) { if (rtlpriv->use_new_trx_flow) {
rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
HW_DESC_RX_PREPARE, HW_DESC_RX_PREPARE,
...@@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) ...@@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
/*rx pkt */ /*rx pkt */
struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[ struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[
rtlpci->rx_ring[rxring_idx].idx]; rtlpci->rx_ring[rxring_idx].idx];
struct sk_buff *new_skb;
if (rtlpriv->use_new_trx_flow) { if (rtlpriv->use_new_trx_flow) {
rx_remained_cnt = rx_remained_cnt =
...@@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) ...@@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb), pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),
rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
/* get a new skb - if fail, old one will be reused */
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
if (unlikely(!new_skb)) {
pr_err("Allocation of new skb failed in %s\n",
__func__);
goto no_new;
}
if (rtlpriv->use_new_trx_flow) { if (rtlpriv->use_new_trx_flow) {
buffer_desc = buffer_desc =
&rtlpci->rx_ring[rxring_idx].buffer_desc &rtlpci->rx_ring[rxring_idx].buffer_desc
...@@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) ...@@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
schedule_work(&rtlpriv->works.lps_change_work); schedule_work(&rtlpriv->works.lps_change_work);
} }
end: end:
skb = new_skb;
no_new:
if (rtlpriv->use_new_trx_flow) { if (rtlpriv->use_new_trx_flow) {
_rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,
rxring_idx, rxring_idx,
rtlpci->rx_ring[rxring_idx].idx); rtlpci->rx_ring[rxring_idx].idx);
} else { } else {
_rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx, _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc,
rxring_idx,
rtlpci->rx_ring[rxring_idx].idx); rtlpci->rx_ring[rxring_idx].idx);
if (rtlpci->rx_ring[rxring_idx].idx == if (rtlpci->rx_ring[rxring_idx].idx ==
rtlpci->rxringcount - 1) rtlpci->rxringcount - 1)
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,
...@@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) ...@@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
rtlpci->rx_ring[rxring_idx].idx = 0; rtlpci->rx_ring[rxring_idx].idx = 0;
for (i = 0; i < rtlpci->rxringcount; i++) { for (i = 0; i < rtlpci->rxringcount; i++) {
entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i];
if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
rxring_idx, i)) rxring_idx, i))
return -ENOMEM; return -ENOMEM;
} }
...@@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) ...@@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
for (i = 0; i < rtlpci->rxringcount; i++) { for (i = 0; i < rtlpci->rxringcount; i++) {
entry = &rtlpci->rx_ring[rxring_idx].desc[i]; entry = &rtlpci->rx_ring[rxring_idx].desc[i];
if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
rxring_idx, i)) rxring_idx, i))
return -ENOMEM; return -ENOMEM;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment