Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v2 3/9] cfg80211: add add_nan_func / rm_nan_func
From: kbuild test robot @ 2016-09-16 10:46 UTC (permalink / raw)
  To: Luca Coelho
  Cc: kbuild-all, johannes, linux-wireless, Ayala Beker,
	Andrei Otcheretianski, Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-4-luca@coelho.fi>

[-- Attachment #1: Type: text/plain, Size: 7963 bytes --]

Hi Ayala,

[auto build test ERROR on mac80211-next/master]
[also build test ERROR on next-20160916]
[cannot apply to v4.8-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Luca-Coelho/Add-support-for-Neighbor-Awareness-Networking/20160916-164553
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
config: x86_64-lkp (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   net/wireless/nl80211.c: In function 'nl80211_nan_add_func':
>> net/wireless/nl80211.c:10588:30: error: implicit declaration of function 'genl_info_snd_portid' [-Werror=implicit-function-declaration]
         wdev->owner_nlportid != genl_info_snd_portid(info))
                                 ^~~~~~~~~~~~~~~~~~~~
>> net/wireless/nl80211.c:10785:6: error: implicit declaration of function 'nla_put_u64' [-Werror=implicit-function-declaration]
     if (nla_put_u64(msg, NL80211_ATTR_COOKIE, func->cookie))
         ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/genl_info_snd_portid +10588 net/wireless/nl80211.c

 10582			return -ENOTCONN;
 10583	
 10584		if (!info->attrs[NL80211_ATTR_NAN_FUNC])
 10585			return -EINVAL;
 10586	
 10587		if (wdev->owner_nlportid &&
 10588		    wdev->owner_nlportid != genl_info_snd_portid(info))
 10589			return -ENOTCONN;
 10590	
 10591		err = nla_parse(tb, NL80211_NAN_FUNC_ATTR_MAX,
 10592				nla_data(info->attrs[NL80211_ATTR_NAN_FUNC]),
 10593				nla_len(info->attrs[NL80211_ATTR_NAN_FUNC]),
 10594				nl80211_nan_func_policy);
 10595		if (err)
 10596			return err;
 10597	
 10598		func = kzalloc(sizeof(*func), GFP_KERNEL);
 10599		if (!func)
 10600			return -ENOMEM;
 10601	
 10602		func->cookie = wdev->wiphy->cookie_counter++;
 10603	
 10604		if (!tb[NL80211_NAN_FUNC_TYPE] ||
 10605		    nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
 10606			err = -EINVAL;
 10607			goto out;
 10608		}
 10609	
 10610	
 10611		func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
 10612	
 10613		if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
 10614			err = -EINVAL;
 10615			goto out;
 10616		}
 10617	
 10618		memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
 10619		       sizeof(func->service_id));
 10620	
 10621		func->close_range =
 10622			nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
 10623	
 10624		if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
 10625			func->serv_spec_info_len =
 10626				nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
 10627			func->serv_spec_info =
 10628				kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
 10629					func->serv_spec_info_len,
 10630					GFP_KERNEL);
 10631			if (!func->serv_spec_info) {
 10632				err = -ENOMEM;
 10633				goto out;
 10634			}
 10635		}
 10636	
 10637		if (tb[NL80211_NAN_FUNC_TTL])
 10638			func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
 10639	
 10640		switch (func->type) {
 10641		case NL80211_NAN_FUNC_PUBLISH:
 10642			if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
 10643				err = -EINVAL;
 10644				goto out;
 10645			}
 10646	
 10647			func->publish_type =
 10648				nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
 10649			func->publish_bcast =
 10650				nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
 10651	
 10652			if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
 10653				func->publish_bcast) {
 10654				err = -EINVAL;
 10655				goto out;
 10656			}
 10657			break;
 10658		case NL80211_NAN_FUNC_SUBSCRIBE:
 10659			func->subscribe_active =
 10660				nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
 10661			break;
 10662		case NL80211_NAN_FUNC_FOLLOW_UP:
 10663			if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
 10664			    !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) {
 10665				err = -EINVAL;
 10666				goto out;
 10667			}
 10668	
 10669			func->followup_id =
 10670				nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
 10671			func->followup_reqid =
 10672				nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
 10673			memcpy(func->followup_dest.addr,
 10674			       nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
 10675			       sizeof(func->followup_dest.addr));
 10676			if (func->ttl) {
 10677				err = -EINVAL;
 10678				goto out;
 10679			}
 10680			break;
 10681		default:
 10682			err = -EINVAL;
 10683			goto out;
 10684		}
 10685	
 10686		if (tb[NL80211_NAN_FUNC_SRF]) {
 10687			struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
 10688	
 10689			err = nla_parse(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
 10690					nla_data(tb[NL80211_NAN_FUNC_SRF]),
 10691					nla_len(tb[NL80211_NAN_FUNC_SRF]), NULL);
 10692			if (err)
 10693				goto out;
 10694	
 10695			func->srf_include =
 10696				nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
 10697	
 10698			if (srf_tb[NL80211_NAN_SRF_BF]) {
 10699				if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
 10700				    !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
 10701					err = -EINVAL;
 10702					goto out;
 10703				}
 10704	
 10705				func->srf_bf_len =
 10706					nla_len(srf_tb[NL80211_NAN_SRF_BF]);
 10707				func->srf_bf =
 10708					kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
 10709						func->srf_bf_len, GFP_KERNEL);
 10710				if (!func->srf_bf) {
 10711					err = -ENOMEM;
 10712					goto out;
 10713				}
 10714	
 10715				func->srf_bf_idx =
 10716					nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
 10717			} else {
 10718				struct nlattr *attr, *mac_attr =
 10719					srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
 10720				int n_entries, rem, i = 0;
 10721	
 10722				if (!mac_attr) {
 10723					err = -EINVAL;
 10724					goto out;
 10725				}
 10726	
 10727				n_entries = validate_acl_mac_addrs(mac_attr);
 10728				if (n_entries <= 0) {
 10729					err = -EINVAL;
 10730					goto out;
 10731				}
 10732	
 10733				func->srf_num_macs = n_entries;
 10734				func->srf_macs =
 10735					kzalloc(sizeof(*func->srf_macs) * n_entries,
 10736						GFP_KERNEL);
 10737				if (!func->srf_macs) {
 10738					err = -ENOMEM;
 10739					goto out;
 10740				}
 10741	
 10742				nla_for_each_nested(attr, mac_attr, rem)
 10743					memcpy(func->srf_macs[i++].addr, nla_data(attr),
 10744					       sizeof(*func->srf_macs));
 10745			}
 10746		}
 10747	
 10748		if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
 10749			err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
 10750						func, true);
 10751			if (err)
 10752				goto out;
 10753		}
 10754	
 10755		if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
 10756			err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
 10757						func, false);
 10758			if (err)
 10759				goto out;
 10760		}
 10761	
 10762		msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 10763		if (!msg) {
 10764			err = -ENOMEM;
 10765			goto out;
 10766		}
 10767	
 10768		hdr = nl80211hdr_put(msg, genl_info_snd_portid(info), info->snd_seq, 0,
 10769				     NL80211_CMD_ADD_NAN_FUNCTION);
 10770		/* This can't really happen - we just allocated 4KB */
 10771		if (WARN_ON(!hdr)) {
 10772			err = -ENOMEM;
 10773			goto out;
 10774		}
 10775	
 10776		err = rdev_add_nan_func(rdev, wdev, func);
 10777	out:
 10778		if (err < 0) {
 10779			cfg80211_free_nan_func(func);
 10780			nlmsg_free(msg);
 10781			return err;
 10782		}
 10783	
 10784		/* propagate the instance id and cookie to userspace  */
 10785		if (nla_put_u64(msg, NL80211_ATTR_COOKIE, func->cookie))
 10786			goto nla_put_failure;
 10787	
 10788		func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 23730 bytes --]

^ permalink raw reply

* Re: [PATCH v2 0/9] Add support for Neighbor Awareness Networking
From: Luca Coelho @ 2016-09-16 10:26 UTC (permalink / raw)
  To: Arend Van Spriel, johannes; +Cc: linux-wireless
In-Reply-To: <1055fff0-4eb0-08c5-2e16-a0b6f2887bda@broadcom.com>

On Fri, 2016-09-16 at 11:00 +0200, Arend Van Spriel wrote:
> On 16-9-2016 10:33, Luca Coelho wrote:
> > 
> > From: Luca Coelho <luciano.coelho@intel.com>
> > 
> > Hi,
> > 
> > This is v2 of the NAN patches that Emmanuel sent a while
> > back[1].  In
> > this version, we squashed some patches and took care of some
> > comments
> > after reviews (both internal and public).
> 
> Hi Luca,
> 
> You may have missed some as I think this should be v4.

Right... I saw those other ones, but they didn't have a cover-letter,
this series is sort of the v2 of "Add support for Neighbor Awareness
Networking".  Or something... :)

In any case, this new series should include all the changes done on the
way.

--
Luca.

^ permalink raw reply

* Re: brcmfmac MAC address change delay and 500ms down delay
From: Arend Van Spriel @ 2016-09-16  9:58 UTC (permalink / raw)
  To: Dan Williams, linux-wireless
In-Reply-To: <1473950537.25907.8.camel@redhat.com>

On 15-9-2016 16:42, Dan Williams wrote:
> Hi,
> 
> While refining NetworkManager's MAC address randomization behavior we
> came across two issues with brcmfmac:
> 
> 1) when changing the MAC address, the driver schedules work for the new
> change and returns success, but doesn't actually change the MAC until
> the work is scheduled.  Because it returns 0 from the
> ndo_set_mac_address hook the net core will generate a NETDEV_CHANGEADDR
> event and rtnetlink will send out an RTM_NEWLINK with the old MAC
> address.  No event for the new address will be sent.  So it's pretty
> hard to figure out when the address actually changed, and when its safe
> to associate, without polling the device's MAC address.  Ugly.

And apparently unnecessary. I recalled we had this as the
ndo_set_mac_address callback could be called in atomic context. So we
are using a worker because we are grabbing a mutex upon sending the
control info to the device. Looking into the core network code it seems
the callback is not called in atomic context so it seems we can get rid
of the worker here. I made a patch

> 2) when closing the device (eg, set !IFF_UP) the driver unconditionally
> blocks for 500ms in __brcmf_cfg80211_down():
> 
> 	if (check_vif_up(ifp->vif)) {
> 		brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
> 
> 		/* Make sure WPA_Supplicant receives all the event
> 		   generated due to DISASSOC call to the fw to keep
> 		   the state fw and WPA_Supplicant state consistent
> 		 */
> 		brcmf_delay(500);
> 	}

This is actually a bogus delay as we are under an RTNL lock here so I
think the events will not go out until after the delay has finished. I
did submit a patch long ago removing this delay, but the change was not
accepted. Let me revisit that.

> Should I dump these into kernel bugzilla, or is there some internal bug
> tracker they could get stuffed into?

Kernel bugzilla is fine although I check it rather infrequently.

Regards,
Arend

^ permalink raw reply

* [PATCH][V2] mwifiex: fix null pointer deference when adapter is null
From: Colin King @ 2016-09-16  9:37 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam, Kalle Valo, linux-wireless,
	netdev

From: Colin Ian King <colin.king@canonical.com>

If adapter is null the error exit path in mwifiex_shutdown_sw is
to down the semaphore sem and print some debug via mwifiex_dbg.
However, passing a NULL adapter to mwifiex_dbg causes a null
pointer deference when accessing adapter->dev.  This fix checks
for a null adapter at the start of the function and to exit
without the need to up the semaphore and we also skip the debug
to avoid the null pointer dereference.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/net/wireless/marvell/mwifiex/main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 9b2e98c..2478ccd 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1369,12 +1369,12 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter, struct semaphore *sem)
 	struct mwifiex_private *priv;
 	int i;
 
+	if (!adapter)
+		goto exit_return;
+
 	if (down_interruptible(sem))
 		goto exit_sem_err;
 
-	if (!adapter)
-		goto exit_remove;
-
 	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 	mwifiex_deauthenticate(priv, NULL);
 
@@ -1430,10 +1430,10 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter, struct semaphore *sem)
 		rtnl_unlock();
 	}
 
-exit_remove:
 	up(sem);
 exit_sem_err:
 	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
+exit_return:
 	return 0;
 }
 
-- 
2.7.4

^ permalink raw reply related

* Re: wireless.wiki.kernel.org: lingering status of http://linuxwireless.org/en/users/Drivers/wl12xx/calibrator/
From: Johannes Berg @ 2016-09-16  9:31 UTC (permalink / raw)
  To: Andreas Mohr; +Cc: linux-wireless
In-Reply-To: <20160915151437.GA24991@rhlx01.hs-esslingen.de>

Hi,

> since we are working with TI WL12xx hardware,
> I keep a reference on
> http://linuxwireless.org/en/users/Drivers/wl12xx/calibrator/ ,
> where it now says:
> "NOTE: this page is for archival only, see the note at the end of the
> page."
> "This is a static dump of the old wiki, taken after locking it in
> January 2015. The new wiki is at https://wireless.wiki.kernel.org/."

Indeed, we migrated the wiki to new infrastructure hosted on kernel.org
back then.

> Trying to find related information by searching for "calibrator" on
> https://wireless.wiki.kernel.org will yield
> https://wireless.wiki.kernel.org/en/developers/documentation/nl80211?
> s[]=calibrator where "wl12xx calibrator" is a *dead link*.
> The apparent underlying reason for this surfaces when going through
> the en ... users ... Drivers hierarchy to
> https://wireless.wiki.kernel.org/en/users/drivers/wl12xx
> where it says
> "
> For relicensing, the content of this page was removed.
> 
> The old website for now has a copy of the old content:
> 
> http://linuxwireless.sipsolutions.net/en/users/Drivers/wl12xx/·
> "

Right, so there were some people who couldn't be reached for
relicensing of their submissions under the license the new wiki
requires. The wl1251 and wl12xx pages were removed since I couldn't
reach Gery Kahn and Oz Krakowski, or they couldn't agree to
relicensing, I don't remember. I still have the Google spreadsheet that
tells me who it was though :-)

> Somehow I am not quite feeling entirely well with this status quo
> (I would expect that that content *will* get lost, and possibly
> rather sooner than later, since someone is bound to eventually say
> "the old site copy is not needed any more").

I have no intention of removing it, since it's a static HTML site and
has no maintenance overhead.

> So, are there some ways to improve the content situation,
> or will this job then eventually need to be done by last-ditch
> efforts (web.archive.org etc.)?

I can't side-step the licensing issue, so no. You can download and
store locally everything you need, I guess.

johannes

^ permalink raw reply

* Re: [PATCH v2 0/9] Add support for Neighbor Awareness Networking
From: Arend Van Spriel @ 2016-09-16  9:00 UTC (permalink / raw)
  To: Luca Coelho, johannes; +Cc: linux-wireless, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

On 16-9-2016 10:33, Luca Coelho wrote:
> From: Luca Coelho <luciano.coelho@intel.com>
> 
> Hi,
> 
> This is v2 of the NAN patches that Emmanuel sent a while back[1].  In
> this version, we squashed some patches and took care of some comments
> after reviews (both internal and public).

Hi Luca,

You may have missed some as I think this should be v4.

Regards,
Arend

[1]
http://mid.gmane.org/1458845547-28762-1-git-send-email-emmanuel.grumbach@intel.com

> NAN was described in the original post[2].
> 
> I hope they're good for merging now, because I'm tired of carrying
> this changes forward in our internal trees. :P
> 
> Nevertheless, comments are welcome, as always.
> 
> [1] http://mid.gmane.org/1456752313-5792-1-git-send-email-emmanuel.grumbach@intel.com
> [2] http://mid.gmane.org/1442500351-8780-1-git-send-email-andrei.otcheretianski@intel.com
> 
> Cheers,
> Luca.
> 
> 
> Ayala Beker (9):
>   cfg80211: add start / stop NAN commands
>   mac80211: add boilerplate code for start / stop NAN
>   cfg80211: add add_nan_func / rm_nan_func
>   cfg80211: allow the user space to change current NAN configuration
>   cfg80211: provide a function to report a match for NAN
>   cfg80211: Provide an API to report NAN function termination
>   mac80211: implement nan_change_conf
>   mac80211: Implement add_nan_func and rm_nan_func
>   mac80211: Add API to report NAN function match
> 
>  include/net/cfg80211.h       | 184 ++++++++++++-
>  include/net/mac80211.h       |  65 +++++
>  include/uapi/linux/nl80211.h | 258 +++++++++++++++++
>  net/mac80211/cfg.c           | 208 ++++++++++++++
>  net/mac80211/chan.c          |   6 +
>  net/mac80211/driver-ops.h    |  82 +++++-
>  net/mac80211/ieee80211_i.h   |  17 ++
>  net/mac80211/iface.c         |  28 +-
>  net/mac80211/main.c          |   8 +
>  net/mac80211/offchannel.c    |   4 +-
>  net/mac80211/rx.c            |   3 +
>  net/mac80211/trace.h         | 133 +++++++++
>  net/mac80211/util.c          |  50 +++-
>  net/wireless/chan.c          |   2 +
>  net/wireless/core.c          |  35 +++
>  net/wireless/core.h          |   3 +
>  net/wireless/mlme.c          |   1 +
>  net/wireless/nl80211.c       | 642 ++++++++++++++++++++++++++++++++++++++++++-
>  net/wireless/rdev-ops.h      |  58 ++++
>  net/wireless/trace.h         |  90 ++++++
>  net/wireless/util.c          |  28 +-
>  21 files changed, 1894 insertions(+), 11 deletions(-)
> 

^ permalink raw reply

* [PATCH v2 9/9] mac80211: Add API to report NAN function match
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

Provide an API to report NAN function match. Mac80211 will lookup the
corresponding cookie and report the match to cfg80211.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/mac80211.h | 16 ++++++++++++++++
 net/mac80211/cfg.c     | 25 +++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5b74229..1b6271e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5777,4 +5777,20 @@ void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,
 				   u8 inst_id,
 				   enum nl80211_nan_func_term_reason reason,
 				   gfp_t gfp);
+
+/**
+ * ieee80211_nan_func_match - notify about NAN function match event.
+ *
+ * This function is used to notify mac80211 about NAN function match. The
+ * cookie inside the match struct will be assigned by mac80211.
+ * Note that this function can't be called from hard irq.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @match: match event information
+ * @gfp: allocation flags
+ */
+void ieee80211_nan_func_match(struct ieee80211_vif *vif,
+			      struct cfg80211_nan_match_params *match,
+			      gfp_t gfp);
+
 #endif /* MAC80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index aee0e25c..20ac00f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3555,6 +3555,31 @@ void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,
 }
 EXPORT_SYMBOL(ieee80211_nan_func_terminated);
 
+void ieee80211_nan_func_match(struct ieee80211_vif *vif,
+			      struct cfg80211_nan_match_params *match,
+			      gfp_t gfp)
+{
+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+	struct cfg80211_nan_func *func;
+
+	if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
+		return;
+
+	spin_lock_bh(&sdata->u.nan.func_lock);
+
+	func = idr_find(&sdata->u.nan.function_inst_ids,  match->inst_id);
+	if (WARN_ON(!func)) {
+		spin_unlock_bh(&sdata->u.nan.func_lock);
+		return;
+	}
+	match->cookie = func->cookie;
+
+	spin_unlock_bh(&sdata->u.nan.func_lock);
+
+	cfg80211_nan_match(ieee80211_vif_to_wdev(vif), match, gfp);
+}
+EXPORT_SYMBOL(ieee80211_nan_func_match);
+
 const struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 8/9] mac80211: Implement add_nan_func and rm_nan_func
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

