PERFORCE change 65353 for review

Sam Leffler sam at FreeBSD.org
Wed Nov 17 11:25:03 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=65353

Change 65353 by sam at sam_ebb on 2004/11/17 19:24:22

	o update for new tx path handling
	o add power save support to the tx path while we're here
	  (incomplete and/or untested)

Affected files ...

.. //depot/projects/wifi/sys/dev/awi/awi.c#4 edit
.. //depot/projects/wifi/sys/dev/wi/if_wi.c#6 edit

Differences ...

==== //depot/projects/wifi/sys/dev/awi/awi.c#4 (text+ko) ====

@@ -746,6 +746,7 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211_node *ni;
 	struct ieee80211_frame *wh;
+	struct ether_header *eh;
 	struct mbuf *m, *m0;
 	int len, dowep;
 	u_int32_t txd, frame, ntxd;
@@ -758,6 +759,7 @@
 		txd = sc->sc_txnext;
 		IF_POLL(&ic->ic_mgtq, m0);
 		dowep = 0;
+		ni = NULL;
 		if (m0 != NULL) {
 			len = m0->m_pkthdr.len;
 			if (awi_next_txd(sc, len, &frame, &ntxd)) {
@@ -765,6 +767,13 @@
 				break;
 			}
 			IF_DEQUEUE(&ic->ic_mgtq, m0);
+			ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif;
+			if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
+			    (m0->m_flags & M_PWR_SAV) == 0) {
+				ieee80211_pwrsave(ic, ni, m0);
+				continue;
+			}
+			m0->m_pkthdr.rcvif = NULL;
 		} else {
 			if (ic->ic_state != IEEE80211_S_RUN)
 				break;
@@ -780,6 +789,7 @@
 				len += sizeof(struct llc) -
 				    sizeof(struct ether_header);
 			if (ic->ic_flags & IEEE80211_F_PRIVACY) {
+				/* XXX other crypto */
 				dowep = 1;
 				len += IEEE80211_WEP_IVLEN +
 				    IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
@@ -789,21 +799,31 @@
 				break;
 			}
 			IFQ_DEQUEUE(&ifp->if_snd, m0);
-			ifp->if_opackets++;
 #if NBPFILTER > 0
 			if (ifp->if_bpf)
 				bpf_mtap(ifp->if_bpf, m0);
 #endif
 			if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap)
 				m0 = awi_ether_encap(sc, m0);
-			else
-				m0 = ieee80211_encap(ic, m0, &ni);
-			if (m0 == NULL) {
-				ifp->if_oerrors++;
-				continue;
+			else {
+				if (m0->m_len < sizeof(struct ether_header) &&
+				    ((m0 = m_pullup(m0, sizeof(struct ether_header)))) == NULL) {
+					ifp->if_oerrors++;
+					continue;
+				}
+				eh = mtod(m0, struct ether_header *);
+				ni = ieee80211_find_txnode(ic, eh->ether_dhost);
+				if (ni == NULL)
+					goto bad;
+				if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
+				    (m0->m_flags & M_PWR_SAV) == 0) {
+					ieee80211_pwrsave(ic, ni, m0);
+					continue;
+				}
+				m0 = ieee80211_encap(ic, m0, ni);
 			}
-			if (ni != NULL)
-				ieee80211_free_node(ic, ni);
+			if (m0 == NULL)
+				goto bad;
 			wh = mtod(m0, struct ieee80211_frame *);
 			if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
 			    (ic->ic_opmode == IEEE80211_M_HOSTAP ||
@@ -812,10 +832,15 @@
 			    (ifp->if_flags & IFF_LINK0) == 0 &&
 			    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
 			    IEEE80211_FC0_TYPE_DATA && ni == NULL) {
-				m_freem(m0);
+			bad:
+				if (m0 != NULL)
+					m_freem(m0);
 				ifp->if_oerrors++;
+				if (ni != NULL)
+					ieee80211_free_node(ni);
 				continue;
 			}
+			ifp->if_opackets++;
 		}
 #if NBPFILTER > 0
 		if (ic->ic_rawbpf)
@@ -827,16 +852,18 @@
 			k = ieee80211_crypto_encap(ic, ni, m0);
 			if (k == NULL) {
 				if (ni != NULL)
-					ieee80211_free_node(ic, ni);
+					ieee80211_free_node(ni);
 				continue;
 			}
 		}
 #ifdef DIAGNOSTIC
 		if (m0->m_pkthdr.len != len) {
-			printf("%s: length %d should be %d\n",
-			    ic->ic_if.if_xname, m0->m_pkthdr.len, len);
+			if_printf(ifp, "length %d should be %d\n",
+			    m0->m_pkthdr.len, len);
 			m_freem(m0);
 			ifp->if_oerrors++;
+			if (ni != NULL)
+				ieee80211_free_node(ni);
 			continue;
 		}
 #endif
@@ -1228,7 +1255,7 @@
 				ni = ieee80211_find_rxnode(ic,
 					mtod(m, struct ieee80211_frame_min *));
 				ieee80211_input(ic, m, ni, rssi, rstamp);
-				ieee80211_free_node(ic, ni);
+				ieee80211_free_node(ni);
 			} else
 				sc->sc_rxpend = m;
   rx_next:

==== //depot/projects/wifi/sys/dev/wi/if_wi.c#6 (text+ko) ====

@@ -866,6 +866,7 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211_node *ni;
 	struct ieee80211_frame *wh;
+	struct ether_header *eh;
 	struct mbuf *m0;
 	struct wi_frame frmhdr;
 	int cur, fid, off, error;
@@ -919,6 +920,23 @@
 				ifp->if_flags |= IFF_OACTIVE;
 				break;
 			}
+			if (m0->m_len < sizeof(struct ether_header) &&
+			    (m0 = m_pullup(m0, sizeof(struct ether_header))) == NULL) {
+				ifp->if_oerrors++;
+				continue;
+			}
+			eh = mtod(m0, struct ether_header *);
+			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
+			if (ni == NULL) {
+				m_freem(m0);
+				continue;
+			}
+			if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
+			    (m0->m_flags & M_PWR_SAV) == 0) {
+				ieee80211_pwrsave(ic, ni, m0);
+				ieee80211_free_node(ni);
+				continue;
+			}
 			ifp->if_opackets++;
 			m_copydata(m0, 0, ETHER_HDR_LEN, 
 			    (caddr_t)&frmhdr.wi_ehdr);
@@ -926,9 +944,10 @@
 			BPF_MTAP(ifp, m0);
 #endif
 
-			m0 = ieee80211_encap(ic, m0, &ni);
+			m0 = ieee80211_encap(ic, m0, ni);
 			if (m0 == NULL) {
 				ifp->if_oerrors++;
+				ieee80211_free_node(ni);
 				continue;
 			}
                         wh = mtod(m0, struct ieee80211_frame *);


More information about the p4-projects mailing list