aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-09-28 17:00:59 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-05 13:35:21 -0400
commit5c895691944862e782c285a871f5d3466797b4ef (patch)
tree7d49f76b23d23253b2c54a1794beb0676c66c615 /drivers/net/wireless
parent85416a4fa193754ef36e12b20bb02fe661cb7f17 (diff)
carl9170: support firmware-based rx filter
The hardware rx-filter was essentially disabled, because of a serve, yet unidentifiable problem with iwlagn. Due to these circumstances the driver and mac80211 were left with the job of filtering. This is very unfortunate and has proven to be expensive in terms of latency, memory and load. Therefore the new 1.8.8.3 firmware introduces a flexible filtering infrastructure which allows the driver to offload some of the checks (FCS & PLCP crc check, RA match, control frame filter, etc...) whenever possible. Note: This patch also includes all changes to the shared headers files since the inclusion. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h2
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h10
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c7
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h16
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h6
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h3
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c30
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h5
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
9 files changed, 75 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 20f2a77e54d..6cf0c9ef47a 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -279,6 +279,7 @@ struct ar9170 {
279 unsigned int beacon_max_len; 279 unsigned int beacon_max_len;
280 bool rx_stream; 280 bool rx_stream;
281 bool tx_stream; 281 bool tx_stream;
282 bool rx_filter;
282 unsigned int mem_blocks; 283 unsigned int mem_blocks;
283 unsigned int mem_block_size; 284 unsigned int mem_block_size;
284 unsigned int rx_size; 285 unsigned int rx_size;
@@ -314,6 +315,7 @@ struct ar9170 {
314 u64 cur_mc_hash; 315 u64 cur_mc_hash;
315 u32 cur_filter; 316 u32 cur_filter;
316 unsigned int filter_state; 317 unsigned int filter_state;
318 unsigned int rx_filter_caps;
317 bool sniffer_enabled; 319 bool sniffer_enabled;
318 320
319 /* MAC */ 321 /* MAC */
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
index 0fc83d2336f..f78728c3829 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.h
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -59,6 +59,16 @@ static inline int carl9170_flush_cab(struct ar9170 *ar,
59 return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0); 59 return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0);
60} 60}
61 61
62static inline int carl9170_rx_filter(struct ar9170 *ar,
63 const unsigned int _rx_filter)
64{
65 __le32 rx_filter = cpu_to_le32(_rx_filter);
66
67 return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER,
68 sizeof(rx_filter), (u8 *)&rx_filter,
69 0, NULL);
70}
71
62struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, 72struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
63 const enum carl9170_cmd_oids cmd, const unsigned int len); 73 const enum carl9170_cmd_oids cmd, const unsigned int len);
64 74
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index 36615462b87..ae6c006bbc5 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -257,6 +257,13 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
257 if (SUPP(CARL9170FW_USB_UP_STREAM)) 257 if (SUPP(CARL9170FW_USB_UP_STREAM))
258 ar->fw.rx_stream = true; 258 ar->fw.rx_stream = true;
259 259
260 if (SUPP(CARL9170FW_RX_FILTER)) {
261 ar->fw.rx_filter = true;
262 ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL |
263 FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS |
264 FIF_PROMISC_IN_BSS;
265 }
266
260 ar->fw.vif_num = otus_desc->vif_num; 267 ar->fw.vif_num = otus_desc->vif_num;
261 ar->fw.cmd_bufs = otus_desc->cmd_bufs; 268 ar->fw.cmd_bufs = otus_desc->cmd_bufs;
262 ar->fw.address = le32_to_cpu(otus_desc->fw_address); 269 ar->fw.address = le32_to_cpu(otus_desc->fw_address);
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d4a4e1dbef0..d552166db50 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -53,6 +53,7 @@ enum carl9170_cmd_oids {
53 CARL9170_CMD_REBOOT = 0x04, 53 CARL9170_CMD_REBOOT = 0x04,
54 CARL9170_CMD_BCN_CTRL = 0x05, 54 CARL9170_CMD_BCN_CTRL = 0x05,
55 CARL9170_CMD_READ_TSF = 0x06, 55 CARL9170_CMD_READ_TSF = 0x06,
56 CARL9170_CMD_RX_FILTER = 0x07,
56 57
57 /* CAM */ 58 /* CAM */
58 CARL9170_CMD_EKEY = 0x10, 59 CARL9170_CMD_EKEY = 0x10,
@@ -153,6 +154,20 @@ struct carl9170_psm {
153} __packed; 154} __packed;
154#define CARL9170_PSM_SIZE 4 155#define CARL9170_PSM_SIZE 4
155 156
157struct carl9170_rx_filter_cmd {
158 __le32 rx_filter;
159} __packed;
160#define CARL9170_RX_FILTER_CMD_SIZE 4
161
162#define CARL9170_RX_FILTER_BAD 0x01
163#define CARL9170_RX_FILTER_OTHER_RA 0x02
164#define CARL9170_RX_FILTER_DECRY_FAIL 0x04
165#define CARL9170_RX_FILTER_CTL_OTHER 0x08
166#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10
167#define CARL9170_RX_FILTER_CTL_BACKR 0x20
168#define CARL9170_RX_FILTER_MGMT 0x40
169#define CARL9170_RX_FILTER_DATA 0x80
170
156struct carl9170_bcn_ctrl_cmd { 171struct carl9170_bcn_ctrl_cmd {
157 __le32 vif_id; 172 __le32 vif_id;
158 __le32 mode; 173 __le32 mode;
@@ -188,6 +203,7 @@ struct carl9170_cmd {
188 struct carl9170_rf_init rf_init; 203 struct carl9170_rf_init rf_init;
189 struct carl9170_psm psm; 204 struct carl9170_psm psm;
190 struct carl9170_bcn_ctrl_cmd bcn_ctrl; 205 struct carl9170_bcn_ctrl_cmd bcn_ctrl;
206 struct carl9170_rx_filter_cmd rx_filter;
191 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 207 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
192 } __packed; 208 } __packed;
193} __packed; 209} __packed;
diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h
index 7cd811708fe..71f3821f605 100644
--- a/drivers/net/wireless/ath/carl9170/fwdesc.h
+++ b/drivers/net/wireless/ath/carl9170/fwdesc.h
@@ -66,6 +66,9 @@ enum carl9170fw_feature_list {
66 /* Firmware PSM support | CARL9170_CMD_PSM */ 66 /* Firmware PSM support | CARL9170_CMD_PSM */
67 CARL9170FW_PSM, 67 CARL9170FW_PSM,
68 68
69 /* Firmware RX filter | CARL9170_CMD_RX_FILTER */
70 CARL9170FW_RX_FILTER,
71
69 /* KEEP LAST */ 72 /* KEEP LAST */
70 __CARL9170FW_FEATURE_NUM 73 __CARL9170FW_FEATURE_NUM
71}; 74};
@@ -142,7 +145,7 @@ struct carl9170fw_fix_desc {
142 (sizeof(struct carl9170fw_fix_desc)) 145 (sizeof(struct carl9170fw_fix_desc))
143 146
144#define CARL9170FW_DBG_DESC_MIN_VER 1 147#define CARL9170FW_DBG_DESC_MIN_VER 1
145#define CARL9170FW_DBG_DESC_CUR_VER 2 148#define CARL9170FW_DBG_DESC_CUR_VER 3
146struct carl9170fw_dbg_desc { 149struct carl9170fw_dbg_desc {
147 struct carl9170fw_desc_head head; 150 struct carl9170fw_desc_head head;
148 151
@@ -150,6 +153,7 @@ struct carl9170fw_dbg_desc {
150 __le32 counter_addr; 153 __le32 counter_addr;
151 __le32 rx_total_addr; 154 __le32 rx_total_addr;
152 __le32 rx_overrun_addr; 155 __le32 rx_overrun_addr;
156 __le32 rx_filter;
153 157
154 /* Put your debugging definitions here */ 158 /* Put your debugging definitions here */
155} __packed; 159} __packed;
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index b1292ac5b70..2f471b3f05a 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -731,6 +731,9 @@ struct ar9170_stream {
731#define SET_VAL(reg, value, newvalue) \ 731#define SET_VAL(reg, value, newvalue) \
732 (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) 732 (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg))
733 733
734#define SET_CONSTVAL(reg, newvalue) \
735 (((newvalue) << reg##_S) & reg)
736
734#define MOD_VAL(reg, value, newvalue) \ 737#define MOD_VAL(reg, value, newvalue) \
735 (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) 738 (((value) & ~reg) | (((newvalue) << reg##_S) & reg))
736#endif /* __CARL9170_SHARED_HW_H */ 739#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 84bd38e9961..3cc99f3f7ab 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -380,6 +380,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw)
380 if (err) 380 if (err)
381 goto out; 381 goto out;
382 382
383 if (ar->fw.rx_filter) {
384 err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA |
385 CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD);
386 if (err)
387 goto out;
388 }
389
383 err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 390 err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER,
384 AR9170_DMA_TRIGGER_RXQ); 391 AR9170_DMA_TRIGGER_RXQ);
385 if (err) 392 if (err)
@@ -840,8 +847,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
840 struct ar9170 *ar = hw->priv; 847 struct ar9170 *ar = hw->priv;
841 848
842 /* mask supported flags */ 849 /* mask supported flags */
843 *new_flags &= FIF_ALLMULTI | FIF_FCSFAIL | FIF_PLCPFAIL | 850 *new_flags &= FIF_ALLMULTI | ar->rx_filter_caps;
844 FIF_OTHER_BSS | FIF_PROMISC_IN_BSS;
845 851
846 if (!IS_ACCEPTING_CMD(ar)) 852 if (!IS_ACCEPTING_CMD(ar))
847 return; 853 return;
@@ -867,6 +873,26 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
867 WARN_ON(carl9170_set_operating_mode(ar)); 873 WARN_ON(carl9170_set_operating_mode(ar));
868 } 874 }
869 875
876 if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) {
877 u32 rx_filter = 0;
878
879 if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)))
880 rx_filter |= CARL9170_RX_FILTER_BAD;
881
882 if (!(*new_flags & FIF_CONTROL))
883 rx_filter |= CARL9170_RX_FILTER_CTL_OTHER;
884
885 if (!(*new_flags & FIF_PSPOLL))
886 rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL;
887
888 if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) {
889 rx_filter |= CARL9170_RX_FILTER_OTHER_RA;
890 rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL;
891 }
892
893 WARN_ON(carl9170_rx_filter(ar, rx_filter));
894 }
895
870 mutex_unlock(&ar->mutex); 896 mutex_unlock(&ar->mutex);
871} 897}
872 898
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 53c18d34ffc..02c34eb4ebd 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -423,8 +423,8 @@
423#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 423#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
424#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 424#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
425 425
426#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
427#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) 426#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c)
427#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
428#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 428#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000
429#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 429#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
430#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 430#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00
@@ -561,7 +561,4 @@
561#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 561#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
562#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 562#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
563 563
564#define REDUCE_CHAIN_0 0x00000050
565#define REDUCE_CHAIN_1 0x00000051
566
567#endif /* __CARL9170_SHARED_PHY_H */ 564#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index 0e917f80eab..ff53f078a0b 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
1#ifndef __CARL9170_SHARED_VERSION_H 1#ifndef __CARL9170_SHARED_VERSION_H
2#define __CARL9170_SHARED_VERSION_H 2#define __CARL9170_SHARED_VERSION_H
3#define CARL9170FW_VERSION_YEAR 10 3#define CARL9170FW_VERSION_YEAR 10
4#define CARL9170FW_VERSION_MONTH 8 4#define CARL9170FW_VERSION_MONTH 9
5#define CARL9170FW_VERSION_DAY 30 5#define CARL9170FW_VERSION_DAY 28
6#define CARL9170FW_VERSION_GIT "1.8.8.1" 6#define CARL9170FW_VERSION_GIT "1.8.8.3"
7#endif /* __CARL9170_SHARED_VERSION_H */ 7#endif /* __CARL9170_SHARED_VERSION_H */