diff options
author | Levi, Shahar <shahar_levi@ti.com> | 2011-01-23 01:27:23 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-01-24 15:58:47 -0500 |
commit | bbba3e6832ad3e974fb593a98abe03f8b60fc7f3 (patch) | |
tree | 06a9d4d0a1e1d4838ad4d919ef0abe2e8780f671 /drivers/net/wireless/wl12xx | |
parent | 4b7fac77b4c1badac84df3dcbdf07199d94cb1c3 (diff) |
wl12xx: BA receiver support
Add new ampdu_action ops to support receiver BA.
The BA initiator session management in FW independently.
Signed-off-by: Shahar Levi <shahar_levi@ti.com>
Reviewed-by: Luciano Coelho <coelho@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.h | 25 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 60 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 1 |
5 files changed, 117 insertions, 4 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 0b9cacc74903..afdc601aa7ea 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -1393,6 +1393,40 @@ out: | |||
1393 | return ret; | 1393 | return ret; |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | /* setup BA session receiver setting in the FW. */ | ||
1397 | int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, | ||
1398 | bool enable) | ||
1399 | { | ||
1400 | struct wl1271_acx_ba_receiver_setup *acx; | ||
1401 | int ret; | ||
1402 | |||
1403 | wl1271_debug(DEBUG_ACX, "acx ba receiver session setting"); | ||
1404 | |||
1405 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1406 | if (!acx) { | ||
1407 | ret = -ENOMEM; | ||
1408 | goto out; | ||
1409 | } | ||
1410 | |||
1411 | /* Single link for now */ | ||
1412 | acx->link_id = 1; | ||
1413 | acx->tid = tid_index; | ||
1414 | acx->enable = enable; | ||
1415 | acx->win_size = 0; | ||
1416 | acx->ssn = ssn; | ||
1417 | |||
1418 | ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx, | ||
1419 | sizeof(*acx)); | ||
1420 | if (ret < 0) { | ||
1421 | wl1271_warning("acx ba receiver session failed: %d", ret); | ||
1422 | goto out; | ||
1423 | } | ||
1424 | |||
1425 | out: | ||
1426 | kfree(acx); | ||
1427 | return ret; | ||
1428 | } | ||
1429 | |||
1396 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) | 1430 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) |
1397 | { | 1431 | { |
1398 | struct wl1271_acx_fw_tsf_information *tsf_info; | 1432 | struct wl1271_acx_fw_tsf_information *tsf_info; |
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index f643e60a566b..4bbaf04f434e 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h | |||
@@ -1095,6 +1095,25 @@ struct wl1271_acx_ba_session_policy { | |||
1095 | u8 padding[3]; | 1095 | u8 padding[3]; |
1096 | } __packed; | 1096 | } __packed; |
1097 | 1097 | ||
1098 | struct wl1271_acx_ba_receiver_setup { | ||
1099 | struct acx_header header; | ||
1100 | |||
1101 | /* Specifies Link Id, Range 0-31, 0xFF means ANY Link Id */ | ||
1102 | u8 link_id; | ||
1103 | |||
1104 | u8 tid; | ||
1105 | |||
1106 | u8 enable; | ||
1107 | |||
1108 | u8 padding[1]; | ||
1109 | |||
1110 | /* Windows size in number of packets */ | ||
1111 | u16 win_size; | ||
1112 | |||
1113 | /* BA session starting sequence number. RANGE 0-FFF */ | ||
1114 | u16 ssn; | ||
1115 | } __packed; | ||
1116 | |||
1098 | struct wl1271_acx_fw_tsf_information { | 1117 | struct wl1271_acx_fw_tsf_information { |
1099 | struct acx_header header; | 1118 | struct acx_header header; |
1100 | 1119 | ||
@@ -1244,8 +1263,10 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, | |||
1244 | int wl1271_acx_set_ht_information(struct wl1271 *wl, | 1263 | int wl1271_acx_set_ht_information(struct wl1271 *wl, |
1245 | u16 ht_operation_mode); | 1264 | u16 ht_operation_mode); |
1246 | int wl1271_acx_set_ba_session(struct wl1271 *wl, | 1265 | int wl1271_acx_set_ba_session(struct wl1271 *wl, |
1247 | enum ieee80211_back_parties direction, | 1266 | enum ieee80211_back_parties direction, |
1248 | u8 tid_index, u8 policy); | 1267 | u8 tid_index, u8 policy); |
1268 | int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, | ||
1269 | bool enable); | ||
1249 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); | 1270 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); |
1250 | int wl1271_acx_max_tx_retry(struct wl1271 *wl); | 1271 | int wl1271_acx_max_tx_retry(struct wl1271 *wl); |
1251 | 1272 | ||
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 2348eadc0de1..70b3dc88a219 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c | |||
@@ -473,7 +473,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl) | |||
473 | u8 ret = 0; | 473 | u8 ret = 0; |
474 | 474 | ||
475 | /* Reset the BA RX indicators */ | 475 | /* Reset the BA RX indicators */ |
476 | wl->ba_allowed = true; | ||
477 | wl->ba_rx_bitmap = 0; | 476 | wl->ba_rx_bitmap = 0; |
478 | 477 | ||
479 | /* validate that FW support BA */ | 478 | /* validate that FW support BA */ |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 01ca666b6c2d..eda2f3d8edf1 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -2724,6 +2724,65 @@ out: | |||
2724 | return ret; | 2724 | return ret; |
2725 | } | 2725 | } |
2726 | 2726 | ||
2727 | int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
2728 | enum ieee80211_ampdu_mlme_action action, | ||
2729 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | ||
2730 | { | ||
2731 | struct wl1271 *wl = hw->priv; | ||
2732 | int ret; | ||
2733 | |||
2734 | mutex_lock(&wl->mutex); | ||
2735 | |||
2736 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | ||
2737 | ret = -EAGAIN; | ||
2738 | goto out; | ||
2739 | } | ||
2740 | |||
2741 | ret = wl1271_ps_elp_wakeup(wl, false); | ||
2742 | if (ret < 0) | ||
2743 | goto out; | ||
2744 | |||
2745 | switch (action) { | ||
2746 | case IEEE80211_AMPDU_RX_START: | ||
2747 | if (wl->ba_support) { | ||
2748 | ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn, | ||
2749 | true); | ||
2750 | if (!ret) | ||
2751 | wl->ba_rx_bitmap |= BIT(tid); | ||
2752 | } else { | ||
2753 | ret = -ENOTSUPP; | ||
2754 | } | ||
2755 | break; | ||
2756 | |||
2757 | case IEEE80211_AMPDU_RX_STOP: | ||
2758 | ret = wl1271_acx_set_ba_receiver_session(wl, tid, 0, false); | ||
2759 | if (!ret) | ||
2760 | wl->ba_rx_bitmap &= ~BIT(tid); | ||
2761 | break; | ||
2762 | |||
2763 | /* | ||
2764 | * The BA initiator session management in FW independently. | ||
2765 | * Falling break here on purpose for all TX APDU commands. | ||
2766 | */ | ||
2767 | case IEEE80211_AMPDU_TX_START: | ||
2768 | case IEEE80211_AMPDU_TX_STOP: | ||
2769 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2770 | ret = -EINVAL; | ||
2771 | break; | ||
2772 | |||
2773 | default: | ||
2774 | wl1271_error("Incorrect ampdu action id=%x\n", action); | ||
2775 | ret = -EINVAL; | ||
2776 | } | ||
2777 | |||
2778 | wl1271_ps_elp_sleep(wl); | ||
2779 | |||
2780 | out: | ||
2781 | mutex_unlock(&wl->mutex); | ||
2782 | |||
2783 | return ret; | ||
2784 | } | ||
2785 | |||
2727 | /* can't be const, mac80211 writes to this */ | 2786 | /* can't be const, mac80211 writes to this */ |
2728 | static struct ieee80211_rate wl1271_rates[] = { | 2787 | static struct ieee80211_rate wl1271_rates[] = { |
2729 | { .bitrate = 10, | 2788 | { .bitrate = 10, |
@@ -2973,6 +3032,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
2973 | .get_survey = wl1271_op_get_survey, | 3032 | .get_survey = wl1271_op_get_survey, |
2974 | .sta_add = wl1271_op_sta_add, | 3033 | .sta_add = wl1271_op_sta_add, |
2975 | .sta_remove = wl1271_op_sta_remove, | 3034 | .sta_remove = wl1271_op_sta_remove, |
3035 | .ampdu_action = wl1271_op_ampdu_action, | ||
2976 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 3036 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
2977 | }; | 3037 | }; |
2978 | 3038 | ||
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index e0bac79cd516..d1de13fe7d9a 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -473,7 +473,6 @@ struct wl1271 { | |||
473 | 473 | ||
474 | /* RX BA constraint value */ | 474 | /* RX BA constraint value */ |
475 | bool ba_support; | 475 | bool ba_support; |
476 | u8 ba_allowed; | ||
477 | u8 ba_rx_bitmap; | 476 | u8 ba_rx_bitmap; |
478 | }; | 477 | }; |
479 | 478 | ||