svn commit: r288290 - head/sys/dev/otus
Adrian Chadd
adrian at FreeBSD.org
Sun Sep 27 03:46:57 UTC 2015
Author: adrian
Date: Sun Sep 27 03:46:55 2015
New Revision: 288290
URL: https://svnweb.freebsd.org/changeset/base/288290
Log:
Track the command response code buffer size and verify it in the
receive path.
Modified:
head/sys/dev/otus/if_otus.c
head/sys/dev/otus/if_otusreg.h
Modified: head/sys/dev/otus/if_otus.c
==============================================================================
--- head/sys/dev/otus/if_otus.c Sun Sep 27 01:37:30 2015 (r288289)
+++ head/sys/dev/otus/if_otus.c Sun Sep 27 03:46:55 2015 (r288290)
@@ -156,7 +156,7 @@ void otus_do_async(struct otus_softc *,
int otus_newstate(struct ieee80211vap *, enum ieee80211_state,
int);
int otus_cmd(struct otus_softc *, uint8_t, const void *, int,
- void *);
+ void *, int);
void otus_write(struct otus_softc *, uint32_t, uint32_t);
int otus_write_barrier(struct otus_softc *);
struct ieee80211_node *otus_node_alloc(struct ieee80211com *);
@@ -702,7 +702,7 @@ otus_attachhook(struct otus_softc *sc)
/* Send an ECHO command to check that everything is settled. */
in = 0xbadc0ffe;
- if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof in, &out) != 0) {
+ if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof in, &out, sizeof(out)) != 0) {
OTUS_UNLOCK(sc);
device_printf(sc->sc_dev,
"%s: echo command failed\n", __func__);
@@ -1282,7 +1282,7 @@ otus_newstate(struct ieee80211vap *vap,
int
otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen,
- void *odata)
+ void *odata, int odatalen)
{
struct otus_tx_cmd *cmd;
struct ar_cmd_hdr *hdr;
@@ -1321,6 +1321,7 @@ otus_cmd(struct otus_softc *sc, uint8_t
__func__, code, ilen, hdr->token);
cmd->odata = odata;
+ cmd->odatalen = odatalen;
cmd->buflen = xferlen;
/* Queue the command to the endpoint */
@@ -1373,7 +1374,7 @@ otus_write_barrier(struct otus_softc *sc
sc->write_idx);
error = otus_cmd(sc, AR_CMD_WREG, sc->write_buf,
- sizeof (sc->write_buf[0]) * sc->write_idx, NULL);
+ sizeof (sc->write_buf[0]) * sc->write_idx, NULL, 0);
sc->write_idx = 0;
return error;
}
@@ -1428,7 +1429,7 @@ otus_read_eeprom(struct otus_softc *sc)
for (i = 0; i < sizeof (sc->eeprom) / 32; i++) {
for (j = 0; j < 8; j++, reg += 4)
regs[j] = htole32(reg);
- error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof regs, eep);
+ error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof regs, eep, 32);
if (error != 0)
break;
eep += 32;
@@ -1477,8 +1478,18 @@ otus_cmd_handle_response(struct otus_sof
(int) cmd->token);
if (hdr->token == cmd->token) {
/* Copy answer into caller's supplied buffer. */
- if (cmd->odata != NULL)
- memcpy(cmd->odata, &hdr[1], hdr->len);
+ if (cmd->odata != NULL) {
+ if (hdr->len != cmd->odatalen) {
+ device_printf(sc->sc_dev,
+ "%s: code 0x%02x, len=%d, olen=%d\n",
+ __func__,
+ (int) hdr->code,
+ (int) hdr->len,
+ (int) cmd->odatalen);
+ }
+ memcpy(cmd->odata, &hdr[1],
+ MIN(cmd->odatalen, hdr->len));
+ }
wakeup(cmd);
}
@@ -1513,8 +1524,9 @@ otus_cmd_rxeof(struct otus_softc *sc, ui
hdr->code);
/*
- * XXX TODO: has to reach into the cmd queue "waiting for
+ * This has to reach into the cmd queue "waiting for
* an RX response" list, grab the head entry and check
+ * if we need to wake anyone up.
*/
if ((hdr->code & 0xc0) != 0xc0) {
otus_cmd_handle_response(sc, hdr);
@@ -2686,7 +2698,7 @@ otus_set_chan(struct otus_softc *sc, str
goto finish;
/* XXX Is that FREQ_START ? */
- error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL);
+ error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL, 0);
if (error != 0)
goto finish;
@@ -2758,7 +2770,7 @@ otus_set_chan(struct otus_softc *sc, str
cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000);
OTUS_DPRINTF(sc, OTUS_DEBUG_RESET,
"%s\n", (code == AR_CMD_RF_INIT) ? "RF_INIT" : "FREQUENCY");
- error = otus_cmd(sc, code, &cmd, sizeof cmd, &rsp);
+ error = otus_cmd(sc, code, &cmd, sizeof cmd, &rsp, sizeof(rsp));
if (error != 0)
goto finish;
if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) {
@@ -2848,14 +2860,14 @@ otus_set_key_cb(struct otus_softc *sc, v
}
key.cipher = htole16(cipher);
memcpy(key.key, k->k_key, MIN(k->k_len, 16));
- error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL);
+ error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0);
if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP)
return;
/* TKIP: set Tx/Rx MIC Key. */
key.kix = htole16(1);
memcpy(key.key, k->k_key + 16, 16);
- (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL);
+ (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0);
}
void
@@ -2886,7 +2898,7 @@ otus_delete_key_cb(struct otus_softc *sc
uid = htole32(k->k_id);
else
uid = htole32(OTUS_UID(cmd->associd));
- (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof uid, NULL);
+ (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof uid, NULL, 0);
}
#endif
Modified: head/sys/dev/otus/if_otusreg.h
==============================================================================
--- head/sys/dev/otus/if_otusreg.h Sun Sep 27 01:37:30 2015 (r288289)
+++ head/sys/dev/otus/if_otusreg.h Sun Sep 27 03:46:55 2015 (r288290)
@@ -875,6 +875,7 @@ struct otus_tx_cmd {
uint8_t *buf;
uint16_t buflen;
void * *odata;
+ uint16_t odatalen;
uint16_t token;
STAILQ_ENTRY(otus_tx_cmd) next_cmd;
};
More information about the svn-src-all
mailing list