diff options
author | Arik Nemtsov <arik@wizery.com> | 2011-09-03 13:22:03 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-09-23 07:43:32 -0400 |
commit | 68eaaf6ee5ac35d8e592834219cee9c9e88fdb24 (patch) | |
tree | 45bb00cb06c9b1cedbe8e19cfd641086a8688cee | |
parent | df4c849f4608e8962f019fea6021ebd602a11641 (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>
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 75 |
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 | ||
3105 | static 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 | |||
3105 | static int wl1271_bss_erp_info_changed(struct wl1271 *wl, | 3161 | static 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; |