Skip to content

Commit

Permalink
wl12xx: implement set_bitrate_mask callback
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eliad Peller authored and Luciano Coelho committed Sep 23, 2011
1 parent 68eaaf6 commit af7fbb2
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 65 deletions.
19 changes: 10 additions & 9 deletions drivers/net/wireless/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1112,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);
Expand All @@ -1122,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);
Expand All @@ -1140,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);
Expand All @@ -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);

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.");
Expand Down Expand Up @@ -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;

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);
Expand Down
17 changes: 10 additions & 7 deletions drivers/net/wireless/wl12xx/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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) {
Expand All @@ -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);
Expand All @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
79 changes: 56 additions & 23 deletions drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2099,6 +2099,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
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);
Expand Down Expand Up @@ -2237,14 +2239,8 @@ static int wl1271_unjoin(struct wl1271 *wl)

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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2370,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 "
Expand Down Expand Up @@ -3214,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);
Expand All @@ -3229,12 +3227,13 @@ 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;
Expand All @@ -3261,13 +3260,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
ret = wl1271_ap_set_probe_resp_tmpl(wl,
beacon->data,
beacon->len,
wl1271_tx_min_rate_get(wl));
min_rate);
else
ret = wl1271_cmd_template_set(wl,
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;
Expand All @@ -3288,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) {
Expand Down Expand Up @@ -3471,12 +3472,15 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
* 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;
Expand Down Expand Up @@ -3523,7 +3527,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,

/* 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;
Expand Down Expand Up @@ -3574,9 +3579,11 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,

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 + OFDM rates */
wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
Expand Down Expand Up @@ -4098,6 +4105,29 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
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;
Expand Down Expand Up @@ -4373,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)
};

Expand Down Expand Up @@ -4793,6 +4824,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);
Expand Down
23 changes: 15 additions & 8 deletions drivers/net/wireless/wl12xx/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "scan.h"
#include "acx.h"
#include "ps.h"
#include "tx.h"

void wl1271_scan_complete_work(struct work_struct *work)
{
Expand Down Expand Up @@ -243,14 +244,17 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
void wl1271_scan_stm(struct wl1271 *wl)
{
int ret = 0;
enum ieee80211_band band;
u32 rate;

switch (wl->scan.state) {
case WL1271_SCAN_STATE_IDLE:
break;

case WL1271_SCAN_STATE_2GHZ_ACTIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
wl->conf.tx.basic_rate);
band = IEEE80211_BAND_2GHZ;
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) {
wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
wl1271_scan_stm(wl);
Expand All @@ -259,8 +263,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;

case WL1271_SCAN_STATE_2GHZ_PASSIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
wl->conf.tx.basic_rate);
band = IEEE80211_BAND_2GHZ;
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 (wl->enable_11a)
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
Expand All @@ -272,8 +277,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;

case WL1271_SCAN_STATE_5GHZ_ACTIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
wl->conf.tx.basic_rate_5);
band = IEEE80211_BAND_5GHZ;
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) {
wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
wl1271_scan_stm(wl);
Expand All @@ -282,8 +288,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;

case WL1271_SCAN_STATE_5GHZ_PASSIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
wl->conf.tx.basic_rate_5);
band = IEEE80211_BAND_5GHZ;
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) {
wl->scan.state = WL1271_SCAN_STATE_DONE;
wl1271_scan_stm(wl);
Expand Down
Loading

0 comments on commit af7fbb2

Please sign in to comment.