Implement add/rm_nan_func functions and handle NAN function
termination notifications. Handle instance_id allocation for
NAN functions and implement the reconfig flow.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/mac80211.h     |  31 ++++++++++++
 net/mac80211/cfg.c         | 114 +++++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/driver-ops.h  |  32 +++++++++++++
 net/mac80211/ieee80211_i.h |   7 +++
 net/mac80211/iface.c       |  20 +++++++-
 net/mac80211/main.c        |   3 ++
 net/mac80211/trace.h       |  52 +++++++++++++++++++++
 net/mac80211/util.c        |  48 ++++++++++++++++++-
 8 files changed, 304 insertions(+), 3 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ef8d02a..5b74229 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2177,6 +2177,8 @@ enum ieee80211_hw_flags {
  * @n_cipher_schemes: a size of an array of cipher schemes definitions.
  * @cipher_schemes: a pointer to an array of cipher scheme definitions
  *	supported by HW.
+ * @max_nan_de_entries: maximum number of NAN DE functions supported by the
+ *	device.
  */
 struct ieee80211_hw {
 	struct ieee80211_conf conf;
@@ -2211,6 +2213,7 @@ struct ieee80211_hw {
 	u8 uapsd_max_sp_len;
 	u8 n_cipher_schemes;
 	const struct ieee80211_cipher_scheme *cipher_schemes;
+	u8 max_nan_de_entries;
 };
 
 static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
@@ -3429,6 +3432,12 @@ enum ieee80211_reconfig_type {
  *	The driver gets both full configuration and the changed parameters since
  *	some devices may need the full configuration while others need only the
  *	changed parameters.
+ * @add_nan_func: Add a NAN function. Returns 0 on success. The data in
+ *	cfg80211_nan_func must not be referenced outside the scope of
+ *	this call.
+ * @rm_nan_func: Remove a NAN function. The driver must call
+ *	ieee80211_nan_func_terminated() with
+ *	NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST reason code upon removal.
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw,
@@ -3673,6 +3682,12 @@ struct ieee80211_ops {
 	int (*nan_change_conf)(struct ieee80211_hw *hw,
 			       struct ieee80211_vif *vif,
 			       struct cfg80211_nan_conf *conf, u32 changes);
+	int (*add_nan_func)(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    const struct cfg80211_nan_func *nan_func);
+	void (*rm_nan_func)(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    u8 instance_id);
 };
 
 /**
@@ -5746,4 +5761,20 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
 			     unsigned long *frame_cnt,
 			     unsigned long *byte_cnt);
+
+/**
+ * ieee80211_nan_func_terminated - notify about NAN function termination.
+ *
+ * This function is used to notify mac80211 about NAN function termination.
+ * Note that this function can't be called from hard irq.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @inst_id: the local instance id
+ * @reason: termination reason (one of the NL80211_NAN_FUNC_TERM_REASON_*)
+ * @gfp: allocation flags
+ */
+void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,
+				   u8 inst_id,
+				   enum nl80211_nan_func_term_reason reason,
+				   gfp_t gfp);
 #endif /* MAC80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 38fdb53..aee0e25c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -174,6 +174,8 @@ static int ieee80211_start_nan(struct wiphy *wiphy,
 	if (ret)
 		ieee80211_sdata_stop(sdata);
 
+	sdata->u.nan.conf = *conf;
+
 	return ret;
 }
 
@@ -216,6 +218,84 @@ static int ieee80211_nan_change_conf(struct wiphy *wiphy,
 	return ret;
 }
 
+static int ieee80211_add_nan_func(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  struct cfg80211_nan_func *nan_func)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+	int ret;
+
+	if (sdata->vif.type != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (!ieee80211_sdata_running(sdata))
+		return -ENETDOWN;
+
+	spin_lock_bh(&sdata->u.nan.func_lock);
+
+	ret = idr_alloc(&sdata->u.nan.function_inst_ids,
+			nan_func, 1, sdata->local->hw.max_nan_de_entries + 1,
+			GFP_ATOMIC);
+	spin_unlock_bh(&sdata->u.nan.func_lock);
+
+	if (ret < 0)
+		return ret;
+
+	nan_func->instance_id = ret;
+
+	WARN_ON(nan_func->instance_id == 0);
+
+	ret = drv_add_nan_func(sdata->local, sdata, nan_func);
+	if (ret) {
+		spin_lock_bh(&sdata->u.nan.func_lock);
+		idr_remove(&sdata->u.nan.function_inst_ids,
+			   nan_func->instance_id);
+		spin_unlock_bh(&sdata->u.nan.func_lock);
+	}
+
+	return ret;
+}
+
+static struct cfg80211_nan_func *
+ieee80211_find_nan_func_by_cookie(struct ieee80211_sub_if_data *sdata,
+				  u64 cookie)
+{
+	struct cfg80211_nan_func *func;
+	int id;
+
+	lockdep_assert_held(&sdata->u.nan.func_lock);
+
+	idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id) {
+		if (func->cookie == cookie)
+			return func;
+	}
+
+	return NULL;
+}
+
+static void ieee80211_rm_nan_func(struct wiphy *wiphy,
+				  struct wireless_dev *wdev, u64 cookie)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+	struct cfg80211_nan_func *func;
+	u8 instance_id = 0;
+
+	if (sdata->vif.type != NL80211_IFTYPE_NAN ||
+	    !ieee80211_sdata_running(sdata))
+		return;
+
+	spin_lock_bh(&sdata->u.nan.func_lock);
+
+	func = ieee80211_find_nan_func_by_cookie(sdata, cookie);
+	if (func)
+		instance_id = func->instance_id;
+
+	spin_unlock_bh(&sdata->u.nan.func_lock);
+
+	if (instance_id)
+		drv_rm_nan_func(sdata->local, sdata, instance_id);
+}
+
 static int ieee80211_set_noack_map(struct wiphy *wiphy,
 				  struct net_device *dev,
 				  u16 noack_map)
@@ -3443,6 +3523,38 @@ static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
 	return -ENOENT;
 }
 
+void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,
+				   u8 inst_id,
+				   enum nl80211_nan_func_term_reason reason,
+				   gfp_t gfp)
+{
+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+	struct cfg80211_nan_func *func;
+	u64 cookie;
+
+	if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
+		return;
+
+	spin_lock_bh(&sdata->u.nan.func_lock);
+
+	func = idr_find(&sdata->u.nan.function_inst_ids, inst_id);
+	if (WARN_ON(!func)) {
+		spin_unlock_bh(&sdata->u.nan.func_lock);
+		return;
+	}
+
+	cookie = func->cookie;
+	idr_remove(&sdata->u.nan.function_inst_ids, inst_id);
+
+	spin_unlock_bh(&sdata->u.nan.func_lock);
+
+	cfg80211_free_nan_func(func);
+
+	cfg80211_nan_func_terminated(ieee80211_vif_to_wdev(vif), inst_id,
+				     reason, cookie, gfp);
+}
+EXPORT_SYMBOL(ieee80211_nan_func_terminated);
+
 const struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -3531,4 +3643,6 @@ const struct cfg80211_ops mac80211_config_ops = {
 	.start_nan = ieee80211_start_nan,
 	.stop_nan = ieee80211_stop_nan,
 	.nan_change_conf = ieee80211_nan_change_conf,
+	.add_nan_func = ieee80211_add_nan_func,
+	.rm_nan_func = ieee80211_rm_nan_func,
 };
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 50aeb3a..ff1066b 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1213,4 +1213,36 @@ static inline int drv_nan_change_conf(struct ieee80211_local *local,
 	return ret;
 }
 
+static inline int drv_add_nan_func(struct ieee80211_local *local,
+				   struct ieee80211_sub_if_data *sdata,
+				   const struct cfg80211_nan_func *nan_func)
+{
+	int ret;
+
+	might_sleep();
+	check_sdata_in_driver(sdata);
+
+	if (!local->ops->add_nan_func)
+		return -EOPNOTSUPP;
+
+	trace_drv_add_nan_func(local, sdata, nan_func);
+	ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
+	trace_drv_return_int(local, ret);
+
+	return ret;
+}
+
+static inline void drv_rm_nan_func(struct ieee80211_local *local,
+				   struct ieee80211_sub_if_data *sdata,
+				   u8 instance_id)
+{
+	might_sleep();
+	check_sdata_in_driver(sdata);
+
+	trace_drv_rm_nan_func(local, sdata, instance_id);
+	if (local->ops->rm_nan_func)
+		local->ops->rm_nan_func(&local->hw, &sdata->vif, instance_id);
+	trace_drv_return_void(local);
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 712b20b..2b391f2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -86,6 +86,8 @@ struct ieee80211_local;
 
 #define IEEE80211_DEAUTH_FRAME_LEN	(24 /* hdr */ + 2 /* reason */)
 
+#define IEEE80211_MAX_NAN_INSTANCE_ID 255
+
 struct ieee80211_fragment_entry {
 	struct sk_buff_head skb_list;
 	unsigned long first_frag_time;
@@ -834,9 +836,14 @@ struct ieee80211_if_mntr {
  * struct ieee80211_if_nan - NAN state
  *
  * @conf: current NAN configuration
+ * @func_ids: a bitmap of available instance_id's
  */
 struct ieee80211_if_nan {
 	struct cfg80211_nan_conf conf;
+
+	/* protects function_inst_ids */
+	spinlock_t func_lock;
+	struct idr function_inst_ids;
 };
 
 struct ieee80211_sub_if_data {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 507f46a..638ec07 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -798,6 +798,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 	struct ps_data *ps;
 	struct cfg80211_chan_def chandef;
 	bool cancel_scan;
+	struct cfg80211_nan_func *func;
 
 	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
@@ -950,11 +951,22 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
 		ieee80211_adjust_monitor_flags(sdata, -1);
 		break;
+	case NL80211_IFTYPE_NAN:
+		/* clean all the functions */
+		spin_lock_bh(&sdata->u.nan.func_lock);
+
+		idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) {
+			idr_remove(&sdata->u.nan.function_inst_ids, i);
+			cfg80211_free_nan_func(func);
+		}
+		idr_destroy(&sdata->u.nan.function_inst_ids);
+
+		spin_unlock_bh(&sdata->u.nan.func_lock);
+		break;
 	case NL80211_IFTYPE_P2P_DEVICE:
 		/* relies on synchronize_rcu() below */
 		RCU_INIT_POINTER(local->p2p_sdata, NULL);
 		/* fall through */
-	case NL80211_IFTYPE_NAN:
 	default:
 		cancel_work_sync(&sdata->work);
 		/*
@@ -1462,9 +1474,13 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
 	case NL80211_IFTYPE_WDS:
 		sdata->vif.bss_conf.bssid = NULL;
 		break;
+	case NL80211_IFTYPE_NAN:
+		idr_init(&sdata->u.nan.function_inst_ids);
+		spin_lock_init(&sdata->u.nan.func_lock);
+		sdata->vif.bss_conf.bssid = sdata->vif.addr;
+		break;
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_P2P_DEVICE:
-	case NL80211_IFTYPE_NAN:
 		sdata->vif.bss_conf.bssid = sdata->vif.addr;
 		break;
 	case NL80211_IFTYPE_UNSPECIFIED:
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b5cf2c5..1075ac2 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1063,6 +1063,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
 	local->dynamic_ps_forced_timeout = -1;
 
+	if (!local->hw.max_nan_de_entries)
+		local->hw.max_nan_de_entries = IEEE80211_MAX_NAN_INSTANCE_ID;
+
 	result = ieee80211_wep_init(local);
 	if (result < 0)
 		wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 0bafe11..e6bed8a 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1781,6 +1781,58 @@ TRACE_EVENT(drv_nan_change_conf,
 	)
 );
 
+TRACE_EVENT(drv_add_nan_func,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 const struct cfg80211_nan_func *func),
+
+	TP_ARGS(local, sdata, func),
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(u8, type)
+		__field(u8, inst_id)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->type = func->type;
+		__entry->inst_id = func->instance_id;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT
+		", type: %u, inst_id: %u",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->type, __entry->inst_id
+	)
+);
+
+TRACE_EVENT(drv_rm_nan_func,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 u8 instance_id),
+
+	TP_ARGS(local, sdata, instance_id),
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(u8, instance_id)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->instance_id = instance_id;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT
+		", instance_id: %u",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->instance_id
+	)
+);
+
 /*
  * Tracing for API calls that drivers call.
  */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5b57fca..91754c8 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1749,6 +1749,46 @@ static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
 	mutex_unlock(&local->sta_mtx);
 }
 
+static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)
+{
+	struct cfg80211_nan_func *func, **funcs;
+	int res, id, i = 0;
+
+	res = drv_start_nan(sdata->local, sdata,
+			    &sdata->u.nan.conf);
+	if (WARN_ON(res))
+		return res;
+
+	funcs = kzalloc((sdata->local->hw.max_nan_de_entries + 1) *
+			sizeof(*funcs), GFP_KERNEL);
+	if (!funcs)
+		return -ENOMEM;
+
+	/* Add all the functions:
+	 * This is a little bit ugly. We need to call a potentially sleeping
+	 * callback for each NAN function, so we can't hold the spinlock.
+	 */
+	spin_lock_bh(&sdata->u.nan.func_lock);
+
+	idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id)
+		funcs[i++] = func;
+
+	spin_unlock_bh(&sdata->u.nan.func_lock);
+
+	for (i = 0; funcs[i]; i++) {
+		res = drv_add_nan_func(sdata->local, sdata, funcs[i]);
+		if (WARN_ON(res))
+			ieee80211_nan_func_terminated(&sdata->vif,
+						      funcs[i]->instance_id,
+						      NL80211_NAN_FUNC_TERM_REASON_ERROR,
+						      GFP_KERNEL);
+	}
+
+	kfree(funcs);
+
+	return 0;
+}
+
 int ieee80211_reconfig(struct ieee80211_local *local)
 {
 	struct ieee80211_hw *hw = &local->hw;
@@ -1972,11 +2012,17 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 				ieee80211_bss_info_change_notify(sdata, changed);
 			}
 			break;
+		case NL80211_IFTYPE_NAN:
+			res = ieee80211_reconfig_nan(sdata);
+			if (res < 0) {
+				ieee80211_handle_reconfig_failure(local);
+				return res;
+			}
+			break;
 		case NL80211_IFTYPE_WDS:
 		case NL80211_IFTYPE_AP_VLAN:
 		case NL80211_IFTYPE_MONITOR:
 		case NL80211_IFTYPE_P2P_DEVICE:
-		case NL80211_IFTYPE_NAN:
 			/* nothing to do */
 			break;
 		case NL80211_IFTYPE_UNSPECIFIED:
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 7/9] mac80211: implement nan_change_conf
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

Implement nan_change_conf callback which allows to change current
NAN configuration (master preference and dual band operation).
Store the current NAN configuration in sdata, so it can be used
both to provide the driver the updated configuration with changes
and also it will be used in hw reconfig flows in next patches.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/mac80211.h     |  9 +++++++++
 net/mac80211/cfg.c         | 31 +++++++++++++++++++++++++++++++
 net/mac80211/driver-ops.h  | 21 +++++++++++++++++++++
 net/mac80211/ieee80211_i.h | 10 ++++++++++
 net/mac80211/trace.h       | 31 +++++++++++++++++++++++++++++++
 5 files changed, 102 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index df9b5cf..ef8d02a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3423,6 +3423,12 @@ enum ieee80211_reconfig_type {
  *
  * @start_nan: join an existing NAN cluster, or create a new one.
  * @stop_nan: leave the NAN cluster.
+ * @nan_change_conf: change NAN configuration. The data in cfg80211_nan_conf
+ *	contains full new configuration and changes specify which parameters
+ *	are changed with respect to the last NAN config.
+ *	The driver gets both full configuration and the changed parameters since
+ *	some devices may need the full configuration while others need only the
+ *	changed parameters.
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw,
@@ -3664,6 +3670,9 @@ struct ieee80211_ops {
 			 struct cfg80211_nan_conf *conf);
 	int (*stop_nan)(struct ieee80211_hw *hw,
 			struct ieee80211_vif *vif);
+	int (*nan_change_conf)(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
+			       struct cfg80211_nan_conf *conf, u32 changes);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9aabb09..38fdb53 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -186,6 +186,36 @@ static void ieee80211_stop_nan(struct wiphy *wiphy,
 	ieee80211_sdata_stop(sdata);
 }
 
+static int ieee80211_nan_change_conf(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     struct cfg80211_nan_conf *conf,
+				     u32 changes)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+	struct cfg80211_nan_conf new_conf;
+	int ret = 0;
+
+	if (sdata->vif.type != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (!ieee80211_sdata_running(sdata))
+		return -ENETDOWN;
+
+	new_conf = sdata->u.nan.conf;
+
+	if (changes & CFG80211_NAN_CONF_CHANGED_PREF)
+		new_conf.master_pref = conf->master_pref;
+
+	if (changes & CFG80211_NAN_CONF_CHANGED_DUAL)
+		new_conf.dual = conf->dual;
+
+	ret = drv_nan_change_conf(sdata->local, sdata, &new_conf, changes);
+	if (!ret)
+		sdata->u.nan.conf = new_conf;
+
+	return ret;
+}
+
 static int ieee80211_set_noack_map(struct wiphy *wiphy,
 				  struct net_device *dev,
 				  u16 noack_map)
@@ -3500,4 +3530,5 @@ const struct cfg80211_ops mac80211_config_ops = {
 	.del_tx_ts = ieee80211_del_tx_ts,
 	.start_nan = ieee80211_start_nan,
 	.stop_nan = ieee80211_stop_nan,
+	.nan_change_conf = ieee80211_nan_change_conf,
 };
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 67b42c8..50aeb3a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1192,4 +1192,25 @@ static inline void drv_stop_nan(struct ieee80211_local *local,
 	trace_drv_return_void(local);
 }
 
+static inline int drv_nan_change_conf(struct ieee80211_local *local,
+				       struct ieee80211_sub_if_data *sdata,
+				       struct cfg80211_nan_conf *conf,
+				       u32 changes)
+{
+	int ret;
+
+	might_sleep();
+	check_sdata_in_driver(sdata);
+
+	if (!local->ops->nan_change_conf)
+		return -EOPNOTSUPP;
+
+	trace_drv_nan_change_conf(local, sdata, conf, changes);
+	ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
+					  changes);
+	trace_drv_return_int(local, ret);
+
+	return ret;
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c71c735..712b20b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -830,6 +830,15 @@ struct ieee80211_if_mntr {
 	u8 mu_follow_addr[ETH_ALEN] __aligned(2);
 };
 
+/**
+ * struct ieee80211_if_nan - NAN state
+ *
+ * @conf: current NAN configuration
+ */
+struct ieee80211_if_nan {
+	struct cfg80211_nan_conf conf;
+};
+
 struct ieee80211_sub_if_data {
 	struct list_head list;
 
@@ -929,6 +938,7 @@ struct ieee80211_sub_if_data {
 		struct ieee80211_if_mesh mesh;
 		struct ieee80211_if_ocb ocb;
 		struct ieee80211_if_mntr mntr;
+		struct ieee80211_if_nan nan;
 	} u;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index deefbfb..0bafe11 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1750,6 +1750,37 @@ TRACE_EVENT(drv_stop_nan,
 	)
 );
 
+TRACE_EVENT(drv_nan_change_conf,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 struct cfg80211_nan_conf *conf,
+		 u32 changes),
+
+	TP_ARGS(local, sdata, conf, changes),
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(u8, master_pref)
+		__field(u8, dual)
+		__field(u32, changes)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->master_pref = conf->master_pref;
+		__entry->dual = conf->dual;
+		__entry->changes = changes;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT
+		", master preference: %u, dual: %d, changes: 0x%x",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->master_pref,
+		__entry->dual, __entry->changes
+	)
+);
+
 /*
  * Tracing for API calls that drivers call.
  */
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 6/9] cfg80211: Provide an API to report NAN function termination
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

Provide a function that reports NAN DE function termination. The function
may be terminated due to one of the following reasons: user request,
ttl expiration or failure.
If the NAN instance is tied to the owner, the notification will be
sent to the socket that started the NAN interface only

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/cfg80211.h       | 16 ++++++++++++
 include/uapi/linux/nl80211.h | 15 ++++++++++++
 net/wireless/nl80211.c       | 58 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a08d7da..81770d6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5676,6 +5676,22 @@ struct cfg80211_nan_match_params {
 void cfg80211_nan_match(struct wireless_dev *wdev,
 			struct cfg80211_nan_match_params *match, gfp_t gfp);
 
+/**
+ * cfg80211_nan_func_terminated - notify about NAN function termination.
+ *
+ * @wdev: the wireless device reporting the match
+ * @inst_id: the local instance id
+ * @reason: termination reason (one of the NL80211_NAN_FUNC_TERM_REASON_*)
+ * @cookie: unique NAN function identifier
+ * @gfp: allocation flags
+ *
+ * This function reports that the a NAN function is terminated.
+ */
+void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
+				  u8 inst_id,
+				  enum nl80211_nan_func_term_reason reason,
+				  u64 cookie, gfp_t gfp);
+
 /* ethtool helper */
 void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index badb4a6..fd86be6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4978,6 +4978,21 @@ enum nl80211_nan_publish_type {
 	NL80211_NAN_UNSOLICITED_PUBLISH = 1 << 1,
 };
 
+/**
+ * enum nl80211_nan_func_term_reason - NAN functions termination reason
+ *
+ * Defines termination reasons of a NAN function
+ *
+ * @NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST: requested by user
+ * @NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED: timeout
+ * @NL80211_NAN_FUNC_TERM_REASON_ERROR: errored
+ */
+enum nl80211_nan_func_term_reason {
+	NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST,
+	NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED,
+	NL80211_NAN_FUNC_TERM_REASON_ERROR,
+};
+
 #define NL80211_NAN_FUNC_SERVICE_ID_LEN 6
 #define NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN 0xff
 #define NL80211_NAN_FUNC_SRF_MAX_LEN 0xff
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4d37717..f817105 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10945,6 +10945,64 @@ nla_put_failure:
 }
 EXPORT_SYMBOL(cfg80211_nan_match);
 
+void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
+				  u8 inst_id,
+				  enum nl80211_nan_func_term_reason reason,
+				  u64 cookie, gfp_t gfp)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct sk_buff *msg;
+	struct nlattr *func_attr;
+	void *hdr;
+
+	if (WARN_ON(!inst_id))
+		return;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RM_NAN_FUNCTION);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
+					 wdev->netdev->ifindex)) ||
+	    nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+		goto nla_put_failure;
+
+	if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+		goto nla_put_failure;
+
+	func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
+	if (!func_attr)
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
+	    nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
+		goto nla_put_failure;
+
+	nla_nest_end(msg, func_attr);
+	genlmsg_end(msg, hdr);
+
+	if (!wdev->owner_nlportid)
+		genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
+					msg, 0, NL80211_MCGRP_NAN, gfp);
+	else
+		genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
+				wdev->owner_nlportid);
+
+	return;
+
+nla_put_failure:
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_func_terminated);
+
 static int nl80211_get_protocol_features(struct sk_buff *skb,
 					 struct genl_info *info)
 {
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 5/9] cfg80211: provide a function to report a match for NAN
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

