- Fixes for suspend/resume code (MPI-350)
- Cache temp. keys so they are preserved across suspend/resume (MPI-350) - Reads and writes are real fast to the MPI-350 causing early timeouts so wait do some DELAYs to slow things down in the spin loops. - Stream line setting RIDs when they are better to be set via another function - Add better support for setting home key via "ifconfig an0 wepkey 9:<key>" Tested by: Peter Radcliffe <pir@pir.net> (in -stable) myself in -current & -stable MFC in: 3 days
This commit is contained in:
parent
a282253a29
commit
b376d47740
@ -154,7 +154,6 @@ static int an_cmd_struct (struct an_softc *, struct an_command *,
|
|||||||
struct an_reply *);
|
struct an_reply *);
|
||||||
static int an_read_record (struct an_softc *, struct an_ltv_gen *);
|
static int an_read_record (struct an_softc *, struct an_ltv_gen *);
|
||||||
static int an_write_record (struct an_softc *, struct an_ltv_gen *);
|
static int an_write_record (struct an_softc *, struct an_ltv_gen *);
|
||||||
static void an_kick (struct an_softc *);
|
|
||||||
static int an_read_data (struct an_softc *, int, int, caddr_t, int);
|
static int an_read_data (struct an_softc *, int, int, caddr_t, int);
|
||||||
static int an_write_data (struct an_softc *, int, int, caddr_t, int);
|
static int an_write_data (struct an_softc *, int, int, caddr_t, int);
|
||||||
static int an_seek (struct an_softc *, int, int, int);
|
static int an_seek (struct an_softc *, int, int, int);
|
||||||
@ -205,7 +204,7 @@ static char an_conf_cache[256];
|
|||||||
|
|
||||||
/* sysctl vars */
|
/* sysctl vars */
|
||||||
|
|
||||||
SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID");
|
SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD, 0, "Wireless driver parameters");
|
||||||
|
|
||||||
/* XXX violate ethernet/netgraph callback hooks */
|
/* XXX violate ethernet/netgraph callback hooks */
|
||||||
extern void (*ng_ether_attach_p)(struct ifnet *ifp);
|
extern void (*ng_ether_attach_p)(struct ifnet *ifp);
|
||||||
@ -264,7 +263,7 @@ sysctl_an_dump(SYSCTL_HANDLER_ARGS)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW,
|
SYSCTL_PROC(_hw_an, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW,
|
||||||
0, sizeof(an_conf), sysctl_an_dump, "A", "");
|
0, sizeof(an_conf), sysctl_an_dump, "A", "");
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -302,7 +301,7 @@ sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCTL_PROC(_machdep, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW,
|
SYSCTL_PROC(_hw_an, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW,
|
||||||
0, sizeof(an_conf_cache), sysctl_an_cache_mode, "A", "");
|
0, sizeof(an_conf_cache), sysctl_an_cache_mode, "A", "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1235,31 +1234,6 @@ an_intr(xsc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
an_kick(sc)
|
|
||||||
struct an_softc *sc;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), AN_CMD_NOOP2);
|
|
||||||
|
|
||||||
if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
|
|
||||||
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < AN_TIMEOUT; i++) {
|
|
||||||
if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350))
|
|
||||||
& AN_EV_CMD)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
|
|
||||||
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
|
|
||||||
}
|
|
||||||
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
|
|
||||||
if (i == AN_TIMEOUT) {
|
|
||||||
printf ("COULDN'T CLEAR\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
an_cmd_struct(sc, cmd, reply)
|
an_cmd_struct(sc, cmd, reply)
|
||||||
@ -1271,7 +1245,7 @@ an_cmd_struct(sc, cmd, reply)
|
|||||||
|
|
||||||
for (i = 0; i != AN_TIMEOUT; i++) {
|
for (i = 0; i != AN_TIMEOUT; i++) {
|
||||||
if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
|
if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
|
||||||
DELAY(10);
|
DELAY(1000);
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1288,11 +1262,9 @@ an_cmd_struct(sc, cmd, reply)
|
|||||||
for (i = 0; i < AN_TIMEOUT; i++) {
|
for (i = 0; i < AN_TIMEOUT; i++) {
|
||||||
if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD)
|
if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD)
|
||||||
break;
|
break;
|
||||||
|
DELAY(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == AN_TIMEOUT)
|
|
||||||
an_kick(sc);
|
|
||||||
|
|
||||||
reply->an_resp0 = CSR_READ_2(sc, AN_RESP0(sc->mpi350));
|
reply->an_resp0 = CSR_READ_2(sc, AN_RESP0(sc->mpi350));
|
||||||
reply->an_resp1 = CSR_READ_2(sc, AN_RESP1(sc->mpi350));
|
reply->an_resp1 = CSR_READ_2(sc, AN_RESP1(sc->mpi350));
|
||||||
reply->an_resp2 = CSR_READ_2(sc, AN_RESP2(sc->mpi350));
|
reply->an_resp2 = CSR_READ_2(sc, AN_RESP2(sc->mpi350));
|
||||||
@ -1554,8 +1526,10 @@ an_write_record(sc, ltv)
|
|||||||
CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
|
CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
|
||||||
((u_int32_t*)&an_rid_desc)[i]);
|
((u_int32_t*)&an_rid_desc)[i]);
|
||||||
|
|
||||||
|
DELAY(100000);
|
||||||
|
|
||||||
if ((i = an_cmd_struct(sc, &cmd, &reply))) {
|
if ((i = an_cmd_struct(sc, &cmd, &reply))) {
|
||||||
printf("an%d: failed to write RID %x %x %x %x %x, %d\n",
|
printf("an%d: failed to write RID 1 %x %x %x %x %x, %d\n",
|
||||||
sc->an_unit, ltv->an_type,
|
sc->an_unit, ltv->an_type,
|
||||||
reply.an_status,
|
reply.an_status,
|
||||||
reply.an_resp0,
|
reply.an_resp0,
|
||||||
@ -1568,7 +1542,7 @@ an_write_record(sc, ltv)
|
|||||||
ptr = (u_int16_t *)buf;
|
ptr = (u_int16_t *)buf;
|
||||||
|
|
||||||
if (reply.an_status & AN_CMD_QUAL_MASK) {
|
if (reply.an_status & AN_CMD_QUAL_MASK) {
|
||||||
printf("an%d: failed to write RID %x %x %x %x %x, %d\n",
|
printf("an%d: failed to write RID 2 %x %x %x %x %x, %d\n",
|
||||||
sc->an_unit, ltv->an_type,
|
sc->an_unit, ltv->an_type,
|
||||||
reply.an_status,
|
reply.an_status,
|
||||||
reply.an_resp0,
|
reply.an_resp0,
|
||||||
@ -1577,6 +1551,7 @@ an_write_record(sc, ltv)
|
|||||||
i);
|
i);
|
||||||
return(EIO);
|
return(EIO);
|
||||||
}
|
}
|
||||||
|
DELAY(100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
@ -1812,6 +1787,10 @@ an_setdef(sc, areq)
|
|||||||
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
|
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
|
||||||
break;
|
break;
|
||||||
case AN_RID_WEP_TEMP:
|
case AN_RID_WEP_TEMP:
|
||||||
|
/* Cache the temp keys */
|
||||||
|
bcopy(areq,
|
||||||
|
&sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex],
|
||||||
|
sizeof(struct an_ltv_key));
|
||||||
case AN_RID_WEP_PERM:
|
case AN_RID_WEP_PERM:
|
||||||
case AN_RID_LEAPUSERNAME:
|
case AN_RID_LEAPUSERNAME:
|
||||||
case AN_RID_LEAPPASSWORD:
|
case AN_RID_LEAPPASSWORD:
|
||||||
@ -2315,7 +2294,7 @@ an_ioctl(ifp, command, data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE80211_IOC_WEPKEY:
|
case IEEE80211_IOC_WEPKEY:
|
||||||
if (ireq->i_val < 0 || ireq->i_val > 7 ||
|
if (ireq->i_val < 0 || ireq->i_val > 8 ||
|
||||||
ireq->i_len > 13) {
|
ireq->i_len > 13) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
@ -2323,27 +2302,35 @@ an_ioctl(ifp, command, data)
|
|||||||
error = copyin(ireq->i_data, tmpstr, 13);
|
error = copyin(ireq->i_data, tmpstr, 13);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* Map the 9th key into the home mode
|
||||||
|
* since that is how it is stored on
|
||||||
|
* the card
|
||||||
|
*/
|
||||||
bzero(&sc->areq, sizeof(struct an_ltv_key));
|
bzero(&sc->areq, sizeof(struct an_ltv_key));
|
||||||
sc->areq.an_len = sizeof(struct an_ltv_key);
|
sc->areq.an_len = sizeof(struct an_ltv_key);
|
||||||
key->mac[0] = 1; /* The others are 0. */
|
key->mac[0] = 1; /* The others are 0. */
|
||||||
key->kindex = ireq->i_val % 4;
|
if (ireq->i_val < 4) {
|
||||||
if (ireq->i_val < 4)
|
|
||||||
sc->areq.an_type = AN_RID_WEP_TEMP;
|
sc->areq.an_type = AN_RID_WEP_TEMP;
|
||||||
else
|
key->kindex = ireq->i_val;
|
||||||
|
} else {
|
||||||
sc->areq.an_type = AN_RID_WEP_PERM;
|
sc->areq.an_type = AN_RID_WEP_PERM;
|
||||||
|
key->kindex = ireq->i_val - 4;
|
||||||
|
}
|
||||||
key->klen = ireq->i_len;
|
key->klen = ireq->i_len;
|
||||||
bcopy(tmpstr, key->key, key->klen);
|
bcopy(tmpstr, key->key, key->klen);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_IOC_WEPTXKEY:
|
case IEEE80211_IOC_WEPTXKEY:
|
||||||
|
if (ireq->i_val < 0 || ireq->i_val > 4) {
|
||||||
|
error = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map the 5th key into the home mode
|
* Map the 5th key into the home mode
|
||||||
* since that is how it is stored on
|
* since that is how it is stored on
|
||||||
* the card
|
* the card
|
||||||
*/
|
*/
|
||||||
if (ireq->i_val < 0 || ireq->i_val > 4) {
|
|
||||||
error = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sc->areq.an_len = sizeof(struct an_ltv_genconfig);
|
sc->areq.an_len = sizeof(struct an_ltv_genconfig);
|
||||||
sc->areq.an_type = AN_RID_ACTUALCFG;
|
sc->areq.an_type = AN_RID_ACTUALCFG;
|
||||||
if (an_read_record(sc,
|
if (an_read_record(sc,
|
||||||
@ -2360,7 +2347,9 @@ an_ioctl(ifp, command, data)
|
|||||||
|
|
||||||
sc->an_config.an_home_product
|
sc->an_config.an_home_product
|
||||||
= config->an_home_product;
|
= config->an_home_product;
|
||||||
an_write_record(sc, (struct an_ltv_gen *)&sc->areq);
|
|
||||||
|
/* update configuration */
|
||||||
|
an_init(sc);
|
||||||
|
|
||||||
bzero(&sc->areq, sizeof(struct an_ltv_key));
|
bzero(&sc->areq, sizeof(struct an_ltv_key));
|
||||||
sc->areq.an_len = sizeof(struct an_ltv_key);
|
sc->areq.an_len = sizeof(struct an_ltv_key);
|
||||||
@ -2828,6 +2817,7 @@ an_shutdown(dev)
|
|||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
an_stop(sc);
|
an_stop(sc);
|
||||||
|
sc->an_gone = 1;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2838,16 +2828,30 @@ an_resume(dev)
|
|||||||
{
|
{
|
||||||
struct an_softc *sc;
|
struct an_softc *sc;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
|
int i;
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
AN_LOCK(sc);
|
||||||
ifp = &sc->arpcom.ac_if;
|
ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
|
sc->an_gone = 0;
|
||||||
an_reset(sc);
|
an_reset(sc);
|
||||||
if (sc->mpi350)
|
if (sc->mpi350)
|
||||||
an_init_mpi350_desc(sc);
|
an_init_mpi350_desc(sc);
|
||||||
an_init(sc);
|
an_init(sc);
|
||||||
|
|
||||||
|
/* Recovery temporary keys */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
sc->areq.an_type = AN_RID_WEP_TEMP;
|
||||||
|
sc->areq.an_len = sizeof(struct an_ltv_key);
|
||||||
|
bcopy(&sc->an_temp_keys[i],
|
||||||
|
&sc->areq, sizeof(struct an_ltv_key));
|
||||||
|
an_setdef(sc, &sc->areq);
|
||||||
|
}
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_UP)
|
if (ifp->if_flags & IFF_UP)
|
||||||
an_start(ifp);
|
an_start(ifp);
|
||||||
|
AN_UNLOCK(sc);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2899,13 +2903,13 @@ int an_nextitem; /* index/# of entries */
|
|||||||
* so ping/unicast anll work say anth pt. to pt. antennae setup.
|
* so ping/unicast anll work say anth pt. to pt. antennae setup.
|
||||||
*/
|
*/
|
||||||
static int an_cache_mcastonly = 0;
|
static int an_cache_mcastonly = 0;
|
||||||
SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
|
SYSCTL_INT(_hw_an, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
|
||||||
&an_cache_mcastonly, 0, "");
|
&an_cache_mcastonly, 0, "");
|
||||||
|
|
||||||
/* set true if you want to limit cache items to IP packets only
|
/* set true if you want to limit cache items to IP packets only
|
||||||
*/
|
*/
|
||||||
static int an_cache_iponly = 1;
|
static int an_cache_iponly = 1;
|
||||||
SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
|
SYSCTL_INT(_hw_an, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
|
||||||
&an_cache_iponly, 0, "");
|
&an_cache_iponly, 0, "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3102,8 +3106,8 @@ an_media_change(ifp)
|
|||||||
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
|
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otype != sc->an_config.an_opmode
|
if (otype != sc->an_config.an_opmode ||
|
||||||
|| orate != sc->an_tx_rate)
|
orate != sc->an_tx_rate)
|
||||||
an_init(sc);
|
an_init(sc);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define AN_TIMEOUT 600000
|
#define AN_TIMEOUT 65536
|
||||||
|
|
||||||
/* Default network name: <empty string> */
|
/* Default network name: <empty string> */
|
||||||
#define AN_DEFAULT_NETNAME ""
|
#define AN_DEFAULT_NETNAME ""
|
||||||
@ -460,8 +460,7 @@ struct an_softc {
|
|||||||
struct an_ltv_caps an_caps;
|
struct an_ltv_caps an_caps;
|
||||||
struct an_ltv_ssidlist an_ssidlist;
|
struct an_ltv_ssidlist an_ssidlist;
|
||||||
struct an_ltv_aplist an_aplist;
|
struct an_ltv_aplist an_aplist;
|
||||||
struct an_ltv_key an_temp_keys;
|
struct an_ltv_key an_temp_keys[4];
|
||||||
struct an_ltv_key an_perm_keys;
|
|
||||||
int an_tx_rate;
|
int an_tx_rate;
|
||||||
int an_rxmode;
|
int an_rxmode;
|
||||||
int an_gone;
|
int an_gone;
|
||||||
|
Loading…
Reference in New Issue
Block a user