- The MiniportReset() function can return NDIS_STATUS_PENDING, in which
case we should wait for the resetdone handler to be called before returning. - When providing resources via ndis_query_resources(), uses the computed rsclen when using bcopy() to copy out the resource data rather than the caller-supplied buffer length. - Avoid using ndis_reset_nic() in if_ndis.c unless we really need to reset the NIC because of a problem. - Allow interrupts to be fielded during ndis_attach(), at least as far as allowing ndis_isr() and ndis_intrhand() to run. - Use ndis_80211_rates_ex when probing for supported rates. Technically, this isn't supposed to work since, although Microsoft added the extended rate structure with the NDIS 5.1 update, the spec still says that the OID_802_11_SUPPORTED_RATES OID uses ndis_80211_rates. In spite of this, it appears some drivers use it anyway. - When adding in our guessed rates, check to see if they already exist so that we avoid any duplicates. - Add a printf() to ndis_open_file() that alerts the user when a driver attempts to open a file under /compat/ndis. With these changes, I can get the driver for the SMC 2802W 54g PCI card to load and run. This board uses a Prism54G chip. Note that in order for this driver to work, you must place the supplied smc2802w.arm firmware image under /compat/ndis. (The firmware is not resident on the device.) Note that this should also allow the 3Com 3CRWE154G72 card to work as well; as far as I can tell, these cards also use a Prism54G chip.
This commit is contained in:
parent
42d122e125
commit
6a50285516
@ -316,7 +316,6 @@ ndis_stop_thread(t)
|
||||
int t;
|
||||
{
|
||||
struct ndis_req *r;
|
||||
struct timeval tv;
|
||||
struct ndisqhead *q;
|
||||
struct proc *p;
|
||||
|
||||
@ -343,9 +342,7 @@ ndis_stop_thread(t)
|
||||
|
||||
/* wait for thread exit */
|
||||
|
||||
tv.tv_sec = 60;
|
||||
tv.tv_usec = 0;
|
||||
tsleep(r, PPAUSE|PCATCH, "ndisthrexit", tvtohz(&tv));
|
||||
tsleep(r, PPAUSE|PCATCH, "ndisthrexit", hz * 60);
|
||||
|
||||
/* Now empty the job list. */
|
||||
|
||||
@ -565,6 +562,7 @@ ndis_resetdone_func(adapter, status, addressingreset)
|
||||
|
||||
if (block->nmb_ifp->if_flags & IFF_DEBUG)
|
||||
device_printf (block->nmb_dev, "reset done...\n");
|
||||
wakeup(block->nmb_ifp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1035,7 +1033,6 @@ ndis_set_info(arg, oid, buf, buflen)
|
||||
ndis_handle adapter;
|
||||
__stdcall ndis_setinfo_handler setfunc;
|
||||
uint32_t byteswritten = 0, bytesneeded = 0;
|
||||
struct timeval tv;
|
||||
int error;
|
||||
|
||||
sc = arg;
|
||||
@ -1051,10 +1048,10 @@ ndis_set_info(arg, oid, buf, buflen)
|
||||
&byteswritten, &bytesneeded);
|
||||
|
||||
if (rval == NDIS_STATUS_PENDING) {
|
||||
tv.tv_sec = 60;
|
||||
tv.tv_usec = 0;
|
||||
error = tsleep(&sc->ndis_block.nmb_wkupdpctimer,
|
||||
PPAUSE|PCATCH, "ndisset", tvtohz(&tv));
|
||||
PROC_LOCK(curthread->td_proc);
|
||||
error = msleep(&sc->ndis_block.nmb_wkupdpctimer,
|
||||
&curthread->td_proc->p_mtx, PPAUSE|PDROP,
|
||||
"ndisset", 5 * hz);
|
||||
rval = sc->ndis_block.nmb_setstat;
|
||||
}
|
||||
|
||||
@ -1211,6 +1208,7 @@ ndis_reset_nic(arg)
|
||||
__stdcall ndis_reset_handler resetfunc;
|
||||
uint8_t addressing_reset;
|
||||
struct ifnet *ifp;
|
||||
int rval;
|
||||
|
||||
sc = arg;
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
@ -1221,7 +1219,12 @@ ndis_reset_nic(arg)
|
||||
if (adapter == NULL || resetfunc == NULL)
|
||||
return(EIO);
|
||||
|
||||
resetfunc(&addressing_reset, adapter);
|
||||
rval = resetfunc(&addressing_reset, adapter);
|
||||
if (rval == NDIS_STATUS_PENDING) {
|
||||
PROC_LOCK(curthread->td_proc);
|
||||
msleep(sc, &curthread->td_proc->p_mtx,
|
||||
PPAUSE|PDROP, "ndisrst", 0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
@ -1438,7 +1441,6 @@ ndis_get_info(arg, oid, buf, buflen)
|
||||
ndis_handle adapter;
|
||||
__stdcall ndis_queryinfo_handler queryfunc;
|
||||
uint32_t byteswritten = 0, bytesneeded = 0;
|
||||
struct timeval tv;
|
||||
int error;
|
||||
|
||||
sc = arg;
|
||||
@ -1456,10 +1458,10 @@ ndis_get_info(arg, oid, buf, buflen)
|
||||
/* Wait for requests that block. */
|
||||
|
||||
if (rval == NDIS_STATUS_PENDING) {
|
||||
tv.tv_sec = 60;
|
||||
tv.tv_usec = 0;
|
||||
error = tsleep(&sc->ndis_block.nmb_wkupdpctimer,
|
||||
PPAUSE|PCATCH, "ndisget", tvtohz(&tv));
|
||||
PROC_LOCK(curthread->td_proc);
|
||||
error = msleep(&sc->ndis_block.nmb_wkupdpctimer,
|
||||
&curthread->td_proc->p_mtx, PPAUSE|PDROP,
|
||||
"ndisget", 5 * hz);
|
||||
rval = sc->ndis_block.nmb_getstat;
|
||||
}
|
||||
|
||||
@ -1503,7 +1505,7 @@ ndis_unload_driver(arg)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define NDIS_LOADED 0x42534F44
|
||||
#define NDIS_LOADED htonl(0x42534F44)
|
||||
|
||||
int
|
||||
ndis_load_driver(img, arg)
|
||||
|
@ -1459,7 +1459,7 @@ typedef ndis_status (*ndis_sendmulti_handler)(ndis_handle,
|
||||
ndis_packet **, uint32_t);
|
||||
typedef void (*ndis_isr_handler)(uint8_t *, uint8_t *, ndis_handle);
|
||||
typedef void (*ndis_interrupt_handler)(ndis_handle);
|
||||
typedef void (*ndis_reset_handler)(uint8_t *, ndis_handle);
|
||||
typedef int (*ndis_reset_handler)(uint8_t *, ndis_handle);
|
||||
typedef void (*ndis_halt_handler)(ndis_handle);
|
||||
typedef void (*ndis_return_handler)(ndis_handle, ndis_packet *);
|
||||
typedef void (*ndis_enable_interrupts_handler)(ndis_handle);
|
||||
|
@ -1037,7 +1037,7 @@ ndis_query_resources(status, adapter, list, buflen)
|
||||
return;
|
||||
}
|
||||
|
||||
bcopy((char *)block->nmb_rlist, (char *)list, *buflen);
|
||||
bcopy((char *)block->nmb_rlist, (char *)list, rsclen);
|
||||
*status = NDIS_STATUS_SUCCESS;
|
||||
return;
|
||||
}
|
||||
@ -2483,6 +2483,7 @@ ndis_open_file(status, filehandle, filelength, filename, highestaddr)
|
||||
mtx_unlock(&Giant);
|
||||
*status = NDIS_STATUS_FILE_NOT_FOUND;
|
||||
free(fh, M_TEMP);
|
||||
printf("NDIS: open file %s failed: %d\n", path, error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -425,9 +425,6 @@ ndis_attach(dev)
|
||||
if (!(sc->ndis_block.nmb_flags & NDIS_ATTRIBUTE_DESERIALIZE))
|
||||
sc->ndis_block.nmb_pktind_func = ndis_rxeof_serial;
|
||||
|
||||
/* Reset the adapter. */
|
||||
ndis_reset_nic(sc);
|
||||
|
||||
/*
|
||||
* Get station address from the driver.
|
||||
*/
|
||||
@ -496,7 +493,7 @@ ndis_attach(dev)
|
||||
if (sc->ndis_80211) {
|
||||
struct ieee80211com *ic = (void *)ifp;
|
||||
ndis_80211_config config;
|
||||
ndis_80211_rates rates;
|
||||
ndis_80211_rates_ex rates;
|
||||
struct ndis_80211_nettype_list *ntl;
|
||||
uint32_t arg;
|
||||
int r;
|
||||
@ -550,6 +547,20 @@ nonettypes:
|
||||
* if this is not 802.11b we're just going to be faking it
|
||||
* all up to heck.
|
||||
*/
|
||||
|
||||
#define TESTSETRATE(x, y) \
|
||||
do { \
|
||||
int i; \
|
||||
for (i = 0; i < ic->ic_sup_rates[x].rs_nrates; i++) { \
|
||||
if (ic->ic_sup_rates[x].rs_rates[i] == (y)) \
|
||||
break; \
|
||||
} \
|
||||
if (i == ic->ic_sup_rates[x].rs_nrates) { \
|
||||
ic->ic_sup_rates[x].rs_rates[i] = (y); \
|
||||
ic->ic_sup_rates[x].rs_nrates++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SETRATE(x, y) \
|
||||
ic->ic_sup_rates[x].rs_rates[ic->ic_sup_rates[x].rs_nrates] = (y)
|
||||
#define INCRATE(x) \
|
||||
@ -601,24 +612,16 @@ nonettypes:
|
||||
* we detect turbo modes, though?
|
||||
*/
|
||||
if (ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) {
|
||||
SETRATE(IEEE80211_MODE_11G, 47);
|
||||
INCRATE(IEEE80211_MODE_11G);
|
||||
SETRATE(IEEE80211_MODE_11G, 72);
|
||||
INCRATE(IEEE80211_MODE_11G);
|
||||
SETRATE(IEEE80211_MODE_11G, 96);
|
||||
INCRATE(IEEE80211_MODE_11G);
|
||||
SETRATE(IEEE80211_MODE_11G, 108);
|
||||
INCRATE(IEEE80211_MODE_11G);
|
||||
TESTSETRATE(IEEE80211_MODE_11G, 47);
|
||||
TESTSETRATE(IEEE80211_MODE_11G, 72);
|
||||
TESTSETRATE(IEEE80211_MODE_11G, 96);
|
||||
TESTSETRATE(IEEE80211_MODE_11G, 108);
|
||||
}
|
||||
if (ic->ic_modecaps & (1<<IEEE80211_MODE_11A)) {
|
||||
SETRATE(IEEE80211_MODE_11A, 47);
|
||||
INCRATE(IEEE80211_MODE_11A);
|
||||
SETRATE(IEEE80211_MODE_11A, 72);
|
||||
INCRATE(IEEE80211_MODE_11A);
|
||||
SETRATE(IEEE80211_MODE_11A, 96);
|
||||
INCRATE(IEEE80211_MODE_11A);
|
||||
SETRATE(IEEE80211_MODE_11A, 108);
|
||||
INCRATE(IEEE80211_MODE_11A);
|
||||
TESTSETRATE(IEEE80211_MODE_11A, 47);
|
||||
TESTSETRATE(IEEE80211_MODE_11A, 72);
|
||||
TESTSETRATE(IEEE80211_MODE_11A, 96);
|
||||
TESTSETRATE(IEEE80211_MODE_11A, 108);
|
||||
}
|
||||
#undef SETRATE
|
||||
#undef INCRATE
|
||||
@ -648,6 +651,7 @@ nonettypes:
|
||||
if (r == 0)
|
||||
ic->ic_caps |= IEEE80211_C_PMGT;
|
||||
i = sizeof(config);
|
||||
bzero((char *)&config, sizeof(config));
|
||||
config.nc_length = i;
|
||||
config.nc_fhconfig.ncf_length = sizeof(ndis_80211_config_fh);
|
||||
r = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &i);
|
||||
@ -687,12 +691,9 @@ nonettypes:
|
||||
fail:
|
||||
if (error)
|
||||
ndis_detach(dev);
|
||||
else {
|
||||
else
|
||||
/* We're done talking to the NIC for now; halt it. */
|
||||
ifp->if_flags |= IFF_UP;
|
||||
ndis_halt_nic(sc);
|
||||
ifp->if_flags &= ~IFF_UP;
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
@ -1114,8 +1115,7 @@ ndis_intr(arg)
|
||||
sc = arg;
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
if (!(ifp->if_flags & IFF_UP) ||
|
||||
sc->ndis_block.nmb_miniportadapterctx == NULL)
|
||||
if (sc->ndis_block.nmb_miniportadapterctx == NULL)
|
||||
return;
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, sc->ndis_intrmtx);
|
||||
@ -1127,7 +1127,7 @@ ndis_intr(arg)
|
||||
}
|
||||
mtx_pool_unlock(ndis_mtxpool, sc->ndis_intrmtx);
|
||||
|
||||
if ((is_our_intr || call_isr) && (ifp->if_flags & IFF_UP))
|
||||
if ((is_our_intr || call_isr))
|
||||
ndis_sched(ndis_intrtask, ifp, NDIS_SWI);
|
||||
|
||||
return;
|
||||
@ -1158,6 +1158,16 @@ ndis_ticktask(xsc)
|
||||
|
||||
sc = xsc;
|
||||
|
||||
hangfunc = sc->ndis_chars.nmc_checkhang_func;
|
||||
|
||||
if (hangfunc != NULL) {
|
||||
rval = hangfunc(sc->ndis_block.nmb_miniportadapterctx);
|
||||
if (rval == TRUE) {
|
||||
ndis_reset_nic(sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
len = sizeof(linkstate);
|
||||
error = ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
(void *)&linkstate, &len);
|
||||
@ -1180,14 +1190,6 @@ ndis_ticktask(xsc)
|
||||
|
||||
NDIS_UNLOCK(sc);
|
||||
|
||||
hangfunc = sc->ndis_chars.nmc_checkhang_func;
|
||||
|
||||
if (hangfunc != NULL) {
|
||||
rval = hangfunc(sc->ndis_block.nmb_miniportadapterctx);
|
||||
if (rval == TRUE)
|
||||
ndis_reset_nic(sc);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1378,7 +1380,6 @@ ndis_init(xsc)
|
||||
/*
|
||||
* Cancel pending I/O and free all RX/TX buffers.
|
||||
*/
|
||||
ndis_reset_nic(sc);
|
||||
ndis_stop(sc);
|
||||
if (ndis_init_nic(sc))
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user