Apply some contributed patches to reduce number of tx buffer allocation
failures and add some support for WEP on Prism II chip. Submitted by: YAMAMOTO Shigeru <shigeru@iij.ad.jp>
This commit is contained in:
parent
ea1bd4d556
commit
82aa2600cc
@ -231,10 +231,34 @@ static int wi_pccard_attach(device_t dev)
|
||||
struct wi_ltv_gen gen;
|
||||
struct ifnet *ifp;
|
||||
int error;
|
||||
u_int32_t flags;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
/*
|
||||
* XXX: quick hack to support Prism II chip.
|
||||
* Currently, we need to set a flags in pccard.conf to specify
|
||||
* which type chip is used.
|
||||
*
|
||||
* We need to replace this code in a future.
|
||||
* It is better to use CIS than using a flag.
|
||||
*/
|
||||
flags = device_get_flags(dev);
|
||||
#define WI_FLAGS_PRISM2 0x10000
|
||||
if (flags & WI_FLAGS_PRISM2) {
|
||||
sc->wi_prism2 = 1;
|
||||
if (bootverbose) {
|
||||
device_printf(dev, "found PrismII chip\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
sc->wi_prism2 = 0;
|
||||
if (bootverbose) {
|
||||
device_printf(dev, "found Lucent chip\n");
|
||||
}
|
||||
}
|
||||
|
||||
error = wi_alloc(dev);
|
||||
if (error) {
|
||||
device_printf(dev, "wi_alloc() failed! (%d)\n", error);
|
||||
@ -320,6 +344,12 @@ static int wi_pccard_attach(device_t dev)
|
||||
wi_read_record(sc, &gen);
|
||||
sc->wi_has_wep = gen.wi_val;
|
||||
|
||||
if (bootverbose) {
|
||||
device_printf(sc->dev,
|
||||
__FUNCTION__ ":wi_has_wep = %d\n",
|
||||
sc->wi_has_wep);
|
||||
}
|
||||
|
||||
bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
|
||||
|
||||
wi_init(sc);
|
||||
@ -589,7 +619,21 @@ static int wi_cmd(sc, cmd, val)
|
||||
{
|
||||
int i, s = 0;
|
||||
|
||||
/* wait for the busy bit to clear */
|
||||
for (i = 0; i < WI_TIMEOUT; i++) {
|
||||
if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
|
||||
break;
|
||||
}
|
||||
DELAY(10*1000); /* 10 m sec */
|
||||
}
|
||||
|
||||
if (i == WI_TIMEOUT) {
|
||||
return(ETIMEDOUT);
|
||||
}
|
||||
|
||||
CSR_WRITE_2(sc, WI_PARAM0, val);
|
||||
CSR_WRITE_2(sc, WI_PARAM1, 0);
|
||||
CSR_WRITE_2(sc, WI_PARAM2, 0);
|
||||
CSR_WRITE_2(sc, WI_COMMAND, cmd);
|
||||
|
||||
for (i = 0; i < WI_TIMEOUT; i++) {
|
||||
@ -621,11 +665,12 @@ static int wi_cmd(sc, cmd, val)
|
||||
static void wi_reset(sc)
|
||||
struct wi_softc *sc;
|
||||
{
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
DELAY(100000);
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
DELAY(100000);
|
||||
#ifdef foo
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
DELAY(100000);
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
#endif
|
||||
DELAY(100000);
|
||||
if (wi_cmd(sc, WI_CMD_INI, 0))
|
||||
device_printf(sc->dev, "init failed\n");
|
||||
CSR_WRITE_2(sc, WI_INT_EN, 0);
|
||||
@ -633,7 +678,7 @@ static void wi_reset(sc)
|
||||
|
||||
/* Calibrate timer. */
|
||||
WI_SETVAL(WI_RID_TICK_TIME, 8);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -646,6 +691,23 @@ static int wi_read_record(sc, ltv)
|
||||
{
|
||||
u_int16_t *ptr;
|
||||
int i, len, code;
|
||||
struct wi_ltv_gen *oltv, p2ltv;
|
||||
|
||||
oltv = ltv;
|
||||
if (sc->wi_prism2) {
|
||||
switch (ltv->wi_type) {
|
||||
case WI_RID_ENCRYPTION:
|
||||
p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
|
||||
p2ltv.wi_len = 2;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
|
||||
p2ltv.wi_len = 2;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell the NIC to enter record read mode. */
|
||||
if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
|
||||
@ -675,6 +737,35 @@ static int wi_read_record(sc, ltv)
|
||||
for (i = 0; i < ltv->wi_len - 1; i++)
|
||||
ptr[i] = CSR_READ_2(sc, WI_DATA1);
|
||||
|
||||
if (sc->wi_prism2) {
|
||||
switch (oltv->wi_type) {
|
||||
case WI_RID_TX_RATE:
|
||||
case WI_RID_CUR_TX_RATE:
|
||||
switch (ltv->wi_val) {
|
||||
case 1: oltv->wi_val = 1; break;
|
||||
case 2: oltv->wi_val = 2; break;
|
||||
case 3: oltv->wi_val = 6; break;
|
||||
case 4: oltv->wi_val = 5; break;
|
||||
case 7: oltv->wi_val = 7; break;
|
||||
case 8: oltv->wi_val = 11; break;
|
||||
case 15: oltv->wi_val = 3; break;
|
||||
default: oltv->wi_val = 0x100 + ltv->wi_val; break;
|
||||
}
|
||||
break;
|
||||
case WI_RID_ENCRYPTION:
|
||||
oltv->wi_len = 2;
|
||||
if (ltv->wi_val & 0x01)
|
||||
oltv->wi_val = 1;
|
||||
else
|
||||
oltv->wi_val = 0;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
oltv->wi_len = 2;
|
||||
oltv->wi_val = ltv->wi_val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -687,6 +778,59 @@ static int wi_write_record(sc, ltv)
|
||||
{
|
||||
u_int16_t *ptr;
|
||||
int i;
|
||||
struct wi_ltv_gen p2ltv;
|
||||
|
||||
if (sc->wi_prism2) {
|
||||
switch (ltv->wi_type) {
|
||||
case WI_RID_TX_RATE:
|
||||
p2ltv.wi_type = WI_RID_TX_RATE;
|
||||
p2ltv.wi_len = 2;
|
||||
switch (ltv->wi_val) {
|
||||
case 1: p2ltv.wi_val = 1; break;
|
||||
case 2: p2ltv.wi_val = 2; break;
|
||||
case 3: p2ltv.wi_val = 15; break;
|
||||
case 5: p2ltv.wi_val = 4; break;
|
||||
case 6: p2ltv.wi_val = 3; break;
|
||||
case 7: p2ltv.wi_val = 7; break;
|
||||
case 11: p2ltv.wi_val = 8; break;
|
||||
default: return EINVAL;
|
||||
}
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_ENCRYPTION:
|
||||
p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
|
||||
p2ltv.wi_len = 2;
|
||||
if (ltv->wi_val)
|
||||
p2ltv.wi_val = 0x03;
|
||||
else
|
||||
p2ltv.wi_val = 0x90;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
|
||||
p2ltv.wi_len = 2;
|
||||
p2ltv.wi_val = ltv->wi_val;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_DEFLT_CRYPT_KEYS:
|
||||
{
|
||||
int error;
|
||||
struct wi_ltv_str ws;
|
||||
struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv;
|
||||
for (i = 0; i < 4; i++) {
|
||||
ws.wi_len = 4;
|
||||
ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
|
||||
memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5);
|
||||
ws.wi_str[5] = '\0';
|
||||
error = wi_write_record(sc,
|
||||
(struct wi_ltv_gen *)&ws);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
|
||||
return(EIO);
|
||||
@ -1362,7 +1506,8 @@ static int wi_alloc(dev)
|
||||
|
||||
rid = 0;
|
||||
sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
0, ~0, (1 << 6),
|
||||
rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
|
||||
if (!sc->iobase) {
|
||||
device_printf(dev, "No I/O space?!\n");
|
||||
return (ENXIO);
|
||||
|
@ -66,6 +66,13 @@ struct wi_counters {
|
||||
#define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0
|
||||
#define WI_RID_TX_CRYPT_KEY 0xFCB1
|
||||
#define WI_RID_WEP_AVAIL 0xFD4F
|
||||
#define WI_RID_P2_TX_CRYPT_KEY 0xFC23
|
||||
#define WI_RID_P2_CRYPT_KEY0 0xFC24
|
||||
#define WI_RID_P2_CRYPT_KEY1 0xFC25
|
||||
#define WI_RID_P2_CRYPT_KEY2 0xFC26
|
||||
#define WI_RID_P2_CRYPT_KEY3 0xFC27
|
||||
#define WI_RID_P2_ENCRYPTION 0xFC28
|
||||
#define WI_RID_CUR_TX_RATE 0xFD44 /* current TX rate */
|
||||
struct wi_key {
|
||||
u_int16_t wi_keylen;
|
||||
u_int8_t wi_keydat[14];
|
||||
@ -118,6 +125,7 @@ struct wi_softc {
|
||||
#endif
|
||||
struct callout_handle wi_stat_ch;
|
||||
struct mtx wi_mtx;
|
||||
int wi_prism2; /* set to 1 if it uses a Prism II chip */
|
||||
};
|
||||
|
||||
#define WI_LOCK(_sc) mtx_enter(&(_sc)->wi_mtx, MTX_DEF)
|
||||
|
@ -231,10 +231,34 @@ static int wi_pccard_attach(device_t dev)
|
||||
struct wi_ltv_gen gen;
|
||||
struct ifnet *ifp;
|
||||
int error;
|
||||
u_int32_t flags;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
/*
|
||||
* XXX: quick hack to support Prism II chip.
|
||||
* Currently, we need to set a flags in pccard.conf to specify
|
||||
* which type chip is used.
|
||||
*
|
||||
* We need to replace this code in a future.
|
||||
* It is better to use CIS than using a flag.
|
||||
*/
|
||||
flags = device_get_flags(dev);
|
||||
#define WI_FLAGS_PRISM2 0x10000
|
||||
if (flags & WI_FLAGS_PRISM2) {
|
||||
sc->wi_prism2 = 1;
|
||||
if (bootverbose) {
|
||||
device_printf(dev, "found PrismII chip\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
sc->wi_prism2 = 0;
|
||||
if (bootverbose) {
|
||||
device_printf(dev, "found Lucent chip\n");
|
||||
}
|
||||
}
|
||||
|
||||
error = wi_alloc(dev);
|
||||
if (error) {
|
||||
device_printf(dev, "wi_alloc() failed! (%d)\n", error);
|
||||
@ -320,6 +344,12 @@ static int wi_pccard_attach(device_t dev)
|
||||
wi_read_record(sc, &gen);
|
||||
sc->wi_has_wep = gen.wi_val;
|
||||
|
||||
if (bootverbose) {
|
||||
device_printf(sc->dev,
|
||||
__FUNCTION__ ":wi_has_wep = %d\n",
|
||||
sc->wi_has_wep);
|
||||
}
|
||||
|
||||
bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
|
||||
|
||||
wi_init(sc);
|
||||
@ -589,7 +619,21 @@ static int wi_cmd(sc, cmd, val)
|
||||
{
|
||||
int i, s = 0;
|
||||
|
||||
/* wait for the busy bit to clear */
|
||||
for (i = 0; i < WI_TIMEOUT; i++) {
|
||||
if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
|
||||
break;
|
||||
}
|
||||
DELAY(10*1000); /* 10 m sec */
|
||||
}
|
||||
|
||||
if (i == WI_TIMEOUT) {
|
||||
return(ETIMEDOUT);
|
||||
}
|
||||
|
||||
CSR_WRITE_2(sc, WI_PARAM0, val);
|
||||
CSR_WRITE_2(sc, WI_PARAM1, 0);
|
||||
CSR_WRITE_2(sc, WI_PARAM2, 0);
|
||||
CSR_WRITE_2(sc, WI_COMMAND, cmd);
|
||||
|
||||
for (i = 0; i < WI_TIMEOUT; i++) {
|
||||
@ -621,11 +665,12 @@ static int wi_cmd(sc, cmd, val)
|
||||
static void wi_reset(sc)
|
||||
struct wi_softc *sc;
|
||||
{
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
DELAY(100000);
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
DELAY(100000);
|
||||
#ifdef foo
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
DELAY(100000);
|
||||
wi_cmd(sc, WI_CMD_INI, 0);
|
||||
#endif
|
||||
DELAY(100000);
|
||||
if (wi_cmd(sc, WI_CMD_INI, 0))
|
||||
device_printf(sc->dev, "init failed\n");
|
||||
CSR_WRITE_2(sc, WI_INT_EN, 0);
|
||||
@ -633,7 +678,7 @@ static void wi_reset(sc)
|
||||
|
||||
/* Calibrate timer. */
|
||||
WI_SETVAL(WI_RID_TICK_TIME, 8);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -646,6 +691,23 @@ static int wi_read_record(sc, ltv)
|
||||
{
|
||||
u_int16_t *ptr;
|
||||
int i, len, code;
|
||||
struct wi_ltv_gen *oltv, p2ltv;
|
||||
|
||||
oltv = ltv;
|
||||
if (sc->wi_prism2) {
|
||||
switch (ltv->wi_type) {
|
||||
case WI_RID_ENCRYPTION:
|
||||
p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
|
||||
p2ltv.wi_len = 2;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
|
||||
p2ltv.wi_len = 2;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell the NIC to enter record read mode. */
|
||||
if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
|
||||
@ -675,6 +737,35 @@ static int wi_read_record(sc, ltv)
|
||||
for (i = 0; i < ltv->wi_len - 1; i++)
|
||||
ptr[i] = CSR_READ_2(sc, WI_DATA1);
|
||||
|
||||
if (sc->wi_prism2) {
|
||||
switch (oltv->wi_type) {
|
||||
case WI_RID_TX_RATE:
|
||||
case WI_RID_CUR_TX_RATE:
|
||||
switch (ltv->wi_val) {
|
||||
case 1: oltv->wi_val = 1; break;
|
||||
case 2: oltv->wi_val = 2; break;
|
||||
case 3: oltv->wi_val = 6; break;
|
||||
case 4: oltv->wi_val = 5; break;
|
||||
case 7: oltv->wi_val = 7; break;
|
||||
case 8: oltv->wi_val = 11; break;
|
||||
case 15: oltv->wi_val = 3; break;
|
||||
default: oltv->wi_val = 0x100 + ltv->wi_val; break;
|
||||
}
|
||||
break;
|
||||
case WI_RID_ENCRYPTION:
|
||||
oltv->wi_len = 2;
|
||||
if (ltv->wi_val & 0x01)
|
||||
oltv->wi_val = 1;
|
||||
else
|
||||
oltv->wi_val = 0;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
oltv->wi_len = 2;
|
||||
oltv->wi_val = ltv->wi_val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -687,6 +778,59 @@ static int wi_write_record(sc, ltv)
|
||||
{
|
||||
u_int16_t *ptr;
|
||||
int i;
|
||||
struct wi_ltv_gen p2ltv;
|
||||
|
||||
if (sc->wi_prism2) {
|
||||
switch (ltv->wi_type) {
|
||||
case WI_RID_TX_RATE:
|
||||
p2ltv.wi_type = WI_RID_TX_RATE;
|
||||
p2ltv.wi_len = 2;
|
||||
switch (ltv->wi_val) {
|
||||
case 1: p2ltv.wi_val = 1; break;
|
||||
case 2: p2ltv.wi_val = 2; break;
|
||||
case 3: p2ltv.wi_val = 15; break;
|
||||
case 5: p2ltv.wi_val = 4; break;
|
||||
case 6: p2ltv.wi_val = 3; break;
|
||||
case 7: p2ltv.wi_val = 7; break;
|
||||
case 11: p2ltv.wi_val = 8; break;
|
||||
default: return EINVAL;
|
||||
}
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_ENCRYPTION:
|
||||
p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
|
||||
p2ltv.wi_len = 2;
|
||||
if (ltv->wi_val)
|
||||
p2ltv.wi_val = 0x03;
|
||||
else
|
||||
p2ltv.wi_val = 0x90;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
|
||||
p2ltv.wi_len = 2;
|
||||
p2ltv.wi_val = ltv->wi_val;
|
||||
ltv = &p2ltv;
|
||||
break;
|
||||
case WI_RID_DEFLT_CRYPT_KEYS:
|
||||
{
|
||||
int error;
|
||||
struct wi_ltv_str ws;
|
||||
struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv;
|
||||
for (i = 0; i < 4; i++) {
|
||||
ws.wi_len = 4;
|
||||
ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
|
||||
memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5);
|
||||
ws.wi_str[5] = '\0';
|
||||
error = wi_write_record(sc,
|
||||
(struct wi_ltv_gen *)&ws);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
|
||||
return(EIO);
|
||||
@ -1362,7 +1506,8 @@ static int wi_alloc(dev)
|
||||
|
||||
rid = 0;
|
||||
sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
0, ~0, (1 << 6),
|
||||
rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
|
||||
if (!sc->iobase) {
|
||||
device_printf(dev, "No I/O space?!\n");
|
||||
return (ENXIO);
|
||||
|
@ -66,6 +66,13 @@ struct wi_counters {
|
||||
#define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0
|
||||
#define WI_RID_TX_CRYPT_KEY 0xFCB1
|
||||
#define WI_RID_WEP_AVAIL 0xFD4F
|
||||
#define WI_RID_P2_TX_CRYPT_KEY 0xFC23
|
||||
#define WI_RID_P2_CRYPT_KEY0 0xFC24
|
||||
#define WI_RID_P2_CRYPT_KEY1 0xFC25
|
||||
#define WI_RID_P2_CRYPT_KEY2 0xFC26
|
||||
#define WI_RID_P2_CRYPT_KEY3 0xFC27
|
||||
#define WI_RID_P2_ENCRYPTION 0xFC28
|
||||
#define WI_RID_CUR_TX_RATE 0xFD44 /* current TX rate */
|
||||
struct wi_key {
|
||||
u_int16_t wi_keylen;
|
||||
u_int8_t wi_keydat[14];
|
||||
@ -118,6 +125,7 @@ struct wi_softc {
|
||||
#endif
|
||||
struct callout_handle wi_stat_ch;
|
||||
struct mtx wi_mtx;
|
||||
int wi_prism2; /* set to 1 if it uses a Prism II chip */
|
||||
};
|
||||
|
||||
#define WI_LOCK(_sc) mtx_enter(&(_sc)->wi_mtx, MTX_DEF)
|
||||
|
Loading…
x
Reference in New Issue
Block a user