Unify all the wifi *_ioctl routines
- Limit grabbing the lock to SIOCSIFFLAGS. - Move ieee80211_start_all() to SIOCSIFFLAGS. - Remove SIOCSIFMEDIA as it is not useful. - Limit ether_ioctl to only SIOCGIFADDR. SIOCSIFADDR and SIOCSIFMTU have no affect as there is no input/output path in the vap parent. The vap code will handle the reinit of the mac address changes. - Split off ndis_ioctl_80211 as it was getting too different to wired devices. This fixes a copyout while locked and a lock recursion. Reviewed by: sam
This commit is contained in:
parent
a239061a54
commit
31a8c1edd8
@ -6277,9 +6277,9 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int error = 0;
|
||||
|
||||
ATH_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
ATH_LOCK(sc);
|
||||
if (IS_RUNNING(ifp)) {
|
||||
/*
|
||||
* To avoid rescanning another access point,
|
||||
@ -6301,6 +6301,7 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
ath_init(sc); /* XXX lose error */
|
||||
} else
|
||||
ath_stop_locked(ifp);
|
||||
ATH_UNLOCK(sc);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
@ -6315,27 +6316,20 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
&sc->sc_stats.ast_rx_noise);
|
||||
#endif
|
||||
sc->sc_stats.ast_tx_rate = sc->sc_hwmap[sc->sc_txrate].ieeerate;
|
||||
ATH_UNLOCK(sc);
|
||||
/*
|
||||
* NB: Drop the softc lock in case of a page fault;
|
||||
* we'll accept any potential inconsisentcy in the
|
||||
* statistics. The alternative is to copy the data
|
||||
* to a local structure.
|
||||
*/
|
||||
return copyout(&sc->sc_stats,
|
||||
ifr->ifr_data, sizeof (sc->sc_stats));
|
||||
ifr->ifr_data, sizeof (sc->sc_stats));
|
||||
#ifdef ATH_DIAGAPI
|
||||
case SIOCGATHDIAG:
|
||||
ATH_UNLOCK(sc);
|
||||
error = ath_ioctl_diag(sc, (struct ath_diag *) ifr);
|
||||
ATH_LOCK(sc);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ATH_UNLOCK(sc);
|
||||
return error;
|
||||
#undef IS_RUNNING
|
||||
}
|
||||
|
@ -147,6 +147,7 @@ static void ndis_starttask (device_object *, void *);
|
||||
static void ndis_resettask (device_object *, void *);
|
||||
static void ndis_inputtask (device_object *, void *);
|
||||
static int ndis_ioctl (struct ifnet *, u_long, caddr_t);
|
||||
static int ndis_ioctl_80211 (struct ifnet *, u_long, caddr_t);
|
||||
static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state,
|
||||
int);
|
||||
static int ndis_nettype_chan (uint32_t);
|
||||
@ -714,6 +715,7 @@ ndis_attach(dev)
|
||||
device_get_nameunit(dev));
|
||||
TASK_INIT(&sc->ndis_scantask, 0, ndis_scan, sc);
|
||||
|
||||
ifp->if_ioctl = ndis_ioctl_80211;
|
||||
ic->ic_ifp = ifp;
|
||||
ic->ic_opmode = IEEE80211_M_STA;
|
||||
ic->ic_phytype = IEEE80211_T_DS;
|
||||
@ -2705,11 +2707,7 @@ ndis_ioctl(ifp, command, data)
|
||||
caddr_t data;
|
||||
{
|
||||
struct ndis_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
struct ndis_oid_data oid;
|
||||
struct ndis_evt evt;
|
||||
void *oidbuf;
|
||||
int i, error = 0;
|
||||
|
||||
/*NDIS_LOCK(sc);*/
|
||||
@ -2751,10 +2749,7 @@ ndis_ioctl(ifp, command, data)
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
if (sc->ndis_80211)
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
|
||||
else
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
|
||||
break;
|
||||
case SIOCSIFCAP:
|
||||
ifp->if_capenable = ifr->ifr_reqcap;
|
||||
@ -2764,6 +2759,46 @@ ndis_ioctl(ifp, command, data)
|
||||
ifp->if_hwassist = 0;
|
||||
ndis_set_offload(sc);
|
||||
break;
|
||||
default:
|
||||
error = ether_ioctl(ifp, command, data);
|
||||
break;
|
||||
}
|
||||
|
||||
/*NDIS_UNLOCK(sc);*/
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
static int
|
||||
ndis_ioctl_80211(ifp, command, data)
|
||||
struct ifnet *ifp;
|
||||
u_long command;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ndis_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
struct ndis_oid_data oid;
|
||||
struct ndis_evt evt;
|
||||
void *oidbuf;
|
||||
int error = 0;
|
||||
|
||||
switch(command) {
|
||||
case SIOCSIFFLAGS:
|
||||
/*NDIS_LOCK(sc);*/
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
ndis_init(sc);
|
||||
ieee80211_start_all(ic);
|
||||
}
|
||||
} else {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
ndis_stop(sc);
|
||||
}
|
||||
sc->ndis_if_flags = ifp->if_flags;
|
||||
error = 0;
|
||||
/*NDIS_UNLOCK(sc);*/
|
||||
break;
|
||||
case SIOCGDRVSPEC:
|
||||
if ((error = priv_check(curthread, PRIV_DRIVER)))
|
||||
break;
|
||||
@ -2863,13 +2898,16 @@ ndis_ioctl(ifp, command, data)
|
||||
NDIS_EVTINC(sc->ndis_evtcidx);
|
||||
NDIS_UNLOCK(sc);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
|
||||
break;
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, command, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*NDIS_UNLOCK(sc);*/
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
|
@ -1847,9 +1847,9 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
int error = 0, startall = 0;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
IPW_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
ipw_init_locked(sc);
|
||||
@ -1859,18 +1859,20 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
ipw_stop_locked(sc);
|
||||
}
|
||||
IPW_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
IPW_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2052,9 +2052,9 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
int error = 0, startall = 0;
|
||||
IWI_LOCK_DECL;
|
||||
|
||||
IWI_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
IWI_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
iwi_init_locked(sc);
|
||||
@ -2064,19 +2064,20 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
iwi_stop_locked(sc);
|
||||
}
|
||||
IWI_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
IWI_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2365,9 +2365,9 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
IWN_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
IWN_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
iwn_init_locked(sc);
|
||||
@ -2377,19 +2377,20 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
iwn_stop_locked(sc);
|
||||
}
|
||||
IWN_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
IWN_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2005,9 +2005,9 @@ rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
RAL_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
RAL_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
rt2560_init_locked(sc);
|
||||
@ -2018,19 +2018,20 @@ rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
rt2560_stop_locked(sc);
|
||||
}
|
||||
RAL_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
RAL_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1747,9 +1747,9 @@ rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
RAL_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
RAL_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
rt2661_init_locked(sc);
|
||||
@ -1760,19 +1760,20 @@ rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
rt2661_stop_locked(sc);
|
||||
}
|
||||
RAL_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
RAL_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1427,9 +1427,9 @@ rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
RUM_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
RUM_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
rum_init(sc);
|
||||
@ -1440,18 +1440,20 @@ rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
rum_stop(sc);
|
||||
}
|
||||
RUM_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
RUM_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2448,9 +2448,9 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
ZYD_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
ZYD_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
if ((ifp->if_flags ^ sc->sc_if_flags) &
|
||||
@ -2465,19 +2465,20 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
zyd_stop(sc, 1);
|
||||
}
|
||||
sc->sc_if_flags = ifp->if_flags;
|
||||
ZYD_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ZYD_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1181,9 +1181,9 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
WI_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
WI_LOCK(sc);
|
||||
/*
|
||||
* Can't do promisc and hostap at the same time. If all that's
|
||||
* changing is the promisc flag, try to short-circuit a call to
|
||||
@ -1209,19 +1209,20 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
sc->wi_gone = 0;
|
||||
}
|
||||
sc->sc_if_flags = ifp->if_flags;
|
||||
WI_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
WI_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -2083,9 +2083,9 @@ wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
|
||||
WPI_LOCK(sc);
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
WPI_LOCK(sc);
|
||||
if ((ifp->if_flags & IFF_UP)) {
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
wpi_init_locked(sc, 0);
|
||||
@ -2094,19 +2094,20 @@ wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) ||
|
||||
(sc->flags & WPI_FLAG_HW_RADIO_OFF))
|
||||
wpi_stop_locked(sc);
|
||||
WPI_UNLOCK(sc);
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
default:
|
||||
case SIOCGIFADDR:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
WPI_UNLOCK(sc);
|
||||
|
||||
if (startall)
|
||||
ieee80211_start_all(ic);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user