Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 225320
b: refs/heads/master
c: c531277
h: refs/heads/master
v: v3
  • Loading branch information
Eliad Peller authored and Luciano Coelho committed Dec 15, 2010
1 parent 8c90ed7 commit 07dd136
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b69eb80bf7a6922fef8056d42b06124a7de31501
refs/heads/master: c5312772156bb5f9b2e95e4c91526d578426a069
4 changes: 2 additions & 2 deletions trunk/drivers/net/wireless/wl12xx/acx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,7 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
return ret;
}

int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address)
{
struct wl1271_acx_arp_filter *acx;
int ret;
Expand All @@ -1057,7 +1057,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
acx->version = ACX_IPV4_VERSION;
acx->enable = enable;

if (enable == true)
if (enable)
memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);

ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
Expand Down
9 changes: 7 additions & 2 deletions trunk/drivers/net/wireless/wl12xx/acx.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,10 +868,15 @@ struct wl1271_acx_bet_enable {
#define ACX_IPV4_VERSION 4
#define ACX_IPV6_VERSION 6
#define ACX_IPV4_ADDR_SIZE 4

/* bitmap of enabled arp_filter features */
#define ACX_ARP_FILTER_ARP_FILTERING BIT(0)
#define ACX_ARP_FILTER_AUTO_ARP BIT(1)

struct wl1271_acx_arp_filter {
struct acx_header header;
u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
u8 enable; /* 1 to enable ARP filtering, 0 to disable */
u8 enable; /* bitmap of enabled ARP filtering features */
u8 padding[2];
u8 address[16]; /* The configured device IP address - all ARP
requests directed to this IP address will pass
Expand Down Expand Up @@ -1168,7 +1173,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl);
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
int wl1271_acx_smart_reflex(struct wl1271 *wl);
int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address);
int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address);
int wl1271_acx_pm_config(struct wl1271 *wl);
int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
Expand Down
41 changes: 41 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,47 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
return skb;
}

int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr)
{
int ret;
struct wl12xx_arp_rsp_template tmpl;
struct ieee80211_hdr_3addr *hdr;
struct arphdr *arp_hdr;

memset(&tmpl, 0, sizeof(tmpl));

/* mac80211 header */
hdr = &tmpl.hdr;
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_DATA |
IEEE80211_FCTL_TODS);
memcpy(hdr->addr1, wl->vif->bss_conf.bssid, ETH_ALEN);
memcpy(hdr->addr2, wl->vif->addr, ETH_ALEN);
memset(hdr->addr3, 0xff, ETH_ALEN);

/* llc layer */
memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header));
tmpl.llc_type = htons(ETH_P_ARP);

/* arp header */
arp_hdr = &tmpl.arp_hdr;
arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
arp_hdr->ar_pro = htons(ETH_P_IP);
arp_hdr->ar_hln = ETH_ALEN;
arp_hdr->ar_pln = 4;
arp_hdr->ar_op = htons(ARPOP_REPLY);

/* arp payload */
memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN);
tmpl.sender_ip = ip_addr;

ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
&tmpl, sizeof(tmpl), 0,
wl->basic_rate);

return ret;
}

int wl1271_build_qos_null_data(struct wl1271 *wl)
{
struct ieee80211_qos_hdr template;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
const u8 *ie, size_t ie_len, u8 band);
struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
struct sk_buff *skb);
int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr);
int wl1271_build_qos_null_data(struct wl1271 *wl);
int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
Expand Down Expand Up @@ -124,6 +125,7 @@ enum cmd_templ {
CMD_TEMPL_CTS, /*
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP,
CMD_TEMPL_MAX = 0xff
};

Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ int wl1271_init_templates_config(struct wl1271 *wl)
if (ret < 0)
return ret;

ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
sizeof
(struct wl12xx_arp_rsp_template),
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
WL1271_CMD_TEMPL_MAX_SIZE, i,
Expand Down
24 changes: 20 additions & 4 deletions trunk/drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2110,10 +2110,26 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
__be32 addr = bss_conf->arp_addr_list[0];
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);

if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled)
ret = wl1271_acx_arp_ip_filter(wl, true, addr);
else
ret = wl1271_acx_arp_ip_filter(wl, false, addr);
if (bss_conf->arp_addr_cnt == 1 &&
bss_conf->arp_filter_enabled) {
/*
* The template should have been configured only upon
* association. however, it seems that the correct ip
* isn't being set (when sending), so we have to
* reconfigure the template upon every ip change.
*/
ret = wl1271_cmd_build_arp_rsp(wl, addr);
if (ret < 0) {
wl1271_warning("build arp rsp failed: %d", ret);
goto out_sleep;
}

ret = wl1271_acx_arp_ip_filter(wl,
(ACX_ARP_FILTER_ARP_FILTERING |
ACX_ARP_FILTER_AUTO_ARP),
addr);
} else
ret = wl1271_acx_arp_ip_filter(wl, 0, addr);

if (ret < 0)
goto out_sleep;
Expand Down
14 changes: 14 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/wl12xx_80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __WL12XX_80211_H__

#include <linux/if_ether.h> /* ETH_ALEN */
#include <linux/if_arp.h>

/* RATES */
#define IEEE80211_CCK_RATE_1MB 0x02
Expand Down Expand Up @@ -140,6 +141,19 @@ struct wl12xx_probe_req_template {
struct wl12xx_ie_rates ext_rates;
} __packed;

struct wl12xx_arp_rsp_template {
struct ieee80211_hdr_3addr hdr;

u8 llc_hdr[sizeof(rfc1042_header)];
u16 llc_type;

struct arphdr arp_hdr;
u8 sender_hw[ETH_ALEN];
u32 sender_ip;
u8 target_hw[ETH_ALEN];
u32 target_ip;
} __packed;


struct wl12xx_probe_resp_template {
struct ieee80211_header header;
Expand Down

0 comments on commit 07dd136

Please sign in to comment.