1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
15 static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev
*rtwdev
,
18 struct rtw_c2h_cmd
*c2h
;
21 c2h
= get_c2h_from_skb(skb
);
22 sub_cmd_id
= c2h
->payload
[0];
26 rtw_tx_report_handle(rtwdev
, skb
);
33 static u16
get_max_amsdu_len(u32 bit_rate
)
35 /* lower than ofdm, do not aggregate */
39 /* lower than 20M 2ss mcs8, make it small */
43 /* lower than 40M 2ss mcs9, make it medium */
47 /* not yet 80M 2ss mcs8/9, make it twice regular packet size */
55 struct rtw_fw_iter_ra_data
{
56 struct rtw_dev
*rtwdev
;
60 static void rtw_fw_ra_report_iter(void *data
, struct ieee80211_sta
*sta
)
62 struct rtw_fw_iter_ra_data
*ra_data
= data
;
63 struct rtw_sta_info
*si
= (struct rtw_sta_info
*)sta
->drv_priv
;
64 u8 mac_id
, rate
, sgi
, bw
;
68 mac_id
= GET_RA_REPORT_MACID(ra_data
->payload
);
69 if (si
->mac_id
!= mac_id
)
72 si
->ra_report
.txrate
.flags
= 0;
74 rate
= GET_RA_REPORT_RATE(ra_data
->payload
);
75 sgi
= GET_RA_REPORT_SGI(ra_data
->payload
);
76 bw
= GET_RA_REPORT_BW(ra_data
->payload
);
78 if (rate
< DESC_RATEMCS0
) {
79 si
->ra_report
.txrate
.legacy
= rtw_desc_to_bitrate(rate
);
83 rtw_desc_to_mcsrate(rate
, &mcs
, &nss
);
84 if (rate
>= DESC_RATEVHT1SS_MCS0
)
85 si
->ra_report
.txrate
.flags
|= RATE_INFO_FLAGS_VHT_MCS
;
86 else if (rate
>= DESC_RATEMCS0
)
87 si
->ra_report
.txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
89 if (rate
>= DESC_RATEMCS0
) {
90 si
->ra_report
.txrate
.mcs
= mcs
;
91 si
->ra_report
.txrate
.nss
= nss
;
95 si
->ra_report
.txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
97 if (bw
== RTW_CHANNEL_WIDTH_80
)
98 si
->ra_report
.txrate
.bw
= RATE_INFO_BW_80
;
99 else if (bw
== RTW_CHANNEL_WIDTH_40
)
100 si
->ra_report
.txrate
.bw
= RATE_INFO_BW_40
;
102 si
->ra_report
.txrate
.bw
= RATE_INFO_BW_20
;
105 bit_rate
= cfg80211_calculate_bitrate(&si
->ra_report
.txrate
);
107 si
->ra_report
.desc_rate
= rate
;
108 si
->ra_report
.bit_rate
= bit_rate
;
110 sta
->max_rc_amsdu_len
= get_max_amsdu_len(bit_rate
);
113 static void rtw_fw_ra_report_handle(struct rtw_dev
*rtwdev
, u8
*payload
,
116 struct rtw_fw_iter_ra_data ra_data
;
118 if (WARN(length
< 7, "invalid ra report c2h length\n"))
121 rtwdev
->dm_info
.tx_rate
= GET_RA_REPORT_RATE(payload
);
122 ra_data
.rtwdev
= rtwdev
;
123 ra_data
.payload
= payload
;
124 rtw_iterate_stas_atomic(rtwdev
, rtw_fw_ra_report_iter
, &ra_data
);
127 void rtw_fw_c2h_cmd_handle(struct rtw_dev
*rtwdev
, struct sk_buff
*skb
)
129 struct rtw_c2h_cmd
*c2h
;
133 pkt_offset
= *((u32
*)skb
->cb
);
134 c2h
= (struct rtw_c2h_cmd
*)(skb
->data
+ pkt_offset
);
135 len
= skb
->len
- pkt_offset
- 2;
137 mutex_lock(&rtwdev
->mutex
);
141 rtw_coex_bt_info_notify(rtwdev
, c2h
->payload
, len
);
144 rtw_coex_wl_fwdbginfo_notify(rtwdev
, c2h
->payload
, len
);
147 rtw_fw_c2h_cmd_handle_ext(rtwdev
, skb
);
150 rtw_fw_ra_report_handle(rtwdev
, c2h
->payload
, len
);
156 mutex_unlock(&rtwdev
->mutex
);
159 void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev
*rtwdev
, u32 pkt_offset
,
162 struct rtw_c2h_cmd
*c2h
;
165 c2h
= (struct rtw_c2h_cmd
*)(skb
->data
+ pkt_offset
);
166 len
= skb
->len
- pkt_offset
- 2;
167 *((u32
*)skb
->cb
) = pkt_offset
;
169 rtw_dbg(rtwdev
, RTW_DBG_FW
, "recv C2H, id=0x%02x, seq=0x%02x, len=%d\n",
170 c2h
->id
, c2h
->seq
, len
);
174 rtw_coex_info_response(rtwdev
, skb
);
177 /* pass offset for further operation */
178 *((u32
*)skb
->cb
) = pkt_offset
;
179 skb_queue_tail(&rtwdev
->c2h_queue
, skb
);
180 ieee80211_queue_work(rtwdev
->hw
, &rtwdev
->c2h_work
);
184 EXPORT_SYMBOL(rtw_fw_c2h_cmd_rx_irqsafe
);
186 static void rtw_fw_send_h2c_command(struct rtw_dev
*rtwdev
,
191 u32 box_reg
, box_ex_reg
;
195 rtw_dbg(rtwdev
, RTW_DBG_FW
,
196 "send H2C content %02x%02x%02x%02x %02x%02x%02x%02x\n",
197 h2c
[3], h2c
[2], h2c
[1], h2c
[0],
198 h2c
[7], h2c
[6], h2c
[5], h2c
[4]);
200 spin_lock(&rtwdev
->h2c
.lock
);
202 box
= rtwdev
->h2c
.last_box_num
;
205 box_reg
= REG_HMEBOX0
;
206 box_ex_reg
= REG_HMEBOX0_EX
;
209 box_reg
= REG_HMEBOX1
;
210 box_ex_reg
= REG_HMEBOX1_EX
;
213 box_reg
= REG_HMEBOX2
;
214 box_ex_reg
= REG_HMEBOX2_EX
;
217 box_reg
= REG_HMEBOX3
;
218 box_ex_reg
= REG_HMEBOX3_EX
;
221 WARN(1, "invalid h2c mail box number\n");
227 box_state
= rtw_read8(rtwdev
, REG_HMETFR
);
228 } while ((box_state
>> box
) & 0x1 && --h2c_wait
> 0);
231 rtw_err(rtwdev
, "failed to send h2c command\n");
235 for (idx
= 0; idx
< 4; idx
++)
236 rtw_write8(rtwdev
, box_reg
+ idx
, h2c
[idx
]);
237 for (idx
= 0; idx
< 4; idx
++)
238 rtw_write8(rtwdev
, box_ex_reg
+ idx
, h2c
[idx
+ 4]);
240 if (++rtwdev
->h2c
.last_box_num
>= 4)
241 rtwdev
->h2c
.last_box_num
= 0;
244 spin_unlock(&rtwdev
->h2c
.lock
);
247 static void rtw_fw_send_h2c_packet(struct rtw_dev
*rtwdev
, u8
*h2c_pkt
)
251 spin_lock(&rtwdev
->h2c
.lock
);
253 FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt
, rtwdev
->h2c
.seq
);
254 ret
= rtw_hci_write_data_h2c(rtwdev
, h2c_pkt
, H2C_PKT_SIZE
);
256 rtw_err(rtwdev
, "failed to send h2c packet\n");
259 spin_unlock(&rtwdev
->h2c
.lock
);
263 rtw_fw_send_general_info(struct rtw_dev
*rtwdev
)
265 struct rtw_fifo_conf
*fifo
= &rtwdev
->fifo
;
266 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
267 u16 total_size
= H2C_PKT_HDR_SIZE
+ 4;
269 rtw_h2c_pkt_set_header(h2c_pkt
, H2C_PKT_GENERAL_INFO
);
271 SET_PKT_H2C_TOTAL_LEN(h2c_pkt
, total_size
);
273 GENERAL_INFO_SET_FW_TX_BOUNDARY(h2c_pkt
,
274 fifo
->rsvd_fw_txbuf_addr
-
275 fifo
->rsvd_boundary
);
277 rtw_fw_send_h2c_packet(rtwdev
, h2c_pkt
);
281 rtw_fw_send_phydm_info(struct rtw_dev
*rtwdev
)
283 struct rtw_hal
*hal
= &rtwdev
->hal
;
284 struct rtw_efuse
*efuse
= &rtwdev
->efuse
;
285 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
286 u16 total_size
= H2C_PKT_HDR_SIZE
+ 8;
289 if (hal
->rf_type
== RF_1T1R
)
290 fw_rf_type
= FW_RF_1T1R
;
291 else if (hal
->rf_type
== RF_2T2R
)
292 fw_rf_type
= FW_RF_2T2R
;
294 rtw_h2c_pkt_set_header(h2c_pkt
, H2C_PKT_PHYDM_INFO
);
296 SET_PKT_H2C_TOTAL_LEN(h2c_pkt
, total_size
);
297 PHYDM_INFO_SET_REF_TYPE(h2c_pkt
, efuse
->rfe_option
);
298 PHYDM_INFO_SET_RF_TYPE(h2c_pkt
, fw_rf_type
);
299 PHYDM_INFO_SET_CUT_VER(h2c_pkt
, hal
->cut_version
);
300 PHYDM_INFO_SET_RX_ANT_STATUS(h2c_pkt
, hal
->antenna_tx
);
301 PHYDM_INFO_SET_TX_ANT_STATUS(h2c_pkt
, hal
->antenna_rx
);
303 rtw_fw_send_h2c_packet(rtwdev
, h2c_pkt
);
306 void rtw_fw_do_iqk(struct rtw_dev
*rtwdev
, struct rtw_iqk_para
*para
)
308 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
309 u16 total_size
= H2C_PKT_HDR_SIZE
+ 1;
311 rtw_h2c_pkt_set_header(h2c_pkt
, H2C_PKT_IQK
);
312 SET_PKT_H2C_TOTAL_LEN(h2c_pkt
, total_size
);
313 IQK_SET_CLEAR(h2c_pkt
, para
->clear
);
314 IQK_SET_SEGMENT_IQK(h2c_pkt
, para
->segment_iqk
);
316 rtw_fw_send_h2c_packet(rtwdev
, h2c_pkt
);
319 void rtw_fw_query_bt_info(struct rtw_dev
*rtwdev
)
321 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
323 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_QUERY_BT_INFO
);
325 SET_QUERY_BT_INFO(h2c_pkt
, true);
327 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
330 void rtw_fw_wl_ch_info(struct rtw_dev
*rtwdev
, u8 link
, u8 ch
, u8 bw
)
332 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
334 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_WL_CH_INFO
);
336 SET_WL_CH_INFO_LINK(h2c_pkt
, link
);
337 SET_WL_CH_INFO_CHNL(h2c_pkt
, ch
);
338 SET_WL_CH_INFO_BW(h2c_pkt
, bw
);
340 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
343 void rtw_fw_query_bt_mp_info(struct rtw_dev
*rtwdev
,
344 struct rtw_coex_info_req
*req
)
346 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
348 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_QUERY_BT_MP_INFO
);
350 SET_BT_MP_INFO_SEQ(h2c_pkt
, req
->seq
);
351 SET_BT_MP_INFO_OP_CODE(h2c_pkt
, req
->op_code
);
352 SET_BT_MP_INFO_PARA1(h2c_pkt
, req
->para1
);
353 SET_BT_MP_INFO_PARA2(h2c_pkt
, req
->para2
);
354 SET_BT_MP_INFO_PARA3(h2c_pkt
, req
->para3
);
356 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
359 void rtw_fw_force_bt_tx_power(struct rtw_dev
*rtwdev
, u8 bt_pwr_dec_lvl
)
361 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
362 u8 index
= 0 - bt_pwr_dec_lvl
;
364 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_FORCE_BT_TX_POWER
);
366 SET_BT_TX_POWER_INDEX(h2c_pkt
, index
);
368 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
371 void rtw_fw_bt_ignore_wlan_action(struct rtw_dev
*rtwdev
, bool enable
)
373 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
375 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_IGNORE_WLAN_ACTION
);
377 SET_IGNORE_WLAN_ACTION_EN(h2c_pkt
, enable
);
379 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
382 void rtw_fw_coex_tdma_type(struct rtw_dev
*rtwdev
,
383 u8 para1
, u8 para2
, u8 para3
, u8 para4
, u8 para5
)
385 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
387 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_COEX_TDMA_TYPE
);
389 SET_COEX_TDMA_TYPE_PARA1(h2c_pkt
, para1
);
390 SET_COEX_TDMA_TYPE_PARA2(h2c_pkt
, para2
);
391 SET_COEX_TDMA_TYPE_PARA3(h2c_pkt
, para3
);
392 SET_COEX_TDMA_TYPE_PARA4(h2c_pkt
, para4
);
393 SET_COEX_TDMA_TYPE_PARA5(h2c_pkt
, para5
);
395 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
398 void rtw_fw_bt_wifi_control(struct rtw_dev
*rtwdev
, u8 op_code
, u8
*data
)
400 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
402 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_BT_WIFI_CONTROL
);
404 SET_BT_WIFI_CONTROL_OP_CODE(h2c_pkt
, op_code
);
406 SET_BT_WIFI_CONTROL_DATA1(h2c_pkt
, *data
);
407 SET_BT_WIFI_CONTROL_DATA2(h2c_pkt
, *(data
+ 1));
408 SET_BT_WIFI_CONTROL_DATA3(h2c_pkt
, *(data
+ 2));
409 SET_BT_WIFI_CONTROL_DATA4(h2c_pkt
, *(data
+ 3));
410 SET_BT_WIFI_CONTROL_DATA5(h2c_pkt
, *(data
+ 4));
412 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
415 void rtw_fw_send_rssi_info(struct rtw_dev
*rtwdev
, struct rtw_sta_info
*si
)
417 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
418 u8 rssi
= ewma_rssi_read(&si
->avg_rssi
);
419 bool stbc_en
= si
->stbc_en
? true : false;
421 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_RSSI_MONITOR
);
423 SET_RSSI_INFO_MACID(h2c_pkt
, si
->mac_id
);
424 SET_RSSI_INFO_RSSI(h2c_pkt
, rssi
);
425 SET_RSSI_INFO_STBC(h2c_pkt
, stbc_en
);
427 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
430 void rtw_fw_send_ra_info(struct rtw_dev
*rtwdev
, struct rtw_sta_info
*si
)
432 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
433 bool no_update
= si
->updated
;
434 bool disable_pt
= true;
436 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_RA_INFO
);
438 SET_RA_INFO_MACID(h2c_pkt
, si
->mac_id
);
439 SET_RA_INFO_RATE_ID(h2c_pkt
, si
->rate_id
);
440 SET_RA_INFO_INIT_RA_LVL(h2c_pkt
, si
->init_ra_lv
);
441 SET_RA_INFO_SGI_EN(h2c_pkt
, si
->sgi_enable
);
442 SET_RA_INFO_BW_MODE(h2c_pkt
, si
->bw_mode
);
443 SET_RA_INFO_LDPC(h2c_pkt
, si
->ldpc_en
);
444 SET_RA_INFO_NO_UPDATE(h2c_pkt
, no_update
);
445 SET_RA_INFO_VHT_EN(h2c_pkt
, si
->vht_enable
);
446 SET_RA_INFO_DIS_PT(h2c_pkt
, disable_pt
);
447 SET_RA_INFO_RA_MASK0(h2c_pkt
, (si
->ra_mask
& 0xff));
448 SET_RA_INFO_RA_MASK1(h2c_pkt
, (si
->ra_mask
& 0xff00) >> 8);
449 SET_RA_INFO_RA_MASK2(h2c_pkt
, (si
->ra_mask
& 0xff0000) >> 16);
450 SET_RA_INFO_RA_MASK3(h2c_pkt
, (si
->ra_mask
& 0xff000000) >> 24);
455 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
458 void rtw_fw_media_status_report(struct rtw_dev
*rtwdev
, u8 mac_id
, bool connect
)
460 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
462 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_MEDIA_STATUS_RPT
);
463 MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt
, connect
);
464 MEDIA_STATUS_RPT_SET_MACID(h2c_pkt
, mac_id
);
466 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
469 void rtw_fw_set_pwr_mode(struct rtw_dev
*rtwdev
)
471 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
472 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
474 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_SET_PWR_MODE
);
476 SET_PWR_MODE_SET_MODE(h2c_pkt
, conf
->mode
);
477 SET_PWR_MODE_SET_RLBM(h2c_pkt
, conf
->rlbm
);
478 SET_PWR_MODE_SET_SMART_PS(h2c_pkt
, conf
->smart_ps
);
479 SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_pkt
, conf
->awake_interval
);
480 SET_PWR_MODE_SET_PORT_ID(h2c_pkt
, conf
->port_id
);
481 SET_PWR_MODE_SET_PWR_STATE(h2c_pkt
, conf
->state
);
483 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
486 void rtw_fw_set_keep_alive_cmd(struct rtw_dev
*rtwdev
, bool enable
)
488 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
489 struct rtw_fw_wow_keep_alive_para mode
= {
491 .pkt_type
= KEEP_ALIVE_NULL_PKT
,
495 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_KEEP_ALIVE
);
496 SET_KEEP_ALIVE_ENABLE(h2c_pkt
, enable
);
497 SET_KEEP_ALIVE_ADOPT(h2c_pkt
, mode
.adopt
);
498 SET_KEEP_ALIVE_PKT_TYPE(h2c_pkt
, mode
.pkt_type
);
499 SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt
, mode
.period
);
501 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
504 void rtw_fw_set_disconnect_decision_cmd(struct rtw_dev
*rtwdev
, bool enable
)
506 struct rtw_wow_param
*rtw_wow
= &rtwdev
->wow
;
507 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
508 struct rtw_fw_wow_disconnect_para mode
= {
514 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_DISCONNECT_DECISION
);
516 if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT
, rtw_wow
->flags
)) {
517 SET_DISCONNECT_DECISION_ENABLE(h2c_pkt
, enable
);
518 SET_DISCONNECT_DECISION_ADOPT(h2c_pkt
, mode
.adopt
);
519 SET_DISCONNECT_DECISION_CHECK_PERIOD(h2c_pkt
, mode
.period
);
520 SET_DISCONNECT_DECISION_TRY_PKT_NUM(h2c_pkt
, mode
.retry_count
);
523 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
526 void rtw_fw_set_wowlan_ctrl_cmd(struct rtw_dev
*rtwdev
, bool enable
)
528 struct rtw_wow_param
*rtw_wow
= &rtwdev
->wow
;
529 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
531 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_WOWLAN
);
533 SET_WOWLAN_FUNC_ENABLE(h2c_pkt
, enable
);
534 if (rtw_wow_mgd_linked(rtwdev
)) {
535 if (test_bit(RTW_WOW_FLAG_EN_MAGIC_PKT
, rtw_wow
->flags
))
536 SET_WOWLAN_MAGIC_PKT_ENABLE(h2c_pkt
, enable
);
537 if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT
, rtw_wow
->flags
))
538 SET_WOWLAN_DEAUTH_WAKEUP_ENABLE(h2c_pkt
, enable
);
539 if (test_bit(RTW_WOW_FLAG_EN_REKEY_PKT
, rtw_wow
->flags
))
540 SET_WOWLAN_REKEY_WAKEUP_ENABLE(h2c_pkt
, enable
);
541 if (rtw_wow
->pattern_cnt
)
542 SET_WOWLAN_PATTERN_MATCH_ENABLE(h2c_pkt
, enable
);
545 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
548 void rtw_fw_set_aoac_global_info_cmd(struct rtw_dev
*rtwdev
,
552 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
554 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_AOAC_GLOBAL_INFO
);
556 SET_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(h2c_pkt
, pairwise_key_enc
);
557 SET_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(h2c_pkt
, group_key_enc
);
559 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
562 void rtw_fw_set_remote_wake_ctrl_cmd(struct rtw_dev
*rtwdev
, bool enable
)
564 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
566 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_REMOTE_WAKE_CTRL
);
568 SET_REMOTE_WAKECTRL_ENABLE(h2c_pkt
, enable
);
570 if (rtw_wow_no_link(rtwdev
))
571 SET_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(h2c_pkt
, enable
);
573 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
576 static u8
rtw_get_rsvd_page_location(struct rtw_dev
*rtwdev
,
577 enum rtw_rsvd_packet_type type
)
579 struct rtw_rsvd_page
*rsvd_pkt
;
582 list_for_each_entry(rsvd_pkt
, &rtwdev
->rsvd_page_list
, list
) {
583 if (type
== rsvd_pkt
->type
)
584 location
= rsvd_pkt
->page
;
590 void rtw_fw_set_nlo_info(struct rtw_dev
*rtwdev
, bool enable
)
592 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
595 loc_nlo
= rtw_get_rsvd_page_location(rtwdev
, RSVD_NLO_INFO
);
597 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_NLO_INFO
);
599 SET_NLO_FUN_EN(h2c_pkt
, enable
);
601 if (rtw_fw_lps_deep_mode
)
602 SET_NLO_PS_32K(h2c_pkt
, enable
);
603 SET_NLO_IGNORE_SECURITY(h2c_pkt
, enable
);
604 SET_NLO_LOC_NLO_INFO(h2c_pkt
, loc_nlo
);
607 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
610 void rtw_fw_set_pg_info(struct rtw_dev
*rtwdev
)
612 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
613 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
616 loc_pg
= rtw_get_rsvd_page_location(rtwdev
, RSVD_LPS_PG_INFO
);
617 loc_dpk
= rtw_get_rsvd_page_location(rtwdev
, RSVD_LPS_PG_DPK
);
619 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_LPS_PG_INFO
);
621 LPS_PG_INFO_LOC(h2c_pkt
, loc_pg
);
622 LPS_PG_DPK_LOC(h2c_pkt
, loc_dpk
);
623 LPS_PG_SEC_CAM_EN(h2c_pkt
, conf
->sec_cam_backup
);
624 LPS_PG_PATTERN_CAM_EN(h2c_pkt
, conf
->pattern_cam_backup
);
626 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
629 u8
rtw_get_rsvd_page_probe_req_location(struct rtw_dev
*rtwdev
,
630 struct cfg80211_ssid
*ssid
)
632 struct rtw_rsvd_page
*rsvd_pkt
;
635 list_for_each_entry(rsvd_pkt
, &rtwdev
->rsvd_page_list
, list
) {
636 if (rsvd_pkt
->type
!= RSVD_PROBE_REQ
)
638 if ((!ssid
&& !rsvd_pkt
->ssid
) ||
639 rtw_ssid_equal(rsvd_pkt
->ssid
, ssid
))
640 location
= rsvd_pkt
->page
;
646 u16
rtw_get_rsvd_page_probe_req_size(struct rtw_dev
*rtwdev
,
647 struct cfg80211_ssid
*ssid
)
649 struct rtw_rsvd_page
*rsvd_pkt
;
652 list_for_each_entry(rsvd_pkt
, &rtwdev
->rsvd_page_list
, list
) {
653 if (rsvd_pkt
->type
!= RSVD_PROBE_REQ
)
655 if ((!ssid
&& !rsvd_pkt
->ssid
) ||
656 rtw_ssid_equal(rsvd_pkt
->ssid
, ssid
))
657 size
= rsvd_pkt
->skb
->len
;
663 void rtw_send_rsvd_page_h2c(struct rtw_dev
*rtwdev
)
665 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
668 SET_H2C_CMD_ID_CLASS(h2c_pkt
, H2C_CMD_RSVD_PAGE
);
670 location
= rtw_get_rsvd_page_location(rtwdev
, RSVD_PROBE_RESP
);
671 *(h2c_pkt
+ 1) = location
;
672 rtw_dbg(rtwdev
, RTW_DBG_FW
, "RSVD_PROBE_RESP loc: %d\n", location
);
674 location
= rtw_get_rsvd_page_location(rtwdev
, RSVD_PS_POLL
);
675 *(h2c_pkt
+ 2) = location
;
676 rtw_dbg(rtwdev
, RTW_DBG_FW
, "RSVD_PS_POLL loc: %d\n", location
);
678 location
= rtw_get_rsvd_page_location(rtwdev
, RSVD_NULL
);
679 *(h2c_pkt
+ 3) = location
;
680 rtw_dbg(rtwdev
, RTW_DBG_FW
, "RSVD_NULL loc: %d\n", location
);
682 location
= rtw_get_rsvd_page_location(rtwdev
, RSVD_QOS_NULL
);
683 *(h2c_pkt
+ 4) = location
;
684 rtw_dbg(rtwdev
, RTW_DBG_FW
, "RSVD_QOS_NULL loc: %d\n", location
);
686 rtw_fw_send_h2c_command(rtwdev
, h2c_pkt
);
689 static struct sk_buff
*
690 rtw_beacon_get(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
)
692 struct sk_buff
*skb_new
;
694 if (vif
->type
!= NL80211_IFTYPE_AP
&&
695 vif
->type
!= NL80211_IFTYPE_ADHOC
&&
696 !ieee80211_vif_is_mesh(vif
)) {
697 skb_new
= alloc_skb(1, GFP_KERNEL
);
702 skb_new
= ieee80211_beacon_get(hw
, vif
);
708 static struct sk_buff
*rtw_nlo_info_get(struct ieee80211_hw
*hw
)
710 struct rtw_dev
*rtwdev
= hw
->priv
;
711 struct rtw_chip_info
*chip
= rtwdev
->chip
;
712 struct rtw_pno_request
*pno_req
= &rtwdev
->wow
.pno_req
;
713 struct rtw_nlo_info_hdr
*nlo_hdr
;
714 struct cfg80211_ssid
*ssid
;
720 if (!pno_req
->inited
|| !pno_req
->match_set_cnt
)
723 size
= sizeof(struct rtw_nlo_info_hdr
) + pno_req
->match_set_cnt
*
724 IEEE80211_MAX_SSID_LEN
+ chip
->tx_pkt_desc_sz
;
726 skb
= alloc_skb(size
, GFP_KERNEL
);
730 skb_reserve(skb
, chip
->tx_pkt_desc_sz
);
732 nlo_hdr
= skb_put_zero(skb
, sizeof(struct rtw_nlo_info_hdr
));
734 nlo_hdr
->nlo_count
= pno_req
->match_set_cnt
;
735 nlo_hdr
->hidden_ap_count
= pno_req
->match_set_cnt
;
737 /* pattern check for firmware */
738 memset(nlo_hdr
->pattern_check
, 0xA5, FW_NLO_INFO_CHECK_SIZE
);
740 for (i
= 0; i
< pno_req
->match_set_cnt
; i
++)
741 nlo_hdr
->ssid_len
[i
] = pno_req
->match_sets
[i
].ssid
.ssid_len
;
743 for (i
= 0; i
< pno_req
->match_set_cnt
; i
++) {
744 ssid
= &pno_req
->match_sets
[i
].ssid
;
745 loc
= rtw_get_rsvd_page_probe_req_location(rtwdev
, ssid
);
747 rtw_err(rtwdev
, "failed to get probe req rsvd loc\n");
751 nlo_hdr
->location
[i
] = loc
;
754 for (i
= 0; i
< pno_req
->match_set_cnt
; i
++) {
755 pos
= skb_put_zero(skb
, IEEE80211_MAX_SSID_LEN
);
756 memcpy(pos
, pno_req
->match_sets
[i
].ssid
.ssid
,
757 pno_req
->match_sets
[i
].ssid
.ssid_len
);
763 static struct sk_buff
*rtw_cs_channel_info_get(struct ieee80211_hw
*hw
)
765 struct rtw_dev
*rtwdev
= hw
->priv
;
766 struct rtw_chip_info
*chip
= rtwdev
->chip
;
767 struct rtw_pno_request
*pno_req
= &rtwdev
->wow
.pno_req
;
768 struct ieee80211_channel
*channels
= pno_req
->channels
;
770 int count
= pno_req
->channel_cnt
;
774 skb
= alloc_skb(4 * count
+ chip
->tx_pkt_desc_sz
, GFP_KERNEL
);
778 skb_reserve(skb
, chip
->tx_pkt_desc_sz
);
780 for (i
= 0; i
< count
; i
++) {
781 pos
= skb_put_zero(skb
, 4);
783 CHSW_INFO_SET_CH(pos
, channels
[i
].hw_value
);
785 if (channels
[i
].flags
& IEEE80211_CHAN_RADAR
)
786 CHSW_INFO_SET_ACTION_ID(pos
, 0);
788 CHSW_INFO_SET_ACTION_ID(pos
, 1);
789 CHSW_INFO_SET_TIMEOUT(pos
, 1);
790 CHSW_INFO_SET_PRI_CH_IDX(pos
, 1);
791 CHSW_INFO_SET_BW(pos
, 0);
797 static struct sk_buff
*rtw_lps_pg_dpk_get(struct ieee80211_hw
*hw
)
799 struct rtw_dev
*rtwdev
= hw
->priv
;
800 struct rtw_chip_info
*chip
= rtwdev
->chip
;
801 struct rtw_dpk_info
*dpk_info
= &rtwdev
->dm_info
.dpk_info
;
802 struct rtw_lps_pg_dpk_hdr
*dpk_hdr
;
806 size
= chip
->tx_pkt_desc_sz
+ sizeof(*dpk_hdr
);
807 skb
= alloc_skb(size
, GFP_KERNEL
);
811 skb_reserve(skb
, chip
->tx_pkt_desc_sz
);
812 dpk_hdr
= skb_put_zero(skb
, sizeof(*dpk_hdr
));
813 dpk_hdr
->dpk_ch
= dpk_info
->dpk_ch
;
814 dpk_hdr
->dpk_path_ok
= dpk_info
->dpk_path_ok
[0];
815 memcpy(dpk_hdr
->dpk_txagc
, dpk_info
->dpk_txagc
, 2);
816 memcpy(dpk_hdr
->dpk_gs
, dpk_info
->dpk_gs
, 4);
817 memcpy(dpk_hdr
->coef
, dpk_info
->coef
, 160);
822 static struct sk_buff
*rtw_lps_pg_info_get(struct ieee80211_hw
*hw
,
823 struct ieee80211_vif
*vif
)
825 struct rtw_dev
*rtwdev
= hw
->priv
;
826 struct rtw_chip_info
*chip
= rtwdev
->chip
;
827 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
828 struct rtw_lps_pg_info_hdr
*pg_info_hdr
;
829 struct rtw_wow_param
*rtw_wow
= &rtwdev
->wow
;
833 size
= chip
->tx_pkt_desc_sz
+ sizeof(*pg_info_hdr
);
834 skb
= alloc_skb(size
, GFP_KERNEL
);
838 skb_reserve(skb
, chip
->tx_pkt_desc_sz
);
839 pg_info_hdr
= skb_put_zero(skb
, sizeof(*pg_info_hdr
));
840 pg_info_hdr
->tx_bu_page_count
= rtwdev
->fifo
.rsvd_drv_pg_num
;
841 pg_info_hdr
->macid
= find_first_bit(rtwdev
->mac_id_map
, RTW_MAX_MAC_ID_NUM
);
842 pg_info_hdr
->sec_cam_count
=
843 rtw_sec_cam_pg_backup(rtwdev
, pg_info_hdr
->sec_cam
);
844 pg_info_hdr
->pattern_count
= rtw_wow
->pattern_cnt
;
846 conf
->sec_cam_backup
= pg_info_hdr
->sec_cam_count
!= 0;
847 conf
->pattern_cam_backup
= rtw_wow
->pattern_cnt
!= 0;
852 static struct sk_buff
*rtw_get_rsvd_page_skb(struct ieee80211_hw
*hw
,
853 struct ieee80211_vif
*vif
,
854 struct rtw_rsvd_page
*rsvd_pkt
)
856 struct sk_buff
*skb_new
;
857 struct cfg80211_ssid
*ssid
;
859 switch (rsvd_pkt
->type
) {
861 skb_new
= rtw_beacon_get(hw
, vif
);
864 skb_new
= ieee80211_pspoll_get(hw
, vif
);
866 case RSVD_PROBE_RESP
:
867 skb_new
= ieee80211_proberesp_get(hw
, vif
);
870 skb_new
= ieee80211_nullfunc_get(hw
, vif
, false);
873 skb_new
= ieee80211_nullfunc_get(hw
, vif
, true);
875 case RSVD_LPS_PG_DPK
:
876 skb_new
= rtw_lps_pg_dpk_get(hw
);
878 case RSVD_LPS_PG_INFO
:
879 skb_new
= rtw_lps_pg_info_get(hw
, vif
);
882 ssid
= (struct cfg80211_ssid
*)rsvd_pkt
->ssid
;
884 skb_new
= ieee80211_probereq_get(hw
, vif
->addr
,
888 skb_new
= ieee80211_probereq_get(hw
, vif
->addr
, NULL
, 0, 0);
891 skb_new
= rtw_nlo_info_get(hw
);
894 skb_new
= rtw_cs_channel_info_get(hw
);
906 static void rtw_fill_rsvd_page_desc(struct rtw_dev
*rtwdev
, struct sk_buff
*skb
)
908 struct rtw_tx_pkt_info pkt_info
;
909 struct rtw_chip_info
*chip
= rtwdev
->chip
;
912 memset(&pkt_info
, 0, sizeof(pkt_info
));
913 rtw_rsvd_page_pkt_info_update(rtwdev
, &pkt_info
, skb
);
914 pkt_desc
= skb_push(skb
, chip
->tx_pkt_desc_sz
);
915 memset(pkt_desc
, 0, chip
->tx_pkt_desc_sz
);
916 rtw_tx_fill_tx_desc(&pkt_info
, skb
);
919 static inline u8
rtw_len_to_page(unsigned int len
, u8 page_size
)
921 return DIV_ROUND_UP(len
, page_size
);
924 static void rtw_rsvd_page_list_to_buf(struct rtw_dev
*rtwdev
, u8 page_size
,
925 u8 page_margin
, u32 page
, u8
*buf
,
926 struct rtw_rsvd_page
*rsvd_pkt
)
928 struct sk_buff
*skb
= rsvd_pkt
->skb
;
931 memcpy(buf
+ page_margin
+ page_size
* (page
- 1),
932 skb
->data
, skb
->len
);
934 memcpy(buf
, skb
->data
, skb
->len
);
937 static struct rtw_rsvd_page
*rtw_alloc_rsvd_page(struct rtw_dev
*rtwdev
,
938 enum rtw_rsvd_packet_type type
,
941 struct rtw_rsvd_page
*rsvd_pkt
= NULL
;
943 rsvd_pkt
= kzalloc(sizeof(*rsvd_pkt
), GFP_KERNEL
);
948 rsvd_pkt
->type
= type
;
949 rsvd_pkt
->add_txdesc
= txdesc
;
954 static void rtw_insert_rsvd_page(struct rtw_dev
*rtwdev
,
955 struct rtw_rsvd_page
*rsvd_pkt
)
957 lockdep_assert_held(&rtwdev
->mutex
);
958 list_add_tail(&rsvd_pkt
->list
, &rtwdev
->rsvd_page_list
);
961 void rtw_add_rsvd_page(struct rtw_dev
*rtwdev
, enum rtw_rsvd_packet_type type
,
964 struct rtw_rsvd_page
*rsvd_pkt
;
966 rsvd_pkt
= rtw_alloc_rsvd_page(rtwdev
, type
, txdesc
);
970 rtw_insert_rsvd_page(rtwdev
, rsvd_pkt
);
973 void rtw_add_rsvd_page_probe_req(struct rtw_dev
*rtwdev
,
974 struct cfg80211_ssid
*ssid
)
976 struct rtw_rsvd_page
*rsvd_pkt
;
978 rsvd_pkt
= rtw_alloc_rsvd_page(rtwdev
, RSVD_PROBE_REQ
, true);
982 rsvd_pkt
->ssid
= ssid
;
983 rtw_insert_rsvd_page(rtwdev
, rsvd_pkt
);
986 void rtw_reset_rsvd_page(struct rtw_dev
*rtwdev
)
988 struct rtw_rsvd_page
*rsvd_pkt
, *tmp
;
990 lockdep_assert_held(&rtwdev
->mutex
);
992 list_for_each_entry_safe(rsvd_pkt
, tmp
, &rtwdev
->rsvd_page_list
, list
) {
993 if (rsvd_pkt
->type
== RSVD_BEACON
)
995 list_del(&rsvd_pkt
->list
);
1000 int rtw_fw_write_data_rsvd_page(struct rtw_dev
*rtwdev
, u16 pg_addr
,
1008 lockdep_assert_held(&rtwdev
->mutex
);
1013 pg_addr
&= BIT_MASK_BCN_HEAD_1_V1
;
1014 rtw_write16(rtwdev
, REG_FIFOPAGE_CTRL_2
, pg_addr
| BIT_BCN_VALID_V1
);
1016 val
= rtw_read8(rtwdev
, REG_CR
+ 1);
1018 val
|= BIT_ENSWBCN
>> 8;
1019 rtw_write8(rtwdev
, REG_CR
+ 1, val
);
1021 val
= rtw_read8(rtwdev
, REG_FWHW_TXQ_CTRL
+ 2);
1023 val
&= ~(BIT_EN_BCNQ_DL
>> 16);
1024 rtw_write8(rtwdev
, REG_FWHW_TXQ_CTRL
+ 2, val
);
1026 ret
= rtw_hci_write_data_rsvd_page(rtwdev
, buf
, size
);
1028 rtw_err(rtwdev
, "failed to write data to rsvd page\n");
1032 if (!check_hw_ready(rtwdev
, REG_FIFOPAGE_CTRL_2
, BIT_BCN_VALID_V1
, 1)) {
1033 rtw_err(rtwdev
, "error beacon valid\n");
1038 rsvd_pg_head
= rtwdev
->fifo
.rsvd_boundary
;
1039 rtw_write16(rtwdev
, REG_FIFOPAGE_CTRL_2
,
1040 rsvd_pg_head
| BIT_BCN_VALID_V1
);
1041 rtw_write8(rtwdev
, REG_FWHW_TXQ_CTRL
+ 2, bckp
[1]);
1042 rtw_write8(rtwdev
, REG_CR
+ 1, bckp
[0]);
1047 static int rtw_download_drv_rsvd_page(struct rtw_dev
*rtwdev
, u8
*buf
, u32 size
)
1053 pg_size
= rtwdev
->chip
->page_size
;
1054 pg_num
= size
/ pg_size
+ ((size
& (pg_size
- 1)) ? 1 : 0);
1055 if (pg_num
> rtwdev
->fifo
.rsvd_drv_pg_num
)
1058 pg_addr
= rtwdev
->fifo
.rsvd_drv_addr
;
1060 return rtw_fw_write_data_rsvd_page(rtwdev
, pg_addr
, buf
, size
);
1063 static u8
*rtw_build_rsvd_page(struct rtw_dev
*rtwdev
,
1064 struct ieee80211_vif
*vif
, u32
*size
)
1066 struct ieee80211_hw
*hw
= rtwdev
->hw
;
1067 struct rtw_chip_info
*chip
= rtwdev
->chip
;
1068 struct sk_buff
*iter
;
1069 struct rtw_rsvd_page
*rsvd_pkt
;
1072 u8 page_size
, page_margin
, tx_desc_sz
;
1075 page_size
= chip
->page_size
;
1076 tx_desc_sz
= chip
->tx_pkt_desc_sz
;
1077 page_margin
= page_size
- tx_desc_sz
;
1079 list_for_each_entry(rsvd_pkt
, &rtwdev
->rsvd_page_list
, list
) {
1080 iter
= rtw_get_rsvd_page_skb(hw
, vif
, rsvd_pkt
);
1082 rtw_err(rtwdev
, "failed to build rsvd packet\n");
1086 /* Fill the tx_desc for the rsvd pkt that requires one.
1087 * And iter->len will be added with size of tx_desc_sz.
1089 if (rsvd_pkt
->add_txdesc
)
1090 rtw_fill_rsvd_page_desc(rtwdev
, iter
);
1092 rsvd_pkt
->skb
= iter
;
1093 rsvd_pkt
->page
= total_page
;
1095 /* Reserved page is downloaded via TX path, and TX path will
1096 * generate a tx_desc at the header to describe length of
1097 * the buffer. If we are not counting page numbers with the
1098 * size of tx_desc added at the first rsvd_pkt (usually a
1099 * beacon, firmware default refer to the first page as the
1100 * content of beacon), we could generate a buffer which size
1101 * is smaller than the actual size of the whole rsvd_page
1103 if (total_page
== 0) {
1104 if (rsvd_pkt
->type
!= RSVD_BEACON
) {
1105 rtw_err(rtwdev
, "first page should be a beacon\n");
1108 total_page
+= rtw_len_to_page(iter
->len
+ tx_desc_sz
,
1111 total_page
+= rtw_len_to_page(iter
->len
, page_size
);
1115 if (total_page
> rtwdev
->fifo
.rsvd_drv_pg_num
) {
1116 rtw_err(rtwdev
, "rsvd page over size: %d\n", total_page
);
1120 *size
= (total_page
- 1) * page_size
+ page_margin
;
1121 buf
= kzalloc(*size
, GFP_KERNEL
);
1125 /* Copy the content of each rsvd_pkt to the buf, and they should
1126 * be aligned to the pages.
1128 * Note that the first rsvd_pkt is a beacon no matter what vif->type.
1129 * And that rsvd_pkt does not require tx_desc because when it goes
1130 * through TX path, the TX path will generate one for it.
1132 list_for_each_entry(rsvd_pkt
, &rtwdev
->rsvd_page_list
, list
) {
1133 rtw_rsvd_page_list_to_buf(rtwdev
, page_size
, page_margin
,
1134 page
, buf
, rsvd_pkt
);
1136 page
+= rtw_len_to_page(rsvd_pkt
->skb
->len
+
1137 tx_desc_sz
, page_size
);
1139 page
+= rtw_len_to_page(rsvd_pkt
->skb
->len
, page_size
);
1141 kfree_skb(rsvd_pkt
->skb
);
1142 rsvd_pkt
->skb
= NULL
;
1148 list_for_each_entry(rsvd_pkt
, &rtwdev
->rsvd_page_list
, list
) {
1149 kfree_skb(rsvd_pkt
->skb
);
1150 rsvd_pkt
->skb
= NULL
;
1157 rtw_download_beacon(struct rtw_dev
*rtwdev
, struct ieee80211_vif
*vif
)
1159 struct ieee80211_hw
*hw
= rtwdev
->hw
;
1160 struct sk_buff
*skb
;
1163 skb
= rtw_beacon_get(hw
, vif
);
1165 rtw_err(rtwdev
, "failed to get beacon skb\n");
1170 ret
= rtw_download_drv_rsvd_page(rtwdev
, skb
->data
, skb
->len
);
1172 rtw_err(rtwdev
, "failed to download drv rsvd page\n");
1180 int rtw_fw_download_rsvd_page(struct rtw_dev
*rtwdev
, struct ieee80211_vif
*vif
)
1186 buf
= rtw_build_rsvd_page(rtwdev
, vif
, &size
);
1188 rtw_err(rtwdev
, "failed to build rsvd page pkt\n");
1192 ret
= rtw_download_drv_rsvd_page(rtwdev
, buf
, size
);
1194 rtw_err(rtwdev
, "failed to download drv rsvd page\n");
1198 /* The last thing is to download the *ONLY* beacon again, because
1199 * the previous tx_desc is to describe the total rsvd page. Download
1200 * the beacon again to replace the TX desc header, and we will get
1201 * a correct tx_desc for the beacon in the rsvd page.
1203 ret
= rtw_download_beacon(rtwdev
, vif
);
1205 rtw_err(rtwdev
, "failed to download beacon\n");
1215 int rtw_dump_drv_rsvd_page(struct rtw_dev
*rtwdev
,
1216 u32 offset
, u32 size
, u32
*buf
)
1218 struct rtw_fifo_conf
*fifo
= &rtwdev
->fifo
;
1226 rtw_warn(rtwdev
, "should be 4-byte aligned\n");
1230 offset
+= fifo
->rsvd_boundary
<< TX_PAGE_SIZE_SHIFT
;
1231 residue
= offset
& (FIFO_PAGE_SIZE
- 1);
1232 start_pg
= offset
>> FIFO_PAGE_SIZE_SHIFT
;
1233 start_pg
+= RSVD_PAGE_START_ADDR
;
1235 rcr
= rtw_read8(rtwdev
, REG_RCR
+ 2);
1236 ctl
= rtw_read16(rtwdev
, REG_PKTBUF_DBG_CTRL
) & 0xf000;
1238 /* disable rx clock gate */
1239 rtw_write8(rtwdev
, REG_RCR
, rcr
| BIT(3));
1242 rtw_write16(rtwdev
, REG_PKTBUF_DBG_CTRL
, start_pg
| ctl
);
1244 for (i
= FIFO_DUMP_ADDR
+ residue
;
1245 i
< FIFO_DUMP_ADDR
+ FIFO_PAGE_SIZE
; i
+= 4) {
1246 buf
[idx
++] = rtw_read32(rtwdev
, i
);
1257 rtw_write16(rtwdev
, REG_PKTBUF_DBG_CTRL
, ctl
);
1258 rtw_write8(rtwdev
, REG_RCR
+ 2, rcr
);
1262 static void __rtw_fw_update_pkt(struct rtw_dev
*rtwdev
, u8 pkt_id
, u16 size
,
1265 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
1266 u16 total_size
= H2C_PKT_HDR_SIZE
+ H2C_PKT_UPDATE_PKT_LEN
;
1268 rtw_h2c_pkt_set_header(h2c_pkt
, H2C_PKT_UPDATE_PKT
);
1270 SET_PKT_H2C_TOTAL_LEN(h2c_pkt
, total_size
);
1271 UPDATE_PKT_SET_PKT_ID(h2c_pkt
, pkt_id
);
1272 UPDATE_PKT_SET_LOCATION(h2c_pkt
, location
);
1274 /* include txdesc size */
1275 UPDATE_PKT_SET_SIZE(h2c_pkt
, size
);
1277 rtw_fw_send_h2c_packet(rtwdev
, h2c_pkt
);
1280 void rtw_fw_update_pkt_probe_req(struct rtw_dev
*rtwdev
,
1281 struct cfg80211_ssid
*ssid
)
1286 loc
= rtw_get_rsvd_page_probe_req_location(rtwdev
, ssid
);
1288 rtw_err(rtwdev
, "failed to get probe_req rsvd loc\n");
1292 size
= rtw_get_rsvd_page_probe_req_size(rtwdev
, ssid
);
1294 rtw_err(rtwdev
, "failed to get probe_req rsvd size\n");
1298 __rtw_fw_update_pkt(rtwdev
, RTW_PACKET_PROBE_REQ
, size
, loc
);
1301 void rtw_fw_channel_switch(struct rtw_dev
*rtwdev
, bool enable
)
1303 struct rtw_pno_request
*rtw_pno_req
= &rtwdev
->wow
.pno_req
;
1304 u8 h2c_pkt
[H2C_PKT_SIZE
] = {0};
1305 u16 total_size
= H2C_PKT_HDR_SIZE
+ H2C_PKT_CH_SWITCH_LEN
;
1307 const struct rtw_ch_switch_option cs_option
= {
1310 .periodic_option
= 2,
1312 .normal_period_sel
= 0,
1315 .slow_period_sel
= 1,
1318 rtw_h2c_pkt_set_header(h2c_pkt
, H2C_PKT_CH_SWITCH
);
1319 SET_PKT_H2C_TOTAL_LEN(h2c_pkt
, total_size
);
1321 CH_SWITCH_SET_START(h2c_pkt
, enable
);
1322 CH_SWITCH_SET_DEST_CH_EN(h2c_pkt
, cs_option
.dest_ch_en
);
1323 CH_SWITCH_SET_DEST_CH(h2c_pkt
, cs_option
.dest_ch
);
1324 CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt
, cs_option
.normal_period
);
1325 CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt
, cs_option
.normal_period_sel
);
1326 CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt
, cs_option
.slow_period
);
1327 CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt
, cs_option
.slow_period_sel
);
1328 CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt
, cs_option
.normal_cycle
);
1329 CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt
, cs_option
.periodic_option
);
1331 CH_SWITCH_SET_CH_NUM(h2c_pkt
, rtw_pno_req
->channel_cnt
);
1332 CH_SWITCH_SET_INFO_SIZE(h2c_pkt
, rtw_pno_req
->channel_cnt
* 4);
1334 loc_ch_info
= rtw_get_rsvd_page_location(rtwdev
, RSVD_CH_INFO
);
1335 CH_SWITCH_SET_INFO_LOC(h2c_pkt
, loc_ch_info
);
1337 rtw_fw_send_h2c_packet(rtwdev
, h2c_pkt
);