diff options
author | hx147065 <none@none> | 2008-02-21 22:32:06 -0800 |
---|---|---|
committer | hx147065 <none@none> | 2008-02-21 22:32:06 -0800 |
commit | 19b23afcc35b3926d062efc1930e65c5fed1084d (patch) | |
tree | 28b61627b2307c9db8b8e5d53a7029130f91ece8 /usr/src | |
parent | bdb0fa453175b220dad117359624622021aad5b2 (diff) | |
download | illumos-gate-19b23afcc35b3926d062efc1930e65c5fed1084d.tar.gz |
6613955 pcwl show wrong channel value with command "dladm show-linkprop"
6632753 wpi need to support SUSPEND/RESUME
6637814 WiFi wpi driver tries to set power when it knows transmitter is off
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/pcwl/pcwl.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/io/wpi/wpi.c | 114 | ||||
-rw-r--r-- | usr/src/uts/common/io/wpi/wpireg.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/wpi/wpivar.h | 5 |
4 files changed, 125 insertions, 16 deletions
diff --git a/usr/src/uts/common/io/pcwl/pcwl.c b/usr/src/uts/common/io/pcwl/pcwl.c index a72862c379..6a5eed3a4e 100644 --- a/usr/src/uts/common/io/pcwl/pcwl.c +++ b/usr/src/uts/common/io/pcwl/pcwl.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -711,7 +711,7 @@ pcwl_card_insert(pcwl_maci_t *pcwl_p) break; } if (tbl_p->flags & CISTPL_CFTABLE_TPCE_FS_PWR && - tbl_p->pd.flags & CISTPL_CFTABLE_TPCE_FS_PWR_VCC) { + tbl_p->pd.flags & CISTPL_CFTABLE_TPCE_FS_PWR_VCC) { if (tbl_p->pd.pd_vcc.avgI > hi) { hi = tbl_p->pd.pd_vcc.avgI; pcwl_p->pcwl_config_hi = tbl_p->index; @@ -2456,7 +2456,7 @@ pcwl_cfg_bssid(mblk_t *mp, pcwl_maci_t *pcwl_p, uint32_t cmd) bzero(buf + WIFI_BUF_OFFSET, sizeof (wl_bssid_t)); } else if (ret == WL_PORT_TO_IBSS || - ret == WL_PORT_TO_BSS || ret == WL_PORT_OOR) { + ret == WL_PORT_TO_BSS || ret == WL_PORT_OOR) { (void) pcwl_get_ltv(pcwl_p, 6, WL_RID_BSSID, (uint16_t *)bssid); PCWL_SWAP16((uint16_t *)bssid, 6); @@ -2769,7 +2769,7 @@ done: static int pcwl_cfg_phy(mblk_t *mp, pcwl_maci_t *pcwl_p, uint32_t cmd) { - uint16_t ret, i; + uint16_t ret, retval, i; pcwl_rf_t *rf_p; wldp_t *infp; wldp_t *outfp; @@ -2790,13 +2790,13 @@ pcwl_cfg_phy(mblk_t *mp, pcwl_maci_t *pcwl_p, uint32_t cmd) outfp->wldp_length = WIFI_BUF_OFFSET + sizeof (wl_dsss_t); if (cmd == WLAN_GET_PARAM) { if (ret = pcwl_get_ltv(pcwl_p, 2, - WL_RID_CURRENT_CHNL, &ret)) { + WL_RID_CURRENT_CHNL, &retval)) { outfp->wldp_length = WIFI_BUF_OFFSET; outfp->wldp_result = WL_HW_ERROR; goto done; } - ((wl_dsss_t *)(outfp->wldp_buf))->wl_dsss_channel = ret; - PCWLDBG((CE_CONT, "pcwl_getset: channel=%d\n", ret)); + ((wl_dsss_t *)(outfp->wldp_buf))->wl_dsss_channel = retval; + PCWLDBG((CE_CONT, "pcwl_getset: channel=%d\n", retval)); ((wl_dsss_t *)(outfp->wldp_buf))->wl_dsss_subtype = WL_DSSS; outfp->wldp_result = WL_SUCCESS; } else if (cmd == WLAN_SET_PARAM) { @@ -2966,7 +2966,7 @@ pcwl_cfg_desiredrates(mblk_t *mp, pcwl_maci_t *pcwl_p, uint32_t cmd) } } PCWLDBG((CE_CONT, "pcwl: get rate=%d\n", rate)); - outfp->wldp_result = WL_SUCCESS; + outfp->wldp_result = WL_SUCCESS; } else if (cmd == WLAN_SET_PARAM) { bzero(rates, sizeof (rates)); for (i = 0; i < 4; i++) { @@ -3468,7 +3468,7 @@ pcwl_cfg_wepkey(mblk_t *mp, pcwl_maci_t *pcwl_p, uint32_t cmd) rf_p->rf_ckeys[i].ckey_dat, i)); } PCWLDBG((CE_CONT, "pcwl: rf_ckeys[%d]=%s\n", i, - (char *)(rf_p->rf_ckeys[i].ckey_dat))); + (char *)(rf_p->rf_ckeys[i].ckey_dat))); } outfp->wldp_result = WL_SUCCESS; } else { diff --git a/usr/src/uts/common/io/wpi/wpi.c b/usr/src/uts/common/io/wpi/wpi.c index c32dfcd67c..3ab12c28af 100644 --- a/usr/src/uts/common/io/wpi/wpi.c +++ b/usr/src/uts/common/io/wpi/wpi.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -71,6 +71,7 @@ #define WPI_DEBUG_TX (1 << 11) #define WPI_DEBUG_RATECTL (1 << 12) #define WPI_DEBUG_RADIO (1 << 13) +#define WPI_DEBUG_RESUME (1 << 14) uint32_t wpi_dbg_flags = 0; #define WPI_DBG(x) \ wpi_dbg x @@ -399,7 +400,23 @@ wpi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) wifi_data_t wd = { 0 }; mac_register_t *macp; - if (cmd != DDI_ATTACH) { + switch (cmd) { + case DDI_ATTACH: + break; + case DDI_RESUME: + sc = ddi_get_soft_state(wpi_soft_state_p, + ddi_get_instance(dip)); + ASSERT(sc != NULL); + mutex_enter(&sc->sc_glock); + sc->sc_flags &= ~WPI_F_SUSPEND; + mutex_exit(&sc->sc_glock); + if (sc->sc_flags & WPI_F_RUNNING) { + (void) wpi_init(sc); + ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); + } + WPI_DBG((WPI_DEBUG_RESUME, "wpi: resume \n")); + return (DDI_SUCCESS); + default: err = DDI_FAILURE; goto attach_fail1; } @@ -669,8 +686,21 @@ wpi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip)); ASSERT(sc != NULL); - if (cmd != DDI_DETACH) + switch (cmd) { + case DDI_DETACH: + break; + case DDI_SUSPEND: + if (sc->sc_flags & WPI_F_RUNNING) { + wpi_stop(sc); + } + mutex_enter(&sc->sc_glock); + sc->sc_flags |= WPI_F_SUSPEND; + mutex_exit(&sc->sc_glock); + WPI_DBG((WPI_DEBUG_RESUME, "wpi: suspend \n")); + return (DDI_SUCCESS); + default: return (DDI_FAILURE); + } if (!(sc->sc_flags & WPI_F_ATTACHED)) return (DDI_FAILURE); @@ -1777,9 +1807,19 @@ wpi_notif_softintr(caddr_t arg) LE_32(*status))); if (LE_32(*status) & 1) { - /* the radio button has to be pushed */ + /* + * the radio button has to be pushed(OFF). It + * is considered as a hw error, the + * wpi_thread() tries to recover it after the + * button is pushed again(ON) + */ cmn_err(CE_NOTE, "wpi: Radio transmitter is off\n"); + sc->sc_ostate = sc->sc_ic.ic_state; + ieee80211_new_state(&sc->sc_ic, + IEEE80211_S_INIT, -1); + sc->sc_flags |= + (WPI_F_HW_ERR_RECOVER | WPI_F_RADIO_OFF); } break; } @@ -1822,6 +1862,11 @@ wpi_intr(caddr_t arg) uint32_t r, rfh; mutex_enter(&sc->sc_glock); + if (sc->sc_flags & WPI_F_SUSPEND) { + mutex_exit(&sc->sc_glock); + return (DDI_INTR_UNCLAIMED); + } + r = WPI_READ(sc, WPI_INTR); if (r == 0 || r == 0xffffffff) { mutex_exit(&sc->sc_glock); @@ -1903,6 +1948,11 @@ wpi_m_tx(void *arg, mblk_t *mp) ieee80211com_t *ic = &sc->sc_ic; mblk_t *next; + if (sc->sc_flags & WPI_F_SUSPEND) { + freemsgchain(mp); + return (NULL); + } + if (ic->ic_state != IEEE80211_S_RUN) { freemsgchain(mp); return (NULL); @@ -1945,6 +1995,16 @@ wpi_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) bzero(cmd, sizeof (*cmd)); mutex_enter(&sc->sc_tx_lock); + if (sc->sc_flags & WPI_F_SUSPEND) { + mutex_exit(&sc->sc_tx_lock); + if ((type & IEEE80211_FC0_TYPE_MASK) != + IEEE80211_FC0_TYPE_DATA) { + freemsg(mp); + } + err = WPI_FAIL; + goto exit; + } + if (ring->queued > ring->count - 64) { WPI_DBG((WPI_DEBUG_TX, "wpi_send(): no txbuf\n")); sc->sc_need_reschedule = 1; @@ -2230,9 +2290,24 @@ wpi_m_start(void *arg) DELAY(1000000); err = wpi_init(sc); } + + if (err) { + /* + * The hw init err(eg. RF is OFF). Return Success to make + * the 'plumb' succeed. The wpi_thread() tries to re-init + * background. + */ + mutex_enter(&sc->sc_glock); + sc->sc_flags |= WPI_F_HW_ERR_RECOVER; + mutex_exit(&sc->sc_glock); + return (WPI_SUCCESS); + } ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + mutex_enter(&sc->sc_glock); + sc->sc_flags |= WPI_F_RUNNING; + mutex_exit(&sc->sc_glock); - return (err); + return (WPI_SUCCESS); } static void @@ -2247,6 +2322,9 @@ wpi_m_stop(void *arg) sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER; sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL; mutex_exit(&sc->sc_mt_lock); + mutex_enter(&sc->sc_glock); + sc->sc_flags &= ~WPI_F_RUNNING; + mutex_exit(&sc->sc_glock); } /*ARGSUSED*/ @@ -2294,9 +2372,27 @@ wpi_thread(wpi_sc_t *sc) ieee80211com_t *ic = &sc->sc_ic; clock_t clk; int times = 0, err, n = 0, timeout = 0; + uint32_t tmp; mutex_enter(&sc->sc_mt_lock); while (sc->sc_mf_thread_switch) { + tmp = WPI_READ(sc, WPI_GPIO_CTL); + if (tmp & WPI_GPIO_HW_RF_KILL) { + sc->sc_flags &= ~WPI_F_RADIO_OFF; + } else { + sc->sc_flags |= WPI_F_RADIO_OFF; + } + /* + * If in SUSPEND or the RF is OFF, do nothing + */ + if ((sc->sc_flags & WPI_F_SUSPEND) || + (sc->sc_flags & WPI_F_RADIO_OFF)) { + mutex_exit(&sc->sc_mt_lock); + delay(drv_usectohz(100000)); + mutex_enter(&sc->sc_mt_lock); + continue; + } + /* * recovery fatal error */ @@ -2320,6 +2416,8 @@ wpi_thread(wpi_sc_t *sc) continue; } n = 0; + if (!err) + sc->sc_flags |= WPI_F_RUNNING; sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER; mutex_exit(&sc->sc_mt_lock); delay(drv_usectohz(2000000)); @@ -2927,6 +3025,12 @@ wpi_init(wpi_sc_t *sc) (void) wpi_power_up(sc); wpi_hw_config(sc); + tmp = WPI_READ(sc, WPI_GPIO_CTL); + if (!(tmp & WPI_GPIO_HW_RF_KILL)) { + cmn_err(CE_WARN, "wpi_init(): Radio transmitter is off\n"); + goto fail1; + } + /* init Rx ring */ wpi_mem_lock(sc); WPI_WRITE(sc, WPI_RX_BASE, sc->sc_rxq.dma_desc.cookie.dmac_address); diff --git a/usr/src/uts/common/io/wpi/wpireg.h b/usr/src/uts/common/io/wpi/wpireg.h index a873d11e5c..0670ed2b16 100644 --- a/usr/src/uts/common/io/wpi/wpireg.h +++ b/usr/src/uts/common/io/wpi/wpireg.h @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -147,6 +147,7 @@ extern "C" { #define WPI_GPIO_SLEEP (1 << 4) #define WPI_GPIO_PWR_STATUS 0x07000000 #define WPI_GPIO_PWR_SLEEP (4 << 24) +#define WPI_GPIO_HW_RF_KILL (1 << 27) /* * possible flags for register WPI_CHICKEN @@ -180,6 +181,7 @@ extern "C" { #define WPI_ALIVE_INTR (1 << 0) #define WPI_WAKEUP_INTR (1 << 1) #define WPI_RX_SWINT (1 << 3) +#define WPI_RF_KILL (1 << 7) #define WPI_SW_ERROR (1 << 25) #define WPI_TX_INTR (1 << 27) #define WPI_HW_ERROR (1 << 29) diff --git a/usr/src/uts/common/io/wpi/wpivar.h b/usr/src/uts/common/io/wpi/wpivar.h index 967acfb386..55f8b68a1c 100644 --- a/usr/src/uts/common/io/wpi/wpivar.h +++ b/usr/src/uts/common/io/wpi/wpivar.h @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* @@ -184,6 +184,7 @@ typedef struct wpi_softc { uint32_t sc_tx_err; uint32_t sc_rx_err; uint32_t sc_tx_retries; + #ifdef WPI_BPF struct bpf_if *sc_drvbpf; @@ -209,6 +210,8 @@ typedef struct wpi_softc { #define WPI_F_HW_ERR_RECOVER (1 << 3) #define WPI_F_RATE_AUTO_CTL (1 << 4) #define WPI_F_RUNNING (1 << 5) +#define WPI_F_SUSPEND (1 << 6) +#define WPI_F_RADIO_OFF (1 << 7) #define WPI_SUCCESS 0 #define WPI_FAIL 1 |