Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
0004  * All rights reserved.
0005  *
0006  * Purpose: Provide functions to setup NIC operation mode
0007  * Functions:
0008  *      vnt_set_rspinf - Set RSPINF
0009  *      vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS
0010  *      vnt_update_top_rates - Update BasicTopRate
0011  *      vnt_add_basic_rate - Add to BasicRateSet
0012  *      vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet
0013  *      vnt_get_tsf_offset - Calculate TSFOffset
0014  *      vnt_get_current_tsf - Read Current NIC TSF counter
0015  *      vnt_get_next_tbtt - Calculate Next Beacon TSF counter
0016  *      vnt_reset_next_tbtt - Set NIC Beacon time
0017  *      vnt_update_next_tbtt - Sync. NIC Beacon time
0018  *      vnt_radio_power_off - Turn Off NIC Radio Power
0019  *      vnt_radio_power_on - Turn On NIC Radio Power
0020  *
0021  * Revision History:
0022  *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
0023  *      08-26-2003 Kyle Hsu:      Modify the definition type of dwIoBase.
0024  *      09-01-2003 Bryan YC Fan:  Add vnt_update_ifs().
0025  *
0026  */
0027 
0028 #include <linux/bitops.h>
0029 #include <linux/errno.h>
0030 #include "device.h"
0031 #include "card.h"
0032 #include "baseband.h"
0033 #include "mac.h"
0034 #include "desc.h"
0035 #include "rf.h"
0036 #include "power.h"
0037 #include "key.h"
0038 #include "usbpipe.h"
0039 
0040 /* const u16 cw_rxbcntsf_off[MAX_RATE] =
0041  *   {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
0042  */
0043 
0044 static const u16 cw_rxbcntsf_off[MAX_RATE] = {
0045     192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3
0046 };
0047 
0048 int vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
0049 {
0050     int ret;
0051 
0052     if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
0053         return -EINVAL;
0054 
0055     /* clear NAV */
0056     vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV);
0057 
0058     /* Set Channel[7] = 0 to tell H/W channel is changing now. */
0059     vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL,
0060                  (BIT(7) | BIT(5) | BIT(4)));
0061 
0062     ret = vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL,
0063                   connection_channel, 0, 0, NULL);
0064     if (ret)
0065         return ret;
0066 
0067     return vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
0068                   (u8)(connection_channel | 0x80));
0069 }
0070 
0071 static const u8 vnt_rspinf_b_short_table[] = {
0072     0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x09, 0x00,
0073     0x15, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x80
0074 };
0075 
0076 static const u8 vnt_rspinf_b_long_table[] = {
0077     0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00,
0078     0x15, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x80
0079 };
0080 
0081 static const u8 vnt_rspinf_a_table[] = {
0082     0x9b, 0x18, 0x9f, 0x10, 0x9a, 0x0a, 0x9e, 0x08, 0x99,
0083     0x08, 0x9d, 0x04, 0x98, 0x04, 0x9c, 0x04, 0x9c, 0x04
0084 };
0085 
0086 static const u8 vnt_rspinf_gb_table[] = {
0087     0x8b, 0x1e, 0x8f, 0x16, 0x8a, 0x12, 0x8e, 0x0e, 0x89,
0088     0x0e, 0x8d, 0x0a, 0x88, 0x0a, 0x8c, 0x0a, 0x8c, 0x0a
0089 };
0090 
0091 int vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
0092 {
0093     const u8 *data;
0094     u16 len;
0095     int ret;
0096 
0097     if (priv->preamble_type) {
0098         data = vnt_rspinf_b_short_table;
0099         len = ARRAY_SIZE(vnt_rspinf_b_short_table);
0100     } else {
0101         data = vnt_rspinf_b_long_table;
0102         len = ARRAY_SIZE(vnt_rspinf_b_long_table);
0103     }
0104 
0105      /* RSPINF_b_1 to RSPINF_b_11 */
0106     ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1,
0107                   MESSAGE_REQUEST_MACREG, len, data);
0108     if (ret)
0109         return ret;
0110 
0111     if (bb_type == BB_TYPE_11A) {
0112         data = vnt_rspinf_a_table;
0113         len = ARRAY_SIZE(vnt_rspinf_a_table);
0114     } else {
0115         data = vnt_rspinf_gb_table;
0116         len = ARRAY_SIZE(vnt_rspinf_gb_table);
0117     }
0118 
0119     /* RSPINF_a_6 to RSPINF_a_72 */
0120     return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_A_6,
0121                    MESSAGE_REQUEST_MACREG, len, data);
0122 }
0123 
0124 int vnt_update_ifs(struct vnt_private *priv)
0125 {
0126     u8 max_min = 0;
0127     u8 data[4];
0128     int ret;
0129 
0130     if (priv->packet_type == PK_TYPE_11A) {
0131         priv->slot = C_SLOT_SHORT;
0132         priv->sifs = C_SIFS_A;
0133         priv->difs = C_SIFS_A + 2 * C_SLOT_SHORT;
0134         max_min = 4;
0135     } else {
0136         priv->sifs = C_SIFS_BG;
0137 
0138         if (priv->short_slot_time) {
0139             priv->slot = C_SLOT_SHORT;
0140             max_min = 4;
0141         } else {
0142             priv->slot = C_SLOT_LONG;
0143             max_min = 5;
0144         }
0145 
0146         priv->difs = C_SIFS_BG + 2 * priv->slot;
0147     }
0148 
0149     priv->eifs = C_EIFS;
0150 
0151     data[0] = (u8)priv->sifs;
0152     data[1] = (u8)priv->difs;
0153     data[2] = (u8)priv->eifs;
0154     data[3] = (u8)priv->slot;
0155 
0156     ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
0157                   MESSAGE_REQUEST_MACREG, 4, &data[0]);
0158     if (ret)
0159         return ret;
0160 
0161     max_min |= 0xa0;
0162 
0163     return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
0164                    MESSAGE_REQUEST_MACREG, 1, &max_min);
0165 }
0166 
0167 void vnt_update_top_rates(struct vnt_private *priv)
0168 {
0169     int pos;
0170 
0171     pos = fls(priv->basic_rates & GENMASK(RATE_54M, RATE_6M));
0172     priv->top_ofdm_basic_rate = pos ? (pos - 1) : RATE_24M;
0173 
0174     pos = fls(priv->basic_rates & GENMASK(RATE_11M, RATE_1M));
0175     priv->top_cck_basic_rate = pos ? (pos - 1) : RATE_1M;
0176 }
0177 
0178 bool vnt_ofdm_min_rate(struct vnt_private *priv)
0179 {
0180     return priv->basic_rates & GENMASK(RATE_54M, RATE_6M) ? true : false;
0181 }
0182 
0183 u8 vnt_get_pkt_type(struct vnt_private *priv)
0184 {
0185     if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B)
0186         return (u8)priv->bb_type;
0187     else if (vnt_ofdm_min_rate(priv))
0188         return PK_TYPE_11GA;
0189     return PK_TYPE_11GB;
0190 }
0191 
0192 /*
0193  * Description: Calculate TSF offset of two TSF input
0194  *              Get TSF Offset from RxBCN's TSF and local TSF
0195  *
0196  * Parameters:
0197  *  In:
0198  *      rx_rate - rx rate.
0199  *      tsf1    - Rx BCN's TSF
0200  *      tsf2    - Local TSF
0201  *  Out:
0202  *      none
0203  *
0204  * Return Value: TSF Offset value
0205  *
0206  */
0207 u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
0208 {
0209     return tsf1 - tsf2 - (u64)cw_rxbcntsf_off[rx_rate % MAX_RATE];
0210 }
0211 
0212 int vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
0213            u64 time_stamp, u64 local_tsf)
0214 {
0215     u64 tsf_offset = 0;
0216     u8 data[8];
0217 
0218     tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf);
0219 
0220     data[0] = (u8)tsf_offset;
0221     data[1] = (u8)(tsf_offset >> 8);
0222     data[2] = (u8)(tsf_offset >> 16);
0223     data[3] = (u8)(tsf_offset >> 24);
0224     data[4] = (u8)(tsf_offset >> 32);
0225     data[5] = (u8)(tsf_offset >> 40);
0226     data[6] = (u8)(tsf_offset >> 48);
0227     data[7] = (u8)(tsf_offset >> 56);
0228 
0229     return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
0230                    MESSAGE_REQUEST_TSF, 0, 8, data);
0231 }
0232 
0233 /*
0234  * Description: Read NIC TSF counter
0235  *              Get local TSF counter
0236  *
0237  * Parameters:
0238  *  In:
0239  *  priv        - The adapter to be read
0240  *  Out:
0241  *  current_tsf - Current TSF counter
0242  *
0243  * Return Value: true if success; otherwise false
0244  *
0245  */
0246 bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
0247 {
0248     *current_tsf = priv->current_tsf;
0249 
0250     return true;
0251 }
0252 
0253 /*
0254  * Description: Clear NIC TSF counter
0255  *              Clear local TSF counter
0256  *
0257  * Parameters:
0258  *  In:
0259  *      priv    - The adapter to be read
0260  *
0261  * Return Value: true if success; otherwise false
0262  *
0263  */
0264 bool vnt_clear_current_tsf(struct vnt_private *priv)
0265 {
0266     vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
0267 
0268     priv->current_tsf = 0;
0269 
0270     return true;
0271 }
0272 
0273 /*
0274  * Description: Read NIC TSF counter
0275  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
0276  *
0277  * Parameters:
0278  *  In:
0279  *      tsf     - Current TSF counter
0280  *      beacon_interval - Beacon Interval
0281  *  Out:
0282  *      tsf     - Current TSF counter
0283  *
0284  * Return Value: TSF value of next Beacon
0285  *
0286  */
0287 u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval)
0288 {
0289     u32 beacon_int;
0290 
0291     beacon_int = beacon_interval * 1024;
0292 
0293     /* Next TBTT =
0294      *  ((local_current_TSF / beacon_interval) + 1) * beacon_interval
0295      */
0296     if (beacon_int) {
0297         do_div(tsf, beacon_int);
0298         tsf += 1;
0299         tsf *= beacon_int;
0300     }
0301 
0302     return tsf;
0303 }
0304 
0305 int vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
0306 {
0307     u64 next_tbtt = 0;
0308     u8 data[8];
0309 
0310     vnt_clear_current_tsf(priv);
0311 
0312     next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval);
0313 
0314     data[0] = (u8)next_tbtt;
0315     data[1] = (u8)(next_tbtt >> 8);
0316     data[2] = (u8)(next_tbtt >> 16);
0317     data[3] = (u8)(next_tbtt >> 24);
0318     data[4] = (u8)(next_tbtt >> 32);
0319     data[5] = (u8)(next_tbtt >> 40);
0320     data[6] = (u8)(next_tbtt >> 48);
0321     data[7] = (u8)(next_tbtt >> 56);
0322 
0323     return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
0324                    MESSAGE_REQUEST_TBTT, 0, 8, data);
0325 }
0326 
0327 int vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
0328              u16 beacon_interval)
0329 {
0330     u8 data[8];
0331     int ret;
0332 
0333     tsf = vnt_get_next_tbtt(tsf, beacon_interval);
0334 
0335     data[0] = (u8)tsf;
0336     data[1] = (u8)(tsf >> 8);
0337     data[2] = (u8)(tsf >> 16);
0338     data[3] = (u8)(tsf >> 24);
0339     data[4] = (u8)(tsf >> 32);
0340     data[5] = (u8)(tsf >> 40);
0341     data[6] = (u8)(tsf >> 48);
0342     data[7] = (u8)(tsf >> 56);
0343 
0344     ret = vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
0345                   MESSAGE_REQUEST_TBTT, 0, 8, data);
0346     if (ret)
0347         return ret;
0348 
0349     dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf);
0350     return 0;
0351 }
0352 
0353 /*
0354  * Description: Turn off Radio power
0355  *
0356  * Parameters:
0357  *  In:
0358  *      priv         - The adapter to be turned off
0359  *  Out:
0360  *      none
0361  *
0362  * Return Value: true if success; otherwise false
0363  *
0364  */
0365 int vnt_radio_power_off(struct vnt_private *priv)
0366 {
0367     int ret = 0;
0368 
0369     switch (priv->rf_type) {
0370     case RF_AL2230:
0371     case RF_AL2230S:
0372     case RF_VT3226:
0373     case RF_VT3226D0:
0374         ret = vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL,
0375                        (SOFTPWRCTL_SWPE2 |
0376                         SOFTPWRCTL_SWPE3));
0377         break;
0378     }
0379 
0380     if (ret)
0381         goto end;
0382 
0383     ret = vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
0384     if (ret)
0385         goto end;
0386 
0387     ret = vnt_set_deep_sleep(priv);
0388     if (ret)
0389         goto end;
0390 
0391     ret = vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
0392 
0393 end:
0394     return ret;
0395 }
0396 
0397 /*
0398  * Description: Turn on Radio power
0399  *
0400  * Parameters:
0401  *  In:
0402  *      priv         - The adapter to be turned on
0403  *  Out:
0404  *      none
0405  *
0406  * Return Value: true if success; otherwise false
0407  *
0408  */
0409 int vnt_radio_power_on(struct vnt_private *priv)
0410 {
0411     int ret = 0;
0412 
0413     ret = vnt_exit_deep_sleep(priv);
0414     if (ret)
0415         return ret;
0416 
0417     ret = vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
0418     if (ret)
0419         return ret;
0420 
0421     switch (priv->rf_type) {
0422     case RF_AL2230:
0423     case RF_AL2230S:
0424     case RF_VT3226:
0425     case RF_VT3226D0:
0426         ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
0427                       (SOFTPWRCTL_SWPE2 |
0428                        SOFTPWRCTL_SWPE3));
0429         if (ret)
0430             return ret;
0431     }
0432 
0433     return vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
0434 }
0435 
0436 int vnt_set_bss_mode(struct vnt_private *priv)
0437 {
0438     int ret;
0439     unsigned char type = priv->bb_type;
0440     unsigned char data = 0;
0441     unsigned char bb_vga_2_3 = 0x00;
0442 
0443     ret = vnt_mac_set_bb_type(priv, type);
0444     if (ret)
0445         return ret;
0446 
0447     priv->packet_type = vnt_get_pkt_type(priv);
0448 
0449     if (priv->bb_type == BB_TYPE_11A) {
0450         data = 0x03;
0451         bb_vga_2_3 = 0x10;
0452     } else if (priv->bb_type == BB_TYPE_11B) {
0453         data = 0x02;
0454     } else if (priv->bb_type == BB_TYPE_11G) {
0455         data = 0x08;
0456     }
0457 
0458     if (data) {
0459         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
0460                      0x88, data);
0461         if (ret)
0462             return ret;
0463     }
0464 
0465     ret = vnt_update_ifs(priv);
0466     if (ret)
0467         return ret;
0468 
0469     ret = vnt_set_rspinf(priv, priv->bb_type);
0470     if (ret)
0471         return ret;
0472 
0473     priv->bb_vga[2] = bb_vga_2_3;
0474     priv->bb_vga[3] = bb_vga_2_3;
0475 
0476     return vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
0477 }