aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-03-18 06:26:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-23 16:50:24 -0400
commit14b228a0d4234e4a2d4e683052da78760e8abf0f (patch)
tree71b0ddf8093169441720c32cb45bf1e297b73944 /drivers/net/wireless
parent801a673ed1b36fc0e7dd92d8bb0090a4dc26a7d0 (diff)
wl1271: Update filters properly
This patch adds support for the filters configured by the mac80211 stack. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c58
3 files changed, 51 insertions, 18 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 4e608067253e..a0262b7723c3 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -54,6 +54,7 @@ enum {
54 DEBUG_CMD = BIT(12), 54 DEBUG_CMD = BIT(12),
55 DEBUG_ACX = BIT(13), 55 DEBUG_ACX = BIT(13),
56 DEBUG_SDIO = BIT(14), 56 DEBUG_SDIO = BIT(14),
57 DEBUG_FILTERS = BIT(15),
57 DEBUG_ALL = ~0, 58 DEBUG_ALL = ~0,
58}; 59};
59 60
@@ -458,6 +459,7 @@ struct wl1271 {
458 /* Default key (for WEP) */ 459 /* Default key (for WEP) */
459 u32 default_key; 460 u32 default_key;
460 461
462 unsigned int filters;
461 unsigned int rx_config; 463 unsigned int rx_config;
462 unsigned int rx_filter; 464 unsigned int rx_filter;
463 465
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 0cbb0e1e3d40..035ddc06034c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -281,15 +281,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
281 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 281 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
282 join->bss_type = bss_type; 282 join->bss_type = bss_type;
283 283
284 /*
285 * FIXME: disable temporarily all filters because after commit
286 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
287 * association. The filter logic needs to be implemented properly
288 * and once that is done, this hack can be removed.
289 */
290 join->rx_config_options = cpu_to_le32(0);
291 join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER);
292
293 if (wl->band == IEEE80211_BAND_2GHZ) 284 if (wl->band == IEEE80211_BAND_2GHZ)
294 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS | 285 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
295 CONF_HW_BIT_RATE_2MBPS | 286 CONF_HW_BIT_RATE_2MBPS |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 688009ba94fa..befc2e9b1842 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1080,6 +1080,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1080 wl->sta_rate_set = 0; 1080 wl->sta_rate_set = 0;
1081 wl->flags = 0; 1081 wl->flags = 0;
1082 wl->vif = NULL; 1082 wl->vif = NULL;
1083 wl->filters = 0;
1083 1084
1084 for (i = 0; i < NUM_TX_QUEUES; i++) 1085 for (i = 0; i < NUM_TX_QUEUES; i++)
1085 wl->tx_blocks_freed[i] = 0; 1086 wl->tx_blocks_freed[i] = 0;
@@ -1088,6 +1089,40 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1088 mutex_unlock(&wl->mutex); 1089 mutex_unlock(&wl->mutex);
1089} 1090}
1090 1091
1092static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
1093{
1094 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1095 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1096
1097 /* combine requested filters with current filter config */
1098 filters = wl->filters | filters;
1099
1100 wl1271_debug(DEBUG_FILTERS, "RX filters set: ");
1101
1102 if (filters & FIF_PROMISC_IN_BSS) {
1103 wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS");
1104 wl->rx_config &= ~CFG_UNI_FILTER_EN;
1105 wl->rx_config |= CFG_BSSID_FILTER_EN;
1106 }
1107 if (filters & FIF_BCN_PRBRESP_PROMISC) {
1108 wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC");
1109 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1110 wl->rx_config &= ~CFG_SSID_FILTER_EN;
1111 }
1112 if (filters & FIF_OTHER_BSS) {
1113 wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS");
1114 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1115 }
1116 if (filters & FIF_CONTROL) {
1117 wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL");
1118 wl->rx_filter |= CFG_RX_CTL_EN;
1119 }
1120 if (filters & FIF_FCSFAIL) {
1121 wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL");
1122 wl->rx_filter |= CFG_RX_FCS_ERROR;
1123 }
1124}
1125
1091static int wl1271_join_channel(struct wl1271 *wl, int channel) 1126static int wl1271_join_channel(struct wl1271 *wl, int channel)
1092{ 1127{
1093 int ret = 0; 1128 int ret = 0;
@@ -1095,12 +1130,12 @@ static int wl1271_join_channel(struct wl1271 *wl, int channel)
1095 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, 1130 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1096 0xad, 0xbe, 0xef }; 1131 0xad, 0xbe, 0xef };
1097 1132
1098 /* disable mac filter, so we hear everything */
1099 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1100
1101 wl->channel = channel; 1133 wl->channel = channel;
1102 memcpy(wl->bssid, dummy_bssid, ETH_ALEN); 1134 memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
1103 1135
1136 /* pass through frames from all BSS */
1137 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1138
1104 /* the dummy join is performed always with STATION BSS type to allow 1139 /* the dummy join is performed always with STATION BSS type to allow
1105 also ad-hoc mode to listen to the surroundings without sending any 1140 also ad-hoc mode to listen to the surroundings without sending any
1106 beacons yet. */ 1141 beacons yet. */
@@ -1126,7 +1161,9 @@ static int wl1271_unjoin_channel(struct wl1271 *wl)
1126 clear_bit(WL1271_FLAG_JOINED, &wl->flags); 1161 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
1127 wl->channel = 0; 1162 wl->channel = 0;
1128 memset(wl->bssid, 0, ETH_ALEN); 1163 memset(wl->bssid, 0, ETH_ALEN);
1129 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 1164
1165 /* stop filterting packets based on bssid */
1166 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1130 1167
1131out: 1168out:
1132 return ret; 1169 return ret;
@@ -1299,14 +1336,14 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1299 if (ret < 0) 1336 if (ret < 0)
1300 goto out_sleep; 1337 goto out_sleep;
1301 1338
1302 kfree(fp);
1303
1304 /* FIXME: We still need to set our filters properly */
1305
1306 /* determine, whether supported filter values have changed */ 1339 /* determine, whether supported filter values have changed */
1307 if (changed == 0) 1340 if (changed == 0)
1308 goto out_sleep; 1341 goto out_sleep;
1309 1342
1343 /* configure filters */
1344 wl->filters = *total;
1345 wl1271_configure_filters(wl, 0);
1346
1310 /* apply configured filters */ 1347 /* apply configured filters */
1311 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); 1348 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
1312 if (ret < 0) 1349 if (ret < 0)
@@ -1317,6 +1354,7 @@ out_sleep:
1317 1354
1318out: 1355out:
1319 mutex_unlock(&wl->mutex); 1356 mutex_unlock(&wl->mutex);
1357 kfree(fp);
1320} 1358}
1321 1359
1322static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 1360static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -1580,7 +1618,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1580 * and enable the BSSID filter 1618 * and enable the BSSID filter
1581 */ 1619 */
1582 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { 1620 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1583 wl->rx_config |= CFG_BSSID_FILTER_EN;
1584 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 1621 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1585 ret = wl1271_cmd_build_null_data(wl); 1622 ret = wl1271_cmd_build_null_data(wl);
1586 if (ret < 0) { 1623 if (ret < 0) {
@@ -1589,6 +1626,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1589 goto out_sleep; 1626 goto out_sleep;
1590 } 1627 }
1591 1628
1629 /* filter out all packets not from this BSSID */
1630 wl1271_configure_filters(wl, 0);
1631
1592 /* Need to update the BSSID (for filtering etc) */ 1632 /* Need to update the BSSID (for filtering etc) */
1593 do_join = true; 1633 do_join = true;
1594 } 1634 }