Provide a function the driver can call to report a match.
This will send the event to the user space.
If the NAN instance is tied to the owner, the notifications will be
sent to the socket that started the NAN interface only.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/cfg80211.h       | 37 +++++++++++++++++++++
 include/uapi/linux/nl80211.h | 31 ++++++++++++++++++
 net/wireless/nl80211.c       | 78 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 146 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b819e32..a08d7da 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5639,6 +5639,43 @@ wiphy_ext_feature_isset(struct wiphy *wiphy,
  */
 void cfg80211_free_nan_func(struct cfg80211_nan_func *f);
 
+/**
+ * struct cfg80211_nan_match_params - NAN match parameters
+ * @type: the type of the function that triggered a match. If it is
+ *	 %NL80211_NAN_FUNC_SUBSCRIBE it means that we replied to a subscriber.
+ *	 If it is %NL80211_NAN_FUNC_PUBLISH, it means that we got a discovery
+ *	 result.
+ *	 If it is %NL80211_NAN_FUNC_FOLLOW_UP, we received a follow up.
+ * @inst_id: the local instance id
+ * @peer_inst_id: the instance id of the peer's function
+ * @addr: the MAC address of the peer
+ * @info_len: the length of the &info
+ * @info: the Service Specific Info from the peer (if any)
+ * @cookie: unique identifier of the corresponding function
+ */
+struct cfg80211_nan_match_params {
+	enum nl80211_nan_function_type type;
+	u8 inst_id;
+	u8 peer_inst_id;
+	const u8 *addr;
+	u8 info_len;
+	const u8 *info;
+	u64 cookie;
+};
+
+/**
+ * cfg80211_nan_match - report a match for a NAN function.
+ * @wdev: the wireless device reporting the match
+ * @match: match notification parameters
+ * @gfp: allocation flags
+ *
+ * This function reports that the a NAN function had a match. This
+ * can be a subscribe that had a match or a solicited publish that
+ * was sent. It can also be a follow up that was received.
+ */
+void cfg80211_nan_match(struct wireless_dev *wdev,
+			struct cfg80211_nan_match_params *match, gfp_t gfp);
+
 /* ethtool helper */
 void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9cf1744..badb4a6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -48,6 +48,7 @@
 #define NL80211_MULTICAST_GROUP_REG		"regulatory"
 #define NL80211_MULTICAST_GROUP_MLME		"mlme"
 #define NL80211_MULTICAST_GROUP_VENDOR		"vendor"
+#define NL80211_MULTICAST_GROUP_NAN		"nan"
 #define NL80211_MULTICAST_GROUP_TESTMODE	"testmode"
 
 /**
@@ -869,6 +870,9 @@
  *	must be operational (%NL80211_CMD_START_NAN was executed).
  *	It must contain at least one of the following attributes:
  *	%NL80211_ATTR_NAN_MASTER_PREF, %NL80211_ATTR_NAN_DUAL.
+ * @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported.
+ *	This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
+ *	%NL80211_ATTR_COOKIE.
  *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
@@ -1063,6 +1067,7 @@ enum nl80211_commands {
 	NL80211_CMD_ADD_NAN_FUNCTION,
 	NL80211_CMD_RM_NAN_FUNCTION,
 	NL80211_CMD_CHANGE_NAN_CONFIG,
+	NL80211_CMD_NAN_MATCH,
 
 	/* add new commands above here */
 
@@ -1923,6 +1928,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See
  *	&enum nl80211_nan_func_attributes for description of this nested
  *	attribute.
+ * @NL80211_ATTR_NAN_MATCH: used to report a match. This is a nested attribute.
+ *	See &enum nl80211_nan_match_attributes.
  *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -2321,6 +2328,7 @@ enum nl80211_attrs {
 	NL80211_ATTR_NAN_MASTER_PREF,
 	NL80211_ATTR_NAN_DUAL,
 	NL80211_ATTR_NAN_FUNC,
+	NL80211_ATTR_NAN_MATCH,
 
 	/* add attributes here, update the policy in nl80211.c */
 
@@ -5067,4 +5075,27 @@ enum nl80211_nan_srf_attributes {
 	NL80211_NAN_SRF_ATTR_MAX = NUM_NL80211_NAN_SRF_ATTR - 1,
 };
 
+/**
+ * enum nl80211_nan_match_attributes - NAN match attributes
+ * @__NL80211_NAN_MATCH_INVALID: invalid
+ * @NL80211_NAN_MATCH_FUNC_LOCAL: the local function that had the
+ *	match. This is a nested attribute.
+ *	See &enum nl80211_nan_func_attributes.
+ * @NL80211_NAN_MATCH_FUNC_PEER: the peer function
+ *	that caused the match. This is a nested attribute.
+ *	See &enum nl80211_nan_func_attributes.
+ *
+ * @NUM_NL80211_NAN_MATCH_ATTR: internal
+ * @NL80211_NAN_MATCH_ATTR_MAX: highest NAN match attribute
+ */
+enum nl80211_nan_match_attributes {
+	__NL80211_NAN_MATCH_INVALID,
+	NL80211_NAN_MATCH_FUNC_LOCAL,
+	NL80211_NAN_MATCH_FUNC_PEER,
+
+	/* keep last */
+	NUM_NL80211_NAN_MATCH_ATTR,
+	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d627527..4d37717 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -56,6 +56,7 @@ enum nl80211_multicast_groups {
 	NL80211_MCGRP_REGULATORY,
 	NL80211_MCGRP_MLME,
 	NL80211_MCGRP_VENDOR,
+	NL80211_MCGRP_NAN,
 	NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
 };
 
@@ -65,6 +66,7 @@ static const struct genl_multicast_group nl80211_mcgrps[] = {
 	[NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
 	[NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
 	[NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
+	[NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
 #ifdef CONFIG_NL80211_TESTMODE
 	[NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
 #endif
@@ -10867,6 +10869,82 @@ static int nl80211_nan_change_config(struct sk_buff *skb,
 	return rdev_nan_change_conf(rdev, wdev, &conf, changed);
 }
 
+void cfg80211_nan_match(struct wireless_dev *wdev,
+			struct cfg80211_nan_match_params *match, gfp_t gfp)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
+	struct sk_buff *msg;
+	void *hdr;
+
+	if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
+		return;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
+					 wdev->netdev->ifindex)) ||
+	    nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+		goto nla_put_failure;
+
+	if (nla_put_u64(msg, NL80211_ATTR_COOKIE, match->cookie) ||
+	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
+		goto nla_put_failure;
+
+	match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
+	if (!match_attr)
+		goto nla_put_failure;
+
+	local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
+	if (!local_func_attr)
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
+		goto nla_put_failure;
+
+	nla_nest_end(msg, local_func_attr);
+
+	peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
+	if (!peer_func_attr)
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
+	    nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
+		goto nla_put_failure;
+
+	if (match->info && match->info_len &&
+	    nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
+		    match->info))
+		goto nla_put_failure;
+
+	nla_nest_end(msg, peer_func_attr);
+	nla_nest_end(msg, match_attr);
+	genlmsg_end(msg, hdr);
+
+	if (!wdev->owner_nlportid)
+		genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
+					msg, 0, NL80211_MCGRP_NAN, gfp);
+	else
+		genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
+				wdev->owner_nlportid);
+
+	return;
+
+nla_put_failure:
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_match);
+
 static int nl80211_get_protocol_features(struct sk_buff *skb,
 					 struct genl_info *info)
 {
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 4/9] cfg80211: allow the user space to change current NAN configuration
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

Some NAN configuration paramaters may change during the operation of
the NaN device. For example, a user may want to update master preference
value when the device gets plugged/unplugged to the power.
Add API that allows to do so.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/cfg80211.h       | 19 +++++++++++++++++++
 include/uapi/linux/nl80211.h | 11 +++++++++--
 net/wireless/nl80211.c       | 45 ++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/rdev-ops.h      | 17 +++++++++++++++++
 net/wireless/trace.h         | 24 +++++++++++++++++++++++
 5 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ced5b8a..b819e32 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2306,6 +2306,18 @@ struct cfg80211_nan_conf {
 };
 
 /**
+ * enum cfg80211_nan_conf_changes - indicates changed fields in NAN
+ * configuration
+ *
+ * @CFG80211_NAN_CONF_CHANGED_PREF: master preference
+ * @CFG80211_NAN_CONF_CHANGED_DUAL: dual band operation
+ */
+enum cfg80211_nan_conf_changes {
+	CFG80211_NAN_CONF_CHANGED_PREF = BIT(0),
+	CFG80211_NAN_CONF_CHANGED_DUAL = BIT(1),
+};
+
+/**
  * struct cfg80211_nan_func_filter - a NAN function Rx / Tx filter
  *
  * @filter: the content of the filter
@@ -2670,6 +2682,9 @@ struct cfg80211_nan_func {
  *	On success the driver should assign an instance_id in the
  *	provided @nan_func.
  * @rm_nan_func: Remove a NAN function.
+ * @nan_change_conf: changes NAN configuration. The changed parameters must
+ *	be specified in @changes (using &enum cfg80211_nan_conf_changes);
+ *	All other parameters must be ignored.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2942,6 +2957,10 @@ struct cfg80211_ops {
 				struct cfg80211_nan_func *nan_func);
 	void	(*rm_nan_func)(struct wiphy *wiphy, struct wireless_dev *wdev,
 			       u64 cookie);
+	int	(*nan_change_conf)(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   struct cfg80211_nan_conf *conf,
+				   u32 changes);
 };
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ab16c8e..9cf1744 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -865,6 +865,10 @@
  *	This command is also used as a notification sent when a NAN function is
  *	terminated. This will contain a %NL80211_ATTR_NAN_FUNC_INST_ID
  *	and %NL80211_ATTR_COOKIE attributes.
+ * @NL80211_CMD_CHANGE_NAN_CONFIG: Change current NAN configuration. NAN
+ *	must be operational (%NL80211_CMD_START_NAN was executed).
+ *	It must contain at least one of the following attributes:
+ *	%NL80211_ATTR_NAN_MASTER_PREF, %NL80211_ATTR_NAN_DUAL.
  *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
@@ -1058,6 +1062,7 @@ enum nl80211_commands {
 	NL80211_CMD_STOP_NAN,
 	NL80211_CMD_ADD_NAN_FUNCTION,
 	NL80211_CMD_RM_NAN_FUNCTION,
+	NL80211_CMD_CHANGE_NAN_CONFIG,
 
 	/* add new commands above here */
 
@@ -1907,12 +1912,14 @@ enum nl80211_commands {
  *	used to pull the stored data for mesh peer in power save state.
  *
  * @NL80211_ATTR_NAN_MASTER_PREF: the master preference to be used by
- *	%NL80211_CMD_START_NAN. Its type is u8 and it can't be 0.
+ *	%NL80211_CMD_START_NAN and optionally with
+ *	%NL80211_CMD_CHANGE_NAN_CONFIG. Its type is u8 and it can't be 0.
  *	Also, values 1 and 255 are reserved for certification purposes and
  *	should not be used during a normal device operation.
  * @NL80211_ATTR_NAN_DUAL: NAN dual band operation config (see
  *	&enum nl80211_nan_dual_band_conf). This attribute is used with
- *	%NL80211_CMD_START_NAN.
+ *	%NL80211_CMD_START_NAN and optionally with
+ *	%NL80211_CMD_CHANGE_NAN_CONFIG.
  * @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See
  *	&enum nl80211_nan_func_attributes for description of this nested
  *	attribute.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 58b3127..d627527 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10830,6 +10830,43 @@ static int nl80211_nan_rm_func(struct sk_buff *skb,
 	return 0;
 }
 
+static int nl80211_nan_change_config(struct sk_buff *skb,
+				     struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+	struct cfg80211_nan_conf conf = {};
+	u32 changed = 0;
+
+	if (wdev->iftype != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (!wdev->nan_started)
+		return -ENOTCONN;
+
+	if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
+		conf.master_pref =
+			nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
+		if (conf.master_pref <= 1 || conf.master_pref == 255)
+			return -EINVAL;
+
+		changed |= CFG80211_NAN_CONF_CHANGED_PREF;
+	}
+
+	if (info->attrs[NL80211_ATTR_NAN_DUAL]) {
+		conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
+		if (conf.dual > NL80211_NAN_BAND_MAX)
+			return -EINVAL;
+
+		changed |= CFG80211_NAN_CONF_CHANGED_DUAL;
+	}
+
+	if (!changed)
+		return -EINVAL;
+
+	return rdev_nan_change_conf(rdev, wdev, &conf, changed);
+}
+
 static int nl80211_get_protocol_features(struct sk_buff *skb,
 					 struct genl_info *info)
 {
@@ -12204,6 +12241,14 @@ static const struct genl_ops nl80211_ops[] = {
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
+		.cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
+		.doit = nl80211_nan_change_config,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
 		.cmd = NL80211_CMD_SET_MCAST_RATE,
 		.doit = nl80211_set_mcast_rate,
 		.policy = nl80211_policy,
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index f42acf4..8b4b9fd 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -928,6 +928,23 @@ static inline void rdev_rm_nan_func(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_void(&rdev->wiphy);
 }
 
+static inline int
+rdev_nan_change_conf(struct cfg80211_registered_device *rdev,
+		     struct wireless_dev *wdev,
+		     struct cfg80211_nan_conf *conf, u32 changes)
+{
+	int ret;
+
+	trace_rdev_nan_change_conf(&rdev->wiphy, wdev, conf, changes);
+	if (rdev->ops->nan_change_conf)
+		ret = rdev->ops->nan_change_conf(&rdev->wiphy, wdev, conf,
+						 changes);
+	else
+		ret = -ENOTSUPP;
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
 static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
 				   struct net_device *dev,
 				   struct cfg80211_acl_data *params)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 4845fe4..477b7e9 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1911,6 +1911,30 @@ TRACE_EVENT(rdev_start_nan,
 		  __entry->dual)
 );
 
+TRACE_EVENT(rdev_nan_change_conf,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 struct cfg80211_nan_conf *conf, u32 changes),
+	TP_ARGS(wiphy, wdev, conf, changes),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(u8, master_pref)
+		__field(u8, dual);
+		__field(u32, changes);
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->master_pref = conf->master_pref;
+		__entry->dual = conf->dual;
+		__entry->changes = changes;
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT
+		  ", master preference: %u, dual: %d, changes: %x",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->master_pref,
+		  __entry->dual, __entry->changes)
+);
+
 DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_nan,
 	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
 	TP_ARGS(wiphy, wdev)
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 3/9] cfg80211: add add_nan_func / rm_nan_func
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

A NAN function can be either publish, subscribe or follow
up. Make all the necessary verifications and just pass the
request to the driver.
Allow the user space application that starts NAN to
forbid any other socket to add or remove functions.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/cfg80211.h       |  91 +++++++++++
 include/uapi/linux/nl80211.h | 153 ++++++++++++++++++
 net/wireless/core.c          |   3 +-
 net/wireless/nl80211.c       | 368 +++++++++++++++++++++++++++++++++++++++++++
 net/wireless/rdev-ops.h      |  21 +++
 net/wireless/trace.h         |  39 +++++
 net/wireless/util.c          |  22 +++
 7 files changed, 696 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ca64d69..ced5b8a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2306,6 +2306,73 @@ struct cfg80211_nan_conf {
 };
 
 /**
+ * struct cfg80211_nan_func_filter - a NAN function Rx / Tx filter
+ *
+ * @filter: the content of the filter
+ * @len: the length of the filter
+ */
+struct cfg80211_nan_func_filter {
+	const u8 *filter;
+	u8 len;
+};
+
+/**
+ * struct cfg80211_nan_func - a NAN function
+ *
+ * @type: &enum nl80211_nan_function_type
+ * @service_id: the service ID of the function
+ * @publish_type: &nl80211_nan_publish_type
+ * @close_range: if true, the range should be limited. Threshold is
+ *	implementation specific.
+ * @publish_bcast: if true, the solicited publish should be broadcasted
+ * @subscribe_active: if true, the subscribe is active
+ * @followup_id: the instance ID for follow up
+ * @followup_reqid: the requestor instance ID for follow up
+ * @followup_dest: MAC address of the recipient of the follow up
+ * @ttl: time to live counter in DW.
+ * @serv_spec_info: Service Specific Info
+ * @serv_spec_info_len: Service Specific Info length
+ * @srf_include: if true, SRF is inclusive
+ * @srf_bf: Bloom Filter
+ * @srf_bf_len: Bloom Filter length
+ * @srf_bf_idx: Bloom Filter index
+ * @srf_macs: SRF MAC addresses
+ * @srf_num_macs: number of MAC addresses in SRF
+ * @rx_filters: rx filters that are matched with corresponding peer's tx_filter
+ * @tx_filters: filters that should be transmitted in the SDF.
+ * @num_rx_filters: length of &rx_filters.
+ * @num_tx_filters: length of &tx_filters.
+ * @instance_id: driver allocated id of the function.
+ * @cookie: unique NAN function identifier.
+ */
+struct cfg80211_nan_func {
+	enum nl80211_nan_function_type type;
+	u8 service_id[NL80211_NAN_FUNC_SERVICE_ID_LEN];
+	u8 publish_type;
+	bool close_range;
+	bool publish_bcast;
+	bool subscribe_active;
+	u8 followup_id;
+	u8 followup_reqid;
+	struct mac_address followup_dest;
+	u32 ttl;
+	const u8 *serv_spec_info;
+	u8 serv_spec_info_len;
+	bool srf_include;
+	const u8 *srf_bf;
+	u8 srf_bf_len;
+	u8 srf_bf_idx;
+	struct mac_address *srf_macs;
+	int srf_num_macs;
+	struct cfg80211_nan_func_filter *rx_filters;
+	struct cfg80211_nan_func_filter *tx_filters;
+	u8 num_tx_filters;
+	u8 num_rx_filters;
+	u8 instance_id;
+	u64 cookie;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2595,6 +2662,14 @@ struct cfg80211_nan_conf {
  *	peers must be on the base channel when the call completes.
  * @start_nan: Start the NAN interface.
  * @stop_nan: Stop the NAN interface.
+ * @add_nan_func: Add a NAN function. Returns negative value on failure.
+ *	On success @nan_func ownership is transferred to the driver and
+ *	it may access it outside of the scope of this function. The driver
+ *	should free the @nan_func when no longer needed by calling
+ *	cfg80211_free_nan_func().
+ *	On success the driver should assign an instance_id in the
+ *	provided @nan_func.
+ * @rm_nan_func: Remove a NAN function.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2863,6 +2938,10 @@ struct cfg80211_ops {
 	int	(*start_nan)(struct wiphy *wiphy, struct wireless_dev *wdev,
 			     struct cfg80211_nan_conf *conf);
 	void	(*stop_nan)(struct wiphy *wiphy, struct wireless_dev *wdev);
+	int	(*add_nan_func)(struct wiphy *wiphy, struct wireless_dev *wdev,
+				struct cfg80211_nan_func *nan_func);
+	void	(*rm_nan_func)(struct wiphy *wiphy, struct wireless_dev *wdev,
+			       u64 cookie);
 };
 
 /*
@@ -3311,6 +3390,8 @@ struct wiphy_iftype_ext_capab {
  * @bss_select_support: bitmask indicating the BSS selection criteria supported
  *	by the driver in the .connect() callback. The bit position maps to the
  *	attribute indices defined in &enum nl80211_bss_select_attr.
+ *
+ * @cookie_counter: unique generic cookie counter, used to identify objects.
  */
 struct wiphy {
 	/* assign these fields before you register the wiphy */
@@ -3440,6 +3521,8 @@ struct wiphy {
 
 	u32 bss_select_support;
 
+	u64 cookie_counter;
+
 	char priv[0] __aligned(NETDEV_ALIGN);
 };
 
@@ -5529,6 +5612,14 @@ wiphy_ext_feature_isset(struct wiphy *wiphy,
 	return (ft_byte & BIT(ftidx % 8)) != 0;
 }
 
+/**
+ * cfg80211_free_nan_func - free NAN function
+ * @f: NAN function that should be freed
+ *
+ * Frees all the NAN function and all it's allocated members.
+ */
+void cfg80211_free_nan_func(struct cfg80211_nan_func *f);
+
 /* ethtool helper */
 void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7ab18c8..ab16c8e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -847,6 +847,24 @@
  *	After this command NAN functions can be added.
  * @NL80211_CMD_STOP_NAN: Stop the NAN operation, identified by
  *	its %NL80211_ATTR_WDEV interface.
+ * @NL80211_CMD_ADD_NAN_FUNCTION: Add a NAN function. The function is defined
+ *	with %NL80211_ATTR_NAN_FUNC nested attribute. When called, this
+ *	operation returns the strictly positive and unique instance id
+ *	(%NL80211_ATTR_NAN_FUNC_INST_ID) and a cookie (%NL80211_ATTR_COOKIE)
+ *	of the function upon success.
+ *	Since instance ID's can be re-used, this cookie is the right
+ *	way to identify the function. This will avoid races when a termination
+ *	event is handled by the user space after it has already added a new
+ *	function that got the same instance id from the kernel as the one
+ *	which just terminated.
+ *	This cookie may be used in NAN events even before the command
+ *	returns, so userspace shouldn't process NAN events until it processes
+ *	the response to this command.
+ *	Look at %NL80211_ATTR_SOCKET_OWNER as well.
+ * @NL80211_CMD_RM_NAN_FUNCTION: Remove a NAN function by cookie.
+ *	This command is also used as a notification sent when a NAN function is
+ *	terminated. This will contain a %NL80211_ATTR_NAN_FUNC_INST_ID
+ *	and %NL80211_ATTR_COOKIE attributes.
  *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
@@ -1038,6 +1056,8 @@ enum nl80211_commands {
 
 	NL80211_CMD_START_NAN,
 	NL80211_CMD_STOP_NAN,
+	NL80211_CMD_ADD_NAN_FUNCTION,
+	NL80211_CMD_RM_NAN_FUNCTION,
 
 	/* add new commands above here */
 
@@ -1893,6 +1913,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_NAN_DUAL: NAN dual band operation config (see
  *	&enum nl80211_nan_dual_band_conf). This attribute is used with
  *	%NL80211_CMD_START_NAN.
+ * @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See
+ *	&enum nl80211_nan_func_attributes for description of this nested
+ *	attribute.
  *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -2290,6 +2313,7 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_NAN_MASTER_PREF,
 	NL80211_ATTR_NAN_DUAL,
+	NL80211_ATTR_NAN_FUNC,
 
 	/* add attributes here, update the policy in nl80211.c */
 
@@ -4907,4 +4931,133 @@ enum nl80211_nan_dual_band_conf {
 	__NL80211_NAN_BAND_AFTER_LAST - 1,
 };
 
+/**
+ * enum nl80211_nan_function_type - NAN function type
+ *
+ * Defines the function type of a NAN function
+ *
+ * @NL80211_NAN_FUNC_PUBLISH: function is publish
+ * @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe
+ * @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up
+ */
+enum nl80211_nan_function_type {
+	NL80211_NAN_FUNC_PUBLISH,
+	NL80211_NAN_FUNC_SUBSCRIBE,
+	NL80211_NAN_FUNC_FOLLOW_UP,
+
+	/* keep last */
+	__NL80211_NAN_FUNC_TYPE_AFTER_LAST,
+	NL80211_NAN_FUNC_MAX_TYPE = __NL80211_NAN_FUNC_TYPE_AFTER_LAST - 1,
+};
+
+/**
+ * enum nl80211_nan_publish_type - NAN publish tx type
+ *
+ * Defines how to send publish Service Discovery Frames
+ *
+ * @NL80211_NAN_SOLICITED_PUBLISH: publish function is solicited
+ * @NL80211_NAN_UNSOLICITED_PUBLISH: publish function is unsolicited
+ */
+enum nl80211_nan_publish_type {
+	NL80211_NAN_SOLICITED_PUBLISH = 1 << 0,
+	NL80211_NAN_UNSOLICITED_PUBLISH = 1 << 1,
+};
+
+#define NL80211_NAN_FUNC_SERVICE_ID_LEN 6
+#define NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN 0xff
+#define NL80211_NAN_FUNC_SRF_MAX_LEN 0xff
+
+/**
+ * enum nl80211_nan_func_attributes - NAN function attributes
+ * @__NL80211_NAN_FUNC_INVALID: invalid
+ * @NL80211_NAN_FUNC_TYPE: &enum nl80211_nan_function_type (u8).
+ * @NL80211_NAN_FUNC_SERVICE_ID: 6 bytes of the service ID hash as
+ *	specified in NAN spec. This is a binary attribute.
+ * @NL80211_NAN_FUNC_PUBLISH_TYPE: relevant if the function's type is
+ *	publish. Defines the transmission type for the publish Service Discovery
+ *	Frame, see &enum nl80211_nan_publish_type. Its type is u8.
+ * @NL80211_NAN_FUNC_PUBLISH_BCAST: relevant if the function is a solicited
+ *	publish. Should the solicited publish Service Discovery Frame be sent to
+ *	the NAN Broadcast address. This is a flag.
+ * @NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE: relevant if the function's type is
+ *	subscribe. Is the subscribe active. This is a flag.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_ID: relevant if the function's type is follow up.
+ *	The instance ID for the follow up Service Discovery Frame. This is u8.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type
+ *	is follow up. This is a u8.
+ *	The requestor instance ID for the follow up Service Discovery Frame.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the
+ *	follow up Service Discovery Frame. This is a binary attribute.
+ * @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a
+ *	close range. The range itself (RSSI) is defined by the device.
+ *	This is a flag.
+ * @NL80211_NAN_FUNC_TTL: strictly positive number of DWs this function should
+ *	stay active. If not present infinite TTL is assumed. This is a u32.
+ * @NL80211_NAN_FUNC_SERVICE_INFO: array of bytes describing the service
+ *	specific info. This is a binary attribute.
+ * @NL80211_NAN_FUNC_SRF: Service Receive Filter. This is a nested attribute.
+ *	See &enum nl80211_nan_srf_attributes.
+ * @NL80211_NAN_FUNC_RX_MATCH_FILTER: Receive Matching filter. This is a nested
+ *	attribute. It is a list of binary values.
+ * @NL80211_NAN_FUNC_TX_MATCH_FILTER: Transmit Matching filter. This is a
+ *	nested attribute. It is a list of binary values.
+ * @NL80211_NAN_FUNC_INSTANCE_ID: The instance ID of the function.
+ *	Its type is u8 and it cannot be 0.
+ * @NL80211_NAN_FUNC_TERM_REASON: NAN function termination reason.
+ *	See &enum nl80211_nan_func_term_reason.
+ *
+ * @NUM_NL80211_NAN_FUNC_ATTR: internal
+ * @NL80211_NAN_FUNC_ATTR_MAX: highest NAN function attribute
+ */
+enum nl80211_nan_func_attributes {
+	__NL80211_NAN_FUNC_INVALID,
+	NL80211_NAN_FUNC_TYPE,
+	NL80211_NAN_FUNC_SERVICE_ID,
+	NL80211_NAN_FUNC_PUBLISH_TYPE,
+	NL80211_NAN_FUNC_PUBLISH_BCAST,
+	NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE,
+	NL80211_NAN_FUNC_FOLLOW_UP_ID,
+	NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID,
+	NL80211_NAN_FUNC_FOLLOW_UP_DEST,
+	NL80211_NAN_FUNC_CLOSE_RANGE,
+	NL80211_NAN_FUNC_TTL,
+	NL80211_NAN_FUNC_SERVICE_INFO,
+	NL80211_NAN_FUNC_SRF,
+	NL80211_NAN_FUNC_RX_MATCH_FILTER,
+	NL80211_NAN_FUNC_TX_MATCH_FILTER,
+	NL80211_NAN_FUNC_INSTANCE_ID,
+	NL80211_NAN_FUNC_TERM_REASON,
+
+	/* keep last */
+	NUM_NL80211_NAN_FUNC_ATTR,
+	NL80211_NAN_FUNC_ATTR_MAX = NUM_NL80211_NAN_FUNC_ATTR - 1
+};
+
+/**
+ * enum nl80211_nan_srf_attributes - NAN Service Response filter attributes
+ * @__NL80211_NAN_SRF_INVALID: invalid
+ * @NL80211_NAN_SRF_INCLUDE: present if the include bit of the SRF set.
+ *	This is a flag.
+ * @NL80211_NAN_SRF_BF: Bloom Filter. Present if and only if
+ *	&NL80211_NAN_SRF_MAC_ADDRS isn't present. This attribute is binary.
+ * @NL80211_NAN_SRF_BF_IDX: index of the Bloom Filter. Mandatory if
+ *	&NL80211_NAN_SRF_BF is present. This is a u8.
+ * @NL80211_NAN_SRF_MAC_ADDRS: list of MAC addresses for the SRF. Present if
+ *	and only if &NL80211_NAN_SRF_BF isn't present. This is a nested
+ *	attribute. Each nested attribute is a MAC address.
+ * @NUM_NL80211_NAN_SRF_ATTR: internal
+ * @NL80211_NAN_SRF_ATTR_MAX: highest NAN SRF attribute
+ */
+enum nl80211_nan_srf_attributes {
+	__NL80211_NAN_SRF_INVALID,
+	NL80211_NAN_SRF_INCLUDE,
+	NL80211_NAN_SRF_BF,
+	NL80211_NAN_SRF_BF_IDX,
+	NL80211_NAN_SRF_MAC_ADDRS,
+
+	/* keep last */
+	NUM_NL80211_NAN_SRF_ATTR,
+	NL80211_NAN_SRF_ATTR_MAX = NUM_NL80211_NAN_SRF_ATTR - 1,
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 0139872..3799884 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -605,7 +605,8 @@ int wiphy_register(struct wiphy *wiphy)
 		return -EINVAL;
 
 	if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_NAN)) &&
-		    (!rdev->ops->start_nan || !rdev->ops->stop_nan)))
+		    (!rdev->ops->start_nan || !rdev->ops->stop_nan ||
+		     !rdev->ops->add_nan_func || !rdev->ops->rm_nan_func)))
 		return -EINVAL;
 
 	/*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 90580f9..58b3127 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -411,6 +411,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
 	[NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
 	[NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 },
+	[NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
 };
 
 /* policy for the key attributes */
@@ -504,6 +505,39 @@ nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
 	},
 };
 
