mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-06 18:29:47 +00:00
urtwn: shutdown the device properly
- R92C path: NetBSD (mostly) - R88E path: TP-Link driver Tested with RTL8188EU and RTL8188CUS. Reviewed by: kevlo Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D5198
This commit is contained in:
parent
15b185341d
commit
6e2ab41693
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=295874
@ -308,6 +308,8 @@ static void urtwn_start(struct urtwn_softc *);
|
||||
static void urtwn_parent(struct ieee80211com *);
|
||||
static int urtwn_r92c_power_on(struct urtwn_softc *);
|
||||
static int urtwn_r88e_power_on(struct urtwn_softc *);
|
||||
static void urtwn_r92c_power_off(struct urtwn_softc *);
|
||||
static void urtwn_r88e_power_off(struct urtwn_softc *);
|
||||
static int urtwn_llt_init(struct urtwn_softc *);
|
||||
#ifndef URTWN_WITHOUT_UCODE
|
||||
static void urtwn_fw_reset(struct urtwn_softc *);
|
||||
@ -1782,6 +1784,7 @@ urtwn_read_rom(struct urtwn_softc *sc)
|
||||
|
||||
sc->sc_rf_write = urtwn_r92c_rf_write;
|
||||
sc->sc_power_on = urtwn_r92c_power_on;
|
||||
sc->sc_power_off = urtwn_r92c_power_off;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1809,6 +1812,7 @@ urtwn_r88e_read_rom(struct urtwn_softc *sc)
|
||||
|
||||
sc->sc_rf_write = urtwn_r88e_rf_write;
|
||||
sc->sc_power_on = urtwn_r88e_power_on;
|
||||
sc->sc_power_off = urtwn_r88e_power_off;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -3235,7 +3239,7 @@ urtwn_r88e_power_on(struct urtwn_softc *sc)
|
||||
|
||||
/* Enable LDO normal mode. */
|
||||
error = urtwn_write_1(sc, R92C_LPLDO_CTRL,
|
||||
urtwn_read_1(sc, R92C_LPLDO_CTRL) & ~0x10);
|
||||
urtwn_read_1(sc, R92C_LPLDO_CTRL) & ~R92C_LPLDO_CTRL_SLEEP);
|
||||
if (error != USB_ERR_NORMAL_COMPLETION)
|
||||
return (EIO);
|
||||
|
||||
@ -3254,6 +3258,269 @@ urtwn_r88e_power_on(struct urtwn_softc *sc)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
urtwn_power_off(struct urtwn_softc *sc)
|
||||
{
|
||||
|
||||
return sc->sc_power_off(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
urtwn_r92c_power_off(struct urtwn_softc *sc)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* Block all Tx queues. */
|
||||
urtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
|
||||
|
||||
/* Disable RF */
|
||||
urtwn_rf_write(sc, 0, 0, 0);
|
||||
|
||||
urtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF);
|
||||
|
||||
/* Reset BB state machine */
|
||||
urtwn_write_1(sc, R92C_SYS_FUNC_EN,
|
||||
R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA |
|
||||
R92C_SYS_FUNC_EN_BB_GLB_RST);
|
||||
urtwn_write_1(sc, R92C_SYS_FUNC_EN,
|
||||
R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA);
|
||||
|
||||
/*
|
||||
* Reset digital sequence
|
||||
*/
|
||||
#ifndef URTWN_WITHOUT_UCODE
|
||||
if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) {
|
||||
/* Reset MCU ready status */
|
||||
urtwn_write_1(sc, R92C_MCUFWDL, 0);
|
||||
|
||||
/* If firmware in ram code, do reset */
|
||||
urtwn_fw_reset(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset MAC and Enable 8051 */
|
||||
urtwn_write_1(sc, R92C_SYS_FUNC_EN + 1,
|
||||
(R92C_SYS_FUNC_EN_CPUEN |
|
||||
R92C_SYS_FUNC_EN_ELDR |
|
||||
R92C_SYS_FUNC_EN_HWPDN) >> 8);
|
||||
|
||||
/* Reset MCU ready status */
|
||||
urtwn_write_1(sc, R92C_MCUFWDL, 0);
|
||||
|
||||
/* Disable MAC clock */
|
||||
urtwn_write_2(sc, R92C_SYS_CLKR,
|
||||
R92C_SYS_CLKR_ANAD16V_EN |
|
||||
R92C_SYS_CLKR_ANA8M |
|
||||
R92C_SYS_CLKR_LOADER_EN |
|
||||
R92C_SYS_CLKR_80M_SSC_DIS |
|
||||
R92C_SYS_CLKR_SYS_EN |
|
||||
R92C_SYS_CLKR_RING_EN |
|
||||
0x4000);
|
||||
|
||||
/* Disable AFE PLL */
|
||||
urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80);
|
||||
|
||||
/* Gated AFE DIG_CLOCK */
|
||||
urtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F);
|
||||
|
||||
/* Isolated digital to PON */
|
||||
urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
|
||||
R92C_SYS_ISO_CTRL_MD2PP |
|
||||
R92C_SYS_ISO_CTRL_PA2PCIE |
|
||||
R92C_SYS_ISO_CTRL_PD2CORE |
|
||||
R92C_SYS_ISO_CTRL_IP2MAC |
|
||||
R92C_SYS_ISO_CTRL_DIOP |
|
||||
R92C_SYS_ISO_CTRL_DIOE);
|
||||
|
||||
/*
|
||||
* Pull GPIO PIN to balance level and LED control
|
||||
*/
|
||||
/* 1. Disable GPIO[7:0] */
|
||||
urtwn_write_2(sc, R92C_GPIO_IOSEL, 0x0000);
|
||||
|
||||
reg = urtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00;
|
||||
reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000;
|
||||
urtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg);
|
||||
|
||||
/* Disable GPIO[10:8] */
|
||||
urtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 0x00);
|
||||
|
||||
reg = urtwn_read_2(sc, R92C_GPIO_IO_SEL) & ~0x00f0;
|
||||
reg |= (((reg & 0x000f) << 4) | 0x0780);
|
||||
urtwn_write_2(sc, R92C_GPIO_IO_SEL, reg);
|
||||
|
||||
/* Disable LED0 & 1 */
|
||||
urtwn_write_2(sc, R92C_LEDCFG0, 0x8080);
|
||||
|
||||
/*
|
||||
* Reset digital sequence
|
||||
*/
|
||||
/* Disable ELDR clock */
|
||||
urtwn_write_2(sc, R92C_SYS_CLKR,
|
||||
R92C_SYS_CLKR_ANAD16V_EN |
|
||||
R92C_SYS_CLKR_ANA8M |
|
||||
R92C_SYS_CLKR_LOADER_EN |
|
||||
R92C_SYS_CLKR_80M_SSC_DIS |
|
||||
R92C_SYS_CLKR_SYS_EN |
|
||||
R92C_SYS_CLKR_RING_EN |
|
||||
0x4000);
|
||||
|
||||
/* Isolated ELDR to PON */
|
||||
urtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1,
|
||||
(R92C_SYS_ISO_CTRL_DIOR |
|
||||
R92C_SYS_ISO_CTRL_PWC_EV12V) >> 8);
|
||||
|
||||
/*
|
||||
* Disable analog sequence
|
||||
*/
|
||||
/* Disable A15 power */
|
||||
urtwn_write_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_OBUF);
|
||||
/* Disable digital core power */
|
||||
urtwn_write_1(sc, R92C_LDOV12D_CTRL,
|
||||
urtwn_read_1(sc, R92C_LDOV12D_CTRL) &
|
||||
~R92C_LDOV12D_CTRL_LDV12_EN);
|
||||
|
||||
/* Enter PFM mode */
|
||||
urtwn_write_1(sc, R92C_SPS0_CTRL, 0x23);
|
||||
|
||||
/* Set USB suspend */
|
||||
urtwn_write_2(sc, R92C_APS_FSMCO,
|
||||
R92C_APS_FSMCO_APDM_HOST |
|
||||
R92C_APS_FSMCO_AFSM_HSUS |
|
||||
R92C_APS_FSMCO_PFM_ALDN);
|
||||
|
||||
/* Lock ISO/CLK/Power control register. */
|
||||
urtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
|
||||
}
|
||||
|
||||
static void
|
||||
urtwn_r88e_power_off(struct urtwn_softc *sc)
|
||||
{
|
||||
uint8_t reg;
|
||||
int ntries;
|
||||
|
||||
/* Disable any kind of TX reports. */
|
||||
urtwn_write_1(sc, R88E_TX_RPT_CTRL,
|
||||
urtwn_read_1(sc, R88E_TX_RPT_CTRL) &
|
||||
~(R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA));
|
||||
|
||||
/* Stop Rx. */
|
||||
urtwn_write_1(sc, R92C_CR, 0);
|
||||
|
||||
/* Move card to Low Power State. */
|
||||
/* Block all Tx queues. */
|
||||
urtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
|
||||
|
||||
for (ntries = 0; ntries < 20; ntries++) {
|
||||
/* Should be zero if no packet is transmitting. */
|
||||
if (urtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
|
||||
break;
|
||||
|
||||
urtwn_ms_delay(sc);
|
||||
}
|
||||
if (ntries == 20) {
|
||||
device_printf(sc->sc_dev, "%s: failed to block Tx queues\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* CCK and OFDM are disabled, and clock are gated. */
|
||||
urtwn_write_1(sc, R92C_SYS_FUNC_EN,
|
||||
urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~R92C_SYS_FUNC_EN_BBRSTB);
|
||||
|
||||
urtwn_ms_delay(sc);
|
||||
|
||||
/* Reset MAC TRX */
|
||||
urtwn_write_1(sc, R92C_CR,
|
||||
R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
|
||||
R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN |
|
||||
R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN);
|
||||
|
||||
/* check if removed later */
|
||||
urtwn_write_1(sc, R92C_CR + 1,
|
||||
urtwn_read_1(sc, R92C_CR + 1) & ~(R92C_CR_ENSEC >> 8));
|
||||
|
||||
/* Respond TxOK to scheduler */
|
||||
urtwn_write_1(sc, R92C_DUAL_TSF_RST,
|
||||
urtwn_read_1(sc, R92C_DUAL_TSF_RST) | 0x20);
|
||||
|
||||
/* If firmware in ram code, do reset. */
|
||||
#ifndef URTWN_WITHOUT_UCODE
|
||||
if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY)
|
||||
urtwn_r88e_fw_reset(sc);
|
||||
#endif
|
||||
|
||||
/* Reset MCU ready status. */
|
||||
urtwn_write_1(sc, R92C_MCUFWDL, 0x00);
|
||||
|
||||
/* Disable 32k. */
|
||||
urtwn_write_1(sc, R88E_32K_CTRL,
|
||||
urtwn_read_1(sc, R88E_32K_CTRL) & ~0x01);
|
||||
|
||||
/* Move card to Disabled state. */
|
||||
/* Turn off RF. */
|
||||
urtwn_write_1(sc, R92C_RF_CTRL, 0);
|
||||
|
||||
/* LDO Sleep mode. */
|
||||
urtwn_write_1(sc, R92C_LPLDO_CTRL,
|
||||
urtwn_read_1(sc, R92C_LPLDO_CTRL) | R92C_LPLDO_CTRL_SLEEP);
|
||||
|
||||
/* Turn off MAC by HW state machine */
|
||||
urtwn_write_1(sc, R92C_APS_FSMCO + 1,
|
||||
urtwn_read_1(sc, R92C_APS_FSMCO + 1) |
|
||||
(R92C_APS_FSMCO_APFM_OFF >> 8));
|
||||
|
||||
for (ntries = 0; ntries < 20; ntries++) {
|
||||
/* Wait until it will be disabled. */
|
||||
if ((urtwn_read_1(sc, R92C_APS_FSMCO + 1) &
|
||||
(R92C_APS_FSMCO_APFM_OFF >> 8)) == 0)
|
||||
break;
|
||||
|
||||
urtwn_ms_delay(sc);
|
||||
}
|
||||
if (ntries == 20) {
|
||||
device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* schmit trigger */
|
||||
urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
|
||||
urtwn_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
|
||||
|
||||
/* Enable WL suspend. */
|
||||
urtwn_write_1(sc, R92C_APS_FSMCO + 1,
|
||||
(urtwn_read_1(sc, R92C_APS_FSMCO + 1) & ~0x10) | 0x08);
|
||||
|
||||
/* Enable bandgap mbias in suspend. */
|
||||
urtwn_write_1(sc, R92C_APS_FSMCO + 3, 0);
|
||||
|
||||
/* Clear SIC_EN register. */
|
||||
urtwn_write_1(sc, R92C_GPIO_MUXCFG + 1,
|
||||
urtwn_read_1(sc, R92C_GPIO_MUXCFG + 1) & ~0x10);
|
||||
|
||||
/* Set USB suspend enable local register */
|
||||
urtwn_write_1(sc, R92C_USB_SUSPEND,
|
||||
urtwn_read_1(sc, R92C_USB_SUSPEND) | 0x10);
|
||||
|
||||
/* Reset MCU IO Wrapper. */
|
||||
reg = urtwn_read_1(sc, R92C_RSV_CTRL + 1);
|
||||
urtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08);
|
||||
urtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08);
|
||||
|
||||
/* marked as 'For Power Consumption' code. */
|
||||
urtwn_write_1(sc, R92C_GPIO_OUT, urtwn_read_1(sc, R92C_GPIO_IN));
|
||||
urtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff);
|
||||
|
||||
urtwn_write_1(sc, R92C_GPIO_IO_SEL,
|
||||
urtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4);
|
||||
urtwn_write_1(sc, R92C_GPIO_MOD,
|
||||
urtwn_read_1(sc, R92C_GPIO_MOD) | 0x0f);
|
||||
|
||||
/* Set LNA, TRSW, EX_PA Pin to output mode. */
|
||||
urtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808);
|
||||
}
|
||||
|
||||
static int
|
||||
urtwn_llt_init(struct urtwn_softc *sc)
|
||||
{
|
||||
@ -4910,9 +5177,10 @@ urtwn_stop(struct urtwn_softc *sc)
|
||||
URTWN_TEMP_MEASURED);
|
||||
sc->thcal_lctemp = 0;
|
||||
callout_stop(&sc->sc_watchdog_ch);
|
||||
urtwn_abort_xfers(sc);
|
||||
|
||||
urtwn_abort_xfers(sc);
|
||||
urtwn_drain_mbufq(sc);
|
||||
urtwn_power_off(sc);
|
||||
URTWN_UNLOCK(sc);
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,10 @@
|
||||
#define R92C_GPIO_IO_SEL 0x042
|
||||
#define R92C_MAC_PINMUX_CFG 0x043
|
||||
#define R92C_GPIO_PIN_CTRL 0x044
|
||||
#define R92C_GPIO_IN 0x044
|
||||
#define R92C_GPIO_OUT 0x045
|
||||
#define R92C_GPIO_IOSEL 0x046
|
||||
#define R92C_GPIO_MOD 0x047
|
||||
#define R92C_GPIO_INTM 0x048
|
||||
#define R92C_LEDCFG0 0x04c
|
||||
#define R92C_LEDCFG1 0x04d
|
||||
@ -79,6 +83,7 @@
|
||||
#define R92C_FSISR 0x054
|
||||
#define R92C_HSIMR 0x058
|
||||
#define R92C_HSISR 0x05c
|
||||
#define R88E_BB_PAD_CTRL 0x064
|
||||
#define R92C_MCUFWDL 0x080
|
||||
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
|
||||
#define R88E_HIMR 0x0b0
|
||||
@ -117,6 +122,7 @@
|
||||
#define R92C_MBIST_START 0x174
|
||||
#define R92C_MBIST_DONE 0x178
|
||||
#define R92C_MBIST_FAIL 0x17c
|
||||
#define R88E_32K_CTRL 0x194
|
||||
#define R92C_C2HEVT_MSG_NORMAL 0x1a0
|
||||
#define R92C_C2HEVT_MSG_TEST 0x1b8
|
||||
#define R92C_C2HEVT_CLEAR 0x1bf
|
||||
@ -204,6 +210,7 @@
|
||||
#define R92C_BE_ADMTIME 0x5c8
|
||||
#define R92C_EDCA_RANDOM_GEN 0x5cc
|
||||
#define R92C_SCH_TXCMD 0x5d0
|
||||
#define R88E_SCH_TXCMD 0x5f8
|
||||
/* WMAC Configuration. */
|
||||
#define R92C_APSD_CTRL 0x600
|
||||
#define R92C_BWOPMODE 0x603
|
||||
@ -303,13 +310,30 @@
|
||||
#define R92C_RF_CTRL_RSTB 0x02
|
||||
#define R92C_RF_CTRL_SDMRSTB 0x04
|
||||
|
||||
/* Bits for R92C_LDOA15_CTRL. */
|
||||
#define R92C_LDOA15_CTRL_EN 0x01
|
||||
#define R92C_LDOA15_CTRL_STBY 0x02
|
||||
#define R92C_LDOA15_CTRL_OBUF 0x04
|
||||
#define R92C_LDOA15_CTRL_REG_VOS 0x08
|
||||
|
||||
/* Bits for R92C_LDOV12D_CTRL. */
|
||||
#define R92C_LDOV12D_CTRL_LDV12_EN 0x01
|
||||
|
||||
/* Bits for R92C_LPLDO_CTRL. */
|
||||
#define R92C_LPLDO_CTRL_SLEEP 0x10
|
||||
|
||||
/* Bits for R92C_AFE_XTAL_CTRL. */
|
||||
#define R92C_AFE_XTAL_CTRL_ADDR_M 0x007ff800
|
||||
#define R92C_AFE_XTAL_CTRL_ADDR_S 11
|
||||
|
||||
/* Bits for R92C_AFE_PLL_CTRL. */
|
||||
#define R92C_AFE_PLL_CTRL_EN 0x0001
|
||||
#define R92C_AFE_PLL_CTRL_320_EN 0x0002
|
||||
#define R92C_AFE_PLL_CTRL_FREF_SEL 0x0004
|
||||
#define R92C_AFE_PLL_CTRL_EDGE_SEL 0x0008
|
||||
#define R92C_AFE_PLL_CTRL_WDOGB 0x0010
|
||||
#define R92C_AFE_PLL_CTRL_LPFEN 0x0020
|
||||
|
||||
/* Bits for R92C_EFUSE_CTRL. */
|
||||
#define R92C_EFUSE_CTRL_DATA_M 0x000000ff
|
||||
#define R92C_EFUSE_CTRL_DATA_S 0
|
||||
@ -748,6 +772,7 @@
|
||||
/*
|
||||
* USB registers.
|
||||
*/
|
||||
#define R92C_USB_SUSPEND 0xfe10
|
||||
#define R92C_USB_INFO 0xfe17
|
||||
#define R92C_USB_SPECIAL_OPTION 0xfe55
|
||||
#define R92C_USB_HCPWM 0xfe57
|
||||
|
@ -172,6 +172,7 @@ struct urtwn_softc {
|
||||
void (*sc_rf_write)(struct urtwn_softc *,
|
||||
int, uint8_t, uint32_t);
|
||||
int (*sc_power_on)(struct urtwn_softc *);
|
||||
void (*sc_power_off)(struct urtwn_softc *);
|
||||
|
||||
struct ieee80211_node *node_list[R88E_MACID_MAX + 1];
|
||||
struct mtx nt_mtx;
|
||||
|
Loading…
x
Reference in New Issue
Block a user