Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: support P2P Device abstraction

After cfg80211 got a P2P Device abstraction, add
support to mac80211. Whether it really is supported
or not will depend on whether or not the driver has
support for it, but mac80211 needs to change to be
able to support drivers that need a P2P Device.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+222 -92
+18
net/mac80211/cfg.c
··· 102 102 return 0; 103 103 } 104 104 105 + static int ieee80211_start_p2p_device(struct wiphy *wiphy, 106 + struct wireless_dev *wdev) 107 + { 108 + return ieee80211_do_open(wdev, true); 109 + } 110 + 111 + static void ieee80211_stop_p2p_device(struct wiphy *wiphy, 112 + struct wireless_dev *wdev) 113 + { 114 + ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev)); 115 + } 116 + 105 117 static int ieee80211_set_noack_map(struct wiphy *wiphy, 106 118 struct net_device *dev, 107 119 u16 noack_map) ··· 1786 1774 case NL80211_IFTYPE_ADHOC: 1787 1775 case NL80211_IFTYPE_MESH_POINT: 1788 1776 case NL80211_IFTYPE_P2P_CLIENT: 1777 + case NL80211_IFTYPE_P2P_DEVICE: 1789 1778 break; 1790 1779 case NL80211_IFTYPE_P2P_GO: 1791 1780 if (sdata->local->ops->hw_scan) ··· 2474 2461 if (!sdata->u.mgd.associated) 2475 2462 need_offchan = true; 2476 2463 break; 2464 + case NL80211_IFTYPE_P2P_DEVICE: 2465 + need_offchan = true; 2466 + break; 2477 2467 default: 2478 2468 return -EOPNOTSUPP; 2479 2469 } ··· 3029 3013 .add_virtual_intf = ieee80211_add_iface, 3030 3014 .del_virtual_intf = ieee80211_del_iface, 3031 3015 .change_virtual_intf = ieee80211_change_iface, 3016 + .start_p2p_device = ieee80211_start_p2p_device, 3017 + .stop_p2p_device = ieee80211_stop_p2p_device, 3032 3018 .add_key = ieee80211_add_key, 3033 3019 .del_key = ieee80211_del_key, 3034 3020 .get_key = ieee80211_get_key,
+1 -1
net/mac80211/driver-ops.h
··· 9 9 { 10 10 WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), 11 11 "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", 12 - sdata->dev->name, sdata->flags); 12 + sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); 13 13 } 14 14 15 15 static inline struct ieee80211_sub_if_data *
+4
net/mac80211/ieee80211_i.h
··· 1080 1080 struct idr ack_status_frames; 1081 1081 spinlock_t ack_status_lock; 1082 1082 1083 + struct ieee80211_sub_if_data __rcu *p2p_sdata; 1084 + 1083 1085 /* dummy netdev for use w/ NAPI */ 1084 1086 struct net_device napi_dev; 1085 1087 ··· 1298 1296 void ieee80211_recalc_idle(struct ieee80211_local *local); 1299 1297 void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, 1300 1298 const int offset); 1299 + int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); 1300 + void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); 1301 1301 1302 1302 static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) 1303 1303 {
+145 -78
net/mac80211/iface.c
··· 100 100 sdata->vif.bss_conf.idle = true; 101 101 continue; 102 102 } 103 + 104 + if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) 105 + continue; 106 + 103 107 /* count everything else */ 104 108 sdata->vif.bss_conf.idle = false; 105 109 count++; ··· 125 121 126 122 list_for_each_entry(sdata, &local->interfaces, list) { 127 123 if (sdata->vif.type == NL80211_IFTYPE_MONITOR || 128 - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 124 + sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 125 + sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) 129 126 continue; 130 127 if (sdata->old_idle == sdata->vif.bss_conf.idle) 131 128 continue; ··· 209 204 { 210 205 return type1 == NL80211_IFTYPE_MONITOR || 211 206 type2 == NL80211_IFTYPE_MONITOR || 207 + type1 == NL80211_IFTYPE_P2P_DEVICE || 208 + type2 == NL80211_IFTYPE_P2P_DEVICE || 212 209 (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) || 213 210 (type1 == NL80211_IFTYPE_WDS && 214 211 (type2 == NL80211_IFTYPE_WDS || ··· 413 406 * an error on interface type changes that have been pre-checked, so most 414 407 * checks should be in ieee80211_check_concurrent_iface. 415 408 */ 416 - static int ieee80211_do_open(struct net_device *dev, bool coming_up) 409 + int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) 417 410 { 418 - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 411 + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 412 + struct net_device *dev = wdev->netdev; 419 413 struct ieee80211_local *local = sdata->local; 420 414 struct sta_info *sta; 421 415 u32 changed = 0; ··· 451 443 case NL80211_IFTYPE_STATION: 452 444 case NL80211_IFTYPE_MONITOR: 453 445 case NL80211_IFTYPE_ADHOC: 446 + case NL80211_IFTYPE_P2P_DEVICE: 454 447 /* no special treatment */ 455 448 break; 456 449 case NL80211_IFTYPE_UNSPECIFIED: 457 450 case NUM_NL80211_IFTYPES: 458 451 case NL80211_IFTYPE_P2P_CLIENT: 459 452 case NL80211_IFTYPE_P2P_GO: 460 - case NL80211_IFTYPE_P2P_DEVICE: 461 453 /* cannot happen */ 462 454 WARN_ON(1); 463 455 break; ··· 480 472 * Copy the hopefully now-present MAC address to 481 473 * this interface, if it has the special null one. 482 474 */ 483 - if (is_zero_ether_addr(dev->dev_addr)) { 475 + if (dev && is_zero_ether_addr(dev->dev_addr)) { 484 476 memcpy(dev->dev_addr, 485 477 local->hw.wiphy->perm_addr, 486 478 ETH_ALEN); ··· 545 537 local->fif_probe_req++; 546 538 } 547 539 548 - changed |= ieee80211_reset_erp_info(sdata); 540 + if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) 541 + changed |= ieee80211_reset_erp_info(sdata); 549 542 ieee80211_bss_info_change_notify(sdata, changed); 550 543 551 544 switch (sdata->vif.type) { ··· 557 548 netif_carrier_off(dev); 558 549 break; 559 550 case NL80211_IFTYPE_WDS: 551 + case NL80211_IFTYPE_P2P_DEVICE: 560 552 break; 561 553 default: 562 554 netif_carrier_on(dev); ··· 594 584 595 585 rate_control_rate_init(sta); 596 586 netif_carrier_on(dev); 587 + } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { 588 + rcu_assign_pointer(local->p2p_sdata, sdata); 597 589 } 598 590 599 591 /* ··· 621 609 622 610 ieee80211_recalc_ps(local, -1); 623 611 624 - netif_tx_start_all_queues(dev); 612 + if (dev) 613 + netif_tx_start_all_queues(dev); 625 614 626 615 return 0; 627 616 err_del_interface: ··· 652 639 if (err) 653 640 return err; 654 641 655 - return ieee80211_do_open(dev, true); 642 + return ieee80211_do_open(&sdata->wdev, true); 656 643 } 657 644 658 645 static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ··· 673 660 /* 674 661 * Stop TX on this interface first. 675 662 */ 676 - netif_tx_stop_all_queues(sdata->dev); 663 + if (sdata->dev) 664 + netif_tx_stop_all_queues(sdata->dev); 677 665 678 666 ieee80211_roc_purge(sdata); 679 667 ··· 713 699 local->fif_probe_req--; 714 700 } 715 701 716 - netif_addr_lock_bh(sdata->dev); 717 - spin_lock_bh(&local->filter_lock); 718 - __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, 719 - sdata->dev->addr_len); 720 - spin_unlock_bh(&local->filter_lock); 721 - netif_addr_unlock_bh(sdata->dev); 702 + if (sdata->dev) { 703 + netif_addr_lock_bh(sdata->dev); 704 + spin_lock_bh(&local->filter_lock); 705 + __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, 706 + sdata->dev->addr_len); 707 + spin_unlock_bh(&local->filter_lock); 708 + netif_addr_unlock_bh(sdata->dev); 722 709 723 - ieee80211_configure_filter(local); 710 + ieee80211_configure_filter(local); 711 + } 724 712 725 713 del_timer_sync(&local->dynamic_ps_timer); 726 714 cancel_work_sync(&local->dynamic_ps_enable_work); ··· 783 767 ieee80211_adjust_monitor_flags(sdata, -1); 784 768 ieee80211_configure_filter(local); 785 769 break; 770 + case NL80211_IFTYPE_P2P_DEVICE: 771 + /* relies on synchronize_rcu() below */ 772 + rcu_assign_pointer(local->p2p_sdata, NULL); 773 + /* fall through */ 786 774 default: 787 775 flush_work(&sdata->work); 788 776 /* ··· 897 877 * Called when the netdev is removed or, by the code below, before 898 878 * the interface type changes. 899 879 */ 900 - static void ieee80211_teardown_sdata(struct net_device *dev) 880 + static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) 901 881 { 902 - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 903 882 struct ieee80211_local *local = sdata->local; 904 883 int flushed; 905 884 int i; ··· 919 900 WARN_ON(flushed); 920 901 } 921 902 903 + static void ieee80211_uninit(struct net_device *dev) 904 + { 905 + ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); 906 + } 907 + 922 908 static u16 ieee80211_netdev_select_queue(struct net_device *dev, 923 909 struct sk_buff *skb) 924 910 { ··· 933 909 static const struct net_device_ops ieee80211_dataif_ops = { 934 910 .ndo_open = ieee80211_open, 935 911 .ndo_stop = ieee80211_stop, 936 - .ndo_uninit = ieee80211_teardown_sdata, 912 + .ndo_uninit = ieee80211_uninit, 937 913 .ndo_start_xmit = ieee80211_subif_start_xmit, 938 914 .ndo_set_rx_mode = ieee80211_set_multicast_list, 939 915 .ndo_change_mtu = ieee80211_change_mtu, ··· 964 940 static const struct net_device_ops ieee80211_monitorif_ops = { 965 941 .ndo_open = ieee80211_open, 966 942 .ndo_stop = ieee80211_stop, 967 - .ndo_uninit = ieee80211_teardown_sdata, 943 + .ndo_uninit = ieee80211_uninit, 968 944 .ndo_start_xmit = ieee80211_monitor_start_xmit, 969 945 .ndo_set_rx_mode = ieee80211_set_multicast_list, 970 946 .ndo_change_mtu = ieee80211_change_mtu, ··· 1123 1099 /* and set some type-dependent values */ 1124 1100 sdata->vif.type = type; 1125 1101 sdata->vif.p2p = false; 1126 - sdata->dev->netdev_ops = &ieee80211_dataif_ops; 1127 1102 sdata->wdev.iftype = type; 1128 1103 1129 1104 sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); ··· 1130 1107 1131 1108 sdata->noack_map = 0; 1132 1109 1133 - /* only monitor differs */ 1134 - sdata->dev->type = ARPHRD_ETHER; 1110 + /* only monitor/p2p-device differ */ 1111 + if (sdata->dev) { 1112 + sdata->dev->netdev_ops = &ieee80211_dataif_ops; 1113 + sdata->dev->type = ARPHRD_ETHER; 1114 + } 1135 1115 1136 1116 skb_queue_head_init(&sdata->skb_queue); 1137 1117 INIT_WORK(&sdata->work, ieee80211_iface_work); ··· 1172 1146 break; 1173 1147 case NL80211_IFTYPE_WDS: 1174 1148 case NL80211_IFTYPE_AP_VLAN: 1175 - break; 1176 1149 case NL80211_IFTYPE_P2P_DEVICE: 1177 - /* not yet supported */ 1150 + break; 1178 1151 case NL80211_IFTYPE_UNSPECIFIED: 1179 1152 case NUM_NL80211_IFTYPES: 1180 1153 BUG(); ··· 1240 1215 1241 1216 ieee80211_do_stop(sdata, false); 1242 1217 1243 - ieee80211_teardown_sdata(sdata->dev); 1218 + ieee80211_teardown_sdata(sdata); 1244 1219 1245 1220 ret = drv_change_interface(local, sdata, internal_type, p2p); 1246 1221 if (ret) ··· 1255 1230 1256 1231 ieee80211_setup_sdata(sdata, type); 1257 1232 1258 - err = ieee80211_do_open(sdata->dev, false); 1233 + err = ieee80211_do_open(&sdata->wdev, false); 1259 1234 WARN(err, "type change: do_open returned %d", err); 1260 1235 1261 1236 return ret; ··· 1282 1257 return ret; 1283 1258 } else { 1284 1259 /* Purge and reset type-dependent state. */ 1285 - ieee80211_teardown_sdata(sdata->dev); 1260 + ieee80211_teardown_sdata(sdata); 1286 1261 ieee80211_setup_sdata(sdata, type); 1287 1262 } 1288 1263 ··· 1298 1273 } 1299 1274 1300 1275 static void ieee80211_assign_perm_addr(struct ieee80211_local *local, 1301 - struct net_device *dev, 1302 - enum nl80211_iftype type) 1276 + u8 *perm_addr, enum nl80211_iftype type) 1303 1277 { 1304 1278 struct ieee80211_sub_if_data *sdata; 1305 1279 u64 mask, start, addr, val, inc; ··· 1307 1283 int i; 1308 1284 1309 1285 /* default ... something at least */ 1310 - memcpy(dev->perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 1286 + memcpy(perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 1311 1287 1312 1288 if (is_zero_ether_addr(local->hw.wiphy->addr_mask) && 1313 1289 local->hw.wiphy->n_addresses <= 1) ··· 1326 1302 list_for_each_entry(sdata, &local->interfaces, list) { 1327 1303 if (sdata->vif.type != NL80211_IFTYPE_AP) 1328 1304 continue; 1329 - memcpy(dev->perm_addr, sdata->vif.addr, ETH_ALEN); 1305 + memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); 1330 1306 break; 1331 1307 } 1332 1308 /* keep default if no AP interface present */ ··· 1345 1321 } 1346 1322 1347 1323 if (!used) { 1348 - memcpy(dev->perm_addr, 1324 + memcpy(perm_addr, 1349 1325 local->hw.wiphy->addresses[i].addr, 1350 1326 ETH_ALEN); 1351 1327 break; ··· 1396 1372 } 1397 1373 1398 1374 if (!used) { 1399 - memcpy(dev->perm_addr, tmp_addr, ETH_ALEN); 1375 + memcpy(perm_addr, tmp_addr, ETH_ALEN); 1400 1376 break; 1401 1377 } 1402 1378 addr = (start & ~mask) | (val & mask); ··· 1412 1388 struct wireless_dev **new_wdev, enum nl80211_iftype type, 1413 1389 struct vif_params *params) 1414 1390 { 1415 - struct net_device *ndev; 1391 + struct net_device *ndev = NULL; 1416 1392 struct ieee80211_sub_if_data *sdata = NULL; 1417 1393 int ret, i; 1418 1394 int txqs = 1; 1419 1395 1420 1396 ASSERT_RTNL(); 1421 1397 1422 - if (local->hw.queues >= IEEE80211_NUM_ACS) 1423 - txqs = IEEE80211_NUM_ACS; 1398 + if (type == NL80211_IFTYPE_P2P_DEVICE) { 1399 + struct wireless_dev *wdev; 1424 1400 1425 - ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, 1426 - name, ieee80211_if_setup, txqs, 1); 1427 - if (!ndev) 1428 - return -ENOMEM; 1429 - dev_net_set(ndev, wiphy_net(local->hw.wiphy)); 1401 + sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, 1402 + GFP_KERNEL); 1403 + if (!sdata) 1404 + return -ENOMEM; 1405 + wdev = &sdata->wdev; 1430 1406 1431 - ndev->needed_headroom = local->tx_headroom + 1432 - 4*6 /* four MAC addresses */ 1433 - + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ 1434 - + 6 /* mesh */ 1435 - + 8 /* rfc1042/bridge tunnel */ 1436 - - ETH_HLEN /* ethernet hard_header_len */ 1437 - + IEEE80211_ENCRYPT_HEADROOM; 1438 - ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; 1407 + sdata->dev = NULL; 1408 + strlcpy(sdata->name, name, IFNAMSIZ); 1409 + ieee80211_assign_perm_addr(local, wdev->address, type); 1410 + memcpy(sdata->vif.addr, wdev->address, ETH_ALEN); 1411 + } else { 1412 + if (local->hw.queues >= IEEE80211_NUM_ACS) 1413 + txqs = IEEE80211_NUM_ACS; 1439 1414 1440 - ret = dev_alloc_name(ndev, ndev->name); 1441 - if (ret < 0) 1442 - goto fail; 1415 + ndev = alloc_netdev_mqs(sizeof(*sdata) + 1416 + local->hw.vif_data_size, 1417 + name, ieee80211_if_setup, txqs, 1); 1418 + if (!ndev) 1419 + return -ENOMEM; 1420 + dev_net_set(ndev, wiphy_net(local->hw.wiphy)); 1443 1421 1444 - ieee80211_assign_perm_addr(local, ndev, type); 1445 - memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 1446 - SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 1422 + ndev->needed_headroom = local->tx_headroom + 1423 + 4*6 /* four MAC addresses */ 1424 + + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ 1425 + + 6 /* mesh */ 1426 + + 8 /* rfc1042/bridge tunnel */ 1427 + - ETH_HLEN /* ethernet hard_header_len */ 1428 + + IEEE80211_ENCRYPT_HEADROOM; 1429 + ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; 1447 1430 1448 - /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ 1449 - sdata = netdev_priv(ndev); 1450 - ndev->ieee80211_ptr = &sdata->wdev; 1451 - memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); 1452 - memcpy(sdata->name, ndev->name, IFNAMSIZ); 1431 + ret = dev_alloc_name(ndev, ndev->name); 1432 + if (ret < 0) { 1433 + free_netdev(ndev); 1434 + return ret; 1435 + } 1436 + 1437 + ieee80211_assign_perm_addr(local, ndev->perm_addr, type); 1438 + memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 1439 + SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 1440 + 1441 + /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ 1442 + sdata = netdev_priv(ndev); 1443 + ndev->ieee80211_ptr = &sdata->wdev; 1444 + memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); 1445 + memcpy(sdata->name, ndev->name, IFNAMSIZ); 1446 + 1447 + sdata->dev = ndev; 1448 + } 1453 1449 1454 1450 /* initialise type-independent data */ 1455 1451 sdata->wdev.wiphy = local->hw.wiphy; 1456 1452 sdata->local = local; 1457 - sdata->dev = ndev; 1458 1453 #ifdef CONFIG_INET 1459 1454 sdata->arp_filter_state = true; 1460 1455 #endif ··· 1502 1459 /* setup type-dependent data */ 1503 1460 ieee80211_setup_sdata(sdata, type); 1504 1461 1505 - if (params) { 1506 - ndev->ieee80211_ptr->use_4addr = params->use_4addr; 1507 - if (type == NL80211_IFTYPE_STATION) 1508 - sdata->u.mgd.use_4addr = params->use_4addr; 1462 + if (ndev) { 1463 + if (params) { 1464 + ndev->ieee80211_ptr->use_4addr = params->use_4addr; 1465 + if (type == NL80211_IFTYPE_STATION) 1466 + sdata->u.mgd.use_4addr = params->use_4addr; 1467 + } 1468 + 1469 + ndev->features |= local->hw.netdev_features; 1470 + 1471 + ret = register_netdevice(ndev); 1472 + if (ret) { 1473 + free_netdev(ndev); 1474 + return ret; 1475 + } 1509 1476 } 1510 - 1511 - ndev->features |= local->hw.netdev_features; 1512 - 1513 - ret = register_netdevice(ndev); 1514 - if (ret) 1515 - goto fail; 1516 1477 1517 1478 mutex_lock(&local->iflist_mtx); 1518 1479 list_add_tail_rcu(&sdata->list, &local->interfaces); ··· 1526 1479 *new_wdev = &sdata->wdev; 1527 1480 1528 1481 return 0; 1529 - 1530 - fail: 1531 - free_netdev(ndev); 1532 - return ret; 1533 1482 } 1534 1483 1535 1484 void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) ··· 1537 1494 mutex_unlock(&sdata->local->iflist_mtx); 1538 1495 1539 1496 synchronize_rcu(); 1540 - unregister_netdevice(sdata->dev); 1497 + 1498 + if (sdata->dev) { 1499 + unregister_netdevice(sdata->dev); 1500 + } else { 1501 + cfg80211_unregister_wdev(&sdata->wdev); 1502 + kfree(sdata); 1503 + } 1504 + } 1505 + 1506 + void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata) 1507 + { 1508 + if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) 1509 + return; 1510 + ieee80211_do_stop(sdata, true); 1511 + ieee80211_teardown_sdata(sdata); 1541 1512 } 1542 1513 1543 1514 /* ··· 1562 1505 { 1563 1506 struct ieee80211_sub_if_data *sdata, *tmp; 1564 1507 LIST_HEAD(unreg_list); 1508 + LIST_HEAD(wdev_list); 1565 1509 1566 1510 ASSERT_RTNL(); 1567 1511 ··· 1570 1512 list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { 1571 1513 list_del(&sdata->list); 1572 1514 1573 - unregister_netdevice_queue(sdata->dev, &unreg_list); 1515 + if (sdata->dev) 1516 + unregister_netdevice_queue(sdata->dev, &unreg_list); 1517 + else 1518 + list_add(&sdata->list, &wdev_list); 1574 1519 } 1575 1520 mutex_unlock(&local->iflist_mtx); 1576 1521 unregister_netdevice_many(&unreg_list); 1577 1522 list_del(&unreg_list); 1523 + 1524 + list_for_each_entry_safe(sdata, tmp, &wdev_list, list) { 1525 + list_del(&sdata->list); 1526 + cfg80211_unregister_wdev(&sdata->wdev); 1527 + kfree(sdata); 1528 + } 1578 1529 } 1579 1530 1580 1531 static int netdev_notify(struct notifier_block *nb,
+9
net/mac80211/main.c
··· 207 207 sdata->vif.bss_conf.bssid = NULL; 208 208 else if (ieee80211_vif_is_mesh(&sdata->vif)) { 209 209 sdata->vif.bss_conf.bssid = zero; 210 + } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { 211 + sdata->vif.bss_conf.bssid = sdata->vif.addr; 212 + WARN_ONCE(changed & ~(BSS_CHANGED_IDLE), 213 + "P2P Device BSS changed %#x", changed); 210 214 } else { 211 215 WARN_ON(1); 212 216 return; ··· 517 513 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 518 514 BIT(IEEE80211_STYPE_AUTH >> 4) | 519 515 BIT(IEEE80211_STYPE_DEAUTH >> 4), 516 + }, 517 + [NL80211_IFTYPE_P2P_DEVICE] = { 518 + .tx = 0xffff, 519 + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 520 + BIT(IEEE80211_STYPE_PROBE_REQ >> 4), 520 521 }, 521 522 }; 522 523
+6
net/mac80211/offchannel.c
··· 116 116 if (!ieee80211_sdata_running(sdata)) 117 117 continue; 118 118 119 + if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) 120 + continue; 121 + 119 122 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) 120 123 set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); 121 124 ··· 147 144 148 145 mutex_lock(&local->iflist_mtx); 149 146 list_for_each_entry(sdata, &local->interfaces, list) { 147 + if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) 148 + continue; 149 + 150 150 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) 151 151 clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); 152 152
+11 -3
net/mac80211/rx.c
··· 2812 2812 if (!bssid) { 2813 2813 if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) 2814 2814 return 0; 2815 - } else if (!ieee80211_bssid_match(bssid, 2816 - sdata->vif.addr)) { 2815 + } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { 2817 2816 /* 2818 2817 * Accept public action frames even when the 2819 2818 * BSSID doesn't match, this is used for P2P ··· 2832 2833 if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) 2833 2834 return 0; 2834 2835 break; 2836 + case NL80211_IFTYPE_P2P_DEVICE: 2837 + if (!ieee80211_is_public_action(hdr, skb->len) && 2838 + !ieee80211_is_probe_req(hdr->frame_control) && 2839 + !ieee80211_is_probe_resp(hdr->frame_control) && 2840 + !ieee80211_is_beacon(hdr->frame_control)) 2841 + return 0; 2842 + if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) 2843 + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2844 + break; 2835 2845 default: 2836 2846 /* should never get here */ 2837 - WARN_ON(1); 2847 + WARN_ON_ONCE(1); 2838 2848 break; 2839 2849 } 2840 2850
+15 -7
net/mac80211/status.c
··· 519 519 u64 cookie = (unsigned long)skb; 520 520 acked = info->flags & IEEE80211_TX_STAT_ACK; 521 521 522 - /* 523 - * TODO: When we have non-netdev frame TX, 524 - * we cannot use skb->dev->ieee80211_ptr 525 - */ 526 - 527 522 if (ieee80211_is_nullfunc(hdr->frame_control) || 528 - ieee80211_is_qos_nullfunc(hdr->frame_control)) 523 + ieee80211_is_qos_nullfunc(hdr->frame_control)) { 529 524 cfg80211_probe_status(skb->dev, hdr->addr1, 530 525 cookie, acked, GFP_ATOMIC); 531 - else 526 + } else if (skb->dev) { 532 527 cfg80211_mgmt_tx_status( 533 528 skb->dev->ieee80211_ptr, cookie, skb->data, 534 529 skb->len, acked, GFP_ATOMIC); 530 + } else { 531 + struct ieee80211_sub_if_data *p2p_sdata; 532 + 533 + rcu_read_lock(); 534 + 535 + p2p_sdata = rcu_dereference(local->p2p_sdata); 536 + if (p2p_sdata) { 537 + cfg80211_mgmt_tx_status( 538 + &p2p_sdata->wdev, cookie, skb->data, 539 + skb->len, acked, GFP_ATOMIC); 540 + } 541 + rcu_read_unlock(); 542 + } 535 543 } 536 544 537 545 if (unlikely(info->ack_frame_id)) {
+1 -1
net/mac80211/trace.h
··· 24 24 __string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") 25 25 #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ 26 26 __entry->p2p = sdata->vif.p2p; \ 27 - __assign_str(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") 27 + __assign_str(vif_name, sdata->dev ? sdata->dev->name : sdata->name) 28 28 #define VIF_PR_FMT " vif:%s(%d%s)" 29 29 #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" 30 30
+12 -2
net/mac80211/util.c
··· 276 276 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 277 277 int ac; 278 278 279 + if (!sdata->dev) 280 + continue; 281 + 279 282 if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) 280 283 continue; 281 284 ··· 366 363 rcu_read_lock(); 367 364 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 368 365 int ac; 366 + 367 + if (!sdata->dev) 368 + continue; 369 369 370 370 for (ac = 0; ac < n_acs; ac++) { 371 371 if (sdata->vif.hw_queue[ac] == queue || ··· 908 902 drv_conf_tx(local, sdata, ac, &qparam); 909 903 } 910 904 911 - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { 905 + if (sdata->vif.type != NL80211_IFTYPE_MONITOR && 906 + sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) { 912 907 sdata->vif.bss_conf.qos = enable_qos; 913 908 if (bss_notify) 914 909 ieee80211_bss_info_change_notify(sdata, ··· 1398 1391 /* ignore virtual */ 1399 1392 break; 1400 1393 case NL80211_IFTYPE_P2P_DEVICE: 1401 - /* not yet supported */ 1394 + changed = BSS_CHANGED_IDLE; 1395 + break; 1402 1396 case NL80211_IFTYPE_UNSPECIFIED: 1403 1397 case NUM_NL80211_IFTYPES: 1404 1398 case NL80211_IFTYPE_P2P_CLIENT: ··· 1585 1577 1586 1578 list_for_each_entry(sdata, &local->interfaces, list) { 1587 1579 if (!ieee80211_sdata_running(sdata)) 1580 + continue; 1581 + if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) 1588 1582 continue; 1589 1583 if (sdata->vif.type != NL80211_IFTYPE_STATION) 1590 1584 goto set;