1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 4 * All rights reserved. 5 * 6 * File: card.c 7 * Purpose: Provide functions to setup NIC operation mode 8 * Functions: 9 * vnt_set_rspinf - Set RSPINF 10 * vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS 11 * vnt_update_top_rates - Update BasicTopRate 12 * vnt_add_basic_rate - Add to BasicRateSet 13 * vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet 14 * vnt_get_tsf_offset - Calculate TSFOffset 15 * vnt_get_current_tsf - Read Current NIC TSF counter 16 * vnt_get_next_tbtt - Calculate Next Beacon TSF counter 17 * vnt_reset_next_tbtt - Set NIC Beacon time 18 * vnt_update_next_tbtt - Sync. NIC Beacon time 19 * vnt_radio_power_off - Turn Off NIC Radio Power 20 * vnt_radio_power_on - Turn On NIC Radio Power 21 * 22 * Revision History: 23 * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. 24 * 08-26-2003 Kyle Hsu: Modify the definition type of dwIoBase. 25 * 09-01-2003 Bryan YC Fan: Add vnt_update_ifs(). 26 * 27 */ 28 29 #include "device.h" 30 #include "card.h" 31 #include "baseband.h" 32 #include "mac.h" 33 #include "desc.h" 34 #include "rf.h" 35 #include "power.h" 36 #include "key.h" 37 #include "usbpipe.h" 38 39 /* const u16 cw_rxbcntsf_off[MAX_RATE] = 40 * {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; 41 */ 42 43 static const u16 cw_rxbcntsf_off[MAX_RATE] = { 44 192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3 45 }; 46 47 /* 48 * Description: Set NIC media channel 49 * 50 * Parameters: 51 * In: 52 * pDevice - The adapter to be set 53 * connection_channel - Channel to be set 54 * Out: 55 * none 56 */ 57 void vnt_set_channel(struct vnt_private *priv, u32 connection_channel) 58 { 59 if (connection_channel > CB_MAX_CHANNEL || !connection_channel) 60 return; 61 62 /* clear NAV */ 63 vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV); 64 65 /* Set Channel[7] = 0 to tell H/W channel is changing now. */ 66 vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0); 67 68 vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL, 69 connection_channel, 0, 0, NULL); 70 71 vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, 72 (u8)(connection_channel | 0x80)); 73 } 74 75 /* 76 * Description: Get CCK mode basic rate 77 * 78 * Parameters: 79 * In: 80 * priv - The adapter to be set 81 * rate_idx - Receiving data rate 82 * Out: 83 * none 84 * 85 * Return Value: response Control frame rate 86 * 87 */ 88 static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx) 89 { 90 u16 ui = rate_idx; 91 92 while (ui > RATE_1M) { 93 if (priv->basic_rates & (1 << ui)) 94 return ui; 95 ui--; 96 } 97 98 return RATE_1M; 99 } 100 101 /* 102 * Description: Get OFDM mode basic rate 103 * 104 * Parameters: 105 * In: 106 * priv - The adapter to be set 107 * rate_idx - Receiving data rate 108 * Out: 109 * none 110 * 111 * Return Value: response Control frame rate 112 * 113 */ 114 static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx) 115 { 116 u16 ui = rate_idx; 117 118 dev_dbg(&priv->usb->dev, "%s basic rate: %d\n", 119 __func__, priv->basic_rates); 120 121 if (!vnt_ofdm_min_rate(priv)) { 122 dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n", 123 __func__, rate_idx); 124 if (rate_idx > RATE_24M) 125 rate_idx = RATE_24M; 126 return rate_idx; 127 } 128 129 while (ui > RATE_11M) { 130 if (priv->basic_rates & (1 << ui)) { 131 dev_dbg(&priv->usb->dev, "%s rate: %d\n", 132 __func__, ui); 133 return ui; 134 } 135 ui--; 136 } 137 138 dev_dbg(&priv->usb->dev, "%s basic rate: 24M\n", __func__); 139 140 return RATE_24M; 141 } 142 143 /* 144 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. 145 * 146 * Parameters: 147 * In: 148 * rate - Tx Rate 149 * bb_type - Tx Packet type 150 * Out: 151 * tx_rate - pointer to RSPINF TxRate field 152 * rsv_time- pointer to RSPINF RsvTime field 153 * 154 * Return Value: none 155 * 156 */ 157 static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type, 158 u8 *tx_rate, u8 *rsv_time) 159 { 160 switch (rate) { 161 case RATE_6M: 162 if (bb_type == BB_TYPE_11A) { 163 *tx_rate = 0x9b; 164 *rsv_time = 24; 165 } else { 166 *tx_rate = 0x8b; 167 *rsv_time = 30; 168 } 169 break; 170 case RATE_9M: 171 if (bb_type == BB_TYPE_11A) { 172 *tx_rate = 0x9f; 173 *rsv_time = 16; 174 } else { 175 *tx_rate = 0x8f; 176 *rsv_time = 22; 177 } 178 break; 179 case RATE_12M: 180 if (bb_type == BB_TYPE_11A) { 181 *tx_rate = 0x9a; 182 *rsv_time = 12; 183 } else { 184 *tx_rate = 0x8a; 185 *rsv_time = 18; 186 } 187 break; 188 case RATE_18M: 189 if (bb_type == BB_TYPE_11A) { 190 *tx_rate = 0x9e; 191 *rsv_time = 8; 192 } else { 193 *tx_rate = 0x8e; 194 *rsv_time = 14; 195 } 196 break; 197 case RATE_36M: 198 if (bb_type == BB_TYPE_11A) { 199 *tx_rate = 0x9d; 200 *rsv_time = 4; 201 } else { 202 *tx_rate = 0x8d; 203 *rsv_time = 10; 204 } 205 break; 206 case RATE_48M: 207 if (bb_type == BB_TYPE_11A) { 208 *tx_rate = 0x98; 209 *rsv_time = 4; 210 } else { 211 *tx_rate = 0x88; 212 *rsv_time = 10; 213 } 214 break; 215 case RATE_54M: 216 if (bb_type == BB_TYPE_11A) { 217 *tx_rate = 0x9c; 218 *rsv_time = 4; 219 } else { 220 *tx_rate = 0x8c; 221 *rsv_time = 10; 222 } 223 break; 224 case RATE_24M: 225 default: 226 if (bb_type == BB_TYPE_11A) { 227 *tx_rate = 0x99; 228 *rsv_time = 8; 229 } else { 230 *tx_rate = 0x89; 231 *rsv_time = 14; 232 } 233 break; 234 } 235 } 236 237 /* 238 * Description: Set RSPINF 239 * 240 * Parameters: 241 * In: 242 * pDevice - The adapter to be set 243 * Out: 244 * none 245 * 246 * Return Value: None. 247 * 248 */ 249 250 void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type) 251 { 252 struct vnt_phy_field phy[4]; 253 u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */ 254 u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 255 u8 data[34]; 256 int i; 257 258 /*RSPINF_b_1*/ 259 vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_1M), 260 PK_TYPE_11B, &phy[0]); 261 262 /*RSPINF_b_2*/ 263 vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_2M), 264 PK_TYPE_11B, &phy[1]); 265 266 /*RSPINF_b_5*/ 267 vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_5M), 268 PK_TYPE_11B, &phy[2]); 269 270 /*RSPINF_b_11*/ 271 vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_11M), 272 PK_TYPE_11B, &phy[3]); 273 274 /*RSPINF_a_6*/ 275 vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]); 276 277 /*RSPINF_a_9*/ 278 vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]); 279 280 /*RSPINF_a_12*/ 281 vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]); 282 283 /*RSPINF_a_18*/ 284 vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]); 285 286 /*RSPINF_a_24*/ 287 vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]); 288 289 /*RSPINF_a_36*/ 290 vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M), 291 bb_type, &tx_rate[5], &rsv_time[5]); 292 293 /*RSPINF_a_48*/ 294 vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M), 295 bb_type, &tx_rate[6], &rsv_time[6]); 296 297 /*RSPINF_a_54*/ 298 vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), 299 bb_type, &tx_rate[7], &rsv_time[7]); 300 301 /*RSPINF_a_72*/ 302 vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), 303 bb_type, &tx_rate[8], &rsv_time[8]); 304 305 put_unaligned(phy[0].len, (u16 *)&data[0]); 306 data[2] = phy[0].signal; 307 data[3] = phy[0].service; 308 309 put_unaligned(phy[1].len, (u16 *)&data[4]); 310 data[6] = phy[1].signal; 311 data[7] = phy[1].service; 312 313 put_unaligned(phy[2].len, (u16 *)&data[8]); 314 data[10] = phy[2].signal; 315 data[11] = phy[2].service; 316 317 put_unaligned(phy[3].len, (u16 *)&data[12]); 318 data[14] = phy[3].signal; 319 data[15] = phy[3].service; 320 321 for (i = 0; i < 9; i++) { 322 data[16 + i * 2] = tx_rate[i]; 323 data[16 + i * 2 + 1] = rsv_time[i]; 324 } 325 326 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1, 327 MESSAGE_REQUEST_MACREG, 34, &data[0]); 328 } 329 330 /* 331 * Description: Update IFS 332 * 333 * Parameters: 334 * In: 335 * priv - The adapter to be set 336 * Out: 337 * none 338 * 339 * Return Value: None. 340 * 341 */ 342 void vnt_update_ifs(struct vnt_private *priv) 343 { 344 u8 max_min = 0; 345 u8 data[4]; 346 347 if (priv->packet_type == PK_TYPE_11A) { 348 priv->slot = C_SLOT_SHORT; 349 priv->sifs = C_SIFS_A; 350 priv->difs = C_SIFS_A + 2 * C_SLOT_SHORT; 351 max_min = 4; 352 } else { 353 priv->sifs = C_SIFS_BG; 354 355 if (priv->short_slot_time) { 356 priv->slot = C_SLOT_SHORT; 357 max_min = 4; 358 } else { 359 priv->slot = C_SLOT_LONG; 360 max_min = 5; 361 } 362 363 priv->difs = C_SIFS_BG + 2 * priv->slot; 364 } 365 366 priv->eifs = C_EIFS; 367 368 switch (priv->rf_type) { 369 case RF_VT3226D0: 370 if (priv->bb_type != BB_TYPE_11B) { 371 priv->sifs -= 1; 372 priv->difs -= 1; 373 break; 374 } 375 /* fall through */ 376 case RF_AIROHA7230: 377 case RF_AL2230: 378 case RF_AL2230S: 379 if (priv->bb_type != BB_TYPE_11B) 380 break; 381 /* fall through */ 382 case RF_RFMD2959: 383 case RF_VT3226: 384 case RF_VT3342A0: 385 priv->sifs -= 3; 386 priv->difs -= 3; 387 break; 388 case RF_MAXIM2829: 389 if (priv->bb_type == BB_TYPE_11A) { 390 priv->sifs -= 5; 391 priv->difs -= 5; 392 } else { 393 priv->sifs -= 2; 394 priv->difs -= 2; 395 } 396 397 break; 398 } 399 400 data[0] = (u8)priv->sifs; 401 data[1] = (u8)priv->difs; 402 data[2] = (u8)priv->eifs; 403 data[3] = (u8)priv->slot; 404 405 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS, 406 MESSAGE_REQUEST_MACREG, 4, &data[0]); 407 408 max_min |= 0xa0; 409 410 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0, 411 MESSAGE_REQUEST_MACREG, 1, &max_min); 412 } 413 414 void vnt_update_top_rates(struct vnt_private *priv) 415 { 416 u8 top_ofdm = RATE_24M, top_cck = RATE_1M; 417 u8 i; 418 419 /*Determines the highest basic rate.*/ 420 for (i = RATE_54M; i >= RATE_6M; i--) { 421 if (priv->basic_rates & (u16)(1 << i)) { 422 top_ofdm = i; 423 break; 424 } 425 } 426 427 priv->top_ofdm_basic_rate = top_ofdm; 428 429 for (i = RATE_11M;; i--) { 430 if (priv->basic_rates & (u16)(1 << i)) { 431 top_cck = i; 432 break; 433 } 434 if (i == RATE_1M) 435 break; 436 } 437 438 priv->top_cck_basic_rate = top_cck; 439 } 440 441 int vnt_ofdm_min_rate(struct vnt_private *priv) 442 { 443 int ii; 444 445 for (ii = RATE_54M; ii >= RATE_6M; ii--) { 446 if ((priv->basic_rates) & ((u16)BIT(ii))) 447 return true; 448 } 449 450 return false; 451 } 452 453 u8 vnt_get_pkt_type(struct vnt_private *priv) 454 { 455 if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B) 456 return (u8)priv->bb_type; 457 else if (vnt_ofdm_min_rate(priv)) 458 return PK_TYPE_11GA; 459 return PK_TYPE_11GB; 460 } 461 462 /* 463 * Description: Calculate TSF offset of two TSF input 464 * Get TSF Offset from RxBCN's TSF and local TSF 465 * 466 * Parameters: 467 * In: 468 * rx_rate - rx rate. 469 * tsf1 - Rx BCN's TSF 470 * tsf2 - Local TSF 471 * Out: 472 * none 473 * 474 * Return Value: TSF Offset value 475 * 476 */ 477 u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2) 478 { 479 return tsf1 - tsf2 - (u64)cw_rxbcntsf_off[rx_rate % MAX_RATE]; 480 } 481 482 /* 483 * Description: Sync. TSF counter to BSS 484 * Get TSF offset and write to HW 485 * 486 * Parameters: 487 * In: 488 * priv - The adapter to be sync. 489 * time_stamp - Rx BCN's TSF 490 * local_tsf - Local TSF 491 * Out: 492 * none 493 * 494 * Return Value: none 495 * 496 */ 497 void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, 498 u64 time_stamp, u64 local_tsf) 499 { 500 u64 tsf_offset = 0; 501 u8 data[8]; 502 503 tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf); 504 505 data[0] = (u8)tsf_offset; 506 data[1] = (u8)(tsf_offset >> 8); 507 data[2] = (u8)(tsf_offset >> 16); 508 data[3] = (u8)(tsf_offset >> 24); 509 data[4] = (u8)(tsf_offset >> 32); 510 data[5] = (u8)(tsf_offset >> 40); 511 data[6] = (u8)(tsf_offset >> 48); 512 data[7] = (u8)(tsf_offset >> 56); 513 514 vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, 515 MESSAGE_REQUEST_TSF, 0, 8, data); 516 } 517 518 /* 519 * Description: Read NIC TSF counter 520 * Get local TSF counter 521 * 522 * Parameters: 523 * In: 524 * priv - The adapter to be read 525 * Out: 526 * current_tsf - Current TSF counter 527 * 528 * Return Value: true if success; otherwise false 529 * 530 */ 531 bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf) 532 { 533 *current_tsf = priv->current_tsf; 534 535 return true; 536 } 537 538 /* 539 * Description: Clear NIC TSF counter 540 * Clear local TSF counter 541 * 542 * Parameters: 543 * In: 544 * priv - The adapter to be read 545 * 546 * Return Value: true if success; otherwise false 547 * 548 */ 549 bool vnt_clear_current_tsf(struct vnt_private *priv) 550 { 551 vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); 552 553 priv->current_tsf = 0; 554 555 return true; 556 } 557 558 /* 559 * Description: Read NIC TSF counter 560 * Get NEXTTBTT from adjusted TSF and Beacon Interval 561 * 562 * Parameters: 563 * In: 564 * tsf - Current TSF counter 565 * beacon_interval - Beacon Interval 566 * Out: 567 * tsf - Current TSF counter 568 * 569 * Return Value: TSF value of next Beacon 570 * 571 */ 572 u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval) 573 { 574 u32 beacon_int; 575 576 beacon_int = beacon_interval * 1024; 577 578 /* Next TBTT = 579 * ((local_current_TSF / beacon_interval) + 1) * beacon_interval 580 */ 581 if (beacon_int) { 582 do_div(tsf, beacon_int); 583 tsf += 1; 584 tsf *= beacon_int; 585 } 586 587 return tsf; 588 } 589 590 /* 591 * Description: Set NIC TSF counter for first Beacon time 592 * Get NEXTTBTT from adjusted TSF and Beacon Interval 593 * 594 * Parameters: 595 * In: 596 * dwIoBase - IO Base 597 * beacon_interval - Beacon Interval 598 * Out: 599 * none 600 * 601 * Return Value: none 602 * 603 */ 604 void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval) 605 { 606 u64 next_tbtt = 0; 607 u8 data[8]; 608 609 vnt_clear_current_tsf(priv); 610 611 next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval); 612 613 data[0] = (u8)next_tbtt; 614 data[1] = (u8)(next_tbtt >> 8); 615 data[2] = (u8)(next_tbtt >> 16); 616 data[3] = (u8)(next_tbtt >> 24); 617 data[4] = (u8)(next_tbtt >> 32); 618 data[5] = (u8)(next_tbtt >> 40); 619 data[6] = (u8)(next_tbtt >> 48); 620 data[7] = (u8)(next_tbtt >> 56); 621 622 vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, 623 MESSAGE_REQUEST_TBTT, 0, 8, data); 624 } 625 626 /* 627 * Description: Sync NIC TSF counter for Beacon time 628 * Get NEXTTBTT and write to HW 629 * 630 * Parameters: 631 * In: 632 * priv - The adapter to be set 633 * tsf - Current TSF counter 634 * beacon_interval - Beacon Interval 635 * Out: 636 * none 637 * 638 * Return Value: none 639 * 640 */ 641 void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, 642 u16 beacon_interval) 643 { 644 u8 data[8]; 645 646 tsf = vnt_get_next_tbtt(tsf, beacon_interval); 647 648 data[0] = (u8)tsf; 649 data[1] = (u8)(tsf >> 8); 650 data[2] = (u8)(tsf >> 16); 651 data[3] = (u8)(tsf >> 24); 652 data[4] = (u8)(tsf >> 32); 653 data[5] = (u8)(tsf >> 40); 654 data[6] = (u8)(tsf >> 48); 655 data[7] = (u8)(tsf >> 56); 656 657 vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, 658 MESSAGE_REQUEST_TBTT, 0, 8, data); 659 660 dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf); 661 } 662 663 /* 664 * Description: Turn off Radio power 665 * 666 * Parameters: 667 * In: 668 * priv - The adapter to be turned off 669 * Out: 670 * none 671 * 672 * Return Value: true if success; otherwise false 673 * 674 */ 675 int vnt_radio_power_off(struct vnt_private *priv) 676 { 677 int ret = true; 678 679 switch (priv->rf_type) { 680 case RF_AL2230: 681 case RF_AL2230S: 682 case RF_AIROHA7230: 683 case RF_VT3226: 684 case RF_VT3226D0: 685 case RF_VT3342A0: 686 vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL, 687 (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); 688 break; 689 } 690 691 vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON); 692 693 vnt_set_deep_sleep(priv); 694 695 vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); 696 697 return ret; 698 } 699 700 /* 701 * Description: Turn on Radio power 702 * 703 * Parameters: 704 * In: 705 * priv - The adapter to be turned on 706 * Out: 707 * none 708 * 709 * Return Value: true if success; otherwise false 710 * 711 */ 712 int vnt_radio_power_on(struct vnt_private *priv) 713 { 714 int ret = true; 715 716 vnt_exit_deep_sleep(priv); 717 718 vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON); 719 720 switch (priv->rf_type) { 721 case RF_AL2230: 722 case RF_AL2230S: 723 case RF_AIROHA7230: 724 case RF_VT3226: 725 case RF_VT3226D0: 726 case RF_VT3342A0: 727 vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL, 728 (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); 729 break; 730 } 731 732 vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); 733 734 return ret; 735 } 736 737 void vnt_set_bss_mode(struct vnt_private *priv) 738 { 739 if (priv->rf_type == RF_AIROHA7230 && priv->bb_type == BB_TYPE_11A) 740 vnt_mac_set_bb_type(priv, BB_TYPE_11G); 741 else 742 vnt_mac_set_bb_type(priv, priv->bb_type); 743 744 priv->packet_type = vnt_get_pkt_type(priv); 745 746 if (priv->bb_type == BB_TYPE_11A) 747 vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x03); 748 else if (priv->bb_type == BB_TYPE_11B) 749 vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x02); 750 else if (priv->bb_type == BB_TYPE_11G) 751 vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x08); 752 753 vnt_update_ifs(priv); 754 vnt_set_rspinf(priv, (u8)priv->bb_type); 755 756 if (priv->bb_type == BB_TYPE_11A) { 757 if (priv->rf_type == RF_AIROHA7230) { 758 priv->bb_vga[0] = 0x20; 759 760 vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 761 0xe7, priv->bb_vga[0]); 762 } 763 764 priv->bb_vga[2] = 0x10; 765 priv->bb_vga[3] = 0x10; 766 } else { 767 if (priv->rf_type == RF_AIROHA7230) { 768 priv->bb_vga[0] = 0x1c; 769 770 vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 771 0xe7, priv->bb_vga[0]); 772 } 773 774 priv->bb_vga[2] = 0x0; 775 priv->bb_vga[3] = 0x0; 776 } 777 778 vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); 779 } 780