Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Nov 2016 01:22:54 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r308949 - head/sys/net80211
Message-ID:  <201611220122.uAM1MsX8060858@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Nov 22 01:22:54 2016
New Revision: 308949
URL: https://svnweb.freebsd.org/changeset/base/308949

Log:
  [net80211] flesh out more IBSS 11n support
  
  * Pepper comments around which describe what state(s) we're in when faking
    up 11n nodes.
  * By default don't fake it up as 11n until we properly negotiate the 11n
    capabilities using probe request/response frames.
  * Send a probe request with our HT information, as the 802.11-2012 spec
    suggests.
  * Reassociate with the driver if we've been promoted.
  
  This is done because although learning a peer via beacons can learn 11n
  state, learning peers via hearing probe frames and broadcast frames
  does not.  Thus, sometimes you end up with an 11n peer in the peer
  table and sometimes you don't.
  
  Note that the probe request/response exchange may not actually succeed.
  Ideally we'd put the peer into some blocking state until we've exchanged
  probe request/reponse to learn capabilities, or we timeout and just
  stay non-11n.
  
  This is more an experiment to get 11n IBSS nodes actually discovering
  each other and be able to transmit.  There are other issues that creep
  up which I'll attempt to address in future commits.
  
  Tested:
  
  * AR9380 NICs in 11n mode.
  
  Reviewed by:	avos
  Differential Revision:	https://reviews.freebsd.org/D8365

Modified:
  head/sys/net80211/ieee80211_adhoc.c
  head/sys/net80211/ieee80211_node.c

Modified: head/sys/net80211/ieee80211_adhoc.c
==============================================================================
--- head/sys/net80211/ieee80211_adhoc.c	Tue Nov 22 01:02:59 2016	(r308948)
+++ head/sys/net80211/ieee80211_adhoc.c	Tue Nov 22 01:22:54 2016	(r308949)
@@ -427,8 +427,12 @@ adhoc_input(struct ieee80211_node *ni, s
 				goto err;
 			}
 			/*
-			 * Fake up a node for this newly
-			 * discovered member of the IBSS.
+			 * Fake up a node for this newly discovered member
+			 * of the IBSS.
+			 *
+			 * Note: This doesn't "upgrade" the node to 11n;
+			 * that will happen after a probe request/response
+			 * exchange.
 			 */
 			ni = ieee80211_fakeup_adhoc_node(vap, wh->i_addr2);
 			if (ni == NULL) {
@@ -773,12 +777,35 @@ adhoc_recv_mgmt(struct ieee80211_node *n
 					ni = ieee80211_add_neighbor(vap, wh, &scan);
 				else
 					ni = NULL;
+
+				/*
+				 * Send a probe request so we announce 11n
+				 * capabilities.
+				 */
+				ieee80211_send_probereq(ni, /* node */
+					vap->iv_myaddr, /* SA */
+					ni->ni_macaddr, /* DA */
+					vap->iv_bss->ni_bssid, /* BSSID */
+					vap->iv_bss->ni_essid,
+					vap->iv_bss->ni_esslen); /* SSID */
+
 			} else if (ni->ni_capinfo == 0) {
 				/*
 				 * Update faked node created on transmit.
 				 * Note this also updates the tsf.
 				 */
 				ieee80211_init_neighbor(ni, wh, &scan);
+
+				/*
+				 * Send a probe request so we announce 11n
+				 * capabilities.
+				 */
+				ieee80211_send_probereq(ni, /* node */
+					vap->iv_myaddr, /* SA */
+					ni->ni_macaddr, /* DA */
+					vap->iv_bss->ni_bssid, /* BSSID */
+					vap->iv_bss->ni_essid,
+					vap->iv_bss->ni_esslen); /* SSID */
 			} else {
 				/*
 				 * Record tsf for potential resync.
@@ -889,6 +916,12 @@ adhoc_recv_mgmt(struct ieee80211_node *n
 		 */
 		ieee80211_send_proberesp(vap, wh->i_addr2,
 		    is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
+
+		/*
+		 * Note: we don't benefit from stashing the probe request
+		 * IEs away to use for IBSS negotiation, because we
+		 * typically don't get all of the IEs.
+		 */
 		break;
 
 	case IEEE80211_FC0_SUBTYPE_ACTION:

Modified: head/sys/net80211/ieee80211_node.c
==============================================================================
--- head/sys/net80211/ieee80211_node.c	Tue Nov 22 01:02:59 2016	(r308948)
+++ head/sys/net80211/ieee80211_node.c	Tue Nov 22 01:22:54 2016	(r308949)
@@ -324,10 +324,11 @@ ieee80211_create_ibss(struct ieee80211va
 	struct ieee80211_node *ni;
 
 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
-		"%s: creating %s on channel %u%c\n", __func__,
+		"%s: creating %s on channel %u%c flags 0x%08x\n", __func__,
 		ieee80211_opmode_name[vap->iv_opmode],
 		ieee80211_chan2ieee(ic, chan),
-		ieee80211_channel_type_char(chan));
+		ieee80211_channel_type_char(chan),
+		chan->ic_flags);
 
 	ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr);
 	if (ni == NULL) {
@@ -408,6 +409,14 @@ ieee80211_create_ibss(struct ieee80211va
 		}
 	}
 
+	/* XXX TODO: other bits and pieces - eg fast-frames? */
+
+	/* If we're an 11n channel then initialise the 11n bits */
+	if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
+		/* XXX what else? */
+		ieee80211_ht_node_init(ni);
+	}
+
 	(void) ieee80211_sta_join1(ieee80211_ref_node(ni));
 }
 
