Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: chromeos/compat-wireless/net/mac80211/status.c

Issue 5326002: Update compat-wireless to 2.6.36-5-spn (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Fixes for !ACK handling, missing local changes, log message fixes Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2002-2005, Instant802 Networks, Inc. 2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
5 * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 * being correct. Clear it so we don't get junk there, and 51 * being correct. Clear it so we don't get junk there, and
52 * indicate that it needs new processing, but must not be 52 * indicate that it needs new processing, but must not be
53 * modified/encrypted again. 53 * modified/encrypted again.
54 */ 54 */
55 memset(&info->control, 0, sizeof(info->control)); 55 memset(&info->control, 0, sizeof(info->control));
56 56
57 info->control.jiffies = jiffies; 57 info->control.jiffies = jiffies;
58 info->control.vif = &sta->sdata->vif; 58 info->control.vif = &sta->sdata->vif;
59 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | 59 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
60 IEEE80211_TX_INTFL_RETRANSMISSION; 60 IEEE80211_TX_INTFL_RETRANSMISSION;
61 info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
61 62
62 sta->tx_filtered_count++; 63 sta->tx_filtered_count++;
63 64
64 /* 65 /*
65 * Clear the TX filter mask for this STA when sending the next 66 * Clear the TX filter mask for this STA when sending the next
66 * packet. If the STA went to power save mode, this will happen 67 * packet. If the STA went to power save mode, this will happen
67 * when it wakes up for the next time. 68 * when it wakes up for the next time.
68 */ 69 */
69 set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); 70 set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT);
70 71
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 if (net_ratelimit()) 117 if (net_ratelimit())
117 printk(KERN_DEBUG "%s: dropped TX filtered frame, " 118 printk(KERN_DEBUG "%s: dropped TX filtered frame, "
118 "queue_len=%d PS=%d @%lu\n", 119 "queue_len=%d PS=%d @%lu\n",
119 wiphy_name(local->hw.wiphy), 120 wiphy_name(local->hw.wiphy),
120 skb_queue_len(&sta->tx_filtered), 121 skb_queue_len(&sta->tx_filtered),
121 !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); 122 !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies);
122 #endif 123 #endif
123 dev_kfree_skb(skb); 124 dev_kfree_skb(skb);
124 } 125 }
125 126
126 static void ieee80211_sta_tx_status(struct sta_info *sta, struct sk_buff *skb) 127 static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
127 { 128 {
128 struct ieee80211_mgmt *mgmt = (void *) skb->data; 129 struct ieee80211_mgmt *mgmt = (void *) skb->data;
129 struct ieee80211_local *local = sta->local; 130 struct ieee80211_local *local = sta->local;
130 struct ieee80211_sub_if_data *sdata = sta->sdata; 131 struct ieee80211_sub_if_data *sdata = sta->sdata;
131 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
132
133 if (sdata->vif.type != NL80211_IFTYPE_STATION)
134 return;
135 132
136 if (ieee80211_is_action(mgmt->frame_control) && 133 if (ieee80211_is_action(mgmt->frame_control) &&
137 » (info->flags & IEEE80211_TX_STAT_ACK) && 134 » sdata->vif.type == NL80211_IFTYPE_STATION &&
138 mgmt->u.action.category == WLAN_CATEGORY_HT && 135 mgmt->u.action.category == WLAN_CATEGORY_HT &&
139 mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) { 136 mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) {
140 /* 137 /*
141 * This update looks racy, but isn't -- if we come 138 * This update looks racy, but isn't -- if we come
142 * here we've definitely got a station that we're 139 * here we've definitely got a station that we're
143 * talking to, and on a managed interface that can 140 * talking to, and on a managed interface that can
144 * only be the AP. And the only other place updating 141 * only be the AP. And the only other place updating
145 * this variable is before we're associated. 142 * this variable is before we're associated.
146 */ 143 */
147 switch (mgmt->u.action.u.ht_smps.smps_control) { 144 switch (mgmt->u.action.u.ht_smps.smps_control) {
148 case WLAN_HT_SMPS_CONTROL_DYNAMIC: 145 case WLAN_HT_SMPS_CONTROL_DYNAMIC:
149 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC; 146 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC;
150 break; 147 break;
151 case WLAN_HT_SMPS_CONTROL_STATIC: 148 case WLAN_HT_SMPS_CONTROL_STATIC:
152 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC; 149 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC;
153 break; 150 break;
154 case WLAN_HT_SMPS_CONTROL_DISABLED: 151 case WLAN_HT_SMPS_CONTROL_DISABLED:
155 default: /* shouldn't happen since we don't send that */ 152 default: /* shouldn't happen since we don't send that */
156 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF; 153 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF;
157 break; 154 break;
158 } 155 }
159 156
160 ieee80211_queue_work(&local->hw, &local->recalc_smps); 157 ieee80211_queue_work(&local->hw, &local->recalc_smps);
161 } else if (ieee80211_is_probe_req(mgmt->frame_control) ||
162 ieee80211_is_nullfunc(mgmt->frame_control)) {
163 struct ieee80211_if_managed *ifmgd = &sta->sdata->u.mgd;
164
165 ifmgd->probe_acked =
166 (info->flags & IEEE80211_TX_STAT_ACK) ? true : false;
167
168 ieee80211_queue_work(&local->hw, &ifmgd->probe_status_work);
169 } else if (ieee80211_is_data(mgmt->frame_control) && 158 } else if (ieee80211_is_data(mgmt->frame_control) &&
170 » » sdata->vif.type == NL80211_IFTYPE_STATION && 159 » » sdata->vif.type == NL80211_IFTYPE_STATION) {
171 » (info->flags & IEEE80211_TX_STAT_ACK)) { 160 » » struct ieee80211_if_managed *ifmgd;
172 » » struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 161 » » ifmgd = &sta->sdata->u.mgd;
173 if (ifmgd->cqm_bitrate_thold != 0 && 162 if (ifmgd->cqm_bitrate_thold != 0 &&
174 (ifmgd->last_cqm_tx_rate.idx != sta->last_tx_rate.idx || 163 (ifmgd->last_cqm_tx_rate.idx != sta->last_tx_rate.idx ||
175 (ifmgd->last_cqm_tx_rate.flags & 164 (ifmgd->last_cqm_tx_rate.flags &
176 (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_40_MHZ_WIDTH | 165 (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_40_MHZ_WIDTH |
177 IEEE80211_TX_RC_SHORT_GI)) != 166 IEEE80211_TX_RC_SHORT_GI)) !=
178 (sta->last_tx_rate.flags & 167 (sta->last_tx_rate.flags &
179 (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_40_MHZ_WIDTH | 168 (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_40_MHZ_WIDTH |
180 IEEE80211_TX_RC_SHORT_GI)) || 169 IEEE80211_TX_RC_SHORT_GI)) ||
181 sdata->u.mgd.last_cqm_bitrate == 0)) { 170 sdata->u.mgd.last_cqm_bitrate == 0)) {
182 ifmgd->last_cqm_tx_rate = sta->last_tx_rate; 171 ifmgd->last_cqm_tx_rate = sta->last_tx_rate;
(...skipping 13 matching lines...) Expand all
196 u16 frag, type; 185 u16 frag, type;
197 __le16 fc; 186 __le16 fc;
198 struct ieee80211_supported_band *sband; 187 struct ieee80211_supported_band *sband;
199 struct ieee80211_tx_status_rtap_hdr *rthdr; 188 struct ieee80211_tx_status_rtap_hdr *rthdr;
200 struct ieee80211_sub_if_data *sdata; 189 struct ieee80211_sub_if_data *sdata;
201 struct net_device *prev_dev = NULL; 190 struct net_device *prev_dev = NULL;
202 struct sta_info *sta, *tmp; 191 struct sta_info *sta, *tmp;
203 int retry_count = -1, i; 192 int retry_count = -1, i;
204 int rates_idx = -1; 193 int rates_idx = -1;
205 bool send_to_cooked; 194 bool send_to_cooked;
195 bool acked;
206 196
207 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 197 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
208 /* the HW cannot have attempted that rate */ 198 /* the HW cannot have attempted that rate */
209 if (i >= hw->max_rates) { 199 if (i >= hw->max_rates) {
210 info->status.rates[i].idx = -1; 200 info->status.rates[i].idx = -1;
211 info->status.rates[i].count = 0; 201 info->status.rates[i].count = 0;
212 } else if (info->status.rates[i].idx >= 0) { 202 } else if (info->status.rates[i].idx >= 0) {
213 rates_idx = i; 203 rates_idx = i;
214 } 204 }
215 205
216 retry_count += info->status.rates[i].count; 206 retry_count += info->status.rates[i].count;
217 } 207 }
218 if (retry_count < 0) 208 if (retry_count < 0)
219 retry_count = 0; 209 retry_count = 0;
220 210
221 rcu_read_lock(); 211 rcu_read_lock();
222 212
223 sband = local->hw.wiphy->bands[info->band]; 213 sband = local->hw.wiphy->bands[info->band];
224 fc = hdr->frame_control; 214 fc = hdr->frame_control;
225 215
226 for_each_sta_info(local, hdr->addr1, sta, tmp) { 216 for_each_sta_info(local, hdr->addr1, sta, tmp) {
227 /* skip wrong virtual interface */ 217 /* skip wrong virtual interface */
228 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) 218 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
229 continue; 219 continue;
230 220
231 » » if (!(info->flags & IEEE80211_TX_STAT_ACK) && 221 » » acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
232 » » test_sta_flags(sta, WLAN_STA_PS_STA)) { 222 » » if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
233 /* 223 /*
234 * The STA is in power save mode, so assume 224 * The STA is in power save mode, so assume
235 * that this TX packet failed because of that. 225 * that this TX packet failed because of that.
236 */ 226 */
237 ieee80211_handle_filtered_frame(local, sta, skb); 227 ieee80211_handle_filtered_frame(local, sta, skb);
238 rcu_read_unlock(); 228 rcu_read_unlock();
239 return; 229 return;
240 } 230 }
241 231
242 if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && 232 if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
(...skipping 11 matching lines...) Expand all
254 & IEEE80211_SCTL_SEQ); 244 & IEEE80211_SCTL_SEQ);
255 ieee80211_send_bar(sta->sdata, hdr->addr1, 245 ieee80211_send_bar(sta->sdata, hdr->addr1,
256 tid, ssn); 246 tid, ssn);
257 } 247 }
258 248
259 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { 249 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
260 ieee80211_handle_filtered_frame(local, sta, skb); 250 ieee80211_handle_filtered_frame(local, sta, skb);
261 rcu_read_unlock(); 251 rcu_read_unlock();
262 return; 252 return;
263 } else { 253 } else {
264 » » » if (!(info->flags & IEEE80211_TX_STAT_ACK)) 254 » » » if (!acked)
265 sta->tx_retry_failed++; 255 sta->tx_retry_failed++;
266 sta->tx_retry_count += retry_count; 256 sta->tx_retry_count += retry_count;
267 } 257 }
268 258
269 rate_control_tx_status(local, sband, sta, skb); 259 rate_control_tx_status(local, sband, sta, skb);
270 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 260 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
271 ieee80211s_update_metric(local, sta, skb); 261 ieee80211s_update_metric(local, sta, skb);
272 262
273 » » if (!(info->flags & IEEE80211_TX_CTL_INJECTED)) 263 » » if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
274 » » » ieee80211_sta_tx_status(sta, skb); 264 » » » ieee80211_frame_acked(sta, skb);
265
266 » » if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
267 » » (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
268 » » » ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked);
275 } 269 }
276 270
277 rcu_read_unlock(); 271 rcu_read_unlock();
278 272
279 ieee80211_led_tx(local, 0); 273 ieee80211_led_tx(local, 0);
280 274
281 /* SNMP counters 275 /* SNMP counters
282 * Fragments are passed to low-level drivers as separate skbs, so these 276 * Fragments are passed to low-level drivers as separate skbs, so these
283 * are actually fragments, not frames. Update frame counters only for 277 * are actually fragments, not frames. Update frame counters only for
284 * the first fragment of the frame. */ 278 * the first fragment of the frame. */
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 continue; 393 continue;
400 394
401 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 395 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
402 !send_to_cooked) 396 !send_to_cooked)
403 continue; 397 continue;
404 398
405 if (prev_dev) { 399 if (prev_dev) {
406 skb2 = skb_clone(skb, GFP_ATOMIC); 400 skb2 = skb_clone(skb, GFP_ATOMIC);
407 if (skb2) { 401 if (skb2) {
408 skb2->dev = prev_dev; 402 skb2->dev = prev_dev;
409 » » » » » netif_receive_skb(skb2); 403 » » » » » netif_rx(skb2);
410 } 404 }
411 } 405 }
412 406
413 prev_dev = sdata->dev; 407 prev_dev = sdata->dev;
414 } 408 }
415 } 409 }
416 if (prev_dev) { 410 if (prev_dev) {
417 skb->dev = prev_dev; 411 skb->dev = prev_dev;
418 » » netif_receive_skb(skb); 412 » » netif_rx(skb);
419 skb = NULL; 413 skb = NULL;
420 } 414 }
421 rcu_read_unlock(); 415 rcu_read_unlock();
422 dev_kfree_skb(skb); 416 dev_kfree_skb(skb);
423 } 417 }
424 EXPORT_SYMBOL(ieee80211_tx_status); 418 EXPORT_SYMBOL(ieee80211_tx_status);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698