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