+/* policy for NAN function attributes */
+static const struct nla_policy
+nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
+	[NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
+	[NL80211_NAN_FUNC_SERVICE_ID] = { .type = NLA_BINARY,
+				    .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
+	[NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
+	[NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
+	[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
+	[NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
+	[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
+	[NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
+	[NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
+	[NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
+	[NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
+			.len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
+	[NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
+	[NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
+	[NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
+	[NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
+	[NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
+};
+
+/* policy for Service Response Filter attributes */
+static const struct nla_policy
+nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
+	[NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
+	[NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
+				 .len =  NL80211_NAN_FUNC_SRF_MAX_LEN },
+	[NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
+	[NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
+};
+
 static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
 				     struct netlink_callback *cb,
 				     struct cfg80211_registered_device **rdev,
@@ -10478,6 +10512,324 @@ static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
+static int validate_nan_filter(struct nlattr *filter_attr)
+{
+	struct nlattr *attr;
+	int len = 0, n_entries = 0, rem;
+
+	nla_for_each_nested(attr, filter_attr, rem) {
+		len += nla_len(attr);
+		n_entries++;
+	}
+
+	if (len >= U8_MAX)
+		return -EINVAL;
+
+	return n_entries;
+}
+
+static int handle_nan_filter(struct nlattr *attr_filter,
+			     struct cfg80211_nan_func *func,
+			     bool tx)
+{
+	struct nlattr *attr;
+	int n_entries, rem, i;
+	struct cfg80211_nan_func_filter *filter;
+
+	n_entries = validate_nan_filter(attr_filter);
+	if (n_entries < 0)
+		return n_entries;
+
+	BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
+
+	filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
+	if (!filter)
+		return -ENOMEM;
+
+	i = 0;
+	nla_for_each_nested(attr, attr_filter, rem) {
+		filter[i].filter = kmemdup(nla_data(attr), nla_len(attr),
+					   GFP_KERNEL);
+		filter[i].len = nla_len(attr);
+		i++;
+	}
+	if (tx) {
+		func->num_tx_filters = n_entries;
+		func->tx_filters = filter;
+	} else {
+		func->num_rx_filters = n_entries;
+		func->rx_filters = filter;
+	}
+
+	return 0;
+}
+
+static int nl80211_nan_add_func(struct sk_buff *skb,
+				struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+	struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
+	struct cfg80211_nan_func *func;
+	struct sk_buff *msg = NULL;
+	void *hdr = NULL;
+	int err = 0;
+
+	if (wdev->iftype != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (!wdev->nan_started)
+		return -ENOTCONN;
+
+	if (!info->attrs[NL80211_ATTR_NAN_FUNC])
+		return -EINVAL;
+
+	if (wdev->owner_nlportid &&
+	    wdev->owner_nlportid != genl_info_snd_portid(info))
+		return -ENOTCONN;
+
+	err = nla_parse(tb, NL80211_NAN_FUNC_ATTR_MAX,
+			nla_data(info->attrs[NL80211_ATTR_NAN_FUNC]),
+			nla_len(info->attrs[NL80211_ATTR_NAN_FUNC]),
+			nl80211_nan_func_policy);
+	if (err)
+		return err;
+
+	func = kzalloc(sizeof(*func), GFP_KERNEL);
+	if (!func)
+		return -ENOMEM;
+
+	func->cookie = wdev->wiphy->cookie_counter++;
+
+	if (!tb[NL80211_NAN_FUNC_TYPE] ||
+	    nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
+		err = -EINVAL;
+		goto out;
+	}
+
+
+	func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
+
+	if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
+	       sizeof(func->service_id));
+
+	func->close_range =
+		nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
+
+	if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
+		func->serv_spec_info_len =
+			nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
+		func->serv_spec_info =
+			kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
+				func->serv_spec_info_len,
+				GFP_KERNEL);
+		if (!func->serv_spec_info) {
+			err = -ENOMEM;
+			goto out;
+		}
+	}
+
+	if (tb[NL80211_NAN_FUNC_TTL])
+		func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
+
+	switch (func->type) {
+	case NL80211_NAN_FUNC_PUBLISH:
+		if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		func->publish_type =
+			nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
+		func->publish_bcast =
+			nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
+
+		if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
+			func->publish_bcast) {
+			err = -EINVAL;
+			goto out;
+		}
+		break;
+	case NL80211_NAN_FUNC_SUBSCRIBE:
+		func->subscribe_active =
+			nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
+		break;
+	case NL80211_NAN_FUNC_FOLLOW_UP:
+		if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
+		    !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		func->followup_id =
+			nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
+		func->followup_reqid =
+			nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
+		memcpy(func->followup_dest.addr,
+		       nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
+		       sizeof(func->followup_dest.addr));
+		if (func->ttl) {
+			err = -EINVAL;
+			goto out;
+		}
+		break;
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (tb[NL80211_NAN_FUNC_SRF]) {
+		struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
+
+		err = nla_parse(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
+				nla_data(tb[NL80211_NAN_FUNC_SRF]),
+				nla_len(tb[NL80211_NAN_FUNC_SRF]), NULL);
+		if (err)
+			goto out;
+
+		func->srf_include =
+			nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
+
+		if (srf_tb[NL80211_NAN_SRF_BF]) {
+			if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
+			    !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
+				err = -EINVAL;
+				goto out;
+			}
+
+			func->srf_bf_len =
+				nla_len(srf_tb[NL80211_NAN_SRF_BF]);
+			func->srf_bf =
+				kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
+					func->srf_bf_len, GFP_KERNEL);
+			if (!func->srf_bf) {
+				err = -ENOMEM;
+				goto out;
+			}
+
+			func->srf_bf_idx =
+				nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
+		} else {
+			struct nlattr *attr, *mac_attr =
+				srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
+			int n_entries, rem, i = 0;
+
+			if (!mac_attr) {
+				err = -EINVAL;
+				goto out;
+			}
+
+			n_entries = validate_acl_mac_addrs(mac_attr);
+			if (n_entries <= 0) {
+				err = -EINVAL;
+				goto out;
+			}
+
+			func->srf_num_macs = n_entries;
+			func->srf_macs =
+				kzalloc(sizeof(*func->srf_macs) * n_entries,
+					GFP_KERNEL);
+			if (!func->srf_macs) {
+				err = -ENOMEM;
+				goto out;
+			}
+
+			nla_for_each_nested(attr, mac_attr, rem)
+				memcpy(func->srf_macs[i++].addr, nla_data(attr),
+				       sizeof(*func->srf_macs));
+		}
+	}
+
+	if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
+		err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
+					func, true);
+		if (err)
+			goto out;
+	}
+
+	if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
+		err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
+					func, false);
+		if (err)
+			goto out;
+	}
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	hdr = nl80211hdr_put(msg, genl_info_snd_portid(info), info->snd_seq, 0,
+			     NL80211_CMD_ADD_NAN_FUNCTION);
+	/* This can't really happen - we just allocated 4KB */
+	if (WARN_ON(!hdr)) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = rdev_add_nan_func(rdev, wdev, func);
+out:
+	if (err < 0) {
+		cfg80211_free_nan_func(func);
+		nlmsg_free(msg);
+		return err;
+	}
+
+	/* propagate the instance id and cookie to userspace  */
+	if (nla_put_u64(msg, NL80211_ATTR_COOKIE, func->cookie))
+		goto nla_put_failure;
+
+	func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
+	if (!func_attr)
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
+		       func->instance_id))
+		goto nla_put_failure;
+
+	nla_nest_end(msg, func_attr);
+
+	genlmsg_end(msg, hdr);
+	return genlmsg_reply(msg, info);
+
+nla_put_failure:
+	nlmsg_free(msg);
+	return -ENOBUFS;
+}
+
+static int nl80211_nan_rm_func(struct sk_buff *skb,
+			       struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+	u64 cookie;
+
+	if (wdev->iftype != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (!wdev->nan_started)
+		return -ENOTCONN;
+
+	if (!info->attrs[NL80211_ATTR_COOKIE])
+		return -EINVAL;
+
+	if (wdev->owner_nlportid &&
+	    wdev->owner_nlportid != genl_info_snd_portid(info))
+		return -ENOTCONN;
+
+	cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
+
+	rdev_rm_nan_func(rdev, wdev, cookie);
+
+	return 0;
+}
+
 static int nl80211_get_protocol_features(struct sk_buff *skb,
 					 struct genl_info *info)
 {
@@ -11836,6 +12188,22 @@ static const struct genl_ops nl80211_ops[] = {
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
+		.cmd = NL80211_CMD_ADD_NAN_FUNCTION,
+		.doit = nl80211_nan_add_func,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL80211_CMD_RM_NAN_FUNCTION,
+		.doit = nl80211_nan_rm_func,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
 		.cmd = NL80211_CMD_SET_MCAST_RATE,
 		.doit = nl80211_set_mcast_rate,
 		.policy = nl80211_policy,
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index afb68a8..f42acf4 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -907,6 +907,27 @@ static inline void rdev_stop_nan(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_void(&rdev->wiphy);
 }
 
+static inline int
+rdev_add_nan_func(struct cfg80211_registered_device *rdev,
+		  struct wireless_dev *wdev,
+		  struct cfg80211_nan_func *nan_func)
+{
+	int ret;
+
+	trace_rdev_add_nan_func(&rdev->wiphy, wdev, nan_func);
+	ret = rdev->ops->add_nan_func(&rdev->wiphy, wdev, nan_func);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline void rdev_rm_nan_func(struct cfg80211_registered_device *rdev,
+				    struct wireless_dev *wdev, u64 cookie)
+{
+	trace_rdev_rm_nan_func(&rdev->wiphy, wdev, cookie);
+	rdev->ops->rm_nan_func(&rdev->wiphy, wdev, cookie);
+	trace_rdev_return_void(&rdev->wiphy);
+}
+
 static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
 				   struct net_device *dev,
 				   struct cfg80211_acl_data *params)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5f3370f..4845fe4 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1916,6 +1916,45 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_nan,
 	TP_ARGS(wiphy, wdev)
 );
 
+TRACE_EVENT(rdev_add_nan_func,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 const struct cfg80211_nan_func *func),
+	TP_ARGS(wiphy, wdev, func),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(u8, func_type)
+		__field(u64, cookie)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->func_type = func->type;
+		__entry->cookie = func->cookie
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", type=%u, cookie=%llu",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->func_type,
+		  __entry->cookie)
+);
+
+TRACE_EVENT(rdev_rm_nan_func,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 u64 cookie),
+	TP_ARGS(wiphy, wdev, cookie),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(u64, cookie)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->cookie = cookie;
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie=%llu",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
+);
+
 TRACE_EVENT(rdev_set_mac_acl,
 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
 		 struct cfg80211_acl_data *params),
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 91868e0..91bae35 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1762,6 +1762,28 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
 }
 EXPORT_SYMBOL(cfg80211_get_station);
 
+void cfg80211_free_nan_func(struct cfg80211_nan_func *f)
+{
+	int i;
+
+	if (!f)
+		return;
+
+	kfree(f->serv_spec_info);
+	kfree(f->srf_bf);
+	kfree(f->srf_macs);
+	for (i = 0; i < f->num_rx_filters; i++)
+		kfree(f->rx_filters[i].filter);
+
+	for (i = 0; i < f->num_tx_filters; i++)
+		kfree(f->tx_filters[i].filter);
+
+	kfree(f->rx_filters);
+	kfree(f->tx_filters);
+	kfree(f);
+}
+EXPORT_SYMBOL(cfg80211_free_nan_func);
+
 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
 const unsigned char rfc1042_header[] __aligned(2) =
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 2/9] mac80211: add boilerplate code for start / stop NAN
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

This code doesn't do much besides allowing to start and
stop the vif.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/mac80211.h    |  9 +++++++++
 net/mac80211/cfg.c        | 36 ++++++++++++++++++++++++++++++++++
 net/mac80211/chan.c       |  3 +++
 net/mac80211/driver-ops.h | 29 ++++++++++++++++++++++++++-
 net/mac80211/iface.c      |  8 ++++++--
 net/mac80211/main.c       |  5 +++++
 net/mac80211/offchannel.c |  3 ++-
 net/mac80211/trace.h      | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/util.c       |  3 ++-
 9 files changed, 141 insertions(+), 5 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5296100..df9b5cf 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3420,6 +3420,9 @@ enum ieee80211_reconfig_type {
  *	synchronization which is needed in case driver has in its RSS queues
  *	pending frames that were received prior to the control path action
  *	currently taken (e.g. disassociation) but are not processed yet.
+ *
+ * @start_nan: join an existing NAN cluster, or create a new one.
+ * @stop_nan: leave the NAN cluster.
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw,
@@ -3655,6 +3658,12 @@ struct ieee80211_ops {
 	void (*wake_tx_queue)(struct ieee80211_hw *hw,
 			      struct ieee80211_txq *txq);
 	void (*sync_rx_queues)(struct ieee80211_hw *hw);
+
+	int (*start_nan)(struct ieee80211_hw *hw,
+			 struct ieee80211_vif *vif,
+			 struct cfg80211_nan_conf *conf);
+	int (*stop_nan)(struct ieee80211_hw *hw,
+			struct ieee80211_vif *vif);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a74027f..9aabb09 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3,6 +3,7 @@
  *
  * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2015  Intel Mobile Communications GmbH
+ * Copyright (C) 2015-2016 Intel Deutschland GmbH
  *
  * This file is GPLv2 as found in COPYING.
  */
@@ -152,6 +153,39 @@ static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
 	ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev));
 }
 
+static int ieee80211_start_nan(struct wiphy *wiphy,
+			       struct wireless_dev *wdev,
+			       struct cfg80211_nan_conf *conf)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+	int ret;
+
+	mutex_lock(&sdata->local->chanctx_mtx);
+	ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
+	mutex_unlock(&sdata->local->chanctx_mtx);
+	if (ret < 0)
+		return ret;
+
+	ret = ieee80211_do_open(wdev, true);
+	if (ret)
+		return ret;
+
+	ret = drv_start_nan(sdata->local, sdata, conf);
+	if (ret)
+		ieee80211_sdata_stop(sdata);
+
+	return ret;
+}
+
+static void ieee80211_stop_nan(struct wiphy *wiphy,
+			       struct wireless_dev *wdev)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+
+	drv_stop_nan(sdata->local, sdata);
+	ieee80211_sdata_stop(sdata);
+}
+
 static int ieee80211_set_noack_map(struct wiphy *wiphy,
 				  struct net_device *dev,
 				  u16 noack_map)
@@ -3464,4 +3498,6 @@ const struct cfg80211_ops mac80211_config_ops = {
 	.set_ap_chanwidth = ieee80211_set_ap_chanwidth,
 	.add_tx_ts = ieee80211_add_tx_ts,
 	.del_tx_ts = ieee80211_del_tx_ts,
+	.start_nan = ieee80211_start_nan,
+	.stop_nan = ieee80211_stop_nan,
 };
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index acb50f8..e4d147e 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -647,6 +647,9 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_chanctx *curr_ctx = NULL;
 	int ret = 0;
 
+	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
+		return -ENOTSUPP;
+
 	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 					 lockdep_is_held(&local->chanctx_mtx));
 
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index fe35a1c..67b42c8 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -163,7 +163,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
 
 	if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
 			 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
