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>
This commit is contained in:
David Gnedt 2014-01-07 13:06:24 +01:00 committed by John W. Linville
parent f7ad1eed4d
commit 204cc5c44f
3 changed files with 53 additions and 0 deletions

View File

@ -960,6 +960,32 @@ out:
return ret;
}
int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address)
{
struct wl1251_acx_arp_filter *acx;
int ret;
wl1251_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx)
return -ENOMEM;
acx->version = ACX_IPV4_VERSION;
acx->enable = enable;
if (enable)
memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
ret = wl1251_cmd_configure(wl, ACX_ARP_IP_FILTER,
acx, sizeof(*acx));
if (ret < 0)
wl1251_warning("failed to set arp ip filter: %d", ret);
kfree(acx);
return ret;
}
int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
u8 aifs, u16 txop)
{

View File

@ -1232,6 +1232,20 @@ struct wl1251_acx_bet_enable {
u8 padding[2];
} __packed;
#define ACX_IPV4_VERSION 4
#define ACX_IPV6_VERSION 6
#define ACX_IPV4_ADDR_SIZE 4
struct wl1251_acx_arp_filter {
struct acx_header header;
u8 version; /* The IP version: 4 - IPv4, 6 - IPv6.*/
u8 enable; /* 1 - ARP filtering is enabled, 0 - disabled */
u8 padding[2];
u8 address[16]; /* The IP address used to filter ARP packets.
ARP packets that do not match this address are
dropped. When the IP Version is 4, the last 12
bytes of the the address are ignored. */
} __attribute__((packed));
struct wl1251_acx_ac_cfg {
struct acx_header header;
@ -1473,6 +1487,7 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl);
int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
u8 max_consecutive);
int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address);
int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
u8 aifs, u16 txop);
int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,

View File

@ -979,6 +979,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
{
struct wl1251 *wl = hw->priv;
struct sk_buff *beacon, *skb;
bool enable;
int ret;
wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@ -1077,6 +1078,17 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
if (changed & BSS_CHANGED_ARP_FILTER) {
__be32 addr = bss_conf->arp_addr_list[0];
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc;
wl1251_acx_arp_ip_filter(wl, enable, addr);
if (ret < 0)
goto out_sleep;
}
if (changed & BSS_CHANGED_BEACON) {
beacon = ieee80211_beacon_get(hw, vif);
if (!beacon)