svn commit: r192045 - projects/mesh11s/sys/net80211

Rui Paulo rpaulo at FreeBSD.org
Wed May 13 15:09:02 UTC 2009


Author: rpaulo
Date: Wed May 13 15:09:01 2009
New Revision: 192045
URL: http://svn.freebsd.org/changeset/base/192045

Log:
  Handle atheros superg and HT on input.
  Handle output data frames. XXX: not sure what's happening to the header
  lenght.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/mesh11s/sys/net80211/ieee80211_mesh.c
  projects/mesh11s/sys/net80211/ieee80211_output.c

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c	Wed May 13 15:07:26 2009	(r192044)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c	Wed May 13 15:09:01 2009	(r192045)
@@ -266,6 +266,7 @@ mesh_input(struct ieee80211_node *ni, st
 	case IEEE80211_FC0_TYPE_DATA:
 		IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, ni,
 		    "%s", "received data frame");
+		/* XXX: make sure we already peered with this node */
 		hdrspace = ieee80211_hdrspace(ic, wh)
 		    + sizeof(struct ieee80211_meshcontrol);
 		if (m->m_len < hdrspace &&
@@ -294,7 +295,7 @@ mesh_input(struct ieee80211_node *ni, st
 		/*
 		 * Next up, any fragmentation.
 		 */
-		if (!IEEE80211_IS_MULTICAST(wh->i_addr3)) {
+		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 			m = ieee80211_defrag(ni, m, hdrspace);
 			if (m == NULL) {
 				/* Fragment dropped or frame not complete yet */
@@ -321,7 +322,18 @@ mesh_input(struct ieee80211_node *ni, st
 			IEEE80211_NODE_STAT(ni, rx_decap);
 			goto err;
 		}
-		
+		/* XXX require HT? */
+		if (qos & IEEE80211_QOS_AMSDU) {
+			m = ieee80211_decap_amsdu(ni, m);
+			if (m == NULL)
+				return IEEE80211_FC0_TYPE_DATA;
+		} else {
+#ifdef IEEE80211_SUPPORT_SUPERG
+			m = ieee80211_decap_fastframe(vap, ni, m);
+			if (m == NULL)
+				return IEEE80211_FC0_TYPE_DATA;
+#endif
+		}		
 		/* XXX SuperG/HT */
 		ieee80211_deliver_data(vap, ni, m);
 		return type;
@@ -1095,6 +1107,14 @@ ieee80211_create_mbss(struct ieee80211va
 	ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
 }
 
+uint32_t
+ieee80211_mesh_getseq(void)
+{
+	static uint32_t seq = 0;
+	
+	return seq++;
+}
+
 static int
 mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
 {

Modified: projects/mesh11s/sys/net80211/ieee80211_output.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_output.c	Wed May 13 15:07:26 2009	(r192044)
+++ projects/mesh11s/sys/net80211/ieee80211_output.c	Wed May 13 15:09:01 2009	(r192045)
@@ -1216,6 +1216,7 @@ ieee80211_encap(struct ieee80211vap *vap
 	 */
 	addqos = (ni->ni_flags & (IEEE80211_NODE_QOS|IEEE80211_NODE_HT)) &&
 		 (m->m_flags & M_EAPOL) == 0;
+	addqos = 1;
 	if (addqos)
 		hdrsize = sizeof(struct ieee80211_qosframe);
 	else
@@ -1223,15 +1224,22 @@ ieee80211_encap(struct ieee80211vap *vap
 	/*
 	 * 4-address frames need to be generated for:
 	 * o packets sent through a WDS vap (IEEE80211_M_WDS)
+	 * o packets sent through a Mesh vap (IEEE80211_M_MBSS)
 	 * o packets sent through a vap marked for relaying
 	 *   (e.g. a station operating with dynamic WDS)
 	 */
 	is4addr = vap->iv_opmode == IEEE80211_M_WDS ||
+	    vap->iv_opmode == IEEE80211_M_MBSS ||
 	    ((vap->iv_flags_ext & IEEE80211_FEXT_4ADDR) &&
 	     !IEEE80211_ADDR_EQ(eh.ether_shost, vap->iv_myaddr));
 	if (is4addr)
 		hdrsize += IEEE80211_ADDR_LEN;
 	/*
+	 * All Mesh data frames have a Mesh Control field.
+	 */
+	if (vap->iv_opmode == IEEE80211_M_MBSS)
+		hdrsize += sizeof(struct ieee80211_meshcontrol);
+	/*
 	 * Honor driver DATAPAD requirement.
 	 */
 	if (ic->ic_flags & IEEE80211_F_DATAPAD)
@@ -1268,7 +1276,7 @@ ieee80211_encap(struct ieee80211vap *vap
 			goto bad;
 	}
 	datalen = m->m_pkthdr.len;		/* NB: w/o 802.11 header */
-
+	hdrspace -= 2;
 	M_PREPEND(m, hdrspace, M_DONTWAIT);
 	if (m == NULL) {
 		vap->iv_stats.is_tx_nobuf++;
@@ -1307,9 +1315,15 @@ ieee80211_encap(struct ieee80211vap *vap
 		IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
 		IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
 		break;
+	case IEEE80211_M_MBSS:
+		wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS;
+		IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
+		IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
+		IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
+		IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, eh.ether_shost);
+		break;
 	case IEEE80211_M_MONITOR:
 	case IEEE80211_M_WDS:		/* NB: is4addr should always be true */
-	case IEEE80211_M_MBSS:
 		goto bad;
 	}
 	if (m->m_flags & M_MORE_DATA)
@@ -1349,6 +1363,19 @@ ieee80211_encap(struct ieee80211vap *vap
 			    htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
 			M_SEQNO_SET(m, seqno);
 		}
+		if (vap->iv_opmode == IEEE80211_M_MBSS) {
+			struct ieee80211_meshqosframe_addr4 *mwh;
+			uint32_t seq;
+				
+			mwh = (struct ieee80211_meshqosframe_addr4 *)wh;
+			mwh->i_mflags	= 0;	/* address extension bit */
+			mwh->i_mttl	= 160;
+			seq = ieee80211_mesh_getseq();
+			mwh->i_mseq[0] = seq & 0xff;
+			mwh->i_mseq[1] = (seq >> 8) & 0xff;
+			mwh->i_mseq[2] = (seq >> 16) & 0xff;
+			mwh->i_mseq[3] = (seq >> 24) & 0xff;
+		}
 	} else {
 		seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
 		*(uint16_t *)wh->i_seq =
@@ -1356,6 +1383,7 @@ ieee80211_encap(struct ieee80211vap *vap
 		M_SEQNO_SET(m, seqno);
 	}
 
+
 	/* check if xmit fragmentation is required */
 	txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold &&
 	    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&


More information about the svn-src-projects mailing list