-			  !sdata->vif.mu_mimo_owner)))
+			  !sdata->vif.mu_mimo_owner) ||
+			 sdata->vif.type == NL80211_IFTYPE_NAN))
 		return;
 
 	if (!check_sdata_in_driver(sdata))
@@ -1165,4 +1166,30 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local,
 	local->ops->wake_tx_queue(&local->hw, &txq->txq);
 }
 
+static inline int drv_start_nan(struct ieee80211_local *local,
+				struct ieee80211_sub_if_data *sdata,
+				struct cfg80211_nan_conf *conf)
+{
+	int ret;
+
+	might_sleep();
+	check_sdata_in_driver(sdata);
+
+	trace_drv_start_nan(local, sdata, conf);
+	ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
+	trace_drv_return_int(local, ret);
+	return ret;
+}
+
+static inline void drv_stop_nan(struct ieee80211_local *local,
+				struct ieee80211_sub_if_data *sdata)
+{
+	might_sleep();
+	check_sdata_in_driver(sdata);
+
+	trace_drv_stop_nan(local, sdata);
+	local->ops->stop_nan(&local->hw, &sdata->vif);
+	trace_drv_return_void(local);
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e694ca2..507f46a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -327,6 +327,9 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
 	int n_queues = sdata->local->hw.queues;
 	int i;
 
+	if (iftype == NL80211_IFTYPE_NAN)
+		return 0;
+
 	if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
 		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 			if (WARN_ON_ONCE(sdata->vif.hw_queue[i] ==
@@ -647,7 +650,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 			local->fif_probe_req++;
 		}
 
-		if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE)
+		if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
+		    sdata->vif.type != NL80211_IFTYPE_NAN)
 			changed |= ieee80211_reset_erp_info(sdata);
 		ieee80211_bss_info_change_notify(sdata, changed);
 
@@ -1726,7 +1730,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 
 	ASSERT_RTNL();
 
-	if (type == NL80211_IFTYPE_P2P_DEVICE) {
+	if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) {
 		struct wireless_dev *wdev;
 
 		sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ac053a9..b5cf2c5 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -821,6 +821,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	     !local->ops->tdls_recv_channel_switch))
 		return -EOPNOTSUPP;
 
+	if (WARN_ON(local->hw.wiphy->interface_modes &
+			BIT(NL80211_IFTYPE_NAN) &&
+		    (!local->ops->start_nan || !local->ops->stop_nan)))
+		return -EINVAL;
+
 #ifdef CONFIG_PM
 	if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
 		return -EINVAL;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 75d5c96..c3f610b 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -128,7 +128,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
 		if (!ieee80211_sdata_running(sdata))
 			continue;
 
-		if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
+		if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
+		    sdata->vif.type == NL80211_IFTYPE_NAN)
 			continue;
 
 		if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 77e4c53..deefbfb 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1700,6 +1700,56 @@ TRACE_EVENT(drv_get_expected_throughput,
 	)
 );
 
+TRACE_EVENT(drv_start_nan,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 struct cfg80211_nan_conf *conf),
+
+	TP_ARGS(local, sdata, conf),
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(u8, master_pref)
+		__field(u8, dual)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->master_pref = conf->master_pref;
+		__entry->dual = conf->dual;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT
+		", master preference: %u, dual: %d",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->master_pref,
+		__entry->dual
+	)
+);
+
+TRACE_EVENT(drv_stop_nan,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata),
+
+	TP_ARGS(local, sdata),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT,
+		LOCAL_PR_ARG, VIF_PR_ARG
+	)
+);
+
 /*
  * Tracing for API calls that drivers call.
  */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 2c78541..5b57fca 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1209,7 +1209,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
 	}
 
 	if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
-	    sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) {
+	    sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
+	    sdata->vif.type != NL80211_IFTYPE_NAN) {
 		sdata->vif.bss_conf.qos = enable_qos;
 		if (bss_notify)
 			ieee80211_bss_info_change_notify(sdata,
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 1/9] cfg80211: add start / stop NAN commands
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, Ayala Beker, Andrei Otcheretianski,
	Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20160916083321.5840-1-luca@coelho.fi>

From: Ayala Beker <ayala.beker@intel.com>

This allows user space to start/stop NAN interface.
A NAN interface is like P2P device in a few aspects: it
doesn't have a netdev associated to it.
Add the new interface type and prevent operations that
can't be executed on NAN interface like scan.

Define several attributes that may be configured by user space
when starting NAN functionality (master preference and dual
band operation)

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 include/net/cfg80211.h       | 21 +++++++++-
 include/uapi/linux/nl80211.h | 52 +++++++++++++++++++++++++
 net/mac80211/cfg.c           |  2 +
 net/mac80211/chan.c          |  3 ++
 net/mac80211/iface.c         |  4 ++
 net/mac80211/offchannel.c    |  1 +
 net/mac80211/rx.c            |  3 ++
 net/mac80211/util.c          |  1 +
 net/wireless/chan.c          |  2 +
 net/wireless/core.c          | 34 ++++++++++++++++
 net/wireless/core.h          |  3 ++
 net/wireless/mlme.c          |  1 +
 net/wireless/nl80211.c       | 93 ++++++++++++++++++++++++++++++++++++++++++--
 net/wireless/rdev-ops.h      | 20 ++++++++++
 net/wireless/trace.h         | 27 +++++++++++++
 net/wireless/util.c          |  6 ++-
 16 files changed, 267 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d5e7f69..ca64d69 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2293,6 +2293,19 @@ struct cfg80211_qos_map {
 };
 
 /**
+ * struct cfg80211_nan_conf - NAN configuration
+ *
+ * This struct defines NAN configuration parameters
+ *
+ * @master_pref: master preference (1 - 255)
+ * @dual: dual band operation mode
+ */
+struct cfg80211_nan_conf {
+	u8 master_pref;
+	enum nl80211_nan_dual_band_conf dual;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2580,6 +2593,8 @@ struct cfg80211_qos_map {
  *	and returning to the base channel for communication with the AP.
  * @tdls_cancel_channel_switch: Stop channel-switching with a TDLS peer. Both
  *	peers must be on the base channel when the call completes.
+ * @start_nan: Start the NAN interface.
+ * @stop_nan: Stop the NAN interface.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2845,6 +2860,9 @@ struct cfg80211_ops {
 	void	(*tdls_cancel_channel_switch)(struct wiphy *wiphy,
 					      struct net_device *dev,
 					      const u8 *addr);
+	int	(*start_nan)(struct wiphy *wiphy, struct wireless_dev *wdev,
+			     struct cfg80211_nan_conf *conf);
+	void	(*stop_nan)(struct wiphy *wiphy, struct wireless_dev *wdev);
 };
 
 /*
@@ -3602,6 +3620,7 @@ struct cfg80211_cached_keys;
  *	beacons, 0 when not valid
  * @address: The address for this device, valid only if @netdev is %NULL
  * @p2p_started: true if this is a P2P Device that has been started
+ * @nan_started: true if this is a NAN interface that has been started
  * @cac_started: true if DFS channel availability check has been started
  * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
  * @cac_time_ms: CAC time in ms
@@ -3633,7 +3652,7 @@ struct wireless_dev {
 
 	struct mutex mtx;
 
-	bool use_4addr, p2p_started;
+	bool use_4addr, p2p_started, nan_started;
 
 	u8 address[ETH_ALEN] __aligned(sizeof(u16));
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 2206941..7ab18c8 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -838,6 +838,16 @@
  *	not running. The driver indicates the status of the scan through
  *	cfg80211_scan_done().
  *
+ * @NL80211_CMD_START_NAN: Start NAN operation, identified by its
+ *	%NL80211_ATTR_WDEV interface. This interface must have been previously
+ *	created with %NL80211_CMD_NEW_INTERFACE. After it has been started, the
+ *	NAN interface will create or join a cluster. This command must have a
+ *	valid %NL80211_ATTR_NAN_MASTER_PREF attribute and optional
+ *	%NL80211_ATTR_NAN_DUAL attributes.
+ *	After this command NAN functions can be added.
+ * @NL80211_CMD_STOP_NAN: Stop the NAN operation, identified by
+ *	its %NL80211_ATTR_WDEV interface.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1026,6 +1036,9 @@ enum nl80211_commands {
 
 	NL80211_CMD_ABORT_SCAN,
 
+	NL80211_CMD_START_NAN,
+	NL80211_CMD_STOP_NAN,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1733,6 +1746,12 @@ enum nl80211_commands {
  *	regulatory indoor configuration would be owned by the netlink socket
  *	that configured the indoor setting, and the indoor operation would be
  *	cleared when the socket is closed.
+ *	If set during NAN interface creation, the interface will be destroyed
+ *	if the socket is closed just like any other interface. Moreover, only
+ *	the netlink socket that created the interface will be allowed to add
+ *	and remove functions. NAN notifications will be sent in unicast to that
+ *	socket. Without this attribute, any socket can add functions and the
+ *	notifications will be sent to the %NL80211_MCGRP_NAN multicast group.
  *
  * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
  *	the TDLS link initiator.
@@ -1867,6 +1886,14 @@ enum nl80211_commands {
  * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer (u16). This is
  *	used to pull the stored data for mesh peer in power save state.
  *
+ * @NL80211_ATTR_NAN_MASTER_PREF: the master preference to be used by
+ *	%NL80211_CMD_START_NAN. Its type is u8 and it can't be 0.
+ *	Also, values 1 and 255 are reserved for certification purposes and
+ *	should not be used during a normal device operation.
+ * @NL80211_ATTR_NAN_DUAL: NAN dual band operation config (see
+ *	&enum nl80211_nan_dual_band_conf). This attribute is used with
+ *	%NL80211_CMD_START_NAN.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2261,6 +2288,9 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_MESH_PEER_AID,
 
+	NL80211_ATTR_NAN_MASTER_PREF,
+	NL80211_ATTR_NAN_DUAL,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -2339,6 +2369,7 @@ enum nl80211_attrs {
  *	commands to create and destroy one
  * @NL80211_IF_TYPE_OCB: Outside Context of a BSS
  *	This mode corresponds to the MIB variable dot11OCBActivated=true
+ * @NL80211_IFTYPE_NAN: NAN device interface type (not a netdev)
  * @NL80211_IFTYPE_MAX: highest interface type number currently defined
  * @NUM_NL80211_IFTYPES: number of defined interface types
  *
@@ -2359,6 +2390,7 @@ enum nl80211_iftype {
 	NL80211_IFTYPE_P2P_GO,
 	NL80211_IFTYPE_P2P_DEVICE,
 	NL80211_IFTYPE_OCB,
+	NL80211_IFTYPE_NAN,
 
 	/* keep last */
 	NUM_NL80211_IFTYPES,
@@ -4855,4 +4887,24 @@ enum nl80211_bss_select_attr {
 	NL80211_BSS_SELECT_ATTR_MAX = __NL80211_BSS_SELECT_ATTR_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_nan_dual_band_conf - NAN dual band configuration
+ *
+ * Defines the NAN dual band mode of operation
+ *
+ * @NL80211_NAN_BAND_DEFAULT: device default mode
+ * @NL80211_NAN_BAND_SINGLE: 2.4GHz only mode
+ * @NL80211_NAN_BAND_DUAL: 2.4GHz and 5.2GHz mode
+  */
+enum nl80211_nan_dual_band_conf {
+	NL80211_NAN_BAND_DEFAULT,
+	NL80211_NAN_BAND_SINGLE,
+	NL80211_NAN_BAND_DUAL,
+
+	/* keep last */
+	__NL80211_NAN_BAND_AFTER_LAST,
+	NL80211_NAN_BAND_MAX =
+	__NL80211_NAN_BAND_AFTER_LAST - 1,
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e29ff57..a74027f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -257,6 +257,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 	case NL80211_IFTYPE_WDS:
 	case NL80211_IFTYPE_MONITOR:
 	case NL80211_IFTYPE_P2P_DEVICE:
+	case NL80211_IFTYPE_NAN:
 	case NL80211_IFTYPE_UNSPECIFIED:
 	case NUM_NL80211_IFTYPES:
 	case NL80211_IFTYPE_P2P_CLIENT:
@@ -2036,6 +2037,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
 		     !(req->flags & NL80211_SCAN_FLAG_AP)))
 			return -EOPNOTSUPP;
 		break;
+	case NL80211_IFTYPE_NAN:
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 74142d0..acb50f8 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -274,6 +274,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
 				    ieee80211_get_max_required_bw(sdata));
 			break;
 		case NL80211_IFTYPE_P2P_DEVICE:
+		case NL80211_IFTYPE_NAN:
 			continue;
 		case NL80211_IFTYPE_ADHOC:
 		case NL80211_IFTYPE_WDS:
@@ -718,6 +719,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 
 		switch (sdata->vif.type) {
 		case NL80211_IFTYPE_P2P_DEVICE:
+		case NL80211_IFTYPE_NAN:
 			continue;
 		case NL80211_IFTYPE_STATION:
 			if (!sdata->u.mgd.associated)
@@ -981,6 +983,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
 	case NL80211_IFTYPE_P2P_GO:
 	case NL80211_IFTYPE_P2P_DEVICE:
 	case NUM_NL80211_IFTYPES:
+	case NL80211_IFTYPE_NAN:
 		WARN_ON(1);
 		break;
 	}
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b0abddc7..e694ca2 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -545,6 +545,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_P2P_DEVICE:
 	case NL80211_IFTYPE_OCB:
+	case NL80211_IFTYPE_NAN:
 		/* no special treatment */
 		break;
 	case NL80211_IFTYPE_UNSPECIFIED:
@@ -660,6 +661,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 			break;
 		case NL80211_IFTYPE_WDS:
 		case NL80211_IFTYPE_P2P_DEVICE:
+		case NL80211_IFTYPE_NAN:
 			break;
 		default:
 			/* not reached */
@@ -948,6 +950,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 		/* relies on synchronize_rcu() below */
 		RCU_INIT_POINTER(local->p2p_sdata, NULL);
 		/* fall through */
+	case NL80211_IFTYPE_NAN:
 	default:
 		cancel_work_sync(&sdata->work);
 		/*
@@ -1457,6 +1460,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
 		break;
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_P2P_DEVICE:
+	case NL80211_IFTYPE_NAN:
 		sdata->vif.bss_conf.bssid = sdata->vif.addr;
 		break;
 	case NL80211_IFTYPE_UNSPECIFIED:
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 55a9c5b..75d5c96 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -838,6 +838,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 	case NL80211_IFTYPE_P2P_DEVICE:
 		need_offchan = true;
 		break;
+	case NL80211_IFTYPE_NAN:
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e796060..c9489a8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3586,6 +3586,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 		       ieee80211_is_probe_req(hdr->frame_control) ||
 		       ieee80211_is_probe_resp(hdr->frame_control) ||
 		       ieee80211_is_beacon(hdr->frame_control);
+	case NL80211_IFTYPE_NAN:
+		/* Currently no frames on NAN interface are allowed */
+		return false;
 	default:
 		break;
 	}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b6865d8..2c78541 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1975,6 +1975,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 		case NL80211_IFTYPE_AP_VLAN:
 		case NL80211_IFTYPE_MONITOR:
 		case NL80211_IFTYPE_P2P_DEVICE:
+		case NL80211_IFTYPE_NAN:
 			/* nothing to do */
 			break;
 		case NL80211_IFTYPE_UNSPECIFIED:
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 0f50622..5497d022 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -372,6 +372,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_WDS:
 	case NL80211_IFTYPE_P2P_DEVICE:
+	case NL80211_IFTYPE_NAN:
 		break;
 	case NL80211_IFTYPE_UNSPECIFIED:
 	case NUM_NL80211_IFTYPES:
@@ -946,6 +947,7 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_WDS:
 	case NL80211_IFTYPE_P2P_DEVICE:
+	case NL80211_IFTYPE_NAN:
 		/* these interface types don't really have a channel */
 		return;
 	case NL80211_IFTYPE_UNSPECIFIED:
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 4911cd9..0139872 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -225,6 +225,23 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
 	}
 }
 
+void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
+		       struct wireless_dev *wdev)
+{
+	ASSERT_RTNL();
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_NAN))
+		return;
+
+	if (!wdev->nan_started)
+		return;
+
+	rdev_stop_nan(rdev, wdev);
+	wdev->nan_started = false;
+
+	rdev->opencount--;
+}
+
 void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
 {
 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
@@ -242,6 +259,9 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
 		case NL80211_IFTYPE_P2P_DEVICE:
 			cfg80211_stop_p2p_device(rdev, wdev);
 			break;
+		case NL80211_IFTYPE_NAN:
+			cfg80211_stop_nan(rdev, wdev);
+			break;
 		default:
 			break;
 		}
@@ -537,6 +557,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
 				    c->limits[j].max > 1))
 				return -EINVAL;
 
+			/* Only a single NAN can be allowed */
+			if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
+				    c->limits[j].max > 1))
+				return -EINVAL;
+
 			cnt += c->limits[j].max;
 			/*
 			 * Don't advertise an unsupported type
@@ -579,6 +604,10 @@ int wiphy_register(struct wiphy *wiphy)
 		     !rdev->ops->tdls_cancel_channel_switch)))
 		return -EINVAL;
 
+	if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_NAN)) &&
+		    (!rdev->ops->start_nan || !rdev->ops->stop_nan)))
+		return -EINVAL;
+
 	/*
 	 * if a wiphy has unsupported modes for regulatory channel enforcement,
 	 * opt-out of enforcement checking
@@ -589,6 +618,7 @@ int wiphy_register(struct wiphy *wiphy)
 				       BIT(NL80211_IFTYPE_P2P_GO) |
 				       BIT(NL80211_IFTYPE_ADHOC) |
 				       BIT(NL80211_IFTYPE_P2P_DEVICE) |
+				       BIT(NL80211_IFTYPE_NAN) |
 				       BIT(NL80211_IFTYPE_AP_VLAN) |
 				       BIT(NL80211_IFTYPE_MONITOR)))
 		wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
@@ -916,6 +946,9 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
 		cfg80211_mlme_purge_registrations(wdev);
 		cfg80211_stop_p2p_device(rdev, wdev);
 		break;
+	case NL80211_IFTYPE_NAN:
+		cfg80211_stop_nan(rdev, wdev);
+		break;
 	default:
 		WARN_ON_ONCE(1);
 		break;
@@ -979,6 +1012,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
 		/* must be handled by mac80211/driver, has no APIs */
 		break;
 	case NL80211_IFTYPE_P2P_DEVICE:
+	case NL80211_IFTYPE_NAN:
 		/* cannot happen, has no netdev */
 		break;
 	case NL80211_IFTYPE_AP_VLAN:
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 5555e3c..9cdca5e 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -488,6 +488,9 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
 void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
 			      struct wireless_dev *wdev);
 
