Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146995581
D5198.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D5198.diff
View Options
Index: head/sys/dev/usb/wlan/if_urtwn.c
===================================================================
--- head/sys/dev/usb/wlan/if_urtwn.c
+++ head/sys/dev/usb/wlan/if_urtwn.c
@@ -308,6 +308,8 @@
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 @@
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 @@
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 @@
/* 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 @@
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_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);
}
Index: head/sys/dev/usb/wlan/if_urtwnreg.h
===================================================================
--- head/sys/dev/usb/wlan/if_urtwnreg.h
+++ head/sys/dev/usb/wlan/if_urtwnreg.h
@@ -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
Index: head/sys/dev/usb/wlan/if_urtwnvar.h
===================================================================
--- head/sys/dev/usb/wlan/if_urtwnvar.h
+++ head/sys/dev/usb/wlan/if_urtwnvar.h
@@ -172,6 +172,7 @@
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;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 8, 10:34 AM (5 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29403248
Default Alt Text
D5198.diff (11 KB)
Attached To
Mode
D5198: urtwn: shutdown the device properly
Attached
Detach File
Event Timeline
Log In to Comment