Add functions necessary for OCB mode interface configuration used in interface bring-up and when 'joining' the network. Signed-off-by: Rostislav Lisovy <rostislav.lisovy@xxxxxxxxxxx> --- net/mac80211/Makefile | 3 ++- net/mac80211/cfg.c | 22 ++++++++++++++++++++++ net/mac80211/chan.c | 1 + net/mac80211/driver-ops.h | 3 ++- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/iface.c | 22 ++++++++++++++++++++++ net/mac80211/ocb.c | 22 ++++++++++++++++++++++ net/mac80211/util.c | 5 +++++ 8 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 net/mac80211/ocb.c diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 1e46ffa..1b9d37f 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -26,7 +26,8 @@ mac80211-y := \ event.o \ chan.o \ trace.o mlme.o \ - tdls.o + tdls.o \ + ocb.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7c56445..ac15b59 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -228,6 +228,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_OCB: /* shouldn't happen */ WARN_ON_ONCE(1); break; @@ -2032,6 +2033,26 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) } #endif +static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev, + struct ocb_setup *setup) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + int err; + + sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; + sdata->smps_mode = IEEE80211_SMPS_OFF; + sdata->needed_rx_chains = sdata->local->rx_chains; + + mutex_lock(&sdata->local->mtx); + err = ieee80211_vif_use_channel(sdata, &setup->chandef, + IEEE80211_CHANCTX_EXCLUSIVE); + mutex_unlock(&sdata->local->mtx); + if (err) + return err; + + return ieee80211_start_ocb(sdata); +} + static int ieee80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) @@ -3768,6 +3789,7 @@ const struct cfg80211_ops mac80211_config_ops = { .join_mesh = ieee80211_join_mesh, .leave_mesh = ieee80211_leave_mesh, #endif + .join_ocb = ieee80211_join_ocb, .change_bss = ieee80211_change_bss, .set_txq_params = ieee80211_set_txq_params, .set_monitor_channel = ieee80211_set_monitor_channel, diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 3702d64..62002de 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -675,6 +675,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: break; default: WARN_ON_ONCE(1); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index df1d502..ccf770d 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -214,7 +214,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, BSS_CHANGED_BEACON_ENABLED) && sdata->vif.type != NL80211_IFTYPE_AP && sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_OCB)) return; if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4668ce9..002fd8f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1421,6 +1421,9 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); +/* OCB code */ +int ieee80211_start_ocb(struct ieee80211_sub_if_data *sdata); + /* mesh code */ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 79fc988..23e573e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -258,6 +258,15 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, list_for_each_entry(nsdata, &local->interfaces, list) { if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { /* + * Only OCB and monitor mode may coexist + */ + if ((sdata->vif.type == NL80211_IFTYPE_OCB && + nsdata->vif.type != NL80211_IFTYPE_MONITOR) || + (sdata->vif.type != NL80211_IFTYPE_MONITOR && + nsdata->vif.type == NL80211_IFTYPE_OCB)) + return -EBUSY; + + /* * Allow only a single IBSS interface to be up at any * time. This is restricted because beacon distribution * cannot work properly if both are in the same IBSS. @@ -519,6 +528,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_OCB: /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: @@ -618,6 +628,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ieee80211_configure_filter(local); } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { local->fif_probe_req++; + } else if (sdata->vif.type == NL80211_IFTYPE_OCB) { + local->fif_other_bss++; + ieee80211_configure_filter(local); } if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) @@ -629,6 +642,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: netif_carrier_off(dev); break; case NL80211_IFTYPE_WDS: @@ -1274,6 +1288,9 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type) { + static u8 bssid_wildcard[ETH_ALEN] = { 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff }; + /* clear type-dependent union */ memset(&sdata->u, 0, sizeof(sdata->u)); @@ -1324,6 +1341,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; ieee80211_sta_setup_sdata(sdata); break; + case NL80211_IFTYPE_OCB: + sdata->vif.bss_conf.bssid = bssid_wildcard; + break; case NL80211_IFTYPE_ADHOC: sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; ieee80211_ibss_setup_sdata(sdata); @@ -1371,6 +1391,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: /* * Could maybe also all others here? * Just not sure how that interacts @@ -1386,6 +1407,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: /* * Could probably support everything * but WDS here (WDS do_open can fail diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c new file mode 100644 index 0000000..2dd9723 --- /dev/null +++ b/net/mac80211/ocb.c @@ -0,0 +1,22 @@ + /* OCB mode implementation + * Copyright 2014, Czech Technical University in Prague, Rostislav Lisovy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "ieee80211_i.h" + +int ieee80211_start_ocb(struct ieee80211_sub_if_data *sdata) +{ + u32 changed = BSS_CHANGED_BEACON_ENABLED; + + sdata->vif.bss_conf.enable_beacon = false; + ieee80211_bss_info_change_notify(sdata, changed); + + /* MORE TO BE DONE ... */ + + netif_carrier_on(sdata->dev); + return 0; +} diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7e0dd4b..bf4fd61 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1689,6 +1689,11 @@ int ieee80211_reconfig(struct ieee80211_local *local) ieee80211_bss_info_change_notify(sdata, changed); sdata_unlock(sdata); break; + case NL80211_IFTYPE_OCB: + changed |= BSS_CHANGED_IBSS | + BSS_CHANGED_BEACON_ENABLED; + ieee80211_bss_info_change_notify(sdata, changed); + break; case NL80211_IFTYPE_ADHOC: changed |= BSS_CHANGED_IBSS; /* fall through */ -- 2.0.0.rc4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html