@@ -1549,6 +1558,9 @@ ieee80211_fakeup_adhoc_node(struct ieee8
 			 * so we can do interesting things (e.g. use
 			 * WME to disable ACK's).
 			 */
+			/*
+			 * XXX TODO: 11n?
+			 */
 			if (vap->iv_flags & IEEE80211_F_WME)
 				ni->ni_flags |= IEEE80211_NODE_QOS;
 #ifdef IEEE80211_SUPPORT_SUPERG
@@ -1558,8 +1570,44 @@ ieee80211_fakeup_adhoc_node(struct ieee8
 		}
 		ieee80211_node_setuptxparms(ni);
 		ieee80211_ratectl_node_init(ni);
+
+		/*
+		 * XXX TODO: 11n? At least 20MHz, at least A-MPDU RX,
+		 * not A-MPDU TX; not 11n rates, etc.  We'll cycle
+		 * that after we hear that we can indeed do 11n
+		 * (either by a beacon frame or by a probe response.)
+		 */
+
+		/*
+		 * This is the first time we see the node.
+		 */
 		if (ic->ic_newassoc != NULL)
 			ic->ic_newassoc(ni, 1);
+
+		/*
+		 * Kick off a probe request to the given node;
+		 * we will then use the probe response to update
+		 * 11n/etc configuration state.
+		 *
+		 * XXX TODO: this isn't guaranteed, and until we get
+		 * a probe response, we won't be able to actually
+		 * do anything 802.11n related to the node.
+		 * So if this does indeed work, maybe we should hold
+		 * off on sending responses until we get the probe
+		 * response, or just default to some sensible subset
+		 * of 802.11n behaviour (eg always allow aggregation
+		 * negotiation TO us, but not FROM us, etc) so we
+		 * aren't entirely busted.
+		 */
+		if (vap->iv_opmode == IEEE80211_M_IBSS) {
+			ieee80211_send_probereq(ni, /* node */
+				vap->iv_myaddr, /* SA */
+				ni->ni_macaddr, /* DA */
+				vap->iv_bss->ni_bssid, /* BSSID */
+				vap->iv_bss->ni_essid,
+				vap->iv_bss->ni_esslen); /* SSID */
+		}
+
 		/* XXX not right for 802.1x/WPA */
 		ieee80211_node_authorize(ni);
 	}
@@ -1632,6 +1680,21 @@ ieee80211_init_neighbor(struct ieee80211
 		    ni->ni_ies.htinfo_ie);
 		ieee80211_node_setuptxparms(ni);
 		ieee80211_ratectl_node_init(ni);
+
+		/* Reassociate; we're now 11n */
+		/*
+		 * XXX TODO: this is the wrong thing to do -
+		 * we're calling it with isnew=1 so the ath(4)
+		 * driver reinitialises the rate tables.
+		 * This "mostly" works for ath(4), but it won't
+		 * be right for firmware devices which allocate
+		 * node states.
+		 *
+		 * So, do we just create a new node and delete
+		 * the old one? Or?
+		 */
+		if (ni->ni_ic->ic_newassoc)
+			ni->ni_ic->ic_newassoc(ni, 1);
 	}
 }
 
@@ -1809,6 +1872,10 @@ ieee80211_find_txnode(struct ieee80211va
 			 * caller to be consistent with
 			 * ieee80211_find_node_locked.
 			 */
+			/*
+			 * XXX TODO: this doesn't fake up 11n state; we need
+			 * to find another way to get it upgraded.
+			 */
 			ni = ieee80211_fakeup_adhoc_node(vap, macaddr);
 			if (ni != NULL)
 				(void) ieee80211_ref_node(ni);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611220122.uAM1MsX8060858>