wlcore: pass wmm configuration to the fw

New fields were added to start_role(ap) and
set_peer_state commands, so the fw will be
able to know whether the sta/ap supports
wmm (the fw uses it in order to choose the
AC for some of its internally-generated frames)

For sta, take this value right from bss_conf->qos.

For ap, check for wmm support by looking for the
WMM IE in the configured beacon.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
Eliad Peller 2012-11-22 18:06:20 +02:00 committed by Luciano Coelho
parent c50a282515
commit d50529c0d8
4 changed files with 35 additions and 6 deletions

View File

@ -570,6 +570,7 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
/* FIXME: Change when adding DFS */ /* FIXME: Change when adding DFS */
cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ cmd->ap.reset_tsf = 1; /* By default reset AP TSF */
cmd->ap.wmm = wlvif->wmm_enabled;
cmd->channel = wlvif->channel; cmd->channel = wlvif->channel;
cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type);
@ -1363,7 +1364,8 @@ out:
return ret; return ret;
} }
int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid) int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 hlid)
{ {
struct wl12xx_cmd_set_peer_state *cmd; struct wl12xx_cmd_set_peer_state *cmd;
int ret = 0; int ret = 0;
@ -1379,6 +1381,10 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
cmd->hlid = hlid; cmd->hlid = hlid;
cmd->state = WL1271_CMD_STA_STATE_CONNECTED; cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
/* wmm param is valid only for station role */
if (wlvif->bss_type == BSS_TYPE_STA_BSS)
cmd->wmm = wlvif->wmm_enabled;
ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0); ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
if (ret < 0) { if (ret < 0) {
wl1271_error("failed to send set peer state command"); wl1271_error("failed to send set peer state command");

View File

@ -76,7 +76,8 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u16 action, u8 id, u8 key_type, u16 action, u8 id, u8 key_type,
u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
u16 tx_seq_16); u16 tx_seq_16);
int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid); int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 hlid);
int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id, int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id,
enum ieee80211_band band, u8 channel); enum ieee80211_band band, u8 channel);
int wl12xx_croc(struct wl1271 *wl, u8 role_id); int wl12xx_croc(struct wl1271 *wl, u8 role_id);
@ -355,7 +356,13 @@ struct wl12xx_cmd_role_start {
u8 reset_tsf; u8 reset_tsf;
u8 padding_1[4]; /*
* ap supports wmm (note that there is additional
* per-sta wmm configuration)
*/
u8 wmm;
u8 padding_1[3];
} __packed ap; } __packed ap;
}; };
} __packed; } __packed;
@ -525,7 +532,14 @@ struct wl12xx_cmd_set_peer_state {
u8 hlid; u8 hlid;
u8 state; u8 state;
u8 padding[2];
/*
* wmm is relevant for sta role only.
* ap role configures the per-sta wmm params in
* the add_peer command.
*/
u8 wmm;
u8 padding[1];
} __packed; } __packed;
struct wl12xx_cmd_roc { struct wl12xx_cmd_roc {

View File

@ -79,7 +79,7 @@ static int wl12xx_set_authorized(struct wl1271 *wl,
if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
return 0; return 0;
ret = wl12xx_cmd_set_peer_state(wl, wlvif->sta.hlid); ret = wl12xx_cmd_set_peer_state(wl, wlvif, wlvif->sta.hlid);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -2630,6 +2630,7 @@ static int wlcore_set_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
wlvif->aid = bss_conf->aid; wlvif->aid = bss_conf->aid;
wlvif->channel_type = bss_conf->channel_type; wlvif->channel_type = bss_conf->channel_type;
wlvif->beacon_int = bss_conf->beacon_int; wlvif->beacon_int = bss_conf->beacon_int;
wlvif->wmm_enabled = bss_conf->qos;
set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags); set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
@ -3692,6 +3693,12 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
goto out; goto out;
} }
wlvif->wmm_enabled =
cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WMM,
beacon->data + ieoffset,
beacon->len - ieoffset);
/* /*
* In case we already have a probe-resp beacon set explicitly * In case we already have a probe-resp beacon set explicitly
* by usermode, don't use the beacon data. * by usermode, don't use the beacon data.
@ -4478,7 +4485,7 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
/* Authorize station (AP mode) */ /* Authorize station (AP mode) */
if (is_ap && if (is_ap &&
new_state == IEEE80211_STA_AUTHORIZED) { new_state == IEEE80211_STA_AUTHORIZED) {
ret = wl12xx_cmd_set_peer_state(wl, hlid); ret = wl12xx_cmd_set_peer_state(wl, wlvif, hlid);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -416,6 +416,8 @@ struct wl12xx_vif {
bool ba_support; bool ba_support;
bool ba_allowed; bool ba_allowed;
bool wmm_enabled;
/* Rx Streaming */ /* Rx Streaming */
struct work_struct rx_streaming_enable_work; struct work_struct rx_streaming_enable_work;
struct work_struct rx_streaming_disable_work; struct work_struct rx_streaming_disable_work;