aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c34
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. */