1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
14 #include "mp_precomp.h"
15 #include "phydm_precomp.h"
16 #include <linux/module.h>
18 static int _rtl_phydm_init_com_info(struct rtl_priv
*rtlpriv
,
19 enum odm_ic_type ic_type
,
20 struct rtl_phydm_params
*params
)
22 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
23 struct rtl_hal
*rtlhal
= rtl_hal(rtlpriv
);
24 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
25 struct rtl_mac
*mac
= rtl_mac(rtlpriv
);
26 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtlpriv
);
27 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtlpriv
);
28 u8 odm_board_type
= ODM_BOARD_DEFAULT
;
32 dm
->adapter
= (void *)rtlpriv
;
34 odm_cmn_info_init(dm
, ODM_CMNINFO_PLATFORM
, ODM_CE
);
36 odm_cmn_info_init(dm
, ODM_CMNINFO_IC_TYPE
, ic_type
);
38 odm_cmn_info_init(dm
, ODM_CMNINFO_INTERFACE
, ODM_ITRF_PCIE
);
40 odm_cmn_info_init(dm
, ODM_CMNINFO_MP_TEST_CHIP
, params
->mp_chip
);
42 odm_cmn_info_init(dm
, ODM_CMNINFO_PATCH_ID
, rtlhal
->oem_id
);
44 odm_cmn_info_init(dm
, ODM_CMNINFO_BWIFI_TEST
, 1);
46 if (rtlphy
->rf_type
== RF_1T1R
)
47 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_1T1R
);
48 else if (rtlphy
->rf_type
== RF_1T2R
)
49 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_1T2R
);
50 else if (rtlphy
->rf_type
== RF_2T2R
)
51 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_2T2R
);
52 else if (rtlphy
->rf_type
== RF_2T2R_GREEN
)
53 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_2T2R_GREEN
);
54 else if (rtlphy
->rf_type
== RF_2T3R
)
55 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_2T3R
);
56 else if (rtlphy
->rf_type
== RF_2T4R
)
57 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_2T4R
);
58 else if (rtlphy
->rf_type
== RF_3T3R
)
59 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_3T3R
);
60 else if (rtlphy
->rf_type
== RF_3T4R
)
61 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_3T4R
);
62 else if (rtlphy
->rf_type
== RF_4T4R
)
63 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_4T4R
);
65 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_TYPE
, ODM_XTXR
);
67 /* 1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= */
68 if (rtlhal
->external_lna_2g
!= 0) {
69 odm_board_type
|= ODM_BOARD_EXT_LNA
;
70 odm_cmn_info_init(dm
, ODM_CMNINFO_EXT_LNA
, 1);
72 if (rtlhal
->external_lna_5g
!= 0) {
73 odm_board_type
|= ODM_BOARD_EXT_LNA_5G
;
74 odm_cmn_info_init(dm
, ODM_CMNINFO_5G_EXT_LNA
, 1);
76 if (rtlhal
->external_pa_2g
!= 0) {
77 odm_board_type
|= ODM_BOARD_EXT_PA
;
78 odm_cmn_info_init(dm
, ODM_CMNINFO_EXT_PA
, 1);
80 if (rtlhal
->external_pa_5g
!= 0) {
81 odm_board_type
|= ODM_BOARD_EXT_PA_5G
;
82 odm_cmn_info_init(dm
, ODM_CMNINFO_5G_EXT_PA
, 1);
84 if (rtlpriv
->cfg
->ops
->get_btc_status())
85 odm_board_type
|= ODM_BOARD_BT
;
87 odm_cmn_info_init(dm
, ODM_CMNINFO_BOARD_TYPE
, odm_board_type
);
88 /* 1 ============== End of BoardType ============== */
90 odm_cmn_info_init(dm
, ODM_CMNINFO_GPA
, rtlhal
->type_gpa
);
91 odm_cmn_info_init(dm
, ODM_CMNINFO_APA
, rtlhal
->type_apa
);
92 odm_cmn_info_init(dm
, ODM_CMNINFO_GLNA
, rtlhal
->type_glna
);
93 odm_cmn_info_init(dm
, ODM_CMNINFO_ALNA
, rtlhal
->type_alna
);
95 odm_cmn_info_init(dm
, ODM_CMNINFO_RFE_TYPE
, rtlhal
->rfe_type
);
97 odm_cmn_info_init(dm
, ODM_CMNINFO_EXT_TRSW
, 0);
99 /*Add by YuChen for kfree init*/
100 odm_cmn_info_init(dm
, ODM_CMNINFO_REGRFKFREEENABLE
, 2);
101 odm_cmn_info_init(dm
, ODM_CMNINFO_RFKFREEENABLE
, 0);
103 /*Antenna diversity relative parameters*/
104 odm_cmn_info_hook(dm
, ODM_CMNINFO_ANT_DIV
,
105 &rtlefuse
->antenna_div_cfg
);
106 odm_cmn_info_init(dm
, ODM_CMNINFO_RF_ANTENNA_TYPE
,
107 rtlefuse
->antenna_div_type
);
108 odm_cmn_info_init(dm
, ODM_CMNINFO_BE_FIX_TX_ANT
, 0);
109 odm_cmn_info_init(dm
, ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH
, 0);
111 /* (8822B) efuse 0x3D7 & 0x3D8 for TX PA bias */
112 odm_cmn_info_init(dm
, ODM_CMNINFO_EFUSE0X3D7
, params
->efuse0x3d7
);
113 odm_cmn_info_init(dm
, ODM_CMNINFO_EFUSE0X3D8
, params
->efuse0x3d8
);
115 /*Add by YuChen for adaptivity init*/
116 odm_cmn_info_hook(dm
, ODM_CMNINFO_ADAPTIVITY
,
117 &rtlpriv
->phydm
.adaptivity_en
);
118 phydm_adaptivity_info_init(dm
, PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE
,
120 phydm_adaptivity_info_init(dm
, PHYDM_ADAPINFO_DCBACKOFF
, 0);
121 phydm_adaptivity_info_init(dm
, PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY
,
123 phydm_adaptivity_info_init(dm
, PHYDM_ADAPINFO_TH_L2H_INI
, 0);
124 phydm_adaptivity_info_init(dm
, PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF
, 0);
126 odm_cmn_info_init(dm
, ODM_CMNINFO_IQKFWOFFLOAD
, 0);
128 /* Pointer reference */
129 odm_cmn_info_hook(dm
, ODM_CMNINFO_TX_UNI
,
130 &rtlpriv
->stats
.txbytesunicast
);
131 odm_cmn_info_hook(dm
, ODM_CMNINFO_RX_UNI
,
132 &rtlpriv
->stats
.rxbytesunicast
);
133 odm_cmn_info_hook(dm
, ODM_CMNINFO_BAND
, &rtlhal
->current_bandtype
);
134 odm_cmn_info_hook(dm
, ODM_CMNINFO_FORCED_RATE
,
135 &rtlpriv
->phydm
.forced_data_rate
);
136 odm_cmn_info_hook(dm
, ODM_CMNINFO_FORCED_IGI_LB
,
137 &rtlpriv
->phydm
.forced_igi_lb
);
139 odm_cmn_info_hook(dm
, ODM_CMNINFO_SEC_CHNL_OFFSET
,
140 &mac
->cur_40_prime_sc
);
141 odm_cmn_info_hook(dm
, ODM_CMNINFO_BW
, &rtlphy
->current_chan_bw
);
142 odm_cmn_info_hook(dm
, ODM_CMNINFO_CHNL
, &rtlphy
->current_channel
);
144 odm_cmn_info_hook(dm
, ODM_CMNINFO_SCAN
, &mac
->act_scanning
);
145 odm_cmn_info_hook(dm
, ODM_CMNINFO_POWER_SAVING
,
146 &ppsc
->dot11_psmode
); /* may add new boolean flag */
147 /*Add by Yuchen for phydm beamforming*/
148 odm_cmn_info_hook(dm
, ODM_CMNINFO_TX_TP
,
149 &rtlpriv
->stats
.txbytesunicast_inperiod_tp
);
150 odm_cmn_info_hook(dm
, ODM_CMNINFO_RX_TP
,
151 &rtlpriv
->stats
.rxbytesunicast_inperiod_tp
);
152 odm_cmn_info_hook(dm
, ODM_CMNINFO_ANT_TEST
,
153 &rtlpriv
->phydm
.antenna_test
);
154 for (i
= 0; i
< ODM_ASSOCIATE_ENTRY_NUM
; i
++)
155 odm_cmn_info_ptr_array_hook(dm
, ODM_CMNINFO_STA_STATUS
, i
,
158 phydm_init_debug_setting(dm
);
160 odm_cmn_info_init(dm
, ODM_CMNINFO_FAB_VER
, params
->fab_ver
);
161 odm_cmn_info_init(dm
, ODM_CMNINFO_CUT_VER
, params
->cut_ver
);
163 /* after ifup, ability is updated again */
164 support_ability
= ODM_RF_CALIBRATION
| ODM_RF_TX_PWR_TRACK
;
165 odm_cmn_info_update(dm
, ODM_CMNINFO_ABILITY
, support_ability
);
170 static int rtl_phydm_init_priv(struct rtl_priv
*rtlpriv
,
171 struct rtl_phydm_params
*params
)
173 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
176 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
181 rtlpriv
->phydm
.internal
=
182 kzalloc(sizeof(struct phy_dm_struct
), GFP_KERNEL
);
183 if (!rtlpriv
->phydm
.internal
)
186 _rtl_phydm_init_com_info(rtlpriv
, ic
, params
);
188 odm_init_all_timers(dm
);
193 static int rtl_phydm_deinit_priv(struct rtl_priv
*rtlpriv
)
195 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
197 odm_cancel_all_timers(dm
);
199 kfree(rtlpriv
->phydm
.internal
);
200 rtlpriv
->phydm
.internal
= NULL
;
205 static bool rtl_phydm_load_txpower_by_rate(struct rtl_priv
*rtlpriv
)
207 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
208 enum hal_status status
;
210 status
= odm_config_bb_with_header_file(dm
, CONFIG_BB_PHY_REG_PG
);
211 if (status
!= HAL_STATUS_SUCCESS
)
217 static bool rtl_phydm_load_txpower_limit(struct rtl_priv
*rtlpriv
)
219 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
220 enum hal_status status
;
222 if (IS_HARDWARE_TYPE_8822B(rtlpriv
)) {
223 odm_read_and_config_mp_8822b_txpwr_lmt(dm
);
225 status
= odm_config_rf_with_header_file(dm
, CONFIG_RF_TXPWR_LMT
,
227 if (status
!= HAL_STATUS_SUCCESS
)
234 static int rtl_phydm_init_dm(struct rtl_priv
*rtlpriv
)
236 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
237 u32 support_ability
= 0;
239 /* clang-format off */
243 | ODM_BB_DYNAMIC_TXPWR
245 | ODM_BB_RSSI_MONITOR
247 /* | ODM_BB_PWR_SAVE*/
248 | ODM_BB_CFO_TRACKING
250 | ODM_RF_TX_PWR_TRACK
253 /* | ODM_BB_PWR_TRAIN*/
255 /* clang-format on */
257 odm_cmn_info_update(dm
, ODM_CMNINFO_ABILITY
, support_ability
);
264 static int rtl_phydm_deinit_dm(struct rtl_priv
*rtlpriv
)
269 static int rtl_phydm_reset_dm(struct rtl_priv
*rtlpriv
)
271 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
278 static bool rtl_phydm_parameter_init(struct rtl_priv
*rtlpriv
, bool post
)
280 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
282 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
283 return config_phydm_parameter_init(dm
, post
? ODM_POST_SETTING
:
289 static bool rtl_phydm_phy_bb_config(struct rtl_priv
*rtlpriv
)
291 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
292 enum hal_status status
;
294 status
= odm_config_bb_with_header_file(dm
, CONFIG_BB_PHY_REG
);
295 if (status
!= HAL_STATUS_SUCCESS
)
298 status
= odm_config_bb_with_header_file(dm
, CONFIG_BB_AGC_TAB
);
299 if (status
!= HAL_STATUS_SUCCESS
)
305 static bool rtl_phydm_phy_rf_config(struct rtl_priv
*rtlpriv
)
307 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
308 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
309 enum hal_status status
;
310 enum odm_rf_radio_path rfpath
;
312 for (rfpath
= 0; rfpath
< rtlphy
->num_total_rfpath
; rfpath
++) {
313 status
= odm_config_rf_with_header_file(dm
, CONFIG_RF_RADIO
,
315 if (status
!= HAL_STATUS_SUCCESS
)
319 status
= odm_config_rf_with_tx_pwr_track_header_file(dm
);
320 if (status
!= HAL_STATUS_SUCCESS
)
326 static bool rtl_phydm_phy_mac_config(struct rtl_priv
*rtlpriv
)
328 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
329 enum hal_status status
;
331 status
= odm_config_mac_with_header_file(dm
);
332 if (status
!= HAL_STATUS_SUCCESS
)
338 static bool rtl_phydm_trx_mode(struct rtl_priv
*rtlpriv
,
339 enum radio_mask tx_path
, enum radio_mask rx_path
,
342 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
344 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
345 return config_phydm_trx_mode_8822b(dm
,
346 (enum odm_rf_path
)tx_path
,
347 (enum odm_rf_path
)rx_path
,
353 static bool rtl_phydm_watchdog(struct rtl_priv
*rtlpriv
)
355 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
356 struct rtl_mac
*mac
= rtl_mac(rtlpriv
);
357 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtlpriv
);
358 bool fw_current_inpsmode
= false;
359 bool fw_ps_awake
= true;
360 u8 is_linked
= false;
361 u8 bsta_state
= false;
362 u8 is_bt_enabled
= false;
364 /* check whether do watchdog */
365 rtlpriv
->cfg
->ops
->get_hw_reg(rtlpriv
->hw
, HW_VAR_FW_PSMODE_STATUS
,
366 (u8
*)(&fw_current_inpsmode
));
367 rtlpriv
->cfg
->ops
->get_hw_reg(rtlpriv
->hw
, HW_VAR_FWLPS_RF_ON
,
368 (u8
*)(&fw_ps_awake
));
369 if (ppsc
->p2p_ps_info
.p2p_ps_mode
)
372 if ((ppsc
->rfpwr_state
== ERFON
) &&
373 ((!fw_current_inpsmode
) && fw_ps_awake
) &&
374 (!ppsc
->rfchange_inprogress
))
379 /* update common info before doing watchdog */
380 if (mac
->link_state
>= MAC80211_LINKED
) {
382 if (mac
->vif
&& mac
->vif
->type
== NL80211_IFTYPE_STATION
)
386 if (rtlpriv
->cfg
->ops
->get_btc_status())
387 is_bt_enabled
= !rtlpriv
->btcoexist
.btc_ops
->btc_is_bt_disabled(
390 odm_cmn_info_update(dm
, ODM_CMNINFO_LINK
, is_linked
);
391 odm_cmn_info_update(dm
, ODM_CMNINFO_STATION_STATE
, bsta_state
);
392 odm_cmn_info_update(dm
, ODM_CMNINFO_BT_ENABLED
, is_bt_enabled
);
400 static bool rtl_phydm_switch_band(struct rtl_priv
*rtlpriv
, u8 central_ch
)
402 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
404 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
405 return config_phydm_switch_band_8822b(dm
, central_ch
);
410 static bool rtl_phydm_switch_channel(struct rtl_priv
*rtlpriv
, u8 central_ch
)
412 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
414 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
415 return config_phydm_switch_channel_8822b(dm
, central_ch
);
420 static bool rtl_phydm_switch_bandwidth(struct rtl_priv
*rtlpriv
,
422 enum ht_channel_width bandwidth
)
424 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
425 enum odm_bw odm_bw
= (enum odm_bw
)bandwidth
;
427 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
428 return config_phydm_switch_bandwidth_8822b(dm
, primary_ch_idx
,
434 static bool rtl_phydm_iq_calibrate(struct rtl_priv
*rtlpriv
)
436 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
438 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
439 phy_iq_calibrate_8822b(dm
, false);
446 static bool rtl_phydm_clear_txpowertracking_state(struct rtl_priv
*rtlpriv
)
448 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
450 odm_clear_txpowertracking_state(dm
);
455 static bool rtl_phydm_pause_dig(struct rtl_priv
*rtlpriv
, bool pause
)
457 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
460 odm_pause_dig(dm
, PHYDM_PAUSE
, PHYDM_PAUSE_LEVEL_0
, 0x1e);
462 odm_pause_dig(dm
, PHYDM_RESUME
, PHYDM_PAUSE_LEVEL_0
, 0xff);
467 static u32
rtl_phydm_read_rf_reg(struct rtl_priv
*rtlpriv
,
468 enum radio_path rfpath
, u32 addr
, u32 mask
)
470 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
471 enum odm_rf_radio_path odm_rfpath
= (enum odm_rf_radio_path
)rfpath
;
473 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
474 return config_phydm_read_rf_reg_8822b(dm
, odm_rfpath
, addr
,
480 static bool rtl_phydm_write_rf_reg(struct rtl_priv
*rtlpriv
,
481 enum radio_path rfpath
, u32 addr
, u32 mask
,
484 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
485 enum odm_rf_radio_path odm_rfpath
= (enum odm_rf_radio_path
)rfpath
;
487 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
488 return config_phydm_write_rf_reg_8822b(dm
, odm_rfpath
, addr
,
494 static u8
rtl_phydm_read_txagc(struct rtl_priv
*rtlpriv
, enum radio_path rfpath
,
497 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
498 enum odm_rf_radio_path odm_rfpath
= (enum odm_rf_radio_path
)rfpath
;
500 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
501 return config_phydm_read_txagc_8822b(dm
, odm_rfpath
, hw_rate
);
506 static bool rtl_phydm_write_txagc(struct rtl_priv
*rtlpriv
, u32 power_index
,
507 enum radio_path rfpath
, u8 hw_rate
)
509 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
510 enum odm_rf_radio_path odm_rfpath
= (enum odm_rf_radio_path
)rfpath
;
512 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
513 return config_phydm_write_txagc_8822b(dm
, power_index
,
514 odm_rfpath
, hw_rate
);
519 static bool rtl_phydm_c2h_content_parsing(struct rtl_priv
*rtlpriv
, u8 cmd_id
,
520 u8 cmd_len
, u8
*content
)
522 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
524 if (phydm_c2H_content_parsing(dm
, cmd_id
, cmd_len
, content
))
530 static bool rtl_phydm_query_phy_status(struct rtl_priv
*rtlpriv
, u8
*phystrpt
,
531 struct ieee80211_hdr
*hdr
,
532 struct rtl_stats
*pstatus
)
534 /* NOTE: phystrpt may be NULL, and need to fill default value */
536 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
537 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtlpriv
);
538 struct rtl_mac
*mac
= rtl_mac(rtlpriv
);
539 struct dm_per_pkt_info pktinfo
; /* input of pydm */
540 struct dm_phy_status_info phy_info
; /* output of phydm */
541 __le16 fc
= hdr
->frame_control
;
543 /* fill driver pstatus */
544 ether_addr_copy(pstatus
->psaddr
, ieee80211_get_SA(hdr
));
547 memset(&pktinfo
, 0, sizeof(pktinfo
));
549 pktinfo
.data_rate
= pstatus
->rate
;
551 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_STATION
) {
552 pktinfo
.station_id
= 0;
554 /* TODO: use rtl_find_sta() to find ID */
555 pktinfo
.station_id
= 0xFF;
558 pktinfo
.is_packet_match_bssid
=
559 (!ieee80211_is_ctl(fc
) &&
560 (ether_addr_equal(mac
->bssid
,
561 ieee80211_has_tods(fc
) ?
563 ieee80211_has_fromds(fc
) ?
566 (!pstatus
->hwerror
) && (!pstatus
->crc
) && (!pstatus
->icv
));
567 pktinfo
.is_packet_to_self
=
568 pktinfo
.is_packet_match_bssid
&&
569 (ether_addr_equal(hdr
->addr1
, rtlefuse
->dev_addr
));
570 pktinfo
.is_to_self
= (!pstatus
->icv
) && (!pstatus
->crc
) &&
571 (ether_addr_equal(hdr
->addr1
, rtlefuse
->dev_addr
));
572 pktinfo
.is_packet_beacon
= (ieee80211_is_beacon(fc
) ? true : false);
574 /* query phy status */
576 odm_phy_status_query(dm
, &phy_info
, phystrpt
, &pktinfo
);
578 memset(&phy_info
, 0, sizeof(phy_info
));
580 /* copy phy_info from phydm to driver */
581 pstatus
->rx_pwdb_all
= phy_info
.rx_pwdb_all
;
582 pstatus
->bt_rx_rssi_percentage
= phy_info
.bt_rx_rssi_percentage
;
583 pstatus
->recvsignalpower
= phy_info
.recv_signal_power
;
584 pstatus
->signalquality
= phy_info
.signal_quality
;
585 pstatus
->rx_mimo_signalquality
[0] = phy_info
.rx_mimo_signal_quality
[0];
586 pstatus
->rx_mimo_signalquality
[1] = phy_info
.rx_mimo_signal_quality
[1];
587 pstatus
->rx_packet_bw
=
588 phy_info
.band_width
; /* HT_CHANNEL_WIDTH_20 <- ODM_BW20M */
590 /* fill driver pstatus */
591 pstatus
->packet_matchbssid
= pktinfo
.is_packet_match_bssid
;
592 pstatus
->packet_toself
= pktinfo
.is_packet_to_self
;
593 pstatus
->packet_beacon
= pktinfo
.is_packet_beacon
;
598 static u8
rtl_phydm_rate_id_mapping(struct rtl_priv
*rtlpriv
,
599 enum wireless_mode wireless_mode
,
600 enum rf_type rf_type
,
601 enum ht_channel_width bw
)
603 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
605 return phydm_rate_id_mapping(dm
, wireless_mode
, rf_type
, bw
);
608 static bool rtl_phydm_get_ra_bitmap(struct rtl_priv
*rtlpriv
,
609 enum wireless_mode wireless_mode
,
610 enum rf_type rf_type
,
611 enum ht_channel_width bw
,
612 u8 tx_rate_level
, /* 0~6 */
616 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
617 const u8 mimo_ps_enable
= 0;
618 const u8 disable_cck_rate
= 0;
620 phydm_update_hal_ra_mask(dm
, wireless_mode
, rf_type
, bw
, mimo_ps_enable
,
621 disable_cck_rate
, tx_bitmap_msb
, tx_bitmap_lsb
,
627 static u8
_rtl_phydm_get_macid(struct rtl_priv
*rtlpriv
,
628 struct ieee80211_sta
*sta
)
630 struct rtl_mac
*mac
= rtl_mac(rtlpriv
);
632 if (mac
->opmode
== NL80211_IFTYPE_STATION
||
633 mac
->opmode
== NL80211_IFTYPE_MESH_POINT
) {
635 } else if (mac
->opmode
== NL80211_IFTYPE_AP
||
636 mac
->opmode
== NL80211_IFTYPE_ADHOC
)
642 static bool rtl_phydm_add_sta(struct rtl_priv
*rtlpriv
,
643 struct ieee80211_sta
*sta
)
645 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
646 struct rtl_sta_info
*sta_entry
= (struct rtl_sta_info
*)sta
->drv_priv
;
647 u8 mac_id
= _rtl_phydm_get_macid(rtlpriv
, sta
);
649 odm_cmn_info_ptr_array_hook(dm
, ODM_CMNINFO_STA_STATUS
, mac_id
,
655 static bool rtl_phydm_del_sta(struct rtl_priv
*rtlpriv
,
656 struct ieee80211_sta
*sta
)
658 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
659 u8 mac_id
= _rtl_phydm_get_macid(rtlpriv
, sta
);
661 odm_cmn_info_ptr_array_hook(dm
, ODM_CMNINFO_STA_STATUS
, mac_id
, NULL
);
666 static u32
rtl_phydm_get_version(struct rtl_priv
*rtlpriv
)
670 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
671 ver
= RELEASE_VERSION_8822B
;
676 static bool rtl_phydm_modify_ra_pcr_threshold(struct rtl_priv
*rtlpriv
,
677 u8 ra_offset_direction
,
678 u8 ra_threshold_offset
)
680 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
682 phydm_modify_RA_PCR_threshold(dm
, ra_offset_direction
,
683 ra_threshold_offset
);
688 static u32
rtl_phydm_query_counter(struct rtl_priv
*rtlpriv
,
689 const char *info_type
)
691 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
692 static const struct query_entry
{
693 const char *query_name
;
694 enum phydm_info_query query_id
;
696 #define QUERY_ENTRY(name) {#name, name}
697 QUERY_ENTRY(PHYDM_INFO_FA_OFDM
),
698 QUERY_ENTRY(PHYDM_INFO_FA_CCK
),
699 QUERY_ENTRY(PHYDM_INFO_CCA_OFDM
),
700 QUERY_ENTRY(PHYDM_INFO_CCA_CCK
),
701 QUERY_ENTRY(PHYDM_INFO_CRC32_OK_CCK
),
702 QUERY_ENTRY(PHYDM_INFO_CRC32_OK_LEGACY
),
703 QUERY_ENTRY(PHYDM_INFO_CRC32_OK_HT
),
704 QUERY_ENTRY(PHYDM_INFO_CRC32_OK_VHT
),
705 QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_CCK
),
706 QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_LEGACY
),
707 QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_HT
),
708 QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_VHT
),
710 #define QUERY_TABLE_SIZE ARRAY_SIZE(query_table)
713 const struct query_entry
*entry
;
715 if (!strcmp(info_type
, "IQK_TOTAL"))
716 return dm
->n_iqk_cnt
;
718 if (!strcmp(info_type
, "IQK_OK"))
719 return dm
->n_iqk_ok_cnt
;
721 if (!strcmp(info_type
, "IQK_FAIL"))
722 return dm
->n_iqk_fail_cnt
;
724 for (i
= 0; i
< QUERY_TABLE_SIZE
; i
++) {
725 entry
= &query_table
[i
];
727 if (!strcmp(info_type
, entry
->query_name
))
728 return phydm_cmn_info_query(dm
, entry
->query_id
);
731 pr_err("Unrecognized info_type:%s!!!!:\n", info_type
);
736 static bool rtl_phydm_debug_cmd(struct rtl_priv
*rtlpriv
, char *in
, u32 in_len
,
737 char *out
, u32 out_len
)
739 struct phy_dm_struct
*dm
= rtlpriv_to_phydm(rtlpriv
);
741 phydm_cmd(dm
, in
, in_len
, 1, out
, out_len
);
746 static struct rtl_phydm_ops rtl_phydm_operation
= {
747 /* init/deinit priv */
748 .phydm_init_priv
= rtl_phydm_init_priv
,
749 .phydm_deinit_priv
= rtl_phydm_deinit_priv
,
750 .phydm_load_txpower_by_rate
= rtl_phydm_load_txpower_by_rate
,
751 .phydm_load_txpower_limit
= rtl_phydm_load_txpower_limit
,
754 .phydm_init_dm
= rtl_phydm_init_dm
,
755 .phydm_deinit_dm
= rtl_phydm_deinit_dm
,
756 .phydm_reset_dm
= rtl_phydm_reset_dm
,
757 .phydm_parameter_init
= rtl_phydm_parameter_init
,
758 .phydm_phy_bb_config
= rtl_phydm_phy_bb_config
,
759 .phydm_phy_rf_config
= rtl_phydm_phy_rf_config
,
760 .phydm_phy_mac_config
= rtl_phydm_phy_mac_config
,
761 .phydm_trx_mode
= rtl_phydm_trx_mode
,
764 .phydm_watchdog
= rtl_phydm_watchdog
,
767 .phydm_switch_band
= rtl_phydm_switch_band
,
768 .phydm_switch_channel
= rtl_phydm_switch_channel
,
769 .phydm_switch_bandwidth
= rtl_phydm_switch_bandwidth
,
770 .phydm_iq_calibrate
= rtl_phydm_iq_calibrate
,
771 .phydm_clear_txpowertracking_state
=
772 rtl_phydm_clear_txpowertracking_state
,
773 .phydm_pause_dig
= rtl_phydm_pause_dig
,
776 .phydm_read_rf_reg
= rtl_phydm_read_rf_reg
,
777 .phydm_write_rf_reg
= rtl_phydm_write_rf_reg
,
778 .phydm_read_txagc
= rtl_phydm_read_txagc
,
779 .phydm_write_txagc
= rtl_phydm_write_txagc
,
782 .phydm_c2h_content_parsing
= rtl_phydm_c2h_content_parsing
,
783 .phydm_query_phy_status
= rtl_phydm_query_phy_status
,
786 .phydm_rate_id_mapping
= rtl_phydm_rate_id_mapping
,
787 .phydm_get_ra_bitmap
= rtl_phydm_get_ra_bitmap
,
790 .phydm_add_sta
= rtl_phydm_add_sta
,
791 .phydm_del_sta
= rtl_phydm_del_sta
,
794 .phydm_get_version
= rtl_phydm_get_version
,
795 .phydm_modify_ra_pcr_threshold
= rtl_phydm_modify_ra_pcr_threshold
,
796 .phydm_query_counter
= rtl_phydm_query_counter
,
799 .phydm_debug_cmd
= rtl_phydm_debug_cmd
,
802 struct rtl_phydm_ops
*rtl_phydm_get_ops_pointer(void)
804 return &rtl_phydm_operation
;
806 EXPORT_SYMBOL(rtl_phydm_get_ops_pointer
);
808 /* ********************************************************
809 * Define phydm callout function in below
810 * ********************************************************
813 u8
phy_get_tx_power_index(void *adapter
, u8 rf_path
, u8 rate
,
814 enum ht_channel_width bandwidth
, u8 channel
)
816 /* rate: DESC_RATE1M */
817 struct rtl_priv
*rtlpriv
= (struct rtl_priv
*)adapter
;
819 return rtlpriv
->cfg
->ops
->get_txpower_index(rtlpriv
->hw
, rf_path
, rate
,
823 void phy_set_tx_power_index_by_rs(void *adapter
, u8 ch
, u8 path
, u8 rs
)
825 struct rtl_priv
*rtlpriv
= (struct rtl_priv
*)adapter
;
827 return rtlpriv
->cfg
->ops
->set_tx_power_index_by_rs(rtlpriv
->hw
, ch
,
831 void phy_store_tx_power_by_rate(void *adapter
, u32 band
, u32 rfpath
, u32 txnum
,
832 u32 regaddr
, u32 bitmask
, u32 data
)
834 struct rtl_priv
*rtlpriv
= (struct rtl_priv
*)adapter
;
836 rtlpriv
->cfg
->ops
->store_tx_power_by_rate(
837 rtlpriv
->hw
, band
, rfpath
, txnum
, regaddr
, bitmask
, data
);
840 void phy_set_tx_power_limit(void *dm
, u8
*regulation
, u8
*band
, u8
*bandwidth
,
841 u8
*rate_section
, u8
*rf_path
, u8
*channel
,
844 struct rtl_priv
*rtlpriv
=
845 (struct rtl_priv
*)((struct phy_dm_struct
*)dm
)->adapter
;
847 rtlpriv
->cfg
->ops
->phy_set_txpower_limit(rtlpriv
->hw
, regulation
, band
,
848 bandwidth
, rate_section
,
849 rf_path
, channel
, power_limit
);
852 void rtl_hal_update_ra_mask(void *adapter
, struct rtl_sta_info
*psta
,
855 struct rtl_priv
*rtlpriv
= (struct rtl_priv
*)adapter
;
856 struct ieee80211_sta
*sta
=
857 container_of((void *)psta
, struct ieee80211_sta
, drv_priv
);
859 rtlpriv
->cfg
->ops
->update_rate_tbl(rtlpriv
->hw
, sta
, rssi_level
, false);
862 MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
863 MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
864 MODULE_LICENSE("GPL");
865 MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");