Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163354519
D4487.id11047.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D4487.id11047.diff
View Options
Index: sys/dev/usb/wlan/if_urtwn.c
===================================================================
--- sys/dev/usb/wlan/if_urtwn.c
+++ sys/dev/usb/wlan/if_urtwn.c
@@ -181,14 +181,15 @@
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void urtwn_vap_delete(struct ieee80211vap *);
-static struct mbuf * urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int,
- int *);
-static struct mbuf * urtwn_report_intr(struct usb_xfer *, struct urtwn_data *,
- int *, int8_t *);
-static struct mbuf * urtwn_rxeof(struct urtwn_softc *, uint8_t *, int,
- int *, int8_t *);
+static struct mbuf * urtwn_rx_copy_to_mbuf(struct urtwn_softc *,
+ struct r92c_rx_stat *, int);
+static struct mbuf * urtwn_report_intr(struct usb_xfer *,
+ struct urtwn_data *);
+static struct mbuf * urtwn_rxeof(struct urtwn_softc *, uint8_t *, int);
static void urtwn_r88e_ratectl_tx_complete(struct urtwn_softc *,
void *);
+static struct ieee80211_node *urtwn_rx_frame(struct urtwn_softc *,
+ struct mbuf *, int8_t *);
static void urtwn_txeof(struct urtwn_softc *, struct urtwn_data *,
int);
static int urtwn_alloc_list(struct urtwn_softc *,
@@ -716,16 +717,13 @@
}
static struct mbuf *
-urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
+urtwn_rx_copy_to_mbuf(struct urtwn_softc *sc, struct r92c_rx_stat *stat,
+ int totlen)
{
struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211_frame *wh;
struct mbuf *m;
- struct r92c_rx_stat *stat;
- uint32_t rxdw0, rxdw3;
- uint8_t rate, cipher;
- int8_t rssi = 0;
- int infosz;
+ uint32_t rxdw0;
+ int pktlen;
/*
* don't pass packets to the ieee80211 framework if the driver isn't
@@ -734,87 +732,47 @@
if (!(sc->sc_flags & URTWN_RUNNING))
return (NULL);
- stat = (struct r92c_rx_stat *)buf;
rxdw0 = le32toh(stat->rxdw0);
- rxdw3 = le32toh(stat->rxdw3);
-
if (rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR)) {
/*
* This should not happen since we setup our Rx filter
* to not receive these frames.
*/
- counter_u64_add(ic->ic_ierrors, 1);
- return (NULL);
- }
- if (pktlen < sizeof(struct ieee80211_frame_ack) ||
- pktlen > MCLBYTES) {
- counter_u64_add(ic->ic_ierrors, 1);
- return (NULL);
- }
-
- rate = MS(rxdw3, R92C_RXDW3_RATE);
- cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
- infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
-
- /* Get RSSI from PHY status descriptor if present. */
- if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
- if (sc->chip & URTWN_CHIP_88E)
- rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
- else
- rssi = urtwn_get_rssi(sc, rate, &stat[1]);
- /* Update our average RSSI. */
- urtwn_update_avgrssi(sc, rate, rssi);
+ DPRINTFN(6, "RX flags error (%s)\n",
+ rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV");
+ goto fail;
}
- m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- device_printf(sc->sc_dev, "could not create RX mbuf\n");
- return (NULL);
+ pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
+ if (pktlen < sizeof(struct ieee80211_frame_ack)) {
+ DPRINTFN(6, "frame too short: %d\n", pktlen);
+ goto fail;
}
- /* Finalize mbuf. */
- memcpy(mtod(m, uint8_t *), (uint8_t *)&stat[1] + infosz, pktlen);
- m->m_pkthdr.len = m->m_len = pktlen;
- wh = mtod(m, struct ieee80211_frame *);
-
- if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
- cipher != R92C_CAM_ALGO_NONE) {
- m->m_flags |= M_WEP;
+ if (__predict_false(totlen > MCLBYTES)) {
+ /* convert to m_getjcl if this happens */
+ device_printf(sc->sc_dev, "%s: frame too long: %d (%d)\n",
+ __func__, pktlen, totlen);
+ goto fail;
}
- if (ieee80211_radiotap_active(ic)) {
- struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = 0;
-
- urtwn_get_tsf(sc, &tap->wr_tsft);
- if (__predict_false(le32toh((uint32_t)tap->wr_tsft) <
- le32toh(stat->rxdw5))) {
- tap->wr_tsft = le32toh(tap->wr_tsft >> 32) - 1;
- tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
- } else
- tap->wr_tsft &= 0xffffffff00000000;
- tap->wr_tsft += stat->rxdw5;
-
- /* Map HW rate index to 802.11 rate. */
- if (!(rxdw3 & R92C_RXDW3_HT)) {
- tap->wr_rate = ridx2rate[rate];
- } else if (rate >= 12) { /* MCS0~15. */
- /* Bit 7 set means HT MCS instead of rate. */
- tap->wr_rate = 0x80 | (rate - 12);
- }
- tap->wr_dbm_antsignal = rssi;
- tap->wr_dbm_antnoise = URTWN_NOISE_FLOOR;
+ if (__predict_false(m == NULL)) {
+ device_printf(sc->sc_dev, "%s: could not allocate RX mbuf\n",
+ __func__);
+ goto fail;
}
- *rssi_p = rssi;
-
+ memcpy(mtod(m, uint8_t *), (uint8_t *)stat, totlen);
+ m->m_pkthdr.len = m->m_len = totlen;
+
return (m);
+fail:
+ counter_u64_add(ic->ic_ierrors, 1);
+ return (NULL);
}
static struct mbuf *
-urtwn_report_intr(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
- int8_t *nf)
+urtwn_report_intr(struct usb_xfer *xfer, struct urtwn_data *data)
{
struct urtwn_softc *sc = data->sc;
struct ieee80211com *ic = &sc->sc_ic;
@@ -837,23 +795,22 @@
switch (report_sel) {
case R88E_RXDW3_RPT_RX:
- return (urtwn_rxeof(sc, buf, len, rssi, nf));
+ return (urtwn_rxeof(sc, buf, len));
case R88E_RXDW3_RPT_TX1:
urtwn_r88e_ratectl_tx_complete(sc, &stat[1]);
break;
default:
- DPRINTFN(7, "case %d was not handled", report_sel);
+ DPRINTFN(7, "case %d was not handled\n", report_sel);
break;
}
} else
- return (urtwn_rxeof(sc, buf, len, rssi, nf));
+ return (urtwn_rxeof(sc, buf, len));
return (NULL);
}
static struct mbuf *
-urtwn_rxeof(struct urtwn_softc *sc, uint8_t *buf, int len, int *rssi,
- int8_t *nf)
+urtwn_rxeof(struct urtwn_softc *sc, uint8_t *buf, int len)
{
struct r92c_rx_stat *stat;
struct mbuf *m, *m0 = NULL, *prevm = NULL;
@@ -883,7 +840,7 @@
if (totlen > len)
break;
- m = urtwn_rx_frame(sc, buf, pktlen, rssi);
+ m = urtwn_rx_copy_to_mbuf(sc, stat, totlen);
if (m0 == NULL)
m0 = m;
if (prevm == NULL)
@@ -931,17 +888,86 @@
URTWN_NT_UNLOCK(sc);
}
+static struct ieee80211_node *
+urtwn_rx_frame(struct urtwn_softc *sc, struct mbuf *m, int8_t *rssi_p)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_frame_min *wh;
+ struct r92c_rx_stat *stat;
+ uint32_t rxdw0, rxdw3;
+ uint8_t rate, cipher;
+ int8_t rssi = URTWN_NOISE_FLOOR + 1;
+ int infosz;
+
+ stat = mtod(m, struct r92c_rx_stat *);
+ rxdw0 = le32toh(stat->rxdw0);
+ rxdw3 = le32toh(stat->rxdw3);
+
+ rate = MS(rxdw3, R92C_RXDW3_RATE);
+ cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
+ infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
+
+ /* Get RSSI from PHY status descriptor if present. */
+ if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
+ else
+ rssi = urtwn_get_rssi(sc, rate, &stat[1]);
+ /* Update our average RSSI. */
+ urtwn_update_avgrssi(sc, rate, rssi);
+ }
+
+ if (ieee80211_radiotap_active(ic)) {
+ struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
+
+ tap->wr_flags = 0;
+
+ urtwn_get_tsf(sc, &tap->wr_tsft);
+ if (__predict_false(le32toh((uint32_t)tap->wr_tsft) <
+ le32toh(stat->rxdw5))) {
+ tap->wr_tsft = le32toh(tap->wr_tsft >> 32) - 1;
+ tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
+ } else
+ tap->wr_tsft &= 0xffffffff00000000;
+ tap->wr_tsft += stat->rxdw5;
+
+ /* Map HW rate index to 802.11 rate. */
+ if (!(rxdw3 & R92C_RXDW3_HT)) {
+ tap->wr_rate = ridx2rate[rate];
+ } else if (rate >= 12) { /* MCS0~15. */
+ /* Bit 7 set means HT MCS instead of rate. */
+ tap->wr_rate = 0x80 | (rate - 12);
+ }
+ tap->wr_dbm_antsignal = rssi;
+ tap->wr_dbm_antnoise = URTWN_NOISE_FLOOR;
+ }
+
+ *rssi_p = rssi;
+
+ /* Drop descriptor. */
+ m_adj(m, sizeof(*stat) + infosz);
+ wh = mtod(m, struct ieee80211_frame_min *);
+
+ if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
+ cipher != R92C_CAM_ALGO_NONE) {
+ m->m_flags |= M_WEP;
+ }
+
+ if (m->m_len >= sizeof(*wh))
+ return (ieee80211_find_rxnode(ic, wh));
+
+ return (NULL);
+}
+
static void
urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211_frame_min *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL, *next;
struct urtwn_data *data;
- int8_t nf;
- int rssi = 1;
+ int8_t nf, rssi;
URTWN_ASSERT_LOCKED(sc);
@@ -951,7 +977,7 @@
if (data == NULL)
goto tr_setup;
STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
- m = urtwn_report_intr(xfer, data, &rssi, &nf);
+ m = urtwn_report_intr(xfer, data);
STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
/* FALLTHROUGH */
case USB_ST_SETUP:
@@ -972,15 +998,13 @@
* ieee80211_input() because here is at the end of a USB
* callback and safe to unlock.
*/
- URTWN_UNLOCK(sc);
while (m != NULL) {
next = m->m_next;
m->m_next = NULL;
- wh = mtod(m, struct ieee80211_frame_min *);
- if (m->m_len >= sizeof(*wh))
- ni = ieee80211_find_rxnode(ic, wh);
- else
- ni = NULL;
+
+ ni = urtwn_rx_frame(sc, m, &rssi);
+ URTWN_UNLOCK(sc);
+
nf = URTWN_NOISE_FLOOR;
if (ni != NULL) {
(void)ieee80211_input(ni, m, rssi - nf, nf);
@@ -989,9 +1013,10 @@
(void)ieee80211_input_all(ic, m, rssi - nf,
nf);
}
+
+ URTWN_LOCK(sc);
m = next;
}
- URTWN_LOCK(sc);
break;
default:
/* needs it to the inactive queue due to a error. */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 23, 10:58 AM (10 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35399637
Default Alt Text
D4487.id11047.diff (9 KB)
Attached To
Mode
D4487: urtwn: fix frame processing in the Rx path
Attached
Detach File
Event Timeline
Log In to Comment