1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2009-2012 Realtek Corporation.*/ 3 4 #include "../wifi.h" 5 #include "../pci.h" 6 #include "../base.h" 7 #include "reg.h" 8 #include "def.h" 9 #include "fw.h" 10 11 static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw) 12 { 13 struct rtl_priv *rtlpriv = rtl_priv(hw); 14 15 rtl_write_dword(rtlpriv, RQPN, 0xffffffff); 16 rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff); 17 rtl_write_byte(rtlpriv, RQPN + 8, 0xff); 18 rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80); 19 } 20 21 static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw) 22 { 23 struct rtl_priv *rtlpriv = rtl_priv(hw); 24 u32 ichecktime = 200; 25 u16 tmpu2b; 26 u8 tmpu1b, cpustatus = 0; 27 28 _rtl92s_fw_set_rqpn(hw); 29 30 /* Enable CPU. */ 31 tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR); 32 /* AFE source */ 33 rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL)); 34 35 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 36 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN)); 37 38 /* Polling IMEM Ready after CPU has refilled. */ 39 do { 40 cpustatus = rtl_read_byte(rtlpriv, TCR); 41 if (cpustatus & IMEM_RDY) { 42 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 43 "IMEM Ready after CPU has refilled\n"); 44 break; 45 } 46 47 udelay(100); 48 } while (ichecktime--); 49 50 if (!(cpustatus & IMEM_RDY)) 51 return false; 52 53 return true; 54 } 55 56 static enum fw_status _rtl92s_firmware_get_nextstatus( 57 enum fw_status fw_currentstatus) 58 { 59 enum fw_status next_fwstatus = 0; 60 61 switch (fw_currentstatus) { 62 case FW_STATUS_INIT: 63 next_fwstatus = FW_STATUS_LOAD_IMEM; 64 break; 65 case FW_STATUS_LOAD_IMEM: 66 next_fwstatus = FW_STATUS_LOAD_EMEM; 67 break; 68 case FW_STATUS_LOAD_EMEM: 69 next_fwstatus = FW_STATUS_LOAD_DMEM; 70 break; 71 case FW_STATUS_LOAD_DMEM: 72 next_fwstatus = FW_STATUS_READY; 73 break; 74 default: 75 break; 76 } 77 78 return next_fwstatus; 79 } 80 81 static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw) 82 { 83 struct rtl_priv *rtlpriv = rtl_priv(hw); 84 struct rtl_phy *rtlphy = &(rtlpriv->phy); 85 86 switch (rtlphy->rf_type) { 87 case RF_1T1R: 88 return 0x11; 89 case RF_1T2R: 90 return 0x12; 91 case RF_2T2R: 92 return 0x22; 93 default: 94 pr_err("Unknown RF type(%x)\n", rtlphy->rf_type); 95 break; 96 } 97 return 0x22; 98 } 99 100 static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw, 101 struct fw_priv *pfw_priv) 102 { 103 /* Update RF types for RATR settings. */ 104 pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw); 105 } 106 107 108 109 static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw, 110 struct sk_buff *skb, u8 last) 111 { 112 struct rtl_priv *rtlpriv = rtl_priv(hw); 113 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 114 struct rtl8192_tx_ring *ring; 115 struct rtl_tx_desc *pdesc; 116 unsigned long flags; 117 u8 idx = 0; 118 119 ring = &rtlpci->tx_ring[TXCMD_QUEUE]; 120 121 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); 122 123 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; 124 pdesc = &ring->desc[idx]; 125 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb); 126 __skb_queue_tail(&ring->queue, skb); 127 128 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); 129 130 return true; 131 } 132 133 static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, 134 u8 *code_virtual_address, u32 buffer_len) 135 { 136 struct rtl_priv *rtlpriv = rtl_priv(hw); 137 struct sk_buff *skb; 138 struct rtl_tcb_desc *tcb_desc; 139 u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE; 140 u16 frag_length, frag_offset = 0; 141 u16 extra_descoffset = 0; 142 u8 last_inipkt = 0; 143 144 _rtl92s_fw_set_rqpn(hw); 145 146 if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { 147 pr_err("Size over FIRMWARE_CODE_SIZE!\n"); 148 return false; 149 } 150 151 extra_descoffset = 0; 152 153 do { 154 if ((buffer_len - frag_offset) > frag_threshold) { 155 frag_length = frag_threshold + extra_descoffset; 156 } else { 157 frag_length = (u16)(buffer_len - frag_offset + 158 extra_descoffset); 159 last_inipkt = 1; 160 } 161 162 /* Allocate skb buffer to contain firmware */ 163 /* info and tx descriptor info. */ 164 skb = dev_alloc_skb(frag_length); 165 if (!skb) 166 return false; 167 skb_reserve(skb, extra_descoffset); 168 skb_put_data(skb, code_virtual_address + frag_offset, 169 (u32)(frag_length - extra_descoffset)); 170 171 tcb_desc = (struct rtl_tcb_desc *)(skb->cb); 172 tcb_desc->queue_index = TXCMD_QUEUE; 173 tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT; 174 tcb_desc->last_inipkt = last_inipkt; 175 176 _rtl92s_cmd_send_packet(hw, skb, last_inipkt); 177 178 frag_offset += (frag_length - extra_descoffset); 179 180 } while (frag_offset < buffer_len); 181 182 rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ); 183 184 return true ; 185 } 186 187 static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, 188 u8 loadfw_status) 189 { 190 struct rtl_priv *rtlpriv = rtl_priv(hw); 191 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 192 struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware; 193 u32 tmpu4b; 194 u8 cpustatus = 0; 195 short pollingcnt = 1000; 196 bool rtstatus = true; 197 198 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 199 "LoadStaus(%d)\n", loadfw_status); 200 201 firmware->fwstatus = (enum fw_status)loadfw_status; 202 203 switch (loadfw_status) { 204 case FW_STATUS_LOAD_IMEM: 205 /* Polling IMEM code done. */ 206 do { 207 cpustatus = rtl_read_byte(rtlpriv, TCR); 208 if (cpustatus & IMEM_CODE_DONE) 209 break; 210 udelay(5); 211 } while (pollingcnt--); 212 213 if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) { 214 pr_err("FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n", 215 cpustatus); 216 goto status_check_fail; 217 } 218 break; 219 220 case FW_STATUS_LOAD_EMEM: 221 /* Check Put Code OK and Turn On CPU */ 222 /* Polling EMEM code done. */ 223 do { 224 cpustatus = rtl_read_byte(rtlpriv, TCR); 225 if (cpustatus & EMEM_CODE_DONE) 226 break; 227 udelay(5); 228 } while (pollingcnt--); 229 230 if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) { 231 pr_err("FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n", 232 cpustatus); 233 goto status_check_fail; 234 } 235 236 /* Turn On CPU */ 237 rtstatus = _rtl92s_firmware_enable_cpu(hw); 238 if (!rtstatus) { 239 pr_err("Enable CPU fail!\n"); 240 goto status_check_fail; 241 } 242 break; 243 244 case FW_STATUS_LOAD_DMEM: 245 /* Polling DMEM code done */ 246 do { 247 cpustatus = rtl_read_byte(rtlpriv, TCR); 248 if (cpustatus & DMEM_CODE_DONE) 249 break; 250 udelay(5); 251 } while (pollingcnt--); 252 253 if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) { 254 pr_err("Polling DMEM code done fail ! cpustatus(%#x)\n", 255 cpustatus); 256 goto status_check_fail; 257 } 258 259 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 260 "DMEM code download success, cpustatus(%#x)\n", 261 cpustatus); 262 263 /* Prevent Delay too much and being scheduled out */ 264 /* Polling Load Firmware ready */ 265 pollingcnt = 2000; 266 do { 267 cpustatus = rtl_read_byte(rtlpriv, TCR); 268 if (cpustatus & FWRDY) 269 break; 270 udelay(40); 271 } while (pollingcnt--); 272 273 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 274 "Polling Load Firmware ready, cpustatus(%x)\n", 275 cpustatus); 276 277 if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || 278 (pollingcnt <= 0)) { 279 pr_err("Polling Load Firmware ready fail ! cpustatus(%x)\n", 280 cpustatus); 281 goto status_check_fail; 282 } 283 284 /* If right here, we can set TCR/RCR to desired value */ 285 /* and config MAC lookback mode to normal mode */ 286 tmpu4b = rtl_read_dword(rtlpriv, TCR); 287 rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV))); 288 289 tmpu4b = rtl_read_dword(rtlpriv, RCR); 290 rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS | 291 RCR_APP_ICV | RCR_APP_MIC)); 292 293 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 294 "Current RCR settings(%#x)\n", tmpu4b); 295 296 /* Set to normal mode. */ 297 rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); 298 break; 299 300 default: 301 pr_err("Unknown status check!\n"); 302 rtstatus = false; 303 break; 304 } 305 306 status_check_fail: 307 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 308 "loadfw_status(%d), rtstatus(%x)\n", 309 loadfw_status, rtstatus); 310 return rtstatus; 311 } 312 313 int rtl92s_download_fw(struct ieee80211_hw *hw) 314 { 315 struct rtl_priv *rtlpriv = rtl_priv(hw); 316 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 317 struct rt_firmware *firmware = NULL; 318 struct fw_hdr *pfwheader; 319 struct fw_priv *pfw_priv = NULL; 320 u8 *puc_mappedfile = NULL; 321 u32 ul_filelength = 0; 322 u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; 323 u8 fwstatus = FW_STATUS_INIT; 324 bool rtstatus = true; 325 326 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) 327 return 1; 328 329 firmware = (struct rt_firmware *)rtlhal->pfirmware; 330 firmware->fwstatus = FW_STATUS_INIT; 331 332 puc_mappedfile = firmware->sz_fw_tmpbuffer; 333 334 /* 1. Retrieve FW header. */ 335 firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; 336 pfwheader = firmware->pfwheader; 337 firmware->firmwareversion = byte(pfwheader->version, 0); 338 firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ 339 340 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 341 "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", 342 pfwheader->signature, 343 pfwheader->version, pfwheader->dmem_size, 344 pfwheader->img_imem_size, pfwheader->img_sram_size); 345 346 /* 2. Retrieve IMEM image. */ 347 if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > 348 sizeof(firmware->fw_imem))) { 349 pr_err("memory for data image is less than IMEM required\n"); 350 goto fail; 351 } else { 352 puc_mappedfile += fwhdr_size; 353 354 memcpy(firmware->fw_imem, puc_mappedfile, 355 pfwheader->img_imem_size); 356 firmware->fw_imem_len = pfwheader->img_imem_size; 357 } 358 359 /* 3. Retriecve EMEM image. */ 360 if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) { 361 pr_err("memory for data image is less than EMEM required\n"); 362 goto fail; 363 } else { 364 puc_mappedfile += firmware->fw_imem_len; 365 366 memcpy(firmware->fw_emem, puc_mappedfile, 367 pfwheader->img_sram_size); 368 firmware->fw_emem_len = pfwheader->img_sram_size; 369 } 370 371 /* 4. download fw now */ 372 fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); 373 while (fwstatus != FW_STATUS_READY) { 374 /* Image buffer redirection. */ 375 switch (fwstatus) { 376 case FW_STATUS_LOAD_IMEM: 377 puc_mappedfile = firmware->fw_imem; 378 ul_filelength = firmware->fw_imem_len; 379 break; 380 case FW_STATUS_LOAD_EMEM: 381 puc_mappedfile = firmware->fw_emem; 382 ul_filelength = firmware->fw_emem_len; 383 break; 384 case FW_STATUS_LOAD_DMEM: 385 /* Partial update the content of header private. */ 386 pfwheader = firmware->pfwheader; 387 pfw_priv = &pfwheader->fwpriv; 388 _rtl92s_firmwareheader_priveupdate(hw, pfw_priv); 389 puc_mappedfile = (u8 *)(firmware->pfwheader) + 390 RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; 391 ul_filelength = fwhdr_size - 392 RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; 393 break; 394 default: 395 pr_err("Unexpected Download step!!\n"); 396 goto fail; 397 } 398 399 /* <2> Download image file */ 400 rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile, 401 ul_filelength); 402 403 if (!rtstatus) { 404 pr_err("fail!\n"); 405 goto fail; 406 } 407 408 /* <3> Check whether load FW process is ready */ 409 rtstatus = _rtl92s_firmware_checkready(hw, fwstatus); 410 if (!rtstatus) { 411 pr_err("rtl8192se: firmware fail!\n"); 412 goto fail; 413 } 414 415 fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); 416 } 417 418 return rtstatus; 419 fail: 420 return 0; 421 } 422 423 static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen, 424 u32 cmd_num, u32 *pelement_id, u32 *pcmd_len, 425 u8 **pcmb_buffer, u8 *cmd_start_seq) 426 { 427 u32 totallen = 0, len = 0, tx_desclen = 0; 428 u32 pre_continueoffset = 0; 429 u8 *ph2c_buffer; 430 u8 i = 0; 431 432 do { 433 /* 8 - Byte alignment */ 434 len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); 435 436 /* Buffer length is not enough */ 437 if (h2cbufferlen < totallen + len + tx_desclen) 438 break; 439 440 /* Clear content */ 441 ph2c_buffer = skb_put(skb, (u32)len); 442 memset((ph2c_buffer + totallen + tx_desclen), 0, len); 443 444 /* CMD len */ 445 le32p_replace_bits((__le32 *)(ph2c_buffer + totallen + 446 tx_desclen), pcmd_len[i], 447 GENMASK(15, 0)); 448 449 /* CMD ID */ 450 le32p_replace_bits((__le32 *)(ph2c_buffer + totallen + 451 tx_desclen), pelement_id[i], 452 GENMASK(23, 16)); 453 454 /* CMD Sequence */ 455 *cmd_start_seq = *cmd_start_seq % 0x80; 456 le32p_replace_bits((__le32 *)(ph2c_buffer + totallen + 457 tx_desclen), *cmd_start_seq, 458 GENMASK(30, 24)); 459 ++*cmd_start_seq; 460 461 /* Copy memory */ 462 memcpy((ph2c_buffer + totallen + tx_desclen + 463 H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]); 464 465 /* CMD continue */ 466 /* set the continue in prevoius cmd. */ 467 if (i < cmd_num - 1) 468 le32p_replace_bits((__le32 *)(ph2c_buffer + 469 pre_continueoffset), 470 1, BIT(31)); 471 472 pre_continueoffset = totallen; 473 474 totallen += len; 475 } while (++i < cmd_num); 476 477 return totallen; 478 } 479 480 static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len) 481 { 482 u32 totallen = 0, len = 0, tx_desclen = 0; 483 u8 i = 0; 484 485 do { 486 /* 8 - Byte alignment */ 487 len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); 488 489 /* Buffer length is not enough */ 490 if (h2cbufferlen < totallen + len + tx_desclen) 491 break; 492 493 totallen += len; 494 } while (++i < cmd_num); 495 496 return totallen + tx_desclen; 497 } 498 499 static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd, 500 u8 *pcmd_buffer) 501 { 502 struct rtl_priv *rtlpriv = rtl_priv(hw); 503 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 504 struct rtl_tcb_desc *cb_desc; 505 struct sk_buff *skb; 506 u32 element_id = 0; 507 u32 cmd_len = 0; 508 u32 len; 509 510 switch (h2c_cmd) { 511 case FW_H2C_SETPWRMODE: 512 element_id = H2C_SETPWRMODE_CMD ; 513 cmd_len = sizeof(struct h2c_set_pwrmode_parm); 514 break; 515 case FW_H2C_JOINBSSRPT: 516 element_id = H2C_JOINBSSRPT_CMD; 517 cmd_len = sizeof(struct h2c_joinbss_rpt_parm); 518 break; 519 case FW_H2C_WOWLAN_UPDATE_GTK: 520 element_id = H2C_WOWLAN_UPDATE_GTK_CMD; 521 cmd_len = sizeof(struct h2c_wpa_two_way_parm); 522 break; 523 case FW_H2C_WOWLAN_UPDATE_IV: 524 element_id = H2C_WOWLAN_UPDATE_IV_CMD; 525 cmd_len = sizeof(unsigned long long); 526 break; 527 case FW_H2C_WOWLAN_OFFLOAD: 528 element_id = H2C_WOWLAN_FW_OFFLOAD; 529 cmd_len = sizeof(u8); 530 break; 531 default: 532 break; 533 } 534 535 len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len); 536 skb = dev_alloc_skb(len); 537 if (!skb) 538 return false; 539 cb_desc = (struct rtl_tcb_desc *)(skb->cb); 540 cb_desc->queue_index = TXCMD_QUEUE; 541 cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL; 542 cb_desc->last_inipkt = false; 543 544 _rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id, 545 &cmd_len, &pcmd_buffer, &rtlhal->h2c_txcmd_seq); 546 _rtl92s_cmd_send_packet(hw, skb, false); 547 rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE); 548 549 return true; 550 } 551 552 void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) 553 { 554 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 555 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 556 struct h2c_set_pwrmode_parm pwrmode; 557 u16 max_wakeup_period = 0; 558 559 pwrmode.mode = mode; 560 pwrmode.flag_low_traffic_en = 0; 561 pwrmode.flag_lpnav_en = 0; 562 pwrmode.flag_rf_low_snr_en = 0; 563 pwrmode.flag_dps_en = 0; 564 pwrmode.bcn_rx_en = 0; 565 pwrmode.bcn_to = 0; 566 le16p_replace_bits((__le16 *)(((u8 *)(&pwrmode) + 8)), 567 mac->vif->bss_conf.beacon_int, GENMASK(15, 0)); 568 pwrmode.app_itv = 0; 569 pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl; 570 pwrmode.smart_ps = 1; 571 pwrmode.bcn_pass_period = 10; 572 573 /* Set beacon pass count */ 574 if (pwrmode.mode == FW_PS_MIN_MODE) 575 max_wakeup_period = mac->vif->bss_conf.beacon_int; 576 else if (pwrmode.mode == FW_PS_MAX_MODE) 577 max_wakeup_period = mac->vif->bss_conf.beacon_int * 578 mac->vif->bss_conf.dtim_period; 579 580 if (max_wakeup_period >= 500) 581 pwrmode.bcn_pass_cnt = 1; 582 else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500)) 583 pwrmode.bcn_pass_cnt = 2; 584 else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300)) 585 pwrmode.bcn_pass_cnt = 3; 586 else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200)) 587 pwrmode.bcn_pass_cnt = 5; 588 else 589 pwrmode.bcn_pass_cnt = 1; 590 591 _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode); 592 593 } 594 595 void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, 596 u8 mstatus, u8 ps_qosinfo) 597 { 598 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 599 struct h2c_joinbss_rpt_parm joinbss_rpt; 600 601 joinbss_rpt.opmode = mstatus; 602 joinbss_rpt.ps_qos_info = ps_qosinfo; 603 joinbss_rpt.bssid[0] = mac->bssid[0]; 604 joinbss_rpt.bssid[1] = mac->bssid[1]; 605 joinbss_rpt.bssid[2] = mac->bssid[2]; 606 joinbss_rpt.bssid[3] = mac->bssid[3]; 607 joinbss_rpt.bssid[4] = mac->bssid[4]; 608 joinbss_rpt.bssid[5] = mac->bssid[5]; 609 le16p_replace_bits((__le16 *)(((u8 *)(&joinbss_rpt) + 8)), 610 mac->vif->bss_conf.beacon_int, GENMASK(15, 0)); 611 le16p_replace_bits((__le16 *)(((u8 *)(&joinbss_rpt) + 10)), 612 mac->assoc_id, GENMASK(15, 0)); 613 614 _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt); 615 } 616 617