aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-09-03 13:22:03 -0400
committerLuciano Coelho <coelho@ti.com>2011-09-23 07:43:32 -0400
commit68eaaf6ee5ac35d8e592834219cee9c9e88fdb24 (patch)
tree45bb00cb06c9b1cedbe8e19cfd641086a8688cee /drivers/net/wireless
parentdf4c849f4608e8962f019fea6021ebd602a11641 (diff)
wl12xx: AP mode - support hidden SSID
If a hidden SSID is requested, generate a probe response template containing the real SSID. Depends on the patch "mac80211: add ssid config to bss information in AP-mode". Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c24
-rw-r--r--drivers/net/wireless/wl12xx/main.c75
2 files changed, 82 insertions, 17 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 084262f169b2..51be8f7fbb88 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -661,12 +661,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
661 661
662 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id); 662 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id);
663 663
664 /* 664 /* trying to use hidden SSID with an old hostapd version */
665 * We currently do not support hidden SSID. The real SSID 665 if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) {
666 * should be fetched from mac80211 first. 666 wl1271_error("got a null SSID from beacon/bss");
667 */
668 if (wl->ssid_len == 0) {
669 wl1271_warning("Hidden SSID currently not supported for AP");
670 ret = -EINVAL; 667 ret = -EINVAL;
671 goto out; 668 goto out;
672 } 669 }
@@ -695,9 +692,18 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
695 cmd->ap.dtim_interval = bss_conf->dtim_period; 692 cmd->ap.dtim_interval = bss_conf->dtim_period;
696 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; 693 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
697 cmd->channel = wl->channel; 694 cmd->channel = wl->channel;
698 cmd->ap.ssid_len = wl->ssid_len; 695
699 cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC; 696 if (!bss_conf->hidden_ssid) {
700 memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len); 697 /* take the SSID from the beacon for backward compatibility */
698 cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
699 cmd->ap.ssid_len = wl->ssid_len;
700 memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
701 } else {
702 cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
703 cmd->ap.ssid_len = bss_conf->ssid_len;
704 memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
705 }
706
701 cmd->ap.local_rates = cpu_to_le32(0xffffffff); 707 cmd->ap.local_rates = cpu_to_le32(0xffffffff);
702 708
703 switch (wl->band) { 709 switch (wl->band) {
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 62118b7988bd..02b5c007d1bf 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -3102,6 +3102,62 @@ static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
3102 skb_trim(skb, skb->len - len); 3102 skb_trim(skb, skb->len - len);
3103} 3103}
3104 3104
3105static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl,
3106 u8 *probe_rsp_data,
3107 size_t probe_rsp_len,
3108 u32 rates)
3109{
3110 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
3111 u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE];
3112 int ssid_ie_offset, ie_offset, templ_len;
3113 const u8 *ptr;
3114
3115 /* no need to change probe response if the SSID is set correctly */
3116 if (wl->ssid_len > 0)
3117 return wl1271_cmd_template_set(wl,
3118 CMD_TEMPL_AP_PROBE_RESPONSE,
3119 probe_rsp_data,
3120 probe_rsp_len, 0,
3121 rates);
3122
3123 if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) {
3124 wl1271_error("probe_rsp template too big");
3125 return -EINVAL;
3126 }
3127
3128 /* start searching from IE offset */
3129 ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
3130
3131 ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset,
3132 probe_rsp_len - ie_offset);
3133 if (!ptr) {
3134 wl1271_error("No SSID in beacon!");
3135 return -EINVAL;
3136 }
3137
3138 ssid_ie_offset = ptr - probe_rsp_data;
3139 ptr += (ptr[1] + 2);
3140
3141 memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset);
3142
3143 /* insert SSID from bss_conf */
3144 probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID;
3145 probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len;
3146 memcpy(probe_rsp_templ + ssid_ie_offset + 2,
3147 bss_conf->ssid, bss_conf->ssid_len);
3148 templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len;
3149
3150 memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len,
3151 ptr, probe_rsp_len - (ptr - probe_rsp_data));
3152 templ_len += probe_rsp_len - (ptr - probe_rsp_data);
3153
3154 return wl1271_cmd_template_set(wl,
3155 CMD_TEMPL_AP_PROBE_RESPONSE,
3156 probe_rsp_templ,
3157 templ_len, 0,
3158 rates);
3159}
3160
3105static int wl1271_bss_erp_info_changed(struct wl1271 *wl, 3161static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
3106 struct ieee80211_bss_conf *bss_conf, 3162 struct ieee80211_bss_conf *bss_conf,
3107 u32 changed) 3163 u32 changed)
@@ -3201,14 +3257,17 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
3201 hdr = (struct ieee80211_hdr *) beacon->data; 3257 hdr = (struct ieee80211_hdr *) beacon->data;
3202 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 3258 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
3203 IEEE80211_STYPE_PROBE_RESP); 3259 IEEE80211_STYPE_PROBE_RESP);
3204 3260 if (is_ap)
3205 tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE : 3261 ret = wl1271_ap_set_probe_resp_tmpl(wl,
3206 CMD_TEMPL_PROBE_RESPONSE; 3262 beacon->data,
3207 ret = wl1271_cmd_template_set(wl, 3263 beacon->len,
3208 tmpl_id, 3264 wl1271_tx_min_rate_get(wl));
3209 beacon->data, 3265 else
3210 beacon->len, 0, 3266 ret = wl1271_cmd_template_set(wl,
3211 wl1271_tx_min_rate_get(wl)); 3267 CMD_TEMPL_PROBE_RESPONSE,
3268 beacon->data,
3269 beacon->len, 0,
3270 wl1271_tx_min_rate_get(wl));
3212 dev_kfree_skb(beacon); 3271 dev_kfree_skb(beacon);
3213 if (ret < 0) 3272 if (ret < 0)
3214 goto out; 3273 goto out;