Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 266569
b: refs/heads/master
c: 8bdfbf4
h: refs/heads/master
i:
  266567: 0733544
v: v3
  • Loading branch information
Jouni Malinen authored and Kalle Valo committed Aug 31, 2011
1 parent 22a881e commit 68919a7
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 4 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: a587526a44d0c2812ee9d650e7c0626b48697aca
refs/heads/master: 8bdfbf40721a4338eb4f6dec55b3205188c45973
96 changes: 93 additions & 3 deletions trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,48 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
return 0;
}

static bool ath6kl_is_p2p_ie(const u8 *pos)
{
return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
pos[2] == 0x50 && pos[3] == 0x6f &&
pos[4] == 0x9a && pos[5] == 0x09;
}

static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
size_t ies_len)
{
const u8 *pos;
u8 *buf = NULL;
size_t len = 0;
int ret;

/*
* Filter out P2P IE(s) since they will be included depending on
* the Probe Request frame in ath6kl_send_go_probe_resp().
*/

if (ies && ies_len) {
buf = kmalloc(ies_len, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
pos = ies;
while (pos + 1 < ies + ies_len) {
if (pos + 2 + pos[1] > ies + ies_len)
break;
if (!ath6kl_is_p2p_ie(pos)) {
memcpy(buf + len, pos, 2 + pos[1]);
len += 2 + pos[1];
}
pos += 2 + pos[1];
}
}

ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
buf, len);
kfree(buf);
return ret;
}

static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *info, bool add)
{
Expand Down Expand Up @@ -1545,9 +1587,8 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
return res;
}
if (info->proberesp_ies) {
res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
info->proberesp_ies,
info->proberesp_ies_len);
res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
info->proberesp_ies_len);
if (res)
return res;
}
Expand Down Expand Up @@ -1735,6 +1776,41 @@ static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
}

static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
size_t len, unsigned int freq)
{
const u8 *pos;
u8 *p2p;
int p2p_len;
int ret;
const struct ieee80211_mgmt *mgmt;

mgmt = (const struct ieee80211_mgmt *) buf;

/* Include P2P IE(s) from the frame generated in user space. */

p2p = kmalloc(len, GFP_KERNEL);
if (p2p == NULL)
return -ENOMEM;
p2p_len = 0;

pos = mgmt->u.probe_resp.variable;
while (pos + 1 < buf + len) {
if (pos + 2 + pos[1] > buf + len)
break;
if (ath6kl_is_p2p_ie(pos)) {
memcpy(p2p + p2p_len, pos, 2 + pos[1]);
p2p_len += 2 + pos[1];
}
pos += 2 + pos[1];
}

ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
p2p, p2p_len);
kfree(p2p);
return ret;
}

static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
Expand All @@ -1743,6 +1819,20 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
{
struct ath6kl *ar = ath6kl_priv(dev);
u32 id;
const struct ieee80211_mgmt *mgmt;

mgmt = (const struct ieee80211_mgmt *) buf;
if (buf + len >= mgmt->u.probe_resp.variable &&
ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
ieee80211_is_probe_resp(mgmt->frame_control)) {
/*
* Send Probe Response frame in AP mode using a separate WMI
* command to allow the target to fill in the generic IEs.
*/
*cookie = 0; /* TX status not supported */
return ath6kl_send_go_probe_resp(ar, buf, len,
chan->center_freq);
}

id = ar->send_action_id++;
if (id == 0) {
Expand Down

0 comments on commit 68919a7

Please sign in to comment.