diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/init.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/main.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/txrx.c | 106 |
6 files changed, 88 insertions, 45 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 8bf447a6a84e..fed7b8077f5e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -2871,6 +2871,11 @@ struct ath6kl *ath6kl_cfg80211_create(void) | |||
2871 | /* Note: ar variable must not be accessed after calling this! */ | 2871 | /* Note: ar variable must not be accessed after calling this! */ |
2872 | void ath6kl_cfg80211_destroy(struct ath6kl *ar) | 2872 | void ath6kl_cfg80211_destroy(struct ath6kl *ar) |
2873 | { | 2873 | { |
2874 | int i; | ||
2875 | |||
2876 | for (i = 0; i < AP_MAX_NUM_STA; i++) | ||
2877 | kfree(ar->sta_list[i].aggr_conn); | ||
2878 | |||
2874 | wiphy_free(ar->wiphy); | 2879 | wiphy_free(ar->wiphy); |
2875 | } | 2880 | } |
2876 | 2881 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index d764afec395b..0d92e7179f8a 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c | |||
@@ -253,6 +253,13 @@ struct ath6kl *ath6kl_core_create(struct device *dev) | |||
253 | spin_lock_init(&ar->sta_list[ctr].psq_lock); | 253 | spin_lock_init(&ar->sta_list[ctr].psq_lock); |
254 | skb_queue_head_init(&ar->sta_list[ctr].psq); | 254 | skb_queue_head_init(&ar->sta_list[ctr].psq); |
255 | skb_queue_head_init(&ar->sta_list[ctr].apsdq); | 255 | skb_queue_head_init(&ar->sta_list[ctr].apsdq); |
256 | ar->sta_list[ctr].aggr_conn = | ||
257 | kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); | ||
258 | if (!ar->sta_list[ctr].aggr_conn) { | ||
259 | ath6kl_err("Failed to allocate memory for sta aggregation information\n"); | ||
260 | ath6kl_core_destroy(ar); | ||
261 | return NULL; | ||
262 | } | ||
256 | } | 263 | } |
257 | 264 | ||
258 | skb_queue_head_init(&ar->mcastpsq); | 265 | skb_queue_head_init(&ar->mcastpsq); |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 1b9054f8f4e4..ed9fcc11b5fc 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -298,6 +298,7 @@ struct ath6kl_sta { | |||
298 | spinlock_t psq_lock; | 298 | spinlock_t psq_lock; |
299 | u8 apsd_info; | 299 | u8 apsd_info; |
300 | struct sk_buff_head apsdq; | 300 | struct sk_buff_head apsdq; |
301 | struct aggr_info_conn *aggr_conn; | ||
301 | }; | 302 | }; |
302 | 303 | ||
303 | struct ath6kl_version { | 304 | struct ath6kl_version { |
@@ -713,6 +714,7 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); | |||
713 | int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); | 714 | int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); |
714 | 715 | ||
715 | struct aggr_info *aggr_init(struct ath6kl_vif *vif); | 716 | struct aggr_info *aggr_init(struct ath6kl_vif *vif); |
717 | void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn); | ||
716 | void ath6kl_rx_refill(struct htc_target *target, | 718 | void ath6kl_rx_refill(struct htc_target *target, |
717 | enum htc_endpoint_id endpoint); | 719 | enum htc_endpoint_id endpoint); |
718 | void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); | 720 | void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); |
@@ -720,7 +722,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target, | |||
720 | enum htc_endpoint_id endpoint, | 722 | enum htc_endpoint_id endpoint, |
721 | int len); | 723 | int len); |
722 | void aggr_module_destroy(struct aggr_info *aggr_info); | 724 | void aggr_module_destroy(struct aggr_info *aggr_info); |
723 | void aggr_reset_state(struct aggr_info *aggr_info); | 725 | void aggr_reset_state(struct aggr_info_conn *aggr_conn); |
724 | 726 | ||
725 | struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); | 727 | struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); |
726 | struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); | 728 | struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 167dc41af2de..4d8eb1cca6e9 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -1660,6 +1660,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) | |||
1660 | void ath6kl_stop_txrx(struct ath6kl *ar) | 1660 | void ath6kl_stop_txrx(struct ath6kl *ar) |
1661 | { | 1661 | { |
1662 | struct ath6kl_vif *vif, *tmp_vif; | 1662 | struct ath6kl_vif *vif, *tmp_vif; |
1663 | int i; | ||
1663 | 1664 | ||
1664 | set_bit(DESTROY_IN_PROGRESS, &ar->flag); | 1665 | set_bit(DESTROY_IN_PROGRESS, &ar->flag); |
1665 | 1666 | ||
@@ -1668,6 +1669,9 @@ void ath6kl_stop_txrx(struct ath6kl *ar) | |||
1668 | return; | 1669 | return; |
1669 | } | 1670 | } |
1670 | 1671 | ||
1672 | for (i = 0; i < AP_MAX_NUM_STA; i++) | ||
1673 | aggr_reset_state(ar->sta_list[i].aggr_conn); | ||
1674 | |||
1671 | spin_lock_bh(&ar->list_lock); | 1675 | spin_lock_bh(&ar->list_lock); |
1672 | list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { | 1676 | list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { |
1673 | list_del(&vif->list); | 1677 | list_del(&vif->list); |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index acb4acb71718..39da1f98da87 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -74,6 +74,7 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, | |||
74 | 74 | ||
75 | ar->sta_list_index = ar->sta_list_index | (1 << free_slot); | 75 | ar->sta_list_index = ar->sta_list_index | (1 << free_slot); |
76 | ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); | 76 | ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); |
77 | aggr_conn_init(vif, sta->aggr_conn); | ||
77 | } | 78 | } |
78 | 79 | ||
79 | static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) | 80 | static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) |
@@ -94,7 +95,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) | |||
94 | sta->sta_flags = 0; | 95 | sta->sta_flags = 0; |
95 | 96 | ||
96 | ar->sta_list_index = ar->sta_list_index & ~(1 << i); | 97 | ar->sta_list_index = ar->sta_list_index & ~(1 << i); |
97 | 98 | aggr_reset_state(sta->aggr_conn); | |
98 | } | 99 | } |
99 | 100 | ||
100 | static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason) | 101 | static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason) |
@@ -602,7 +603,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, | |||
602 | netif_carrier_on(vif->ndev); | 603 | netif_carrier_on(vif->ndev); |
603 | spin_unlock_bh(&vif->if_lock); | 604 | spin_unlock_bh(&vif->if_lock); |
604 | 605 | ||
605 | aggr_reset_state(vif->aggr_cntxt); | 606 | aggr_reset_state(vif->aggr_cntxt->aggr_conn); |
606 | vif->reconnect_flag = 0; | 607 | vif->reconnect_flag = 0; |
607 | 608 | ||
608 | if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { | 609 | if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { |
@@ -924,7 +925,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, | |||
924 | assoc_resp_len, assoc_info, | 925 | assoc_resp_len, assoc_info, |
925 | prot_reason_status); | 926 | prot_reason_status); |
926 | 927 | ||
927 | aggr_reset_state(vif->aggr_cntxt); | 928 | aggr_reset_state(vif->aggr_cntxt->aggr_conn); |
928 | 929 | ||
929 | del_timer(&vif->disconnect_timer); | 930 | del_timer(&vif->disconnect_timer); |
930 | 931 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 8cf7b2fa0f41..62c12102e146 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -22,12 +22,18 @@ | |||
22 | * aid - tid_mux4..tid_mux7 | 22 | * aid - tid_mux4..tid_mux7 |
23 | */ | 23 | */ |
24 | #define ATH6KL_TID_MASK 0xf | 24 | #define ATH6KL_TID_MASK 0xf |
25 | #define ATH6KL_AID_SHIFT 4 | ||
25 | 26 | ||
26 | static inline u8 ath6kl_get_tid(u8 tid_mux) | 27 | static inline u8 ath6kl_get_tid(u8 tid_mux) |
27 | { | 28 | { |
28 | return tid_mux & ATH6KL_TID_MASK; | 29 | return tid_mux & ATH6KL_TID_MASK; |
29 | } | 30 | } |
30 | 31 | ||
32 | static inline u8 ath6kl_get_aid(u8 tid_mux) | ||
33 | { | ||
34 | return tid_mux >> ATH6KL_AID_SHIFT; | ||
35 | } | ||
36 | |||
31 | static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, | 37 | static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, |
32 | u32 *map_no) | 38 | u32 *map_no) |
33 | { | 39 | { |
@@ -1003,7 +1009,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr, | |||
1003 | dev_kfree_skb(skb); | 1009 | dev_kfree_skb(skb); |
1004 | } | 1010 | } |
1005 | 1011 | ||
1006 | static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, | 1012 | static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, |
1007 | u16 seq_no, u8 order) | 1013 | u16 seq_no, u8 order) |
1008 | { | 1014 | { |
1009 | struct sk_buff *skb; | 1015 | struct sk_buff *skb; |
@@ -1011,12 +1017,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, | |||
1011 | struct skb_hold_q *node; | 1017 | struct skb_hold_q *node; |
1012 | u16 idx, idx_end, seq_end; | 1018 | u16 idx, idx_end, seq_end; |
1013 | struct rxtid_stats *stats; | 1019 | struct rxtid_stats *stats; |
1014 | struct aggr_info_conn *agg_conn; | ||
1015 | 1020 | ||
1016 | if (!p_aggr || !p_aggr->aggr_conn) | ||
1017 | return; | ||
1018 | |||
1019 | agg_conn = p_aggr->aggr_conn; | ||
1020 | rxtid = &agg_conn->rx_tid[tid]; | 1021 | rxtid = &agg_conn->rx_tid[tid]; |
1021 | stats = &agg_conn->stat[tid]; | 1022 | stats = &agg_conn->stat[tid]; |
1022 | 1023 | ||
@@ -1047,7 +1048,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, | |||
1047 | 1048 | ||
1048 | if (node->skb) { | 1049 | if (node->skb) { |
1049 | if (node->is_amsdu) | 1050 | if (node->is_amsdu) |
1050 | aggr_slice_amsdu(p_aggr, rxtid, node->skb); | 1051 | aggr_slice_amsdu(agg_conn->aggr_info, rxtid, |
1052 | node->skb); | ||
1051 | else | 1053 | else |
1052 | skb_queue_tail(&rxtid->q, node->skb); | 1054 | skb_queue_tail(&rxtid->q, node->skb); |
1053 | node->skb = NULL; | 1055 | node->skb = NULL; |
@@ -1066,7 +1068,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, | |||
1066 | ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); | 1068 | ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); |
1067 | } | 1069 | } |
1068 | 1070 | ||
1069 | static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, | 1071 | static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, |
1070 | u16 seq_no, | 1072 | u16 seq_no, |
1071 | bool is_amsdu, struct sk_buff *frame) | 1073 | bool is_amsdu, struct sk_buff *frame) |
1072 | { | 1074 | { |
@@ -1077,7 +1079,6 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, | |||
1077 | u16 idx, st, cur, end; | 1079 | u16 idx, st, cur, end; |
1078 | bool is_queued = false; | 1080 | bool is_queued = false; |
1079 | u16 extended_end; | 1081 | u16 extended_end; |
1080 | struct aggr_info_conn *agg_conn = agg_info->aggr_conn; | ||
1081 | 1082 | ||
1082 | rxtid = &agg_conn->rx_tid[tid]; | 1083 | rxtid = &agg_conn->rx_tid[tid]; |
1083 | stats = &agg_conn->stat[tid]; | 1084 | stats = &agg_conn->stat[tid]; |
@@ -1086,7 +1087,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, | |||
1086 | 1087 | ||
1087 | if (!rxtid->aggr) { | 1088 | if (!rxtid->aggr) { |
1088 | if (is_amsdu) { | 1089 | if (is_amsdu) { |
1089 | aggr_slice_amsdu(agg_info, rxtid, frame); | 1090 | aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame); |
1090 | is_queued = true; | 1091 | is_queued = true; |
1091 | stats->num_amsdu++; | 1092 | stats->num_amsdu++; |
1092 | while ((skb = skb_dequeue(&rxtid->q))) | 1093 | while ((skb = skb_dequeue(&rxtid->q))) |
@@ -1110,7 +1111,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, | |||
1110 | (cur < end || cur > extended_end)) || | 1111 | (cur < end || cur > extended_end)) || |
1111 | ((end > extended_end) && (cur > extended_end) && | 1112 | ((end > extended_end) && (cur > extended_end) && |
1112 | (cur < end))) { | 1113 | (cur < end))) { |
1113 | aggr_deque_frms(agg_info, tid, 0, 0); | 1114 | aggr_deque_frms(agg_conn, tid, 0, 0); |
1114 | if (cur >= rxtid->hold_q_sz - 1) | 1115 | if (cur >= rxtid->hold_q_sz - 1) |
1115 | rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); | 1116 | rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); |
1116 | else | 1117 | else |
@@ -1127,7 +1128,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, | |||
1127 | st = ATH6KL_MAX_SEQ_NO - | 1128 | st = ATH6KL_MAX_SEQ_NO - |
1128 | (rxtid->hold_q_sz - 2 - cur); | 1129 | (rxtid->hold_q_sz - 2 - cur); |
1129 | 1130 | ||
1130 | aggr_deque_frms(agg_info, tid, st, 0); | 1131 | aggr_deque_frms(agg_conn, tid, st, 0); |
1131 | } | 1132 | } |
1132 | 1133 | ||
1133 | stats->num_oow++; | 1134 | stats->num_oow++; |
@@ -1166,7 +1167,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, | |||
1166 | 1167 | ||
1167 | spin_unlock_bh(&rxtid->lock); | 1168 | spin_unlock_bh(&rxtid->lock); |
1168 | 1169 | ||
1169 | aggr_deque_frms(agg_info, tid, 0, 1); | 1170 | aggr_deque_frms(agg_conn, tid, 0, 1); |
1170 | 1171 | ||
1171 | if (agg_conn->timer_scheduled) | 1172 | if (agg_conn->timer_scheduled) |
1172 | rxtid->progress = true; | 1173 | rxtid->progress = true; |
@@ -1278,6 +1279,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1278 | struct sk_buff *skb1 = NULL; | 1279 | struct sk_buff *skb1 = NULL; |
1279 | struct ethhdr *datap = NULL; | 1280 | struct ethhdr *datap = NULL; |
1280 | struct ath6kl_vif *vif; | 1281 | struct ath6kl_vif *vif; |
1282 | struct aggr_info_conn *aggr_conn; | ||
1281 | u16 seq_no, offset; | 1283 | u16 seq_no, offset; |
1282 | u8 tid, if_idx; | 1284 | u8 tid, if_idx; |
1283 | 1285 | ||
@@ -1529,11 +1531,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1529 | 1531 | ||
1530 | datap = (struct ethhdr *) skb->data; | 1532 | datap = (struct ethhdr *) skb->data; |
1531 | 1533 | ||
1532 | if (is_unicast_ether_addr(datap->h_dest) && | 1534 | if (is_unicast_ether_addr(datap->h_dest)) { |
1533 | aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no, | 1535 | if (vif->nw_type == AP_NETWORK) { |
1534 | is_amsdu, skb)) | 1536 | conn = ath6kl_find_sta(vif, datap->h_source); |
1535 | /* aggregation code will handle the skb */ | 1537 | if (!conn) |
1536 | return; | 1538 | return; |
1539 | aggr_conn = conn->aggr_conn; | ||
1540 | } else | ||
1541 | aggr_conn = vif->aggr_cntxt->aggr_conn; | ||
1542 | |||
1543 | if (aggr_process_recv_frm(aggr_conn, tid, seq_no, | ||
1544 | is_amsdu, skb)) { | ||
1545 | /* aggregation code will handle the skb */ | ||
1546 | return; | ||
1547 | } | ||
1548 | } | ||
1537 | 1549 | ||
1538 | ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); | 1550 | ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); |
1539 | } | 1551 | } |
@@ -1558,7 +1570,7 @@ static void aggr_timeout(unsigned long arg) | |||
1558 | rxtid->seq_next, | 1570 | rxtid->seq_next, |
1559 | ((rxtid->seq_next + rxtid->hold_q_sz-1) & | 1571 | ((rxtid->seq_next + rxtid->hold_q_sz-1) & |
1560 | ATH6KL_MAX_SEQ_NO)); | 1572 | ATH6KL_MAX_SEQ_NO)); |
1561 | aggr_deque_frms(aggr_conn->aggr_info, i, 0, 0); | 1573 | aggr_deque_frms(aggr_conn, i, 0, 0); |
1562 | } | 1574 | } |
1563 | 1575 | ||
1564 | aggr_conn->timer_scheduled = false; | 1576 | aggr_conn->timer_scheduled = false; |
@@ -1598,7 +1610,7 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) | |||
1598 | stats = &aggr_conn->stat[tid]; | 1610 | stats = &aggr_conn->stat[tid]; |
1599 | 1611 | ||
1600 | if (rxtid->aggr) | 1612 | if (rxtid->aggr) |
1601 | aggr_deque_frms(aggr_conn->aggr_info, tid, 0, 0); | 1613 | aggr_deque_frms(aggr_conn, tid, 0, 0); |
1602 | 1614 | ||
1603 | rxtid->aggr = false; | 1615 | rxtid->aggr = false; |
1604 | rxtid->progress = false; | 1616 | rxtid->progress = false; |
@@ -1616,17 +1628,23 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) | |||
1616 | void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, | 1628 | void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, |
1617 | u8 win_sz) | 1629 | u8 win_sz) |
1618 | { | 1630 | { |
1619 | struct aggr_info *p_aggr = vif->aggr_cntxt; | 1631 | struct ath6kl_sta *sta; |
1620 | struct aggr_info_conn *aggr_conn; | 1632 | struct aggr_info_conn *aggr_conn = NULL; |
1621 | struct rxtid *rxtid; | 1633 | struct rxtid *rxtid; |
1622 | struct rxtid_stats *stats; | 1634 | struct rxtid_stats *stats; |
1623 | u16 hold_q_size; | 1635 | u16 hold_q_size; |
1624 | u8 tid; | 1636 | u8 tid, aid; |
1625 | 1637 | ||
1626 | if (!p_aggr || !p_aggr->aggr_conn) | 1638 | if (vif->nw_type == AP_NETWORK) { |
1627 | return; | 1639 | aid = ath6kl_get_aid(tid_mux); |
1640 | sta = ath6kl_find_sta_by_aid(vif->ar, aid); | ||
1641 | if (sta) | ||
1642 | aggr_conn = sta->aggr_conn; | ||
1643 | } else | ||
1644 | aggr_conn = vif->aggr_cntxt->aggr_conn; | ||
1628 | 1645 | ||
1629 | aggr_conn = p_aggr->aggr_conn; | 1646 | if (!aggr_conn) |
1647 | return; | ||
1630 | 1648 | ||
1631 | tid = ath6kl_get_tid(tid_mux); | 1649 | tid = ath6kl_get_tid(tid_mux); |
1632 | if (tid >= NUM_OF_TIDS) | 1650 | if (tid >= NUM_OF_TIDS) |
@@ -1656,8 +1674,7 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, | |||
1656 | rxtid->aggr = true; | 1674 | rxtid->aggr = true; |
1657 | } | 1675 | } |
1658 | 1676 | ||
1659 | static void aggr_conn_init(struct ath6kl_vif *vif, | 1677 | void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) |
1660 | struct aggr_info_conn *aggr_conn) | ||
1661 | { | 1678 | { |
1662 | struct rxtid *rxtid; | 1679 | struct rxtid *rxtid; |
1663 | u8 i; | 1680 | u8 i; |
@@ -1709,39 +1726,46 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) | |||
1709 | 1726 | ||
1710 | void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) | 1727 | void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) |
1711 | { | 1728 | { |
1712 | struct aggr_info *p_aggr = vif->aggr_cntxt; | 1729 | struct ath6kl_sta *sta; |
1713 | struct rxtid *rxtid; | 1730 | struct rxtid *rxtid; |
1714 | struct aggr_info_conn *aggr_conn; | 1731 | struct aggr_info_conn *aggr_conn = NULL; |
1715 | u8 tid; | 1732 | u8 tid, aid; |
1733 | |||
1734 | if (vif->nw_type == AP_NETWORK) { | ||
1735 | aid = ath6kl_get_aid(tid_mux); | ||
1736 | sta = ath6kl_find_sta_by_aid(vif->ar, aid); | ||
1737 | if (sta) | ||
1738 | aggr_conn = sta->aggr_conn; | ||
1739 | } else | ||
1740 | aggr_conn = vif->aggr_cntxt->aggr_conn; | ||
1716 | 1741 | ||
1717 | if (!p_aggr || !p_aggr->aggr_conn) | 1742 | if (!aggr_conn) |
1718 | return; | 1743 | return; |
1719 | 1744 | ||
1720 | tid = ath6kl_get_tid(tid_mux); | 1745 | tid = ath6kl_get_tid(tid_mux); |
1721 | if (tid >= NUM_OF_TIDS) | 1746 | if (tid >= NUM_OF_TIDS) |
1722 | return; | 1747 | return; |
1723 | 1748 | ||
1724 | aggr_conn = p_aggr->aggr_conn; | ||
1725 | rxtid = &aggr_conn->rx_tid[tid]; | 1749 | rxtid = &aggr_conn->rx_tid[tid]; |
1726 | 1750 | ||
1727 | if (rxtid->aggr) | 1751 | if (rxtid->aggr) |
1728 | aggr_delete_tid_state(aggr_conn, tid); | 1752 | aggr_delete_tid_state(aggr_conn, tid); |
1729 | } | 1753 | } |
1730 | 1754 | ||
1731 | void aggr_reset_state(struct aggr_info *aggr_info) | 1755 | void aggr_reset_state(struct aggr_info_conn *aggr_conn) |
1732 | { | 1756 | { |
1733 | u8 tid; | 1757 | u8 tid; |
1734 | 1758 | ||
1735 | if (!aggr_info || !aggr_info->aggr_conn) | 1759 | if (!aggr_conn) |
1736 | return; | 1760 | return; |
1737 | 1761 | ||
1738 | if (aggr_info->aggr_conn->timer_scheduled) { | 1762 | if (aggr_conn->timer_scheduled) { |
1739 | del_timer(&aggr_info->aggr_conn->timer); | 1763 | del_timer(&aggr_conn->timer); |
1740 | aggr_info->aggr_conn->timer_scheduled = false; | 1764 | aggr_conn->timer_scheduled = false; |
1741 | } | 1765 | } |
1742 | 1766 | ||
1743 | for (tid = 0; tid < NUM_OF_TIDS; tid++) | 1767 | for (tid = 0; tid < NUM_OF_TIDS; tid++) |
1744 | aggr_delete_tid_state(aggr_info->aggr_conn, tid); | 1768 | aggr_delete_tid_state(aggr_conn, tid); |
1745 | } | 1769 | } |
1746 | 1770 | ||
1747 | /* clean up our amsdu buffer list */ | 1771 | /* clean up our amsdu buffer list */ |
@@ -1768,10 +1792,10 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar) | |||
1768 | 1792 | ||
1769 | void aggr_module_destroy(struct aggr_info *aggr_info) | 1793 | void aggr_module_destroy(struct aggr_info *aggr_info) |
1770 | { | 1794 | { |
1771 | if (!aggr_info || !aggr_info->aggr_conn) | 1795 | if (!aggr_info) |
1772 | return; | 1796 | return; |
1773 | 1797 | ||
1774 | aggr_reset_state(aggr_info); | 1798 | aggr_reset_state(aggr_info->aggr_conn); |
1775 | skb_queue_purge(&aggr_info->rx_amsdu_freeq); | 1799 | skb_queue_purge(&aggr_info->rx_amsdu_freeq); |
1776 | kfree(aggr_info->aggr_conn); | 1800 | kfree(aggr_info->aggr_conn); |
1777 | kfree(aggr_info); | 1801 | kfree(aggr_info); |