1970 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2012 Realtek Corporation.*/3 4#include "wifi.h"5#include "core.h"6#include "cam.h"7#include "base.h"8#include "ps.h"9#include "pwrseqcmd.h"10 11#include "btcoexist/rtl_btc.h"12#include <linux/firmware.h>13#include <linux/export.h>14#include <net/cfg80211.h>15 16u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {17 36, 38, 40, 42, 44, 46, 48, /* Band 1 */18 52, 54, 56, 58, 60, 62, 64, /* Band 2 */19 100, 102, 104, 106, 108, 110, 112, /* Band 3 */20 116, 118, 120, 122, 124, 126, 128, /* Band 3 */21 132, 134, 136, 138, 140, 142, 144, /* Band 3 */22 149, 151, 153, 155, 157, 159, 161, /* Band 4 */23 165, 167, 169, 171, 173, 175, 177 /* Band 4 */24};25EXPORT_SYMBOL(channel5g);26 27u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {28 42, 58, 106, 122, 138, 155, 17129};30EXPORT_SYMBOL(channel5g_80m);31 32void rtl_addr_delay(u32 addr)33{34 if (addr == 0xfe)35 mdelay(50);36 else if (addr == 0xfd)37 msleep(5);38 else if (addr == 0xfc)39 msleep(1);40 else if (addr == 0xfb)41 usleep_range(50, 100);42 else if (addr == 0xfa)43 usleep_range(5, 10);44 else if (addr == 0xf9)45 usleep_range(1, 2);46}47EXPORT_SYMBOL(rtl_addr_delay);48 49void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,50 u32 mask, u32 data)51{52 if (addr >= 0xf9 && addr <= 0xfe) {53 rtl_addr_delay(addr);54 } else {55 rtl_set_rfreg(hw, rfpath, addr, mask, data);56 udelay(1);57 }58}59EXPORT_SYMBOL(rtl_rfreg_delay);60 61void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)62{63 if (addr >= 0xf9 && addr <= 0xfe) {64 rtl_addr_delay(addr);65 } else {66 rtl_set_bbreg(hw, addr, MASKDWORD, data);67 udelay(1);68 }69}70EXPORT_SYMBOL(rtl_bb_delay);71 72static void rtl_fw_do_work(const struct firmware *firmware, void *context,73 bool is_wow)74{75 struct ieee80211_hw *hw = context;76 struct rtl_priv *rtlpriv = rtl_priv(hw);77 int err;78 79 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,80 "Firmware callback routine entered!\n");81 if (!firmware) {82 if (rtlpriv->cfg->alt_fw_name) {83 err = request_firmware(&firmware,84 rtlpriv->cfg->alt_fw_name,85 rtlpriv->io.dev);86 pr_info("Loading alternative firmware %s\n",87 rtlpriv->cfg->alt_fw_name);88 if (!err)89 goto found_alt;90 }91 pr_err("Selected firmware is not available\n");92 rtlpriv->max_fw_size = 0;93 goto exit;94 }95found_alt:96 if (firmware->size > rtlpriv->max_fw_size) {97 pr_err("Firmware is too big!\n");98 release_firmware(firmware);99 goto exit;100 }101 if (!is_wow) {102 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data,103 firmware->size);104 rtlpriv->rtlhal.fwsize = firmware->size;105 } else {106 memcpy(rtlpriv->rtlhal.wowlan_firmware, firmware->data,107 firmware->size);108 rtlpriv->rtlhal.wowlan_fwsize = firmware->size;109 }110 release_firmware(firmware);111 112exit:113 complete(&rtlpriv->firmware_loading_complete);114}115 116void rtl_fw_cb(const struct firmware *firmware, void *context)117{118 rtl_fw_do_work(firmware, context, false);119}120EXPORT_SYMBOL(rtl_fw_cb);121 122void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context)123{124 rtl_fw_do_work(firmware, context, true);125}126EXPORT_SYMBOL(rtl_wowlan_fw_cb);127 128/*mutex for start & stop is must here. */129static int rtl_op_start(struct ieee80211_hw *hw)130{131 int err = 0;132 struct rtl_priv *rtlpriv = rtl_priv(hw);133 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));134 135 if (!is_hal_stop(rtlhal))136 return 0;137 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))138 return 0;139 mutex_lock(&rtlpriv->locks.conf_mutex);140 err = rtlpriv->intf_ops->adapter_start(hw);141 if (!err)142 rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer);143 mutex_unlock(&rtlpriv->locks.conf_mutex);144 return err;145}146 147static void rtl_op_stop(struct ieee80211_hw *hw, bool suspend)148{149 struct rtl_priv *rtlpriv = rtl_priv(hw);150 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));151 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));152 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));153 bool support_remote_wakeup = false;154 155 if (is_hal_stop(rtlhal))156 return;157 158 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,159 (u8 *)(&support_remote_wakeup));160 /* here is must, because adhoc do stop and start,161 * but stop with RFOFF may cause something wrong,162 * like adhoc TP163 */164 if (unlikely(ppsc->rfpwr_state == ERFOFF))165 rtl_ips_nic_on(hw);166 167 mutex_lock(&rtlpriv->locks.conf_mutex);168 /* if wowlan supported, DON'T clear connected info */169 if (!(support_remote_wakeup &&170 rtlhal->enter_pnp_sleep)) {171 mac->link_state = MAC80211_NOLINK;172 eth_zero_addr(mac->bssid);173 mac->vendor = PEER_UNKNOWN;174 175 /* reset sec info */176 rtl_cam_reset_sec_info(hw);177 178 rtl_deinit_deferred_work(hw, false);179 }180 rtlpriv->intf_ops->adapter_stop(hw);181 182 mutex_unlock(&rtlpriv->locks.conf_mutex);183}184 185static void rtl_op_tx(struct ieee80211_hw *hw,186 struct ieee80211_tx_control *control,187 struct sk_buff *skb)188{189 struct rtl_priv *rtlpriv = rtl_priv(hw);190 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));191 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));192 struct rtl_tcb_desc tcb_desc;193 194 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));195 196 if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))197 goto err_free;198 199 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))200 goto err_free;201 202 if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb))203 rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc);204 return;205 206err_free:207 dev_kfree_skb_any(skb);208}209 210static int rtl_op_add_interface(struct ieee80211_hw *hw,211 struct ieee80211_vif *vif)212{213 struct rtl_priv *rtlpriv = rtl_priv(hw);214 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));215 int err = 0;216 u8 retry_limit = 0x30;217 218 if (mac->vif) {219 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,220 "vif has been set!! mac->vif = 0x%p\n", mac->vif);221 return -EOPNOTSUPP;222 }223 224 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;225 226 rtl_ips_nic_on(hw);227 228 mutex_lock(&rtlpriv->locks.conf_mutex);229 switch (ieee80211_vif_type_p2p(vif)) {230 case NL80211_IFTYPE_P2P_CLIENT:231 mac->p2p = P2P_ROLE_CLIENT;232 fallthrough;233 case NL80211_IFTYPE_STATION:234 if (mac->beacon_enabled == 1) {235 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,236 "NL80211_IFTYPE_STATION\n");237 mac->beacon_enabled = 0;238 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,239 rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);240 }241 break;242 case NL80211_IFTYPE_ADHOC:243 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,244 "NL80211_IFTYPE_ADHOC\n");245 246 mac->link_state = MAC80211_LINKED;247 rtlpriv->cfg->ops->set_bcn_reg(hw);248 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)249 mac->basic_rates = 0xfff;250 else251 mac->basic_rates = 0xff0;252 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,253 (u8 *)(&mac->basic_rates));254 255 retry_limit = 0x07;256 break;257 case NL80211_IFTYPE_P2P_GO:258 mac->p2p = P2P_ROLE_GO;259 fallthrough;260 case NL80211_IFTYPE_AP:261 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,262 "NL80211_IFTYPE_AP\n");263 264 mac->link_state = MAC80211_LINKED;265 rtlpriv->cfg->ops->set_bcn_reg(hw);266 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)267 mac->basic_rates = 0xfff;268 else269 mac->basic_rates = 0xff0;270 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,271 (u8 *)(&mac->basic_rates));272 273 retry_limit = 0x07;274 break;275 case NL80211_IFTYPE_MESH_POINT:276 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,277 "NL80211_IFTYPE_MESH_POINT\n");278 279 mac->link_state = MAC80211_LINKED;280 rtlpriv->cfg->ops->set_bcn_reg(hw);281 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)282 mac->basic_rates = 0xfff;283 else284 mac->basic_rates = 0xff0;285 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,286 (u8 *)(&mac->basic_rates));287 288 retry_limit = 0x07;289 break;290 default:291 pr_err("operation mode %d is not supported!\n",292 vif->type);293 err = -EOPNOTSUPP;294 goto out;295 }296 297 if (mac->p2p) {298 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,299 "p2p role %x\n", vif->type);300 mac->basic_rates = 0xff0;/*disable cck rate for p2p*/301 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,302 (u8 *)(&mac->basic_rates));303 }304 mac->vif = vif;305 mac->opmode = vif->type;306 rtlpriv->cfg->ops->set_network_type(hw, vif->type);307 memcpy(mac->mac_addr, vif->addr, ETH_ALEN);308 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);309 310 mac->retry_long = retry_limit;311 mac->retry_short = retry_limit;312 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,313 (u8 *)(&retry_limit));314out:315 mutex_unlock(&rtlpriv->locks.conf_mutex);316 return err;317}318 319static void rtl_op_remove_interface(struct ieee80211_hw *hw,320 struct ieee80211_vif *vif)321{322 struct rtl_priv *rtlpriv = rtl_priv(hw);323 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));324 325 mutex_lock(&rtlpriv->locks.conf_mutex);326 327 /* Free beacon resources */328 if (vif->type == NL80211_IFTYPE_AP ||329 vif->type == NL80211_IFTYPE_ADHOC ||330 vif->type == NL80211_IFTYPE_MESH_POINT) {331 if (mac->beacon_enabled == 1) {332 mac->beacon_enabled = 0;333 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,334 rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);335 }336 }337 338 /*339 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as340 *NO LINK for our hardware.341 */342 mac->p2p = 0;343 mac->vif = NULL;344 mac->link_state = MAC80211_NOLINK;345 eth_zero_addr(mac->bssid);346 mac->vendor = PEER_UNKNOWN;347 mac->opmode = NL80211_IFTYPE_UNSPECIFIED;348 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);349 350 mutex_unlock(&rtlpriv->locks.conf_mutex);351}352 353static int rtl_op_change_interface(struct ieee80211_hw *hw,354 struct ieee80211_vif *vif,355 enum nl80211_iftype new_type, bool p2p)356{357 struct rtl_priv *rtlpriv = rtl_priv(hw);358 int ret;359 360 rtl_op_remove_interface(hw, vif);361 362 vif->type = new_type;363 vif->p2p = p2p;364 ret = rtl_op_add_interface(hw, vif);365 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,366 "p2p %x\n", p2p);367 return ret;368}369 370#ifdef CONFIG_PM371static u16 crc16_ccitt(u8 data, u16 crc)372{373 u8 shift_in, data_bit, crc_bit11, crc_bit4, crc_bit15;374 u8 i;375 u16 result;376 377 for (i = 0; i < 8; i++) {378 crc_bit15 = ((crc & BIT(15)) ? 1 : 0);379 data_bit = (data & (BIT(0) << i) ? 1 : 0);380 shift_in = crc_bit15 ^ data_bit;381 382 result = crc << 1;383 if (shift_in == 0)384 result &= (~BIT(0));385 else386 result |= BIT(0);387 388 crc_bit11 = ((crc & BIT(11)) ? 1 : 0) ^ shift_in;389 if (crc_bit11 == 0)390 result &= (~BIT(12));391 else392 result |= BIT(12);393 394 crc_bit4 = ((crc & BIT(4)) ? 1 : 0) ^ shift_in;395 if (crc_bit4 == 0)396 result &= (~BIT(5));397 else398 result |= BIT(5);399 400 crc = result;401 }402 403 return crc;404}405 406static u16 _calculate_wol_pattern_crc(u8 *pattern, u16 len)407{408 u16 crc = 0xffff;409 u32 i;410 411 for (i = 0; i < len; i++)412 crc = crc16_ccitt(pattern[i], crc);413 414 crc = ~crc;415 416 return crc;417}418 419static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw,420 struct cfg80211_wowlan *wow)421{422 struct rtl_priv *rtlpriv = rtl_priv(hw);423 struct rtl_mac *mac = &rtlpriv->mac80211;424 struct cfg80211_pkt_pattern *patterns = wow->patterns;425 struct rtl_wow_pattern rtl_pattern;426 const u8 *pattern_os, *mask_os;427 u8 mask[MAX_WOL_BIT_MASK_SIZE] = {0};428 u8 content[MAX_WOL_PATTERN_SIZE] = {0};429 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};430 u8 multicast_addr1[2] = {0x33, 0x33};431 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};432 u8 i, mask_len;433 u16 j, len;434 435 for (i = 0; i < wow->n_patterns; i++) {436 memset(&rtl_pattern, 0, sizeof(struct rtl_wow_pattern));437 memset(mask, 0, MAX_WOL_BIT_MASK_SIZE);438 if (patterns[i].pattern_len < 0 ||439 patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) {440 rtl_dbg(rtlpriv, COMP_POWER, DBG_WARNING,441 "Pattern[%d] is too long\n", i);442 continue;443 }444 pattern_os = patterns[i].pattern;445 mask_len = DIV_ROUND_UP(patterns[i].pattern_len, 8);446 mask_os = patterns[i].mask;447 RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,448 "pattern content\n", pattern_os,449 patterns[i].pattern_len);450 RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,451 "mask content\n", mask_os, mask_len);452 /* 1. unicast? multicast? or broadcast? */453 if (memcmp(pattern_os, broadcast_addr, 6) == 0)454 rtl_pattern.type = BROADCAST_PATTERN;455 else if (memcmp(pattern_os, multicast_addr1, 2) == 0 ||456 memcmp(pattern_os, multicast_addr2, 3) == 0)457 rtl_pattern.type = MULTICAST_PATTERN;458 else if (memcmp(pattern_os, mac->mac_addr, 6) == 0)459 rtl_pattern.type = UNICAST_PATTERN;460 else461 rtl_pattern.type = UNKNOWN_TYPE;462 463 /* 2. translate mask_from_os to mask_for_hw */464 465/******************************************************************************466 * pattern from OS uses 'ethenet frame', like this:467 468 | 6 | 6 | 2 | 20 | Variable | 4 |469 |--------+--------+------+-----------+------------+-----|470 | 802.3 Mac Header | IP Header | TCP Packet | FCS |471 | DA | SA | Type |472 473 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,474 475 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |476 |-------------------+--------+------+-----------+------------+-----|477 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |478 | Others | Tpye |479 480 * Therefore, we need translate mask_from_OS to mask_to_hw.481 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,482 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,483 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.484 ******************************************************************************/485 486 /* Shift 6 bits */487 for (j = 0; j < mask_len - 1; j++) {488 mask[j] = mask_os[j] >> 6;489 mask[j] |= (mask_os[j + 1] & 0x3F) << 2;490 }491 mask[j] = (mask_os[j] >> 6) & 0x3F;492 /* Set bit 0-5 to zero */493 mask[0] &= 0xC0;494 495 RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,496 "mask to hw\n", mask, mask_len);497 for (j = 0; j < (MAX_WOL_BIT_MASK_SIZE + 1) / 4; j++) {498 rtl_pattern.mask[j] = mask[j * 4];499 rtl_pattern.mask[j] |= (mask[j * 4 + 1] << 8);500 rtl_pattern.mask[j] |= (mask[j * 4 + 2] << 16);501 rtl_pattern.mask[j] |= (mask[j * 4 + 3] << 24);502 }503 504 /* To get the wake up pattern from the mask.505 * We do not count first 12 bits which means506 * DA[6] and SA[6] in the pattern to match HW design.507 */508 len = 0;509 for (j = 12; j < patterns[i].pattern_len; j++) {510 if ((mask_os[j / 8] >> (j % 8)) & 0x01) {511 content[len] = pattern_os[j];512 len++;513 }514 }515 516 RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,517 "pattern to hw\n", content, len);518 /* 3. calculate crc */519 rtl_pattern.crc = _calculate_wol_pattern_crc(content, len);520 rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,521 "CRC_Remainder = 0x%x\n", rtl_pattern.crc);522 523 /* 4. write crc & mask_for_hw to hw */524 rtlpriv->cfg->ops->add_wowlan_pattern(hw, &rtl_pattern, i);525 }526 rtl_write_byte(rtlpriv, 0x698, wow->n_patterns);527}528 529static int rtl_op_suspend(struct ieee80211_hw *hw,530 struct cfg80211_wowlan *wow)531{532 struct rtl_priv *rtlpriv = rtl_priv(hw);533 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);534 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));535 536 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n");537 if (WARN_ON(!wow))538 return -EINVAL;539 540 /* to resolve s4 can not wake up*/541 rtlhal->last_suspend_sec = ktime_get_real_seconds();542 543 if ((ppsc->wo_wlan_mode & WAKE_ON_PATTERN_MATCH) && wow->n_patterns)544 _rtl_add_wowlan_patterns(hw, wow);545 546 rtlhal->driver_is_goingto_unload = true;547 rtlhal->enter_pnp_sleep = true;548 549 rtl_lps_leave(hw, true);550 rtl_op_stop(hw, false);551 device_set_wakeup_enable(wiphy_dev(hw->wiphy), true);552 return 0;553}554 555static int rtl_op_resume(struct ieee80211_hw *hw)556{557 struct rtl_priv *rtlpriv = rtl_priv(hw);558 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);559 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));560 time64_t now;561 562 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n");563 rtlhal->driver_is_goingto_unload = false;564 rtlhal->enter_pnp_sleep = false;565 rtlhal->wake_from_pnp_sleep = true;566 567 /* to resolve s4 can not wake up*/568 now = ktime_get_real_seconds();569 if (now - rtlhal->last_suspend_sec < 5)570 return -1;571 572 rtl_op_start(hw);573 device_set_wakeup_enable(wiphy_dev(hw->wiphy), false);574 ieee80211_resume_disconnect(mac->vif);575 rtlhal->wake_from_pnp_sleep = false;576 return 0;577}578#endif579 580static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)581{582 struct rtl_priv *rtlpriv = rtl_priv(hw);583 struct rtl_phy *rtlphy = &(rtlpriv->phy);584 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));585 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));586 struct ieee80211_conf *conf = &hw->conf;587 588 if (mac->skip_scan)589 return 1;590 591 mutex_lock(&rtlpriv->locks.conf_mutex);592 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2)*/593 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,594 "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n");595 }596 597 /*For IPS */598 if (changed & IEEE80211_CONF_CHANGE_IDLE) {599 if (hw->conf.flags & IEEE80211_CONF_IDLE)600 rtl_ips_nic_off(hw);601 else602 rtl_ips_nic_on(hw);603 } else {604 /*605 *although rfoff may not cause by ips, but we will606 *check the reason in set_rf_power_state function607 */608 if (unlikely(ppsc->rfpwr_state == ERFOFF))609 rtl_ips_nic_on(hw);610 }611 612 /*For LPS */613 if ((changed & IEEE80211_CONF_CHANGE_PS) &&614 rtlpriv->psc.swctrl_lps && !rtlpriv->psc.fwctrl_lps) {615 cancel_delayed_work(&rtlpriv->works.ps_work);616 cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);617 if (conf->flags & IEEE80211_CONF_PS) {618 rtlpriv->psc.sw_ps_enabled = true;619 /* sleep here is must, or we may recv the beacon and620 * cause mac80211 into wrong ps state, this will cause621 * power save nullfunc send fail, and further cause622 * pkt loss, So sleep must quickly but not immediatly623 * because that will cause nullfunc send by mac80211624 * fail, and cause pkt loss, we have tested that 5mA625 * is worked very well */626 if (!rtlpriv->psc.multi_buffered)627 queue_delayed_work(rtlpriv->works.rtl_wq,628 &rtlpriv->works.ps_work,629 MSECS(5));630 } else {631 rtl_swlps_rf_awake(hw);632 rtlpriv->psc.sw_ps_enabled = false;633 }634 }635 636 if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&637 !rtlpriv->proximity.proxim_on) {638 struct ieee80211_channel *channel = hw->conf.chandef.chan;639 enum nl80211_chan_width width = hw->conf.chandef.width;640 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;641 u8 wide_chan = (u8) channel->hw_value;642 643 /* channel_type is for 20&40M */644 if (width < NL80211_CHAN_WIDTH_80)645 channel_type =646 cfg80211_get_chandef_type(&hw->conf.chandef);647 if (mac->act_scanning)648 mac->n_channels++;649 650 /*651 *because we should back channel to652 *current_network.chan in scanning,653 *So if set_chan == current_network.chan654 *we should set it.655 *because mac80211 tell us wrong bw40656 *info for cisco1253 bw20, so we modify657 *it here based on UPPER & LOWER658 */659 660 if (width >= NL80211_CHAN_WIDTH_80) {661 if (width == NL80211_CHAN_WIDTH_80) {662 u32 center = hw->conf.chandef.center_freq1;663 u32 primary =664 (u32)hw->conf.chandef.chan->center_freq;665 666 rtlphy->current_chan_bw =667 HT_CHANNEL_WIDTH_80;668 mac->bw_80 = true;669 mac->bw_40 = true;670 if (center > primary) {671 mac->cur_80_prime_sc =672 PRIME_CHNL_OFFSET_LOWER;673 if (center - primary == 10) {674 mac->cur_40_prime_sc =675 PRIME_CHNL_OFFSET_UPPER;676 677 wide_chan += 2;678 } else if (center - primary == 30) {679 mac->cur_40_prime_sc =680 PRIME_CHNL_OFFSET_LOWER;681 682 wide_chan += 6;683 }684 } else {685 mac->cur_80_prime_sc =686 PRIME_CHNL_OFFSET_UPPER;687 if (primary - center == 10) {688 mac->cur_40_prime_sc =689 PRIME_CHNL_OFFSET_LOWER;690 691 wide_chan -= 2;692 } else if (primary - center == 30) {693 mac->cur_40_prime_sc =694 PRIME_CHNL_OFFSET_UPPER;695 696 wide_chan -= 6;697 }698 }699 }700 } else {701 switch (channel_type) {702 case NL80211_CHAN_HT20:703 case NL80211_CHAN_NO_HT:704 /* SC */705 mac->cur_40_prime_sc =706 PRIME_CHNL_OFFSET_DONT_CARE;707 rtlphy->current_chan_bw =708 HT_CHANNEL_WIDTH_20;709 mac->bw_40 = false;710 mac->bw_80 = false;711 break;712 case NL80211_CHAN_HT40MINUS:713 /* SC */714 mac->cur_40_prime_sc =715 PRIME_CHNL_OFFSET_UPPER;716 rtlphy->current_chan_bw =717 HT_CHANNEL_WIDTH_20_40;718 mac->bw_40 = true;719 mac->bw_80 = false;720 721 /*wide channel */722 wide_chan -= 2;723 724 break;725 case NL80211_CHAN_HT40PLUS:726 /* SC */727 mac->cur_40_prime_sc =728 PRIME_CHNL_OFFSET_LOWER;729 rtlphy->current_chan_bw =730 HT_CHANNEL_WIDTH_20_40;731 mac->bw_40 = true;732 mac->bw_80 = false;733 734 /*wide channel */735 wide_chan += 2;736 737 break;738 default:739 mac->bw_40 = false;740 mac->bw_80 = false;741 pr_err("switch case %#x not processed\n",742 channel_type);743 break;744 }745 }746 747 if (wide_chan <= 0)748 wide_chan = 1;749 750 /* In scanning, when before we offchannel we may send a ps=1751 * null to AP, and then we may send a ps = 0 null to AP quickly,752 * but first null may have caused AP to put lots of packet to753 * hw tx buffer. These packets must be tx'd before we go off754 * channel so we must delay more time to let AP flush these755 * packets before going offchannel, or dis-association or756 * delete BA will be caused by AP757 */758 if (rtlpriv->mac80211.offchan_delay) {759 rtlpriv->mac80211.offchan_delay = false;760 mdelay(50);761 }762 763 rtlphy->current_channel = wide_chan;764 765 rtlpriv->cfg->ops->switch_channel(hw);766 rtlpriv->cfg->ops->set_channel_access(hw);767 rtlpriv->cfg->ops->set_bw_mode(hw, channel_type);768 }769 770 mutex_unlock(&rtlpriv->locks.conf_mutex);771 772 return 0;773}774 775static void rtl_op_configure_filter(struct ieee80211_hw *hw,776 unsigned int changed_flags,777 unsigned int *new_flags, u64 multicast)778{779 bool update_rcr = false;780 struct rtl_priv *rtlpriv = rtl_priv(hw);781 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));782 783 *new_flags &= RTL_SUPPORTED_FILTERS;784 if (0 == changed_flags)785 return;786 787 /*TODO: we disable broadcast now, so enable here */788 if (changed_flags & FIF_ALLMULTI) {789 if (*new_flags & FIF_ALLMULTI) {790 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |791 rtlpriv->cfg->maps[MAC_RCR_AB];792 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,793 "Enable receive multicast frame\n");794 } else {795 mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |796 rtlpriv->cfg->maps[MAC_RCR_AB]);797 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,798 "Disable receive multicast frame\n");799 }800 update_rcr = true;801 }802 803 if (changed_flags & FIF_FCSFAIL) {804 if (*new_flags & FIF_FCSFAIL) {805 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];806 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,807 "Enable receive FCS error frame\n");808 } else {809 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];810 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,811 "Disable receive FCS error frame\n");812 }813 if (!update_rcr)814 update_rcr = true;815 }816 817 /* if ssid not set to hw don't check bssid818 * here just used for linked scanning, & linked819 * and nolink check bssid is set in set network_type820 */821 if (changed_flags & FIF_BCN_PRBRESP_PROMISC &&822 mac->link_state >= MAC80211_LINKED) {823 if (mac->opmode != NL80211_IFTYPE_AP &&824 mac->opmode != NL80211_IFTYPE_MESH_POINT) {825 if (*new_flags & FIF_BCN_PRBRESP_PROMISC)826 rtlpriv->cfg->ops->set_chk_bssid(hw, false);827 else828 rtlpriv->cfg->ops->set_chk_bssid(hw, true);829 if (update_rcr)830 update_rcr = false;831 }832 }833 834 if (changed_flags & FIF_CONTROL) {835 if (*new_flags & FIF_CONTROL) {836 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];837 838 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,839 "Enable receive control frame.\n");840 } else {841 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];842 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,843 "Disable receive control frame.\n");844 }845 if (!update_rcr)846 update_rcr = true;847 }848 849 if (changed_flags & FIF_OTHER_BSS) {850 if (*new_flags & FIF_OTHER_BSS) {851 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];852 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,853 "Enable receive other BSS's frame.\n");854 } else {855 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];856 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,857 "Disable receive other BSS's frame.\n");858 }859 if (!update_rcr)860 update_rcr = true;861 }862 863 if (update_rcr)864 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,865 (u8 *)(&mac->rx_conf));866}867 868static int rtl_op_sta_add(struct ieee80211_hw *hw,869 struct ieee80211_vif *vif,870 struct ieee80211_sta *sta)871{872 struct rtl_priv *rtlpriv = rtl_priv(hw);873 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));874 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));875 struct rtl_sta_info *sta_entry;876 877 if (sta) {878 sta_entry = (struct rtl_sta_info *)sta->drv_priv;879 spin_lock_bh(&rtlpriv->locks.entry_list_lock);880 list_add_tail(&sta_entry->list, &rtlpriv->entry_list);881 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);882 if (rtlhal->current_bandtype == BAND_ON_2_4G) {883 sta_entry->wireless_mode = WIRELESS_MODE_G;884 if (sta->deflink.supp_rates[0] <= 0xf)885 sta_entry->wireless_mode = WIRELESS_MODE_B;886 if (sta->deflink.ht_cap.ht_supported)887 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;888 889 if (vif->type == NL80211_IFTYPE_ADHOC)890 sta_entry->wireless_mode = WIRELESS_MODE_G;891 } else if (rtlhal->current_bandtype == BAND_ON_5G) {892 sta_entry->wireless_mode = WIRELESS_MODE_A;893 if (sta->deflink.ht_cap.ht_supported)894 sta_entry->wireless_mode = WIRELESS_MODE_N_5G;895 if (sta->deflink.vht_cap.vht_supported)896 sta_entry->wireless_mode = WIRELESS_MODE_AC_5G;897 898 if (vif->type == NL80211_IFTYPE_ADHOC)899 sta_entry->wireless_mode = WIRELESS_MODE_A;900 }901 /*disable cck rate for p2p*/902 if (mac->p2p)903 sta->deflink.supp_rates[0] &= 0xfffffff0;904 905 memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);906 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,907 "Add sta addr is %pM\n", sta->addr);908 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true);909 }910 911 return 0;912}913 914static int rtl_op_sta_remove(struct ieee80211_hw *hw,915 struct ieee80211_vif *vif,916 struct ieee80211_sta *sta)917{918 struct rtl_priv *rtlpriv = rtl_priv(hw);919 struct rtl_sta_info *sta_entry;920 921 if (sta) {922 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,923 "Remove sta addr is %pM\n", sta->addr);924 sta_entry = (struct rtl_sta_info *)sta->drv_priv;925 sta_entry->wireless_mode = 0;926 sta_entry->ratr_index = 0;927 spin_lock_bh(&rtlpriv->locks.entry_list_lock);928 list_del(&sta_entry->list);929 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);930 }931 return 0;932}933 934static int _rtl_get_hal_qnum(u16 queue)935{936 int qnum;937 938 switch (queue) {939 case 0:940 qnum = AC3_VO;941 break;942 case 1:943 qnum = AC2_VI;944 break;945 case 2:946 qnum = AC0_BE;947 break;948 case 3:949 qnum = AC1_BK;950 break;951 default:952 qnum = AC0_BE;953 break;954 }955 return qnum;956}957 958/*959 *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3960 *for rtl819x BE = 0, BK = 1, VI = 2, VO = 3961 */962static int rtl_op_conf_tx(struct ieee80211_hw *hw,963 struct ieee80211_vif *vif,964 unsigned int link_id, u16 queue,965 const struct ieee80211_tx_queue_params *param)966{967 struct rtl_priv *rtlpriv = rtl_priv(hw);968 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));969 int aci;970 971 if (queue >= AC_MAX) {972 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,973 "queue number %d is incorrect!\n", queue);974 return -EINVAL;975 }976 977 aci = _rtl_get_hal_qnum(queue);978 mac->ac[aci].aifs = param->aifs;979 mac->ac[aci].cw_min = cpu_to_le16(param->cw_min);980 mac->ac[aci].cw_max = cpu_to_le16(param->cw_max);981 mac->ac[aci].tx_op = cpu_to_le16(param->txop);982 memcpy(&mac->edca_param[aci], param, sizeof(*param));983 rtlpriv->cfg->ops->set_qos(hw, aci);984 return 0;985}986 987static void send_beacon_frame(struct ieee80211_hw *hw,988 struct ieee80211_vif *vif)989{990 struct rtl_priv *rtlpriv = rtl_priv(hw);991 struct sk_buff *skb = ieee80211_beacon_get(hw, vif, 0);992 struct rtl_tcb_desc tcb_desc;993 994 if (skb) {995 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));996 rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc);997 }998}999 1000void rtl_update_beacon_work_callback(struct work_struct *work)1001{1002 struct rtl_works *rtlworks =1003 container_of(work, struct rtl_works, update_beacon_work);1004 struct ieee80211_hw *hw = rtlworks->hw;1005 struct rtl_priv *rtlpriv = rtl_priv(hw);1006 struct ieee80211_vif *vif = rtlpriv->mac80211.vif;1007 1008 if (!vif) {1009 WARN_ONCE(true, "no vif to update beacon\n");1010 return;1011 }1012 1013 mutex_lock(&rtlpriv->locks.conf_mutex);1014 send_beacon_frame(hw, vif);1015 mutex_unlock(&rtlpriv->locks.conf_mutex);1016}1017EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback);1018 1019static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,1020 struct ieee80211_vif *vif,1021 struct ieee80211_bss_conf *bss_conf,1022 u64 changed)1023{1024 struct rtl_priv *rtlpriv = rtl_priv(hw);1025 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);1026 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1027 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));1028 1029 mutex_lock(&rtlpriv->locks.conf_mutex);1030 if (vif->type == NL80211_IFTYPE_ADHOC ||1031 vif->type == NL80211_IFTYPE_AP ||1032 vif->type == NL80211_IFTYPE_MESH_POINT) {1033 if (changed & BSS_CHANGED_BEACON ||1034 (changed & BSS_CHANGED_BEACON_ENABLED &&1035 bss_conf->enable_beacon)) {1036 if (mac->beacon_enabled == 0) {1037 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1038 "BSS_CHANGED_BEACON_ENABLED\n");1039 1040 /*start hw beacon interrupt. */1041 /*rtlpriv->cfg->ops->set_bcn_reg(hw); */1042 mac->beacon_enabled = 1;1043 rtlpriv->cfg->ops->update_interrupt_mask(hw,1044 rtlpriv->cfg->maps1045 [RTL_IBSS_INT_MASKS], 0);1046 1047 if (rtlpriv->cfg->ops->linked_set_reg)1048 rtlpriv->cfg->ops->linked_set_reg(hw);1049 send_beacon_frame(hw, vif);1050 }1051 }1052 if ((changed & BSS_CHANGED_BEACON_ENABLED &&1053 !bss_conf->enable_beacon)) {1054 if (mac->beacon_enabled == 1) {1055 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1056 "ADHOC DISABLE BEACON\n");1057 1058 mac->beacon_enabled = 0;1059 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,1060 rtlpriv->cfg->maps1061 [RTL_IBSS_INT_MASKS]);1062 }1063 }1064 if (changed & BSS_CHANGED_BEACON_INT) {1065 rtl_dbg(rtlpriv, COMP_BEACON, DBG_TRACE,1066 "BSS_CHANGED_BEACON_INT\n");1067 mac->beacon_interval = bss_conf->beacon_int;1068 rtlpriv->cfg->ops->set_bcn_intv(hw);1069 }1070 }1071 1072 /*TODO: reference to enum ieee80211_bss_change */1073 if (changed & BSS_CHANGED_ASSOC) {1074 u8 mstatus;1075 1076 if (vif->cfg.assoc) {1077 struct ieee80211_sta *sta = NULL;1078 u8 keep_alive = 10;1079 1080 mstatus = RT_MEDIA_CONNECT;1081 /* we should reset all sec info & cam1082 * before set cam after linked, we should not1083 * reset in disassoc, that will cause tkip->wep1084 * fail because some flag will be wrong */1085 /* reset sec info */1086 rtl_cam_reset_sec_info(hw);1087 /* reset cam to fix wep fail issue1088 * when change from wpa to wep */1089 rtl_cam_reset_all_entry(hw);1090 1091 mac->link_state = MAC80211_LINKED;1092 mac->cnt_after_linked = 0;1093 mac->assoc_id = vif->cfg.aid;1094 memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);1095 1096 if (rtlpriv->cfg->ops->linked_set_reg)1097 rtlpriv->cfg->ops->linked_set_reg(hw);1098 1099 rcu_read_lock();1100 sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);1101 if (!sta) {1102 rcu_read_unlock();1103 goto out;1104 }1105 rtl_dbg(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD,1106 "send PS STATIC frame\n");1107 if (rtlpriv->dm.supp_phymode_switch) {1108 if (sta->deflink.ht_cap.ht_supported)1109 rtl_send_smps_action(hw, sta,1110 IEEE80211_SMPS_STATIC);1111 }1112 1113 if (rtlhal->current_bandtype == BAND_ON_5G) {1114 mac->mode = WIRELESS_MODE_A;1115 } else {1116 if (sta->deflink.supp_rates[0] <= 0xf)1117 mac->mode = WIRELESS_MODE_B;1118 else1119 mac->mode = WIRELESS_MODE_G;1120 }1121 1122 if (sta->deflink.ht_cap.ht_supported) {1123 if (rtlhal->current_bandtype == BAND_ON_2_4G)1124 mac->mode = WIRELESS_MODE_N_24G;1125 else1126 mac->mode = WIRELESS_MODE_N_5G;1127 }1128 1129 if (sta->deflink.vht_cap.vht_supported) {1130 if (rtlhal->current_bandtype == BAND_ON_5G)1131 mac->mode = WIRELESS_MODE_AC_5G;1132 else1133 mac->mode = WIRELESS_MODE_AC_24G;1134 }1135 1136 if (vif->type == NL80211_IFTYPE_STATION)1137 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0,1138 true);1139 rcu_read_unlock();1140 1141 /* to avoid AP Disassociation caused by inactivity */1142 rtlpriv->cfg->ops->set_hw_reg(hw,1143 HW_VAR_KEEP_ALIVE,1144 (u8 *)(&keep_alive));1145 1146 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1147 "BSS_CHANGED_ASSOC\n");1148 } else {1149 struct cfg80211_bss *bss = NULL;1150 1151 mstatus = RT_MEDIA_DISCONNECT;1152 1153 if (mac->link_state == MAC80211_LINKED)1154 rtl_lps_leave(hw, true);1155 if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)1156 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);1157 mac->link_state = MAC80211_NOLINK;1158 1159 bss = cfg80211_get_bss(hw->wiphy, NULL,1160 (u8 *)mac->bssid, NULL, 0,1161 IEEE80211_BSS_TYPE_ESS,1162 IEEE80211_PRIVACY_OFF);1163 1164 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1165 "bssid = %pMF\n", mac->bssid);1166 1167 if (bss) {1168 cfg80211_unlink_bss(hw->wiphy, bss);1169 cfg80211_put_bss(hw->wiphy, bss);1170 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1171 "cfg80211_unlink !!\n");1172 }1173 1174 eth_zero_addr(mac->bssid);1175 mac->vendor = PEER_UNKNOWN;1176 mac->mode = 0;1177 1178 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1179 "BSS_CHANGED_UN_ASSOC\n");1180 }1181 rtlpriv->cfg->ops->set_network_type(hw, vif->type);1182 /* For FW LPS:1183 * To tell firmware we have connected or disconnected1184 */1185 rtlpriv->cfg->ops->set_hw_reg(hw,1186 HW_VAR_H2C_FW_JOINBSSRPT,1187 (u8 *)(&mstatus));1188 ppsc->report_linked = (mstatus == RT_MEDIA_CONNECT) ?1189 true : false;1190 1191 if (rtlpriv->cfg->ops->get_btc_status())1192 rtlpriv->btcoexist.btc_ops->btc_mediastatus_notify(1193 rtlpriv, mstatus);1194 }1195 1196 if (changed & BSS_CHANGED_ERP_CTS_PROT) {1197 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1198 "BSS_CHANGED_ERP_CTS_PROT\n");1199 mac->use_cts_protect = bss_conf->use_cts_prot;1200 }1201 1202 if (changed & BSS_CHANGED_ERP_PREAMBLE) {1203 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD,1204 "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",1205 bss_conf->use_short_preamble);1206 1207 mac->short_preamble = bss_conf->use_short_preamble;1208 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,1209 (u8 *)(&mac->short_preamble));1210 }1211 1212 if (changed & BSS_CHANGED_ERP_SLOT) {1213 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1214 "BSS_CHANGED_ERP_SLOT\n");1215 1216 if (bss_conf->use_short_slot)1217 mac->slot_time = RTL_SLOT_TIME_9;1218 else1219 mac->slot_time = RTL_SLOT_TIME_20;1220 1221 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,1222 (u8 *)(&mac->slot_time));1223 }1224 1225 if (changed & BSS_CHANGED_HT) {1226 struct ieee80211_sta *sta = NULL;1227 1228 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1229 "BSS_CHANGED_HT\n");1230 1231 rcu_read_lock();1232 sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);1233 if (sta) {1234 if (sta->deflink.ht_cap.ampdu_density >1235 mac->current_ampdu_density)1236 mac->current_ampdu_density =1237 sta->deflink.ht_cap.ampdu_density;1238 if (sta->deflink.ht_cap.ampdu_factor <1239 mac->current_ampdu_factor)1240 mac->current_ampdu_factor =1241 sta->deflink.ht_cap.ampdu_factor;1242 }1243 rcu_read_unlock();1244 1245 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,1246 (u8 *)(&mac->max_mss_density));1247 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,1248 &mac->current_ampdu_factor);1249 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,1250 &mac->current_ampdu_density);1251 }1252 1253 if (changed & BSS_CHANGED_BSSID) {1254 u32 basic_rates;1255 struct ieee80211_sta *sta = NULL;1256 1257 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,1258 (u8 *)bss_conf->bssid);1259 1260 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG,1261 "bssid: %pM\n", bss_conf->bssid);1262 1263 mac->vendor = PEER_UNKNOWN;1264 memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);1265 1266 rcu_read_lock();1267 sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);1268 if (!sta) {1269 rcu_read_unlock();1270 goto out;1271 }1272 1273 if (rtlhal->current_bandtype == BAND_ON_5G) {1274 mac->mode = WIRELESS_MODE_A;1275 } else {1276 if (sta->deflink.supp_rates[0] <= 0xf)1277 mac->mode = WIRELESS_MODE_B;1278 else1279 mac->mode = WIRELESS_MODE_G;1280 }1281 1282 if (sta->deflink.ht_cap.ht_supported) {1283 if (rtlhal->current_bandtype == BAND_ON_2_4G)1284 mac->mode = WIRELESS_MODE_N_24G;1285 else1286 mac->mode = WIRELESS_MODE_N_5G;1287 }1288 1289 if (sta->deflink.vht_cap.vht_supported) {1290 if (rtlhal->current_bandtype == BAND_ON_5G)1291 mac->mode = WIRELESS_MODE_AC_5G;1292 else1293 mac->mode = WIRELESS_MODE_AC_24G;1294 }1295 1296 /* just station need it, because ibss & ap mode will1297 * set in sta_add, and will be NULL here */1298 if (vif->type == NL80211_IFTYPE_STATION) {1299 struct rtl_sta_info *sta_entry;1300 1301 sta_entry = (struct rtl_sta_info *)sta->drv_priv;1302 sta_entry->wireless_mode = mac->mode;1303 }1304 1305 if (sta->deflink.ht_cap.ht_supported) {1306 mac->ht_enable = true;1307 1308 /*1309 * for cisco 1252 bw20 it's wrong1310 * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {1311 * mac->bw_40 = true;1312 * }1313 * */1314 }1315 1316 if (sta->deflink.vht_cap.vht_supported)1317 mac->vht_enable = true;1318 1319 if (changed & BSS_CHANGED_BASIC_RATES) {1320 /* for 5G must << RATE_6M_INDEX = 4,1321 * because 5G have no cck rate*/1322 if (rtlhal->current_bandtype == BAND_ON_5G)1323 basic_rates = sta->deflink.supp_rates[1] << 4;1324 else1325 basic_rates = sta->deflink.supp_rates[0];1326 1327 mac->basic_rates = basic_rates;1328 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,1329 (u8 *)(&basic_rates));1330 }1331 rcu_read_unlock();1332 }1333out:1334 mutex_unlock(&rtlpriv->locks.conf_mutex);1335}1336 1337static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)1338{1339 struct rtl_priv *rtlpriv = rtl_priv(hw);1340 u64 tsf;1341 1342 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *)(&tsf));1343 return tsf;1344}1345 1346static void rtl_op_set_tsf(struct ieee80211_hw *hw,1347 struct ieee80211_vif *vif, u64 tsf)1348{1349 struct rtl_priv *rtlpriv = rtl_priv(hw);1350 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1351 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;1352 1353 mac->tsf = tsf;1354 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *)(&bibss));1355}1356 1357static void rtl_op_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)1358{1359 struct rtl_priv *rtlpriv = rtl_priv(hw);1360 u8 tmp = 0;1361 1362 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *)(&tmp));1363}1364 1365static void rtl_op_sta_notify(struct ieee80211_hw *hw,1366 struct ieee80211_vif *vif,1367 enum sta_notify_cmd cmd,1368 struct ieee80211_sta *sta)1369{1370 switch (cmd) {1371 case STA_NOTIFY_SLEEP:1372 break;1373 case STA_NOTIFY_AWAKE:1374 break;1375 default:1376 break;1377 }1378}1379 1380static int rtl_op_ampdu_action(struct ieee80211_hw *hw,1381 struct ieee80211_vif *vif,1382 struct ieee80211_ampdu_params *params)1383{1384 struct rtl_priv *rtlpriv = rtl_priv(hw);1385 struct ieee80211_sta *sta = params->sta;1386 enum ieee80211_ampdu_mlme_action action = params->action;1387 u16 tid = params->tid;1388 u16 *ssn = ¶ms->ssn;1389 1390 switch (action) {1391 case IEEE80211_AMPDU_TX_START:1392 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1393 "IEEE80211_AMPDU_TX_START: TID:%d\n", tid);1394 return rtl_tx_agg_start(hw, vif, sta, tid, ssn);1395 case IEEE80211_AMPDU_TX_STOP_CONT:1396 case IEEE80211_AMPDU_TX_STOP_FLUSH:1397 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:1398 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1399 "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid);1400 return rtl_tx_agg_stop(hw, vif, sta, tid);1401 case IEEE80211_AMPDU_TX_OPERATIONAL:1402 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1403 "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid);1404 rtl_tx_agg_oper(hw, sta, tid);1405 break;1406 case IEEE80211_AMPDU_RX_START:1407 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1408 "IEEE80211_AMPDU_RX_START:TID:%d\n", tid);1409 return rtl_rx_agg_start(hw, sta, tid);1410 case IEEE80211_AMPDU_RX_STOP:1411 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE,1412 "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);1413 return rtl_rx_agg_stop(hw, sta, tid);1414 default:1415 pr_err("IEEE80211_AMPDU_ERR!!!!:\n");1416 return -EOPNOTSUPP;1417 }1418 return 0;1419}1420 1421static void rtl_op_sw_scan_start(struct ieee80211_hw *hw,1422 struct ieee80211_vif *vif,1423 const u8 *mac_addr)1424{1425 struct rtl_priv *rtlpriv = rtl_priv(hw);1426 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1427 1428 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");1429 mac->act_scanning = true;1430 if (rtlpriv->link_info.higher_busytraffic) {1431 mac->skip_scan = true;1432 return;1433 }1434 1435 if (rtlpriv->cfg->ops->get_btc_status())1436 rtlpriv->btcoexist.btc_ops->btc_scan_notify(rtlpriv, 1);1437 else if (rtlpriv->btcoexist.btc_ops)1438 rtlpriv->btcoexist.btc_ops->btc_scan_notify_wifi_only(rtlpriv,1439 1);1440 1441 if (mac->link_state == MAC80211_LINKED) {1442 rtl_lps_leave(hw, true);1443 mac->link_state = MAC80211_LINKED_SCANNING;1444 } else {1445 rtl_ips_nic_on(hw);1446 }1447 1448 /* Dul mac */1449 rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;1450 1451 rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);1452 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0);1453}1454 1455static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw,1456 struct ieee80211_vif *vif)1457{1458 struct rtl_priv *rtlpriv = rtl_priv(hw);1459 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1460 1461 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");1462 mac->act_scanning = false;1463 mac->skip_scan = false;1464 1465 rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num;1466 1467 if (rtlpriv->link_info.higher_busytraffic)1468 return;1469 1470 /* p2p will use 1/6/11 to scan */1471 if (mac->n_channels == 3)1472 mac->p2p_in_use = true;1473 else1474 mac->p2p_in_use = false;1475 mac->n_channels = 0;1476 /* Dul mac */1477 rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;1478 1479 if (mac->link_state == MAC80211_LINKED_SCANNING) {1480 mac->link_state = MAC80211_LINKED;1481 if (mac->opmode == NL80211_IFTYPE_STATION) {1482 /* fix fwlps issue */1483 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);1484 }1485 }1486 1487 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);1488 if (rtlpriv->cfg->ops->get_btc_status())1489 rtlpriv->btcoexist.btc_ops->btc_scan_notify(rtlpriv, 0);1490 else if (rtlpriv->btcoexist.btc_ops)1491 rtlpriv->btcoexist.btc_ops->btc_scan_notify_wifi_only(rtlpriv,1492 0);1493}1494 1495static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,1496 struct ieee80211_vif *vif, struct ieee80211_sta *sta,1497 struct ieee80211_key_conf *key)1498{1499 struct rtl_priv *rtlpriv = rtl_priv(hw);1500 u8 key_type = NO_ENCRYPTION;1501 u8 key_idx;1502 bool group_key = false;1503 bool wep_only = false;1504 int err = 0;1505 u8 mac_addr[ETH_ALEN];1506 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };1507 1508 rtlpriv->btcoexist.btc_info.in_4way = false;1509 1510 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {1511 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,1512 "not open hw encryption\n");1513 return -ENOSPC; /*User disabled HW-crypto */1514 }1515 /* To support IBSS, use sw-crypto for GTK */1516 if ((vif->type == NL80211_IFTYPE_ADHOC ||1517 vif->type == NL80211_IFTYPE_MESH_POINT) &&1518 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))1519 return -ENOSPC;1520 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1521 "%s hardware based encryption for keyidx: %d, mac: %pM\n",1522 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,1523 sta ? sta->addr : bcast_addr);1524 rtlpriv->sec.being_setkey = true;1525 rtl_ips_nic_on(hw);1526 mutex_lock(&rtlpriv->locks.conf_mutex);1527 /* <1> get encryption alg */1528 1529 switch (key->cipher) {1530 case WLAN_CIPHER_SUITE_WEP40:1531 key_type = WEP40_ENCRYPTION;1532 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n");1533 break;1534 case WLAN_CIPHER_SUITE_WEP104:1535 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n");1536 key_type = WEP104_ENCRYPTION;1537 break;1538 case WLAN_CIPHER_SUITE_TKIP:1539 key_type = TKIP_ENCRYPTION;1540 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n");1541 break;1542 case WLAN_CIPHER_SUITE_CCMP:1543 key_type = AESCCMP_ENCRYPTION;1544 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n");1545 break;1546 case WLAN_CIPHER_SUITE_AES_CMAC:1547 /* HW don't support CMAC encryption,1548 * use software CMAC encryption1549 */1550 key_type = AESCMAC_ENCRYPTION;1551 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n");1552 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1553 "HW don't support CMAC encryption, use software CMAC encryption\n");1554 err = -EOPNOTSUPP;1555 goto out_unlock;1556 default:1557 pr_err("alg_err:%x!!!!:\n", key->cipher);1558 goto out_unlock;1559 }1560 if (key_type == WEP40_ENCRYPTION ||1561 key_type == WEP104_ENCRYPTION ||1562 vif->type == NL80211_IFTYPE_ADHOC)1563 rtlpriv->sec.use_defaultkey = true;1564 1565 /* <2> get key_idx */1566 key_idx = (u8) (key->keyidx);1567 if (key_idx > 3)1568 goto out_unlock;1569 /* <3> if pairwise key enable_hw_sec */1570 group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);1571 1572 /* wep always be group key, but there are two conditions:1573 * 1) wep only: is just for wep enc, in this condition1574 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION1575 * will be true & enable_hw_sec will be set when wep1576 * ke setting.1577 * 2) wep(group) + AES(pairwise): some AP like cisco1578 * may use it, in this condition enable_hw_sec will not1579 * be set when wep key setting */1580 /* we must reset sec_info after lingked before set key,1581 * or some flag will be wrong*/1582 if (vif->type == NL80211_IFTYPE_AP ||1583 vif->type == NL80211_IFTYPE_MESH_POINT) {1584 if (!group_key || key_type == WEP40_ENCRYPTION ||1585 key_type == WEP104_ENCRYPTION) {1586 if (group_key)1587 wep_only = true;1588 rtlpriv->cfg->ops->enable_hw_sec(hw);1589 }1590 } else {1591 if (!group_key || vif->type == NL80211_IFTYPE_ADHOC ||1592 rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {1593 if (rtlpriv->sec.pairwise_enc_algorithm ==1594 NO_ENCRYPTION &&1595 (key_type == WEP40_ENCRYPTION ||1596 key_type == WEP104_ENCRYPTION))1597 wep_only = true;1598 rtlpriv->sec.pairwise_enc_algorithm = key_type;1599 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1600 "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n",1601 key_type);1602 rtlpriv->cfg->ops->enable_hw_sec(hw);1603 }1604 }1605 /* <4> set key based on cmd */1606 switch (cmd) {1607 case SET_KEY:1608 if (wep_only) {1609 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1610 "set WEP(group/pairwise) key\n");1611 /* Pairwise key with an assigned MAC address. */1612 rtlpriv->sec.pairwise_enc_algorithm = key_type;1613 rtlpriv->sec.group_enc_algorithm = key_type;1614 /*set local buf about wep key. */1615 memcpy(rtlpriv->sec.key_buf[key_idx],1616 key->key, key->keylen);1617 rtlpriv->sec.key_len[key_idx] = key->keylen;1618 eth_zero_addr(mac_addr);1619 } else if (group_key) { /* group key */1620 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1621 "set group key\n");1622 /* group key */1623 rtlpriv->sec.group_enc_algorithm = key_type;1624 /*set local buf about group key. */1625 memcpy(rtlpriv->sec.key_buf[key_idx],1626 key->key, key->keylen);1627 rtlpriv->sec.key_len[key_idx] = key->keylen;1628 eth_broadcast_addr(mac_addr);1629 } else { /* pairwise key */1630 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1631 "set pairwise key\n");1632 if (!sta) {1633 WARN_ONCE(true,1634 "rtlwifi: pairwise key without mac_addr\n");1635 1636 err = -EOPNOTSUPP;1637 goto out_unlock;1638 }1639 /* Pairwise key with an assigned MAC address. */1640 rtlpriv->sec.pairwise_enc_algorithm = key_type;1641 /*set local buf about pairwise key. */1642 memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],1643 key->key, key->keylen);1644 rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;1645 rtlpriv->sec.pairwise_key =1646 rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];1647 memcpy(mac_addr, sta->addr, ETH_ALEN);1648 }1649 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,1650 group_key, key_type, wep_only,1651 false);1652 /* <5> tell mac80211 do something: */1653 /*must use sw generate IV, or can not work !!!!. */1654 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;1655 key->hw_key_idx = key_idx;1656 if (key_type == TKIP_ENCRYPTION)1657 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;1658 /*use software CCMP encryption for management frames (MFP) */1659 if (key_type == AESCCMP_ENCRYPTION)1660 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;1661 break;1662 case DISABLE_KEY:1663 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1664 "disable key delete one entry\n");1665 /*set local buf about wep key. */1666 if (vif->type == NL80211_IFTYPE_AP ||1667 vif->type == NL80211_IFTYPE_MESH_POINT) {1668 if (sta)1669 rtl_cam_del_entry(hw, sta->addr);1670 }1671 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);1672 rtlpriv->sec.key_len[key_idx] = 0;1673 eth_zero_addr(mac_addr);1674 /*1675 *mac80211 will delete entries one by one,1676 *so don't use rtl_cam_reset_all_entry1677 *or clear all entry here.1678 */1679 rtl_wait_tx_report_acked(hw, 500); /* wait 500ms for TX ack */1680 1681 rtl_cam_delete_one_entry(hw, mac_addr, key_idx);1682 break;1683 default:1684 pr_err("cmd_err:%x!!!!:\n", cmd);1685 }1686out_unlock:1687 mutex_unlock(&rtlpriv->locks.conf_mutex);1688 rtlpriv->sec.being_setkey = false;1689 return err;1690}1691 1692static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)1693{1694 struct rtl_priv *rtlpriv = rtl_priv(hw);1695 1696 bool radio_state;1697 bool blocked;1698 u8 valid = 0;1699 1700 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))1701 return;1702 1703 mutex_lock(&rtlpriv->locks.conf_mutex);1704 1705 /*if Radio On return true here */1706 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);1707 1708 if (valid) {1709 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {1710 rtlpriv->rfkill.rfkill_state = radio_state;1711 1712 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1713 "wireless radio switch turned %s\n",1714 radio_state ? "on" : "off");1715 1716 blocked = !rtlpriv->rfkill.rfkill_state;1717 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);1718 }1719 }1720 1721 mutex_unlock(&rtlpriv->locks.conf_mutex);1722}1723 1724/* this function is called by mac80211 to flush tx buffer1725 * before switch channle or power save, or tx buffer packet1726 * maybe send after offchannel or rf sleep, this may cause1727 * dis-association by AP */1728static void rtl_op_flush(struct ieee80211_hw *hw,1729 struct ieee80211_vif *vif,1730 u32 queues,1731 bool drop)1732{1733 struct rtl_priv *rtlpriv = rtl_priv(hw);1734 1735 if (rtlpriv->intf_ops->flush)1736 rtlpriv->intf_ops->flush(hw, queues, drop);1737}1738 1739static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,1740 bool set)1741{1742 struct rtl_priv *rtlpriv = rtl_priv(hw);1743 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));1744 1745 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU)1746 schedule_work(&rtlpriv->works.update_beacon_work);1747 1748 return 0;1749}1750 1751/* Description:1752 * This routine deals with the Power Configuration CMD1753 * parsing for RTL8723/RTL8188E Series IC.1754 * Assumption:1755 * We should follow specific format that was released from HW SD.1756 */1757bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,1758 u8 faversion, u8 interface_type,1759 struct wlan_pwr_cfg pwrcfgcmd[])1760{1761 struct wlan_pwr_cfg cfg_cmd;1762 bool polling_bit = false;1763 u32 ary_idx = 0;1764 u8 value = 0;1765 u32 offset = 0;1766 u32 polling_count = 0;1767 u32 max_polling_cnt = 5000;1768 1769 do {1770 cfg_cmd = pwrcfgcmd[ary_idx];1771 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,1772 "%s: offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",1773 __func__,1774 GET_PWR_CFG_OFFSET(cfg_cmd),1775 GET_PWR_CFG_CUT_MASK(cfg_cmd),1776 GET_PWR_CFG_FAB_MASK(cfg_cmd),1777 GET_PWR_CFG_INTF_MASK(cfg_cmd),1778 GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd),1779 GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd));1780 1781 if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) &&1782 (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) &&1783 (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) {1784 switch (GET_PWR_CFG_CMD(cfg_cmd)) {1785 case PWR_CMD_READ:1786 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,1787 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");1788 break;1789 case PWR_CMD_WRITE:1790 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,1791 "%s(): PWR_CMD_WRITE\n", __func__);1792 offset = GET_PWR_CFG_OFFSET(cfg_cmd);1793 1794 /*Read the value from system register*/1795 value = rtl_read_byte(rtlpriv, offset);1796 value &= (~(GET_PWR_CFG_MASK(cfg_cmd)));1797 value |= (GET_PWR_CFG_VALUE(cfg_cmd) &1798 GET_PWR_CFG_MASK(cfg_cmd));1799 1800 /*Write the value back to system register*/1801 rtl_write_byte(rtlpriv, offset, value);1802 break;1803 case PWR_CMD_POLLING:1804 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,1805 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");1806 polling_bit = false;1807 offset = GET_PWR_CFG_OFFSET(cfg_cmd);1808 1809 do {1810 value = rtl_read_byte(rtlpriv, offset);1811 1812 value &= GET_PWR_CFG_MASK(cfg_cmd);1813 if (value ==1814 (GET_PWR_CFG_VALUE(cfg_cmd) &1815 GET_PWR_CFG_MASK(cfg_cmd)))1816 polling_bit = true;1817 else1818 udelay(10);1819 1820 if (polling_count++ > max_polling_cnt)1821 return false;1822 } while (!polling_bit);1823 break;1824 case PWR_CMD_DELAY:1825 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,1826 "%s: PWR_CMD_DELAY\n", __func__);1827 if (GET_PWR_CFG_VALUE(cfg_cmd) ==1828 PWRSEQ_DELAY_US)1829 udelay(GET_PWR_CFG_OFFSET(cfg_cmd));1830 else1831 mdelay(GET_PWR_CFG_OFFSET(cfg_cmd));1832 break;1833 case PWR_CMD_END:1834 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,1835 "%s: PWR_CMD_END\n", __func__);1836 return true;1837 default:1838 WARN_ONCE(true,1839 "rtlwifi: rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");1840 break;1841 }1842 }1843 ary_idx++;1844 } while (1);1845 1846 return true;1847}1848EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing);1849 1850bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)1851{1852 struct rtl_priv *rtlpriv = rtl_priv(hw);1853 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));1854 struct rtl8192_tx_ring *ring;1855 struct rtl_tx_desc *pdesc;1856 unsigned long flags;1857 struct sk_buff *pskb = NULL;1858 1859 ring = &rtlpci->tx_ring[BEACON_QUEUE];1860 1861 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);1862 pskb = __skb_dequeue(&ring->queue);1863 if (pskb)1864 dev_kfree_skb_irq(pskb);1865 1866 /*this is wrong, fill_tx_cmddesc needs update*/1867 pdesc = &ring->desc[0];1868 1869 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, skb);1870 1871 __skb_queue_tail(&ring->queue, skb);1872 1873 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);1874 1875 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);1876 1877 return true;1878}1879EXPORT_SYMBOL(rtl_cmd_send_packet);1880 1881void rtl_init_sw_leds(struct ieee80211_hw *hw)1882{1883 struct rtl_priv *rtlpriv = rtl_priv(hw);1884 1885 rtlpriv->ledctl.sw_led0 = LED_PIN_LED0;1886 rtlpriv->ledctl.sw_led1 = LED_PIN_LED1;1887}1888EXPORT_SYMBOL(rtl_init_sw_leds);1889 1890const struct ieee80211_ops rtl_ops = {1891 .add_chanctx = ieee80211_emulate_add_chanctx,1892 .remove_chanctx = ieee80211_emulate_remove_chanctx,1893 .change_chanctx = ieee80211_emulate_change_chanctx,1894 .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,1895 .start = rtl_op_start,1896 .stop = rtl_op_stop,1897 .tx = rtl_op_tx,1898 .wake_tx_queue = ieee80211_handle_wake_tx_queue,1899 .add_interface = rtl_op_add_interface,1900 .remove_interface = rtl_op_remove_interface,1901 .change_interface = rtl_op_change_interface,1902#ifdef CONFIG_PM1903 .suspend = rtl_op_suspend,1904 .resume = rtl_op_resume,1905#endif1906 .config = rtl_op_config,1907 .configure_filter = rtl_op_configure_filter,1908 .set_key = rtl_op_set_key,1909 .conf_tx = rtl_op_conf_tx,1910 .bss_info_changed = rtl_op_bss_info_changed,1911 .get_tsf = rtl_op_get_tsf,1912 .set_tsf = rtl_op_set_tsf,1913 .reset_tsf = rtl_op_reset_tsf,1914 .sta_notify = rtl_op_sta_notify,1915 .ampdu_action = rtl_op_ampdu_action,1916 .sw_scan_start = rtl_op_sw_scan_start,1917 .sw_scan_complete = rtl_op_sw_scan_complete,1918 .rfkill_poll = rtl_op_rfkill_poll,1919 .sta_add = rtl_op_sta_add,1920 .sta_remove = rtl_op_sta_remove,1921 .flush = rtl_op_flush,1922 .set_tim = rtl_op_set_tim,1923};1924EXPORT_SYMBOL_GPL(rtl_ops);1925 1926bool rtl_btc_status_false(void)1927{1928 return false;1929}1930EXPORT_SYMBOL_GPL(rtl_btc_status_false);1931 1932void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igvalue)1933{1934 struct rtl_priv *rtlpriv = rtl_priv(hw);1935 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;1936 1937 dm_digtable->dig_enable_flag = true;1938 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;1939 dm_digtable->cur_igvalue = cur_igvalue;1940 dm_digtable->pre_igvalue = 0;1941 dm_digtable->cur_sta_cstate = DIG_STA_DISCONNECT;1942 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;1943 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;1944 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;1945 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;1946 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;1947 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;1948 dm_digtable->rx_gain_max = DM_DIG_MAX;1949 dm_digtable->rx_gain_min = DM_DIG_MIN;1950 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;1951 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;1952 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;1953 dm_digtable->pre_cck_cca_thres = 0xff;1954 dm_digtable->cur_cck_cca_thres = 0x83;1955 dm_digtable->forbidden_igi = DM_DIG_MIN;1956 dm_digtable->large_fa_hit = 0;1957 dm_digtable->recover_cnt = 0;1958 dm_digtable->dig_min_0 = 0x25;1959 dm_digtable->dig_min_1 = 0x25;1960 dm_digtable->media_connect_0 = false;1961 dm_digtable->media_connect_1 = false;1962 rtlpriv->dm.dm_initialgain_enable = true;1963 dm_digtable->bt30_cur_igi = 0x32;1964 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;1965 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;1966 dm_digtable->pre_cck_fa_state = 0;1967 dm_digtable->cur_cck_fa_state = 0;1968}1969EXPORT_SYMBOL(rtl_dm_diginit);1970