74#include <sys/sockio.h>
75#include <sys/sysctl.h>
79#include <sys/kernel.h>
80#include <sys/socket.h>
82#include <sys/malloc.h>
83#include <sys/module.h>
85#include <sys/endian.h>
90#include <net/if_var.h>
91#include <net/if_arp.h>
92#include <net/ethernet.h>
94#include <net/if_media.h>
95#include <net/if_types.h>
98#include <netinet/in.h>
99#include <netinet/in_systm.h>
100#include <netinet/in_var.h>
101#include <netinet/if_ether.h>
102#include <netinet/ip.h>
105#include <net80211/ieee80211_var.h>
106#include <net80211/ieee80211_input.h>
107#include <net80211/ieee80211_regdomain.h>
108#include <net80211/ieee80211_radiotap.h>
117static SYSCTL_NODE(_hw_usb, OID_AUTO, uath, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
125 0,
"regulatory domain");
129SYSCTL_INT(_hw_usb_uath, OID_AUTO,
debug, CTLFLAG_RWTUN, &uath_debug, 0,
132 UATH_DEBUG_XMIT = 0x00000001,
133 UATH_DEBUG_XMIT_DUMP = 0x00000002,
134 UATH_DEBUG_RECV = 0x00000004,
135 UATH_DEBUG_TX_PROC = 0x00000008,
136 UATH_DEBUG_RX_PROC = 0x00000010,
137 UATH_DEBUG_RECV_ALL = 0x00000020,
138 UATH_DEBUG_INIT = 0x00000040,
139 UATH_DEBUG_DEVCAP = 0x00000080,
140 UATH_DEBUG_CMDS = 0x00000100,
141 UATH_DEBUG_CMDS_DUMP = 0x00000200,
142 UATH_DEBUG_RESET = 0x00000400,
143 UATH_DEBUG_STATE = 0x00000800,
144 UATH_DEBUG_MULTICAST = 0x00001000,
145 UATH_DEBUG_WME = 0x00002000,
146 UATH_DEBUG_CHANNEL = 0x00004000,
147 UATH_DEBUG_RATES = 0x00008000,
148 UATH_DEBUG_CRYPTO = 0x00010000,
149 UATH_DEBUG_LED = 0x00020000,
150 UATH_DEBUG_ANY = 0xffffffff
152#define DPRINTF(sc, m, fmt, ...) do { \
153 if (sc->sc_debug & (m)) \
154 printf(fmt, __VA_ARGS__); \
157#define DPRINTF(sc, m, fmt, ...) do { \
164#define UATH_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
215 .force_short_xfer = 1,
239 .force_short_xfer = 1,
248 const char [IFNAMSIZ],
int,
enum ieee80211_opmode,
int,
249 const uint8_t [IEEE80211_ADDR_LEN],
250 const uint8_t [IEEE80211_ADDR_LEN]);
260 int,
void *,
int,
int);
265static void uath_dump_cmd(
const uint8_t *,
int,
char);
270 uint8_t macaddr[IEEE80211_ADDR_LEN]);
279static int uath_transmit(
struct ieee80211com *,
struct mbuf *);
281static int uath_raw_xmit(
struct ieee80211_node *,
struct mbuf *,
282 const struct ieee80211_bpf_params *);
292 struct ieee80211_channel *);
305static int uath_newstate(
struct ieee80211vap *,
enum ieee80211_state,
308 const struct ieee80211_key *,
int);
332 struct ieee80211com *ic = &sc->
sc_ic;
333 uint8_t bands[IEEE80211_MODE_BYTES];
347 mtx_init(&sc->
sc_mtx, device_get_nameunit(sc->
sc_dev), MTX_NETWORK_LOCK,
351 mbufq_init(&sc->
sc_snd, ifqmaxlen);
356 device_printf(
dev,
"could not allocate USB transfers, "
372 "could not allocate Tx command list\n");
382 device_printf(sc->
sc_dev,
"could not initialize adapter\n");
388 "could not get device capabilities\n");
399 device_printf(sc->
sc_dev,
"could not get device status\n");
408 device_printf(sc->
sc_dev,
"could not allocate Rx data list\n");
413 device_printf(sc->
sc_dev,
"could not allocate Tx data list\n");
419 ic->ic_name = device_get_nameunit(
dev);
420 ic->ic_phytype = IEEE80211_T_OFDM;
421 ic->ic_opmode = IEEE80211_M_STA;
426 IEEE80211_C_MONITOR |
428 IEEE80211_C_SHPREAMBLE |
437 memset(bands, 0,
sizeof(bands));
438 setbit(bands, IEEE80211_MODE_11B);
439 setbit(bands, IEEE80211_MODE_11G);
441 setbit(bands, IEEE80211_MODE_11A);
443 ieee80211_init_channels(ic, NULL, bands);
445 ieee80211_ifattach(ic);
457 ieee80211_radiotap_attach(ic,
464 ieee80211_announce(ic);
479 struct ieee80211com *ic = &sc->
sc_ic;
521 ieee80211_ifdetach(ic);
572 &setup,
sizeof setup, NULL, 0, 0);
577uath_dump_cmd(
const uint8_t *buf,
int len,
char prefix)
579 const char *sep =
"";
582 for (i = 0; i <
len; i++) {
584 printf(
"%s%c ", sep, prefix);
587 else if ((i % 4) == 0)
589 printf(
"%02x", buf[i]);
595uath_codename(
int code)
597 static const char *names[] = {
602 "TARGET_GET_CAPABILITY",
611 "UPDATE_CONNECT_ATTR",
627 "RESET_KEY_CACHE_ENTRY",
628 "SET_KEY_CACHE_ENTRY",
630 "SET_REGULATORY_DOMAIN",
633 "SET_STA_BEACON_TIMERS",
641 "SET_ANTENNA_SWITCH",
642 "0x2c",
"0x2d",
"0x2e",
643 "USE_SHORT_SLOT_TIME",
646 "SET_RX_MULTICAST_FILTER",
652 "SET_TX_POWER_LIMIT",
653 "SET_TX_QUEUE_PARAMS",
659 if (code < nitems(names))
662 return "SET_DEFAULT_KEY";
663 snprintf(buf,
sizeof(buf),
"0x%02x", code);
673 void *odata,
int olen,
int flags)
684 device_printf(
sc->
sc_dev,
"%s: empty inactive queue\n",
698 memcpy((uint8_t *)(hdr + 1), idata, ilen);
701 if (sc->
sc_debug & UATH_DEBUG_CMDS) {
702 printf(
"%s: send %s [flags 0x%x] olen %d\n",
703 __func__, uath_codename(
code), cmd->
flags, olen);
704 if (sc->
sc_debug & UATH_DEBUG_CMDS_DUMP)
705 uath_dump_cmd(cmd->
buf, cmd->
buflen,
'+');
709 KASSERT(odata == NULL ||
711 (
"odata %p olen %u", odata, olen));
722 error = mtx_sleep(cmd, &sc->
sc_mtx, 0,
"uathcmd", 2 * hz);
725 device_printf(sc->
sc_dev,
"timeout waiting for reply "
727 }
else if (cmd->
olen != olen) {
728 device_printf(sc->
sc_dev,
"unexpected reply data count "
729 "to cmd 0x%x (%u), got %u, expected %u\n",
740 int ilen,
void *odata,
int olen,
int flags)
752 flags &= ~UATH_CMD_FLAG_READ;
770 DPRINTF(
sc, UATH_DEBUG_XMIT,
"%s: %s\n", __func__,
771 "out of command xmit buffers");
794 "could not query stats, error %d\n",
error);
808 device_printf(sc->
sc_dev,
"could not read capability %u\n",
819#define GETCAP(x, v) do { \
820 error = uath_get_capability(sc, x, &v); \
823 DPRINTF(sc, UATH_DEBUG_DEVCAP, \
824 "%s: %s=0x%08x\n", __func__, #x, v); \
881 device_printf(sc->
sc_dev,
"could not read MAC address\n");
889 "could not read device serial number\n");
900 which = htobe32(which);
905 "could not read EEPROM offset 0x%02x\n", be32toh(which));
915 for (i = 0; i < ndata; i++) {
927 if (dp->
ni != NULL) {
928 ieee80211_free_node(dp->
ni);
936 int ndata,
int maxsz,
void *dma_buf)
940 for (i = 0; i < ndata; i++) {
944 if (dma_buf == NULL) {
946 dp->
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
949 "could not allocate rx mbuf\n");
953 dp->
buf = mtod(dp->
m, uint8_t *);
956 dp->
buf = ((uint8_t *)dma_buf) + (i * maxsz);
1029static struct ieee80211vap *
1031 enum ieee80211_opmode opmode,
int flags,
1032 const uint8_t bssid[IEEE80211_ADDR_LEN],
1033 const uint8_t mac[IEEE80211_ADDR_LEN])
1036 struct ieee80211vap *vap;
1038 if (!TAILQ_EMPTY(&ic->ic_vaps))
1040 uvp = malloc(
sizeof(
struct uath_vap), M_80211_VAP, M_WAITOK | M_ZERO);
1044 if (ieee80211_vap_setup(ic, vap,
name, unit, opmode,
1045 flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
1047 free(uvp, M_80211_VAP);
1056 ieee80211_vap_attach(vap, ieee80211_media_change,
1057 ieee80211_media_status, mac);
1058 ic->ic_opmode = opmode;
1067 ieee80211_vap_detach(
vap);
1068 free(uvp, M_80211_VAP);
1074 struct ieee80211com *ic = &sc->
sc_ic;
1075 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1092 vap ? vap->iv_myaddr : ic->ic_macaddr, IEEE80211_ADDR_LEN);
1113 device_printf(sc->
sc_dev,
1114 "could not start target, error %d\n",
error);
1117 DPRINTF(sc, UATH_DEBUG_INIT,
"%s returns handle: 0x%x\n",
1123 device_printf(sc->
sc_dev,
1124 "could not switch channel, error %d\n",
error);
1158 sc->
sc_flags &= ~UATH_FLAG_INITDONE;
1179 write.
reg = htobe32(
reg);
1180 write.
len = htobe32(0);
1181 *(uint32_t *)write.
data = htobe32(
val);
1184 3 *
sizeof (uint32_t), 0);
1186 device_printf(sc->
sc_dev,
"could not write register 0x%02x\n",
1199 write.
reg = htobe32(
reg);
1200 write.
len = htobe32(
len);
1205 (
len == 0) ?
sizeof (uint32_t) : 2 *
sizeof (uint32_t) +
len, 0);
1207 device_printf(sc->
sc_dev,
1208 "could not write %d bytes to register 0x%02x\n",
len,
reg);
1223 device_printf(sc->
sc_dev,
1224 "could not set channel, error %d\n",
error);
1230 device_printf(sc->
sc_dev,
1231 "could not reset Tx queues, error %d\n",
error);
1237 device_printf(sc->
sc_dev,
1238 "could not init Tx queues, error %d\n",
error);
1243 device_printf(sc->
sc_dev,
1244 "could not set led state, error %d\n",
error);
1249 device_printf(sc->
sc_dev,
1250 "could not flush pipes, error %d\n",
error);
1263 rxfilter.
op = htobe32(
op);
1265 DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
1266 "setting Rx filter=0x%x flags=0x%x\n",
bits,
op);
1268 sizeof rxfilter, 0);
1275 struct ieee80211com *ic = &sc->
sc_ic;
1279 device_printf(sc->
sc_dev,
"device timeout\n");
1280 counter_u64_add(ic->ic_oerrors, 1);
1281 ieee80211_restart_all(ic);
1350 desc->txqid = htobe32(0);
1351 desc->connid = htobe32(0);
1352 desc->flags = htobe32(0);
1355 if (sc->
sc_debug & UATH_DEBUG_CMDS) {
1356 DPRINTF(sc, UATH_DEBUG_RESET,
"send flush ix %d\n",
1358 if (sc->
sc_debug & UATH_DEBUG_CMDS_DUMP)
1359 uath_dump_cmd(
data->buf,
data->buflen,
'+');
1383 DPRINTF(
sc, UATH_DEBUG_XMIT,
"%s: %s\n", __func__,
1384 "out of xmit buffers");
1397 DPRINTF(
sc, UATH_DEBUG_XMIT,
"%s: stop queue\n", __func__);
1406 "set led state %sconnected\n", connected ?
"" :
"!");
1407 connected = htobe32(connected);
1409 &connected,
sizeof connected, 0);
1416 struct ieee80211com *ic = &sc->
sc_ic;
1420 memset(&reset, 0,
sizeof(reset));
1421 if (IEEE80211_IS_CHAN_2GHZ(c))
1423 if (IEEE80211_IS_CHAN_5GHZ(c))
1426 if (IEEE80211_IS_CHAN_OFDM(c))
1428 else if (IEEE80211_IS_CHAN_CCK(c))
1431 if (c->ic_flags & IEEE80211_CHAN_TURBO)
1433 reset.
freq = htobe32(c->ic_freq);
1438 DPRINTF(sc, UATH_DEBUG_CHANNEL,
"set channel %d, flags 0x%x freq %u\n",
1439 ieee80211_chan2ieee(ic, c),
1440 be32toh(reset.
flags), be32toh(reset.
freq));
1449 DPRINTF(sc, UATH_DEBUG_RESET,
"%s: reset Tx queues\n", __func__);
1450 for (ac = 0; ac < 4; ac++) {
1451 const uint32_t qid = htobe32(ac);
1474 DPRINTF(sc, UATH_DEBUG_WME,
"%s: setup Tx queues\n", __func__);
1475 for (ac = 0; ac < 4; ac++) {
1476 qinfo.
qid = htobe32(ac);
1477 qinfo.
len = htobe32(
sizeof(qinfo.
attr));
1479 qinfo.
attr.
aifs = htobe32(uath_wme_11g[ac].aifsn);
1480 qinfo.
attr.
logcwmin = htobe32(uath_wme_11g[ac].logcwmin);
1481 qinfo.
attr.
logcwmax = htobe32(uath_wme_11g[ac].logcwmax);
1483 uath_wme_11g[ac].txop));
1484 qinfo.
attr.
mode = htobe32(uath_wme_11g[ac].acm);
1507 if (ic->ic_nrunning > 0) {
1516 ieee80211_start_all(ic);
1523 struct ieee80211vap *vap = ni->ni_vap;
1526 const struct ieee80211_frame *wh;
1527 struct ieee80211_key *
k;
1528 int framelen, msglen;
1537 if (ieee80211_radiotap_active_vap(vap)) {
1541 if (m0->m_flags & M_FRAG)
1542 tap->
wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
1544 ieee80211_radiotap_tx(vap, m0);
1547 wh = mtod(m0,
struct ieee80211_frame *);
1548 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1549 k = ieee80211_crypto_encap(ni, m0);
1556 wh = mtod(m0,
struct ieee80211_frame *);
1558 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(
desc + 1));
1560 framelen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
1567 if (m0->m_flags & M_LASTFRAG)
1570 chunk->
length = htobe16(msglen);
1573 desc->msglen = htobe32(msglen);
1577 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1578 case IEEE80211_FC0_TYPE_CTL:
1579 case IEEE80211_FC0_TYPE_MGT:
1581 if (ni->ni_flags & IEEE80211_NODE_QOS) {
1587 case IEEE80211_FC0_TYPE_DATA:
1589 desc->txqid = htobe32(M_WME_GETAC(m0));
1592 device_printf(sc->
sc_dev,
"bogus frame type 0x%x (%s)\n",
1593 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
1597 if (vap->iv_state == IEEE80211_S_AUTH ||
1598 vap->iv_state == IEEE80211_S_ASSOC ||
1599 vap->iv_state == IEEE80211_S_RUN)
1603 desc->flags = htobe32(0 );
1604 desc->buflen = htobe32(m0->m_pkthdr.len);
1608 "send frame ix %u framelen %d msglen %d connid 0x%x txqid 0x%x\n",
1609 desc->msgid, framelen, msglen, be32toh(
desc->connid),
1610 be32toh(
desc->txqid));
1611 if (sc->
sc_debug & UATH_DEBUG_XMIT_DUMP)
1612 uath_dump_cmd(
data->buf,
data->buflen,
'+');
1628 uath_datahead *frags,
struct ieee80211_node *ni)
1634 STAILQ_FOREACH_SAFE(bf, frags,
next,
next) {
1636 STAILQ_REMOVE_HEAD(frags,
next);
1639 ieee80211_node_decref(
ni);
1650 struct mbuf *m0,
struct ieee80211_node *
ni)
1656 for (
m = m0->m_nextpkt;
m != NULL;
m =
m->m_nextpkt) {
1662 ieee80211_node_incref(
ni);
1663 STAILQ_INSERT_TAIL(frags, bf,
next);
1666 return !STAILQ_EMPTY(frags);
1695 struct ieee80211_node *ni;
1696 struct mbuf *m, *
next;
1697 uath_datahead frags;
1705 while ((m = mbufq_dequeue(&sc->
sc_snd)) != NULL) {
1708 mbufq_prepend(&sc->
sc_snd, m);
1712 ni = (
struct ieee80211_node *)m->m_pkthdr.rcvif;
1713 m->m_pkthdr.rcvif = NULL;
1720 STAILQ_INIT(&frags);
1721 if ((m->m_flags & M_FRAG) &&
1724 "%s: out of txfrag buffers\n", __func__);
1725 ieee80211_free_mbuf(m);
1737 next = m->m_nextpkt;
1740 if_inc_counter(ni->ni_vap->iv_ifp,
1741 IFCOUNTER_OERRORS, 1);
1746 ieee80211_free_node(ni);
1755 if (ni->ni_vap->iv_state != IEEE80211_S_RUN) {
1757 "%s: flush fragmented packet, state %s\n",
1759 ieee80211_state_name[ni->ni_vap->iv_state]);
1760 ieee80211_free_mbuf(
next);
1764 bf = STAILQ_FIRST(&frags);
1765 KASSERT(bf != NULL, (
"no buf for txfrag"));
1766 STAILQ_REMOVE_HEAD(&frags,
next);
1776 const struct ieee80211_bpf_params *params)
1778 struct ieee80211com *ic = ni->ni_ic;
1888 const struct ieee80211_rateset *rs;
1889 struct ieee80211com *ic = &sc->
sc_ic;
1890 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1891 struct ieee80211_node *ni;
1894 ni = ieee80211_ref_node(vap->iv_bss);
1895 memset(&create, 0,
sizeof(create));
1897 create.
bssid = htobe32(0);
1907 if (IEEE80211_IS_CHAN_A(ni->ni_chan))
1909 else if (IEEE80211_IS_CHAN_ANYG(ni->ni_chan))
1913 ieee80211_free_node(ni);
1924 memset(&rates, 0,
sizeof(rates));
1929 bcopy(rs->rs_rates, &rates.
rateset.
set[0], rs->rs_nrates);
1932 "setting supported rates nrates=%d\n", rs->rs_nrates);
1934 &rates,
sizeof rates, 0);
1940 struct ieee80211com *ic = &sc->
sc_ic;
1941 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1942 struct ieee80211_node *ni;
1945 ni = ieee80211_ref_node(vap->iv_bss);
1947 associd.defaultrateix = htobe32(1);
1948 associd.associd = htobe32(ni->ni_associd);
1949 associd.timoffset = htobe32(0x3b);
1950 IEEE80211_ADDR_COPY(
associd.bssid, ni->ni_bssid);
1951 ieee80211_free_node(ni);
1964 DPRINTF(sc, UATH_DEBUG_LED,
"set %s led %s (steady)\n",
1972 int blinkrate,
int slowmode)
1981 DPRINTF(sc, UATH_DEBUG_LED,
"set %s led %s (blink)\n",
1990 enum ieee80211_state ostate = vap->iv_state;
1992 struct ieee80211_node *ni;
1993 struct ieee80211com *ic = vap->iv_ic;
1998 "%s: %s -> %s\n", __func__, ieee80211_state_name[
vap->iv_state],
1999 ieee80211_state_name[nstate]);
2001 IEEE80211_UNLOCK(ic);
2005 ni = ieee80211_ref_node(
vap->iv_bss);
2008 case IEEE80211_S_INIT:
2009 if (ostate == IEEE80211_S_RUN) {
2015 case IEEE80211_S_SCAN:
2018 case IEEE80211_S_AUTH:
2024 device_printf(sc->
sc_dev,
2025 "could not set crypto keys, error %d\n",
error);
2029 device_printf(sc->
sc_dev,
"could not switch channel\n");
2033 device_printf(sc->
sc_dev,
2034 "could not create connection\n");
2039 case IEEE80211_S_ASSOC:
2041 device_printf(sc->
sc_dev,
2042 "could not set negotiated rate set\n");
2047 case IEEE80211_S_RUN:
2049 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2058 ni->ni_txrate = ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates-1];
2061 device_printf(sc->
sc_dev,
2062 "could not write association id\n");
2078 ieee80211_free_node(ni);
2092 memset(&crypto, 0,
sizeof(crypto));
2094 crypto.magic1 = htobe32(1);
2095 crypto.
size = htobe32(368);
2096 crypto.mask = htobe32(0xffff);
2097 crypto.flags = htobe32(0x80000068);
2099 crypto.flags |= htobe32(
index << 16);
2100 memset(crypto.magic2, 0xff,
sizeof(crypto.magic2));
2106 for (i = 0; i < wk->wk_keylen; i++)
2107 crypto.key[i] = wk->wk_key[i] ^ 0xaa;
2109 DPRINTF(sc, UATH_DEBUG_CRYPTO,
2110 "setting crypto key index=%d len=%d\n",
index, wk->wk_keylen);
2125 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2126 const struct ieee80211_key *wk = &vap->iv_nw_keys[i];
2128 if (wk->wk_flags & (IEEE80211_KEY_XMIT|IEEE80211_KEY_RECV)) {
2134 if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE) {
2141#define UATH_SYSCTL_STAT_ADD32(c, h, n, p, d) \
2142 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
2147 struct sysctl_ctx_list *ctx;
2148 struct sysctl_oid_list *
child;
2149 struct sysctl_oid *tree;
2153 ctx = device_get_sysctl_ctx(sc->
sc_dev);
2154 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->
sc_dev));
2156 tree = SYSCTL_ADD_NODE(ctx,
child, OID_AUTO,
"stats",
2157 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
"UATH statistics");
2158 child = SYSCTL_CHILDREN(tree);
2204#undef UATH_SYSCTL_STAT_ADD32
2217 if (sc->
sc_debug & UATH_DEBUG_CMDS) {
2218 uint32_t
len = be32toh(hdr->
len);
2219 printf(
"%s: %s [ix %u] len %u status %u\n",
2220 __func__, uath_codename(be32toh(hdr->
code)),
2222 if (sc->
sc_debug & UATH_DEBUG_CMDS_DUMP)
2223 uath_dump_cmd(cmd->
buf,
2228 hdr->
len = be32toh(hdr->
len);
2231 switch (hdr->
code & 0xff) {
2234 DPRINTF(sc, UATH_DEBUG_RX_PROC | UATH_DEBUG_RECV_ALL,
2235 "%s: code %d hdr len %u\n",
2236 __func__, hdr->
code & 0xff, hdr->
len);
2243 uint32_t *rp = (uint32_t *)(hdr+1);
2246 if (
sizeof(*hdr) > hdr->
len ||
2248 device_printf(sc->
sc_dev,
2249 "%s: invalid WDC msg length %u; "
2250 "msg ignored\n", __func__, hdr->
len);
2259 dlen = hdr->
len -
sizeof(*hdr);
2260 if (dlen >=
sizeof(uint32_t)) {
2261 olen = be32toh(rp[0]);
2262 dlen -=
sizeof(uint32_t);
2265 olen =
sizeof(uint32_t);
2270 if (cmd->
odata != NULL) {
2272 if (olen > (u_int)cmd->
olen) {
2274 device_printf(sc->
sc_dev,
2275 "%s: cmd 0x%x olen %u cmd olen %u\n",
2276 __func__, hdr->
code, olen,
2282 device_printf(sc->
sc_dev,
2283 "%s: cmd 0x%x olen %u dlen %u\n",
2284 __func__, hdr->
code, olen, dlen);
2289 bcopy(&rp[1], cmd->
odata, olen);
2301 dlen = hdr->
len -
sizeof(*hdr);
2302 if (dlen !=
sizeof(uint32_t)) {
2303 device_printf(sc->
sc_dev,
2304 "%s: dlen (%u) != %zu!\n",
2305 __func__, dlen,
sizeof(uint32_t));
2310 bcopy(hdr+1, cmd->
odata,
sizeof(uint32_t));
2311 cmd->
olen =
sizeof(uint32_t);
2317 DPRINTF(sc, UATH_DEBUG_RX_PROC | UATH_DEBUG_RECV_ALL,
2318 "%s: received Tx notification\n", __func__);
2322 DPRINTF(sc, UATH_DEBUG_RX_PROC | UATH_DEBUG_RECV_ALL,
2323 "%s: received device statistics\n", __func__);
2353 device_printf(sc->
sc_dev,
2354 "%s: short xfer error (actlen %d)\n",
2363 hdr->
len = be32toh(hdr->
len);
2364 if (hdr->
len > (uint32_t)actlen) {
2365 device_printf(sc->
sc_dev,
2366 "%s: truncated xfer (len %u, actlen %d)\n",
2367 __func__, hdr->
len, actlen);
2412 DPRINTF(
sc, UATH_DEBUG_XMIT,
"%s: empty pending queue\n",
2478 struct ieee80211com *ic = &sc->
sc_ic;
2481 struct mbuf *m =
data->m, *mnew, *mp;
2488 DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
2489 "%s: wrong xfer size (len=%d)\n", __func__, actlen);
2490 counter_u64_add(ic->ic_ierrors, 1);
2495 chunklen = be16toh(chunk->
length);
2496 if (chunk->
seqnum == 0 && chunk->
flags == 0 && chunklen == 0) {
2497 device_printf(sc->
sc_dev,
"%s: strange response\n", __func__);
2498 counter_u64_add(ic->ic_ierrors, 1);
2503 if (chunklen > actlen) {
2504 device_printf(sc->
sc_dev,
2505 "%s: invalid chunk length (len %u > actlen %d)\n",
2506 __func__, chunklen, actlen);
2507 counter_u64_add(ic->ic_ierrors, 1);
2514 DPRINTF(sc, UATH_DEBUG_XMIT,
"invalid seqnum %d, expected %d\n",
2531 device_printf(sc->
sc_dev,
2532 "%s: invalid chunk length %d\n",
2533 __func__, chunklen);
2534 counter_u64_add(ic->ic_ierrors, 1);
2551 counter_u64_add(ic->ic_ierrors, 1);
2558 m->m_len = chunklen;
2565 m->m_flags &= ~M_PKTHDR;
2572 mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
2574 DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
2575 "%s: can't get new mbuf, drop frame\n", __func__);
2576 counter_u64_add(ic->ic_ierrors, 1);
2584 data->buf = mtod(mnew, uint8_t *);
2602 if ((uint8_t *)chunk + actlen -
sizeof(
struct uath_rx_desc) <
2604 device_printf(sc->
sc_dev,
2605 "%s: wrong Rx descriptor pointer "
2606 "(desc %p chunk %p actlen %d)\n",
2607 __func__,
desc, chunk, actlen);
2608 counter_u64_add(ic->ic_ierrors, 1);
2617 DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
2618 "%s: frame len %u code %u status %u rate %u antenna %u "
2619 "rssi %d channel %u phyerror %u connix %u decrypterror %u "
2620 "keycachemiss %u\n", __func__, be32toh(
desc->framelen)
2621 , be32toh(
desc->code), be32toh(
desc->status), be32toh(
desc->rate)
2622 , be32toh(
desc->antenna), be32toh(
desc->rssi), be32toh(
desc->channel)
2623 , be32toh(
desc->phyerror), be32toh(
desc->connix)
2624 , be32toh(
desc->decrypterror), be32toh(
desc->keycachemiss));
2626 if (be32toh(
desc->len) > MCLBYTES) {
2627 DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
2628 "%s: bad descriptor (len=%d)\n", __func__,
2629 be32toh(
desc->len));
2630 counter_u64_add(ic->ic_ierrors, 1);
2645 device_printf(sc->
sc_dev,
2646 "%s: framelen too small (%u)\n",
2647 __func__, be32toh(
desc->framelen));
2648 counter_u64_add(ic->ic_ierrors, 1);
2657 framelen <
sizeof(
struct ieee80211_frame_ack)) {
2658 device_printf(sc->
sc_dev,
2659 "%s: wrong frame length (%u, actlen %d)!\n",
2661 counter_u64_add(ic->ic_ierrors, 1);
2668 m->m_pkthdr.len = m->m_len =
framelen;
2672 mp->m_flags |= M_PKTHDR;
2679 ieee80211_radiotap_active(ic)) {
2681 uint32_t tsf_hi = be32toh(
desc->tstamp_high);
2682 uint32_t tsf_lo = be32toh(
desc->tstamp_low);
2685 tap->
wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
2688 tap->
wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
2706 struct ieee80211com *ic = &sc->
sc_ic;
2707 struct ieee80211_frame *wh;
2708 struct ieee80211_node *ni;
2709 struct epoch_tracker et;
2710 struct mbuf *m = NULL;
2751 if (m != NULL &&
desc != NULL) {
2752 wh = mtod(m,
struct ieee80211_frame *);
2753 ni = ieee80211_find_rxnode(ic,
2754 (
struct ieee80211_frame_min *)wh);
2756 NET_EPOCH_ENTER(et);
2758 (void) ieee80211_input(ni, m,
2759 (
int)be32toh(
desc->rssi), nf);
2761 ieee80211_free_node(ni);
2763 (
void) ieee80211_input_all(ic, m,
2764 (
int)be32toh(
desc->rssi), nf);
2783 counter_u64_add(ic->ic_ierrors, 1);
2799 ieee80211_tx_complete(
data->ni,
data->m, 0);
2829 DPRINTF(
sc, UATH_DEBUG_XMIT,
"%s: empty pending queue\n",
2847 if (
data->ni != NULL) {
2848 if_inc_counter(
data->ni->ni_vap->iv_ifp,
2849 IFCOUNTER_OERRORS, 1);
2851 ieee80211_free_node(
data->ni);
MODULE_DEPEND(uath, wlan, 1, 1, 1)
static int uath_get_devcap(struct uath_softc *)
static int uath_flush(struct uath_softc *)
static void uath_vap_delete(struct ieee80211vap *)
static int uath_set_ledstate(struct uath_softc *, int)
#define UATH_SYSCTL_STAT_ADD32(c, h, n, p, d)
static void uath_set_channel(struct ieee80211com *)
static int uath_txfrag_setup(struct uath_softc *sc, uath_datahead *frags, struct mbuf *m0, struct ieee80211_node *ni)
USB_PNP_HOST_INFO(uath_devs)
static int uath_dataflush(struct uath_softc *)
static void uath_free_tx_data_list(struct uath_softc *)
static struct uath_data * _uath_getbuf(struct uath_softc *sc)
static void uath_parent(struct ieee80211com *)
static int uath_detach(device_t dev)
static usb_callback_t uath_intr_tx_callback
static driver_t uath_driver
static void uath_scan_start(struct ieee80211com *)
static void uath_stat(void *)
SYSCTL_INT(_hw_usb_uath, OID_AUTO, countrycode, CTLFLAG_RWTUN, &uath_countrycode, 0, "country code")
static void uath_txfrag_cleanup(struct uath_softc *sc, uath_datahead *frags, struct ieee80211_node *ni)
static int uath_transmit(struct ieee80211com *, struct mbuf *)
static void uath_watchdog(void *)
static int uath_regdomain
static int uath_config(struct uath_softc *, uint32_t, uint32_t)
static int uath_match(device_t dev)
static int uath_set_rxfilter(struct uath_softc *, uint32_t, uint32_t)
static void uath_update_rxstat(struct uath_softc *sc, uint32_t status)
static void uath_update_mcast(struct ieee80211com *)
static int uath_get_capability(struct uath_softc *, uint32_t, uint32_t *)
DRIVER_MODULE(uath, uhub, uath_driver, uath_devclass, NULL, 0)
static int uath_set_chan(struct uath_softc *, struct ieee80211_channel *)
static usb_callback_t uath_bulk_tx_callback
static int uath_write_associd(struct uath_softc *sc)
static int uath_init(struct uath_softc *)
static int uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, struct uath_data *data)
static int uath_wme_init(struct uath_softc *)
CTASSERT(sizeof(u_int) >=sizeof(uint32_t))
static void uath_free_rx_data_list(struct uath_softc *)
static void uath_update_promisc(struct ieee80211com *)
static int uath_set_ledblink(struct uath_softc *sc, int lednum, int ledmode, int blinkrate, int slowmode)
static void uath_sysctl_node(struct uath_softc *)
static usb_callback_t uath_bulk_rx_callback
static int uath_attach(device_t dev)
#define DPRINTF(sc, m, fmt,...)
static const struct usb_config uath_usbconfig[UATH_N_XFERS]
static void uath_start(struct uath_softc *)
static int uath_cmdsend(struct uath_softc *sc, uint32_t code, const void *idata, int ilen, void *odata, int olen, int flags)
static usb_callback_t uath_intr_rx_callback
static int uath_reset_tx_queues(struct uath_softc *)
static int uath_set_keys(struct uath_softc *, struct ieee80211vap *)
static devclass_t uath_devclass
static int uath_config_multi(struct uath_softc *, uint32_t, const void *, int)
static int uath_alloc_cmd_list(struct uath_softc *, struct uath_cmd[])
static int uath_get_status(struct uath_softc *, uint32_t, void *, int)
static struct mbuf * uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, struct uath_rx_desc **pdesc)
static int uath_get_devstatus(struct uath_softc *, uint8_t macaddr[IEEE80211_ADDR_LEN])
static void uath_data_txeof(struct usb_xfer *xfer, struct uath_data *data)
static struct ieee80211vap * uath_vap_create(struct ieee80211com *, const char[IFNAMSIZ], int, enum ieee80211_opmode, int, const uint8_t[IEEE80211_ADDR_LEN], const uint8_t[IEEE80211_ADDR_LEN])
static int uath_set_key(struct uath_softc *, const struct ieee80211_key *, int)
static int uath_set_rxmulti_filter(struct uath_softc *sc)
static int uath_create_connection(struct uath_softc *sc, uint32_t connid)
static struct uath_cmd * uath_get_cmdbuf(struct uath_softc *)
static int uath_alloc_rx_data_list(struct uath_softc *)
static int uath_set_ledsteady(struct uath_softc *sc, int lednum, int ledmode)
static void uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
static void uath_scan_end(struct ieee80211com *)
static int uath_host_available(struct uath_softc *)
static SYSCTL_NODE(_hw_usb, OID_AUTO, uath, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB Atheros")
static void uath_free_data_list(struct uath_softc *sc, struct uath_data data[], int ndata, int fillmbuf)
static int uath_alloc_data_list(struct uath_softc *sc, struct uath_data data[], int ndata, int maxsz, void *dma_buf)
static const STRUCT_USB_HOST_ID uath_devs[]
static void uath_abort_xfers(struct uath_softc *)
static int uath_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *)
static int uath_newstate(struct ieee80211vap *, enum ieee80211_state, int)
static int uath_alloc_tx_data_list(struct uath_softc *)
static int uath_set_rates(struct uath_softc *sc, const struct ieee80211_rateset *rs)
static void uath_free_cmd_list(struct uath_softc *, struct uath_cmd[])
static int uath_switch_channel(struct uath_softc *, struct ieee80211_channel *)
static device_method_t uath_methods[]
static int uath_cmd_read(struct uath_softc *, uint32_t, const void *, int, void *, int, int)
static int uath_countrycode
static void uath_stop(struct uath_softc *)
static struct uath_data * uath_getbuf(struct uath_softc *)
static int uath_cmd_write(struct uath_softc *, uint32_t, const void *, int, int)
static int uath_cmdflush(struct uath_softc *)
#define WDCMSG_HOST_AVAILABLE
#define UATH_FILTER_OP_SET
@ CAP_FAST_FRAMES_SUPPORT
@ CAP_ANALOG_5GHz_REVISION
@ CAP_ANALOG_2GHz_REVISION
@ CAP_TWICE_ANTENNAGAIN_2G
@ CAP_CHAN_SPREAD_SUPPORT
@ CAP_TWICE_ANTENNAGAIN_5G
@ CAP_TURBO_PRIME_SUPPORT
@ CAP_CHAP_TUNING_SUPPORT
#define WDCMSG_RELEASE_TX_QUEUE
#define WDCMSG_CREATE_CONNECTION
#define WDCMSG_SET_BASIC_RATE
#define WDCMSG_TARGET_GET_CAPABILITY
#define UATH_STATUS_KEY_ERR
#define WDCMSG_SET_PWR_MODE
#define UATH_FILTER_RX_MCAST
#define WDCMSG_TARGET_GET_STATUS
#define WDCMSG_TARGET_GET_STATS
#define UATH_CONFIG_INDEX
#define WDCMSG_SET_LED_STEADY
#define WDCMSG_SET_LED_STATE
#define UATH_STATUS_STOP_IN_PROGRESS
#define WDCMSG_SET_LED_BLINK
#define UATH_FILTER_RX_BEACON
#define UATH_TXQID_MINRATE
#define WDCMSG_TARGET_STOP
#define WDCMSG_SETUP_TX_QUEUE
#define WDCMSG_SEND_COMPLETE
#define UATH_STATUS_PHY_ERR
#define UATH_STATUS_CRC_ERR
#define UATH_CFLAGS_RXMSG
#define UATH_STATUS_DECOMP_ERR
#define WDCMSG_RESET_KEY_CACHE
#define WDCMSG_SET_KEY_CACHE_ENTRY
#define WDCMSG_SET_DEFAULT_KEY
#define WDCMSG_TARGET_SET_CONFIG
#define UATH_FILTER_RX_BCAST
#define UATH_STATUS_DECRYPT_MIC_ERR
#define UATH_STATUS_DECRYPT_CRC_ERR
@ CFG_GMODE_PROTECT_RATE_INDEX
@ CFG_RATE_CONTROL_ENABLE
#define UATH_FILTER_RX_UCAST
#define UATH_LED_ACTIVITY
#define UATH_FILTER_OP_INIT
#define WDCMSG_TARGET_START
#define WDCMSG_WRITE_ASSOCID
#define UATH_RX_DUMMYSIZE
#define UATH_FILTER_RX_PROM
#define UATH_CFLAGS_FINAL
#define UATH_STAT_INC(sc, var)
#define UATH_RESET_INTRX(sc)
#define UATH_FLAG_INITDONE
#define UATH_RX_DATA_LIST_COUNT
#define UATH_RX_RADIOTAP_PRESENT
#define UATH_FLAG_INVALID
#define UATH_ASSERT_LOCKED(sc)
#define UATH_DATA_TIMEOUT
#define UATH_STAT_DEC(sc, var)
#define UATH_CMD_FLAG_ASYNC
#define UATH_CMD_LIST_COUNT
#define UATH_CMD_FLAG_MAGIC
#define UATH_TX_RADIOTAP_PRESENT
#define UATH_TX_DATA_LIST_COUNT
#define UATH_MAX_INTRX_SIZE
#define UATH_CMD_FLAG_READ
struct uath_cmd_rateset rateset
struct uath_cmd_connection_attr connattr
struct uath_cmd_rateset rateset
uint8_t set[UATH_MAX_NRATES]
struct uath_cmd_txq_attr attr
struct ieee80211_node * ni
uint32_t supportCipherAES_CCM
uint32_t analog2GhzRevision
uint32_t chanSpreadSupport
uint32_t twiceAntennaGain5G
uint32_t analog5GhzRevision
uint32_t chapTuningSupport
uint32_t supportCipherWEP
uint32_t supportCipherTKIP
uint32_t twiceAntennaGain2G
uint32_t turboPrimeSupport
uint32_t fastFramesSupport
struct ieee80211com sc_ic
uath_cmdhead sc_cmd_active
struct usb_xfer * sc_xfer[UATH_N_XFERS]
struct mbuf * sc_intrx_head
uath_cmdhead sc_cmd_inactive
struct uath_data sc_tx[UATH_TX_DATA_LIST_COUNT]
struct uath_cmd sc_cmd[UATH_CMD_LIST_COUNT]
uath_datahead sc_rx_inactive
struct usb_device * sc_udev
struct mbuf * sc_intrx_tail
uath_cmdhead sc_cmd_pending
uath_datahead sc_rx_active
struct uath_devcap sc_devcap
uath_datahead sc_tx_inactive
struct uath_tx_radiotap_header sc_txtap
uath_cmdhead sc_cmd_waiting
struct uath_data sc_rx[UATH_RX_DATA_LIST_COUNT]
struct uath_rx_radiotap_header sc_rxtap
uath_datahead sc_tx_active
uath_datahead sc_tx_pending
struct callout watchdog_ch
uint32_t st_decrypt_micerr
uint32_t st_stopinprogress
uint32_t st_badchunkseqnum
uint32_t st_decrypt_crcerr
int(* newstate)(struct ieee80211vap *, enum ieee80211_state, int)
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_device * device
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
struct usb_endpoint_descriptor desc
const char * usbd_errstr(usb_error_t err)
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, void *ptr, usb_frlength_t len)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
void * usbd_xfer_get_frame_buffer(struct usb_xfer *xfer, usb_frcount_t frindex)
struct usb_page_cache * usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
void usbd_transfer_start(struct usb_xfer *xfer)
void usbd_transfer_drain(struct usb_xfer *xfer)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
#define USB_ST_TRANSFERRED
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define STRUCT_USB_HOST_ID
#define USB_GET_STATE(xfer)