wl12xx: implement set_bitrate_mask callback
Save the configured bitrate, and use the min allowed rate as the basic rate (e.g. when scanning). Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
committed by
Luciano Coelho
parent
68eaaf6ee5
commit
af7fbb28ef
@@ -1112,6 +1112,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
|
|||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 rate;
|
||||||
|
|
||||||
skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
|
skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
|
||||||
ie, ie_len);
|
ie, ie_len);
|
||||||
@@ -1122,14 +1123,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
|
|||||||
|
|
||||||
wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
|
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)
|
if (band == IEEE80211_BAND_2GHZ)
|
||||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
|
||||||
skb->data, skb->len, 0,
|
skb->data, skb->len, 0, rate);
|
||||||
wl->conf.tx.basic_rate);
|
|
||||||
else
|
else
|
||||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
|
||||||
skb->data, skb->len, 0,
|
skb->data, skb->len, 0, rate);
|
||||||
wl->conf.tx.basic_rate_5);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
@@ -1140,6 +1140,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
|
|||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 rate;
|
||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
|
skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
|
||||||
@@ -1148,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);
|
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)
|
if (wl->band == IEEE80211_BAND_2GHZ)
|
||||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
|
||||||
skb->data, skb->len, 0,
|
skb->data, skb->len, 0, rate);
|
||||||
wl->conf.tx.basic_rate);
|
|
||||||
else
|
else
|
||||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
|
||||||
skb->data, skb->len, 0,
|
skb->data, skb->len, 0, rate);
|
||||||
wl->conf.tx.basic_rate_5);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
wl1271_error("Unable to set ap probe request template.");
|
wl1271_error("Unable to set ap probe request template.");
|
||||||
@@ -1448,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;
|
sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET;
|
||||||
|
|
||||||
cmd->supported_rates =
|
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",
|
wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
|
||||||
cmd->supported_rates, sta->uapsd_queues);
|
cmd->supported_rates, sta->uapsd_queues);
|
||||||
|
@@ -103,6 +103,7 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
|
|||||||
{
|
{
|
||||||
struct wl12xx_disconn_template *tmpl;
|
struct wl12xx_disconn_template *tmpl;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 rate;
|
||||||
|
|
||||||
tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
|
tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
|
||||||
if (!tmpl) {
|
if (!tmpl) {
|
||||||
@@ -113,9 +114,9 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
|
|||||||
tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||||
IEEE80211_STYPE_DEAUTH);
|
IEEE80211_STYPE_DEAUTH);
|
||||||
|
|
||||||
|
rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
|
||||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
|
||||||
tmpl, sizeof(*tmpl), 0,
|
tmpl, sizeof(*tmpl), 0, rate);
|
||||||
wl1271_tx_min_rate_get(wl));
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(tmpl);
|
kfree(tmpl);
|
||||||
@@ -126,6 +127,7 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl)
|
|||||||
{
|
{
|
||||||
struct ieee80211_hdr_3addr *nullfunc;
|
struct ieee80211_hdr_3addr *nullfunc;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 rate;
|
||||||
|
|
||||||
nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
|
nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
|
||||||
if (!nullfunc) {
|
if (!nullfunc) {
|
||||||
@@ -142,9 +144,9 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl)
|
|||||||
memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
|
memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
|
||||||
memcpy(nullfunc->addr3, 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,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
|
||||||
sizeof(*nullfunc), 0,
|
sizeof(*nullfunc), 0, rate);
|
||||||
wl1271_tx_min_rate_get(wl));
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(nullfunc);
|
kfree(nullfunc);
|
||||||
@@ -155,6 +157,7 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
|
|||||||
{
|
{
|
||||||
struct ieee80211_qos_hdr *qosnull;
|
struct ieee80211_qos_hdr *qosnull;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 rate;
|
||||||
|
|
||||||
qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
|
qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
|
||||||
if (!qosnull) {
|
if (!qosnull) {
|
||||||
@@ -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->addr2, wl->mac_addr, ETH_ALEN);
|
||||||
memcpy(qosnull->addr3, 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,
|
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
|
||||||
sizeof(*qosnull), 0,
|
sizeof(*qosnull), 0, rate);
|
||||||
wl1271_tx_min_rate_get(wl));
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(qosnull);
|
kfree(qosnull);
|
||||||
@@ -498,7 +501,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* use the min basic rate for AP broadcast/multicast */
|
/* 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.short_retry_limit = 10;
|
||||||
rc.long_retry_limit = 10;
|
rc.long_retry_limit = 10;
|
||||||
rc.aflags = 0;
|
rc.aflags = 0;
|
||||||
|
@@ -2099,6 +2099,8 @@ deinit:
|
|||||||
wl->time_offset = 0;
|
wl->time_offset = 0;
|
||||||
wl->session_counter = 0;
|
wl->session_counter = 0;
|
||||||
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
|
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->vif = NULL;
|
||||||
wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
|
wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
|
||||||
wl1271_free_ap_keys(wl);
|
wl1271_free_ap_keys(wl);
|
||||||
@@ -2237,14 +2239,8 @@ out:
|
|||||||
|
|
||||||
static void wl1271_set_band_rate(struct wl1271 *wl)
|
static void wl1271_set_band_rate(struct wl1271 *wl)
|
||||||
{
|
{
|
||||||
if (wl->band == IEEE80211_BAND_2GHZ) {
|
wl->basic_rate_set = wl->bitrate_masks[wl->band];
|
||||||
wl->basic_rate_set = wl->conf.tx.basic_rate;
|
wl->rate_set = wl->basic_rate_set;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wl12xx_is_roc(struct wl1271 *wl)
|
static bool wl12xx_is_roc(struct wl1271 *wl)
|
||||||
@@ -2273,7 +2269,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
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);
|
ret = wl1271_acx_sta_rate_policies(wl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2370,7 +2366,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
|
|||||||
if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
|
if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
|
||||||
wl1271_set_band_rate(wl);
|
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);
|
ret = wl1271_acx_sta_rate_policies(wl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
wl1271_warning("rate policy for channel "
|
wl1271_warning("rate policy for channel "
|
||||||
@@ -3214,6 +3211,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
|||||||
|
|
||||||
if ((changed & BSS_CHANGED_BEACON)) {
|
if ((changed & BSS_CHANGED_BEACON)) {
|
||||||
struct ieee80211_hdr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
|
u32 min_rate;
|
||||||
int ieoffset = offsetof(struct ieee80211_mgmt,
|
int ieoffset = offsetof(struct ieee80211_mgmt,
|
||||||
u.beacon.variable);
|
u.beacon.variable);
|
||||||
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
|
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
|
||||||
@@ -3229,12 +3227,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
|||||||
dev_kfree_skb(beacon);
|
dev_kfree_skb(beacon);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
min_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
|
||||||
tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
|
tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
|
||||||
CMD_TEMPL_BEACON;
|
CMD_TEMPL_BEACON;
|
||||||
ret = wl1271_cmd_template_set(wl, tmpl_id,
|
ret = wl1271_cmd_template_set(wl, tmpl_id,
|
||||||
beacon->data,
|
beacon->data,
|
||||||
beacon->len, 0,
|
beacon->len, 0,
|
||||||
wl1271_tx_min_rate_get(wl));
|
min_rate);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_kfree_skb(beacon);
|
dev_kfree_skb(beacon);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3261,13 +3260,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
|||||||
ret = wl1271_ap_set_probe_resp_tmpl(wl,
|
ret = wl1271_ap_set_probe_resp_tmpl(wl,
|
||||||
beacon->data,
|
beacon->data,
|
||||||
beacon->len,
|
beacon->len,
|
||||||
wl1271_tx_min_rate_get(wl));
|
min_rate);
|
||||||
else
|
else
|
||||||
ret = wl1271_cmd_template_set(wl,
|
ret = wl1271_cmd_template_set(wl,
|
||||||
CMD_TEMPL_PROBE_RESPONSE,
|
CMD_TEMPL_PROBE_RESPONSE,
|
||||||
beacon->data,
|
beacon->data,
|
||||||
beacon->len, 0,
|
beacon->len, 0,
|
||||||
wl1271_tx_min_rate_get(wl));
|
min_rate);
|
||||||
dev_kfree_skb(beacon);
|
dev_kfree_skb(beacon);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3288,8 +3287,10 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
|
|||||||
if ((changed & BSS_CHANGED_BASIC_RATES)) {
|
if ((changed & BSS_CHANGED_BASIC_RATES)) {
|
||||||
u32 rates = bss_conf->basic_rates;
|
u32 rates = bss_conf->basic_rates;
|
||||||
|
|
||||||
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates);
|
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
|
||||||
wl->basic_rate = wl1271_tx_min_rate_get(wl);
|
wl->band);
|
||||||
|
wl->basic_rate = wl1271_tx_min_rate_get(wl,
|
||||||
|
wl->basic_rate_set);
|
||||||
|
|
||||||
ret = wl1271_init_ap_rates(wl);
|
ret = wl1271_init_ap_rates(wl);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -3471,12 +3472,15 @@ sta_not_found:
|
|||||||
* to use with control frames.
|
* to use with control frames.
|
||||||
*/
|
*/
|
||||||
rates = bss_conf->basic_rates;
|
rates = bss_conf->basic_rates;
|
||||||
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
|
wl->basic_rate_set =
|
||||||
rates);
|
wl1271_tx_enabled_rates_get(wl, rates,
|
||||||
wl->basic_rate = wl1271_tx_min_rate_get(wl);
|
wl->band);
|
||||||
|
wl->basic_rate =
|
||||||
|
wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
|
||||||
if (sta_rate_set)
|
if (sta_rate_set)
|
||||||
wl->rate_set = wl1271_tx_enabled_rates_get(wl,
|
wl->rate_set = wl1271_tx_enabled_rates_get(wl,
|
||||||
sta_rate_set);
|
sta_rate_set,
|
||||||
|
wl->band);
|
||||||
ret = wl1271_acx_sta_rate_policies(wl);
|
ret = wl1271_acx_sta_rate_policies(wl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3523,7 +3527,8 @@ sta_not_found:
|
|||||||
|
|
||||||
/* revert back to minimum rates for the current band */
|
/* revert back to minimum rates for the current band */
|
||||||
wl1271_set_band_rate(wl);
|
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);
|
ret = wl1271_acx_sta_rate_policies(wl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3574,9 +3579,11 @@ sta_not_found:
|
|||||||
|
|
||||||
if (bss_conf->ibss_joined) {
|
if (bss_conf->ibss_joined) {
|
||||||
u32 rates = bss_conf->basic_rates;
|
u32 rates = bss_conf->basic_rates;
|
||||||
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
|
wl->basic_rate_set =
|
||||||
rates);
|
wl1271_tx_enabled_rates_get(wl, rates,
|
||||||
wl->basic_rate = wl1271_tx_min_rate_get(wl);
|
wl->band);
|
||||||
|
wl->basic_rate =
|
||||||
|
wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
|
||||||
|
|
||||||
/* by default, use 11b + OFDM rates */
|
/* by default, use 11b + OFDM rates */
|
||||||
wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
|
wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
|
||||||
@@ -4098,6 +4105,29 @@ out:
|
|||||||
return ret;
|
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)
|
static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
struct wl1271 *wl = hw->priv;
|
struct wl1271 *wl = hw->priv;
|
||||||
@@ -4373,6 +4403,7 @@ static const struct ieee80211_ops wl1271_ops = {
|
|||||||
.sta_remove = wl1271_op_sta_remove,
|
.sta_remove = wl1271_op_sta_remove,
|
||||||
.ampdu_action = wl1271_op_ampdu_action,
|
.ampdu_action = wl1271_op_ampdu_action,
|
||||||
.tx_frames_pending = wl1271_tx_frames_pending,
|
.tx_frames_pending = wl1271_tx_frames_pending,
|
||||||
|
.set_bitrate_mask = wl12xx_set_bitrate_mask,
|
||||||
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
|
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4793,6 +4824,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
|
|||||||
|
|
||||||
/* Apply default driver configuration. */
|
/* Apply default driver configuration. */
|
||||||
wl1271_conf_init(wl);
|
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);
|
order = get_order(WL1271_AGGR_BUFFER_SIZE);
|
||||||
wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
|
wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "scan.h"
|
#include "scan.h"
|
||||||
#include "acx.h"
|
#include "acx.h"
|
||||||
#include "ps.h"
|
#include "ps.h"
|
||||||
|
#include "tx.h"
|
||||||
|
|
||||||
void wl1271_scan_complete_work(struct work_struct *work)
|
void wl1271_scan_complete_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
@@ -243,14 +244,17 @@ out:
|
|||||||
void wl1271_scan_stm(struct wl1271 *wl)
|
void wl1271_scan_stm(struct wl1271 *wl)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
enum ieee80211_band band;
|
||||||
|
u32 rate;
|
||||||
|
|
||||||
switch (wl->scan.state) {
|
switch (wl->scan.state) {
|
||||||
case WL1271_SCAN_STATE_IDLE:
|
case WL1271_SCAN_STATE_IDLE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WL1271_SCAN_STATE_2GHZ_ACTIVE:
|
case WL1271_SCAN_STATE_2GHZ_ACTIVE:
|
||||||
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
|
band = IEEE80211_BAND_2GHZ;
|
||||||
wl->conf.tx.basic_rate);
|
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
|
||||||
|
ret = wl1271_scan_send(wl, band, false, rate);
|
||||||
if (ret == WL1271_NOTHING_TO_SCAN) {
|
if (ret == WL1271_NOTHING_TO_SCAN) {
|
||||||
wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
|
wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
|
||||||
wl1271_scan_stm(wl);
|
wl1271_scan_stm(wl);
|
||||||
@@ -259,8 +263,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WL1271_SCAN_STATE_2GHZ_PASSIVE:
|
case WL1271_SCAN_STATE_2GHZ_PASSIVE:
|
||||||
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
|
band = IEEE80211_BAND_2GHZ;
|
||||||
wl->conf.tx.basic_rate);
|
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
|
||||||
|
ret = wl1271_scan_send(wl, band, true, rate);
|
||||||
if (ret == WL1271_NOTHING_TO_SCAN) {
|
if (ret == WL1271_NOTHING_TO_SCAN) {
|
||||||
if (wl->enable_11a)
|
if (wl->enable_11a)
|
||||||
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
|
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
|
||||||
@@ -272,8 +277,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WL1271_SCAN_STATE_5GHZ_ACTIVE:
|
case WL1271_SCAN_STATE_5GHZ_ACTIVE:
|
||||||
ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
|
band = IEEE80211_BAND_5GHZ;
|
||||||
wl->conf.tx.basic_rate_5);
|
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
|
||||||
|
ret = wl1271_scan_send(wl, band, false, rate);
|
||||||
if (ret == WL1271_NOTHING_TO_SCAN) {
|
if (ret == WL1271_NOTHING_TO_SCAN) {
|
||||||
wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
|
wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
|
||||||
wl1271_scan_stm(wl);
|
wl1271_scan_stm(wl);
|
||||||
@@ -282,8 +288,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WL1271_SCAN_STATE_5GHZ_PASSIVE:
|
case WL1271_SCAN_STATE_5GHZ_PASSIVE:
|
||||||
ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
|
band = IEEE80211_BAND_5GHZ;
|
||||||
wl->conf.tx.basic_rate_5);
|
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
|
||||||
|
ret = wl1271_scan_send(wl, band, true, rate);
|
||||||
if (ret == WL1271_NOTHING_TO_SCAN) {
|
if (ret == WL1271_NOTHING_TO_SCAN) {
|
||||||
wl->scan.state = WL1271_SCAN_STATE_DONE;
|
wl->scan.state = WL1271_SCAN_STATE_DONE;
|
||||||
wl1271_scan_stm(wl);
|
wl1271_scan_stm(wl);
|
||||||
|
@@ -450,13 +450,14 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
|
|||||||
return total_len;
|
return total_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
|
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
|
||||||
|
enum ieee80211_band rate_band)
|
||||||
{
|
{
|
||||||
struct ieee80211_supported_band *band;
|
struct ieee80211_supported_band *band;
|
||||||
u32 enabled_rates = 0;
|
u32 enabled_rates = 0;
|
||||||
int bit;
|
int bit;
|
||||||
|
|
||||||
band = wl->hw->wiphy->bands[wl->band];
|
band = wl->hw->wiphy->bands[rate_band];
|
||||||
for (bit = 0; bit < band->n_bitrates; bit++) {
|
for (bit = 0; bit < band->n_bitrates; bit++) {
|
||||||
if (rate_set & 0x1)
|
if (rate_set & 0x1)
|
||||||
enabled_rates |= band->bitrates[bit].hw_value;
|
enabled_rates |= band->bitrates[bit].hw_value;
|
||||||
@@ -989,20 +990,10 @@ void wl1271_tx_flush(struct wl1271 *wl)
|
|||||||
wl1271_warning("Unable to flush all TX buffers, timed out.");
|
wl1271_warning("Unable to flush all TX buffers, timed out.");
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 wl1271_tx_min_rate_get(struct wl1271 *wl)
|
u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
|
||||||
{
|
{
|
||||||
int i;
|
if (WARN_ON(!rate_set))
|
||||||
u32 rate = 0;
|
return 0;
|
||||||
|
|
||||||
if (!wl->basic_rate_set) {
|
return BIT(__ffs(rate_set));
|
||||||
WARN_ON(1);
|
|
||||||
wl->basic_rate_set = wl->conf.tx.basic_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; !rate; i++) {
|
|
||||||
if ((wl->basic_rate_set >> i) & 0x1)
|
|
||||||
rate = 1 << i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rate;
|
|
||||||
}
|
}
|
||||||
|
@@ -209,8 +209,9 @@ void wl1271_tx_complete(struct wl1271 *wl);
|
|||||||
void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
|
void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
|
||||||
void wl1271_tx_flush(struct wl1271 *wl);
|
void wl1271_tx_flush(struct wl1271 *wl);
|
||||||
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
|
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
|
||||||
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
|
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
|
||||||
u32 wl1271_tx_min_rate_get(struct wl1271 *wl);
|
enum ieee80211_band rate_band);
|
||||||
|
u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
|
||||||
u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb);
|
u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb);
|
||||||
void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
|
void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
|
||||||
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
|
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
|
||||||
|
@@ -526,6 +526,7 @@ struct wl1271 {
|
|||||||
u32 basic_rate_set;
|
u32 basic_rate_set;
|
||||||
u32 basic_rate;
|
u32 basic_rate;
|
||||||
u32 rate_set;
|
u32 rate_set;
|
||||||
|
u32 bitrate_masks[IEEE80211_NUM_BANDS];
|
||||||
|
|
||||||
/* The current band */
|
/* The current band */
|
||||||
enum ieee80211_band band;
|
enum ieee80211_band band;
|
||||||
|
Reference in New Issue
Block a user