Commit 204cc5c4 authored by David Gnedt's avatar David Gnedt Committed by John W. Linville

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: default avatarDavid Gnedt <david.gnedt@davizone.at>
Signed-off-by: default avatarPali Rohár <pali.rohar@gmail.com>
Signed-off-by: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f7ad1eed
......@@ -960,6 +960,32 @@ int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
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)
{
......
......@@ -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,
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment