linux/drivers/net/wireless/realtek/rtw88/fw.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2/* Copyright(c) 2018-2019  Realtek Corporation
   3 */
   4
   5#include "main.h"
   6#include "coex.h"
   7#include "fw.h"
   8#include "tx.h"
   9#include "reg.h"
  10#include "sec.h"
  11#include "debug.h"
  12#include "util.h"
  13#include "wow.h"
  14
  15static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,
  16                                      struct sk_buff *skb)
  17{
  18        struct rtw_c2h_cmd *c2h;
  19        u8 sub_cmd_id;
  20
  21        c2h = get_c2h_from_skb(skb);
  22        sub_cmd_id = c2h->payload[0];
  23
  24        switch (sub_cmd_id) {
  25        case C2H_CCX_RPT:
  26                rtw_tx_report_handle(rtwdev, skb);
  27                break;
  28        default:
  29                break;
  30        }
  31}
  32
  33static u16 get_max_amsdu_len(u32 bit_rate)
  34{
  35        /* lower than ofdm, do not aggregate */
  36        if (bit_rate < 550)
  37                return 1;
  38
  39        /* lower than 20M 2ss mcs8, make it small */
  40        if (bit_rate < 1800)
  41                return 1200;
  42
  43        /* lower than 40M 2ss mcs9, make it medium */
  44        if (bit_rate < 4000)
  45                return 2600;
  46
  47        /* not yet 80M 2ss mcs8/9, make it twice regular packet size */
  48        if (bit_rate < 7000)
  49                return 3500;
  50
  51        /* unlimited */
  52        return 0;
  53}
  54
  55struct rtw_fw_iter_ra_data {
  56        struct rtw_dev *rtwdev;
  57        u8 *payload;
  58};
  59
  60static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
  61{
  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;
  65        u8 mcs, nss;
  66        u32 bit_rate;
  67
  68        mac_id = GET_RA_REPORT_MACID(ra_data->payload);
  69        if (si->mac_id != mac_id)
  70                return;
  71
  72        si->ra_report.txrate.flags = 0;
  73
  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);
  77
  78        if (rate < DESC_RATEMCS0) {
  79                si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate);
  80                goto legacy;
  81        }
  82
  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;
  88
  89        if (rate >= DESC_RATEMCS0) {
  90                si->ra_report.txrate.mcs = mcs;
  91                si->ra_report.txrate.nss = nss;
  92        }
  93
  94        if (sgi)
  95                si->ra_report.txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
  96
  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;
 101        else
 102                si->ra_report.txrate.bw = RATE_INFO_BW_20;
 103
 104legacy:
 105        bit_rate = cfg80211_calculate_bitrate(&si->ra_report.txrate);
 106
 107        si->ra_report.desc_rate = rate;
 108        si->ra_report.bit_rate = bit_rate;
 109
 110        sta->max_rc_amsdu_len = get_max_amsdu_len(bit_rate);
 111}
 112
 113static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload,
 114                                    u8 length)
 115{
 116        struct rtw_fw_iter_ra_data ra_data;
 117
 118        if (WARN(length < 7, "invalid ra report c2h length\n"))
 119                return;
 120
 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);
 125}
 126
 127void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
 128{
 129        struct rtw_c2h_cmd *c2h;
 130        u32 pkt_offset;
 131        u8 len;
 132
 133        pkt_offset = *((u32 *)skb->cb);
 134        c2h = (struct rtw_c2h_cmd *)(skb->data + pkt_offset);
 135        len = skb->len - pkt_offset - 2;
 136
 137        mutex_lock(&rtwdev->mutex);
 138
 139        if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags))
 140                goto unlock;
 141
 142        switch (c2h->id) {
 143        case C2H_BT_INFO:
 144                rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
 145                break;
 146        case C2H_WLAN_INFO:
 147                rtw_coex_wl_fwdbginfo_notify(rtwdev, c2h->payload, len);
 148                break;
 149        case C2H_HALMAC:
 150                rtw_fw_c2h_cmd_handle_ext(rtwdev, skb);
 151                break;
 152        case C2H_RA_RPT:
 153                rtw_fw_ra_report_handle(rtwdev, c2h->payload, len);
 154                break;
 155        default:
 156                break;
 157        }
 158
 159unlock:
 160        mutex_unlock(&rtwdev->mutex);
 161}
 162
 163void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
 164                               struct sk_buff *skb)
 165{
 166        struct rtw_c2h_cmd *c2h;
 167        u8 len;
 168
 169        c2h = (struct rtw_c2h_cmd *)(skb->data + pkt_offset);
 170        len = skb->len - pkt_offset - 2;
 171        *((u32 *)skb->cb) = pkt_offset;
 172
 173        rtw_dbg(rtwdev, RTW_DBG_FW, "recv C2H, id=0x%02x, seq=0x%02x, len=%d\n",
 174                c2h->id, c2h->seq, len);
 175
 176        switch (c2h->id) {
 177        case C2H_BT_MP_INFO:
 178                rtw_coex_info_response(rtwdev, skb);
 179                break;
 180        default:
 181                /* pass offset for further operation */
 182                *((u32 *)skb->cb) = pkt_offset;
 183                skb_queue_tail(&rtwdev->c2h_queue, skb);
 184                ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
 185                break;
 186        }
 187}
 188EXPORT_SYMBOL(rtw_fw_c2h_cmd_rx_irqsafe);
 189
 190static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 191                                    u8 *h2c)
 192{
 193        u8 box;
 194        u8 box_state;
 195        u32 box_reg, box_ex_reg;
 196        u32 h2c_wait;
 197        int idx;
 198
 199        rtw_dbg(rtwdev, RTW_DBG_FW,
 200                "send H2C content %02x%02x%02x%02x %02x%02x%02x%02x\n",
 201                h2c[3], h2c[2], h2c[1], h2c[0],
 202                h2c[7], h2c[6], h2c[5], h2c[4]);
 203
 204        spin_lock(&rtwdev->h2c.lock);
 205
 206        box = rtwdev->h2c.last_box_num;
 207        switch (box) {
 208        case 0:
 209                box_reg = REG_HMEBOX0;
 210                box_ex_reg = REG_HMEBOX0_EX;
 211                break;
 212        case 1:
 213                box_reg = REG_HMEBOX1;
 214                box_ex_reg = REG_HMEBOX1_EX;
 215                break;
 216        case 2:
 217                box_reg = REG_HMEBOX2;
 218                box_ex_reg = REG_HMEBOX2_EX;
 219                break;
 220        case 3:
 221                box_reg = REG_HMEBOX3;
 222                box_ex_reg = REG_HMEBOX3_EX;
 223                break;
 224        default:
 225                WARN(1, "invalid h2c mail box number\n");
 226                goto out;
 227        }
 228
 229        h2c_wait = 20;
 230        do {
 231                box_state = rtw_read8(rtwdev, REG_HMETFR);
 232        } while ((box_state >> box) & 0x1 && --h2c_wait > 0);
 233
 234        if (!h2c_wait) {
 235                rtw_err(rtwdev, "failed to send h2c command\n");
 236                goto out;
 237        }
 238
 239        for (idx = 0; idx < 4; idx++)
 240                rtw_write8(rtwdev, box_reg + idx, h2c[idx]);
 241        for (idx = 0; idx < 4; idx++)
 242                rtw_write8(rtwdev, box_ex_reg + idx, h2c[idx + 4]);
 243
 244        if (++rtwdev->h2c.last_box_num >= 4)
 245                rtwdev->h2c.last_box_num = 0;
 246
 247out:
 248        spin_unlock(&rtwdev->h2c.lock);
 249}
 250
 251static void rtw_fw_send_h2c_packet(struct rtw_dev *rtwdev, u8 *h2c_pkt)
 252{
 253        int ret;
 254
 255        spin_lock(&rtwdev->h2c.lock);
 256
 257        FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq);
 258        ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE);
 259        if (ret)
 260                rtw_err(rtwdev, "failed to send h2c packet\n");
 261        rtwdev->h2c.seq++;
 262
 263        spin_unlock(&rtwdev->h2c.lock);
 264}
 265
 266void
 267rtw_fw_send_general_info(struct rtw_dev *rtwdev)
 268{
 269        struct rtw_fifo_conf *fifo = &rtwdev->fifo;
 270        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 271        u16 total_size = H2C_PKT_HDR_SIZE + 4;
 272
 273        rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO);
 274
 275        SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size);
 276
 277        GENERAL_INFO_SET_FW_TX_BOUNDARY(h2c_pkt,
 278                                        fifo->rsvd_fw_txbuf_addr -
 279                                        fifo->rsvd_boundary);
 280
 281        rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
 282}
 283
 284void
 285rtw_fw_send_phydm_info(struct rtw_dev *rtwdev)
 286{
 287        struct rtw_hal *hal = &rtwdev->hal;
 288        struct rtw_efuse *efuse = &rtwdev->efuse;
 289        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 290        u16 total_size = H2C_PKT_HDR_SIZE + 8;
 291        u8 fw_rf_type = 0;
 292
 293        if (hal->rf_type == RF_1T1R)
 294                fw_rf_type = FW_RF_1T1R;
 295        else if (hal->rf_type == RF_2T2R)
 296                fw_rf_type = FW_RF_2T2R;
 297
 298        rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_PHYDM_INFO);
 299
 300        SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size);
 301        PHYDM_INFO_SET_REF_TYPE(h2c_pkt, efuse->rfe_option);
 302        PHYDM_INFO_SET_RF_TYPE(h2c_pkt, fw_rf_type);
 303        PHYDM_INFO_SET_CUT_VER(h2c_pkt, hal->cut_version);
 304        PHYDM_INFO_SET_RX_ANT_STATUS(h2c_pkt, hal->antenna_tx);
 305        PHYDM_INFO_SET_TX_ANT_STATUS(h2c_pkt, hal->antenna_rx);
 306
 307        rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
 308}
 309
 310void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para)
 311{
 312        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 313        u16 total_size = H2C_PKT_HDR_SIZE + 1;
 314
 315        rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_IQK);
 316        SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size);
 317        IQK_SET_CLEAR(h2c_pkt, para->clear);
 318        IQK_SET_SEGMENT_IQK(h2c_pkt, para->segment_iqk);
 319
 320        rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
 321}
 322
 323void rtw_fw_query_bt_info(struct rtw_dev *rtwdev)
 324{
 325        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 326
 327        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_INFO);
 328
 329        SET_QUERY_BT_INFO(h2c_pkt, true);
 330
 331        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 332}
 333
 334void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw)
 335{
 336        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 337
 338        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WL_CH_INFO);
 339
 340        SET_WL_CH_INFO_LINK(h2c_pkt, link);
 341        SET_WL_CH_INFO_CHNL(h2c_pkt, ch);
 342        SET_WL_CH_INFO_BW(h2c_pkt, bw);
 343
 344        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 345}
 346
 347void rtw_fw_query_bt_mp_info(struct rtw_dev *rtwdev,
 348                             struct rtw_coex_info_req *req)
 349{
 350        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 351
 352        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_MP_INFO);
 353
 354        SET_BT_MP_INFO_SEQ(h2c_pkt, req->seq);
 355        SET_BT_MP_INFO_OP_CODE(h2c_pkt, req->op_code);
 356        SET_BT_MP_INFO_PARA1(h2c_pkt, req->para1);
 357        SET_BT_MP_INFO_PARA2(h2c_pkt, req->para2);
 358        SET_BT_MP_INFO_PARA3(h2c_pkt, req->para3);
 359
 360        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 361}
 362
 363void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl)
 364{
 365        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 366        u8 index = 0 - bt_pwr_dec_lvl;
 367
 368        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_FORCE_BT_TX_POWER);
 369
 370        SET_BT_TX_POWER_INDEX(h2c_pkt, index);
 371
 372        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 373}
 374
 375void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable)
 376{
 377        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 378
 379        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_IGNORE_WLAN_ACTION);
 380
 381        SET_IGNORE_WLAN_ACTION_EN(h2c_pkt, enable);
 382
 383        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 384}
 385
 386void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev,
 387                           u8 para1, u8 para2, u8 para3, u8 para4, u8 para5)
 388{
 389        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 390
 391        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_COEX_TDMA_TYPE);
 392
 393        SET_COEX_TDMA_TYPE_PARA1(h2c_pkt, para1);
 394        SET_COEX_TDMA_TYPE_PARA2(h2c_pkt, para2);
 395        SET_COEX_TDMA_TYPE_PARA3(h2c_pkt, para3);
 396        SET_COEX_TDMA_TYPE_PARA4(h2c_pkt, para4);
 397        SET_COEX_TDMA_TYPE_PARA5(h2c_pkt, para5);
 398
 399        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 400}
 401
 402void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data)
 403{
 404        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 405
 406        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BT_WIFI_CONTROL);
 407
 408        SET_BT_WIFI_CONTROL_OP_CODE(h2c_pkt, op_code);
 409
 410        SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, *data);
 411        SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, *(data + 1));
 412        SET_BT_WIFI_CONTROL_DATA3(h2c_pkt, *(data + 2));
 413        SET_BT_WIFI_CONTROL_DATA4(h2c_pkt, *(data + 3));
 414        SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, *(data + 4));
 415
 416        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 417}
 418
 419void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
 420{
 421        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 422        u8 rssi = ewma_rssi_read(&si->avg_rssi);
 423        bool stbc_en = si->stbc_en ? true : false;
 424
 425        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RSSI_MONITOR);
 426
 427        SET_RSSI_INFO_MACID(h2c_pkt, si->mac_id);
 428        SET_RSSI_INFO_RSSI(h2c_pkt, rssi);
 429        SET_RSSI_INFO_STBC(h2c_pkt, stbc_en);
 430
 431        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 432}
 433
 434void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
 435{
 436        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 437        bool no_update = si->updated;
 438        bool disable_pt = true;
 439
 440        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
 441
 442        SET_RA_INFO_MACID(h2c_pkt, si->mac_id);
 443        SET_RA_INFO_RATE_ID(h2c_pkt, si->rate_id);
 444        SET_RA_INFO_INIT_RA_LVL(h2c_pkt, si->init_ra_lv);
 445        SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable);
 446        SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode);
 447        SET_RA_INFO_LDPC(h2c_pkt, si->ldpc_en);
 448        SET_RA_INFO_NO_UPDATE(h2c_pkt, no_update);
 449        SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable);
 450        SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt);
 451        SET_RA_INFO_RA_MASK0(h2c_pkt, (si->ra_mask & 0xff));
 452        SET_RA_INFO_RA_MASK1(h2c_pkt, (si->ra_mask & 0xff00) >> 8);
 453        SET_RA_INFO_RA_MASK2(h2c_pkt, (si->ra_mask & 0xff0000) >> 16);
 454        SET_RA_INFO_RA_MASK3(h2c_pkt, (si->ra_mask & 0xff000000) >> 24);
 455
 456        si->init_ra_lv = 0;
 457        si->updated = true;
 458
 459        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 460}
 461
 462void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect)
 463{
 464        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 465
 466        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_MEDIA_STATUS_RPT);
 467        MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, connect);
 468        MEDIA_STATUS_RPT_SET_MACID(h2c_pkt, mac_id);
 469
 470        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 471}
 472
 473void rtw_fw_set_pwr_mode(struct rtw_dev *rtwdev)
 474{
 475        struct rtw_lps_conf *conf = &rtwdev->lps_conf;
 476        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 477
 478        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_SET_PWR_MODE);
 479
 480        SET_PWR_MODE_SET_MODE(h2c_pkt, conf->mode);
 481        SET_PWR_MODE_SET_RLBM(h2c_pkt, conf->rlbm);
 482        SET_PWR_MODE_SET_SMART_PS(h2c_pkt, conf->smart_ps);
 483        SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_pkt, conf->awake_interval);
 484        SET_PWR_MODE_SET_PORT_ID(h2c_pkt, conf->port_id);
 485        SET_PWR_MODE_SET_PWR_STATE(h2c_pkt, conf->state);
 486
 487        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 488}
 489
 490void rtw_fw_set_keep_alive_cmd(struct rtw_dev *rtwdev, bool enable)
 491{
 492        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 493        struct rtw_fw_wow_keep_alive_para mode = {
 494                .adopt = true,
 495                .pkt_type = KEEP_ALIVE_NULL_PKT,
 496                .period = 5,
 497        };
 498
 499        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_KEEP_ALIVE);
 500        SET_KEEP_ALIVE_ENABLE(h2c_pkt, enable);
 501        SET_KEEP_ALIVE_ADOPT(h2c_pkt, mode.adopt);
 502        SET_KEEP_ALIVE_PKT_TYPE(h2c_pkt, mode.pkt_type);
 503        SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt, mode.period);
 504
 505        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 506}
 507
 508void rtw_fw_set_disconnect_decision_cmd(struct rtw_dev *rtwdev, bool enable)
 509{
 510        struct rtw_wow_param *rtw_wow = &rtwdev->wow;
 511        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 512        struct rtw_fw_wow_disconnect_para mode = {
 513                .adopt = true,
 514                .period = 30,
 515                .retry_count = 5,
 516        };
 517
 518        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_DISCONNECT_DECISION);
 519
 520        if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) {
 521                SET_DISCONNECT_DECISION_ENABLE(h2c_pkt, enable);
 522                SET_DISCONNECT_DECISION_ADOPT(h2c_pkt, mode.adopt);
 523                SET_DISCONNECT_DECISION_CHECK_PERIOD(h2c_pkt, mode.period);
 524                SET_DISCONNECT_DECISION_TRY_PKT_NUM(h2c_pkt, mode.retry_count);
 525        }
 526
 527        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 528}
 529
 530void rtw_fw_set_wowlan_ctrl_cmd(struct rtw_dev *rtwdev, bool enable)
 531{
 532        struct rtw_wow_param *rtw_wow = &rtwdev->wow;
 533        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 534
 535        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WOWLAN);
 536
 537        SET_WOWLAN_FUNC_ENABLE(h2c_pkt, enable);
 538        if (rtw_wow_mgd_linked(rtwdev)) {
 539                if (test_bit(RTW_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
 540                        SET_WOWLAN_MAGIC_PKT_ENABLE(h2c_pkt, enable);
 541                if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags))
 542                        SET_WOWLAN_DEAUTH_WAKEUP_ENABLE(h2c_pkt, enable);
 543                if (test_bit(RTW_WOW_FLAG_EN_REKEY_PKT, rtw_wow->flags))
 544                        SET_WOWLAN_REKEY_WAKEUP_ENABLE(h2c_pkt, enable);
 545                if (rtw_wow->pattern_cnt)
 546                        SET_WOWLAN_PATTERN_MATCH_ENABLE(h2c_pkt, enable);
 547        }
 548
 549        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 550}
 551
 552void rtw_fw_set_aoac_global_info_cmd(struct rtw_dev *rtwdev,
 553                                     u8 pairwise_key_enc,
 554                                     u8 group_key_enc)
 555{
 556        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 557
 558        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_AOAC_GLOBAL_INFO);
 559
 560        SET_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(h2c_pkt, pairwise_key_enc);
 561        SET_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(h2c_pkt, group_key_enc);
 562
 563        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 564}
 565
 566void rtw_fw_set_remote_wake_ctrl_cmd(struct rtw_dev *rtwdev, bool enable)
 567{
 568        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 569
 570        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_REMOTE_WAKE_CTRL);
 571
 572        SET_REMOTE_WAKECTRL_ENABLE(h2c_pkt, enable);
 573
 574        if (rtw_wow_no_link(rtwdev))
 575                SET_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(h2c_pkt, enable);
 576
 577        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 578}
 579
 580static u8 rtw_get_rsvd_page_location(struct rtw_dev *rtwdev,
 581                                     enum rtw_rsvd_packet_type type)
 582{
 583        struct rtw_rsvd_page *rsvd_pkt;
 584        u8 location = 0;
 585
 586        list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) {
 587                if (type == rsvd_pkt->type)
 588                        location = rsvd_pkt->page;
 589        }
 590
 591        return location;
 592}
 593
 594void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable)
 595{
 596        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 597        u8 loc_nlo;
 598
 599        loc_nlo = rtw_get_rsvd_page_location(rtwdev, RSVD_NLO_INFO);
 600
 601        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_NLO_INFO);
 602
 603        SET_NLO_FUN_EN(h2c_pkt, enable);
 604        if (enable) {
 605                if (rtw_fw_lps_deep_mode)
 606                        SET_NLO_PS_32K(h2c_pkt, enable);
 607                SET_NLO_IGNORE_SECURITY(h2c_pkt, enable);
 608                SET_NLO_LOC_NLO_INFO(h2c_pkt, loc_nlo);
 609        }
 610
 611        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 612}
 613
 614void rtw_fw_set_pg_info(struct rtw_dev *rtwdev)
 615{
 616        struct rtw_lps_conf *conf = &rtwdev->lps_conf;
 617        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 618        u8 loc_pg, loc_dpk;
 619
 620        loc_pg = rtw_get_rsvd_page_location(rtwdev, RSVD_LPS_PG_INFO);
 621        loc_dpk = rtw_get_rsvd_page_location(rtwdev, RSVD_LPS_PG_DPK);
 622
 623        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_LPS_PG_INFO);
 624
 625        LPS_PG_INFO_LOC(h2c_pkt, loc_pg);
 626        LPS_PG_DPK_LOC(h2c_pkt, loc_dpk);
 627        LPS_PG_SEC_CAM_EN(h2c_pkt, conf->sec_cam_backup);
 628        LPS_PG_PATTERN_CAM_EN(h2c_pkt, conf->pattern_cam_backup);
 629
 630        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 631}
 632
 633u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev,
 634                                        struct cfg80211_ssid *ssid)
 635{
 636        struct rtw_rsvd_page *rsvd_pkt;
 637        u8 location = 0;
 638
 639        list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) {
 640                if (rsvd_pkt->type != RSVD_PROBE_REQ)
 641                        continue;
 642                if ((!ssid && !rsvd_pkt->ssid) ||
 643                    rtw_ssid_equal(rsvd_pkt->ssid, ssid))
 644                        location = rsvd_pkt->page;
 645        }
 646
 647        return location;
 648}
 649
 650u16 rtw_get_rsvd_page_probe_req_size(struct rtw_dev *rtwdev,
 651                                     struct cfg80211_ssid *ssid)
 652{
 653        struct rtw_rsvd_page *rsvd_pkt;
 654        u16 size = 0;
 655
 656        list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) {
 657                if (rsvd_pkt->type != RSVD_PROBE_REQ)
 658                        continue;
 659                if ((!ssid && !rsvd_pkt->ssid) ||
 660                    rtw_ssid_equal(rsvd_pkt->ssid, ssid))
 661                        size = rsvd_pkt->skb->len;
 662        }
 663
 664        return size;
 665}
 666
 667void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev)
 668{
 669        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 670        u8 location = 0;
 671
 672        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RSVD_PAGE);
 673
 674        location = rtw_get_rsvd_page_location(rtwdev, RSVD_PROBE_RESP);
 675        *(h2c_pkt + 1) = location;
 676        rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_PROBE_RESP loc: %d\n", location);
 677
 678        location = rtw_get_rsvd_page_location(rtwdev, RSVD_PS_POLL);
 679        *(h2c_pkt + 2) = location;
 680        rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_PS_POLL loc: %d\n", location);
 681
 682        location = rtw_get_rsvd_page_location(rtwdev, RSVD_NULL);
 683        *(h2c_pkt + 3) = location;
 684        rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_NULL loc: %d\n", location);
 685
 686        location = rtw_get_rsvd_page_location(rtwdev, RSVD_QOS_NULL);
 687        *(h2c_pkt + 4) = location;
 688        rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_QOS_NULL loc: %d\n", location);
 689
 690        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 691}
 692
 693static struct sk_buff *rtw_nlo_info_get(struct ieee80211_hw *hw)
 694{
 695        struct rtw_dev *rtwdev = hw->priv;
 696        struct rtw_chip_info *chip = rtwdev->chip;
 697        struct rtw_pno_request *pno_req = &rtwdev->wow.pno_req;
 698        struct rtw_nlo_info_hdr *nlo_hdr;
 699        struct cfg80211_ssid *ssid;
 700        struct sk_buff *skb;
 701        u8 *pos, loc;
 702        u32 size;
 703        int i;
 704
 705        if (!pno_req->inited || !pno_req->match_set_cnt)
 706                return NULL;
 707
 708        size = sizeof(struct rtw_nlo_info_hdr) + pno_req->match_set_cnt *
 709                      IEEE80211_MAX_SSID_LEN + chip->tx_pkt_desc_sz;
 710
 711        skb = alloc_skb(size, GFP_KERNEL);
 712        if (!skb)
 713                return NULL;
 714
 715        skb_reserve(skb, chip->tx_pkt_desc_sz);
 716
 717        nlo_hdr = skb_put_zero(skb, sizeof(struct rtw_nlo_info_hdr));
 718
 719        nlo_hdr->nlo_count = pno_req->match_set_cnt;
 720        nlo_hdr->hidden_ap_count = pno_req->match_set_cnt;
 721
 722        /* pattern check for firmware */
 723        memset(nlo_hdr->pattern_check, 0xA5, FW_NLO_INFO_CHECK_SIZE);
 724
 725        for (i = 0; i < pno_req->match_set_cnt; i++)
 726                nlo_hdr->ssid_len[i] = pno_req->match_sets[i].ssid.ssid_len;
 727
 728        for (i = 0; i < pno_req->match_set_cnt; i++) {
 729                ssid = &pno_req->match_sets[i].ssid;
 730                loc  = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid);
 731                if (!loc) {
 732                        rtw_err(rtwdev, "failed to get probe req rsvd loc\n");
 733                        kfree_skb(skb);
 734                        return NULL;
 735                }
 736                nlo_hdr->location[i] = loc;
 737        }
 738
 739        for (i = 0; i < pno_req->match_set_cnt; i++) {
 740                pos = skb_put_zero(skb, IEEE80211_MAX_SSID_LEN);
 741                memcpy(pos, pno_req->match_sets[i].ssid.ssid,
 742                       pno_req->match_sets[i].ssid.ssid_len);
 743        }
 744
 745        return skb;
 746}
 747
 748static struct sk_buff *rtw_cs_channel_info_get(struct ieee80211_hw *hw)
 749{
 750        struct rtw_dev *rtwdev = hw->priv;
 751        struct rtw_chip_info *chip = rtwdev->chip;
 752        struct rtw_pno_request *pno_req = &rtwdev->wow.pno_req;
 753        struct ieee80211_channel *channels = pno_req->channels;
 754        struct sk_buff *skb;
 755        int count =  pno_req->channel_cnt;
 756        u8 *pos;
 757        int i = 0;
 758
 759        skb = alloc_skb(4 * count + chip->tx_pkt_desc_sz, GFP_KERNEL);
 760        if (!skb)
 761                return NULL;
 762
 763        skb_reserve(skb, chip->tx_pkt_desc_sz);
 764
 765        for (i = 0; i < count; i++) {
 766                pos = skb_put_zero(skb, 4);
 767
 768                CHSW_INFO_SET_CH(pos, channels[i].hw_value);
 769
 770                if (channels[i].flags & IEEE80211_CHAN_RADAR)
 771                        CHSW_INFO_SET_ACTION_ID(pos, 0);
 772                else
 773                        CHSW_INFO_SET_ACTION_ID(pos, 1);
 774                CHSW_INFO_SET_TIMEOUT(pos, 1);
 775                CHSW_INFO_SET_PRI_CH_IDX(pos, 1);
 776                CHSW_INFO_SET_BW(pos, 0);
 777        }
 778
 779        return skb;
 780}
 781
 782static struct sk_buff *rtw_lps_pg_dpk_get(struct ieee80211_hw *hw)
 783{
 784        struct rtw_dev *rtwdev = hw->priv;
 785        struct rtw_chip_info *chip = rtwdev->chip;
 786        struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
 787        struct rtw_lps_pg_dpk_hdr *dpk_hdr;
 788        struct sk_buff *skb;
 789        u32 size;
 790
 791        size = chip->tx_pkt_desc_sz + sizeof(*dpk_hdr);
 792        skb = alloc_skb(size, GFP_KERNEL);
 793        if (!skb)
 794                return NULL;
 795
 796        skb_reserve(skb, chip->tx_pkt_desc_sz);
 797        dpk_hdr = skb_put_zero(skb, sizeof(*dpk_hdr));
 798        dpk_hdr->dpk_ch = dpk_info->dpk_ch;
 799        dpk_hdr->dpk_path_ok = dpk_info->dpk_path_ok[0];
 800        memcpy(dpk_hdr->dpk_txagc, dpk_info->dpk_txagc, 2);
 801        memcpy(dpk_hdr->dpk_gs, dpk_info->dpk_gs, 4);
 802        memcpy(dpk_hdr->coef, dpk_info->coef, 160);
 803
 804        return skb;
 805}
 806
 807static struct sk_buff *rtw_lps_pg_info_get(struct ieee80211_hw *hw)
 808{
 809        struct rtw_dev *rtwdev = hw->priv;
 810        struct rtw_chip_info *chip = rtwdev->chip;
 811        struct rtw_lps_conf *conf = &rtwdev->lps_conf;
 812        struct rtw_lps_pg_info_hdr *pg_info_hdr;
 813        struct rtw_wow_param *rtw_wow = &rtwdev->wow;
 814        struct sk_buff *skb;
 815        u32 size;
 816
 817        size = chip->tx_pkt_desc_sz + sizeof(*pg_info_hdr);
 818        skb = alloc_skb(size, GFP_KERNEL);
 819        if (!skb)
 820                return NULL;
 821
 822        skb_reserve(skb, chip->tx_pkt_desc_sz);
 823        pg_info_hdr = skb_put_zero(skb, sizeof(*pg_info_hdr));
 824        pg_info_hdr->tx_bu_page_count = rtwdev->fifo.rsvd_drv_pg_num;
 825        pg_info_hdr->macid = find_first_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
 826        pg_info_hdr->sec_cam_count =
 827                rtw_sec_cam_pg_backup(rtwdev, pg_info_hdr->sec_cam);
 828        pg_info_hdr->pattern_count = rtw_wow->pattern_cnt;
 829
 830        conf->sec_cam_backup = pg_info_hdr->sec_cam_count != 0;
 831        conf->pattern_cam_backup = rtw_wow->pattern_cnt != 0;
 832
 833        return skb;
 834}
 835
 836static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
 837                                             struct rtw_rsvd_page *rsvd_pkt)
 838{
 839        struct ieee80211_vif *vif;
 840        struct rtw_vif *rtwvif;
 841        struct sk_buff *skb_new;
 842        struct cfg80211_ssid *ssid;
 843
 844        if (rsvd_pkt->type == RSVD_DUMMY) {
 845                skb_new = alloc_skb(1, GFP_KERNEL);
 846                if (!skb_new)
 847                        return NULL;
 848
 849                skb_put(skb_new, 1);
 850                return skb_new;
 851        }
 852
 853        rtwvif = rsvd_pkt->rtwvif;
 854        if (!rtwvif)
 855                return NULL;
 856
 857        vif = rtwvif_to_vif(rtwvif);
 858
 859        switch (rsvd_pkt->type) {
 860        case RSVD_BEACON:
 861                skb_new = ieee80211_beacon_get(hw, vif);
 862                break;
 863        case RSVD_PS_POLL:
 864                skb_new = ieee80211_pspoll_get(hw, vif);
 865                break;
 866        case RSVD_PROBE_RESP:
 867                skb_new = ieee80211_proberesp_get(hw, vif);
 868                break;
 869        case RSVD_NULL:
 870                skb_new = ieee80211_nullfunc_get(hw, vif, false);
 871                break;
 872        case RSVD_QOS_NULL:
 873                skb_new = ieee80211_nullfunc_get(hw, vif, true);
 874                break;
 875        case RSVD_LPS_PG_DPK:
 876                skb_new = rtw_lps_pg_dpk_get(hw);
 877                break;
 878        case RSVD_LPS_PG_INFO:
 879                skb_new = rtw_lps_pg_info_get(hw);
 880                break;
 881        case RSVD_PROBE_REQ:
 882                ssid = (struct cfg80211_ssid *)rsvd_pkt->ssid;
 883                if (ssid)
 884                        skb_new = ieee80211_probereq_get(hw, vif->addr,
 885                                                         ssid->ssid,
 886                                                         ssid->ssid_len, 0);
 887                else
 888                        skb_new = ieee80211_probereq_get(hw, vif->addr, NULL, 0, 0);
 889                break;
 890        case RSVD_NLO_INFO:
 891                skb_new = rtw_nlo_info_get(hw);
 892                break;
 893        case RSVD_CH_INFO:
 894                skb_new = rtw_cs_channel_info_get(hw);
 895                break;
 896        default:
 897                return NULL;
 898        }
 899
 900        if (!skb_new)
 901                return NULL;
 902
 903        return skb_new;
 904}
 905
 906static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb)
 907{
 908        struct rtw_tx_pkt_info pkt_info;
 909        struct rtw_chip_info *chip = rtwdev->chip;
 910        u8 *pkt_desc;
 911
 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);
 917}
 918
 919static inline u8 rtw_len_to_page(unsigned int len, u8 page_size)
 920{
 921        return DIV_ROUND_UP(len, page_size);
 922}
 923
 924static 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)
 927{
 928        struct sk_buff *skb = rsvd_pkt->skb;
 929
 930        if (page >= 1)
 931                memcpy(buf + page_margin + page_size * (page - 1),
 932                       skb->data, skb->len);
 933        else
 934                memcpy(buf, skb->data, skb->len);
 935}
 936
 937static struct rtw_rsvd_page *rtw_alloc_rsvd_page(struct rtw_dev *rtwdev,
 938                                                 enum rtw_rsvd_packet_type type,
 939                                                 bool txdesc)
 940{
 941        struct rtw_rsvd_page *rsvd_pkt = NULL;
 942
 943        rsvd_pkt = kzalloc(sizeof(*rsvd_pkt), GFP_KERNEL);
 944
 945        if (!rsvd_pkt)
 946                return NULL;
 947
 948        INIT_LIST_HEAD(&rsvd_pkt->vif_list);
 949        INIT_LIST_HEAD(&rsvd_pkt->build_list);
 950        rsvd_pkt->type = type;
 951        rsvd_pkt->add_txdesc = txdesc;
 952
 953        return rsvd_pkt;
 954}
 955
 956static void rtw_insert_rsvd_page(struct rtw_dev *rtwdev,
 957                                 struct rtw_vif *rtwvif,
 958                                 struct rtw_rsvd_page *rsvd_pkt)
 959{
 960        lockdep_assert_held(&rtwdev->mutex);
 961
 962        list_add_tail(&rsvd_pkt->vif_list, &rtwvif->rsvd_page_list);
 963}
 964
 965static void rtw_add_rsvd_page(struct rtw_dev *rtwdev,
 966                              struct rtw_vif *rtwvif,
 967                              enum rtw_rsvd_packet_type type,
 968                              bool txdesc)
 969{
 970        struct rtw_rsvd_page *rsvd_pkt;
 971
 972        rsvd_pkt = rtw_alloc_rsvd_page(rtwdev, type, txdesc);
 973        if (!rsvd_pkt) {
 974                rtw_err(rtwdev, "failed to alloc rsvd page %d\n", type);
 975                return;
 976        }
 977
 978        rsvd_pkt->rtwvif = rtwvif;
 979        rtw_insert_rsvd_page(rtwdev, rtwvif, rsvd_pkt);
 980}
 981
 982static void rtw_add_rsvd_page_probe_req(struct rtw_dev *rtwdev,
 983                                        struct rtw_vif *rtwvif,
 984                                        struct cfg80211_ssid *ssid)
 985{
 986        struct rtw_rsvd_page *rsvd_pkt;
 987
 988        rsvd_pkt = rtw_alloc_rsvd_page(rtwdev, RSVD_PROBE_REQ, true);
 989        if (!rsvd_pkt) {
 990                rtw_err(rtwdev, "failed to alloc probe req rsvd page\n");
 991                return;
 992        }
 993
 994        rsvd_pkt->rtwvif = rtwvif;
 995        rsvd_pkt->ssid = ssid;
 996        rtw_insert_rsvd_page(rtwdev, rtwvif, rsvd_pkt);
 997}
 998
 999void rtw_remove_rsvd_page(struct rtw_dev *rtwdev,
1000                          struct rtw_vif *rtwvif)
1001{
1002        struct rtw_rsvd_page *rsvd_pkt, *tmp;
1003
1004        lockdep_assert_held(&rtwdev->mutex);
1005
1006        /* remove all of the rsvd pages for vif */
1007        list_for_each_entry_safe(rsvd_pkt, tmp, &rtwvif->rsvd_page_list,
1008                                 vif_list) {
1009                list_del(&rsvd_pkt->vif_list);
1010                if (!list_empty(&rsvd_pkt->build_list))
1011                        list_del(&rsvd_pkt->build_list);
1012                kfree(rsvd_pkt);
1013        }
1014}
1015
1016void rtw_add_rsvd_page_bcn(struct rtw_dev *rtwdev,
1017                           struct rtw_vif *rtwvif)
1018{
1019        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
1020
1021        if (vif->type != NL80211_IFTYPE_AP &&
1022            vif->type != NL80211_IFTYPE_ADHOC &&
1023            vif->type != NL80211_IFTYPE_MESH_POINT) {
1024                rtw_warn(rtwdev, "Cannot add beacon rsvd page for %d\n",
1025                         vif->type);
1026                return;
1027        }
1028
1029        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_BEACON, false);
1030}
1031
1032void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev,
1033                           struct rtw_vif *rtwvif)
1034{
1035        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
1036        struct rtw_wow_param *rtw_wow = &rtwdev->wow;
1037        struct rtw_pno_request *rtw_pno_req = &rtw_wow->pno_req;
1038        struct cfg80211_ssid *ssid;
1039        int i;
1040
1041        if (vif->type != NL80211_IFTYPE_STATION) {
1042                rtw_warn(rtwdev, "Cannot add PNO rsvd page for %d\n",
1043                         vif->type);
1044                return;
1045        }
1046
1047        for (i = 0 ; i < rtw_pno_req->match_set_cnt; i++) {
1048                ssid = &rtw_pno_req->match_sets[i].ssid;
1049                rtw_add_rsvd_page_probe_req(rtwdev, rtwvif, ssid);
1050        }
1051
1052        rtw_add_rsvd_page_probe_req(rtwdev, rtwvif, NULL);
1053        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_NLO_INFO, false);
1054        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_CH_INFO, true);
1055}
1056
1057void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
1058                           struct rtw_vif *rtwvif)
1059{
1060        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
1061
1062        if (vif->type != NL80211_IFTYPE_STATION) {
1063                rtw_warn(rtwdev, "Cannot add sta rsvd page for %d\n",
1064                         vif->type);
1065                return;
1066        }
1067
1068        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_PS_POLL, true);
1069        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_QOS_NULL, true);
1070        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_NULL, true);
1071        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_DPK, true);
1072        rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_INFO, true);
1073}
1074
1075int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
1076                                u8 *buf, u32 size)
1077{
1078        u8 bckp[2];
1079        u8 val;
1080        u16 rsvd_pg_head;
1081        int ret;
1082
1083        lockdep_assert_held(&rtwdev->mutex);
1084
1085        if (!size)
1086                return -EINVAL;
1087
1088        pg_addr &= BIT_MASK_BCN_HEAD_1_V1;
1089        rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, pg_addr | BIT_BCN_VALID_V1);
1090
1091        val = rtw_read8(rtwdev, REG_CR + 1);
1092        bckp[0] = val;
1093        val |= BIT_ENSWBCN >> 8;
1094        rtw_write8(rtwdev, REG_CR + 1, val);
1095
1096        val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
1097        bckp[1] = val;
1098        val &= ~(BIT_EN_BCNQ_DL >> 16);
1099        rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, val);
1100
1101        ret = rtw_hci_write_data_rsvd_page(rtwdev, buf, size);
1102        if (ret) {
1103                rtw_err(rtwdev, "failed to write data to rsvd page\n");
1104                goto restore;
1105        }
1106
1107        if (!check_hw_ready(rtwdev, REG_FIFOPAGE_CTRL_2, BIT_BCN_VALID_V1, 1)) {
1108                rtw_err(rtwdev, "error beacon valid\n");
1109                ret = -EBUSY;
1110        }
1111
1112restore:
1113        rsvd_pg_head = rtwdev->fifo.rsvd_boundary;
1114        rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,
1115                    rsvd_pg_head | BIT_BCN_VALID_V1);
1116        rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
1117        rtw_write8(rtwdev, REG_CR + 1, bckp[0]);
1118
1119        return ret;
1120}
1121
1122static int rtw_download_drv_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
1123{
1124        u32 pg_size;
1125        u32 pg_num = 0;
1126        u16 pg_addr = 0;
1127
1128        pg_size = rtwdev->chip->page_size;
1129        pg_num = size / pg_size + ((size & (pg_size - 1)) ? 1 : 0);
1130        if (pg_num > rtwdev->fifo.rsvd_drv_pg_num)
1131                return -ENOMEM;
1132
1133        pg_addr = rtwdev->fifo.rsvd_drv_addr;
1134
1135        return rtw_fw_write_data_rsvd_page(rtwdev, pg_addr, buf, size);
1136}
1137
1138static void __rtw_build_rsvd_page_reset(struct rtw_dev *rtwdev)
1139{
1140        struct rtw_rsvd_page *rsvd_pkt, *tmp;
1141
1142        list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list,
1143                                 build_list) {
1144                list_del_init(&rsvd_pkt->build_list);
1145
1146                /* Don't free except for the dummy rsvd page,
1147                 * others will be freed when removing vif
1148                 */
1149                if (rsvd_pkt->type == RSVD_DUMMY)
1150                        kfree(rsvd_pkt);
1151        }
1152}
1153
1154static void rtw_build_rsvd_page_iter(void *data, u8 *mac,
1155                                     struct ieee80211_vif *vif)
1156{
1157        struct rtw_dev *rtwdev = data;
1158        struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
1159        struct rtw_rsvd_page *rsvd_pkt;
1160
1161        list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) {
1162                if (rsvd_pkt->type == RSVD_BEACON)
1163                        list_add(&rsvd_pkt->build_list,
1164                                 &rtwdev->rsvd_page_list);
1165                else
1166                        list_add_tail(&rsvd_pkt->build_list,
1167                                      &rtwdev->rsvd_page_list);
1168        }
1169}
1170
1171static int  __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev)
1172{
1173        struct rtw_rsvd_page *rsvd_pkt;
1174
1175        __rtw_build_rsvd_page_reset(rtwdev);
1176
1177        /* gather rsvd page from vifs */
1178        rtw_iterate_vifs_atomic(rtwdev, rtw_build_rsvd_page_iter, rtwdev);
1179
1180        rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list,
1181                                            struct rtw_rsvd_page, build_list);
1182        if (!rsvd_pkt) {
1183                WARN(1, "Should not have an empty reserved page\n");
1184                return -EINVAL;
1185        }
1186
1187        /* the first rsvd should be beacon, otherwise add a dummy one */
1188        if (rsvd_pkt->type != RSVD_BEACON) {
1189                struct rtw_rsvd_page *dummy_pkt;
1190
1191                dummy_pkt = rtw_alloc_rsvd_page(rtwdev, RSVD_DUMMY, false);
1192                if (!dummy_pkt) {
1193                        rtw_err(rtwdev, "failed to alloc dummy rsvd page\n");
1194                        return -ENOMEM;
1195                }
1196
1197                list_add(&dummy_pkt->build_list, &rtwdev->rsvd_page_list);
1198        }
1199
1200        return 0;
1201}
1202
1203static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size)
1204{
1205        struct ieee80211_hw *hw = rtwdev->hw;
1206        struct rtw_chip_info *chip = rtwdev->chip;
1207        struct sk_buff *iter;
1208        struct rtw_rsvd_page *rsvd_pkt;
1209        u32 page = 0;
1210        u8 total_page = 0;
1211        u8 page_size, page_margin, tx_desc_sz;
1212        u8 *buf;
1213        int ret;
1214
1215        page_size = chip->page_size;
1216        tx_desc_sz = chip->tx_pkt_desc_sz;
1217        page_margin = page_size - tx_desc_sz;
1218
1219        ret = __rtw_build_rsvd_page_from_vifs(rtwdev);
1220        if (ret) {
1221                rtw_err(rtwdev,
1222                        "failed to build rsvd page from vifs, ret %d\n", ret);
1223                return NULL;
1224        }
1225
1226        list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) {
1227                iter = rtw_get_rsvd_page_skb(hw, rsvd_pkt);
1228                if (!iter) {
1229                        rtw_err(rtwdev, "failed to build rsvd packet\n");
1230                        goto release_skb;
1231                }
1232
1233                /* Fill the tx_desc for the rsvd pkt that requires one.
1234                 * And iter->len will be added with size of tx_desc_sz.
1235                 */
1236                if (rsvd_pkt->add_txdesc)
1237                        rtw_fill_rsvd_page_desc(rtwdev, iter);
1238
1239                rsvd_pkt->skb = iter;
1240                rsvd_pkt->page = total_page;
1241
1242                /* Reserved page is downloaded via TX path, and TX path will
1243                 * generate a tx_desc at the header to describe length of
1244                 * the buffer. If we are not counting page numbers with the
1245                 * size of tx_desc added at the first rsvd_pkt (usually a
1246                 * beacon, firmware default refer to the first page as the
1247                 * content of beacon), we could generate a buffer which size
1248                 * is smaller than the actual size of the whole rsvd_page
1249                 */
1250                if (total_page == 0) {
1251                        if (rsvd_pkt->type != RSVD_BEACON &&
1252                            rsvd_pkt->type != RSVD_DUMMY) {
1253                                rtw_err(rtwdev, "first page should be a beacon\n");
1254                                goto release_skb;
1255                        }
1256                        total_page += rtw_len_to_page(iter->len + tx_desc_sz,
1257                                                      page_size);
1258                } else {
1259                        total_page += rtw_len_to_page(iter->len, page_size);
1260                }
1261        }
1262
1263        if (total_page > rtwdev->fifo.rsvd_drv_pg_num) {
1264                rtw_err(rtwdev, "rsvd page over size: %d\n", total_page);
1265                goto release_skb;
1266        }
1267
1268        *size = (total_page - 1) * page_size + page_margin;
1269        buf = kzalloc(*size, GFP_KERNEL);
1270        if (!buf)
1271                goto release_skb;
1272
1273        /* Copy the content of each rsvd_pkt to the buf, and they should
1274         * be aligned to the pages.
1275         *
1276         * Note that the first rsvd_pkt is a beacon no matter what vif->type.
1277         * And that rsvd_pkt does not require tx_desc because when it goes
1278         * through TX path, the TX path will generate one for it.
1279         */
1280        list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) {
1281                rtw_rsvd_page_list_to_buf(rtwdev, page_size, page_margin,
1282                                          page, buf, rsvd_pkt);
1283                if (page == 0)
1284                        page += rtw_len_to_page(rsvd_pkt->skb->len +
1285                                                tx_desc_sz, page_size);
1286                else
1287                        page += rtw_len_to_page(rsvd_pkt->skb->len, page_size);
1288
1289                kfree_skb(rsvd_pkt->skb);
1290                rsvd_pkt->skb = NULL;
1291        }
1292
1293        return buf;
1294
1295release_skb:
1296        list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) {
1297                kfree_skb(rsvd_pkt->skb);
1298                rsvd_pkt->skb = NULL;
1299        }
1300
1301        return NULL;
1302}
1303
1304static int rtw_download_beacon(struct rtw_dev *rtwdev)
1305{
1306        struct ieee80211_hw *hw = rtwdev->hw;
1307        struct rtw_rsvd_page *rsvd_pkt;
1308        struct sk_buff *skb;
1309        int ret = 0;
1310
1311        rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list,
1312                                            struct rtw_rsvd_page, build_list);
1313        if (!rsvd_pkt) {
1314                rtw_err(rtwdev, "failed to get rsvd page from build list\n");
1315                return -ENOENT;
1316        }
1317
1318        if (rsvd_pkt->type != RSVD_BEACON &&
1319            rsvd_pkt->type != RSVD_DUMMY) {
1320                rtw_err(rtwdev, "invalid rsvd page type %d, should be beacon or dummy\n",
1321                        rsvd_pkt->type);
1322                return -EINVAL;
1323        }
1324
1325        skb = rtw_get_rsvd_page_skb(hw, rsvd_pkt);
1326        if (!skb) {
1327                rtw_err(rtwdev, "failed to get beacon skb\n");
1328                return -ENOMEM;
1329        }
1330
1331        ret = rtw_download_drv_rsvd_page(rtwdev, skb->data, skb->len);
1332        if (ret)
1333                rtw_err(rtwdev, "failed to download drv rsvd page\n");
1334
1335        dev_kfree_skb(skb);
1336
1337        return ret;
1338}
1339
1340int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev)
1341{
1342        u8 *buf;
1343        u32 size;
1344        int ret;
1345
1346        buf = rtw_build_rsvd_page(rtwdev, &size);
1347        if (!buf) {
1348                rtw_err(rtwdev, "failed to build rsvd page pkt\n");
1349                return -ENOMEM;
1350        }
1351
1352        ret = rtw_download_drv_rsvd_page(rtwdev, buf, size);
1353        if (ret) {
1354                rtw_err(rtwdev, "failed to download drv rsvd page\n");
1355                goto free;
1356        }
1357
1358        /* The last thing is to download the *ONLY* beacon again, because
1359         * the previous tx_desc is to describe the total rsvd page. Download
1360         * the beacon again to replace the TX desc header, and we will get
1361         * a correct tx_desc for the beacon in the rsvd page.
1362         */
1363        ret = rtw_download_beacon(rtwdev);
1364        if (ret) {
1365                rtw_err(rtwdev, "failed to download beacon\n");
1366                goto free;
1367        }
1368
1369free:
1370        kfree(buf);
1371
1372        return ret;
1373}
1374
1375int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev,
1376                           u32 offset, u32 size, u32 *buf)
1377{
1378        struct rtw_fifo_conf *fifo = &rtwdev->fifo;
1379        u32 residue, i;
1380        u16 start_pg;
1381        u16 idx = 0;
1382        u16 ctl;
1383        u8 rcr;
1384
1385        if (size & 0x3) {
1386                rtw_warn(rtwdev, "should be 4-byte aligned\n");
1387                return -EINVAL;
1388        }
1389
1390        offset += fifo->rsvd_boundary << TX_PAGE_SIZE_SHIFT;
1391        residue = offset & (FIFO_PAGE_SIZE - 1);
1392        start_pg = offset >> FIFO_PAGE_SIZE_SHIFT;
1393        start_pg += RSVD_PAGE_START_ADDR;
1394
1395        rcr = rtw_read8(rtwdev, REG_RCR + 2);
1396        ctl = rtw_read16(rtwdev, REG_PKTBUF_DBG_CTRL) & 0xf000;
1397
1398        /* disable rx clock gate */
1399        rtw_write8(rtwdev, REG_RCR, rcr | BIT(3));
1400
1401        do {
1402                rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, start_pg | ctl);
1403
1404                for (i = FIFO_DUMP_ADDR + residue;
1405                     i < FIFO_DUMP_ADDR + FIFO_PAGE_SIZE; i += 4) {
1406                        buf[idx++] = rtw_read32(rtwdev, i);
1407                        size -= 4;
1408                        if (size == 0)
1409                                goto out;
1410                }
1411
1412                residue = 0;
1413                start_pg++;
1414        } while (size);
1415
1416out:
1417        rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, ctl);
1418        rtw_write8(rtwdev, REG_RCR + 2, rcr);
1419        return 0;
1420}
1421
1422static void __rtw_fw_update_pkt(struct rtw_dev *rtwdev, u8 pkt_id, u16 size,
1423                                u8 location)
1424{
1425        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
1426        u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_UPDATE_PKT_LEN;
1427
1428        rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_UPDATE_PKT);
1429
1430        SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size);
1431        UPDATE_PKT_SET_PKT_ID(h2c_pkt, pkt_id);
1432        UPDATE_PKT_SET_LOCATION(h2c_pkt, location);
1433
1434        /* include txdesc size */
1435        UPDATE_PKT_SET_SIZE(h2c_pkt, size);
1436
1437        rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
1438}
1439
1440void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev,
1441                                 struct cfg80211_ssid *ssid)
1442{
1443        u8 loc;
1444        u32 size;
1445
1446        loc = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid);
1447        if (!loc) {
1448                rtw_err(rtwdev, "failed to get probe_req rsvd loc\n");
1449                return;
1450        }
1451
1452        size = rtw_get_rsvd_page_probe_req_size(rtwdev, ssid);
1453        if (!size) {
1454                rtw_err(rtwdev, "failed to get probe_req rsvd size\n");
1455                return;
1456        }
1457
1458        __rtw_fw_update_pkt(rtwdev, RTW_PACKET_PROBE_REQ, size, loc);
1459}
1460
1461void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable)
1462{
1463        struct rtw_pno_request *rtw_pno_req = &rtwdev->wow.pno_req;
1464        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
1465        u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_CH_SWITCH_LEN;
1466        u8 loc_ch_info;
1467        const struct rtw_ch_switch_option cs_option = {
1468                .dest_ch_en = 1,
1469                .dest_ch = 1,
1470                .periodic_option = 2,
1471                .normal_period = 5,
1472                .normal_period_sel = 0,
1473                .normal_cycle = 10,
1474                .slow_period = 1,
1475                .slow_period_sel = 1,
1476        };
1477
1478        rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_CH_SWITCH);
1479        SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size);
1480
1481        CH_SWITCH_SET_START(h2c_pkt, enable);
1482        CH_SWITCH_SET_DEST_CH_EN(h2c_pkt, cs_option.dest_ch_en);
1483        CH_SWITCH_SET_DEST_CH(h2c_pkt, cs_option.dest_ch);
1484        CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt, cs_option.normal_period);
1485        CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt, cs_option.normal_period_sel);
1486        CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt, cs_option.slow_period);
1487        CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt, cs_option.slow_period_sel);
1488        CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt, cs_option.normal_cycle);
1489        CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt, cs_option.periodic_option);
1490
1491        CH_SWITCH_SET_CH_NUM(h2c_pkt, rtw_pno_req->channel_cnt);
1492        CH_SWITCH_SET_INFO_SIZE(h2c_pkt, rtw_pno_req->channel_cnt * 4);
1493
1494        loc_ch_info = rtw_get_rsvd_page_location(rtwdev, RSVD_CH_INFO);
1495        CH_SWITCH_SET_INFO_LOC(h2c_pkt, loc_ch_info);
1496
1497        rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
1498}
1499