ar9300_power.c revision 250003
1/* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include "opt_ah.h" 18 19#ifdef AH_SUPPORT_AR9300 20 21#include "ah.h" 22#include "ah_internal.h" 23 24#include "ar9300/ar9300.h" 25#include "ar9300/ar9300reg.h" 26 27#if ATH_WOW_OFFLOAD 28void ar9300_wowoffload_prep(struct ath_hal *ah) 29{ 30 struct ath_hal_9300 *ahp = AH9300(ah); 31 32 ahp->ah_mcast_filter_l32_set = 0; 33 ahp->ah_mcast_filter_u32_set = 0; 34} 35 36void ar9300_wowoffload_post(struct ath_hal *ah) 37{ 38 struct ath_hal_9300 *ahp = AH9300(ah); 39 u_int32_t val; 40 41 if (ahp->ah_mcast_filter_l32_set != 0) { 42 val = OS_REG_READ(ah, AR_MCAST_FIL0); 43 val &= ~ahp->ah_mcast_filter_l32_set; 44 OS_REG_WRITE(ah, AR_MCAST_FIL0, val); 45 } 46 if (ahp->ah_mcast_filter_u32_set != 0) { 47 val = OS_REG_READ(ah, AR_MCAST_FIL1); 48 val &= ~ahp->ah_mcast_filter_u32_set; 49 OS_REG_WRITE(ah, AR_MCAST_FIL1, val); 50 } 51 52 ahp->ah_mcast_filter_l32_set = 0; 53 ahp->ah_mcast_filter_u32_set = 0; 54} 55 56static void ar9300_wowoffload_add_mcast_filter(struct ath_hal *ah, u_int8_t *mc_addr) 57{ 58 struct ath_hal_9300 *ahp = AH9300(ah); 59 u_int32_t reg, val; 60 u_int8_t pos, high32; 61 62 memcpy((u_int8_t *) &val, &mc_addr[0], 3); 63 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 64 memcpy((u_int8_t *) &val, &mc_addr[3], 3); 65 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 66 high32 = pos & 0x20; 67 reg = high32 ? AR_MCAST_FIL1 : AR_MCAST_FIL0; 68 pos &= 0x1F; 69 70 val = OS_REG_READ(ah, reg); 71 if ((val & (1 << pos)) == 0) { 72 val |= (1 << pos); 73 if (high32) { 74 ahp->ah_mcast_filter_u32_set |= (1 << pos); 75 } else { 76 ahp->ah_mcast_filter_l32_set |= (1 << pos); 77 } 78 OS_REG_WRITE(ah, reg, val); 79 } 80} 81 82/* 83 * DeviceID SWAR - EV91928 84 * 85 * During SW WOW, 0x4004[13] is set to allow BT eCPU to access WLAN MAC 86 * registers. Setting 00x4004[13] will prevent eeprom state machine to 87 * load customizable PCIE configuration registers, which lead to the PCIE 88 * device id stay as default 0xABCD. The SWAR to have BT eCPU to write 89 * to PCIE registers as soon as it detects PCIE reset is deasserted. 90 */ 91void ar9300_wowoffload_download_devid_swar(struct ath_hal *ah) 92{ 93 u_int32_t addr = AR_WOW_OFFLOAD_WLAN_REGSET_NUM; 94 95 OS_REG_WRITE(ah, addr, 8); 96 addr += 4; 97 OS_REG_WRITE(ah, addr, 0x5000); 98 addr += 4; 99 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) pcie_000 = %08x\n", 100 AH_PRIVATE(ah)->ah_config.ath_hal_pcie_000); 101 OS_REG_WRITE(ah, addr, AH_PRIVATE(ah)->ah_config.ath_hal_pcie_000); 102 addr += 4; 103 OS_REG_WRITE(ah, addr, 0x5008); 104 addr += 4; 105 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) pcie_008 = %08x\n", 106 AH_PRIVATE(ah)->ah_config.ath_hal_pcie_008); 107 OS_REG_WRITE(ah, addr, AH_PRIVATE(ah)->ah_config.ath_hal_pcie_008); 108 addr += 4; 109 OS_REG_WRITE(ah, addr, 0x502c); 110 addr += 4; 111 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) pcie_02c = %08x\n", 112 AH_PRIVATE(ah)->ah_config.ath_hal_pcie_02c); 113 OS_REG_WRITE(ah, addr, AH_PRIVATE(ah)->ah_config.ath_hal_pcie_02c); 114 addr += 4; 115 OS_REG_WRITE(ah, addr, 0x18c00); 116 addr += 4; 117 OS_REG_WRITE(ah, addr, 0x18212ede); 118 addr += 4; 119 OS_REG_WRITE(ah, addr, 0x18c04); 120 addr += 4; 121 OS_REG_WRITE(ah, addr, 0x008001d8); 122 addr += 4; 123 OS_REG_WRITE(ah, addr, 0x18c08); 124 addr += 4; 125 OS_REG_WRITE(ah, addr, 0x0003580c); 126 addr += 4; 127 OS_REG_WRITE(ah, addr, 0x570c); 128 addr += 4; 129 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) pcie_70c = %08x\n", 130 AH_PRIVATE(ah)->ah_config.ath_hal_pcie_70c); 131 OS_REG_WRITE(ah, addr, AH_PRIVATE(ah)->ah_config.ath_hal_pcie_70c); 132 addr += 4; 133 OS_REG_WRITE(ah, addr, 0x5040); 134 addr += 4; 135 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) pcie_040 = %08x\n", 136 AH_PRIVATE(ah)->ah_config.ath_hal_pcie_040); 137 OS_REG_WRITE(ah, addr, AH_PRIVATE(ah)->ah_config.ath_hal_pcie_040); 138 addr += 4; 139/* 140 A_SOC_REG_WRITE(0x45000, 0x0034168c); 141 A_SOC_REG_WRITE(0x45008, 0x02800001); 142 A_SOC_REG_WRITE(0x4502c, 0x3117168c); 143 A_SOC_REG_WRITE(0x58c00, 0x18212ede); 144 A_SOC_REG_WRITE(0x58c04, 0x000801d8); 145 A_SOC_REG_WRITE(0x58c08, 0x0003580c); 146 A_SOC_REG_WRITE(0x4570c, 0x275f3f01); 147 A_SOC_REG_WRITE(0x45040, 0xffc25001); 148*/ 149} 150 151/* Retrieve updated information from MAC PCU buffer. 152 * Embedded CPU would have written the value before exiting WoW 153 * */ 154void ar9300_wowoffload_retrieve_data(struct ath_hal *ah, void *buf, u_int32_t param) 155{ 156 u_int32_t rc_lower, rc_upper; 157 158 if (param == WOW_PARAM_REPLAY_CNTR) { 159 rc_lower = OS_REG_READ(ah, AR_WOW_TXBUF(0)); 160 rc_upper = OS_REG_READ(ah, AR_WOW_TXBUF(1)); 161 *(u_int64_t *)buf = rc_lower + (rc_upper << 32); 162 } 163 else if (param == WOW_PARAM_KEY_TSC) { 164 rc_lower = OS_REG_READ(ah, AR_WOW_TXBUF(2)); 165 rc_upper = OS_REG_READ(ah, AR_WOW_TXBUF(3)); 166 *(u_int64_t *)buf = rc_lower + (rc_upper << 32); 167 } 168 else if (param == WOW_PARAM_TX_SEQNUM) { 169 *(u_int32_t *)buf = OS_REG_READ(ah, AR_WOW_TXBUF(4)); 170 } 171 172} 173 174/* Download GTK rekey related information to the embedded CPU */ 175u_int32_t ar9300_wowoffload_download_rekey_data(struct ath_hal *ah, u_int32_t *data, u_int32_t bytes) 176{ 177 int i; 178 int mbox_status = OS_REG_READ(ah, AR_MBOX_CTRL_STATUS); 179 u_int32_t gtk_data_start; 180 181 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) %s, bytes=%d\n", __func__, bytes); 182 if (AR_SREV_JUPITER(ah) && 183 (bytes > (AR_WOW_OFFLOAD_GTK_DATA_WORDS_JUPITER * 4))) 184 { 185 bytes = AR_WOW_OFFLOAD_GTK_DATA_WORDS_JUPITER * 4; 186 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) bytes truncated to %d\n", bytes); 187 } 188 /* Check if mailbox is busy */ 189 if (mbox_status != 0) { 190 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: Mailbox register busy! Reg = 0x%x", __func__, mbox_status); 191 return 1; 192 } 193 194 /* Clear status */ 195 OS_REG_WRITE(ah, AR_EMB_CPU_WOW_STATUS, 0x0); 196 OS_REG_WRITE(ah, AR_WLAN_WOW_ENABLE, 0); 197 OS_REG_WRITE(ah, AR_WLAN_WOW_STATUS, 0xFFFFFFFF); 198 199 if (AR_SREV_JUPITER(ah)) { 200 gtk_data_start = AR_WOW_OFFLOAD_GTK_DATA_START_JUPITER; 201 } else { 202 gtk_data_start = AR_WOW_OFFLOAD_GTK_DATA_START; 203 } 204 for (i = 0;i < bytes/4; i++) { 205 OS_REG_WRITE(ah, gtk_data_start + i * 4, data[i]); 206 } 207 208 return 0; 209} 210 211void ar9300_wowoffload_download_acer_magic( struct ath_hal *ah, 212 HAL_BOOL valid, 213 u_int8_t* datap, 214 u_int32_t bytes) 215{ 216 u_int32_t *p32 = (u_int32_t *) datap; 217 u_int32_t l = 0, u = 0; 218 219 if (valid) { 220 l = *p32; 221 p32++; 222 u = *(u_int16_t *) p32; 223 } 224 225 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_ACER_MAGIC_START, l); 226 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_ACER_MAGIC_START + 4, u); 227 228 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 229 "%s: Aer Magic: %02x-%02x-%02x-%02x-%02x-%02x\n", __func__, 230 datap[0], datap[1], datap[2], datap[3], datap[4], datap[5]); 231} 232 233void ar9300_wowoffload_download_acer_swka( struct ath_hal *ah, 234 u_int32_t id, 235 HAL_BOOL valid, 236 u_int32_t period, 237 u_int32_t size, 238 u_int32_t* datap) 239{ 240 u_int32_t ka_period[2] = { 241 AR_WOW_OFFLOAD_ACER_KA0_PERIOD_MS, 242 AR_WOW_OFFLOAD_ACER_KA1_PERIOD_MS 243 }; 244 u_int32_t ka_size[2] = { 245 AR_WOW_OFFLOAD_ACER_KA0_SIZE, 246 AR_WOW_OFFLOAD_ACER_KA1_SIZE 247 }; 248 u_int32_t ka_data[2] = { 249 AR_WOW_OFFLOAD_ACER_KA0_DATA, 250 AR_WOW_OFFLOAD_ACER_KA1_DATA 251 }; 252 u_int32_t n_data = AR_WOW_OFFLOAD_ACER_KA0_DATA_WORDS; 253 int i; 254 255 if (id >= 2) { 256 return; 257 } 258 259 if (valid) { 260 OS_REG_WRITE(ah, ka_period[id], period); 261 OS_REG_WRITE(ah, ka_size[id], size); 262 } else { 263 OS_REG_WRITE(ah, ka_period[id], 0); 264 OS_REG_WRITE(ah, ka_size[id], 0); 265 } 266 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: id=%d, period=%d ms, size=%d bytes\n", 267 __func__, id, period, size); 268 269 if (size < (n_data * 4)) { 270 n_data = (size + 3) / 4; 271 } 272 for (i=0; i<n_data * 4; i+=4) { 273 OS_REG_WRITE(ah, ka_data[id] + i, *datap); 274 /*HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) %08x\n", *datap);*/ 275 datap++; 276 } 277} 278 279void ar9300_wowoffload_download_arp_info(struct ath_hal *ah, u_int32_t id, u_int32_t *data) 280{ 281 u_int32_t addr; 282 struct hal_wow_offload_arp_info *p_info = (struct hal_wow_offload_arp_info *) data; 283 284 if (id == 0) { 285 addr = AR_WOW_OFFLOAD_ARP0_VALID; 286 } else if (id == 1) { 287 addr = AR_WOW_OFFLOAD_ARP1_VALID; 288 } else { 289 return; 290 } 291 292 if (p_info->valid) { 293 OS_REG_WRITE(ah, addr, 0x1); 294 addr += 4; 295 OS_REG_WRITE(ah, addr, p_info->RemoteIPv4Address.u32); 296 addr += 4; 297 OS_REG_WRITE(ah, addr, p_info->HostIPv4Address.u32); 298 addr += 4; 299 OS_REG_WRITE(ah, addr, p_info->MacAddress.u32[0]); 300 addr += 4; 301 OS_REG_WRITE(ah, addr, p_info->MacAddress.u32[1]); 302 } else { 303 OS_REG_WRITE(ah, addr, 0x0); 304 } 305} 306 307#define WOW_WRITE_NS_IPV6_ADDRESS(_ah, _buf_addr, _p_ipv6_addr) \ 308 { \ 309 u_int32_t offset = (_buf_addr); \ 310 u_int32_t *p_ipv6_addr = (u_int32_t *) (_p_ipv6_addr); \ 311 int i; \ 312 for (i = 0; i < 4; i++) { \ 313 OS_REG_WRITE((_ah), offset, *p_ipv6_addr); \ 314 offset += 4; \ 315 p_ipv6_addr ++; \ 316 } \ 317 } 318 319void ar9300_wowoffload_download_ns_info(struct ath_hal *ah, u_int32_t id, u_int32_t *data) 320{ 321 u_int32_t addr; 322 struct hal_wow_offload_ns_info *p_info = (struct hal_wow_offload_ns_info *) data; 323 u_int8_t mc_addr[6]; 324 325 if (id == 0) { 326 addr = AR_WOW_OFFLOAD_NS0_VALID; 327 } else if (id == 1) { 328 addr = AR_WOW_OFFLOAD_NS1_VALID; 329 } else { 330 return; 331 } 332 333 if (p_info->valid) { 334 OS_REG_WRITE(ah, addr, 0x1); 335 addr += 4; 336 WOW_WRITE_NS_IPV6_ADDRESS(ah, addr, &p_info->RemoteIPv6Address.u32[0]); 337 addr += 4 * 4; 338 WOW_WRITE_NS_IPV6_ADDRESS(ah, addr, &p_info->SolicitedNodeIPv6Address.u32[0]); 339 addr += 4 * 4; 340 OS_REG_WRITE(ah, addr, p_info->MacAddress.u32[0]); 341 addr += 4; 342 OS_REG_WRITE(ah, addr, p_info->MacAddress.u32[1]); 343 addr += 4; 344 WOW_WRITE_NS_IPV6_ADDRESS(ah, addr, &p_info->TargetIPv6Addresses[0].u32[0]); 345 addr += 4 * 4; 346 WOW_WRITE_NS_IPV6_ADDRESS(ah, addr, &p_info->TargetIPv6Addresses[1].u32[0]); 347 348 mc_addr[0] = 0x33; 349 mc_addr[1] = 0x33; 350 mc_addr[2] = 0xFF; 351 mc_addr[3] = p_info->SolicitedNodeIPv6Address.u8[13]; 352 mc_addr[4] = p_info->SolicitedNodeIPv6Address.u8[14]; 353 mc_addr[5] = p_info->SolicitedNodeIPv6Address.u8[15]; 354 ar9300_wowoffload_add_mcast_filter(ah, mc_addr); 355 } else { 356 OS_REG_WRITE(ah, addr, 0x0); 357 } 358} 359 360/* Download transmit parameters for GTK response frame during WoW 361 * offload */ 362u_int32_t ar9300_wow_offload_download_hal_params(struct ath_hal *ah) 363{ 364 u_int32_t tpc = 0x3f; /* Transmit Power Control */ 365 u_int32_t tx_tries_series = 7; 366 u_int32_t tx_rate_series, transmit_rate; 367 u_int32_t gtk_txdesc_param_start; 368 369 if (AH_PRIVATE(ah)->ah_curchan->channel_flags & CHANNEL_CCK) { 370 transmit_rate = 0x1B; /* CCK_1M */ 371 } else { 372 transmit_rate = 0xB; /* OFDM_6M */ 373 } 374 375 /* Use single rate for now. Change later as need be */ 376 tx_rate_series = transmit_rate; 377 tx_tries_series = 7; 378 379 if (AR_SREV_JUPITER(ah)) { 380 gtk_txdesc_param_start = AR_WOW_OFFLOAD_GTK_TXDESC_PARAM_START_JUPITER; 381 } else { 382 gtk_txdesc_param_start = AR_WOW_OFFLOAD_GTK_TXDESC_PARAM_START; 383 } 384#define AR_WOW_OFFLOAD_GTK_TXDESC_PARAM(x) (gtk_txdesc_param_start + ((x) * 4)) 385 386 /* Do not change the data order unless firmware code on embedded 387 * CPU is changed correspondingly */ 388 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_GTK_TXDESC_PARAM(0), tx_rate_series); 389 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_GTK_TXDESC_PARAM(1), tx_tries_series); 390 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_GTK_TXDESC_PARAM(2), AH9300(ah)->ah_tx_chainmask); 391 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_GTK_TXDESC_PARAM(3), tpc); 392 393 return 0; 394} 395 396/* Indicate to the embedded CPU that host is ready to enter WoW mode. 397 * Embedded CPU will copy relevant information from the MAC PCU buffer 398 */ 399u_int32_t ar9300_wow_offload_handshake(struct ath_hal *ah, u_int32_t pattern_enable) 400{ 401 int val; 402 int mbox_status = OS_REG_READ(ah, AR_MBOX_CTRL_STATUS); 403#if ATH_WOW_OFFLOAD 404 u_int32_t bt_handshake_timeout_us = HAL_WOW_CTRL_WAIT_BT_TO(ah) * 100000; 405 406#define AH_DEFAULT_BT_WAIT_TIMEOUT 3000000; /* 3 sec */ 407 if (bt_handshake_timeout_us == 0) { 408 bt_handshake_timeout_us = AH_DEFAULT_BT_WAIT_TIMEOUT; 409 } 410 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) TIMEOUT: %d us\n", bt_handshake_timeout_us); 411#endif /* ATH_WOW_OFFLOAD */ 412 413 if (mbox_status & AR_MBOX_WOW_REQ) { 414 /* WOW mode request handshake is already in progress. 415 * Do nothing */ 416 return 0; 417 } 418 419 /* Clear status */ 420 OS_REG_WRITE(ah, AR_MBOX_CTRL_STATUS, 0); 421 OS_REG_WRITE(ah, AR_EMB_CPU_WOW_STATUS, 0x0); 422 OS_REG_WRITE(ah, AR_WLAN_WOW_ENABLE, 0); 423 OS_REG_WRITE(ah, AR_WLAN_WOW_STATUS, 0xFFFFFFFF); 424 425 OS_REG_WRITE(ah, AR_RIMT, 0); 426 OS_REG_WRITE(ah, AR_TIMT, 0); 427 428 val = 0; 429 if (pattern_enable & AH_WOW_USER_PATTERN_EN) { 430 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - User pattern\n"); 431 val |= AR_EMB_CPU_WOW_ENABLE_PATTERN_MATCH; 432 } 433 else { 434 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - User pattern\n"); 435 } 436 if ((pattern_enable & AH_WOW_MAGIC_PATTERN_EN) 437#if ATH_WOW_OFFLOAD 438 || (pattern_enable & AH_WOW_ACER_MAGIC_EN) 439#endif 440 ) 441 { 442 val |= AR_EMB_CPU_WOW_ENABLE_MAGIC_PATTERN; 443 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - Magic pattern\n"); 444 } 445 else { 446 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - Magic pattern\n"); 447 } 448 if ((pattern_enable & AH_WOW_LINK_CHANGE) 449#if ATH_WOW_OFFLOAD 450 || HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_KAFAIL_ENABLE) 451#endif 452 ) 453 { 454 val |= AR_EMB_CPU_WOW_ENABLE_KEEP_ALIVE_FAIL; 455 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - Kepp alive fail\n"); 456 } 457 else { 458 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - Kepp alive fail\n"); 459 } 460 if (pattern_enable & AH_WOW_BEACON_MISS) { 461 val |= AR_EMB_CPU_WOW_ENABLE_BEACON_MISS; 462 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - Becon Miss\n"); 463 } 464 else { 465 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - Becon Miss\n"); 466 } 467 468 OS_REG_WRITE(ah, AR_EMB_CPU_WOW_ENABLE, val); 469 470 OS_REG_CLR_BIT(ah, AR_MBOX_CTRL_STATUS, AR_MBOX_WOW_CONF); 471 OS_REG_SET_BIT(ah, AR_MBOX_CTRL_STATUS, AR_MBOX_WOW_REQ); 472 OS_REG_SET_BIT(ah, AR_MBOX_CTRL_STATUS, AR_MBOX_INT_EMB_CPU); 473 474 if (!ath_hal_wait(ah, AR_MBOX_CTRL_STATUS, AR_MBOX_WOW_CONF, AR_MBOX_WOW_CONF, bt_handshake_timeout_us)) { 475 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: WoW offload handshake failed", __func__); 476 return 0; 477 } 478 else { 479 OS_REG_CLR_BIT(ah, AR_MBOX_CTRL_STATUS, AR_MBOX_WOW_CONF); 480 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, "%s: WoW offload handshake successful",__func__); 481 } 482 return 1; 483} 484#endif /* ATH_WOW_OFFLOAD */ 485 486/* 487 * Notify Power Mgt is enabled in self-generated frames. 488 * If requested, force chip awake. 489 * 490 * Returns A_OK if chip is awake or successfully forced awake. 491 * 492 * WARNING WARNING WARNING 493 * There is a problem with the chip where sometimes it will not wake up. 494 */ 495HAL_BOOL 496ar9300_set_power_mode_awake(struct ath_hal *ah, int set_chip) 497{ 498 struct ath_hal_9300 *ahp = AH9300(ah); 499#define POWER_UP_TIME 10000 500 u_int32_t val; 501 int i; 502 503 /* Set Bits 14 and 17 of AR_WA before powering on the chip. */ 504 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), ahp->ah_wa_reg_val); 505 OS_DELAY(10); /* delay to allow the write to take effect. */ 506 507 if (set_chip) { 508 /* Do a Power-On-Reset if MAC is shutdown */ 509 if ((OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_SHUTDOWN)) { 510 if (ar9300_set_reset_reg(ah, HAL_RESET_POWER_ON) != AH_TRUE) { 511 HALASSERT(0); 512 return AH_FALSE; 513 } 514 } 515 516 OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 517 518 OS_DELAY(50); 519 520 for (i = POWER_UP_TIME / 50; i > 0; i--) { 521 val = OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; 522 if (val == AR_RTC_STATUS_ON) { 523 break; 524 } 525 OS_DELAY(50); 526 OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 527 } 528 if (i == 0) { 529 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: Failed to wakeup in %uus\n", 530 __func__, POWER_UP_TIME / 20); 531 return AH_FALSE; 532 } 533 534 } 535 536 OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 537 return AH_TRUE; 538#undef POWER_UP_TIME 539} 540 541/* 542 * Notify Power Mgt is disabled in self-generated frames. 543 * If requested, force chip to sleep. 544 */ 545static void 546ar9300_set_power_mode_sleep(struct ath_hal *ah, int set_chip) 547{ 548 struct ath_hal_9300 *ahp = AH9300(ah); 549 550 OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 551 if (set_chip ) { 552 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 553 OS_REG_WRITE(ah, AR_TIMER_MODE, 554 OS_REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); 555 OS_REG_WRITE(ah, AR_GEN_TIMERS2_MODE, 556 OS_REG_READ(ah, AR_GEN_TIMERS2_MODE) & 0xFFFFFF00); 557 OS_REG_WRITE(ah, AR_SLP32_INC, 558 OS_REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); 559 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); 560 OS_DELAY(100); 561 } 562 /* Clear the RTC force wake bit to allow the mac to go to sleep */ 563 OS_REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 564 565 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 566 /* 567 * In Jupiter, after enter sleep mode, hardware will send 568 * a SYS_SLEEPING message through MCI interface. Add a 569 * few us delay to make sure the message can reach BT side. 570 */ 571 OS_DELAY(100); 572 } 573 574 if (!AR_SREV_JUPITER_10(ah)) { 575 /* Shutdown chip. Active low */ 576 OS_REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); 577 /* Settle time */ 578 OS_DELAY(2); 579 } 580 } 581 582#if ATH_WOW_OFFLOAD 583 if (!AR_SREV_JUPITER(ah) || !HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_SET_4004_BIT14)) 584#endif /* ATH_WOW_OFFLOAD */ 585 { 586 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ 587 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), 588 ahp->ah_wa_reg_val & ~AR_WA_D3_TO_L1_DISABLE); 589 } 590} 591 592/* 593 * Notify Power Management is enabled in self-generating 594 * frames. If request, set power mode of chip to 595 * auto/normal. Duration in units of 128us (1/8 TU). 596 */ 597static void 598ar9300_set_power_mode_network_sleep(struct ath_hal *ah, int set_chip) 599{ 600 struct ath_hal_9300 *ahp = AH9300(ah); 601 602 OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 603 if (set_chip) { 604 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; 605 606 if (! p_cap->hal_auto_sleep_support) { 607 /* Set wake_on_interrupt bit; clear force_wake bit */ 608 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 609 } 610 else { 611 /* 612 * When chip goes into network sleep, it could be waken up by 613 * MCI_INT interrupt caused by BT's HW messages (LNA_xxx, CONT_xxx) 614 * which chould be in a very fast rate (~100us). This will cause 615 * chip to leave and re-enter network sleep mode frequently, which 616 * in consequence will have WLAN MCI HW to generate lots of 617 * SYS_WAKING and SYS_SLEEPING messages which will make BT CPU 618 * to busy to process. 619 */ 620 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 621 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 622 OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & 623 ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK); 624 } 625 626 /* Clear the RTC force wake bit to allow the mac to go to sleep */ 627 OS_REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 628 629 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 630 /* 631 * In Jupiter, after enter sleep mode, hardware will send 632 * a SYS_SLEEPING message through MCI interface. Add a 633 * few us delay to make sure the message can reach BT side. 634 */ 635 OS_DELAY(30); 636 } 637 } 638 } 639 640#if ATH_WOW_OFFLOAD 641 if (!AR_SREV_JUPITER(ah) || !HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_SET_4004_BIT14)) 642#endif /* ATH_WOW_OFFLOAD */ 643 { 644 /* Clear Bit 14 of AR_WA after putting chip into Sleep mode. */ 645 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), 646 ahp->ah_wa_reg_val & ~AR_WA_D3_TO_L1_DISABLE); 647 } 648} 649 650/* 651 * Set power mgt to the requested mode, and conditionally set 652 * the chip as well 653 */ 654HAL_BOOL 655ar9300_set_power_mode(struct ath_hal *ah, HAL_POWER_MODE mode, int set_chip) 656{ 657 struct ath_hal_9300 *ahp = AH9300(ah); 658#if AH_DEBUG || AH_PRINT_FILTER 659 static const char* modes[] = { 660 "AWAKE", 661 "FULL-SLEEP", 662 "NETWORK SLEEP", 663 "UNDEFINED" 664 }; 665#endif 666 int status = AH_TRUE; 667 668 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__, 669 modes[ar9300_get_power_mode(ah)], modes[mode], 670 set_chip ? "set chip " : ""); 671 672 switch (mode) { 673 case HAL_PM_AWAKE: 674 status = ar9300_set_power_mode_awake(ah, set_chip); 675#if ATH_SUPPORT_MCI 676 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 677 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 678 } 679#endif 680 break; 681 case HAL_PM_FULL_SLEEP: 682#if ATH_SUPPORT_MCI 683 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 684 if (ar9300_get_power_mode(ah) == HAL_PM_AWAKE) { 685 if ((ar9300_mci_state(ah, HAL_MCI_STATE_ENABLE, NULL) != 0) && 686 (ahp->ah_mci_bt_state != MCI_BT_SLEEP) && 687 !ahp->ah_mci_halted_bt_gpm) 688 { 689 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 690 "(MCI) %s: HALT BT GPM (full_sleep)\n", __func__); 691 ar9300_mci_send_coex_halt_bt_gpm(ah, AH_TRUE, AH_TRUE); 692 } 693 } 694 ahp->ah_mci_ready = AH_FALSE; 695 } 696#endif 697#if ATH_SUPPORT_MCI 698 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 699 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 700 } 701#endif 702 ar9300_set_power_mode_sleep(ah, set_chip); 703 ahp->ah_chip_full_sleep = AH_TRUE; 704 break; 705 case HAL_PM_NETWORK_SLEEP: 706#if ATH_SUPPORT_MCI 707 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 708 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 709 } 710#endif 711 ar9300_set_power_mode_network_sleep(ah, set_chip); 712 break; 713 default: 714 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 715 "%s: unknown power mode %u\n", __func__, mode); 716 return AH_FALSE; 717 } 718 return status; 719} 720 721/* 722 * Return the current sleep mode of the chip 723 */ 724HAL_POWER_MODE 725ar9300_get_power_mode(struct ath_hal *ah) 726{ 727 int mode = OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; 728 729 switch (mode) { 730 case AR_RTC_STATUS_ON: 731 case AR_RTC_STATUS_WAKEUP: 732 return HAL_PM_AWAKE; 733 break; 734 case AR_RTC_STATUS_SLEEP: 735 return HAL_PM_NETWORK_SLEEP; 736 break; 737 case AR_RTC_STATUS_SHUTDOWN: 738 return HAL_PM_FULL_SLEEP; 739 break; 740 default: 741 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 742 "%s: unknown power mode 0x%x\n", __func__, mode); 743 return HAL_PM_UNDEFINED; 744 } 745} 746 747/* 748 * Set SM power save mode 749 */ 750void 751ar9300_set_sm_power_mode(struct ath_hal *ah, HAL_SMPS_MODE mode) 752{ 753 int regval; 754 struct ath_hal_9300 *ahp = AH9300(ah); 755 756 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) != HAL_OK) { 757 return; 758 } 759 760 /* Program low & high power chainmask settings and enable MAC control */ 761 regval = SM(AR_PCU_SMPS_LPWR_CHNMSK_VAL, AR_PCU_SMPS_LPWR_CHNMSK) | 762 SM(ahp->ah_rx_chainmask, AR_PCU_SMPS_HPWR_CHNMSK) | 763 AR_PCU_SMPS_MAC_CHAINMASK; 764 765 /* Program registers according to required SM power mode.*/ 766 switch (mode) { 767 case HAL_SMPS_SW_CTRL_LOW_PWR: 768 OS_REG_WRITE(ah, AR_PCU_SMPS, regval); 769 break; 770 case HAL_SMPS_SW_CTRL_HIGH_PWR: 771 OS_REG_WRITE(ah, AR_PCU_SMPS, regval | AR_PCU_SMPS_SW_CTRL_HPWR); 772 break; 773 case HAL_SMPS_HW_CTRL: 774 OS_REG_WRITE(ah, AR_PCU_SMPS, regval | AR_PCU_SMPS_HW_CTRL_EN); 775 break; 776 case HAL_SMPS_DEFAULT: 777 OS_REG_WRITE(ah, AR_PCU_SMPS, 0); 778 break; 779 default: 780 break; 781 } 782 ahp->ah_sm_power_mode = mode; 783} 784 785#if ATH_WOW 786#if NOT_NEEDED_FOR_OSPREY /* not compiled for darwin */ 787/* 788 * This routine is called to configure the SerDes register for the 789 * Merlin 2.0 and above chip during WOW sleep. 790 */ 791static void 792ar9280_config_ser_des__wow_sleep(struct ath_hal *ah) 793{ 794 int i; 795 struct ath_hal_9300 *ahp = AH9300(ah); 796 797 /* 798 * For WOW sleep, we reprogram the SerDes so that the PLL and CHK REQ 799 * are both enabled. This uses more power but the Maverick team reported 800 * that otherwise, WOW sleep is unstable and chip may disappears. 801 */ 802 for (i = 0; i < ahp->ah_ini_pcie_serdes_wow.ia_rows; i++) { 803 OS_REG_WRITE(ah, 804 INI_RA(&ahp->ah_ini_pcie_serdes_wow, i, 0), 805 INI_RA(&ahp->ah_ini_pcie_serdes_wow, i, 1)); 806 } 807 OS_DELAY(1000); 808} 809#endif /* if NOT_NEEDED_FOR_OSPREY */ 810static HAL_BOOL 811ar9300_wow_create_keep_alive_pattern(struct ath_hal *ah) 812{ 813 struct ath_hal_9300 *ahp = AH9300(ah); 814 u_int32_t frame_len = 28; 815 u_int32_t tpc = 0x3f; 816 u_int32_t transmit_rate; 817 u_int32_t frame_type = 0x2; /* Frame Type -> Data; */ 818 u_int32_t sub_type = 0x4; /* Subtype -> Null Data */ 819 u_int32_t to_ds = 1; 820 u_int32_t duration_id = 0x3d; 821 u_int8_t *sta_mac_addr, *ap_mac_addr; 822 u_int8_t *addr1, *addr2, *addr3; 823 u_int32_t ctl[13] = { 0, }; 824#define NUM_KA_DATA_WORDS 6 825 u_int32_t data_word[NUM_KA_DATA_WORDS]; 826 u_int32_t i; 827 u_int32_t wow_ka_dataword0; 828 829 sta_mac_addr = (u_int8_t *)ahp->ah_macaddr; 830 ap_mac_addr = (u_int8_t *)ahp->ah_bssid; 831 addr2 = sta_mac_addr; 832 addr1 = addr3 = ap_mac_addr; 833 834 if (AH_PRIVATE(ah)->ah_curchan->channel_flags & CHANNEL_CCK) { 835 transmit_rate = 0x1B; /* CCK_1M */ 836 } else { 837 transmit_rate = 0xB; /* OFDM_6M */ 838 } 839 840 /* Set the Transmit Buffer. */ 841 ctl[0] = (frame_len | (tpc << 16)); 842 ctl[1] = 0; 843 ctl[2] = (0x7 << 16); /* tx_tries0 */ 844 ctl[3] = transmit_rate; 845 ctl[4] = 0; 846 ctl[7] = ahp->ah_tx_chainmask << 2; 847 848 for (i = 0; i < 13; i++) { 849 OS_REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 850 } 851 852 data_word[0] = 853 (frame_type << 2) | 854 (sub_type << 4) | 855 (to_ds << 8) | 856 (duration_id << 16); 857 data_word[1] = (((u_int32_t)addr1[3] << 24) | ((u_int32_t)addr1[2] << 16) | 858 ((u_int32_t)addr1[1]) << 8 | ((u_int32_t)addr1[0])); 859 data_word[2] = (((u_int32_t)addr2[1] << 24) | ((u_int32_t)addr2[0] << 16) | 860 ((u_int32_t)addr1[5]) << 8 | ((u_int32_t)addr1[4])); 861 data_word[3] = (((u_int32_t)addr2[5] << 24) | ((u_int32_t)addr2[4] << 16) | 862 ((u_int32_t)addr2[3]) << 8 | ((u_int32_t)addr2[2])); 863 data_word[4] = (((u_int32_t)addr3[3] << 24) | ((u_int32_t)addr3[2] << 16) | 864 ((u_int32_t)addr3[1]) << 8 | (u_int32_t)addr3[0]); 865 data_word[5] = (((u_int32_t)addr3[5]) << 8 | ((u_int32_t)addr3[4])); 866 867 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 868 /* Jupiter 2.0 has an extra descriptor word (Time based 869 * discard) compared to other chips */ 870 OS_REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + 12 * 4), 0); 871 wow_ka_dataword0 = AR_WOW_TXBUF(13); 872 } 873 else { 874 wow_ka_dataword0 = AR_WOW_TXBUF(12); 875 } 876 877 for (i = 0; i < NUM_KA_DATA_WORDS; i++) { 878 OS_REG_WRITE(ah, (wow_ka_dataword0 + i * 4), data_word[i]); 879 } 880 881 return AH_TRUE; 882} 883 884/* TBD: Should querying hal for hardware capability */ 885#define MAX_PATTERN_SIZE 256 886#define MAX_PATTERN_MASK_SIZE 32 887#define MAX_NUM_USER_PATTERN 6 /* Deducting the disassoc/deauth packets */ 888 889void 890ar9300_wow_apply_pattern( 891 struct ath_hal *ah, 892 u_int8_t *p_ath_pattern, 893 u_int8_t *p_ath_mask, 894 int32_t pattern_count, 895 u_int32_t ath_pattern_len) 896{ 897 int i; 898 u_int32_t reg_pat[] = { 899 AR_WOW_TB_PATTERN0, 900 AR_WOW_TB_PATTERN1, 901 AR_WOW_TB_PATTERN2, 902 AR_WOW_TB_PATTERN3, 903 AR_WOW_TB_PATTERN4, 904 AR_WOW_TB_PATTERN5, 905 AR_WOW_TB_PATTERN6, 906 AR_WOW_TB_PATTERN7 907 }; 908 u_int32_t reg_mask[] = { 909 AR_WOW_TB_MASK0, 910 AR_WOW_TB_MASK1, 911 AR_WOW_TB_MASK2, 912 AR_WOW_TB_MASK3, 913 AR_WOW_TB_MASK4, 914 AR_WOW_TB_MASK5, 915 AR_WOW_TB_MASK6, 916 AR_WOW_TB_MASK7 917 }; 918 u_int32_t pattern_val; 919 u_int32_t mask_val; 920 u_int32_t val; 921 u_int8_t mask_bit = 0x1; 922 u_int8_t pattern; 923 924 /* TBD: should check count by querying the hardware capability */ 925 if (pattern_count >= MAX_NUM_USER_PATTERN) { 926 return; 927 } 928 929 pattern = (u_int8_t)OS_REG_READ(ah, AR_WOW_PATTERN_REG); 930 pattern = pattern | (mask_bit << pattern_count); 931 OS_REG_WRITE(ah, AR_WOW_PATTERN_REG, pattern); 932 933 /* Set the registers for pattern */ 934 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { 935 pattern_val = (((u_int32_t)p_ath_pattern[i + 0]) | 936 ((u_int32_t)p_ath_pattern[i + 1] << 8) | 937 ((u_int32_t)p_ath_pattern[i + 2] << 16) | 938 ((u_int32_t)p_ath_pattern[i + 3] << 24)); 939 OS_REG_WRITE(ah, (reg_pat[pattern_count] + i), pattern_val); 940 } 941 942 /* Set the registers for mask */ 943 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { 944 mask_val = (((u_int32_t)p_ath_mask[i + 0]) | 945 ((u_int32_t)p_ath_mask[i + 1] << 8) | 946 ((u_int32_t)p_ath_mask[i + 2] << 16) | 947 ((u_int32_t)p_ath_mask[i + 3] << 24)); 948 OS_REG_WRITE(ah, (reg_mask[pattern_count] + i), mask_val); 949 } 950 951 /* XXX */ 952 /* Set the pattern length to be matched */ 953 if (pattern_count < 4) { 954 /* Pattern 0-3 uses AR_WOW_LENGTH1_REG register */ 955 val = OS_REG_READ(ah, AR_WOW_LENGTH1_REG); 956 val = ((val & (~AR_WOW_LENGTH1_MASK(pattern_count))) | 957 ((ath_pattern_len & AR_WOW_LENGTH_MAX) << 958 AR_WOW_LENGTH1_SHIFT(pattern_count))); 959 OS_REG_WRITE(ah, AR_WOW_LENGTH1_REG, val); 960 } else { 961 /* Pattern 4-7 uses AR_WOW_LENGTH2_REG register */ 962 val = OS_REG_READ(ah, AR_WOW_LENGTH2_REG); 963 val = ((val & (~AR_WOW_LENGTH2_MASK(pattern_count))) | 964 ((ath_pattern_len & AR_WOW_LENGTH_MAX) << 965 AR_WOW_LENGTH2_SHIFT(pattern_count))); 966 OS_REG_WRITE(ah, AR_WOW_LENGTH2_REG, val); 967 } 968 969 AH_PRIVATE(ah)->ah_wow_event_mask |= 970 (1 << (pattern_count + AR_WOW_PATTERN_FOUND_SHIFT)); 971 972 return; 973} 974 975HAL_BOOL 976ar9300_set_power_mode_wow_sleep(struct ath_hal *ah) 977{ 978 OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 979 980 OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ 981 if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) { 982 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, "%s: dma failed to stop in 10ms\n" 983 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", __func__, 984 OS_REG_READ(ah, AR_CR), OS_REG_READ(ah, AR_DIAG_SW)); 985 return AH_FALSE; 986 } else { 987#if 0 988 OS_REG_WRITE(ah, AR_RXDP, 0x0); 989#endif 990 991 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 992 "%s: TODO How to disable RXDP!!\n", __func__); 993 994#if ATH_SUPPORT_MCI 995 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 996 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 997 } 998#endif 999 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 1000 1001 return AH_TRUE; 1002 } 1003} 1004 1005 1006HAL_BOOL 1007ar9300_wow_enable( 1008 struct ath_hal *ah, 1009 u_int32_t pattern_enable, 1010 u_int32_t timeout_in_seconds, 1011 int clearbssid, 1012 HAL_BOOL offloadEnable) 1013{ 1014 uint32_t init_val, val, rval = 0; 1015 const int ka_delay = 4; /* Delay of 4 millisec between two keep_alive's */ 1016 uint32_t wow_event_mask; 1017#if ATH_WOW_OFFLOAD 1018 uint32_t wow_feature_enable = 1019 //AR_WOW_OFFLOAD_ENA_GTK | 1020 //AR_WOW_OFFLOAD_ENA_ARP_OFFLOAD | 1021 //AR_WOW_OFFLOAD_ENA_NS_OFFLOAD | 1022 //AR_WOW_OFFLOAD_ENA_ACER_MAGIC | 1023 //AR_WOW_OFFLOAD_ENA_STD_MAGIC | 1024 //AR_WOW_OFFLOAD_ENA_4WAY_WAKE | 1025 //AR_WOW_OFFLOAD_ENA_SWKA | 1026 //AR_WOW_OFFLOAD_ENA_BT_SLEEP | 1027 AR_WOW_OFFLOAD_ENA_SW_NULL; 1028#endif 1029 1030 /* 1031 * ah_wow_event_mask is a mask to the AR_WOW_PATTERN_REG register to 1032 * indicate which WOW events that we have enabled. The WOW Events are 1033 * from the pattern_enable in this function and pattern_count of 1034 * ar9300_wow_apply_pattern() 1035 */ 1036 wow_event_mask = AH_PRIVATE(ah)->ah_wow_event_mask; 1037 1038 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 1039 "%s: offload: %d, pattern: %08x, event_mask: %08x\n", 1040 __func__, offloadEnable, pattern_enable, wow_event_mask); 1041 1042 /* 1043 * Untie Power-On-Reset from the PCI-E Reset. When we are in WOW sleep, 1044 * we do not want the Reset from the PCI-E to disturb our hw state. 1045 */ 1046 if (AH_PRIVATE(ah)->ah_is_pci_express == AH_TRUE) { 1047 1048 u_int32_t wa_reg_val; 1049 /* 1050 * We need to untie the internal POR (power-on-reset) to the external 1051 * PCI-E reset. We also need to tie the PCI-E Phy reset to the PCI-E 1052 * reset. 1053 */ 1054 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 1055 "%s: Untie POR and PCIE reset\n", __func__); 1056 wa_reg_val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_WA)); 1057 wa_reg_val = wa_reg_val & ~(AR_WA_UNTIE_RESET_EN); 1058 wa_reg_val = wa_reg_val | AR_WA_RESET_EN | AR_WA_POR_SHORT; 1059 /* 1060 * This bit is to bypass the EEPROM/OTP state machine, (by clearing its 1061 * busy state while PCIE_rst is asserted), to allow BT embedded CPU 1062 * be able to access WLAN registers. Otherwise the eCPU access will be 1063 * stalled as eeprom_sm is held in busy state. 1064 * 1065 * EV91928 is that when this bit is set, after host wakeup and PCIE_rst 1066 * deasserted, PCIE configuration registers will be reset and DeviceID 1067 * SubsystemID etc. registers will be different from values before 1068 * entering sleep. This will cause Windows to detect a device removal. 1069 * 1070 * For HW WOW, this bit should keep as cleared. 1071 */ 1072 if (offloadEnable) { 1073 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 1074 "%s: Set AR_WA.13 COLD_RESET_OVERRIDE\n", __func__); 1075 wa_reg_val = wa_reg_val | AR_WA_COLD_RESET_OVERRIDE; 1076 1077#if ATH_WOW_OFFLOAD 1078 if (AR_SREV_JUPITER(ah)) { 1079 wa_reg_val = wa_reg_val | AR_WA_D3_TO_L1_DISABLE; 1080 } 1081#endif 1082 } 1083 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), wa_reg_val); 1084 } 1085 1086 /* 1087 * Set the power states appropriately and enable pme. 1088 */ 1089 val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL)); 1090 val |= 1091 AR_PMCTRL_HOST_PME_EN | 1092 AR_PMCTRL_PWR_PM_CTRL_ENA | 1093 AR_PMCTRL_AUX_PWR_DET; 1094 1095 /* 1096 * Set and clear WOW_PME_CLEAR registers for the chip to generate next 1097 * wow signal. 1098 */ 1099 val |= AR_PMCTRL_WOW_PME_CLR; 1100 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL), val); 1101 val &= ~AR_PMCTRL_WOW_PME_CLR; 1102 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL), val); 1103 1104 /* 1105 * Setup for for: 1106 * - beacon misses 1107 * - magic pattern 1108 * - keep alive timeout 1109 * - pattern matching 1110 */ 1111 1112 /* 1113 * Program some default values for keep-alives, beacon misses, etc. 1114 */ 1115 init_val = OS_REG_READ(ah, AR_WOW_PATTERN_REG); 1116 val = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF) | init_val; 1117 OS_REG_WRITE(ah, AR_WOW_PATTERN_REG, val); 1118 rval = OS_REG_READ(ah, AR_WOW_PATTERN_REG); 1119 1120 val = 1121 AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) | 1122 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) | 1123 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT); 1124 OS_REG_WRITE(ah, AR_WOW_COUNT_REG, val); 1125 rval = OS_REG_READ(ah, AR_WOW_COUNT_REG); 1126 1127 if (pattern_enable & AH_WOW_BEACON_MISS) { 1128 val = AR_WOW_BEACON_TIMO; 1129 } else { 1130 /* We are not using the beacon miss. Program a large value. */ 1131 val = AR_WOW_BEACON_TIMO_MAX; 1132 } 1133 OS_REG_WRITE(ah, AR_WOW_BCN_TIMO_REG, val); 1134 rval = OS_REG_READ(ah, AR_WOW_BCN_TIMO_REG); 1135 1136 /* 1137 * Keep Alive Timo in ms. 1138 */ 1139 if (pattern_enable == 0) { 1140 val = AR_WOW_KEEP_ALIVE_NEVER; 1141 } else { 1142 val = AH_PRIVATE(ah)->ah_config.ath_hal_keep_alive_timeout * 32; 1143 } 1144 OS_REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO_REG, val); 1145 rval = OS_REG_READ(ah, AR_WOW_KEEP_ALIVE_TIMO_REG); 1146 1147 /* 1148 * Keep Alive delay in us. 1149 */ 1150 val = ka_delay * 1000; 1151 OS_REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY_REG, val); 1152 rval = OS_REG_READ(ah, AR_WOW_KEEP_ALIVE_DELAY_REG); 1153 1154 /* 1155 * Create keep_alive Pattern to respond to beacons. 1156 */ 1157 ar9300_wow_create_keep_alive_pattern(ah); 1158 1159 /* 1160 * Configure Mac Wow Registers. 1161 */ 1162 1163 val = OS_REG_READ(ah, AR_WOW_KEEP_ALIVE_REG); 1164 1165 /* 1166 * Send keep alive timeouts anyway. 1167 */ 1168 val &= ~AR_WOW_KEEP_ALIVE_AUTO_DIS; 1169 1170 if (pattern_enable & AH_WOW_LINK_CHANGE) { 1171 val &= ~ AR_WOW_KEEP_ALIVE_FAIL_DIS; 1172 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL; 1173 } else { 1174 val |= AR_WOW_KEEP_ALIVE_FAIL_DIS; 1175 } 1176#if ATH_WOW_OFFLOAD 1177 if (offloadEnable) { 1178 /* Don't enable KA frames yet. BT CPU is not 1179 * yet ready. */ 1180 } 1181 else 1182#endif /* ATH_WOW_OFFLOAD */ 1183 { 1184 OS_REG_WRITE(ah, AR_WOW_KEEP_ALIVE_REG, val); 1185 val = OS_REG_READ(ah, AR_WOW_KEEP_ALIVE_REG); 1186 } 1187 1188 1189 /* 1190 * We are relying on a bmiss failure. Ensure we have enough 1191 * threshold to prevent AH_FALSE positives. 1192 */ 1193 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, 1194 AR_WOW_BMISSTHRESHOLD); 1195 1196 val = OS_REG_READ(ah, AR_WOW_BCN_EN_REG); 1197 if (pattern_enable & AH_WOW_BEACON_MISS) { 1198 val |= AR_WOW_BEACON_FAIL_EN; 1199 wow_event_mask |= AR_WOW_BEACON_FAIL; 1200 } else { 1201 val &= ~AR_WOW_BEACON_FAIL_EN; 1202 } 1203 OS_REG_WRITE(ah, AR_WOW_BCN_EN_REG, val); 1204 val = OS_REG_READ(ah, AR_WOW_BCN_EN_REG); 1205 1206 /* 1207 * Enable the magic packet registers. 1208 */ 1209 val = OS_REG_READ(ah, AR_WOW_PATTERN_REG); 1210 if ((pattern_enable & AH_WOW_MAGIC_PATTERN_EN) 1211#if ATH_WOW_OFFLOAD 1212 || (pattern_enable & AH_WOW_ACER_MAGIC_EN) 1213#endif 1214 ) 1215 { 1216 val |= AR_WOW_MAGIC_EN; 1217 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND; 1218 } else { 1219 val &= ~AR_WOW_MAGIC_EN; 1220 } 1221 val |= AR_WOW_MAC_INTR_EN; 1222 OS_REG_WRITE(ah, AR_WOW_PATTERN_REG, val); 1223 val = OS_REG_READ(ah, AR_WOW_PATTERN_REG); 1224 1225#if ATH_WOW_OFFLOAD 1226 if (HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_FORCE_BT_SLEEP)) { 1227 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_BT_SLEEP; 1228 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - BT SLEEP\n"); 1229 } else { 1230 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_BT_SLEEP; 1231 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - BT SLEEP\n"); 1232 } 1233 1234 if (HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_SW_NULL_DISABLE)) { 1235 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - SW NULL\n"); 1236 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_SW_NULL; 1237 } else { 1238 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - SW NULL\n"); 1239 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_SW_NULL; 1240 } 1241 1242 if (HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_DEVID_SWAR_DISABLE)) { 1243 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - DevID SWAR\n"); 1244 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_DEVID_SWAR; 1245 } else { 1246 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - DevID SWAR\n"); 1247 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_DEVID_SWAR; 1248 } 1249 1250 if (pattern_enable & AH_WOW_ACER_KEEP_ALIVE_EN) { 1251 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - Acer SWKA\n"); 1252 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_SWKA; 1253 } else { 1254 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - Acer SWKA\n"); 1255 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_SWKA; 1256 } 1257 1258 if (pattern_enable & AH_WOW_ACER_MAGIC_EN) { 1259 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - Standard Magic\n"); 1260 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_STD_MAGIC; 1261 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - Acer Magic\n"); 1262 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_ACER_MAGIC; 1263 } else { 1264 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - Standard Magic\n"); 1265 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_STD_MAGIC; 1266 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - Acer Magic\n"); 1267 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_ACER_MAGIC; 1268 } 1269 1270 if ((pattern_enable & AH_WOW_4WAY_HANDSHAKE_EN) || 1271 HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_FORCE_4WAY_HS_WAKE)) { 1272 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - 4Way Handshake\n"); 1273 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_4WAY_WAKE; 1274 } else { 1275 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - 4Way Handshake\n"); 1276 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_4WAY_WAKE; 1277 } 1278 1279 if((pattern_enable & AH_WOW_AP_ASSOCIATION_LOST_EN) || 1280 HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_FORCE_AP_LOSS_WAKE)) 1281 { 1282 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - AP loss wake\n"); 1283 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_AP_LOSS_WAKE; 1284 } else { 1285 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - AP loss wake\n"); 1286 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_AP_LOSS_WAKE; 1287 } 1288 1289 if((pattern_enable & AH_WOW_GTK_HANDSHAKE_ERROR_EN) || 1290 HAL_WOW_CTRL(ah, HAL_WOW_OFFLOAD_FORCE_GTK_ERR_WAKE)) 1291 { 1292 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - GTK error wake\n"); 1293 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_GTK_ERROR_WAKE; 1294 } else { 1295 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - GTK error wake\n"); 1296 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_GTK_ERROR_WAKE; 1297 } 1298 1299 if (pattern_enable & AH_WOW_GTK_OFFLOAD_EN) { 1300 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - GTK offload\n"); 1301 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_GTK; 1302 } else { 1303 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - GTK offload\n"); 1304 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_GTK; 1305 } 1306 1307 if (pattern_enable & AH_WOW_ARP_OFFLOAD_EN) { 1308 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - ARP offload\n"); 1309 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_ARP_OFFLOAD; 1310 } else { 1311 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - ARP offload\n"); 1312 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_ARP_OFFLOAD; 1313 } 1314 1315 if (pattern_enable & AH_WOW_NS_OFFLOAD_EN) { 1316 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) ENA - NS offload\n"); 1317 wow_feature_enable |= AR_WOW_OFFLOAD_ENA_NS_OFFLOAD; 1318 } else { 1319 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) DIS - NS offload\n"); 1320 wow_feature_enable &= ~AR_WOW_OFFLOAD_ENA_NS_OFFLOAD; 1321 } 1322 1323#endif /* ATH_WOW_OFFLOAD */ 1324 1325 /* For Kite and later version of the chips 1326 * enable wow pattern match for packets less than 1327 * 256 bytes for all patterns. 1328 */ 1329 /* XXX */ 1330 OS_REG_WRITE( 1331 ah, AR_WOW_PATTERN_MATCH_LT_256B_REG, AR_WOW_PATTERN_SUPPORTED); 1332 1333 /* 1334 * Set the power states appropriately and enable PME. 1335 */ 1336 val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL)); 1337 val |= 1338 AR_PMCTRL_PWR_STATE_D1D3 | 1339 AR_PMCTRL_HOST_PME_EN | 1340 AR_PMCTRL_PWR_PM_CTRL_ENA; 1341 val &= ~AR_PCIE_PM_CTRL_ENA; 1342 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL), val); 1343 1344 /* Wake on Timer Interrupt. Test mode only. Used in Manufacturing line. */ 1345 if (timeout_in_seconds) { 1346 /* convert Timeout to u_secs */ 1347 OS_REG_WRITE(ah, AR_NEXT_NDP_TIMER, 1348 OS_REG_READ(ah, AR_TSF_L32) + timeout_in_seconds * 1000000 ); 1349 /* timer_period = 30 seconds always */ 1350 OS_REG_WRITE(ah, AR_NDP_PERIOD, 30 * 1000000); 1351 OS_REG_WRITE(ah, AR_TIMER_MODE, OS_REG_READ(ah, AR_TIMER_MODE) | 0x80); 1352 OS_REG_WRITE(ah, AR_IMR_S5, OS_REG_READ(ah, AR_IMR_S5) | 0x80); 1353 OS_REG_WRITE(ah, AR_IMR, OS_REG_READ(ah, AR_IMR) | AR_IMR_GENTMR); 1354 if (clearbssid) { 1355 OS_REG_WRITE(ah, AR_BSS_ID0, 0); 1356 OS_REG_WRITE(ah, AR_BSS_ID1, 0); 1357 } 1358 } 1359 1360 /* Enable Seq# generation when asleep. */ 1361 OS_REG_WRITE(ah, AR_STA_ID1, 1362 OS_REG_READ(ah, AR_STA_ID1) & ~AR_STA_ID1_PRESERVE_SEQNUM); 1363 1364 1365 AH_PRIVATE(ah)->ah_wow_event_mask = wow_event_mask; 1366 1367#if ATH_WOW_OFFLOAD 1368 if (offloadEnable) { 1369 /* Force MAC awake before entering SW WoW mode */ 1370 OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 1371#if ATH_SUPPORT_MCI 1372 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 1373 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 1374 } 1375#endif 1376 1377 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_COMMAND_JUPITER, wow_feature_enable); 1378 OS_REG_WRITE(ah, AR_WOW_OFFLOAD_STATUS_JUPITER, 0x0); 1379 if (wow_feature_enable & AR_WOW_OFFLOAD_ENA_SW_NULL) { 1380 OS_REG_WRITE(ah, AR_WOW_SW_NULL_PARAMETER, 1381 ((1000) | 1382 (4 << AR_WOW_SW_NULL_SHORT_PERIOD_MASK_S))); 1383 } 1384 1385 if (wow_feature_enable & AR_WOW_OFFLOAD_ENA_DEVID_SWAR) { 1386 ar9300_wowoffload_download_devid_swar(ah); 1387 } 1388 1389 ar9300_wow_offload_download_hal_params(ah); 1390 ar9300_wow_offload_handshake(ah, pattern_enable); 1391 AH9300(ah)->ah_chip_full_sleep = AH_FALSE; 1392 1393 //OS_REG_SET_BIT(ah, AR_SW_WOW_CONTROL, AR_HW_WOW_DISABLE); 1394 } 1395 else 1396#endif /* ATH_WOW_OFFLOAD */ 1397 { 1398#if ATH_SUPPORT_MCI 1399 if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) { 1400 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 1401 } 1402#endif 1403 ar9300_set_power_mode_wow_sleep(ah); 1404 AH9300(ah)->ah_chip_full_sleep = AH_TRUE; 1405 } 1406 1407 return (AH_TRUE); 1408} 1409 1410u_int32_t 1411//ar9300_wow_wake_up(struct ath_hal *ah, u_int8_t *chipPatternBytes) 1412ar9300_wow_wake_up(struct ath_hal *ah, HAL_BOOL offloadEnabled) 1413{ 1414 uint32_t wow_status = 0; 1415 uint32_t val = 0, rval; 1416 1417 OS_REG_CLR_BIT(ah, AR_SW_WOW_CONTROL, AR_HW_WOW_DISABLE); 1418 OS_REG_CLR_BIT(ah, AR_SW_WOW_CONTROL, AR_SW_WOW_ENABLE); 1419 1420#if ATH_WOW_OFFLOAD 1421 /* If WoW was offloaded to embedded CPU, use the global 1422 * shared register to know the wakeup reason */ 1423 if (offloadEnabled) { 1424 val = OS_REG_READ(ah, AR_EMB_CPU_WOW_STATUS); 1425 if (val) { 1426 if (val & AR_EMB_CPU_WOW_STATUS_MAGIC_PATTERN) { 1427 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) SW MAGIC_PATTERN\n"); 1428 wow_status |= AH_WOW_MAGIC_PATTERN_EN; 1429 } 1430 if (val & AR_EMB_CPU_WOW_STATUS_PATTERN_MATCH) { 1431 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) SW USER_PATTERN\n"); 1432 wow_status |= AH_WOW_USER_PATTERN_EN; 1433 } 1434 if (val & AR_EMB_CPU_WOW_STATUS_KEEP_ALIVE_FAIL) { 1435 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) SW KEEP_ALIVE_FAIL\n"); 1436 wow_status |= AH_WOW_LINK_CHANGE; 1437 } 1438 if (val & AR_EMB_CPU_WOW_STATUS_BEACON_MISS) { 1439 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) SW BEACON_FAIL\n"); 1440 wow_status |= AH_WOW_BEACON_MISS; 1441 } 1442 } 1443 1444 /* Clear status and mask registers */ 1445 OS_REG_WRITE(ah, AR_EMB_CPU_WOW_STATUS, 0x0); 1446 OS_REG_WRITE(ah, AR_EMB_CPU_WOW_ENABLE, 0); 1447 OS_REG_WRITE(ah, AR_MBOX_CTRL_STATUS, 0); 1448 1449 } 1450 else 1451#endif /* ATH_WOW_OFFLOAD */ 1452 { 1453 /* 1454 * Read the WOW Status register to know the wakeup reason. 1455 */ 1456 rval = OS_REG_READ(ah, AR_WOW_PATTERN_REG); 1457 val = AR_WOW_STATUS(rval); 1458 1459 /* 1460 * Mask only the WOW events that we have enabled. 1461 * Sometimes we have spurious WOW events from the AR_WOW_PATTERN_REG 1462 * register. This mask will clean it up. 1463 */ 1464 val &= AH_PRIVATE(ah)->ah_wow_event_mask; 1465 1466 if (val) { 1467 if (val & AR_WOW_MAGIC_PAT_FOUND) { 1468 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) HW MAGIC_PATTERN\n"); 1469 wow_status |= AH_WOW_MAGIC_PATTERN_EN; 1470 } 1471 if (AR_WOW_PATTERN_FOUND(val)) { 1472 //int i, offset; 1473 //offset = OS_REG_READ(ah, AR_WOW_RXBUF_START_ADDR); 1474 //// Read matched pattern for wake packet detection indication. 1475 //for( i = 0; i< MAX_PATTERN_SIZE/4; i+=4) 1476 //{ 1477 // // RX FIFO is only 8K wrapping. 1478 // if(offset >= 8 * 1024 / 4) offset = 0; 1479 // *(u_int32_t*)(chipPatternBytes + i) = OS_REG_READ( ah,offset ); 1480 // offset++; 1481 //} 1482 wow_status |= AH_WOW_USER_PATTERN_EN; 1483 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) HW USER_PATTERN\n"); 1484 } 1485 if (val & AR_WOW_KEEP_ALIVE_FAIL) { 1486 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) HW KEEP_ALIVE_FAIL\n"); 1487 wow_status |= AH_WOW_LINK_CHANGE; 1488 } 1489 if (val & AR_WOW_BEACON_FAIL) { 1490 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "(WOW) HW BEACON_FAIL\n"); 1491 wow_status |= AH_WOW_BEACON_MISS; 1492 } 1493 } 1494 } 1495 1496 /* 1497 * Set and clear WOW_PME_CLEAR registers for the chip to generate next 1498 * wow signal. 1499 * Disable D3 before accessing other registers ? 1500 */ 1501 val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL)); 1502 /* Check the bit value 0x01000000 (7-10)? */ 1503 val &= ~AR_PMCTRL_PWR_STATE_D1D3; 1504 val |= AR_PMCTRL_WOW_PME_CLR; 1505 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL), val); 1506 1507 /* 1508 * Clear all events. 1509 */ 1510 OS_REG_WRITE(ah, AR_WOW_PATTERN_REG, 1511 AR_WOW_CLEAR_EVENTS(OS_REG_READ(ah, AR_WOW_PATTERN_REG))); 1512 1513 //HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 1514 // "%s: Skip PCIE WA programming\n", __func__); 1515#if 0 1516 /* 1517 * Tie reset register. 1518 * FIXME: Per David Quan not tieing it back might have some repurcussions. 1519 */ 1520 /* XXX */ 1521 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), OS_REG_READ(ah, AR_WA) | 1522 AR_WA_UNTIE_RESET_EN | AR_WA_POR_SHORT | AR_WA_RESET_EN); 1523#endif 1524 1525 /* Restore the Beacon Threshold to init value */ 1526 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR); 1527 1528 /* 1529 * Restore the way the PCI-E Reset, Power-On-Reset, external PCIE_POR_SHORT 1530 * pins are tied to its original value. Previously just before WOW sleep, 1531 * we untie the PCI-E Reset to our Chip's Power On Reset so that 1532 * any PCI-E reset from the bus will not reset our chip. 1533 */ 1534 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "%s: restore AR_WA\n", __func__); 1535 if (AH_PRIVATE(ah)->ah_is_pci_express == AH_TRUE) { 1536 ar9300_config_pci_power_save(ah, 0, 0); 1537 } 1538 1539 AH_PRIVATE(ah)->ah_wow_event_mask = 0; 1540 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 1541 "(WOW) wow_status=%08x\n", wow_status); 1542 1543 return (wow_status); 1544} 1545 1546void 1547ar9300_wow_set_gpio_reset_low(struct ath_hal *ah) 1548{ 1549 uint32_t val; 1550 1551 val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT)); 1552 val |= (1 << (2 * 2)); 1553 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT), val); 1554 val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT)); 1555 /* val = OS_REG_READ(ah,AR_GPIO_IN_OUT ); */ 1556} 1557#endif /* ATH_WOW */ 1558 1559#endif /* AH_SUPPORT_AR9300 */ 1560