summaryrefslogtreecommitdiff
path: root/sys/dev/ic/malo.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2006-11-12 14:26:05 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2006-11-12 14:26:05 +0000
commit3095c9ba6ae8c6e69dfcc12b83f167a032a9c93d (patch)
tree2b7315be48c2a6d7c044df17478ffabd63df81de /sys/dev/ic/malo.c
parent722c2e57dd5785cf5a2929ef7b39259b750b147a (diff)
Rewrite part of malo_tx_mgt() to do the mbuf dance in a nicer way. This
is still ugly beyond any help but what do you expect from HW that needs to insert unused fields between header and data? OK mglocker@
Diffstat (limited to 'sys/dev/ic/malo.c')
-rw-r--r--sys/dev/ic/malo.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/dev/ic/malo.c b/sys/dev/ic/malo.c
index 85676a10aa6..75a96aa2053 100644
--- a/sys/dev/ic/malo.c
+++ b/sys/dev/ic/malo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: malo.c,v 1.22 2006/11/12 14:18:29 claudio Exp $ */
+/* $OpenBSD: malo.c,v 1.23 2006/11/12 14:26:04 claudio Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -1304,6 +1304,13 @@ malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
/* send mgt frames at the lowest available rate */
rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
+ if (m0->m_len < sizeof(struct ieee80211_frame *)) {
+ m0 = m_pullup(m0, sizeof(struct ieee80211_frame *));
+ if (m0 == NULL) {
+ ifp->if_ierrors++;
+ return (ENOBUFS);
+ }
+ }
wh = mtod(m0, struct ieee80211_frame *);
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
@@ -1347,14 +1354,20 @@ malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
* 6 bytes addr4 (inject)
* n bytes 802.11 frame body
*/
- m0 = m_pullup(m0, sizeof(*wh));
- if (M_TRAILINGSPACE(m0) < 8)
- return (1);
- bcopy(m0->m_data + 24, m0->m_data + 32, m0->m_len - 24);
- bcopy(m0->m_data, m0->m_data + 2, 24);
+ if (M_LEADINGSPACE(m0) < 8) {
+ if (M_TRAILINGSPACE(m0) < 8)
+ panic("%s: not enough space for mbuf dance",
+ sc->sc_dev.dv_xname);
+ bcopy(m0->m_data, m0->m_data + 8, m0->m_len);
+ m0->m_data += 8;
+ }
+
+ /* move frame header */
+ bcopy(m0->m_data, m0->m_data - 6, sizeof(*wh));
+ m0->m_data -= 8;
m0->m_len += 8;
m0->m_pkthdr.len += 8;
- *(uint16_t *)m0->m_data = htole16(m0->m_len - 32); /* FW len */
+ *mtod(m0, uint16_t *) = htole16(m0->m_len - 32); /* FW len */
error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
BUS_DMA_NOWAIT);