+void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
+		       struct wireless_dev *wdev);
+
 #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
 
 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index d6abb07..cbb48e2 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -634,6 +634,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 			 * fall through, P2P device only supports
 			 * public action frames
 			 */
+		case NL80211_IFTYPE_NAN:
 		default:
 			err = -EOPNOTSUPP;
 			break;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 887c4c1..90580f9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -409,6 +409,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 		.len = VHT_MUMIMO_GROUPS_DATA_LEN
 	},
 	[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
+	[NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
+	[NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -934,6 +936,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
 	case NL80211_IFTYPE_UNSPECIFIED:
 	case NL80211_IFTYPE_OCB:
 	case NL80211_IFTYPE_MONITOR:
+	case NL80211_IFTYPE_NAN:
 	case NL80211_IFTYPE_P2P_DEVICE:
 	case NL80211_IFTYPE_WDS:
 	case NUM_NL80211_IFTYPES:
@@ -2819,7 +2822,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 	    !(rdev->wiphy.interface_modes & (1 << type)))
 		return -EOPNOTSUPP;
 
-	if ((type == NL80211_IFTYPE_P2P_DEVICE ||
+	if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
 	     rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
 	    info->attrs[NL80211_ATTR_MAC]) {
 		nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
@@ -2875,9 +2878,10 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 		       wdev->mesh_id_up_len);
 		wdev_unlock(wdev);
 		break;
+	case NL80211_IFTYPE_NAN:
 	case NL80211_IFTYPE_P2P_DEVICE:
 		/*
-		 * P2P Device doesn't have a netdev, so doesn't go
+		 * P2P Device and NAN do not have a netdev, so don't go
 		 * through the netdev notifier and must be added here
 		 */
 		mutex_init(&wdev->mtx);
@@ -6138,6 +6142,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
 	wiphy = &rdev->wiphy;
 
+	if (wdev->iftype == NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
 	if (!rdev->ops->scan)
 		return -EOPNOTSUPP;
 
@@ -8898,6 +8905,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
 	case NL80211_IFTYPE_P2P_GO:
 	case NL80211_IFTYPE_P2P_DEVICE:
 		break;
+	case NL80211_IFTYPE_NAN:
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -8943,6 +8951,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_P2P_GO:
 		break;
+	case NL80211_IFTYPE_NAN:
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -9059,6 +9068,7 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in
 	case NL80211_IFTYPE_P2P_GO:
 	case NL80211_IFTYPE_P2P_DEVICE:
 		break;
+	case NL80211_IFTYPE_NAN:
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -10414,6 +10424,60 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
+static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+	struct cfg80211_nan_conf conf = {};
+	int err;
+
+	if (wdev->iftype != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (wdev->nan_started)
+		return -EEXIST;
+
+	if (rfkill_blocked(rdev->rfkill))
+		return -ERFKILL;
+
+	if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
+		return -EINVAL;
+
+	if (!info->attrs[NL80211_ATTR_NAN_DUAL])
+		return -EINVAL;
+
+	conf.master_pref =
+		nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
+	if (!conf.master_pref)
+		return -EINVAL;
+
+	conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
+	if (conf.dual > NL80211_NAN_BAND_MAX)
+		return -EINVAL;
+
+	err = rdev_start_nan(rdev, wdev, &conf);
+	if (err)
+		return err;
+
+	wdev->nan_started = true;
+	rdev->opencount++;
+
+	return 0;
+}
+
+static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+
+	if (wdev->iftype != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	cfg80211_stop_nan(rdev, wdev);
+
+	return 0;
+}
+
 static int nl80211_get_protocol_features(struct sk_buff *skb,
 					 struct genl_info *info)
 {
@@ -11115,7 +11179,14 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 
 			dev_hold(dev);
 		} else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
-			if (!wdev->p2p_started) {
+			if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
+			    !wdev->p2p_started) {
+				if (rtnl)
+					rtnl_unlock();
+				return -ENETDOWN;
+			}
+			if (wdev->iftype == NL80211_IFTYPE_NAN &&
+			    !wdev->nan_started) {
 				if (rtnl)
 					rtnl_unlock();
 				return -ENETDOWN;
@@ -11749,6 +11820,22 @@ static const struct genl_ops nl80211_ops[] = {
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
+		.cmd = NL80211_CMD_START_NAN,
+		.doit = nl80211_start_nan,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL80211_CMD_STOP_NAN,
+		.doit = nl80211_stop_nan,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
 		.cmd = NL80211_CMD_SET_MCAST_RATE,
 		.doit = nl80211_set_mcast_rate,
 		.policy = nl80211_policy,
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 85ff30b..afb68a8 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -887,6 +887,26 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_void(&rdev->wiphy);
 }
 
+static inline int rdev_start_nan(struct cfg80211_registered_device *rdev,
+				 struct wireless_dev *wdev,
+				 struct cfg80211_nan_conf *conf)
+{
+	int ret;
+
+	trace_rdev_start_nan(&rdev->wiphy, wdev, conf);
+	ret = rdev->ops->start_nan(&rdev->wiphy, wdev, conf);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline void rdev_stop_nan(struct cfg80211_registered_device *rdev,
+				 struct wireless_dev *wdev)
+{
+	trace_rdev_stop_nan(&rdev->wiphy, wdev);
+	rdev->ops->stop_nan(&rdev->wiphy, wdev);
+	trace_rdev_return_void(&rdev->wiphy);
+}
+
 static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
 				   struct net_device *dev,
 				   struct cfg80211_acl_data *params)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 72b5255..5f3370f 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1889,6 +1889,33 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_device,
 	TP_ARGS(wiphy, wdev)
 );
 
+TRACE_EVENT(rdev_start_nan,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 struct cfg80211_nan_conf *conf),
+	TP_ARGS(wiphy, wdev, conf),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(u8, master_pref)
+		__field(u8, dual);
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->master_pref = conf->master_pref;
+		__entry->dual = conf->dual;
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT
+		  ", master preference: %u, dual: %d",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->master_pref,
+		  __entry->dual)
+);
+
+DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_nan,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+	TP_ARGS(wiphy, wdev)
+);
+
 TRACE_EVENT(rdev_set_mac_acl,
 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
 		 struct cfg80211_acl_data *params),
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 9e6e2aa..91868e0 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1008,8 +1008,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 	if (otype == NL80211_IFTYPE_AP_VLAN)
 		return -EOPNOTSUPP;
 
-	/* cannot change into P2P device type */
-	if (ntype == NL80211_IFTYPE_P2P_DEVICE)
+	/* cannot change into P2P device or NAN */
+	if (ntype == NL80211_IFTYPE_P2P_DEVICE ||
+	    ntype == NL80211_IFTYPE_NAN)
 		return -EOPNOTSUPP;
 
 	if (!rdev->ops->change_virtual_intf ||
@@ -1088,6 +1089,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 			/* not happening */
 			break;
 		case NL80211_IFTYPE_P2P_DEVICE:
+		case NL80211_IFTYPE_NAN:
 			WARN_ON(1);
 			break;
 		}
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 0/9] Add support for Neighbor Awareness Networking
From: Luca Coelho @ 2016-09-16  8:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Luca Coelho

From: Luca Coelho <luciano.coelho@intel.com>

Hi,

This is v2 of the NAN patches that Emmanuel sent a while back[1].  In
this version, we squashed some patches and took care of some comments
after reviews (both internal and public).

NAN was described in the original post[2].

I hope they're good for merging now, because I'm tired of carrying
this changes forward in our internal trees. :P

Nevertheless, comments are welcome, as always.

[1] http://mid.gmane.org/1456752313-5792-1-git-send-email-emmanuel.grumbach@intel.com
[2] http://mid.gmane.org/1442500351-8780-1-git-send-email-andrei.otcheretianski@intel.com

Cheers,
Luca.


Ayala Beker (9):
  cfg80211: add start / stop NAN commands
  mac80211: add boilerplate code for start / stop NAN
  cfg80211: add add_nan_func / rm_nan_func
  cfg80211: allow the user space to change current NAN configuration
  cfg80211: provide a function to report a match for NAN
  cfg80211: Provide an API to report NAN function termination
  mac80211: implement nan_change_conf
  mac80211: Implement add_nan_func and rm_nan_func
  mac80211: Add API to report NAN function match

 include/net/cfg80211.h       | 184 ++++++++++++-
 include/net/mac80211.h       |  65 +++++
 include/uapi/linux/nl80211.h | 258 +++++++++++++++++
 net/mac80211/cfg.c           | 208 ++++++++++++++
 net/mac80211/chan.c          |   6 +
 net/mac80211/driver-ops.h    |  82 +++++-
 net/mac80211/ieee80211_i.h   |  17 ++
 net/mac80211/iface.c         |  28 +-
 net/mac80211/main.c          |   8 +
 net/mac80211/offchannel.c    |   4 +-
 net/mac80211/rx.c            |   3 +
 net/mac80211/trace.h         | 133 +++++++++
 net/mac80211/util.c          |  50 +++-
 net/wireless/chan.c          |   2 +
 net/wireless/core.c          |  35 +++
 net/wireless/core.h          |   3 +
 net/wireless/mlme.c          |   1 +
 net/wireless/nl80211.c       | 642 ++++++++++++++++++++++++++++++++++++++++++-
 net/wireless/rdev-ops.h      |  58 ++++
 net/wireless/trace.h         |  90 ++++++
 net/wireless/util.c          |  28 +-
 21 files changed, 1894 insertions(+), 11 deletions(-)

-- 
2.9.3

^ permalink raw reply

* [PATCH v2 07/25] iwlwifi: introduce trans API to get byte count table
From: Luca Coelho @ 2016-09-16  7:55 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Sara Sharon, Luca Coelho
In-Reply-To: <1474012383.5664.62.camel@coelho.fi>

From: Sara Sharon <sara.sharon@intel.com>

In future HW the byte count table address will be configured
by ucode per queue. Add API to expose the byte count table to
the opmode

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h     | 11 +++++++++++
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  1 +
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c    |  2 ++
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c       |  8 ++++++++
 4 files changed, 22 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 883cb487b..04e998d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -645,6 +645,8 @@ struct iwl_trans_ops {
 	void (*txq_set_shared_mode)(struct iwl_trans *trans, u32 txq_id,
 				    bool shared);
 
+	dma_addr_t (*get_txq_byte_table)(struct iwl_trans *trans, int txq_id);
+
 	int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
 	void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
 				 bool freeze);
@@ -1069,6 +1071,15 @@ static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans,
 		trans->ops->txq_set_shared_mode(trans, queue, shared_mode);
 }
 
+static inline dma_addr_t iwl_trans_get_txq_byte_table(struct iwl_trans *trans,
+						      int queue)
+{
+	/* we should never be called if the trans doesn't support it */
+	BUG_ON(!trans->ops->get_txq_byte_table);
+
+	return trans->ops->get_txq_byte_table(trans, queue);
+}
+
 static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
 					int fifo, int sta_id, int tid,
 					int frame_limit, u16 ssn,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 975900a..b9dc82b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -476,6 +476,7 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue,
 				bool configure_scd);
 void iwl_trans_pcie_txq_set_shared_mode(struct iwl_trans *trans, u32 txq_id,
 					bool shared_mode);
