diff options
author | Kalle Valo <kalle.valo@nokia.com> | 2009-11-30 03:18:27 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-21 18:55:57 -0500 |
commit | 27336f1c0cd68fb9ae45493321f0d6980144230e (patch) | |
tree | bbbf451f951c26f543ebeb0e10d076892bb6bee8 | |
parent | 86dff7a7955f1e14c1f2c142312462fae70ea7e4 (diff) |
wl1251: implement wl1251_acx_tid_cfg()
Needed for WMM.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Reviewed-by: Janne Ylalehto <janne.ylalehto@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_acx.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_acx.h | 55 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_main.c | 11 |
3 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c index b409c75499dd..beff084040b5 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ b/drivers/net/wireless/wl12xx/wl1251_acx.c | |||
@@ -1009,3 +1009,39 @@ out: | |||
1009 | kfree(acx); | 1009 | kfree(acx); |
1010 | return ret; | 1010 | return ret; |
1011 | } | 1011 | } |
1012 | |||
1013 | int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, | ||
1014 | enum wl1251_acx_channel_type type, | ||
1015 | u8 tsid, enum wl1251_acx_ps_scheme ps_scheme, | ||
1016 | enum wl1251_acx_ack_policy ack_policy) | ||
1017 | { | ||
1018 | struct wl1251_acx_tid_cfg *acx; | ||
1019 | int ret = 0; | ||
1020 | |||
1021 | wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d " | ||
1022 | "ps_scheme %d ack_policy %d", queue, type, tsid, | ||
1023 | ps_scheme, ack_policy); | ||
1024 | |||
1025 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1026 | |||
1027 | if (!acx) { | ||
1028 | ret = -ENOMEM; | ||
1029 | goto out; | ||
1030 | } | ||
1031 | |||
1032 | acx->queue = queue; | ||
1033 | acx->type = type; | ||
1034 | acx->tsid = tsid; | ||
1035 | acx->ps_scheme = ps_scheme; | ||
1036 | acx->ack_policy = ack_policy; | ||
1037 | |||
1038 | ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); | ||
1039 | if (ret < 0) { | ||
1040 | wl1251_warning("acx tid cfg failed: %d", ret); | ||
1041 | goto out; | ||
1042 | } | ||
1043 | |||
1044 | out: | ||
1045 | kfree(acx); | ||
1046 | return ret; | ||
1047 | } | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index 56793245b287..26160c45784c 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h | |||
@@ -1196,6 +1196,57 @@ struct wl1251_acx_ac_cfg { | |||
1196 | u16 txop_limit; | 1196 | u16 txop_limit; |
1197 | } __attribute__ ((packed)); | 1197 | } __attribute__ ((packed)); |
1198 | 1198 | ||
1199 | |||
1200 | enum wl1251_acx_channel_type { | ||
1201 | CHANNEL_TYPE_DCF = 0, | ||
1202 | CHANNEL_TYPE_EDCF = 1, | ||
1203 | CHANNEL_TYPE_HCCA = 2, | ||
1204 | }; | ||
1205 | |||
1206 | enum wl1251_acx_ps_scheme { | ||
1207 | /* regular ps: simple sending of packets */ | ||
1208 | WL1251_ACX_PS_SCHEME_LEGACY = 0, | ||
1209 | |||
1210 | /* sending a packet triggers a unscheduled apsd downstream */ | ||
1211 | WL1251_ACX_PS_SCHEME_UPSD_TRIGGER = 1, | ||
1212 | |||
1213 | /* a pspoll packet will be sent before every data packet */ | ||
1214 | WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL = 2, | ||
1215 | |||
1216 | /* scheduled apsd mode */ | ||
1217 | WL1251_ACX_PS_SCHEME_SAPSD = 3, | ||
1218 | }; | ||
1219 | |||
1220 | enum wl1251_acx_ack_policy { | ||
1221 | WL1251_ACX_ACK_POLICY_LEGACY = 0, | ||
1222 | WL1251_ACX_ACK_POLICY_NO_ACK = 1, | ||
1223 | WL1251_ACX_ACK_POLICY_BLOCK = 2, | ||
1224 | }; | ||
1225 | |||
1226 | struct wl1251_acx_tid_cfg { | ||
1227 | struct acx_header header; | ||
1228 | |||
1229 | /* tx queue id number (0-7) */ | ||
1230 | u8 queue; | ||
1231 | |||
1232 | /* channel access type for the queue, enum wl1251_acx_channel_type */ | ||
1233 | u8 type; | ||
1234 | |||
1235 | /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */ | ||
1236 | u8 tsid; | ||
1237 | |||
1238 | /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */ | ||
1239 | u8 ps_scheme; | ||
1240 | |||
1241 | /* the tx queue ack policy, enum wl1251_acx_ack_policy */ | ||
1242 | u8 ack_policy; | ||
1243 | |||
1244 | u8 padding[3]; | ||
1245 | |||
1246 | /* not supported */ | ||
1247 | u32 apsdconf[2]; | ||
1248 | } __attribute__ ((packed)); | ||
1249 | |||
1199 | /************************************************************************* | 1250 | /************************************************************************* |
1200 | 1251 | ||
1201 | Host Interrupt Register (WiLink -> Host) | 1252 | Host Interrupt Register (WiLink -> Host) |
@@ -1354,5 +1405,9 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl); | |||
1354 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); | 1405 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); |
1355 | int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, | 1406 | int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, |
1356 | u8 aifs, u16 txop); | 1407 | u8 aifs, u16 txop); |
1408 | int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, | ||
1409 | enum wl1251_acx_channel_type type, | ||
1410 | u8 tsid, enum wl1251_acx_ps_scheme ps_scheme, | ||
1411 | enum wl1251_acx_ack_policy ack_policy); | ||
1357 | 1412 | ||
1358 | #endif /* __WL1251_ACX_H__ */ | 1413 | #endif /* __WL1251_ACX_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index c1c7cb5aea2b..74770ada37de 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -1302,7 +1302,18 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1302 | ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue), | 1302 | ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue), |
1303 | params->cw_min, params->cw_max, | 1303 | params->cw_min, params->cw_max, |
1304 | params->aifs, params->txop); | 1304 | params->aifs, params->txop); |
1305 | if (ret < 0) | ||
1306 | goto out_sleep; | ||
1307 | |||
1308 | ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue), | ||
1309 | CHANNEL_TYPE_DCF, | ||
1310 | wl1251_tx_get_queue(queue), | ||
1311 | WL1251_ACX_PS_SCHEME_LEGACY, | ||
1312 | WL1251_ACX_ACK_POLICY_LEGACY); | ||
1313 | if (ret < 0) | ||
1314 | goto out_sleep; | ||
1305 | 1315 | ||
1316 | out_sleep: | ||
1306 | wl1251_ps_elp_sleep(wl); | 1317 | wl1251_ps_elp_sleep(wl); |
1307 | 1318 | ||
1308 | out: | 1319 | out: |