diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-03-18 06:26:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-23 16:50:24 -0400 |
commit | 14b228a0d4234e4a2d4e683052da78760e8abf0f (patch) | |
tree | 71b0ddf8093169441720c32cb45bf1e297b73944 /drivers | |
parent | 801a673ed1b36fc0e7dd92d8bb0090a4dc26a7d0 (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')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 58 |
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 | ||
1092 | static 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 | |||
1091 | static int wl1271_join_channel(struct wl1271 *wl, int channel) | 1126 | static 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 | ||
1131 | out: | 1168 | out: |
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 | ||
1318 | out: | 1355 | out: |
1319 | mutex_unlock(&wl->mutex); | 1356 | mutex_unlock(&wl->mutex); |
1357 | kfree(fp); | ||
1320 | } | 1358 | } |
1321 | 1359 | ||
1322 | static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 1360 | static 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 | } |