+dma_addr_t iwl_trans_pcie_get_txq_byte_table(struct iwl_trans *trans, int txq);
 void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans,
 				  struct iwl_txq *txq);
 int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 0c2ccbe..21b1be1 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2803,6 +2803,8 @@ static const struct iwl_trans_ops trans_ops_pcie = {
 	.txq_disable = iwl_trans_pcie_txq_disable,
 	.txq_enable = iwl_trans_pcie_txq_enable,
 
+	.get_txq_byte_table = iwl_trans_pcie_get_txq_byte_table,
+
 	.txq_set_shared_mode = iwl_trans_pcie_txq_set_shared_mode,
 
 	.wait_tx_queue_empty = iwl_trans_pcie_wait_txq_empty,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 1c46f14..57a657a 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1352,6 +1352,14 @@ void iwl_trans_pcie_txq_set_shared_mode(struct iwl_trans *trans, u32 txq_id,
 	txq->ampdu = !shared_mode;
 }
 
+dma_addr_t iwl_trans_pcie_get_txq_byte_table(struct iwl_trans *trans, int txq)
+{
+	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+	return trans_pcie->scd_bc_tbls.dma +
+	       txq * sizeof(struct iwlagn_scd_bc_tbl);
+}
+
 void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
 				bool configure_scd)
 {
-- 
2.9.3

^ permalink raw reply related

* pull-request: iwlwifi-next 2016-09-15-2
From: Luca Coelho @ 2016-09-16  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, linuxwifi
In-Reply-To: <1474000615.5664.57.camel@coelho.fi>

[-- Attachment #1: Type: text/plain, Size: 4967 bytes --]

Hi Kalle,

This is v2 of my pull-request.  I have fixed the compilation error with
alpha (and possibly other) platforms.

I'll send v2 of the changed patch as a reply to this email.

Let me know if everything's fine (or not). :)

Luca.


The following changes since commit 76f8c0e17edc6eba43f84952e5a87c7f50f69370:

  iwlwifi: pcie: remove dead code (2016-08-30 14:16:43 +0300)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git tags/iwlwifi-next-for-kalle-2016-09-15-2

for you to fetch changes up to fd659f8e75b7f8214b4f323d46248205b4566e10:

  iwlwifi: mvm: tighten BAID range check (2016-09-16 09:10:35 +0300)

----------------------------------------------------------------
* work for new hardware support continues
* dynamic queue allocation stabilization
* improvements in the MSIx code
* multiqueue support work continues
* new firmware version support
* general cleanups and improvements

----------------------------------------------------------------
Emmanuel Grumbach (1):
      iwlwifi: mvm: bump max API to 26

Haim Dreyfuss (3):
      iwlwifi: pcie: Configure shared interrupt vector in MSIX mode
      iwlwifi: pcie: Set affinity mask for rx interrupt vectors per cpu
      iwlwifi: pcie: replace possible_cpus() with online_cpus() in MSIX mode

Johannes Berg (3):
      iwlwifi: mvm: make RSS RX more robust
      iwlwifi: mvm: remove pointless _bh from spinlock in timer
      iwlwifi: mvm: tighten BAID range check

Liad Kaufman (3):
      iwlwifi: mvm: don't free queue after delba in dqa
      iwlwifi: mvm: fix pending frames tracking on tx resp
      iwlwifi: mvm: free reserved queue on STA removal

Oren Givon (2):
      iwlwifi: add the new 9560 series
      iwlwifi: add the new 8275 series

Sara Sharon (10):
      iwlwifi: mvm: call a different txq_enable function
      iwlwifi: pcie: introduce new tfd and tb formats
      iwlwifi: mvm: remove dump of locked registers
      iwlwifi: mvm: support new shared memory config API
      iwlwifi: introduce trans API to get byte count table
      iwlwifi: pcie: assign and access a000 TFD & TBs
      iwlwifi: change byte count table for a000 devices
      iwlwifi: pcie: merge iwl_queue and iwl_txq
      iwlwifi: mvm: support new BA notification response
      iwlwifi: pcie: change indentation of iwl_pcie_set_interrupt_capa()

Sharon Dvir (1):
      iwlwifi: unify iwl_get_ucode_image() implementations

Wei Yongjun (1):
      iwlwifi: mvm: use setup_timer instead of init_timer and data fields

kbuild test robot (1):
      iwlwifi: fix semicolon.cocci warnings

 drivers/net/wireless/intel/iwlwifi/dvm/ucode.c     |  11 +--
 drivers/net/wireless/intel/iwlwifi/iwl-7000.c      |   4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-8000.c      |  15 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-9000.c      |  13 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-a000.c      |   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h    |   2 +
 drivers/net/wireless/intel/iwlwifi/iwl-csr.h       |   2 +
 drivers/net/wireless/intel/iwlwifi/iwl-fh.h        |  57 +++++++++---
 drivers/net/wireless/intel/iwlwifi/iwl-fw.h        |   9 ++
 drivers/net/wireless/intel/iwlwifi/iwl-io.c        |   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-trans.c     |   1 +
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h     |  15 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h |  79 ++++++++++++++++
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h    |  22 ++++-
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c    |   4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c        | 109 ++++++++++++----------
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h       |   9 +-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c       |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c      |   8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c       |  36 ++++++--
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c        | 175 +++++++++++++++++++++++------------
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c      |   5 +
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 127 +++++++++++++++----------
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c       |  16 +++-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c    | 247 +++++++++++++++++++++++++++++++++----------------
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c       | 384 +++++++++++++++++++++++++++++++++++++++++++++-------------------------------
 26 files changed, 897 insertions(+), 459 deletions(-)

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* RE: [PATCH v8] cfg80211: Provision to allow the support for different beacon intervals
From: Undekari, Sunil Dutt @ 2016-09-16  6:34 UTC (permalink / raw)
  To: Johannes Berg, Kushwaha, Purushottam
  Cc: linux-wireless@vger.kernel.org, Malinen, Jouni,
	Hullur Subramanyam, Amarnath
In-Reply-To: <1473675843.29016.18.camel@sipsolutions.net>

PkluIG9yZGVyIHRvIHZhbGlkYXRlIGEgbmV3IGJlYWNvbiBpbnRlcnZhbCwgeW91J3JlIGZpcnN0
IGxvb2tpbmcgdXAgdGhlIG1pbiBHQ0QgdmFsdWUgb2YgYWxsIHRoZSBjb21iaW5hdGlvbnMgdGhh
dCBhbGxvdyB0aGUgKmN1cnJlbnQqIHNjZW5hcmlvLCBidXQgZG9pbmcgdGhhdCBtYXRjaGluZyB3
aXRob3V0IHRoZSByaWdodCAjIG9mIGNoYW5uZWxzIG9yID5yYWRhciBkZXRlY3QgcGFyYW1ldGVy
cz8gQW5kIHRoZW4geW91J3JlIHRyeWluZyB0byBtYXRjaCB0aGF0IHRvIHRoZSBuZXcgYmVhY29u
IGludGVydmFsPw0KWWVzIC4gUGxlYXNlIGFsbG93IHVzIHRvIGV4cGxhaW4gdGhlIHJhdGlvbmFs
ZSBmb3IgZG9pbmcgc28uIA0KMS4gVGhlIGludGVudGlvbiBoZXJlIGlzIHRvIGVuc3VyZSB0aGF0
IHRoZSBiZWFjb24gaW50ZXJ2YWwgY29uZmlndXJlZCBmb3IgYW55IHNpbmdsZSBpbnRlcmZhY2Ug
aXMgZ3JlYXRlciB0aGFuIHRoZSAiZGlmZl9iZWFjb25faW50X2djZF9taW4iICBzcGVjaWZpZWQg
aW4gdGhlIHJlc3BlY3RpdmUgY29tYmluYXRpb25zLiAgDQoyLiBTaW5jZSAiZGlmZl9iZWFjb25f
aW50X2djZF9taW4iICBpcyBvbmx5IHNwZWNpZmllZCAvIGFkdmVydGlzZWQgaW4gdGhlIGludGVy
ZmFjZSBjb21iaW5hdGlvbnMgLCBvdXIgbG9naWMgd2FzIHRvIGdldCB0aGUgbWluaW1hbCAiZGlm
Zl9iZWFjb25faW50X2djZF9taW4iIG9mIGFsbCB0aGUgbWF0Y2hpbmcgY29tYmluYXRpb25zIGFu
ZCBsYXRlciANCiAgICBjb21wYXJlIHdpdGggdGhlIG5ldyBiZWFjb24gaW50ZXJ2YWwuIChBUEkg
ImNmZzgwMjExX2l0ZXJfY29tYmluYXRpb25zIiBoYXMgdG8gYmUgaW52b2tlZCB0byBnZXQgdGhl
IGNvcnJlc3BvbmRpbmcgImRpZmZfYmVhY29uX2ludF9nY2RfbWluIikNCjMuIElmIHRoZSBiZWFj
b24gaW50ZXJ2YWwgY29uZmlndXJlZCBuZWVkcyB0byBiZSBlbnN1cmVkIHRvIGJlIGdyZWF0ZXIg
dGhhbiB0aGUgImRpZmZfYmVhY29uX2ludF9nY2RfbWluIiBjb25maWd1cmVkIGZvciBib3RoIHRo
ZSAic2luZ2xlIGludGVyZmFjZSIgYW5kICJpbnRlcmZhY2UgY29tYmluYXRpb24iICwgd2UgaGF2
ZSByZXNvcnRlZCB0byANCiAgICAgIjIiICAoZ2V0IHRoZSBtaW5pbWFsIG9mICJkaWZmX2JlYWNv
bl9pbnRfZ2NkX21pbiIgYW1vbmcgYWxsIHRoZSBtYXRjaGVkIGludGVyZmFjZSBjb21iaW5hdGlv
bnMgYW5kIHRoZW4gY29tcGFyZSBpdCB3aXRoIHRoZSBjb25maWd1cmVkIGJlYWNvbiBpbnRlcnZh
bCkuIA0KDQo+SWYgdGhlIGRyaXZlciBzcGVjaWZpZWQgZGlmZl9iZWFjb25faW50X2djZF9taW4s
IHRoZW4gZG9uJ3QgZG8gYW55dGhpbmcgaW4gY2ZnODAyMTFfdmFsaWRhdGVfYmVhY29uX2ludCgp
LCBvdGhlciB0aGFuIHBlcmhhcHMgYSBtaW5pbWFsIHJhbmdlIGNoZWNrIGFnYWluc3QgdGhlIG1p
bmltdW0gb2YgYWxsID5kaWZmX2JlYWNvbl9pbnRfZ2NkX21pbiB2YWx1ZXMgZm9yIGFsbCBjb21i
aW5hdGlvbnMuDQo+IFRoYXQgbmV3IGFyZ3VtZW50IGNvdWxkIGJlIG1hZGUgdGhlIEdDRCBvZiBh
bGwgZXhpc3RpbmcgYmVhY29uaW5nIGludGVyZmFjZXMgKG9yIDAgaWYgbm8gc3VjaCBleGlzdHMp
LCBzaW5jZSB0aGF0J3Mgc3VmZmljaWVudCBmb3IgY2hlY2tpbmcgYWdhaW5zdCBhIG5ldyBtaW5f
Z2NkLg0KSWYgSSB1bmRlcnN0YW5kIHRoaXMgY29ycmVjdGx5ICwgYXJlIHlvdSBzYXlpbmcgdGhh
dCB0aGlzIG5ldyBhcmd1bWVudCB0byBjZmc4MDIxMV9pdGVyX2NvbWJpbmF0aW9ucyBzaGFsbCBi
ZSB0aGUgR0NEIG9mIGFsbCB0aGUgZXhpc3RpbmcgYmVhY29uIGludGVydmFscyBhbmQgd291bGQg
YmUgdXNlZCB0byBtYXRjaCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nICJkaWZmX2JlYWNvbl9pbnRf
Z2NkX21pbiIgb2YgdGhlIGludGVyZmFjZSBjb21iaW5hdGlvbnMgaW4gImNmZzgwMjExX2l0ZXJf
Y29tYmluYXRpb25zIi4gDQpJZiB5ZXMgLCB0aGlzIEdDRCBhcmd1bWVudCBkb2VzIG5vdCByZXBy
ZXNlbnQgLCBpZiB0aGUgYmVhY29uIGludGVydmFscyBvZiBhbGwgdGhlIGV4aXN0aW5nIGludGVy
ZmFjZXMgZGlmZmVyIG9yIG5vdCAsIGlzbuKAmXQgPyBJZiB0aGUgImRpZmZfYmVhY29uX2ludF9n
Y2RfbWluIiAgb2YgdGhlIGFsbCB0aGUgbWF0Y2hpbmcgaW50ZXJmYWNlIGNvbWJpbmF0aW9ucyBp
cyAwICwgc3VjaCBkaWZmZXJlZCBiZWFjb24gaW50ZXJ2YWxzIHdvdWxkIHBhc3MgdGhlIGNoZWNr
ICwgY29udHJhZGljdGluZyB0aGUgZXhpc3RpbmcgbG9naWMgKCBub3QgYWxsb3dpbmcgdGhlIGRp
ZmZlcmVkIGJlYWNvbiBpbnRlcnZhbHMpLCBpc24ndCA/IA0KDQpUaHVzLCB3b3VsZG4ndCBpdCBi
ZSBhIGJldHRlciBvcHRpb24gdG8gZmlyc3QgZ2V0IHRoZSAiZGlmZl9iZWFjb25faW50X2djZF9t
aW4iIGFkdmVydGlzZWQgYnkgdGhlIHJlc3BlY3RpdmUgaW50ZXJmYWNlIGNvbWJpbmF0aW9ucyBh
bmQgdGhlbiBsYXRlciBjb21wYXJlIGl0IHdpdGggdGhlIGNvbmZpZ3VyZWQgLyBjYWxjdWxhdGVk
IGJlYWNvbiANCmludGVydmFsJ3MgR0NEIC4gDQpBbHNvICwgbm90IHF1aXRlIHN1cmUgaG93IHdv
dWxkIHlvdXIgY29tbWVudCAiIG1hdGNoaW5nIHdpdGhvdXQgdGhlIHJpZ2h0ICMgb2YgY2hhbm5l
bHMgb3IgcmFkYXIgZGV0ZWN0IHBhcmFtZXRlcnMiIGdldCBhZGRyZXNzZWQgd2l0aCB5b3VyIG5l
dyBwcm9wb3NhbCAoIGFkZGluZyBhIG5ldyBhcmd1bWVudCB0byAiY2ZnODAyMTFfaXRlcl9jb21i
aW5hdGlvbnMiICkgDQoNClJlZ2FyZHMsDQpTdW5pbA0KDQoNCg0KDQoNCi0tLS0tT3JpZ2luYWwg
TWVzc2FnZS0tLS0tDQpGcm9tOiBKb2hhbm5lcyBCZXJnIFttYWlsdG86am9oYW5uZXNAc2lwc29s
dXRpb25zLm5ldF0gDQpTZW50OiBNb25kYXksIFNlcHRlbWJlciAxMiwgMjAxNiAzOjU0IFBNDQpU
bzogS3VzaHdhaGEsIFB1cnVzaG90dGFtIDxwa3VzaHdhaEBxdGkucXVhbGNvbW0uY29tPg0KQ2M6
IGxpbnV4LXdpcmVsZXNzQHZnZXIua2VybmVsLm9yZzsgTWFsaW5lbiwgSm91bmkgPGpvdW5pQHFj
YS5xdWFsY29tbS5jb20+OyBVbmRla2FyaSwgU3VuaWwgRHV0dCA8dXNkdXR0QHF0aS5xdWFsY29t
bS5jb20+OyBIdWxsdXIgU3VicmFtYW55YW0sIEFtYXJuYXRoIDxhbWFybmF0aEBxY2EucXVhbGNv
bW0uY29tPg0KU3ViamVjdDogUmU6IFtQQVRDSCB2OF0gY2ZnODAyMTE6IFByb3Zpc2lvbiB0byBh
bGxvdyB0aGUgc3VwcG9ydCBmb3IgZGlmZmVyZW50IGJlYWNvbiBpbnRlcnZhbHMNCg0KSG1tLiBB
cGFydCBmcm9tIHNvbWUgbWlzbGVhZGluZyBkb2N1bWVudGF0aW9uLCB0aGF0IGRvZXNuJ3QgbWVu
dGlvbiAiR0NEIiBhdCBhbGwsIHRoZSBsb2dpYyBzZWVtcyBvZGQuDQoNCkluIG9yZGVyIHRvIHZh
bGlkYXRlIGEgbmV3IGJlYWNvbiBpbnRlcnZhbCwgeW91J3JlIGZpcnN0IGxvb2tpbmcgdXAgdGhl
IG1pbiBHQ0QgdmFsdWUgb2YgYWxsIHRoZSBjb21iaW5hdGlvbnMgdGhhdCBhbGxvdyB0aGUgKmN1
cnJlbnQqIHNjZW5hcmlvLCBidXQgZG9pbmcgdGhhdCBtYXRjaGluZyB3aXRob3V0IHRoZSByaWdo
dCAjIG9mIGNoYW5uZWxzIG9yIHJhZGFyIGRldGVjdCBwYXJhbWV0ZXJzPyBBbmQgdGhlbiB5b3Un
cmUgdHJ5aW5nIHRvIG1hdGNoIHRoYXQgdG8gdGhlIG5ldyBiZWFjb24gaW50ZXJ2YWw/DQoNCkl0
IHNlZW1zIHRvIG1lIHRoYXQgdGhlIGxvZ2ljIHNob3VsZCBiZSBzb21ldGhpbmcgbGlrZToNCg0K
SWYgdGhlIGRyaXZlciBzcGVjaWZpZWTCoGRpZmZfYmVhY29uX2ludF9nY2RfbWluLCB0aGVuIGRv
bid0IGRvIGFueXRoaW5nIGluwqBjZmc4MDIxMV92YWxpZGF0ZV9iZWFjb25faW50KCksIG90aGVy
IHRoYW4gcGVyaGFwcyBhIG1pbmltYWwgcmFuZ2UgY2hlY2sgYWdhaW5zdCB0aGUgbWluaW11bSBv
ZiBhbGwgZGlmZl9iZWFjb25faW50X2djZF9taW4gdmFsdWVzIGZvciBhbGwgY29tYmluYXRpb25z
Lg0KDQpUaGVuLCBhZGQgYSBuZXcgYXJndW1lbnQgdG/CoGNmZzgwMjExX2NoZWNrX2NvbWJpbmF0
aW9ucygpIChhbmQNCmNmZzgwMjExX2l0ZXJfY29tYmluYXRpb25zKCkpIHRvIGhhdmUgdGhlIGJl
YWNvbiBpbnRlcnZhbHMgZm9yIGVhY2ggYmVhY29uaW5nIGludGVyZmFjZSwgYW5kIHVzZSB0aGF0
IGluIG9yZGVyIHRvIG1hdGNoIGlmIGEgY29tYmluYXRpb24gZml0cywgaW5zaWRlwqBjZmc4MDIx
MV9pdGVyX2NvbWJpbmF0aW9ucygpLg0KDQpUaGF0IG5ldyBhcmd1bWVudCBjb3VsZCBiZSBtYWRl
IHRoZSBHQ0Qgb2YgYWxsIGV4aXN0aW5nIGJlYWNvbmluZyBpbnRlcmZhY2VzIChvciAwIGlmIG5v
IHN1Y2ggZXhpc3RzKSwgc2luY2UgdGhhdCdzIHN1ZmZpY2llbnQgZm9yIGNoZWNraW5nIGFnYWlu
c3QgYSBuZXcgbWluX2djZC4NCg0Kam9oYW5uZXMNCg==

^ permalink raw reply

* Re: pull-request: mac80211 2016-09-13
From: David Miller @ 2016-09-16  5:34 UTC (permalink / raw)
  To: johannes; +Cc: netdev, linux-wireless
In-Reply-To: <1473797004-24158-1-git-send-email-johannes@sipsolutions.net>

From: Johannes Berg <johannes@sipsolutions.net>
Date: Tue, 13 Sep 2016 22:03:23 +0200

> We found a few more issues, I'm sending you small fixes here. The diffstat
> would be even shorter, but one of Felix's patches has to move about 30 lines
> of code, which makes it seem much bigger than it really is.
> 
> Let me know if there's any problem.

Pulled, thanks Johannes.

^ permalink raw reply

* Re: pull-request: iwlwifi-next 2016-09-15
From: Luca Coelho @ 2016-09-16  4:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, linuxwifi
In-Reply-To: <1473962425.5664.41.camel@coelho.fi>

Huomenta Kalle,

The kbuild bot scripts reported a compilation error, because
DMA_ERROR_CODE is not defined in some platforms (e.g. alpha).

So please drop this pull request.  I'll fix the problem and send a new
version.

----------8<----------

All errors (new ones prefixed by >>):

   In file included from drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h:32:0,
                    from drivers/net/wireless/intel/iwlwifi/iwl-io.h:32,
                    from drivers/net/wireless/intel/iwlwifi/iwl-io.c:34:
   drivers/net/wireless/intel/iwlwifi/iwl-trans.h: In function 'iwl_trans_get_txq_byte_table':
>> drivers/net/wireless/intel/iwlwifi/iwl-trans.h:1079:9: error: 'DMA_ERROR_CODE' undeclared (first use in this function)
     return DMA_ERROR_CODE;
            ^
   drivers/net/wireless/intel/iwlwifi/iwl-trans.h:1079:9: note: each undeclared identifier is reported only once for each function it appears in
--
   In file included from drivers/net/wireless/intel/iwlwifi/dvm/../iwl-eeprom-read.h:66:0,
                    from drivers/net/wireless/intel/iwlwifi/dvm/main.c:48:
   drivers/net/wireless/intel/iwlwifi/dvm/../iwl-trans.h: In function 'iwl_trans_get_txq_byte_table':
>> drivers/net/wireless/intel/iwlwifi/dvm/../iwl-trans.h:1079:9: error: 'DMA_ERROR_CODE' undeclared (first use in this function)
     return DMA_ERROR_CODE;
            ^
   drivers/net/wireless/intel/iwlwifi/dvm/../iwl-trans.h:1079:9: note: each undeclared identifier is reported only once for each function it appears in
--
   In file included from drivers/net/wireless/intel/iwlwifi/mvm/fw.c:70:0:
   drivers/net/wireless/intel/iwlwifi/mvm/../iwl-trans.h: In function 'iwl_trans_get_txq_byte_table':
>> drivers/net/wireless/intel/iwlwifi/mvm/../iwl-trans.h:1079:9: error: 'DMA_ERROR_CODE' undeclared (first use in this function)
     return DMA_ERROR_CODE;
            ^
   drivers/net/wireless/intel/iwlwifi/mvm/../iwl-trans.h:1079:9: note: each undeclared identifier is reported only once for each function it appears in

vim +/DMA_ERROR_CODE +1079 drivers/net/wireless/intel/iwlwifi/iwl-trans.h

  1073  
  1074  static inline dma_addr_t iwl_trans_get_txq_byte_table(struct iwl_trans *trans,
  1075                                                        int queue)
  1076  {
  1077          if (trans->ops->get_txq_byte_table)
  1078                  return trans->ops->get_txq_byte_table(trans, queue);
> 1079          return DMA_ERROR_CODE;
  1080  }
  1081  
  1082  static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,

---------->8----------

--
Cheers,
Luca.



On Thu, 2016-09-15 at 21:00 +0300, Luca Coelho wrote:
> Hi Kalle,
> 
> One more pull request intended for 4.9.  There are changes all over,
> mostly new hardware support, DQA, multiqueue MSIx work, and a bunch
> of
> cleanups and improvements.  More details in the tag description.
> 
> Let me know if everything's fine (or not). :)
> 
> Luca.
> 
> 
> The following changes since commit
> 76f8c0e17edc6eba43f84952e5a87c7f50f69370:
> 
>   iwlwifi: pcie: remove dead code (2016-08-30 14:16:43 +0300)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-
> next.git tags/iwlwifi-next-for-kalle-2016-09-15
> 
> for you to fetch changes up to
> ace403cf409d68c61ae75e71fd8a681263d73e20:
> 
>   iwlwifi: mvm: tighten BAID range check (2016-09-15 20:43:47 +0300)
> 
> ----------------------------------------------------------------
> * work for new hardware support continues
> * dynamic queue allocation stabilization
> * improvements in the MSIx code
> * multiqueue support work continues
> * new firmware version support
> * general cleanups and improvements
> 
> ----------------------------------------------------------------
> Emmanuel Grumbach (1):
>       iwlwifi: mvm: bump max API to 26
> 
> Haim Dreyfuss (3):
>       iwlwifi: pcie: Configure shared interrupt vector in MSIX mode
>       iwlwifi: pcie: Set affinity mask for rx interrupt vectors per
> cpu
>       iwlwifi: pcie: replace possible_cpus() with online_cpus() in
> MSIX mode
> 
> Johannes Berg (3):
>       iwlwifi: mvm: make RSS RX more robust
>       iwlwifi: mvm: remove pointless _bh from spinlock in timer
>       iwlwifi: mvm: tighten BAID range check
> 
> Liad Kaufman (3):
>       iwlwifi: mvm: don't free queue after delba in dqa
>       iwlwifi: mvm: fix pending frames tracking on tx resp
>       iwlwifi: mvm: free reserved queue on STA removal
> 
> Oren Givon (2):
>       iwlwifi: add the new 9560 series
>       iwlwifi: add the new 8275 series
> 
> Sara Sharon (10):
>       iwlwifi: mvm: call a different txq_enable function
>       iwlwifi: pcie: introduce new tfd and tb formats
>       iwlwifi: mvm: remove dump of locked registers
>       iwlwifi: mvm: support new shared memory config API
>       iwlwifi: introduce trans API to get byte count table
>       iwlwifi: pcie: assign and access a000 TFD & TBs
>       iwlwifi: change byte count table for a000 devices
>       iwlwifi: pcie: merge iwl_queue and iwl_txq
>       iwlwifi: mvm: support new BA notification response
>       iwlwifi: pcie: change indentation of
> iwl_pcie_set_interrupt_capa()
> 
> Sharon Dvir (1):
>       iwlwifi: unify iwl_get_ucode_image() implementations
> 
> Wei Yongjun (1):
>       iwlwifi: mvm: use setup_timer instead of init_timer and data
> fields
> 
> kbuild test robot (1):
>       iwlwifi: fix semicolon.cocci warnings
> 
>  drivers/net/wireless/intel/iwlwifi/dvm/ucode.c     |  11 +--
>  drivers/net/wireless/intel/iwlwifi/iwl-7000.c      |   4 +-
>  drivers/net/wireless/intel/iwlwifi/iwl-8000.c      |  15 ++-
>  drivers/net/wireless/intel/iwlwifi/iwl-9000.c      |  13 ++-
>  drivers/net/wireless/intel/iwlwifi/iwl-a000.c      |   2 +-
>  drivers/net/wireless/intel/iwlwifi/iwl-config.h    |   2 +
>  drivers/net/wireless/intel/iwlwifi/iwl-csr.h       |   2 +
>  drivers/net/wireless/intel/iwlwifi/iwl-fh.h        |  57 +++++++++
> ---
>  drivers/net/wireless/intel/iwlwifi/iwl-fw.h        |   9 ++
>  drivers/net/wireless/intel/iwlwifi/iwl-io.c        |   2 +-
>  drivers/net/wireless/intel/iwlwifi/iwl-trans.c     |   1 +
>  drivers/net/wireless/intel/iwlwifi/iwl-trans.h     |  14 ++-
>  drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h |  79
> ++++++++++++++++
>  drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h    |  22 ++++-
>  drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c    |   4 +-
>  drivers/net/wireless/intel/iwlwifi/mvm/fw.c        | 109
> ++++++++++++----------
>  drivers/net/wireless/intel/iwlwifi/mvm/mvm.h       |   9 +-
>  drivers/net/wireless/intel/iwlwifi/mvm/ops.c       |   2 +-
>  drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c      |   8 +-
>  drivers/net/wireless/intel/iwlwifi/mvm/sta.c       |  36 ++++++--
>  drivers/net/wireless/intel/iwlwifi/mvm/tx.c        | 175
> +++++++++++++++++++++++------------
>  drivers/net/wireless/intel/iwlwifi/pcie/drv.c      |   5 +
>  drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 127
> +++++++++++++++----------
>  drivers/net/wireless/intel/iwlwifi/pcie/rx.c       |  16 +++-
>  drivers/net/wireless/intel/iwlwifi/pcie/trans.c    | 247
> +++++++++++++++++++++++++++++++++----------------
>  drivers/net/wireless/intel/iwlwifi/pcie/tx.c       | 384
> +++++++++++++++++++++++++++++++++++++++++++++----------------------
> ---------
>  26 files changed, 896 insertions(+), 459 deletions(-)

^ permalink raw reply

* Re: [PATCH] mwifiex: fix null pointer deference when adapter is null
From: Kalle Valo @ 2016-09-16  3:56 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Colin King, kbuild-all, Amitkumar Karwar, Nishant Sarmukadam,
	linux-wireless, netdev, linux-kernel
In-Reply-To: <201609160029.fRGnTGuA%fengguang.wu@intel.com>

kbuild test robot <lkp@intel.com> writes:

> url:    https://github.com/0day-ci/linux/commits/Colin-King/mwifiex-fix-null-pointer-deference-when-adapter-is-null/20160915-231625
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
> config: x86_64-randconfig-x013-201637 (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
>
> All warnings (new ones prefixed by >>):
>
>    drivers/net/wireless/marvell/mwifiex/main.c: In function 'mwifiex_shutdown_sw':
>>> drivers/net/wireless/marvell/mwifiex/main.c:1433:1: warning: label 'exit_remove' defined but not used [-Wunused-label]
>     exit_remove:
>     ^~~~~~~~~~~

Looks like a valid warning to me, so please resend.

-- 
Kalle Valo

^ permalink raw reply

* Re: brcmfmac43430-sdio.bin in linux-firmware
From: Fabio Estevam @ 2016-09-15 23:09 UTC (permalink / raw)
  To: Arend Van Spriel; +Cc: linux-wireless, brcm80211-dev-list, Hante Meuleman
In-Reply-To: <e9fde75d-a17a-8a3e-feee-6495eec0f67f@broadcom.com>

Hi Arend,

On Wed, Aug 24, 2016 at 4:22 PM, Arend Van Spriel
<arend.vanspriel@broadcom.com> wrote:

> I could, but this is handled by Cypress now. I have asked for firmware
> release tag so I can release it.

I see brcmfmac43430-sdio.bin in linux-firmware git tree now.

Thanks a lot for your help!

^ permalink raw reply

* Re: [PATCH v2 09/21] ath10k: print fw debug messages in hex.
From: Grumbach, Emmanuel @ 2016-09-15 20:22 UTC (permalink / raw)
  To: greearb@candelatech.com, kvalo@qca.qualcomm.com
  Cc: linux-wireless@vger.kernel.org, ath10k@lists.infradead.org
In-Reply-To: <50a08de4-1959-3dc9-cfc7-89d5b2914cc5@candelatech.com>

T24gVGh1LCAyMDE2LTA5LTE1IGF0IDEwOjU5IC0wNzAwLCBCZW4gR3JlZWFyIHdyb3RlOg0KPiBP
biAwOS8xNS8yMDE2IDEwOjM0IEFNLCBHcnVtYmFjaCwgRW1tYW51ZWwgd3JvdGU6DQo+ID4gT24g
VGh1LCAyMDE2LTA5LTE1IGF0IDA4OjE0IC0wNzAwLCBCZW4gR3JlZWFyIHdyb3RlOg0KPiA+ID4g
T24gMDkvMTUvMjAxNiAwNzowNiBBTSwgVmFsbywgS2FsbGUgd3JvdGU6DQo+ID4gPiA+IEJlbiBH
cmVlYXIgPGdyZWVhcmJAY2FuZGVsYXRlY2guY29tPiB3cml0ZXM6DQo+ID4gPiA+IA0KPiA+ID4g
PiA+IE9uIDA5LzE0LzIwMTYgMDc6MTggQU0sIFZhbG8sIEthbGxlIHdyb3RlOg0KPiA+ID4gPiA+
ID4gZ3JlZWFyYkBjYW5kZWxhdGVjaC5jb20gd3JpdGVzOg0KPiA+ID4gPiA+ID4gDQo+ID4gPiA+
ID4gPiA+IEZyb206IEJlbiBHcmVlYXIgPGdyZWVhcmJAY2FuZGVsYXRlY2guY29tPg0KPiA+ID4g
PiA+ID4gPiANCj4gPiA+ID4gPiA+ID4gVGhpcyBhbGxvd3MgdXNlci1zcGFjZSB0b29scyB0byBk
ZWNvZGUgZGVidWctbG9nDQo+ID4gPiA+ID4gPiA+IG1lc3NhZ2VzIGJ5IHBhcnNpbmcgZG1lc2cg
b3IgL3Zhci9sb2cvbWVzc2FnZXMuDQo+ID4gPiA+ID4gPiA+IA0KPiA+ID4gPiA+ID4gPiBTaWdu
ZWQtb2ZmLWJ5OiBCZW4gR3JlZWFyIDxncmVlYXJiQGNhbmRlbGF0ZWNoLmNvbT4NCj4gPiA+ID4g
PiA+IA0KPiA+ID4gPiA+ID4gRG9uJ3QgdHJhY2luZyBwb2ludHMgYWxyZWFkeSBwcm92aWRlIHRo
ZSBzYW1lIGluZm9ybWF0aW9uPw0KPiA+ID4gPiA+IA0KPiA+ID4gPiA+IFRyYWNpbmcgdG9vbHMg
YXJlIGRpZmZpY3VsdCB0byBzZXQgdXAgYW5kIG1heSBub3QgYmUNCj4gPiA+ID4gPiBhdmFpbGFi
bGUgb24NCj4gPiA+ID4gPiByYW5kb20gZW1iZWRkZWQgZGV2aWNlcy4gIEFuZCBpZiB3ZSBhcmUg
ZGVhbGluZyB3aXRoIGJ1Zw0KPiA+ID4gPiA+IHJlcG9ydHMNCj4gPiA+ID4gPiBmcm9tDQo+ID4g
PiA+ID4gdGhlIGZpZWxkLCBtb3N0IHVzZXJzIHdpbGwgbm90IGJlIGFibGUgdG8gc2V0IGl0IHVw
DQo+ID4gPiA+ID4gcmVnYXJkbGVzcy4NCj4gPiA+ID4gPiANCj4gPiA+ID4gPiBUaGVyZSBhcmUg
c2ltaWxhciB3YXlzIHRvIHByaW50IG91dCBoZXgsIGJ1dCB0aGUgbG9naWMgYmVsb3cNCj4gPiA+
ID4gPiBjcmVhdGVzDQo+ID4gPiA+ID4gc3BlY2lmaWMgYW5kIHBhcnNlYWJsZSBsb2dzIGluIHRo
ZSAnZG1lc2cnIG91dHB1dCBhbmQNCj4gPiA+ID4gPiBzaW1pbGFyLg0KPiA+ID4gPiA+IA0KPiA+
ID4gPiA+IEkgaGF2ZSB3cml0dGVuIGEgdG9vbCB0aGF0IGNhbiBkZWNvZGUgdGhlc2UgbWVzc2Fn
ZXMgaW50bw0KPiA+ID4gPiA+IHVzZWZ1bA0KPiA+ID4gPiA+IGh1bWFuLXJlYWRhYmxlDQo+ID4g
PiA+ID4gdGV4dCBzbyB0aGF0IEkgY2FuIGRlYnVnIGZpcm13YXJlIGlzc3VlcyBib3RoIGxvY2Fs
bHkgYW5kDQo+ID4gPiA+ID4gZnJvbQ0KPiA+ID4gPiA+IGZpZWxkIHJlcG9ydHMuDQo+ID4gPiA+
ID4gDQo+ID4gPiA+ID4gU3RvY2sgZmlybXdhcmUgZ2VuZXJhdGVzIHNpbWlsYXIgbG9ncyBhbmQg
UUNBIGNvdWxkIHdyaXRlDQo+ID4gPiA+ID4gdGhlaXINCj4gPiA+ID4gPiBvd24gZGVjb2RlIGxv
Z2ljDQo+ID4gPiA+ID4gZm9yIHRoZWlyIGZpcm13YXJlIHZlcnNpb25zLg0KPiA+ID4gPiANCj4g
PiA+ID4gUmVpbnZlbnRpbmcgdGhlIHdoZWVsIGJ5IHVzaW5nIHByaW50ayBhcyB0aGUgZGVsaXZl
cnkgbWVjaGFuaXNtDQo+ID4gPiA+IGRvZXNuJ3QNCj4gPiA+ID4gc291bmQgbGlrZSBhIGdvb2Qg
aWRlYS4gSUlSQyBFbW1hbnVlbCB0YWxrZWQgYWJvdXQgc29tZSBraW5kIG9mDQo+ID4gPiA+IGZp
cm13YXJlDQo+ID4gPiA+IGRlYnVnZ2luZyBmcmFtZXdvcmssIGhlIG1pZ2h0IGhhdmUgc29tZSBp
ZGVhcy4NCj4gPiA+IA0KPiA+ID4gV2FpdGluZyBmb3IgbWFnaWNhbCBmcmFtZXdvcmtzIHRvIGZp
eCBwcm9ibGVtcyBpcyBldmVuIHdvcnNlLg0KPiA+ID4gDQo+ID4gSXQgaGFzIGJlZW4geWVhcnMg
c2luY2UgYXRoMTBrIGhhcyBiZWVuIGluIHRoZSBrZXJuZWwuICBUaGVyZSBpcw0KPiA+ID4gYmFz
aWNhbGx5DQo+ID4gPiBzdGlsbCBubyB3YXkgdG8gZGVidWcgd2hhdCB0aGUgZmlybXdhcmUgaXMg
ZG9pbmcuDQo+ID4gPiANCj4gPiANCj4gPiBJIGtub3cgdGhlIGZlZWxpbmcgOikgSSB3YXMgaW4g
dGhlIHNhbWUgc2l0dWF0aW9uIGJlZm9yZSBJIGFkZGVkDQo+ID4gc3R1ZmYNCj4gPiBmb3IgaXds
d2lmaS4NCj4gPiANCj4gPiA+IE15IHBhdGNoIGdpdmVzIHlvdSBzb21ldGhpbmcgdGhhdCBjYW4g
d29yayByaWdodCBub3csIHdpdGggdGhlDQo+ID4gPiBzdGFuZGFyZCAnZG1lc2cnDQo+ID4gPiBm
cmFtZXdvcmsgZm91bmQgaW4gdmlydHVhbGx5IGFsbCBrZXJuZWxzIG5ldyBhbmQgb2xkLCBhbmQg
aXQgaGFzDQo+ID4gPiBiZWVuDQo+ID4gPiBwcm92ZW4NCj4gPiA+IHRvIGJlIHVzZWZ1bCBpbiB0
aGUgZmllbGQuICBUaGUgbWVzc2FnZXMgYXJlIGFsc28gbmljZWx5DQo+ID4gPiBpbnRlcmxlYXZl
ZA0KPiA+ID4gd2l0aCB0aGUNCj4gPiA+IHJlc3Qgb2YgdGhlIG1hYzgwMjExIHN0YWNrIG1lc3Nh
Z2VzIGFuZCBhbnkgb3RoZXIgZHJpdmVyDQo+ID4gPiBtZXNzYWdlcywgc28NCj4gPiA+IHlvdSBo
YXZlDQo+ID4gPiBjb250ZXh0Lg0KPiA+ID4gDQo+ID4gPiBJZiBzb21lb25lIHdhbnRzIHRvIGFk
ZCBzdXBwb3J0IGZvciBhIGZyYW1ld29yayBsYXRlciwgdGhlbiBieQ0KPiA+ID4gYWxsDQo+ID4g
PiBtZWFucywgcG9zdA0KPiA+ID4gdGhlIHBhdGNoZXMgd2hlbiBpdCBpcyByZWFkeS4NCj4gPiAN
Cj4gPiBGcm9tIG15IGV4cGVyaWVuY2UsIGEgc3Ryb25nIGFuZCBlYXN5LXRvLXVzZSBmaXJtd2Fy
ZSBkZWJ1Zw0KPiA+IGluZnJhc3RydWN0dXJlIGlzIGltcG9ydGFudCBiZWNhdXNlIHR5cGljYWxs
eSwgdGhlIGZpcm13YXJlIGlzDQo+ID4gd3JpdHRlbg0KPiA+IGJ5IG90aGVyIHBlb3BsZSB3aG8g
aGF2ZSBkaWZmZXJlbnQgcHJpb3JpdGllcyAoYW5kIGFyZSBub3QgYWx3YXlzDQo+ID4gTGludXgN
Cj4gPiB3aXphcmRzKSBldGMuLi4gQmVpbmcgYWJsZSB0byBnaXZlIHRoZW0gZ29vZCBkYXRhIGlz
IHRoZSBvbmx5IHdheQ0KPiA+IHRvDQo+ID4gaGF2ZSB0aGVtIGZpeCB0aGVpciBidWdzIDopIEZv
ciB1cywgaXQgd2FzIHJlYWxseSBhIGdhbWUgY2hhbmdlci4NCj4gPiBXaGVuDQo+ID4geW91IHdv
cmsgZm9yIGEgYmlnIGNvcnBvcmF0ZSwgaGF2aW5nIDIgZ3JvdXBzIHdvcmsgYmV0dGVyIHRvZ2V0
aGVyDQo+ID4gYWx3YXlzIGhhcyBhIGJpZyBpbXBhY3QuIFRoYXQncyBmb3IgdGhlIHBoaWxvc29w
aGljYWwgcGFydCA6KQ0KPiA+IA0KPiA+IEZXSVc6IHdoYXQgSSBkaWQgaGFzIG5vdGhpbmcgdG8g
ZG8gd2l0aCBGVyAnbGl2ZSB0cmFjaW5nJywgYnV0IHdpdGgNCj4gPiBmaXJtd2FyZSBkdW1wcy4g
T25lIHBhcnQgb2Ygb3VyIGZpcm13YXJlIGR1bXBzIGluY2x1ZGUgdHJhY2luZy4gV2UNCj4gPiBh
bHNvDQo+ID4gaGF2ZSAiZmlybXdhcmUgcHJpbnRzIiwgYnV0IHdlIGRvbid0IHByaW50IHRoZW0g
aW4gdGhlIGtlcm5lbCBsb2cNCj4gPiBhbmQNCj4gPiB0aGV5IGFyZSBub3QgcGFydCBvZiB0aGUg
ZmlybXdhcmUgZHVtcCB0aGluZy4gV2UgcmF0aGVyIHJlY29yZCB0aGVtDQo+ID4gaW4NCj4gPiB0
cmFjZXBvaW50cyBqdXN0IGxpa2UgcmVhbGx5ICphbnl0aGluZyogdGhhdCBjb21lcyBmcm9tIHRo
ZQ0KPiA+IGZpcm13YXJlLg0KPiA+IEJhc2ljYWxseSwgd2UgaGF2ZSAyIGxheWVycywgdGhlIHRy
YW5zcG9ydCBsYXllciAoUENJZSkgYW5kIHRoZQ0KPiA+IG9wZXJhdGlvbl9tb2RlIGxheWVyLiBU
aGUgZmlyc3QganVzdCBicmluZ3MgdGhlIGRhdGEgZnJvbSB0aGUNCj4gPiBmaXJtd2FyZQ0KPiA+
IGFuZCBpbiB0aGF0IGxheWVyIHdlICpibGluZGx5KiByZWNvcmQgZXZlcnl0aGluZyBpbiB0cmFj
ZXBvaW50cy4gSW4NCj4gPiB0aGUNCj4gPiBvcGVyYXRpb25fbW9kZSBsYXllciwgd2UgbG9vayBh
dCB0aGUgZGF0YSBpdHNlbGYuIEluIGNhc2Ugb2YgZGVidWcNCj4gPiBwcmludHMgZnJvbSB0aGUg
ZmlybXdhcmUsIHdlIHNpbXBseSBkaXNjYXJkIHRoZW0sIGJlY2F1c2Ugd2UgZG9uJ3QNCj4gPiBy
ZWFsbHkgY2FyZSBvZiB0aGUgbWVhbmluZy4gQWxsIHdlIHdhbnQgaXMgdG8gaGF2ZSB0aGVtIGdv
IHRocm91Z2gNCj4gPiB0aGUNCj4gPiBQQ0llIGxheWVyIHNvIHRoYXQgdGhleSBhcmUgcmVjb3Jk
ZWQgaW4gdGhlIHRyYWNlcG9pbnRzLg0KPiA+IFdoZW4gd2UgZmluaXNoIHJlY29yZGluZyB0aGUg
c2VxdWVuY2Ugd2Ugd2FudGVkIHdpdGggdHJhY2luZyAodHJhY2UNCj4gPiAtY21kKSwgd2UgcGFy
c2UgdGhlIG91dHB1dCBhbmQgdGhlbiwgd2UgcGFyc2UgdGhlIGZpcm13YXJlIHByaW50cy4NCj4g
PiBJTUhPLCB0aGlzIGlzIG1vcmUgcmVsaWFibGUgdGhhbiBrZXJuZWwgbG9ncyBhbmQgeW91IGRv
bid0IGxvc2UgdGhlDQo+ID4gYWxpZ25tZW50IHdpdGggdGhlIGRyaXZlciB0cmFjZXMgYXMgbG9u
ZyBhcyB5b3UgaGF2ZSBkcml2ZXIgZGF0YSBpbg0KPiA+IHRyYWNlcG9pbnRzIGFzIHdlbGwuDQo+
IA0KPiBJIGhhdmUgb3RoZXIgcGF0Y2hlcyB0aGF0IHJlbWVtYmVyIHRoZSBsYXN0IDEwMCBvciBz
byBmaXJtd2FyZSBsb2cNCj4gbWVzc2FnZXMgZnJvbQ0KPiB0aGUga2VybmVsIGFuZCBwcm92aWRl
IHRoYXQgaW4gYSBiaW5hcnkgZHVtcCBpbWFnZSB3aGVuIGZpcm13YXJlDQo+IGNyYXNoZXMuDQo+
IA0KPiBUaGlzIGlzIGluZGVlZCB2ZXJ5IHVzZWZ1bC4NCj4gDQo+IEJ1dCwgd2hlbiBkZWJ1Z2dp
bmcgbm9uLWNyYXNoIG9jY2FzaW9ucywgaXQgaXMgc3RpbGwgdXNlZnVsIHRvIHNlZQ0KPiB3aGF0
DQo+IHRoZSBmaXJtd2FyZSBpcyBkb2luZy4NCj4gDQoNCkZvciB0aGF0LCBJIGhhdmUgY29tZSB1
cCB3aXRoIHRoZSAidHJpZ2dlcnMiLiBUcmlnZ2VycyBhcmUgY29uZGl0aW9ucw0KdGhhdCBjYW4g
YmUgZGV0ZWN0ZWQgYnkgdGhlIGRyaXZlciBhbmQgZW5hYmxlZCBieSB0aGUgdXNlci4gU28NCmJh
c2ljYWxseSwgd2UgY2FuIHNheTogIlBsZWFzZSBkdW1wIHRoZSBsb2dzIHdoZW4geW91IGFyZSBk
ZWF1dGgnZWQgYnkNCnRoZSBBUCIuIE9yIHdoZW4geW91IGdldCBkZWxCQSwgb3Igd2hlbiB0aGUg
c3RhdHMgdGhhdCBjb21lIHVwIGZyb20gdGhlDQpmaXJtd2FyZSBzYXkgc3VjaCBhbmQgc3VjaCBl
dGMuLi4gVGhlcmUgYXJlIGhvb2tzIHRoYXQgSSBhZGRlZCBpbg0KbWFjODAyMTEgdG8gbGV0IHRo
ZSBkcml2ZXIga25vdyBhYm91dCBldmVudHMgdGhhdCBhcmUgaGFuZGxlZCB0aGVyZQ0KKE1MTUUg
YW5kIGZyaWVuZHMpLiBUaGVuLCBldmVuIGlmIHlvdXIgbG9ncyBhcmUgc3RvcmVkIGluIGEgY3lj
bGljDQpidWZmZXIsIHlvdSBkb24ndCBtaXNzIHRoZW0gYW5kIHlvdSBjYXRjaCB0aGVtIGF0IHRo
ZSByaWdodCBzcG90Lg0KT25lIG9mIHRoZSBtb3N0IHVzZWZ1bCB0cmlnZ2VyIHdlIGhhdmUgaXMg
d2hlbiBhIFR4IHBhY2tldCBpcyBkcm9wcGVkLg0KWW91IGNhbiB0YWtlIGEgbG9vayBhdCBzdHJ1
Y3QgaXdsX2Z3X2RiZ190cmlnZ2VyX3RsdiBpbiBpd2x3aWZpIGlmIHlvdQ0Kd2FudC4NCg0KPiBG
b3IgaW5zdGFuY2UsIG1heWJlIGl0IGlzIHJlcG9ydGluZyBsb3RzIG9mIHR4LWhhbmdzIGFuZC9v
ciBsb3ctbGV2ZWwNCj4gcmVzZXRzLiAgVGhpcyBnaXZlcyB5b3UgYSBjbHVlIGFzIHRvIHdoeSBh
IHVzZXIgbWlnaHQgcmVwb3J0ICdteSB3aWZpDQo+IHN1Y2tzJy4NCj4gPiBTaW5jZSBJIGFtIGJv
dGggRlcgYW5kIGRyaXZlciB0ZWFtIGZvciBteSBmaXJtd2FyZSB2YXJpYW50LA0KPiBhbmQgbXkg
YXBwcm9hY2ggaGFzIGJlZW4gd29ya2luZyBmb3IgbWUsIHRoZW4gSSBmZWVsIGl0IGlzIGNlcnRh
aW5seQ0KPiBiZXR0ZXIgdGhhbg0KPiB0aGUgY3VycmVudCBzdGF0ZS4gIEFuZCBqdXN0IG1heWJl
IHRoZSBvZmZpY2lhbCB1cHN0cmVhbSBGVyB0ZWFtDQo+IGNvdWxkIHN0YXJ0DQo+IHVzaW5nIHNv
bWV0aGluZyBzaW1pbGFyIGFzIHdlbGwuICBDdXJyZW50bHksIEkgZG9uJ3Qgc2VlIGhvdyB0aGV5
IGNhbg0KPiBldmVyIG1ha2UNCj4gbXVjaCBwcm9ncmVzcyBvbiBmaXJtd2FyZSBjcmFzaGVzIHJl
cG9ydGVkIGluIHN0b2NrIGtlcm5lbHMuDQo+ID4gVGhhbmtzLA0KPiBCZW4NCg==

^ permalink raw reply

* [PATCH 20/25] iwlwifi: mvm: bump max API to 26
From: Luca Coelho @ 2016-09-15 18:11 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Emmanuel Grumbach, Luca Coelho
In-Reply-To: <1473962425.5664.41.camel@coelho.fi>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

The driver now support version 26 of the firmware APIs.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-7000.c | 4 ++--
 drivers/net/wireless/intel/iwlwifi/iwl-8000.c | 4 ++--
 drivers/net/wireless/intel/iwlwifi/iwl-9000.c | 2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-a000.c | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
index 64690c14..aa575fb 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
@@ -73,8 +73,8 @@
 /* Highest firmware API version supported */
 #define IWL7260_UCODE_API_MAX	17
 #define IWL7265_UCODE_API_MAX	17
-#define IWL7265D_UCODE_API_MAX	24
-#define IWL3168_UCODE_API_MAX	24
+#define IWL7265D_UCODE_API_MAX	26
+#define IWL3168_UCODE_API_MAX	26
 
 /* Lowest firmware API version supported */
 #define IWL7260_UCODE_API_MIN	16
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
index cde4f26..990cf2b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
@@ -70,8 +70,8 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX	24
-#define IWL8265_UCODE_API_MAX	24
+#define IWL8000_UCODE_API_MAX	26
+#define IWL8265_UCODE_API_MAX	26
 
 /* Lowest firmware API version supported */
 #define IWL8000_UCODE_API_MIN	16
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
index 4d68985..a2c7946 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
@@ -55,7 +55,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL9000_UCODE_API_MAX	24
+#define IWL9000_UCODE_API_MAX	26
 
 /* Lowest firmware API version supported */
 #define IWL9000_UCODE_API_MIN	16
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
index 4d78232..ea16185 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
@@ -55,7 +55,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL_A000_UCODE_API_MAX	24
+#define IWL_A000_UCODE_API_MAX	26
 
 /* Lowest firmware API version supported */
 #define IWL_A000_UCODE_API_MIN	24
-- 
2.9.3

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox