aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-10-19 09:44:42 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-26 06:57:06 -0400
commit1041638f2bba0f1de75e66086d50fb1251d64dcf (patch)
tree95d5ea3a83302d27887dcdc2d425682216937f3f
parent7b20b8e8d70a0f4f18c254b42e5b157f93731e9f (diff)
mac80211: add explicit AP/GO driver operations
Depending on the driver, a lot of setup may be necessary to start operating as an AP, some of which may fail. Add an explicit AP start driver method to make such failures easier to handle, and add an AP stop driver method for symmetry. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h10
-rw-r--r--net/mac80211/cfg.c11
-rw-r--r--net/mac80211/driver-ops.h25
-rw-r--r--net/mac80211/pm.c4
-rw-r--r--net/mac80211/trace.h37
-rw-r--r--net/mac80211/util.c6
6 files changed, 92 insertions, 1 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 00b7204708b..5f5327452c9 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 */
2385struct ieee80211_ops { 2392struct 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 95bf3d5d009..34fd3eba309 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 77407b31e1f..1701ad7013a 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
939static 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
953static 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 9f404ac901a..0f1c434638b 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 0638541b625..5e74e77cba9 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
1399TRACE_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
1430DEFINE_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 ea8a6744a9d..dd0e6f20fc5 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 |