aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti
diff options
context:
space:
mode:
authorDavid Gnedt <david.gnedt@davizone.at>2014-01-07 07:06:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-01-09 10:53:39 -0500
commit204cc5c44fb695ece1eab15dd6fb92340028106d (patch)
tree222a1e7a48d91db05cdd44b22108375bfaa6c419 /drivers/net/wireless/ti
parentf7ad1eed4d4b9d5f0b7ada151d5670e7cb33a6e7 (diff)
wl1251: implement hardware ARP filtering
Update hardware ARP filter configuration on BSS_CHANGED_ARP_FILTER notification from mac80211. Ported from wl1271 driver. Signed-off-by: David Gnedt <david.gnedt@davizone.at> Signed-off-by: Pali Rohár <pali.rohar@gmail.com> Signed-off-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ti')
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c26
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.h15
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c12
3 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index 374268d5ac6a..eaf2d5dadcb9 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -960,6 +960,32 @@ out:
960 return ret; 960 return ret;
961} 961}
962 962
963int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address)
964{
965 struct wl1251_acx_arp_filter *acx;
966 int ret;
967
968 wl1251_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
969
970 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
971 if (!acx)
972 return -ENOMEM;
973
974 acx->version = ACX_IPV4_VERSION;
975 acx->enable = enable;
976
977 if (enable)
978 memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
979
980 ret = wl1251_cmd_configure(wl, ACX_ARP_IP_FILTER,
981 acx, sizeof(*acx));
982 if (ret < 0)
983 wl1251_warning("failed to set arp ip filter: %d", ret);
984
985 kfree(acx);
986 return ret;
987}
988
963int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, 989int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
964 u8 aifs, u16 txop) 990 u8 aifs, u16 txop)
965{ 991{
diff --git a/drivers/net/wireless/ti/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h
index c2ba100f9b1a..ba9ddc05e47a 100644
--- a/drivers/net/wireless/ti/wl1251/acx.h
+++ b/drivers/net/wireless/ti/wl1251/acx.h
@@ -1232,6 +1232,20 @@ struct wl1251_acx_bet_enable {
1232 u8 padding[2]; 1232 u8 padding[2];
1233} __packed; 1233} __packed;
1234 1234
1235#define ACX_IPV4_VERSION 4
1236#define ACX_IPV6_VERSION 6
1237#define ACX_IPV4_ADDR_SIZE 4
1238struct wl1251_acx_arp_filter {
1239 struct acx_header header;
1240 u8 version; /* The IP version: 4 - IPv4, 6 - IPv6.*/
1241 u8 enable; /* 1 - ARP filtering is enabled, 0 - disabled */
1242 u8 padding[2];
1243 u8 address[16]; /* The IP address used to filter ARP packets.
1244 ARP packets that do not match this address are
1245 dropped. When the IP Version is 4, the last 12
1246 bytes of the the address are ignored. */
1247} __attribute__((packed));
1248
1235struct wl1251_acx_ac_cfg { 1249struct wl1251_acx_ac_cfg {
1236 struct acx_header header; 1250 struct acx_header header;
1237 1251
@@ -1473,6 +1487,7 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl);
1473int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); 1487int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
1474int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, 1488int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
1475 u8 max_consecutive); 1489 u8 max_consecutive);
1490int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address);
1476int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, 1491int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1477 u8 aifs, u16 txop); 1492 u8 aifs, u16 txop);
1478int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, 1493int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 358073d6029e..9fee7f4d1152 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -979,6 +979,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
979{ 979{
980 struct wl1251 *wl = hw->priv; 980 struct wl1251 *wl = hw->priv;
981 struct sk_buff *beacon, *skb; 981 struct sk_buff *beacon, *skb;
982 bool enable;
982 int ret; 983 int ret;
983 984
984 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 985 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1077,6 +1078,17 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1077 } 1078 }
1078 } 1079 }
1079 1080
1081 if (changed & BSS_CHANGED_ARP_FILTER) {
1082 __be32 addr = bss_conf->arp_addr_list[0];
1083 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
1084
1085 enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc;
1086 wl1251_acx_arp_ip_filter(wl, enable, addr);
1087
1088 if (ret < 0)
1089 goto out_sleep;
1090 }
1091
1080 if (changed & BSS_CHANGED_BEACON) { 1092 if (changed & BSS_CHANGED_BEACON) {
1081 beacon = ieee80211_beacon_get(hw, vif); 1093 beacon = ieee80211_beacon_get(hw, vif);
1082 if (!beacon) 1094 if (!beacon)