1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2009-2012 Realtek Corporation.*/ 3 4 #include "wifi.h" 5 #include "base.h" 6 #include "ps.h" 7 #include <linux/export.h> 8 #include "btcoexist/rtl_btc.h" 9 10 bool rtl_ps_enable_nic(struct ieee80211_hw *hw) 11 { 12 struct rtl_priv *rtlpriv = rtl_priv(hw); 13 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 14 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 15 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); 16 17 /*<1> reset trx ring */ 18 if (rtlhal->interface == INTF_PCI) 19 rtlpriv->intf_ops->reset_trx_ring(hw); 20 21 if (is_hal_stop(rtlhal)) 22 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 23 "Driver is already down!\n"); 24 25 /*<2> Enable Adapter */ 26 if (rtlpriv->cfg->ops->hw_init(hw)) 27 return false; 28 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, 29 &rtlmac->retry_long); 30 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 31 32 rtlpriv->cfg->ops->switch_channel(hw); 33 rtlpriv->cfg->ops->set_channel_access(hw); 34 rtlpriv->cfg->ops->set_bw_mode(hw, 35 cfg80211_get_chandef_type(&hw->conf.chandef)); 36 37 /*<3> Enable Interrupt */ 38 rtlpriv->cfg->ops->enable_interrupt(hw); 39 40 /*<enable timer> */ 41 rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer); 42 43 return true; 44 } 45 EXPORT_SYMBOL(rtl_ps_enable_nic); 46 47 bool rtl_ps_disable_nic(struct ieee80211_hw *hw) 48 { 49 struct rtl_priv *rtlpriv = rtl_priv(hw); 50 51 /*<1> Stop all timer */ 52 rtl_deinit_deferred_work(hw, true); 53 54 /*<2> Disable Interrupt */ 55 rtlpriv->cfg->ops->disable_interrupt(hw); 56 tasklet_kill(&rtlpriv->works.irq_tasklet); 57 58 /*<3> Disable Adapter */ 59 rtlpriv->cfg->ops->hw_disable(hw); 60 61 return true; 62 } 63 EXPORT_SYMBOL(rtl_ps_disable_nic); 64 65 static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, 66 enum rf_pwrstate state_toset, 67 u32 changesource) 68 { 69 struct rtl_priv *rtlpriv = rtl_priv(hw); 70 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 71 bool actionallowed = false; 72 u16 rfwait_cnt = 0; 73 74 /*Only one thread can change 75 *the RF state at one time, and others 76 *should wait to be executed. 77 */ 78 while (true) { 79 spin_lock(&rtlpriv->locks.rf_ps_lock); 80 if (ppsc->rfchange_inprogress) { 81 spin_unlock(&rtlpriv->locks.rf_ps_lock); 82 83 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 84 "RF Change in progress! Wait to set..state_toset(%d).\n", 85 state_toset); 86 87 /* Set RF after the previous action is done. */ 88 while (ppsc->rfchange_inprogress) { 89 rfwait_cnt++; 90 mdelay(1); 91 /*Wait too long, return false to avoid 92 *to be stuck here. 93 */ 94 if (rfwait_cnt > 100) 95 return false; 96 } 97 } else { 98 ppsc->rfchange_inprogress = true; 99 spin_unlock(&rtlpriv->locks.rf_ps_lock); 100 break; 101 } 102 } 103 104 switch (state_toset) { 105 case ERFON: 106 ppsc->rfoff_reason &= (~changesource); 107 108 if ((changesource == RF_CHANGE_BY_HW) && 109 (ppsc->hwradiooff)) { 110 ppsc->hwradiooff = false; 111 } 112 113 if (!ppsc->rfoff_reason) { 114 ppsc->rfoff_reason = 0; 115 actionallowed = true; 116 } 117 118 break; 119 120 case ERFOFF: 121 122 if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) { 123 ppsc->hwradiooff = true; 124 } 125 126 ppsc->rfoff_reason |= changesource; 127 actionallowed = true; 128 break; 129 130 case ERFSLEEP: 131 ppsc->rfoff_reason |= changesource; 132 actionallowed = true; 133 break; 134 135 default: 136 pr_err("switch case %#x not processed\n", state_toset); 137 break; 138 } 139 140 if (actionallowed) 141 rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); 142 143 spin_lock(&rtlpriv->locks.rf_ps_lock); 144 ppsc->rfchange_inprogress = false; 145 spin_unlock(&rtlpriv->locks.rf_ps_lock); 146 147 return actionallowed; 148 } 149 150 static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) 151 { 152 struct rtl_priv *rtlpriv = rtl_priv(hw); 153 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 154 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 155 156 ppsc->swrf_processing = true; 157 158 if (ppsc->inactive_pwrstate == ERFON && 159 rtlhal->interface == INTF_PCI) { 160 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && 161 RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { 162 rtlpriv->intf_ops->disable_aspm(hw); 163 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); 164 } 165 } 166 167 rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, 168 RF_CHANGE_BY_IPS); 169 170 if (ppsc->inactive_pwrstate == ERFOFF && 171 rtlhal->interface == INTF_PCI) { 172 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && 173 !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { 174 rtlpriv->intf_ops->enable_aspm(hw); 175 RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); 176 } 177 } 178 179 ppsc->swrf_processing = false; 180 } 181 182 void rtl_ips_nic_off_wq_callback(struct work_struct *work) 183 { 184 struct rtl_works *rtlworks = container_of(work, struct rtl_works, 185 ips_nic_off_wq.work); 186 struct ieee80211_hw *hw = rtlworks->hw; 187 struct rtl_priv *rtlpriv = rtl_priv(hw); 188 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 189 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 190 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 191 enum rf_pwrstate rtstate; 192 193 if (mac->opmode != NL80211_IFTYPE_STATION) { 194 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 195 "not station return\n"); 196 return; 197 } 198 199 if (mac->p2p_in_use) 200 return; 201 202 if (mac->link_state > MAC80211_NOLINK) 203 return; 204 205 if (is_hal_stop(rtlhal)) 206 return; 207 208 if (rtlpriv->sec.being_setkey) 209 return; 210 211 if (rtlpriv->cfg->ops->bt_coex_off_before_lps) 212 rtlpriv->cfg->ops->bt_coex_off_before_lps(hw); 213 214 if (ppsc->inactiveps) { 215 rtstate = ppsc->rfpwr_state; 216 217 /* 218 *Do not enter IPS in the following conditions: 219 *(1) RF is already OFF or Sleep 220 *(2) swrf_processing (indicates the IPS is still under going) 221 *(3) Connectted (only disconnected can trigger IPS) 222 *(4) IBSS (send Beacon) 223 *(5) AP mode (send Beacon) 224 *(6) monitor mode (rcv packet) 225 */ 226 227 if (rtstate == ERFON && 228 !ppsc->swrf_processing && 229 (mac->link_state == MAC80211_NOLINK) && 230 !mac->act_scanning) { 231 rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 232 "IPSEnter(): Turn off RF\n"); 233 234 ppsc->inactive_pwrstate = ERFOFF; 235 ppsc->in_powersavemode = true; 236 237 /* call before RF off */ 238 if (rtlpriv->cfg->ops->get_btc_status()) 239 rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, 240 ppsc->inactive_pwrstate); 241 242 /*rtl_pci_reset_trx_ring(hw); */ 243 _rtl_ps_inactive_ps(hw); 244 } 245 } 246 } 247 248 void rtl_ips_nic_off(struct ieee80211_hw *hw) 249 { 250 struct rtl_priv *rtlpriv = rtl_priv(hw); 251 252 /* because when link with ap, mac80211 will ask us 253 * to disable nic quickly after scan before linking, 254 * this will cause link failed, so we delay 100ms here 255 */ 256 queue_delayed_work(rtlpriv->works.rtl_wq, 257 &rtlpriv->works.ips_nic_off_wq, MSECS(100)); 258 } 259 260 /* NOTICE: any opmode should exc nic_on, or disable without 261 * nic_on may something wrong, like adhoc TP 262 */ 263 void rtl_ips_nic_on(struct ieee80211_hw *hw) 264 { 265 struct rtl_priv *rtlpriv = rtl_priv(hw); 266 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 267 enum rf_pwrstate rtstate; 268 269 cancel_delayed_work_sync(&rtlpriv->works.ips_nic_off_wq); 270 271 mutex_lock(&rtlpriv->locks.ips_mutex); 272 if (ppsc->inactiveps) { 273 rtstate = ppsc->rfpwr_state; 274 275 if (rtstate != ERFON && 276 !ppsc->swrf_processing && 277 ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { 278 279 ppsc->inactive_pwrstate = ERFON; 280 ppsc->in_powersavemode = false; 281 _rtl_ps_inactive_ps(hw); 282 /* call after RF on */ 283 if (rtlpriv->cfg->ops->get_btc_status()) 284 rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, 285 ppsc->inactive_pwrstate); 286 } 287 } 288 mutex_unlock(&rtlpriv->locks.ips_mutex); 289 } 290 EXPORT_SYMBOL_GPL(rtl_ips_nic_on); 291 292 /*for FW LPS*/ 293 294 /* 295 *Determine if we can set Fw into PS mode 296 *in current condition.Return TRUE if it 297 *can enter PS mode. 298 */ 299 static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) 300 { 301 struct rtl_priv *rtlpriv = rtl_priv(hw); 302 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 303 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 304 u32 ps_timediff; 305 306 ps_timediff = jiffies_to_msecs(jiffies - 307 ppsc->last_delaylps_stamp_jiffies); 308 309 if (ps_timediff < 2000) { 310 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 311 "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); 312 return false; 313 } 314 315 if (mac->link_state != MAC80211_LINKED) 316 return false; 317 318 if (mac->opmode == NL80211_IFTYPE_ADHOC) 319 return false; 320 321 return true; 322 } 323 324 /* Change current and default preamble mode.*/ 325 void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) 326 { 327 struct rtl_priv *rtlpriv = rtl_priv(hw); 328 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 329 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 330 bool enter_fwlps; 331 332 if (mac->opmode == NL80211_IFTYPE_ADHOC) 333 return; 334 335 if (mac->link_state != MAC80211_LINKED) 336 return; 337 338 if (ppsc->dot11_psmode == rt_psmode && rt_psmode == EACTIVE) 339 return; 340 341 /* Update power save mode configured. */ 342 ppsc->dot11_psmode = rt_psmode; 343 344 /* 345 *<FW control LPS> 346 *1. Enter PS mode 347 * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode 348 * cmd to set Fw into PS mode. 349 *2. Leave PS mode 350 * Send H2C fw_pwrmode cmd to Fw to set Fw into Active 351 * mode and set RPWM to turn RF on. 352 */ 353 354 if ((ppsc->fwctrl_lps) && ppsc->report_linked) { 355 if (ppsc->dot11_psmode == EACTIVE) { 356 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 357 "FW LPS leave ps_mode:%x\n", 358 FW_PS_ACTIVE_MODE); 359 enter_fwlps = false; 360 ppsc->pwr_mode = FW_PS_ACTIVE_MODE; 361 ppsc->smart_ps = 0; 362 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_LPS_ACTION, 363 (u8 *)(&enter_fwlps)); 364 if (ppsc->p2p_ps_info.opp_ps) 365 rtl_p2p_ps_cmd(hw , P2P_PS_ENABLE); 366 367 if (rtlpriv->cfg->ops->get_btc_status()) 368 rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); 369 } else { 370 if (rtl_get_fwlps_doze(hw)) { 371 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 372 "FW LPS enter ps_mode:%x\n", 373 ppsc->fwctrl_psmode); 374 if (rtlpriv->cfg->ops->get_btc_status()) 375 rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); 376 enter_fwlps = true; 377 ppsc->pwr_mode = ppsc->fwctrl_psmode; 378 ppsc->smart_ps = 2; 379 rtlpriv->cfg->ops->set_hw_reg(hw, 380 HW_VAR_FW_LPS_ACTION, 381 (u8 *)(&enter_fwlps)); 382 383 } else { 384 /* Reset the power save related parameters. */ 385 ppsc->dot11_psmode = EACTIVE; 386 } 387 } 388 } 389 } 390 391 /* Interrupt safe routine to enter the leisure power save mode.*/ 392 static void rtl_lps_enter_core(struct ieee80211_hw *hw) 393 { 394 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 395 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 396 struct rtl_priv *rtlpriv = rtl_priv(hw); 397 398 if (!ppsc->fwctrl_lps) 399 return; 400 401 if (rtlpriv->sec.being_setkey) 402 return; 403 404 if (rtlpriv->link_info.busytraffic) 405 return; 406 407 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ 408 if (mac->cnt_after_linked < 5) 409 return; 410 411 if (mac->opmode == NL80211_IFTYPE_ADHOC) 412 return; 413 414 if (mac->link_state != MAC80211_LINKED) 415 return; 416 417 mutex_lock(&rtlpriv->locks.lps_mutex); 418 419 /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because 420 * bt_ccoexist may ask to enter lps. 421 * In normal case, this constraint move to rtl_lps_set_psmode(). 422 */ 423 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 424 "Enter 802.11 power save mode...\n"); 425 rtl_lps_set_psmode(hw, EAUTOPS); 426 427 mutex_unlock(&rtlpriv->locks.lps_mutex); 428 } 429 430 /* Interrupt safe routine to leave the leisure power save mode.*/ 431 static void rtl_lps_leave_core(struct ieee80211_hw *hw) 432 { 433 struct rtl_priv *rtlpriv = rtl_priv(hw); 434 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 435 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 436 437 mutex_lock(&rtlpriv->locks.lps_mutex); 438 439 if (ppsc->fwctrl_lps) { 440 if (ppsc->dot11_psmode != EACTIVE) { 441 442 /*FIX ME */ 443 /*rtlpriv->cfg->ops->enable_interrupt(hw); */ 444 445 if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && 446 RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && 447 rtlhal->interface == INTF_PCI) { 448 rtlpriv->intf_ops->disable_aspm(hw); 449 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); 450 } 451 452 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 453 "Busy Traffic,Leave 802.11 power save..\n"); 454 455 rtl_lps_set_psmode(hw, EACTIVE); 456 } 457 } 458 mutex_unlock(&rtlpriv->locks.lps_mutex); 459 } 460 461 /* For sw LPS*/ 462 void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) 463 { 464 struct rtl_priv *rtlpriv = rtl_priv(hw); 465 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 466 struct ieee80211_hdr *hdr = data; 467 struct ieee80211_tim_ie *tim_ie; 468 u8 *tim; 469 u8 tim_len; 470 bool u_buffed; 471 bool m_buffed; 472 473 if (mac->opmode != NL80211_IFTYPE_STATION) 474 return; 475 476 if (!rtlpriv->psc.swctrl_lps) 477 return; 478 479 if (rtlpriv->mac80211.link_state != MAC80211_LINKED) 480 return; 481 482 if (!rtlpriv->psc.sw_ps_enabled) 483 return; 484 485 if (rtlpriv->psc.fwctrl_lps) 486 return; 487 488 if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) 489 return; 490 491 /* check if this really is a beacon */ 492 if (!ieee80211_is_beacon(hdr->frame_control)) 493 return; 494 495 /* min. beacon length + FCS_LEN */ 496 if (len <= 40 + FCS_LEN) 497 return; 498 499 /* and only beacons from the associated BSSID, please */ 500 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) 501 return; 502 503 rtlpriv->psc.last_beacon = jiffies; 504 505 tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); 506 if (!tim) 507 return; 508 509 if (tim[1] < sizeof(*tim_ie)) 510 return; 511 512 tim_len = tim[1]; 513 tim_ie = (struct ieee80211_tim_ie *) &tim[2]; 514 515 if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) 516 rtlpriv->psc.dtim_counter = tim_ie->dtim_count; 517 518 /* Check whenever the PHY can be turned off again. */ 519 520 /* 1. What about buffered unicast traffic for our AID? */ 521 u_buffed = ieee80211_check_tim(tim_ie, tim_len, 522 rtlpriv->mac80211.assoc_id); 523 524 /* 2. Maybe the AP wants to send multicast/broadcast data? */ 525 m_buffed = tim_ie->bitmap_ctrl & 0x01; 526 rtlpriv->psc.multi_buffered = m_buffed; 527 528 /* unicast will process by mac80211 through 529 * set ~IEEE80211_CONF_PS, So we just check 530 * multicast frames here */ 531 if (!m_buffed) { 532 /* back to low-power land. and delay is 533 * prevent null power save frame tx fail */ 534 queue_delayed_work(rtlpriv->works.rtl_wq, 535 &rtlpriv->works.ps_work, MSECS(5)); 536 } else { 537 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 538 "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); 539 } 540 } 541 EXPORT_SYMBOL_GPL(rtl_swlps_beacon); 542 543 void rtl_swlps_rf_awake(struct ieee80211_hw *hw) 544 { 545 struct rtl_priv *rtlpriv = rtl_priv(hw); 546 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 547 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 548 549 if (!rtlpriv->psc.swctrl_lps) 550 return; 551 if (mac->link_state != MAC80211_LINKED) 552 return; 553 554 if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && 555 RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { 556 rtlpriv->intf_ops->disable_aspm(hw); 557 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); 558 } 559 560 mutex_lock(&rtlpriv->locks.lps_mutex); 561 rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); 562 mutex_unlock(&rtlpriv->locks.lps_mutex); 563 } 564 565 void rtl_swlps_rfon_wq_callback(struct work_struct *work) 566 { 567 struct rtl_works *rtlworks = container_of(work, struct rtl_works, 568 ps_rfon_wq.work); 569 struct ieee80211_hw *hw = rtlworks->hw; 570 571 rtl_swlps_rf_awake(hw); 572 } 573 574 void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) 575 { 576 struct rtl_priv *rtlpriv = rtl_priv(hw); 577 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 578 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 579 u8 sleep_intv; 580 581 if (!rtlpriv->psc.sw_ps_enabled) 582 return; 583 584 if ((rtlpriv->sec.being_setkey) || 585 (mac->opmode == NL80211_IFTYPE_ADHOC)) 586 return; 587 588 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ 589 if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5)) 590 return; 591 592 if (rtlpriv->link_info.busytraffic) 593 return; 594 595 spin_lock(&rtlpriv->locks.rf_ps_lock); 596 if (rtlpriv->psc.rfchange_inprogress) { 597 spin_unlock(&rtlpriv->locks.rf_ps_lock); 598 return; 599 } 600 spin_unlock(&rtlpriv->locks.rf_ps_lock); 601 602 mutex_lock(&rtlpriv->locks.lps_mutex); 603 rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); 604 mutex_unlock(&rtlpriv->locks.lps_mutex); 605 606 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && 607 !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { 608 rtlpriv->intf_ops->enable_aspm(hw); 609 RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); 610 } 611 612 /* here is power save alg, when this beacon is DTIM 613 * we will set sleep time to dtim_period * n; 614 * when this beacon is not DTIM, we will set sleep 615 * time to sleep_intv = rtlpriv->psc.dtim_counter or 616 * MAX_SW_LPS_SLEEP_INTV(default set to 5) */ 617 618 if (rtlpriv->psc.dtim_counter == 0) { 619 if (hw->conf.ps_dtim_period == 1) 620 sleep_intv = hw->conf.ps_dtim_period * 2; 621 else 622 sleep_intv = hw->conf.ps_dtim_period; 623 } else { 624 sleep_intv = rtlpriv->psc.dtim_counter; 625 } 626 627 if (sleep_intv > MAX_SW_LPS_SLEEP_INTV) 628 sleep_intv = MAX_SW_LPS_SLEEP_INTV; 629 630 /* this print should always be dtim_conter = 0 & 631 * sleep = dtim_period, that meaons, we should 632 * awake before every dtim */ 633 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 634 "dtim_counter:%x will sleep :%d beacon_intv\n", 635 rtlpriv->psc.dtim_counter, sleep_intv); 636 637 /* we tested that 40ms is enough for sw & hw sw delay */ 638 queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, 639 MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40)); 640 } 641 642 void rtl_lps_change_work_callback(struct work_struct *work) 643 { 644 struct rtl_works *rtlworks = 645 container_of(work, struct rtl_works, lps_change_work); 646 struct ieee80211_hw *hw = rtlworks->hw; 647 struct rtl_priv *rtlpriv = rtl_priv(hw); 648 649 if (rtlpriv->enter_ps) 650 rtl_lps_enter_core(hw); 651 else 652 rtl_lps_leave_core(hw); 653 } 654 EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback); 655 656 void rtl_lps_enter(struct ieee80211_hw *hw, bool may_block) 657 { 658 struct rtl_priv *rtlpriv = rtl_priv(hw); 659 660 if (may_block) 661 return rtl_lps_enter_core(hw); 662 rtlpriv->enter_ps = true; 663 schedule_work(&rtlpriv->works.lps_change_work); 664 } 665 EXPORT_SYMBOL_GPL(rtl_lps_enter); 666 667 void rtl_lps_leave(struct ieee80211_hw *hw, bool may_block) 668 { 669 struct rtl_priv *rtlpriv = rtl_priv(hw); 670 671 if (may_block) 672 return rtl_lps_leave_core(hw); 673 rtlpriv->enter_ps = false; 674 schedule_work(&rtlpriv->works.lps_change_work); 675 } 676 EXPORT_SYMBOL_GPL(rtl_lps_leave); 677 678 void rtl_swlps_wq_callback(struct work_struct *work) 679 { 680 struct rtl_works *rtlworks = container_of(work, struct rtl_works, 681 ps_work.work); 682 struct ieee80211_hw *hw = rtlworks->hw; 683 struct rtl_priv *rtlpriv = rtl_priv(hw); 684 685 /* we can sleep after ps null send ok */ 686 if (rtlpriv->psc.state_inap) 687 rtl_swlps_rf_sleep(hw); 688 } 689 690 static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, 691 unsigned int len) 692 { 693 struct rtl_priv *rtlpriv = rtl_priv(hw); 694 struct ieee80211_mgmt *mgmt = data; 695 struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); 696 u8 *pos, *end, *ie; 697 u16 noa_len; 698 static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; 699 u8 noa_num, index , i, noa_index = 0; 700 bool find_p2p_ie = false , find_p2p_ps_ie = false; 701 702 pos = (u8 *)mgmt->u.beacon.variable; 703 end = data + len; 704 ie = NULL; 705 706 while (pos + 1 < end) { 707 if (pos + 2 + pos[1] > end) 708 return; 709 710 if (pos[0] == 221 && pos[1] > 4) { 711 if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) { 712 ie = pos + 2+4; 713 break; 714 } 715 } 716 pos += 2 + pos[1]; 717 } 718 719 if (ie == NULL) 720 return; 721 find_p2p_ie = true; 722 /*to find noa ie*/ 723 while (ie + 1 < end) { 724 noa_len = le16_to_cpu(*((__le16 *)&ie[1])); 725 if (ie + 3 + ie[1] > end) 726 return; 727 728 if (ie[0] == 12) { 729 find_p2p_ps_ie = true; 730 if ((noa_len - 2) % 13 != 0) { 731 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 732 "P2P notice of absence: invalid length.%d\n", 733 noa_len); 734 return; 735 } else { 736 noa_num = (noa_len - 2) / 13; 737 if (noa_num > P2P_MAX_NOA_NUM) 738 noa_num = P2P_MAX_NOA_NUM; 739 740 } 741 noa_index = ie[3]; 742 if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == 743 P2P_PS_NONE || noa_index != p2pinfo->noa_index) { 744 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, 745 "update NOA ie.\n"); 746 p2pinfo->noa_index = noa_index; 747 p2pinfo->opp_ps = (ie[4] >> 7); 748 p2pinfo->ctwindow = ie[4] & 0x7F; 749 p2pinfo->noa_num = noa_num; 750 index = 5; 751 for (i = 0; i < noa_num; i++) { 752 p2pinfo->noa_count_type[i] = 753 *(u8 *)(ie + index); 754 index += 1; 755 p2pinfo->noa_duration[i] = 756 le32_to_cpu(*(__le32 *)(ie + index)); 757 index += 4; 758 p2pinfo->noa_interval[i] = 759 le32_to_cpu(*(__le32 *)(ie + index)); 760 index += 4; 761 p2pinfo->noa_start_time[i] = 762 le32_to_cpu(*(__le32 *)(ie + index)); 763 index += 4; 764 } 765 766 if (p2pinfo->opp_ps == 1) { 767 p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; 768 /* Driver should wait LPS entering 769 * CTWindow 770 */ 771 if (rtlpriv->psc.fw_current_inpsmode) 772 rtl_p2p_ps_cmd(hw, 773 P2P_PS_ENABLE); 774 } else if (p2pinfo->noa_num > 0) { 775 p2pinfo->p2p_ps_mode = P2P_PS_NOA; 776 rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); 777 } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { 778 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); 779 } 780 } 781 break; 782 } 783 ie += 3 + noa_len; 784 } 785 786 if (find_p2p_ie) { 787 if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) && 788 (!find_p2p_ps_ie)) 789 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); 790 } 791 } 792 793 static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, 794 unsigned int len) 795 { 796 struct rtl_priv *rtlpriv = rtl_priv(hw); 797 struct ieee80211_mgmt *mgmt = data; 798 struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); 799 u8 noa_num, index , i , noa_index = 0; 800 u8 *pos, *end, *ie; 801 u16 noa_len; 802 static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; 803 804 pos = (u8 *)&mgmt->u.action.category; 805 end = data + len; 806 ie = NULL; 807 808 if (pos[0] == 0x7f) { 809 if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0) 810 ie = pos + 3+4; 811 } 812 813 if (ie == NULL) 814 return; 815 816 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); 817 /*to find noa ie*/ 818 while (ie + 1 < end) { 819 noa_len = le16_to_cpu(*(__le16 *)&ie[1]); 820 if (ie + 3 + ie[1] > end) 821 return; 822 823 if (ie[0] == 12) { 824 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); 825 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", 826 ie, noa_len); 827 if ((noa_len - 2) % 13 != 0) { 828 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, 829 "P2P notice of absence: invalid length.%d\n", 830 noa_len); 831 return; 832 } else { 833 noa_num = (noa_len - 2) / 13; 834 if (noa_num > P2P_MAX_NOA_NUM) 835 noa_num = P2P_MAX_NOA_NUM; 836 837 } 838 noa_index = ie[3]; 839 if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == 840 P2P_PS_NONE || noa_index != p2pinfo->noa_index) { 841 p2pinfo->noa_index = noa_index; 842 p2pinfo->opp_ps = (ie[4] >> 7); 843 p2pinfo->ctwindow = ie[4] & 0x7F; 844 p2pinfo->noa_num = noa_num; 845 index = 5; 846 for (i = 0; i < noa_num; i++) { 847 p2pinfo->noa_count_type[i] = 848 *(u8 *)(ie + index); 849 index += 1; 850 p2pinfo->noa_duration[i] = 851 le32_to_cpu(*(__le32 *)(ie + index)); 852 index += 4; 853 p2pinfo->noa_interval[i] = 854 le32_to_cpu(*(__le32 *)(ie + index)); 855 index += 4; 856 p2pinfo->noa_start_time[i] = 857 le32_to_cpu(*(__le32 *)(ie + index)); 858 index += 4; 859 } 860 861 if (p2pinfo->opp_ps == 1) { 862 p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; 863 /* Driver should wait LPS entering 864 * CTWindow 865 */ 866 if (rtlpriv->psc.fw_current_inpsmode) 867 rtl_p2p_ps_cmd(hw, 868 P2P_PS_ENABLE); 869 } else if (p2pinfo->noa_num > 0) { 870 p2pinfo->p2p_ps_mode = P2P_PS_NOA; 871 rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); 872 } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { 873 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); 874 } 875 } 876 break; 877 } 878 ie += 3 + noa_len; 879 } 880 } 881 882 void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state) 883 { 884 struct rtl_priv *rtlpriv = rtl_priv(hw); 885 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); 886 struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); 887 888 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n", p2p_ps_state); 889 switch (p2p_ps_state) { 890 case P2P_PS_DISABLE: 891 p2pinfo->p2p_ps_state = p2p_ps_state; 892 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, 893 &p2p_ps_state); 894 p2pinfo->noa_index = 0; 895 p2pinfo->ctwindow = 0; 896 p2pinfo->opp_ps = 0; 897 p2pinfo->noa_num = 0; 898 p2pinfo->p2p_ps_mode = P2P_PS_NONE; 899 if (rtlps->fw_current_inpsmode) { 900 if (rtlps->smart_ps == 0) { 901 rtlps->smart_ps = 2; 902 rtlpriv->cfg->ops->set_hw_reg(hw, 903 HW_VAR_H2C_FW_PWRMODE, 904 &rtlps->pwr_mode); 905 } 906 907 } 908 break; 909 case P2P_PS_ENABLE: 910 if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { 911 p2pinfo->p2p_ps_state = p2p_ps_state; 912 913 if (p2pinfo->ctwindow > 0) { 914 if (rtlps->smart_ps != 0) { 915 rtlps->smart_ps = 0; 916 rtlpriv->cfg->ops->set_hw_reg(hw, 917 HW_VAR_H2C_FW_PWRMODE, 918 &rtlps->pwr_mode); 919 } 920 } 921 rtlpriv->cfg->ops->set_hw_reg(hw, 922 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, 923 &p2p_ps_state); 924 925 } 926 break; 927 case P2P_PS_SCAN: 928 case P2P_PS_SCAN_DONE: 929 case P2P_PS_ALLSTASLEEP: 930 if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { 931 p2pinfo->p2p_ps_state = p2p_ps_state; 932 rtlpriv->cfg->ops->set_hw_reg(hw, 933 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, 934 &p2p_ps_state); 935 } 936 break; 937 default: 938 break; 939 } 940 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, 941 "ctwindow %x oppps %x\n", 942 p2pinfo->ctwindow, p2pinfo->opp_ps); 943 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, 944 "count %x duration %x index %x interval %x start time %x noa num %x\n", 945 p2pinfo->noa_count_type[0], 946 p2pinfo->noa_duration[0], 947 p2pinfo->noa_index, 948 p2pinfo->noa_interval[0], 949 p2pinfo->noa_start_time[0], 950 p2pinfo->noa_num); 951 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); 952 } 953 954 void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) 955 { 956 struct rtl_priv *rtlpriv = rtl_priv(hw); 957 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 958 struct ieee80211_hdr *hdr = data; 959 960 if (!mac->p2p) 961 return; 962 if (mac->link_state != MAC80211_LINKED) 963 return; 964 /* min. beacon length + FCS_LEN */ 965 if (len <= 40 + FCS_LEN) 966 return; 967 968 /* and only beacons from the associated BSSID, please */ 969 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) 970 return; 971 972 /* check if this really is a beacon */ 973 if (!(ieee80211_is_beacon(hdr->frame_control) || 974 ieee80211_is_probe_resp(hdr->frame_control) || 975 ieee80211_is_action(hdr->frame_control))) 976 return; 977 978 if (ieee80211_is_action(hdr->frame_control)) 979 rtl_p2p_action_ie(hw , data , len - FCS_LEN); 980 else 981 rtl_p2p_noa_ie(hw , data , len - FCS_LEN); 982 } 983 EXPORT_SYMBOL_GPL(rtl_p2p_info); 984