The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ath/ath_hal/ar5212/ar5212_power.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2002-2008 Atheros Communications, Inc.
    6  *
    7  * Permission to use, copy, modify, and/or distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  *
   19  * $FreeBSD$
   20  */
   21 #include "opt_ah.h"
   22 
   23 #include "ah.h"
   24 #include "ah_internal.h"
   25 
   26 #include "ar5212/ar5212.h"
   27 #include "ar5212/ar5212reg.h"
   28 #include "ar5212/ar5212desc.h"
   29 
   30 /*
   31  * Notify Power Mgt is enabled in self-generated frames.
   32  * If requested, force chip awake.
   33  *
   34  * Returns A_OK if chip is awake or successfully forced awake.
   35  *
   36  * WARNING WARNING WARNING
   37  * There is a problem with the chip where sometimes it will not wake up.
   38  */
   39 static HAL_BOOL
   40 ar5212SetPowerModeAwake(struct ath_hal *ah, int setChip)
   41 {
   42 #define AR_SCR_MASK \
   43     (AR_SCR_SLDUR|AR_SCR_SLE|AR_SCR_SLDTP|AR_SCR_SLDWP|\
   44      AR_SCR_SLEPOL|AR_SCR_MIBIE|AR_SCR_UNKNOWN)
   45 #define POWER_UP_TIME   2000
   46         uint32_t scr, val;
   47         int i;
   48 
   49         if (setChip) {
   50                 /*
   51                  * Be careful setting the AWAKE mode.  When we are called
   52                  * with the chip powered down the read returns 0xffffffff
   53                  * which when blindly written back with OS_REG_RMW_FIELD 
   54                  * enables the MIB interrupt for the sleep performance
   55                  * counters.  This can result in an interrupt storm when
   56                  * ANI is in operation as no one knows to turn off the MIB
   57                  * interrupt cause.
   58                  */
   59                 scr = OS_REG_READ(ah, AR_SCR);
   60                 if (scr & ~AR_SCR_MASK) {
   61                         HALDEBUG(ah, HAL_DEBUG_ANY,
   62                             "%s: bogus SCR 0x%x, PCICFG 0x%x\n",
   63                             __func__, scr, OS_REG_READ(ah, AR_PCICFG));
   64                         scr = 0;
   65                 }
   66                 scr = (scr &~ AR_SCR_SLE) | AR_SCR_SLE_WAKE;
   67                 OS_REG_WRITE(ah, AR_SCR, scr);
   68                 OS_DELAY(10);   /* Give chip the chance to awake */
   69 
   70                 for (i = POWER_UP_TIME / 50; i != 0; i--) {
   71                         val = OS_REG_READ(ah, AR_PCICFG);
   72                         if ((val & AR_PCICFG_SPWR_DN) == 0)
   73                                 break;
   74                         OS_DELAY(50);
   75                         OS_REG_WRITE(ah, AR_SCR, scr);
   76                 }
   77                 if (i == 0) {
   78 #ifdef AH_DEBUG
   79                         ath_hal_printf(ah, "%s: Failed to wakeup in %ums\n",
   80                                 __func__, POWER_UP_TIME/50);
   81 #endif
   82                         return AH_FALSE;
   83                 }
   84         } 
   85 
   86         OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
   87         return AH_TRUE;
   88 #undef POWER_UP_TIME
   89 #undef AR_SCR_MASK
   90 }
   91 
   92 /*
   93  * Notify Power Mgt is disabled in self-generated frames.
   94  * If requested, force chip to sleep.
   95  */
   96 static void
   97 ar5212SetPowerModeSleep(struct ath_hal *ah, int setChip)
   98 {
   99         OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
  100         if (setChip)
  101                 OS_REG_RMW_FIELD(ah, AR_SCR, AR_SCR_SLE, AR_SCR_SLE_SLP);
  102 }
  103 
  104 /*
  105  * Notify Power Management is enabled in self-generating
  106  * fames.  If request, set power mode of chip to
  107  * auto/normal.  Duration in units of 128us (1/8 TU).
  108  */
  109 static void
  110 ar5212SetPowerModeNetworkSleep(struct ath_hal *ah, int setChip)
  111 {
  112         OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
  113         if (setChip)
  114                 OS_REG_RMW_FIELD(ah, AR_SCR, AR_SCR_SLE, AR_SCR_SLE_NORM);
  115 }
  116 
  117 /*
  118  * Set power mgt to the requested mode, and conditionally set
  119  * the chip as well
  120  */
  121 HAL_BOOL
  122 ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
  123 {
  124 #ifdef AH_DEBUG
  125         static const char* modes[] = {
  126                 "AWAKE",
  127                 "FULL-SLEEP",
  128                 "NETWORK SLEEP",
  129                 "UNDEFINED"
  130         };
  131 #endif
  132         int status = AH_TRUE;
  133 
  134         HALDEBUG(ah, HAL_DEBUG_POWER, "%s: %s -> %s (%s)\n", __func__,
  135                 modes[ah->ah_powerMode], modes[mode],
  136                 setChip ? "set chip " : "");
  137         switch (mode) {
  138         case HAL_PM_AWAKE:
  139                 if (setChip)
  140                         ah->ah_powerMode = mode;
  141                 status = ar5212SetPowerModeAwake(ah, setChip);
  142                 break;
  143         case HAL_PM_FULL_SLEEP:
  144                 ar5212SetPowerModeSleep(ah, setChip);
  145                 if (setChip)
  146                         ah->ah_powerMode = mode;
  147                 break;
  148         case HAL_PM_NETWORK_SLEEP:
  149                 ar5212SetPowerModeNetworkSleep(ah, setChip);
  150                 if (setChip)
  151                         ah->ah_powerMode = mode;
  152                 break;
  153         default:
  154                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n",
  155                     __func__, mode);
  156                 return AH_FALSE;
  157         }
  158         return status;
  159 }
  160 
  161 /*
  162  * Return the current sleep mode of the chip
  163  */
  164 HAL_POWER_MODE
  165 ar5212GetPowerMode(struct ath_hal *ah)
  166 {
  167         /* Just so happens the h/w maps directly to the abstracted value */
  168         return MS(OS_REG_READ(ah, AR_SCR), AR_SCR_SLE);
  169 }
  170 
  171 #if 0
  172 /*
  173  * Return the current sleep state of the chip
  174  * TRUE = sleeping
  175  */
  176 HAL_BOOL
  177 ar5212GetPowerStatus(struct ath_hal *ah)
  178 {
  179         return (OS_REG_READ(ah, AR_PCICFG) & AR_PCICFG_SPWR_DN) != 0;
  180 }
  181 #endif

Cache object: f9bd2c7f0a2f0f6e678998c2604995b0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.