Page MenuHomeFreeBSD

D4487.id11047.diff
No OneTemporary

D4487.id11047.diff

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

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)

Event Timeline