Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102936899
D47522.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D47522.diff
View Options
diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h
--- a/sys/dev/rtwn/if_rtwnvar.h
+++ b/sys/dev/rtwn/if_rtwnvar.h
@@ -32,7 +32,7 @@
#define RTWN_MACID_VALID 0x8000
#define RTWN_MACID_LIMIT 128
-#define RTWN_TX_TIMEOUT 5000 /* ms */
+#define RTWN_TX_TIMEOUT 1000 /* ms */
#define RTWN_MAX_EPOUT 4
#define RTWN_PORT_COUNT 2
diff --git a/sys/dev/rtwn/usb/rtwn_usb_attach.c b/sys/dev/rtwn/usb/rtwn_usb_attach.c
--- a/sys/dev/rtwn/usb/rtwn_usb_attach.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_attach.c
@@ -156,10 +156,12 @@
if (error != 0)
return (error);
- STAILQ_INIT(&uc->uc_tx_active);
- STAILQ_INIT(&uc->uc_tx_inactive);
- STAILQ_INIT(&uc->uc_tx_pending);
+ for (i = RTWN_BULK_TX_FIRST; i < RTWN_BULK_EP_COUNT; i++) {
+ STAILQ_INIT(&uc->uc_tx_active[i]);
+ STAILQ_INIT(&uc->uc_tx_pending[i]);
+ }
+ STAILQ_INIT(&uc->uc_tx_inactive);
for (i = 0; i < RTWN_USB_TX_LIST_COUNT; i++)
STAILQ_INSERT_HEAD(&uc->uc_tx_inactive, &uc->uc_tx[i], next);
@@ -207,23 +209,29 @@
rtwn_usb_free_tx_list(struct rtwn_softc *sc)
{
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
+ int i;
rtwn_usb_free_list(sc, uc->uc_tx, RTWN_USB_TX_LIST_COUNT);
- STAILQ_INIT(&uc->uc_tx_active);
+ for (i = RTWN_BULK_TX_FIRST; i < RTWN_BULK_EP_COUNT; i++) {
+ STAILQ_INIT(&uc->uc_tx_active[i]);
+ STAILQ_INIT(&uc->uc_tx_pending[i]);
+ }
STAILQ_INIT(&uc->uc_tx_inactive);
- STAILQ_INIT(&uc->uc_tx_pending);
}
static void
rtwn_usb_reset_lists(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
+ int i;
RTWN_ASSERT_LOCKED(sc);
- rtwn_usb_reset_tx_list(uc, &uc->uc_tx_active, vap);
- rtwn_usb_reset_tx_list(uc, &uc->uc_tx_pending, vap);
+ for (i = RTWN_BULK_TX_FIRST; i < RTWN_BULK_EP_COUNT; i++) {
+ rtwn_usb_reset_tx_list(uc, &uc->uc_tx_active[i], vap);
+ rtwn_usb_reset_tx_list(uc, &uc->uc_tx_pending[i], vap);
+ }
if (vap == NULL) {
rtwn_usb_reset_rx_list(uc);
sc->qfullmsk = 0;
@@ -295,7 +303,7 @@
/* abort any pending transfers */
RTWN_UNLOCK(sc);
- for (i = 0; i < RTWN_N_TRANSFER; i++)
+ for (i = 0; i < RTWN_BULK_EP_COUNT; i++)
usbd_transfer_drain(uc->uc_xfer[i]);
RTWN_LOCK(sc);
}
@@ -432,7 +440,7 @@
rtwn_usb_free_rx_list(sc);
/* Detach all USB transfers. */
- usbd_transfer_unsetup(uc->uc_xfer, RTWN_N_TRANSFER);
+ usbd_transfer_unsetup(uc->uc_xfer, RTWN_BULK_EP_COUNT);
rtwn_detach_private(sc);
mtx_destroy(&sc->sc_mtx);
diff --git a/sys/dev/rtwn/usb/rtwn_usb_ep.c b/sys/dev/rtwn/usb/rtwn_usb_ep.c
--- a/sys/dev/rtwn/usb/rtwn_usb_ep.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_ep.c
@@ -55,7 +55,7 @@
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
-static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
+static const struct usb_config rtwn_config_common[RTWN_BULK_EP_COUNT] = {
[RTWN_BULK_RX] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
@@ -76,7 +76,7 @@
.pipe_bof = 1,
.force_short_xfer = 1,
},
- .callback = rtwn_bulk_tx_callback,
+ .callback = rtwn_bulk_tx_callback_be,
.timeout = RTWN_TX_TIMEOUT, /* ms */
},
[RTWN_BULK_TX_BK] = {
@@ -89,7 +89,7 @@
.pipe_bof = 1,
.force_short_xfer = 1,
},
- .callback = rtwn_bulk_tx_callback,
+ .callback = rtwn_bulk_tx_callback_bk,
.timeout = RTWN_TX_TIMEOUT, /* ms */
},
[RTWN_BULK_TX_VI] = {
@@ -102,7 +102,7 @@
.pipe_bof = 1,
.force_short_xfer = 1
},
- .callback = rtwn_bulk_tx_callback,
+ .callback = rtwn_bulk_tx_callback_vi,
.timeout = RTWN_TX_TIMEOUT, /* ms */
},
[RTWN_BULK_TX_VO] = {
@@ -115,7 +115,7 @@
.pipe_bof = 1,
.force_short_xfer = 1
},
- .callback = rtwn_bulk_tx_callback,
+ .callback = rtwn_bulk_tx_callback_vo,
.timeout = RTWN_TX_TIMEOUT, /* ms */
},
};
@@ -225,7 +225,7 @@
rtwn_config[RTWN_BULK_RX].bufsize =
uc->uc_rx_buf_size * RTWN_USB_RXBUFSZ_UNIT;
error = usbd_transfer_setup(uc->uc_udev, &iface_index,
- uc->uc_xfer, rtwn_config, RTWN_N_TRANSFER, uc, &sc->sc_mtx);
+ uc->uc_xfer, rtwn_config, RTWN_BULK_EP_COUNT, uc, &sc->sc_mtx);
free(rtwn_config, M_TEMP);
if (error) {
diff --git a/sys/dev/rtwn/usb/rtwn_usb_tx.h b/sys/dev/rtwn/usb/rtwn_usb_tx.h
--- a/sys/dev/rtwn/usb/rtwn_usb_tx.h
+++ b/sys/dev/rtwn/usb/rtwn_usb_tx.h
@@ -17,7 +17,10 @@
#ifndef RTWN_USB_TX_H
#define RTWN_USB_TX_H
-void rtwn_bulk_tx_callback(struct usb_xfer *, usb_error_t);
+void rtwn_bulk_tx_callback_bk(struct usb_xfer *, usb_error_t);
+void rtwn_bulk_tx_callback_be(struct usb_xfer *, usb_error_t);
+void rtwn_bulk_tx_callback_vi(struct usb_xfer *, usb_error_t);
+void rtwn_bulk_tx_callback_vo(struct usb_xfer *, usb_error_t);
int rtwn_usb_tx_start(struct rtwn_softc *, struct ieee80211_node *,
struct mbuf *, uint8_t *, uint8_t, int);
diff --git a/sys/dev/rtwn/usb/rtwn_usb_tx.c b/sys/dev/rtwn/usb/rtwn_usb_tx.c
--- a/sys/dev/rtwn/usb/rtwn_usb_tx.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_tx.c
@@ -105,6 +105,7 @@
rtwn_usb_txeof(struct rtwn_usb_softc *uc, struct rtwn_data *data, int status)
{
struct rtwn_softc *sc = &uc->uc_sc;
+ bool is_empty = true;
RTWN_ASSERT_LOCKED(sc);
@@ -120,42 +121,54 @@
STAILQ_INSERT_TAIL(&uc->uc_tx_inactive, data, next);
sc->qfullmsk = 0;
+
#ifndef D4054
- if (STAILQ_EMPTY(&uc->uc_tx_active) && STAILQ_EMPTY(&uc->uc_tx_pending))
+ for (int i = RTWN_BULK_TX_FIRST; i < RTWN_BULK_EP_COUNT; i++) {
+ if (!STAILQ_EMPTY(&uc->uc_tx_active[i]) ||
+ !STAILQ_EMPTY(&uc->uc_tx_pending[i]))
+ is_empty = false;
+ }
+
+ if (is_empty)
sc->sc_tx_timer = 0;
else
sc->sc_tx_timer = 5;
#endif
}
-void
-rtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
+static void
+rtwn_bulk_tx_callback_qid(struct usb_xfer *xfer, usb_error_t error, int qid)
{
struct rtwn_usb_softc *uc = usbd_xfer_softc(xfer);
struct rtwn_softc *sc = &uc->uc_sc;
struct rtwn_data *data;
+ bool do_is_empty_check = false;
+ int i;
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT,
+ "%s: called, qid=%d\n", __func__, qid);
RTWN_ASSERT_LOCKED(sc);
switch (USB_GET_STATE(xfer)){
case USB_ST_TRANSFERRED:
- data = STAILQ_FIRST(&uc->uc_tx_active);
+ data = STAILQ_FIRST(&uc->uc_tx_active[qid]);
if (data == NULL)
goto tr_setup;
- STAILQ_REMOVE_HEAD(&uc->uc_tx_active, next);
+ STAILQ_REMOVE_HEAD(&uc->uc_tx_active[qid], next);
rtwn_usb_txeof(uc, data, 0);
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
- data = STAILQ_FIRST(&uc->uc_tx_pending);
+ data = STAILQ_FIRST(&uc->uc_tx_pending[qid]);
if (data == NULL) {
RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT,
"%s: empty pending queue\n", __func__);
- sc->sc_tx_n_active = 0;
+ do_is_empty_check = true;
goto finish;
}
- STAILQ_REMOVE_HEAD(&uc->uc_tx_pending, next);
- STAILQ_INSERT_TAIL(&uc->uc_tx_active, data, next);
+ STAILQ_REMOVE_HEAD(&uc->uc_tx_pending[qid], next);
+ STAILQ_INSERT_TAIL(&uc->uc_tx_active[qid], data, next);
/*
* Note: if this is a beacon frame, ensure that it will go
@@ -169,11 +182,16 @@
sc->sc_tx_n_active++;
break;
default:
- data = STAILQ_FIRST(&uc->uc_tx_active);
+ data = STAILQ_FIRST(&uc->uc_tx_active[qid]);
if (data == NULL)
goto tr_setup;
- STAILQ_REMOVE_HEAD(&uc->uc_tx_active, next);
+ STAILQ_REMOVE_HEAD(&uc->uc_tx_active[qid], next);
rtwn_usb_txeof(uc, data, 1);
+ if (error != 0)
+ device_printf(sc->sc_dev,
+ "%s: called; txeof error=%s\n",
+ __func__,
+ usbd_errstr(error));
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
goto tr_setup;
@@ -181,6 +199,19 @@
break;
}
finish:
+
+ /*
+ * Clear sc_tx_n_active if all the pending transfers are 0.
+ *
+ * This is currently a crutch because net80211 doesn't provide
+ * a way to defer all the FF checks or one of the FF checks.
+ * Eventually this should just be tracked per-endpoint.
+ */
+ for (i = RTWN_BULK_TX_FIRST; i < RTWN_BULK_EP_COUNT; i++)
+ if (STAILQ_FIRST(&uc->uc_tx_pending[i]) != NULL)
+ do_is_empty_check = false;
+ if (do_is_empty_check)
+ sc->sc_tx_n_active = 0;
#ifdef IEEE80211_SUPPORT_SUPERG
/*
* If the TX active queue drops below a certain
@@ -210,6 +241,34 @@
rtwn_start(sc);
}
+void
+rtwn_bulk_tx_callback_be(struct usb_xfer *xfer, usb_error_t error)
+{
+
+ rtwn_bulk_tx_callback_qid(xfer, error, RTWN_BULK_TX_BE);
+}
+
+void
+rtwn_bulk_tx_callback_bk(struct usb_xfer *xfer, usb_error_t error)
+{
+
+ rtwn_bulk_tx_callback_qid(xfer, error, RTWN_BULK_TX_BK);
+}
+
+void
+rtwn_bulk_tx_callback_vi(struct usb_xfer *xfer, usb_error_t error)
+{
+
+ rtwn_bulk_tx_callback_qid(xfer, error, RTWN_BULK_TX_VI);
+}
+
+void
+rtwn_bulk_tx_callback_vo(struct usb_xfer *xfer, usb_error_t error)
+{
+
+ rtwn_bulk_tx_callback_qid(xfer, error, RTWN_BULK_TX_VO);
+}
+
static void
rtwn_usb_tx_checksum(struct rtwn_tx_desc_common *txd)
{
@@ -226,6 +285,7 @@
struct rtwn_data *data;
struct usb_xfer *xfer;
uint16_t ac;
+ int qid = 0;
RTWN_ASSERT_LOCKED(sc);
@@ -236,17 +296,23 @@
if (data == NULL)
return (ENOBUFS);
+ /* TODO: should really get a consistent AC/TID, ath(4) style */
ac = M_WME_GETAC(m);
switch (type) {
case IEEE80211_FC0_TYPE_CTL:
case IEEE80211_FC0_TYPE_MGT:
- xfer = uc->uc_xfer[RTWN_BULK_TX_VO];
+ qid = RTWN_BULK_TX_VO;
break;
default:
- xfer = uc->uc_xfer[wme2qid[ac]];
+ qid = wme2qid[ac];
break;
}
+ xfer = uc->uc_xfer[qid];
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT,
+ "%s: called, ac=%d, qid=%d, xfer=%p\n",
+ __func__, ac, qid, xfer);
txd = (struct rtwn_tx_desc_common *)tx_desc;
txd->pktlen = htole16(m->m_pkthdr.len);
@@ -264,6 +330,7 @@
data->buflen = m->m_pkthdr.len + sc->txdesc_len;
data->id = id;
data->ni = ni;
+ data->qid = qid;
if (data->ni != NULL) {
data->m = m;
#ifndef D4054
@@ -271,7 +338,7 @@
#endif
}
- STAILQ_INSERT_TAIL(&uc->uc_tx_pending, data, next);
+ STAILQ_INSERT_TAIL(&uc->uc_tx_pending[qid], data, next);
if (STAILQ_EMPTY(&uc->uc_tx_inactive))
sc->qfullmsk = 1;
diff --git a/sys/dev/rtwn/usb/rtwn_usb_var.h b/sys/dev/rtwn/usb/rtwn_usb_var.h
--- a/sys/dev/rtwn/usb/rtwn_usb_var.h
+++ b/sys/dev/rtwn/usb/rtwn_usb_var.h
@@ -37,6 +37,7 @@
uint8_t *buf;
/* 'id' is meaningful for beacons only */
int id;
+ int qid;
uint16_t buflen;
struct mbuf *m;
struct ieee80211_node *ni;
@@ -50,15 +51,16 @@
RTWN_BULK_TX_BK, /* = WME_AC_BK */
RTWN_BULK_TX_VI, /* = WME_AC_VI */
RTWN_BULK_TX_VO, /* = WME_AC_VO */
- RTWN_N_TRANSFER = 5,
+ RTWN_BULK_EP_COUNT = 5,
};
#define RTWN_EP_QUEUES RTWN_BULK_RX
+#define RTWN_BULK_TX_FIRST RTWN_BULK_TX_BE
struct rtwn_usb_softc {
struct rtwn_softc uc_sc; /* must be the first */
struct usb_device *uc_udev;
- struct usb_xfer *uc_xfer[RTWN_N_TRANSFER];
+ struct usb_xfer *uc_xfer[RTWN_BULK_EP_COUNT];
struct rtwn_data uc_rx[RTWN_USB_RX_LIST_COUNT];
rtwn_datahead uc_rx_active;
@@ -70,9 +72,9 @@
int uc_rx_off;
struct rtwn_data uc_tx[RTWN_USB_TX_LIST_COUNT];
- rtwn_datahead uc_tx_active;
+ rtwn_datahead uc_tx_active[RTWN_BULK_EP_COUNT];
rtwn_datahead uc_tx_inactive;
- rtwn_datahead uc_tx_pending;
+ rtwn_datahead uc_tx_pending[RTWN_BULK_EP_COUNT];
int (*uc_align_rx)(int, int);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 19, 11:43 PM (22 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14725460
Default Alt Text
D47522.diff (10 KB)
Attached To
Mode
D47522: rtwn: change the USB TX transfers to only do one pending transfer per endpoint
Attached
Detach File
Event Timeline
Log In to Comment