aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-15 06:55:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:11 -0400
commite039fa4a4195ac4ee895e6f3d1334beed63256fe (patch)
treecfd0762d73df96b73052378be7b157c4ac6e7035 /net/mac80211/main.c
parente24549485f859be6518929bb1c9c0257d79f033d (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.c128
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
973static int __ieee80211_if_config(struct net_device *dev, 973static 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
1015int ieee80211_if_config_beacon(struct net_device *dev) 1012int 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
1031int ieee80211_hw_config(struct ieee80211_local *local) 1026int ieee80211_hw_config(struct ieee80211_local *local)
@@ -1180,38 +1175,20 @@ void ieee80211_reset_erp_info(struct net_device *dev)
1180} 1175}
1181 1176
1182void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 1177void 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. */
1275static void ieee80211_remove_tx_extra(struct ieee80211_local *local, 1247static 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
1339static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, 1302static 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
1410void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, 1372void 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)