diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:11 -0400 |
commit | e039fa4a4195ac4ee895e6f3d1334beed63256fe (patch) | |
tree | cfd0762d73df96b73052378be7b157c4ac6e7035 /net/mac80211/main.c | |
parent | e24549485f859be6518929bb1c9c0257d79f033d (diff) |
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit
information and status in skb->cb rather than allocating extra
memory for it and copying all the data around. To make it fit,
a union is used where only data that is necessary for all steps
is kept outside of the union.
A number of fixes were done by Ivo, as well as the rt2x00 part
of this patch.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 128 |
1 files changed, 40 insertions, 88 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9761d9bd5a79..8f1ff7ef1667 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -971,8 +971,7 @@ void ieee80211_if_setup(struct net_device *dev) | |||
971 | /* everything else */ | 971 | /* everything else */ |
972 | 972 | ||
973 | static int __ieee80211_if_config(struct net_device *dev, | 973 | static int __ieee80211_if_config(struct net_device *dev, |
974 | struct sk_buff *beacon, | 974 | struct sk_buff *beacon) |
975 | struct ieee80211_tx_control *control) | ||
976 | { | 975 | { |
977 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 976 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
978 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 977 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -990,13 +989,11 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
990 | conf.ssid_len = sdata->u.sta.ssid_len; | 989 | conf.ssid_len = sdata->u.sta.ssid_len; |
991 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 990 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
992 | conf.beacon = beacon; | 991 | conf.beacon = beacon; |
993 | conf.beacon_control = control; | ||
994 | ieee80211_start_mesh(dev); | 992 | ieee80211_start_mesh(dev); |
995 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 993 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
996 | conf.ssid = sdata->u.ap.ssid; | 994 | conf.ssid = sdata->u.ap.ssid; |
997 | conf.ssid_len = sdata->u.ap.ssid_len; | 995 | conf.ssid_len = sdata->u.ap.ssid_len; |
998 | conf.beacon = beacon; | 996 | conf.beacon = beacon; |
999 | conf.beacon_control = control; | ||
1000 | } | 997 | } |
1001 | return local->ops->config_interface(local_to_hw(local), | 998 | return local->ops->config_interface(local_to_hw(local), |
1002 | &sdata->vif, &conf); | 999 | &sdata->vif, &conf); |
@@ -1009,23 +1006,21 @@ int ieee80211_if_config(struct net_device *dev) | |||
1009 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | 1006 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && |
1010 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1007 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
1011 | return ieee80211_if_config_beacon(dev); | 1008 | return ieee80211_if_config_beacon(dev); |
1012 | return __ieee80211_if_config(dev, NULL, NULL); | 1009 | return __ieee80211_if_config(dev, NULL); |
1013 | } | 1010 | } |
1014 | 1011 | ||
1015 | int ieee80211_if_config_beacon(struct net_device *dev) | 1012 | int ieee80211_if_config_beacon(struct net_device *dev) |
1016 | { | 1013 | { |
1017 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1014 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1018 | struct ieee80211_tx_control control; | ||
1019 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1015 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1020 | struct sk_buff *skb; | 1016 | struct sk_buff *skb; |
1021 | 1017 | ||
1022 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1018 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
1023 | return 0; | 1019 | return 0; |
1024 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, | 1020 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif); |
1025 | &control); | ||
1026 | if (!skb) | 1021 | if (!skb) |
1027 | return -ENOMEM; | 1022 | return -ENOMEM; |
1028 | return __ieee80211_if_config(dev, skb, &control); | 1023 | return __ieee80211_if_config(dev, skb); |
1029 | } | 1024 | } |
1030 | 1025 | ||
1031 | int ieee80211_hw_config(struct ieee80211_local *local) | 1026 | int ieee80211_hw_config(struct ieee80211_local *local) |
@@ -1180,38 +1175,20 @@ void ieee80211_reset_erp_info(struct net_device *dev) | |||
1180 | } | 1175 | } |
1181 | 1176 | ||
1182 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 1177 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
1183 | struct sk_buff *skb, | 1178 | struct sk_buff *skb) |
1184 | struct ieee80211_tx_status *status) | ||
1185 | { | 1179 | { |
1186 | struct ieee80211_local *local = hw_to_local(hw); | 1180 | struct ieee80211_local *local = hw_to_local(hw); |
1187 | struct ieee80211_tx_status *saved; | 1181 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1188 | int tmp; | 1182 | int tmp; |
1189 | 1183 | ||
1190 | skb->dev = local->mdev; | 1184 | skb->dev = local->mdev; |
1191 | saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC); | ||
1192 | if (unlikely(!saved)) { | ||
1193 | if (net_ratelimit()) | ||
1194 | printk(KERN_WARNING "%s: Not enough memory, " | ||
1195 | "dropping tx status", skb->dev->name); | ||
1196 | /* should be dev_kfree_skb_irq, but due to this function being | ||
1197 | * named _irqsafe instead of just _irq we can't be sure that | ||
1198 | * people won't call it from non-irq contexts */ | ||
1199 | dev_kfree_skb_any(skb); | ||
1200 | return; | ||
1201 | } | ||
1202 | memcpy(saved, status, sizeof(struct ieee80211_tx_status)); | ||
1203 | /* copy pointer to saved status into skb->cb for use by tasklet */ | ||
1204 | memcpy(skb->cb, &saved, sizeof(saved)); | ||
1205 | |||
1206 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | 1185 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; |
1207 | skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ? | 1186 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? |
1208 | &local->skb_queue : &local->skb_queue_unreliable, skb); | 1187 | &local->skb_queue : &local->skb_queue_unreliable, skb); |
1209 | tmp = skb_queue_len(&local->skb_queue) + | 1188 | tmp = skb_queue_len(&local->skb_queue) + |
1210 | skb_queue_len(&local->skb_queue_unreliable); | 1189 | skb_queue_len(&local->skb_queue_unreliable); |
1211 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | 1190 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
1212 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1191 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
1213 | memcpy(&saved, skb->cb, sizeof(saved)); | ||
1214 | kfree(saved); | ||
1215 | dev_kfree_skb_irq(skb); | 1192 | dev_kfree_skb_irq(skb); |
1216 | tmp--; | 1193 | tmp--; |
1217 | I802_DEBUG_INC(local->tx_status_drop); | 1194 | I802_DEBUG_INC(local->tx_status_drop); |
@@ -1225,7 +1202,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1225 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 1202 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
1226 | struct sk_buff *skb; | 1203 | struct sk_buff *skb; |
1227 | struct ieee80211_rx_status rx_status; | 1204 | struct ieee80211_rx_status rx_status; |
1228 | struct ieee80211_tx_status *tx_status; | ||
1229 | struct ieee80211_ra_tid *ra_tid; | 1205 | struct ieee80211_ra_tid *ra_tid; |
1230 | 1206 | ||
1231 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1207 | while ((skb = skb_dequeue(&local->skb_queue)) || |
@@ -1240,12 +1216,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1240 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); | 1216 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); |
1241 | break; | 1217 | break; |
1242 | case IEEE80211_TX_STATUS_MSG: | 1218 | case IEEE80211_TX_STATUS_MSG: |
1243 | /* get pointer to saved status out of skb->cb */ | ||
1244 | memcpy(&tx_status, skb->cb, sizeof(tx_status)); | ||
1245 | skb->pkt_type = 0; | 1219 | skb->pkt_type = 0; |
1246 | ieee80211_tx_status(local_to_hw(local), | 1220 | ieee80211_tx_status(local_to_hw(local), skb); |
1247 | skb, tx_status); | ||
1248 | kfree(tx_status); | ||
1249 | break; | 1221 | break; |
1250 | case IEEE80211_DELBA_MSG: | 1222 | case IEEE80211_DELBA_MSG: |
1251 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 1223 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -1274,24 +1246,15 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1274 | * Also, tx_packet_data in cb is restored from tx_control. */ | 1246 | * Also, tx_packet_data in cb is restored from tx_control. */ |
1275 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1247 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1276 | struct ieee80211_key *key, | 1248 | struct ieee80211_key *key, |
1277 | struct sk_buff *skb, | 1249 | struct sk_buff *skb) |
1278 | struct ieee80211_tx_control *control) | ||
1279 | { | 1250 | { |
1280 | int hdrlen, iv_len, mic_len; | 1251 | int hdrlen, iv_len, mic_len; |
1281 | struct ieee80211_tx_packet_data *pkt_data; | 1252 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1282 | 1253 | ||
1283 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1254 | info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | |
1284 | pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; | 1255 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT | |
1285 | pkt_data->flags = 0; | 1256 | IEEE80211_TX_CTL_REQUEUE | |
1286 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 1257 | IEEE80211_TX_CTL_EAPOL_FRAME; |
1287 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1288 | if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT) | ||
1289 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | ||
1290 | if (control->flags & IEEE80211_TXCTL_REQUEUE) | ||
1291 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | ||
1292 | if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) | ||
1293 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | ||
1294 | pkt_data->queue = control->queue; | ||
1295 | 1258 | ||
1296 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1259 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1297 | 1260 | ||
@@ -1338,9 +1301,10 @@ no_key: | |||
1338 | 1301 | ||
1339 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 1302 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
1340 | struct sta_info *sta, | 1303 | struct sta_info *sta, |
1341 | struct sk_buff *skb, | 1304 | struct sk_buff *skb) |
1342 | struct ieee80211_tx_status *status) | ||
1343 | { | 1305 | { |
1306 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1307 | |||
1344 | sta->tx_filtered_count++; | 1308 | sta->tx_filtered_count++; |
1345 | 1309 | ||
1346 | /* | 1310 | /* |
@@ -1382,18 +1346,16 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1382 | */ | 1346 | */ |
1383 | if (test_sta_flags(sta, WLAN_STA_PS) && | 1347 | if (test_sta_flags(sta, WLAN_STA_PS) && |
1384 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1348 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
1385 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1349 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1386 | &status->control); | ||
1387 | skb_queue_tail(&sta->tx_filtered, skb); | 1350 | skb_queue_tail(&sta->tx_filtered, skb); |
1388 | return; | 1351 | return; |
1389 | } | 1352 | } |
1390 | 1353 | ||
1391 | if (!test_sta_flags(sta, WLAN_STA_PS) && | 1354 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
1392 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1355 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { |
1393 | /* Software retry the packet once */ | 1356 | /* Software retry the packet once */ |
1394 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1357 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
1395 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1358 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1396 | &status->control); | ||
1397 | dev_queue_xmit(skb); | 1359 | dev_queue_xmit(skb); |
1398 | return; | 1360 | return; |
1399 | } | 1361 | } |
@@ -1407,28 +1369,20 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1407 | dev_kfree_skb(skb); | 1369 | dev_kfree_skb(skb); |
1408 | } | 1370 | } |
1409 | 1371 | ||
1410 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1372 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
1411 | struct ieee80211_tx_status *status) | ||
1412 | { | 1373 | { |
1413 | struct sk_buff *skb2; | 1374 | struct sk_buff *skb2; |
1414 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1375 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1415 | struct ieee80211_local *local = hw_to_local(hw); | 1376 | struct ieee80211_local *local = hw_to_local(hw); |
1377 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1416 | u16 frag, type; | 1378 | u16 frag, type; |
1417 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1379 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
1418 | struct ieee80211_sub_if_data *sdata; | 1380 | struct ieee80211_sub_if_data *sdata; |
1419 | struct net_device *prev_dev = NULL; | 1381 | struct net_device *prev_dev = NULL; |
1420 | 1382 | ||
1421 | if (!status) { | ||
1422 | printk(KERN_ERR | ||
1423 | "%s: ieee80211_tx_status called with NULL status\n", | ||
1424 | wiphy_name(local->hw.wiphy)); | ||
1425 | dev_kfree_skb(skb); | ||
1426 | return; | ||
1427 | } | ||
1428 | |||
1429 | rcu_read_lock(); | 1383 | rcu_read_lock(); |
1430 | 1384 | ||
1431 | if (status->excessive_retries) { | 1385 | if (info->status.excessive_retries) { |
1432 | struct sta_info *sta; | 1386 | struct sta_info *sta; |
1433 | sta = sta_info_get(local, hdr->addr1); | 1387 | sta = sta_info_get(local, hdr->addr1); |
1434 | if (sta) { | 1388 | if (sta) { |
@@ -1437,27 +1391,23 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1437 | * The STA is in power save mode, so assume | 1391 | * The STA is in power save mode, so assume |
1438 | * that this TX packet failed because of that. | 1392 | * that this TX packet failed because of that. |
1439 | */ | 1393 | */ |
1440 | status->excessive_retries = 0; | 1394 | ieee80211_handle_filtered_frame(local, sta, skb); |
1441 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | ||
1442 | ieee80211_handle_filtered_frame(local, sta, | ||
1443 | skb, status); | ||
1444 | rcu_read_unlock(); | 1395 | rcu_read_unlock(); |
1445 | return; | 1396 | return; |
1446 | } | 1397 | } |
1447 | } | 1398 | } |
1448 | } | 1399 | } |
1449 | 1400 | ||
1450 | if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) { | 1401 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
1451 | struct sta_info *sta; | 1402 | struct sta_info *sta; |
1452 | sta = sta_info_get(local, hdr->addr1); | 1403 | sta = sta_info_get(local, hdr->addr1); |
1453 | if (sta) { | 1404 | if (sta) { |
1454 | ieee80211_handle_filtered_frame(local, sta, skb, | 1405 | ieee80211_handle_filtered_frame(local, sta, skb); |
1455 | status); | ||
1456 | rcu_read_unlock(); | 1406 | rcu_read_unlock(); |
1457 | return; | 1407 | return; |
1458 | } | 1408 | } |
1459 | } else | 1409 | } else |
1460 | rate_control_tx_status(local->mdev, skb, status); | 1410 | rate_control_tx_status(local->mdev, skb); |
1461 | 1411 | ||
1462 | rcu_read_unlock(); | 1412 | rcu_read_unlock(); |
1463 | 1413 | ||
@@ -1471,14 +1421,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1471 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 1421 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
1472 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | 1422 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; |
1473 | 1423 | ||
1474 | if (status->flags & IEEE80211_TX_STATUS_ACK) { | 1424 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
1475 | if (frag == 0) { | 1425 | if (frag == 0) { |
1476 | local->dot11TransmittedFrameCount++; | 1426 | local->dot11TransmittedFrameCount++; |
1477 | if (is_multicast_ether_addr(hdr->addr1)) | 1427 | if (is_multicast_ether_addr(hdr->addr1)) |
1478 | local->dot11MulticastTransmittedFrameCount++; | 1428 | local->dot11MulticastTransmittedFrameCount++; |
1479 | if (status->retry_count > 0) | 1429 | if (info->status.retry_count > 0) |
1480 | local->dot11RetryCount++; | 1430 | local->dot11RetryCount++; |
1481 | if (status->retry_count > 1) | 1431 | if (info->status.retry_count > 1) |
1482 | local->dot11MultipleRetryCount++; | 1432 | local->dot11MultipleRetryCount++; |
1483 | } | 1433 | } |
1484 | 1434 | ||
@@ -1524,17 +1474,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1524 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 1474 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
1525 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 1475 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); |
1526 | 1476 | ||
1527 | if (!(status->flags & IEEE80211_TX_STATUS_ACK) && | 1477 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
1528 | !is_multicast_ether_addr(hdr->addr1)) | 1478 | !is_multicast_ether_addr(hdr->addr1)) |
1529 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 1479 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
1530 | 1480 | ||
1531 | if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && | 1481 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && |
1532 | (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) | 1482 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) |
1533 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 1483 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
1534 | else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1484 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1535 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 1485 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
1536 | 1486 | ||
1537 | rthdr->data_retries = status->retry_count; | 1487 | rthdr->data_retries = info->status.retry_count; |
1538 | 1488 | ||
1539 | /* XXX: is this sufficient for BPF? */ | 1489 | /* XXX: is this sufficient for BPF? */ |
1540 | skb_set_mac_header(skb, 0); | 1490 | skb_set_mac_header(skb, 0); |
@@ -1895,7 +1845,9 @@ static int __init ieee80211_init(void) | |||
1895 | struct sk_buff *skb; | 1845 | struct sk_buff *skb; |
1896 | int ret; | 1846 | int ret; |
1897 | 1847 | ||
1898 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1848 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1849 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | ||
1850 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | ||
1899 | 1851 | ||
1900 | ret = rc80211_pid_init(); | 1852 | ret = rc80211_pid_init(); |
1901 | if (ret) | 1853 | if (ret) |