Loading drivers/net/wireless/wl12xx/cmd.c +25 −18 Original line number Diff line number Diff line Loading @@ -661,12 +661,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl) wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id); /* * We currently do not support hidden SSID. The real SSID * should be fetched from mac80211 first. */ if (wl->ssid_len == 0) { wl1271_warning("Hidden SSID currently not supported for AP"); /* trying to use hidden SSID with an old hostapd version */ if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) { wl1271_error("got a null SSID from beacon/bss"); ret = -EINVAL; goto out; } Loading Loading @@ -695,9 +692,18 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl) cmd->ap.dtim_interval = bss_conf->dtim_period; cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; cmd->channel = wl->channel; cmd->ap.ssid_len = wl->ssid_len; if (!bss_conf->hidden_ssid) { /* take the SSID from the beacon for backward compatibility */ cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC; cmd->ap.ssid_len = wl->ssid_len; memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len); } else { cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN; cmd->ap.ssid_len = bss_conf->ssid_len; memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); } cmd->ap.local_rates = cpu_to_le32(0xffffffff); switch (wl->band) { Loading Loading @@ -1106,6 +1112,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, { struct sk_buff *skb; int ret; u32 rate; skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, ie, ie_len); Loading @@ -1116,14 +1123,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); if (band == IEEE80211_BAND_2GHZ) ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, skb->data, skb->len, 0, wl->conf.tx.basic_rate); skb->data, skb->len, 0, rate); else ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, skb->data, skb->len, 0, wl->conf.tx.basic_rate_5); skb->data, skb->len, 0, rate); out: dev_kfree_skb(skb); Loading @@ -1134,6 +1140,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, struct sk_buff *skb) { int ret; u32 rate; if (!skb) skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); Loading @@ -1142,14 +1149,13 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]); if (wl->band == IEEE80211_BAND_2GHZ) ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, skb->data, skb->len, 0, wl->conf.tx.basic_rate); skb->data, skb->len, 0, rate); else ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, skb->data, skb->len, 0, wl->conf.tx.basic_rate_5); skb->data, skb->len, 0, rate); if (ret < 0) wl1271_error("Unable to set ap probe request template."); Loading Loading @@ -1442,7 +1448,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates)); cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, wl->band)); wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x", cmd->supported_rates, sta->uapsd_queues); Loading drivers/net/wireless/wl12xx/conf.h +2 −4 Original line number Diff line number Diff line Loading @@ -454,12 +454,10 @@ struct conf_rx_settings { #define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \ CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS) /* * Default rates for working as IBSS. use 11b rates */ /* default rates for working as IBSS (11b and OFDM) */ #define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \ CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \ CONF_HW_BIT_RATE_11MBPS); CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES); struct conf_tx_rate_class { Loading drivers/net/wireless/wl12xx/event.c +1 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl) } else { int i; struct wl1271_link *lnk; for (i = WL1271_AP_STA_HLID_START; i < WL12XX_MAX_LINKS; i++) { for (i = WL1271_AP_STA_HLID_START; i < AP_MAX_LINKS; i++) { lnk = &wl->links[i]; if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap) continue; Loading drivers/net/wireless/wl12xx/init.c +10 −7 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl) { struct wl12xx_disconn_template *tmpl; int ret; u32 rate; tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); if (!tmpl) { Loading @@ -113,9 +114,9 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl) tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, tmpl, sizeof(*tmpl), 0, wl1271_tx_min_rate_get(wl)); tmpl, sizeof(*tmpl), 0, rate); out: kfree(tmpl); Loading @@ -126,6 +127,7 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl) { struct ieee80211_hdr_3addr *nullfunc; int ret; u32 rate; nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); if (!nullfunc) { Loading @@ -142,9 +144,9 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl) memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN); memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN); rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, sizeof(*nullfunc), 0, wl1271_tx_min_rate_get(wl)); sizeof(*nullfunc), 0, rate); out: kfree(nullfunc); Loading @@ -155,6 +157,7 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) { struct ieee80211_qos_hdr *qosnull; int ret; u32 rate; qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); if (!qosnull) { Loading @@ -171,9 +174,9 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN); memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN); rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, sizeof(*qosnull), 0, wl1271_tx_min_rate_get(wl)); sizeof(*qosnull), 0, rate); out: kfree(qosnull); Loading Loading @@ -498,7 +501,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl) return ret; /* use the min basic rate for AP broadcast/multicast */ rc.enabled_rates = wl1271_tx_min_rate_get(wl); rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); rc.short_retry_limit = 10; rc.long_retry_limit = 10; rc.aflags = 0; Loading drivers/net/wireless/wl12xx/main.c +171 −30 Original line number Diff line number Diff line Loading @@ -2099,6 +2099,8 @@ deinit: wl->time_offset = 0; wl->session_counter = 0; wl->rate_set = CONF_TX_RATE_MASK_BASIC; wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; wl->vif = NULL; wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; wl1271_free_ap_keys(wl); Loading Loading @@ -2237,14 +2239,8 @@ out: static void wl1271_set_band_rate(struct wl1271 *wl) { if (wl->band == IEEE80211_BAND_2GHZ) { wl->basic_rate_set = wl->conf.tx.basic_rate; wl->rate_set = wl->conf.tx.basic_rate; } else { wl->basic_rate_set = wl->conf.tx.basic_rate_5; wl->rate_set = wl->conf.tx.basic_rate_5; } wl->basic_rate_set = wl->bitrate_masks[wl->band]; wl->rate_set = wl->basic_rate_set; } static bool wl12xx_is_roc(struct wl1271 *wl) Loading Loading @@ -2273,7 +2269,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) if (ret < 0) goto out; } wl->rate_set = wl1271_tx_min_rate_get(wl); wl->rate_set = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; Loading Loading @@ -2355,6 +2351,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL && ((wl->band != conf->channel->band) || (wl->channel != channel))) { /* send all pending packets */ wl1271_tx_work_locked(wl); wl->band = conf->channel->band; wl->channel = channel; Loading @@ -2368,7 +2366,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) wl1271_set_band_rate(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) wl1271_warning("rate policy for channel " Loading Loading @@ -3069,6 +3068,93 @@ static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, return 0; } static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset) { int len; const u8 *next, *end = skb->data + skb->len; u8 *ie = (u8 *)cfg80211_find_ie(eid, skb->data + ieoffset, skb->len - ieoffset); if (!ie) return; len = ie[1] + 2; next = ie + len; memmove(ie, next, end - next); skb_trim(skb, skb->len - len); } static void wl12xx_remove_vendor_ie(struct sk_buff *skb, unsigned int oui, u8 oui_type, int ieoffset) { int len; const u8 *next, *end = skb->data + skb->len; u8 *ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type, skb->data + ieoffset, skb->len - ieoffset); if (!ie) return; len = ie[1] + 2; next = ie + len; memmove(ie, next, end - next); skb_trim(skb, skb->len - len); } static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u8 *probe_rsp_data, size_t probe_rsp_len, u32 rates) { struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf; u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE]; int ssid_ie_offset, ie_offset, templ_len; const u8 *ptr; /* no need to change probe response if the SSID is set correctly */ if (wl->ssid_len > 0) return wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, probe_rsp_data, probe_rsp_len, 0, rates); if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) { wl1271_error("probe_rsp template too big"); return -EINVAL; } /* start searching from IE offset */ ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset, probe_rsp_len - ie_offset); if (!ptr) { wl1271_error("No SSID in beacon!"); return -EINVAL; } ssid_ie_offset = ptr - probe_rsp_data; ptr += (ptr[1] + 2); memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset); /* insert SSID from bss_conf */ probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID; probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len; memcpy(probe_rsp_templ + ssid_ie_offset + 2, bss_conf->ssid, bss_conf->ssid_len); templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len; memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len, ptr, probe_rsp_len - (ptr - probe_rsp_data)); templ_len += probe_rsp_len - (ptr - probe_rsp_data); return wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, probe_rsp_templ, templ_len, 0, rates); } static int wl1271_bss_erp_info_changed(struct wl1271 *wl, struct ieee80211_bss_conf *bss_conf, u32 changed) Loading Loading @@ -3125,6 +3211,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, if ((changed & BSS_CHANGED_BEACON)) { struct ieee80211_hdr *hdr; u32 min_rate; int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); Loading @@ -3140,28 +3227,46 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, dev_kfree_skb(beacon); goto out; } min_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : CMD_TEMPL_BEACON; ret = wl1271_cmd_template_set(wl, tmpl_id, beacon->data, beacon->len, 0, wl1271_tx_min_rate_get(wl)); min_rate); if (ret < 0) { dev_kfree_skb(beacon); goto out; } /* remove TIM ie from probe response */ wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); /* * remove p2p ie from probe response. * the fw reponds to probe requests that don't include * the p2p ie. probe requests with p2p ie will be passed, * and will be responded by the supplicant (the spec * forbids including the p2p ie when responding to probe * requests that didn't include it). */ wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, ieoffset); hdr = (struct ieee80211_hdr *) beacon->data; hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE : CMD_TEMPL_PROBE_RESPONSE; if (is_ap) ret = wl1271_ap_set_probe_resp_tmpl(wl, beacon->data, beacon->len, min_rate); else ret = wl1271_cmd_template_set(wl, tmpl_id, CMD_TEMPL_PROBE_RESPONSE, beacon->data, beacon->len, 0, wl1271_tx_min_rate_get(wl)); min_rate); dev_kfree_skb(beacon); if (ret < 0) goto out; Loading @@ -3182,8 +3287,10 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, if ((changed & BSS_CHANGED_BASIC_RATES)) { u32 rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, wl->band); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_init_ap_rates(wl); if (ret < 0) { Loading Loading @@ -3365,12 +3472,15 @@ sta_not_found: * to use with control frames. */ rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, wl->band); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); if (sta_rate_set) wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rate_set); sta_rate_set, wl->band); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; Loading Loading @@ -3417,7 +3527,8 @@ sta_not_found: /* revert back to minimum rates for the current band */ wl1271_set_band_rate(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; Loading Loading @@ -3468,11 +3579,13 @@ sta_not_found: if (bss_conf->ibss_joined) { u32 rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, wl->band); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); /* by default, use 11b rates */ /* by default, use 11b + OFDM rates */ wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) Loading Loading @@ -3992,6 +4105,29 @@ out: return ret; } static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) { struct wl1271 *wl = hw->priv; int i; wl1271_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x", mask->control[NL80211_BAND_2GHZ].legacy, mask->control[NL80211_BAND_5GHZ].legacy); mutex_lock(&wl->mutex); for (i = 0; i < IEEE80211_NUM_BANDS; i++) wl->bitrate_masks[i] = wl1271_tx_enabled_rates_get(wl, mask->control[i].legacy, i); mutex_unlock(&wl->mutex); return 0; } static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) { struct wl1271 *wl = hw->priv; Loading Loading @@ -4267,6 +4403,7 @@ static const struct ieee80211_ops wl1271_ops = { .sta_remove = wl1271_op_sta_remove, .ampdu_action = wl1271_op_ampdu_action, .tx_frames_pending = wl1271_tx_frames_pending, .set_bitrate_mask = wl12xx_set_bitrate_mask, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) }; Loading Loading @@ -4585,6 +4722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) int i, j, ret; unsigned int order; BUILD_BUG_ON(AP_MAX_LINKS > WL12XX_MAX_LINKS); hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); if (!hw) { wl1271_error("could not alloc ieee80211_hw"); Loading Loading @@ -4687,6 +4826,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) /* Apply default driver configuration. */ wl1271_conf_init(wl); wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; order = get_order(WL1271_AGGR_BUFFER_SIZE); wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); Loading Loading
drivers/net/wireless/wl12xx/cmd.c +25 −18 Original line number Diff line number Diff line Loading @@ -661,12 +661,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl) wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id); /* * We currently do not support hidden SSID. The real SSID * should be fetched from mac80211 first. */ if (wl->ssid_len == 0) { wl1271_warning("Hidden SSID currently not supported for AP"); /* trying to use hidden SSID with an old hostapd version */ if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) { wl1271_error("got a null SSID from beacon/bss"); ret = -EINVAL; goto out; } Loading Loading @@ -695,9 +692,18 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl) cmd->ap.dtim_interval = bss_conf->dtim_period; cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; cmd->channel = wl->channel; cmd->ap.ssid_len = wl->ssid_len; if (!bss_conf->hidden_ssid) { /* take the SSID from the beacon for backward compatibility */ cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC; cmd->ap.ssid_len = wl->ssid_len; memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len); } else { cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN; cmd->ap.ssid_len = bss_conf->ssid_len; memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); } cmd->ap.local_rates = cpu_to_le32(0xffffffff); switch (wl->band) { Loading Loading @@ -1106,6 +1112,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, { struct sk_buff *skb; int ret; u32 rate; skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, ie, ie_len); Loading @@ -1116,14 +1123,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); if (band == IEEE80211_BAND_2GHZ) ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, skb->data, skb->len, 0, wl->conf.tx.basic_rate); skb->data, skb->len, 0, rate); else ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, skb->data, skb->len, 0, wl->conf.tx.basic_rate_5); skb->data, skb->len, 0, rate); out: dev_kfree_skb(skb); Loading @@ -1134,6 +1140,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, struct sk_buff *skb) { int ret; u32 rate; if (!skb) skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); Loading @@ -1142,14 +1149,13 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]); if (wl->band == IEEE80211_BAND_2GHZ) ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, skb->data, skb->len, 0, wl->conf.tx.basic_rate); skb->data, skb->len, 0, rate); else ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, skb->data, skb->len, 0, wl->conf.tx.basic_rate_5); skb->data, skb->len, 0, rate); if (ret < 0) wl1271_error("Unable to set ap probe request template."); Loading Loading @@ -1442,7 +1448,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates)); cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, wl->band)); wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x", cmd->supported_rates, sta->uapsd_queues); Loading
drivers/net/wireless/wl12xx/conf.h +2 −4 Original line number Diff line number Diff line Loading @@ -454,12 +454,10 @@ struct conf_rx_settings { #define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \ CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS) /* * Default rates for working as IBSS. use 11b rates */ /* default rates for working as IBSS (11b and OFDM) */ #define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \ CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \ CONF_HW_BIT_RATE_11MBPS); CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES); struct conf_tx_rate_class { Loading
drivers/net/wireless/wl12xx/event.c +1 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl) } else { int i; struct wl1271_link *lnk; for (i = WL1271_AP_STA_HLID_START; i < WL12XX_MAX_LINKS; i++) { for (i = WL1271_AP_STA_HLID_START; i < AP_MAX_LINKS; i++) { lnk = &wl->links[i]; if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap) continue; Loading
drivers/net/wireless/wl12xx/init.c +10 −7 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl) { struct wl12xx_disconn_template *tmpl; int ret; u32 rate; tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); if (!tmpl) { Loading @@ -113,9 +114,9 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl) tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, tmpl, sizeof(*tmpl), 0, wl1271_tx_min_rate_get(wl)); tmpl, sizeof(*tmpl), 0, rate); out: kfree(tmpl); Loading @@ -126,6 +127,7 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl) { struct ieee80211_hdr_3addr *nullfunc; int ret; u32 rate; nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); if (!nullfunc) { Loading @@ -142,9 +144,9 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl) memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN); memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN); rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, sizeof(*nullfunc), 0, wl1271_tx_min_rate_get(wl)); sizeof(*nullfunc), 0, rate); out: kfree(nullfunc); Loading @@ -155,6 +157,7 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) { struct ieee80211_qos_hdr *qosnull; int ret; u32 rate; qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); if (!qosnull) { Loading @@ -171,9 +174,9 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN); memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN); rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, sizeof(*qosnull), 0, wl1271_tx_min_rate_get(wl)); sizeof(*qosnull), 0, rate); out: kfree(qosnull); Loading Loading @@ -498,7 +501,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl) return ret; /* use the min basic rate for AP broadcast/multicast */ rc.enabled_rates = wl1271_tx_min_rate_get(wl); rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); rc.short_retry_limit = 10; rc.long_retry_limit = 10; rc.aflags = 0; Loading
drivers/net/wireless/wl12xx/main.c +171 −30 Original line number Diff line number Diff line Loading @@ -2099,6 +2099,8 @@ deinit: wl->time_offset = 0; wl->session_counter = 0; wl->rate_set = CONF_TX_RATE_MASK_BASIC; wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; wl->vif = NULL; wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; wl1271_free_ap_keys(wl); Loading Loading @@ -2237,14 +2239,8 @@ out: static void wl1271_set_band_rate(struct wl1271 *wl) { if (wl->band == IEEE80211_BAND_2GHZ) { wl->basic_rate_set = wl->conf.tx.basic_rate; wl->rate_set = wl->conf.tx.basic_rate; } else { wl->basic_rate_set = wl->conf.tx.basic_rate_5; wl->rate_set = wl->conf.tx.basic_rate_5; } wl->basic_rate_set = wl->bitrate_masks[wl->band]; wl->rate_set = wl->basic_rate_set; } static bool wl12xx_is_roc(struct wl1271 *wl) Loading Loading @@ -2273,7 +2269,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) if (ret < 0) goto out; } wl->rate_set = wl1271_tx_min_rate_get(wl); wl->rate_set = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; Loading Loading @@ -2355,6 +2351,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL && ((wl->band != conf->channel->band) || (wl->channel != channel))) { /* send all pending packets */ wl1271_tx_work_locked(wl); wl->band = conf->channel->band; wl->channel = channel; Loading @@ -2368,7 +2366,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) wl1271_set_band_rate(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) wl1271_warning("rate policy for channel " Loading Loading @@ -3069,6 +3068,93 @@ static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, return 0; } static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset) { int len; const u8 *next, *end = skb->data + skb->len; u8 *ie = (u8 *)cfg80211_find_ie(eid, skb->data + ieoffset, skb->len - ieoffset); if (!ie) return; len = ie[1] + 2; next = ie + len; memmove(ie, next, end - next); skb_trim(skb, skb->len - len); } static void wl12xx_remove_vendor_ie(struct sk_buff *skb, unsigned int oui, u8 oui_type, int ieoffset) { int len; const u8 *next, *end = skb->data + skb->len; u8 *ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type, skb->data + ieoffset, skb->len - ieoffset); if (!ie) return; len = ie[1] + 2; next = ie + len; memmove(ie, next, end - next); skb_trim(skb, skb->len - len); } static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u8 *probe_rsp_data, size_t probe_rsp_len, u32 rates) { struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf; u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE]; int ssid_ie_offset, ie_offset, templ_len; const u8 *ptr; /* no need to change probe response if the SSID is set correctly */ if (wl->ssid_len > 0) return wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, probe_rsp_data, probe_rsp_len, 0, rates); if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) { wl1271_error("probe_rsp template too big"); return -EINVAL; } /* start searching from IE offset */ ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset, probe_rsp_len - ie_offset); if (!ptr) { wl1271_error("No SSID in beacon!"); return -EINVAL; } ssid_ie_offset = ptr - probe_rsp_data; ptr += (ptr[1] + 2); memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset); /* insert SSID from bss_conf */ probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID; probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len; memcpy(probe_rsp_templ + ssid_ie_offset + 2, bss_conf->ssid, bss_conf->ssid_len); templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len; memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len, ptr, probe_rsp_len - (ptr - probe_rsp_data)); templ_len += probe_rsp_len - (ptr - probe_rsp_data); return wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, probe_rsp_templ, templ_len, 0, rates); } static int wl1271_bss_erp_info_changed(struct wl1271 *wl, struct ieee80211_bss_conf *bss_conf, u32 changed) Loading Loading @@ -3125,6 +3211,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, if ((changed & BSS_CHANGED_BEACON)) { struct ieee80211_hdr *hdr; u32 min_rate; int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); Loading @@ -3140,28 +3227,46 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, dev_kfree_skb(beacon); goto out; } min_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : CMD_TEMPL_BEACON; ret = wl1271_cmd_template_set(wl, tmpl_id, beacon->data, beacon->len, 0, wl1271_tx_min_rate_get(wl)); min_rate); if (ret < 0) { dev_kfree_skb(beacon); goto out; } /* remove TIM ie from probe response */ wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); /* * remove p2p ie from probe response. * the fw reponds to probe requests that don't include * the p2p ie. probe requests with p2p ie will be passed, * and will be responded by the supplicant (the spec * forbids including the p2p ie when responding to probe * requests that didn't include it). */ wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, ieoffset); hdr = (struct ieee80211_hdr *) beacon->data; hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE : CMD_TEMPL_PROBE_RESPONSE; if (is_ap) ret = wl1271_ap_set_probe_resp_tmpl(wl, beacon->data, beacon->len, min_rate); else ret = wl1271_cmd_template_set(wl, tmpl_id, CMD_TEMPL_PROBE_RESPONSE, beacon->data, beacon->len, 0, wl1271_tx_min_rate_get(wl)); min_rate); dev_kfree_skb(beacon); if (ret < 0) goto out; Loading @@ -3182,8 +3287,10 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, if ((changed & BSS_CHANGED_BASIC_RATES)) { u32 rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, wl->band); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_init_ap_rates(wl); if (ret < 0) { Loading Loading @@ -3365,12 +3472,15 @@ sta_not_found: * to use with control frames. */ rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, wl->band); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); if (sta_rate_set) wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rate_set); sta_rate_set, wl->band); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; Loading Loading @@ -3417,7 +3527,8 @@ sta_not_found: /* revert back to minimum rates for the current band */ wl1271_set_band_rate(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; Loading Loading @@ -3468,11 +3579,13 @@ sta_not_found: if (bss_conf->ibss_joined) { u32 rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, wl->band); wl->basic_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); /* by default, use 11b rates */ /* by default, use 11b + OFDM rates */ wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) Loading Loading @@ -3992,6 +4105,29 @@ out: return ret; } static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) { struct wl1271 *wl = hw->priv; int i; wl1271_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x", mask->control[NL80211_BAND_2GHZ].legacy, mask->control[NL80211_BAND_5GHZ].legacy); mutex_lock(&wl->mutex); for (i = 0; i < IEEE80211_NUM_BANDS; i++) wl->bitrate_masks[i] = wl1271_tx_enabled_rates_get(wl, mask->control[i].legacy, i); mutex_unlock(&wl->mutex); return 0; } static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) { struct wl1271 *wl = hw->priv; Loading Loading @@ -4267,6 +4403,7 @@ static const struct ieee80211_ops wl1271_ops = { .sta_remove = wl1271_op_sta_remove, .ampdu_action = wl1271_op_ampdu_action, .tx_frames_pending = wl1271_tx_frames_pending, .set_bitrate_mask = wl12xx_set_bitrate_mask, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) }; Loading Loading @@ -4585,6 +4722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) int i, j, ret; unsigned int order; BUILD_BUG_ON(AP_MAX_LINKS > WL12XX_MAX_LINKS); hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); if (!hw) { wl1271_error("could not alloc ieee80211_hw"); Loading Loading @@ -4687,6 +4826,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) /* Apply default driver configuration. */ wl1271_conf_init(wl); wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; order = get_order(WL1271_AGGR_BUFFER_SIZE); wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); Loading