diff options
Diffstat (limited to 'net/mac80211/iface.c')
| -rw-r--r-- | net/mac80211/iface.c | 34 | 
1 files changed, 29 insertions, 5 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index c1cc200ac81f..66785739dad3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c  | |||
| @@ -188,6 +188,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
| 188 | break; | 188 | break; | 
| 189 | case NL80211_IFTYPE_UNSPECIFIED: | 189 | case NL80211_IFTYPE_UNSPECIFIED: | 
| 190 | case NUM_NL80211_IFTYPES: | 190 | case NUM_NL80211_IFTYPES: | 
| 191 | case NL80211_IFTYPE_P2P_CLIENT: | ||
| 192 | case NL80211_IFTYPE_P2P_GO: | ||
| 191 | /* cannot happen */ | 193 | /* cannot happen */ | 
| 192 | WARN_ON(1); | 194 | WARN_ON(1); | 
| 193 | break; | 195 | break; | 
| @@ -280,6 +282,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
| 280 | netif_carrier_on(dev); | 282 | netif_carrier_on(dev); | 
| 281 | } | 283 | } | 
| 282 | 284 | ||
| 285 | set_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
| 286 | |||
| 283 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { | 287 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { | 
| 284 | /* Create STA entry for the WDS peer */ | 288 | /* Create STA entry for the WDS peer */ | 
| 285 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, | 289 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, | 
| @@ -331,8 +335,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
| 331 | 335 | ||
| 332 | netif_tx_start_all_queues(dev); | 336 | netif_tx_start_all_queues(dev); | 
| 333 | 337 | ||
| 334 | set_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
| 335 | |||
| 336 | return 0; | 338 | return 0; | 
| 337 | err_del_interface: | 339 | err_del_interface: | 
| 338 | drv_remove_interface(local, &sdata->vif); | 340 | drv_remove_interface(local, &sdata->vif); | 
| @@ -343,6 +345,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
| 343 | sdata->bss = NULL; | 345 | sdata->bss = NULL; | 
| 344 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 346 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 
| 345 | list_del(&sdata->u.vlan.list); | 347 | list_del(&sdata->u.vlan.list); | 
| 348 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
| 346 | return res; | 349 | return res; | 
| 347 | } | 350 | } | 
| 348 | 351 | ||
| @@ -843,6 +846,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
| 843 | 846 | ||
| 844 | /* and set some type-dependent values */ | 847 | /* and set some type-dependent values */ | 
| 845 | sdata->vif.type = type; | 848 | sdata->vif.type = type; | 
| 849 | sdata->vif.p2p = false; | ||
| 846 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; | 850 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; | 
| 847 | sdata->wdev.iftype = type; | 851 | sdata->wdev.iftype = type; | 
| 848 | 852 | ||
| @@ -856,10 +860,20 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
| 856 | INIT_WORK(&sdata->work, ieee80211_iface_work); | 860 | INIT_WORK(&sdata->work, ieee80211_iface_work); | 
| 857 | 861 | ||
| 858 | switch (type) { | 862 | switch (type) { | 
| 863 | case NL80211_IFTYPE_P2P_GO: | ||
| 864 | type = NL80211_IFTYPE_AP; | ||
| 865 | sdata->vif.type = type; | ||
| 866 | sdata->vif.p2p = true; | ||
| 867 | /* fall through */ | ||
| 859 | case NL80211_IFTYPE_AP: | 868 | case NL80211_IFTYPE_AP: | 
| 860 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | 869 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | 
| 861 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 870 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 
| 862 | break; | 871 | break; | 
| 872 | case NL80211_IFTYPE_P2P_CLIENT: | ||
| 873 | type = NL80211_IFTYPE_STATION; | ||
| 874 | sdata->vif.type = type; | ||
| 875 | sdata->vif.p2p = true; | ||
| 876 | /* fall through */ | ||
| 863 | case NL80211_IFTYPE_STATION: | 877 | case NL80211_IFTYPE_STATION: | 
| 864 | ieee80211_sta_setup_sdata(sdata); | 878 | ieee80211_sta_setup_sdata(sdata); | 
| 865 | break; | 879 | break; | 
| @@ -893,6 +907,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | |||
| 893 | { | 907 | { | 
| 894 | struct ieee80211_local *local = sdata->local; | 908 | struct ieee80211_local *local = sdata->local; | 
| 895 | int ret, err; | 909 | int ret, err; | 
| 910 | enum nl80211_iftype internal_type = type; | ||
| 911 | bool p2p = false; | ||
| 896 | 912 | ||
| 897 | ASSERT_RTNL(); | 913 | ASSERT_RTNL(); | 
| 898 | 914 | ||
| @@ -925,11 +941,19 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | |||
| 925 | * code isn't prepared to handle). | 941 | * code isn't prepared to handle). | 
| 926 | */ | 942 | */ | 
| 927 | break; | 943 | break; | 
| 944 | case NL80211_IFTYPE_P2P_CLIENT: | ||
| 945 | p2p = true; | ||
| 946 | internal_type = NL80211_IFTYPE_STATION; | ||
| 947 | break; | ||
| 948 | case NL80211_IFTYPE_P2P_GO: | ||
| 949 | p2p = true; | ||
| 950 | internal_type = NL80211_IFTYPE_AP; | ||
| 951 | break; | ||
| 928 | default: | 952 | default: | 
| 929 | return -EBUSY; | 953 | return -EBUSY; | 
| 930 | } | 954 | } | 
| 931 | 955 | ||
| 932 | ret = ieee80211_check_concurrent_iface(sdata, type); | 956 | ret = ieee80211_check_concurrent_iface(sdata, internal_type); | 
| 933 | if (ret) | 957 | if (ret) | 
| 934 | return ret; | 958 | return ret; | 
| 935 | 959 | ||
| @@ -937,7 +961,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | |||
| 937 | 961 | ||
| 938 | ieee80211_teardown_sdata(sdata->dev); | 962 | ieee80211_teardown_sdata(sdata->dev); | 
| 939 | 963 | ||
| 940 | ret = drv_change_interface(local, sdata, type); | 964 | ret = drv_change_interface(local, sdata, internal_type, p2p); | 
| 941 | if (ret) | 965 | if (ret) | 
| 942 | type = sdata->vif.type; | 966 | type = sdata->vif.type; | 
| 943 | 967 | ||
| @@ -956,7 +980,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
| 956 | 980 | ||
| 957 | ASSERT_RTNL(); | 981 | ASSERT_RTNL(); | 
| 958 | 982 | ||
| 959 | if (type == sdata->vif.type) | 983 | if (type == ieee80211_vif_type_p2p(&sdata->vif)) | 
| 960 | return 0; | 984 | return 0; | 
| 961 | 985 | ||
| 962 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | 986 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | 
