Mercurial > illumos > illumos-gate
changeset 6062:f12fdb80179b
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
author | hx147065 |
---|---|
date | Thu, 21 Feb 2008 22:32:06 -0800 |
parents | fb86e2a70b6a |
children | 82d075ed8729 |
files | usr/src/uts/common/io/pcwl/pcwl.c usr/src/uts/common/io/wpi/wpi.c usr/src/uts/common/io/wpi/wpireg.h usr/src/uts/common/io/wpi/wpivar.h |
diffstat | 4 files changed, 126 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/pcwl/pcwl.c Thu Feb 21 22:26:00 2008 -0800 +++ b/usr/src/uts/common/io/pcwl/pcwl.c Thu Feb 21 22:32:06 2008 -0800 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } 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 @@ 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 {
--- a/usr/src/uts/common/io/wpi/wpi.c Thu Feb 21 22:26:00 2008 -0800 +++ b/usr/src/uts/common/io/wpi/wpi.c Thu Feb 21 22:32:06 2008 -0800 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); - - return (err); + mutex_enter(&sc->sc_glock); + sc->sc_flags |= WPI_F_RUNNING; + mutex_exit(&sc->sc_glock); + + return (WPI_SUCCESS); } static void @@ -2247,6 +2322,9 @@ 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 @@ 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 @@ 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 @@ (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);
--- a/usr/src/uts/common/io/wpi/wpireg.h Thu Feb 21 22:26:00 2008 -0800 +++ b/usr/src/uts/common/io/wpi/wpireg.h Thu Feb 21 22:32:06 2008 -0800 @@ -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 @@ #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 @@ #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)
--- a/usr/src/uts/common/io/wpi/wpivar.h Thu Feb 21 22:26:00 2008 -0800 +++ b/usr/src/uts/common/io/wpi/wpivar.h Thu Feb 21 22:32:06 2008 -0800 @@ -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 @@ 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 @@ #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