diff options
-rw-r--r-- | include/net/mac80211.h | 10 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 11 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 25 | ||||
-rw-r--r-- | net/mac80211/pm.c | 4 | ||||
-rw-r--r-- | net/mac80211/trace.h | 37 | ||||
-rw-r--r-- | net/mac80211/util.c | 6 |
6 files changed, 92 insertions, 1 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 00b7204708bd..5f5327452c9a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2381,6 +2381,13 @@ enum ieee80211_rate_control_changed { | |||
2381 | * to vif. Possible use is for hw queue remapping. | 2381 | * to vif. Possible use is for hw queue remapping. |
2382 | * @unassign_vif_chanctx: Notifies device driver about channel context being | 2382 | * @unassign_vif_chanctx: Notifies device driver about channel context being |
2383 | * unbound from vif. | 2383 | * unbound from vif. |
2384 | * @start_ap: Start operation on the AP interface, this is called after all the | ||
2385 | * information in bss_conf is set and beacon can be retrieved. A channel | ||
2386 | * context is bound before this is called. Note that if the driver uses | ||
2387 | * software scan or ROC, this (and @stop_ap) isn't called when the AP is | ||
2388 | * just "paused" for scanning/ROC, which is indicated by the beacon being | ||
2389 | * disabled/enabled via @bss_info_changed. | ||
2390 | * @stop_ap: Stop operation on the AP interface. | ||
2384 | */ | 2391 | */ |
2385 | struct ieee80211_ops { | 2392 | struct ieee80211_ops { |
2386 | void (*tx)(struct ieee80211_hw *hw, | 2393 | void (*tx)(struct ieee80211_hw *hw, |
@@ -2406,6 +2413,9 @@ struct ieee80211_ops { | |||
2406 | struct ieee80211_bss_conf *info, | 2413 | struct ieee80211_bss_conf *info, |
2407 | u32 changed); | 2414 | u32 changed); |
2408 | 2415 | ||
2416 | int (*start_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | ||
2417 | void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | ||
2418 | |||
2409 | u64 (*prepare_multicast)(struct ieee80211_hw *hw, | 2419 | u64 (*prepare_multicast)(struct ieee80211_hw *hw, |
2410 | struct netdev_hw_addr_list *mc_list); | 2420 | struct netdev_hw_addr_list *mc_list); |
2411 | void (*configure_filter)(struct ieee80211_hw *hw, | 2421 | void (*configure_filter)(struct ieee80211_hw *hw, |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 95bf3d5d009f..34fd3eba3090 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -922,6 +922,15 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
922 | return err; | 922 | return err; |
923 | changed |= err; | 923 | changed |= err; |
924 | 924 | ||
925 | err = drv_start_ap(sdata->local, sdata); | ||
926 | if (err) { | ||
927 | old = rtnl_dereference(sdata->u.ap.beacon); | ||
928 | if (old) | ||
929 | kfree_rcu(old, rcu_head); | ||
930 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); | ||
931 | return err; | ||
932 | } | ||
933 | |||
925 | ieee80211_bss_info_change_notify(sdata, changed); | 934 | ieee80211_bss_info_change_notify(sdata, changed); |
926 | 935 | ||
927 | netif_carrier_on(dev); | 936 | netif_carrier_on(dev); |
@@ -979,6 +988,8 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
979 | sta_info_flush(local, sdata); | 988 | sta_info_flush(local, sdata); |
980 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 989 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
981 | 990 | ||
991 | drv_stop_ap(sdata->local, sdata); | ||
992 | |||
982 | /* free all potentially still buffered bcast frames */ | 993 | /* free all potentially still buffered bcast frames */ |
983 | local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); | 994 | local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); |
984 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); | 995 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 77407b31e1ff..1701ad7013a4 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -936,4 +936,29 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, | |||
936 | trace_drv_return_void(local); | 936 | trace_drv_return_void(local); |
937 | } | 937 | } |
938 | 938 | ||
939 | static inline int drv_start_ap(struct ieee80211_local *local, | ||
940 | struct ieee80211_sub_if_data *sdata) | ||
941 | { | ||
942 | int ret = 0; | ||
943 | |||
944 | check_sdata_in_driver(sdata); | ||
945 | |||
946 | trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); | ||
947 | if (local->ops->start_ap) | ||
948 | ret = local->ops->start_ap(&local->hw, &sdata->vif); | ||
949 | trace_drv_return_int(local, ret); | ||
950 | return ret; | ||
951 | } | ||
952 | |||
953 | static inline void drv_stop_ap(struct ieee80211_local *local, | ||
954 | struct ieee80211_sub_if_data *sdata) | ||
955 | { | ||
956 | check_sdata_in_driver(sdata); | ||
957 | |||
958 | trace_drv_stop_ap(local, sdata); | ||
959 | if (local->ops->stop_ap) | ||
960 | local->ops->stop_ap(&local->hw, &sdata->vif); | ||
961 | trace_drv_return_void(local); | ||
962 | } | ||
963 | |||
939 | #endif /* __MAC80211_DRIVER_OPS */ | 964 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 9f404ac901ab..0f1c434638bc 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -135,6 +135,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
135 | ieee80211_bss_info_change_notify(sdata, | 135 | ieee80211_bss_info_change_notify(sdata, |
136 | BSS_CHANGED_BEACON_ENABLED); | 136 | BSS_CHANGED_BEACON_ENABLED); |
137 | 137 | ||
138 | if (sdata->vif.type == NL80211_IFTYPE_AP && | ||
139 | rcu_access_pointer(sdata->u.ap.beacon)) | ||
140 | drv_stop_ap(local, sdata); | ||
141 | |||
138 | /* the interface is leaving the channel and is removed */ | 142 | /* the interface is leaving the channel and is removed */ |
139 | ieee80211_vif_release_channel(sdata); | 143 | ieee80211_vif_release_channel(sdata); |
140 | drv_remove_interface(local, sdata); | 144 | drv_remove_interface(local, sdata); |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 0638541b625f..5e74e77cba9a 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -1396,6 +1396,43 @@ DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx, | |||
1396 | TP_ARGS(local, sdata, ctx) | 1396 | TP_ARGS(local, sdata, ctx) |
1397 | ); | 1397 | ); |
1398 | 1398 | ||
1399 | TRACE_EVENT(drv_start_ap, | ||
1400 | TP_PROTO(struct ieee80211_local *local, | ||
1401 | struct ieee80211_sub_if_data *sdata, | ||
1402 | struct ieee80211_bss_conf *info), | ||
1403 | |||
1404 | TP_ARGS(local, sdata, info), | ||
1405 | |||
1406 | TP_STRUCT__entry( | ||
1407 | LOCAL_ENTRY | ||
1408 | VIF_ENTRY | ||
1409 | __field(u8, dtimper) | ||
1410 | __field(u16, bcnint) | ||
1411 | __dynamic_array(u8, ssid, info->ssid_len); | ||
1412 | __field(bool, hidden_ssid); | ||
1413 | ), | ||
1414 | |||
1415 | TP_fast_assign( | ||
1416 | LOCAL_ASSIGN; | ||
1417 | VIF_ASSIGN; | ||
1418 | __entry->dtimper = info->dtim_period; | ||
1419 | __entry->bcnint = info->beacon_int; | ||
1420 | memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); | ||
1421 | __entry->hidden_ssid = info->hidden_ssid; | ||
1422 | ), | ||
1423 | |||
1424 | TP_printk( | ||
1425 | LOCAL_PR_FMT VIF_PR_FMT, | ||
1426 | LOCAL_PR_ARG, VIF_PR_ARG | ||
1427 | ) | ||
1428 | ); | ||
1429 | |||
1430 | DEFINE_EVENT(local_sdata_evt, drv_stop_ap, | ||
1431 | TP_PROTO(struct ieee80211_local *local, | ||
1432 | struct ieee80211_sub_if_data *sdata), | ||
1433 | TP_ARGS(local, sdata) | ||
1434 | ); | ||
1435 | |||
1399 | /* | 1436 | /* |
1400 | * Tracing for API calls that drivers call. | 1437 | * Tracing for API calls that drivers call. |
1401 | */ | 1438 | */ |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ea8a6744a9db..dd0e6f20fc51 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1467,9 +1467,13 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1467 | case NL80211_IFTYPE_AP: | 1467 | case NL80211_IFTYPE_AP: |
1468 | changed |= BSS_CHANGED_SSID; | 1468 | changed |= BSS_CHANGED_SSID; |
1469 | 1469 | ||
1470 | if (sdata->vif.type == NL80211_IFTYPE_AP) | 1470 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
1471 | changed |= BSS_CHANGED_AP_PROBE_RESP; | 1471 | changed |= BSS_CHANGED_AP_PROBE_RESP; |
1472 | 1472 | ||
1473 | if (rcu_access_pointer(sdata->u.ap.beacon)) | ||
1474 | drv_start_ap(local, sdata); | ||
1475 | } | ||
1476 | |||
1473 | /* fall through */ | 1477 | /* fall through */ |
1474 | case NL80211_IFTYPE_MESH_POINT: | 1478 | case NL80211_IFTYPE_MESH_POINT: |
1475 | changed |= BSS_CHANGED_BEACON | | 1479 | changed |= BSS_CHANGED_BEACON | |