aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 8fefed2342d7..9db66d58f0ef 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -86,6 +86,7 @@ MODULE_PARM_DESC(ap_mode_default,
86 86
87#define MWL8K_RX_QUEUES 1 87#define MWL8K_RX_QUEUES 1
88#define MWL8K_TX_QUEUES 4 88#define MWL8K_TX_QUEUES 4
89#define MWL8K_MAX_AMPDU_QUEUES 8
89 90
90struct rxd_ops { 91struct rxd_ops {
91 int rxd_size; 92 int rxd_size;
@@ -159,6 +160,9 @@ struct mwl8k_priv {
159 u32 ap_macids_supported; 160 u32 ap_macids_supported;
160 u32 sta_macids_supported; 161 u32 sta_macids_supported;
161 162
163 /* Ampdu stream information */
164 u8 num_ampdu_queues;
165
162 /* firmware access */ 166 /* firmware access */
163 struct mutex fw_mutex; 167 struct mutex fw_mutex;
164 struct task_struct *fw_mutex_owner; 168 struct task_struct *fw_mutex_owner;
@@ -190,8 +194,8 @@ struct mwl8k_priv {
190 int pending_tx_pkts; 194 int pending_tx_pkts;
191 195
192 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 196 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
193 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 197 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES + MWL8K_MAX_AMPDU_QUEUES];
194 u32 txq_offset[MWL8K_TX_QUEUES]; 198 u32 txq_offset[MWL8K_TX_QUEUES + MWL8K_MAX_AMPDU_QUEUES];
195 199
196 bool radio_on; 200 bool radio_on;
197 bool radio_short_preamble; 201 bool radio_short_preamble;
@@ -1322,7 +1326,7 @@ struct mwl8k_tx_desc {
1322 __le16 pkt_len; 1326 __le16 pkt_len;
1323 __u8 dest_MAC_addr[ETH_ALEN]; 1327 __u8 dest_MAC_addr[ETH_ALEN];
1324 __le32 next_txd_phys_addr; 1328 __le32 next_txd_phys_addr;
1325 __le32 reserved; 1329 __le32 timestamp;
1326 __le16 rate_info; 1330 __le16 rate_info;
1327 __u8 peer_id; 1331 __u8 peer_id;
1328 __u8 tx_frag_cnt; 1332 __u8 tx_frag_cnt;
@@ -2023,13 +2027,16 @@ struct mwl8k_cmd_get_hw_spec_ap {
2023 __le32 wcbbase2; 2027 __le32 wcbbase2;
2024 __le32 wcbbase3; 2028 __le32 wcbbase3;
2025 __le32 fw_api_version; 2029 __le32 fw_api_version;
2030 __le32 caps;
2031 __le32 num_of_ampdu_queues;
2032 __le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES];
2026} __packed; 2033} __packed;
2027 2034
2028static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) 2035static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2029{ 2036{
2030 struct mwl8k_priv *priv = hw->priv; 2037 struct mwl8k_priv *priv = hw->priv;
2031 struct mwl8k_cmd_get_hw_spec_ap *cmd; 2038 struct mwl8k_cmd_get_hw_spec_ap *cmd;
2032 int rc; 2039 int rc, i;
2033 u32 api_version; 2040 u32 api_version;
2034 2041
2035 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2042 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2061,10 +2068,17 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2061 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 2068 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
2062 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 2069 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
2063 priv->hw_rev = cmd->hw_rev; 2070 priv->hw_rev = cmd->hw_rev;
2064 mwl8k_setup_2ghz_band(hw); 2071 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
2065 priv->ap_macids_supported = 0x000000ff; 2072 priv->ap_macids_supported = 0x000000ff;
2066 priv->sta_macids_supported = 0x00000000; 2073 priv->sta_macids_supported = 0x00000000;
2067 2074 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
2075 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
2076 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
2077 " but we only support %d.\n",
2078 priv->num_ampdu_queues,
2079 MWL8K_MAX_AMPDU_QUEUES);
2080 priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES;
2081 }
2068 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; 2082 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
2069 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2083 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2070 2084
@@ -2075,6 +2089,10 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2075 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff; 2089 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
2076 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff; 2090 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
2077 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff; 2091 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
2092
2093 for (i = 0; i < priv->num_ampdu_queues; i++)
2094 priv->txq_offset[i + MWL8K_TX_QUEUES] =
2095 le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff;
2078 } 2096 }
2079 2097
2080done: 2098done:
@@ -2103,6 +2121,14 @@ struct mwl8k_cmd_set_hw_spec {
2103 __le32 total_rxd; 2121 __le32 total_rxd;
2104} __packed; 2122} __packed;
2105 2123
2124/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause
2125 * packets to expire 500 ms after the timestamp in the tx descriptor. That is,
2126 * the packets that are queued for more than 500ms, will be dropped in the
2127 * hardware. This helps minimizing the issues caused due to head-of-line
2128 * blocking where a slow client can hog the bandwidth and affect traffic to a
2129 * faster client.
2130 */
2131#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400
2106#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 2132#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
2107#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 2133#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
2108#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 2134#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
@@ -4434,7 +4460,7 @@ enum {
4434 MWL8366, 4460 MWL8366,
4435}; 4461};
4436 4462
4437#define MWL8K_8366_AP_FW_API 1 4463#define MWL8K_8366_AP_FW_API 2
4438#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" 4464#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
4439#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) 4465#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
4440 4466
@@ -4650,6 +4676,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4650 * total number of queues from the result CMD_GET_HW_SPEC, so for this 4676 * total number of queues from the result CMD_GET_HW_SPEC, so for this
4651 * case we must initialize the tx queues after. 4677 * case we must initialize the tx queues after.
4652 */ 4678 */
4679 priv->num_ampdu_queues = 0;
4653 if (!priv->ap_fw) { 4680 if (!priv->ap_fw) {
4654 rc = mwl8k_init_txqs(hw); 4681 rc = mwl8k_init_txqs(hw);
4655 if (rc) 4682 if (rc)