Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/dev/usb Introduce sleep states and power control.



details:   https://anonhg.NetBSD.org/src-all/rev/8e5f690c1305
branches:  trunk
changeset: 377103:8e5f690c1305
user:      Nathanial Sloss <nat%netbsd.org@localhost>
date:      Fri Aug 05 23:29:29 2022 +1000

description:
Introduce sleep states and power control.

diffstat:

 sys/dev/usb/if_urtwn.c |  55 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 52 insertions(+), 3 deletions(-)

diffs (115 lines):

diff -r 4eef587df97e -r 8e5f690c1305 sys/dev/usb/if_urtwn.c
--- a/sys/dev/usb/if_urtwn.c    Sat Jul 23 23:24:13 2022 +1000
+++ b/sys/dev/usb/if_urtwn.c    Fri Aug 05 23:29:29 2022 +1000
@@ -348,6 +348,7 @@ static void urtwn_scan_end(struct ieee80
 static void    urtwn_set_channel(struct ieee80211com *);
 static void    urtwn_update_mcast(struct ieee80211com *);
 
+static void    power_control(struct urtwn_softc *, bool);
 /* Aliases. */
 #define        urtwn_bb_write  urtwn_write_4
 #define        urtwn_bb_read   urtwn_read_4
@@ -511,6 +512,7 @@ urtwn_attach( device_t parent, device_t 
            IEEE80211_C_SHPREAMBLE |    /* Short preamble supported. */
            IEEE80211_C_SHSLOT |        /* Short slot time supported. */
            IEEE80211_C_BGSCAN |        /* capable of bg scanning */
+           IEEE80211_C_SWSLEEP|        /* handle sleeps */
            IEEE80211_C_WME |           /* 802.11e */
            IEEE80211_C_WPA;            /* 802.11i */
 
@@ -1653,6 +1655,39 @@ urtwn_calib_to_cb(struct urtwn_softc *sc
 }
 
 static void
+power_control(struct urtwn_softc *sc, bool lowpower)
+{
+
+       if (!ISSET(sc->chip, URTWN_CHIP_92C)) {
+               struct r92e_fw_cmd_setpwrmode cmd;
+               memset(&cmd, 0, sizeof cmd);
+               if (lowpower) {
+                       cmd.mode = FWMODE_LOW_POWER;
+                       cmd.smartps = SRTPS_LOW_POWER;
+                       cmd.pwr_state = PS_RFON;
+               } else {
+                       cmd.mode = FWMODE_ACTIVE;
+                       cmd.smartps = SRTPS_LOW_POWER;
+               }
+               cmd.awake_int = 1;
+               urtwn_fw_cmd(sc, R92E_CMD_SET_PWRMODE, &cmd, sizeof(cmd));
+       } else {
+               struct r92c_fw_cmd_setpwrmode cmd;
+               memset(&cmd, 0, sizeof cmd);
+               if (lowpower) {
+                       cmd.mode = FWMODE_LOW_POWER;
+                       cmd.smartps = SRTPS_LOW_POWER;
+               } else {
+                       cmd.mode = FWMODE_ACTIVE;
+                       cmd.smartps = SRTPS_LOW_POWER;
+               }
+               cmd.bcn_time = 0;
+               urtwn_fw_cmd(sc, R92C_CMD_SET_PWRMODE, &cmd, sizeof(cmd));
+       }
+       urtwn_delay_ms(sc, 200);
+}
+
+static void
 urtwn_newassoc(struct ieee80211_node *ni, int isnew)
 {
        URTWNHIST_FUNC();
@@ -1714,7 +1749,7 @@ urtwn_newstate(struct ieee80211vap *vap,
                break;
 
        case IEEE80211_S_RUN:
-               if (nstate == IEEE80211_S_RUN)
+               if (nstate == IEEE80211_S_RUN || nstate == IEEE80211_S_SLEEP)
                        break;
                /* Turn link LED off. */
                urtwn_set_led(sc, URTWN_LED_LINK, 0);
@@ -1755,9 +1790,13 @@ urtwn_newstate(struct ieee80211vap *vap,
                /* flush all cam entries */
                urtwn_cam_init(sc);
                break;
+       case IEEE80211_S_SLEEP:
+               if (nstate == IEEE80211_S_SLEEP)
+                       break;
+               power_control(sc, false);
+               break;
        case IEEE80211_S_CAC:
        case IEEE80211_S_CSA:
-       case IEEE80211_S_SLEEP:
                printf ("URTWN UNKNOWN oSTATE: %d\n", ostate);
                /* NNN what do we do in these states? XXX */
                break;
@@ -1852,6 +1891,9 @@ urtwn_newstate(struct ieee80211vap *vap,
        case IEEE80211_S_RUN:
                if (ostate == IEEE80211_S_RUN)
                        break;
+               if (ostate == IEEE80211_S_SLEEP)
+                       goto restart_calib;
+
                ni = vap->iv_bss;
 
 #if 0
@@ -1972,13 +2014,20 @@ urtwn_newstate(struct ieee80211vap *vap,
                sc->thcal_state = 0;
                sc->thcal_lctemp = 0;
 
+restart_calib:
+               /* Start periodic calibration. */
+               if (!usbwifi_isdying(&sc->sc_uw))
+                       callout_schedule(&sc->sc_calib_to, hz);
+               break;
+       case IEEE80211_S_SLEEP:
+               if (ostate != IEEE80211_S_SLEEP)
+                       power_control(sc, false);
                /* Start periodic calibration. */
                if (!usbwifi_isdying(&sc->sc_uw))
                        callout_schedule(&sc->sc_calib_to, hz);
                break;
        case IEEE80211_S_CAC:
        case IEEE80211_S_CSA:
-       case IEEE80211_S_SLEEP:
                /* NNN what do we do in these states? XXX */
                printf ("URTWN UNKNOWN nSTATE: %d\n", nstate);
                break;



Home | Main Index | Thread Index | Old Index