d74165d0d3bb41ace130de167b20547dded341ca
[linux-2.6-microblaze.git] / drivers / staging / vt6656 / card.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4  * All rights reserved.
5  *
6  * Purpose: Provide functions to setup NIC operation mode
7  * Functions:
8  *      vnt_set_rspinf - Set RSPINF
9  *      vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS
10  *      vnt_update_top_rates - Update BasicTopRate
11  *      vnt_add_basic_rate - Add to BasicRateSet
12  *      vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet
13  *      vnt_get_tsf_offset - Calculate TSFOffset
14  *      vnt_get_current_tsf - Read Current NIC TSF counter
15  *      vnt_get_next_tbtt - Calculate Next Beacon TSF counter
16  *      vnt_reset_next_tbtt - Set NIC Beacon time
17  *      vnt_update_next_tbtt - Sync. NIC Beacon time
18  *      vnt_radio_power_off - Turn Off NIC Radio Power
19  *      vnt_radio_power_on - Turn On NIC Radio Power
20  *
21  * Revision History:
22  *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
23  *      08-26-2003 Kyle Hsu:      Modify the definition type of dwIoBase.
24  *      09-01-2003 Bryan YC Fan:  Add vnt_update_ifs().
25  *
26  */
27
28 #include <linux/bitops.h>
29 #include <linux/errno.h>
30 #include "device.h"
31 #include "card.h"
32 #include "baseband.h"
33 #include "mac.h"
34 #include "desc.h"
35 #include "rf.h"
36 #include "power.h"
37 #include "key.h"
38 #include "usbpipe.h"
39
40 /* const u16 cw_rxbcntsf_off[MAX_RATE] =
41  *   {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
42  */
43
44 static const u16 cw_rxbcntsf_off[MAX_RATE] = {
45         192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3
46 };
47
48 int vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
49 {
50         int ret;
51
52         if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
53                 return -EINVAL;
54
55         /* clear NAV */
56         vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV);
57
58         /* Set Channel[7] = 0 to tell H/W channel is changing now. */
59         vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL,
60                              (BIT(7) | BIT(5) | BIT(4)));
61
62         ret = vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL,
63                               connection_channel, 0, 0, NULL);
64         if (ret)
65                 return ret;
66
67         return vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
68                                   (u8)(connection_channel | 0x80));
69 }
70
71 static const u8 vnt_rspinf_b_short_table[] = {
72         0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x09, 0x00,
73         0x15, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x80
74 };
75
76 static const u8 vnt_rspinf_b_long_table[] = {
77         0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00,
78         0x15, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x80
79 };
80
81 static const u8 vnt_rspinf_a_table[] = {
82         0x9b, 0x18, 0x9f, 0x10, 0x9a, 0x0a, 0x9e, 0x08, 0x99,
83         0x08, 0x9d, 0x04, 0x98, 0x04, 0x9c, 0x04, 0x9c, 0x04
84 };
85
86 static const u8 vnt_rspinf_gb_table[] = {
87         0x8b, 0x1e, 0x8f, 0x16, 0x8a, 0x12, 0x8e, 0x0e, 0x89,
88         0x0e, 0x8d, 0x0a, 0x88, 0x0a, 0x8c, 0x0a, 0x8c, 0x0a
89 };
90
91 int vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
92 {
93         const u8 *data;
94         u16 len;
95         int ret;
96
97         if (priv->preamble_type) {
98                 data = vnt_rspinf_b_short_table;
99                 len = ARRAY_SIZE(vnt_rspinf_b_short_table);
100         } else {
101                 data = vnt_rspinf_b_long_table;
102                 len = ARRAY_SIZE(vnt_rspinf_b_long_table);
103         }
104
105          /* RSPINF_b_1 to RSPINF_b_11 */
106         ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1,
107                               MESSAGE_REQUEST_MACREG, len, data);
108         if (ret)
109                 return ret;
110
111         if (bb_type == BB_TYPE_11A) {
112                 data = vnt_rspinf_a_table;
113                 len = ARRAY_SIZE(vnt_rspinf_a_table);
114         } else {
115                 data = vnt_rspinf_gb_table;
116                 len = ARRAY_SIZE(vnt_rspinf_gb_table);
117         }
118
119         /* RSPINF_a_6 to RSPINF_a_72 */
120         return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_A_6,
121                                MESSAGE_REQUEST_MACREG, len, data);
122 }
123
124 int vnt_update_ifs(struct vnt_private *priv)
125 {
126         u8 max_min = 0;
127         u8 data[4];
128         int ret;
129
130         if (priv->packet_type == PK_TYPE_11A) {
131                 priv->slot = C_SLOT_SHORT;
132                 priv->sifs = C_SIFS_A;
133                 priv->difs = C_SIFS_A + 2 * C_SLOT_SHORT;
134                 max_min = 4;
135         } else {
136                 priv->sifs = C_SIFS_BG;
137
138                 if (priv->short_slot_time) {
139                         priv->slot = C_SLOT_SHORT;
140                         max_min = 4;
141                 } else {
142                         priv->slot = C_SLOT_LONG;
143                         max_min = 5;
144                 }
145
146                 priv->difs = C_SIFS_BG + 2 * priv->slot;
147         }
148
149         priv->eifs = C_EIFS;
150
151         data[0] = (u8)priv->sifs;
152         data[1] = (u8)priv->difs;
153         data[2] = (u8)priv->eifs;
154         data[3] = (u8)priv->slot;
155
156         ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
157                               MESSAGE_REQUEST_MACREG, 4, &data[0]);
158         if (ret)
159                 return ret;
160
161         max_min |= 0xa0;
162
163         return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
164                                MESSAGE_REQUEST_MACREG, 1, &max_min);
165 }
166
167 void vnt_update_top_rates(struct vnt_private *priv)
168 {
169         int pos;
170
171         pos = fls(priv->basic_rates & GENMASK(RATE_54M, RATE_6M));
172         priv->top_ofdm_basic_rate = pos ? (pos - 1) : RATE_24M;
173
174         pos = fls(priv->basic_rates & GENMASK(RATE_11M, RATE_1M));
175         priv->top_cck_basic_rate = pos ? (pos - 1) : RATE_1M;
176 }
177
178 bool vnt_ofdm_min_rate(struct vnt_private *priv)
179 {
180         return priv->basic_rates & GENMASK(RATE_54M, RATE_6M) ? true : false;
181 }
182
183 u8 vnt_get_pkt_type(struct vnt_private *priv)
184 {
185         if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B)
186                 return (u8)priv->bb_type;
187         else if (vnt_ofdm_min_rate(priv))
188                 return PK_TYPE_11GA;
189         return PK_TYPE_11GB;
190 }
191
192 /*
193  * Description: Calculate TSF offset of two TSF input
194  *              Get TSF Offset from RxBCN's TSF and local TSF
195  *
196  * Parameters:
197  *  In:
198  *      rx_rate - rx rate.
199  *      tsf1    - Rx BCN's TSF
200  *      tsf2    - Local TSF
201  *  Out:
202  *      none
203  *
204  * Return Value: TSF Offset value
205  *
206  */
207 u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
208 {
209         return tsf1 - tsf2 - (u64)cw_rxbcntsf_off[rx_rate % MAX_RATE];
210 }
211
212 int vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
213                    u64 time_stamp, u64 local_tsf)
214 {
215         u64 tsf_offset = 0;
216         u8 data[8];
217
218         tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf);
219
220         data[0] = (u8)tsf_offset;
221         data[1] = (u8)(tsf_offset >> 8);
222         data[2] = (u8)(tsf_offset >> 16);
223         data[3] = (u8)(tsf_offset >> 24);
224         data[4] = (u8)(tsf_offset >> 32);
225         data[5] = (u8)(tsf_offset >> 40);
226         data[6] = (u8)(tsf_offset >> 48);
227         data[7] = (u8)(tsf_offset >> 56);
228
229         return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
230                                MESSAGE_REQUEST_TSF, 0, 8, data);
231 }
232
233 /*
234  * Description: Read NIC TSF counter
235  *              Get local TSF counter
236  *
237  * Parameters:
238  *  In:
239  *      priv            - The adapter to be read
240  *  Out:
241  *      current_tsf     - Current TSF counter
242  *
243  * Return Value: true if success; otherwise false
244  *
245  */
246 bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
247 {
248         *current_tsf = priv->current_tsf;
249
250         return true;
251 }
252
253 /*
254  * Description: Clear NIC TSF counter
255  *              Clear local TSF counter
256  *
257  * Parameters:
258  *  In:
259  *      priv    - The adapter to be read
260  *
261  * Return Value: true if success; otherwise false
262  *
263  */
264 bool vnt_clear_current_tsf(struct vnt_private *priv)
265 {
266         vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
267
268         priv->current_tsf = 0;
269
270         return true;
271 }
272
273 /*
274  * Description: Read NIC TSF counter
275  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
276  *
277  * Parameters:
278  *  In:
279  *      tsf             - Current TSF counter
280  *      beacon_interval - Beacon Interval
281  *  Out:
282  *      tsf             - Current TSF counter
283  *
284  * Return Value: TSF value of next Beacon
285  *
286  */
287 u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval)
288 {
289         u32 beacon_int;
290
291         beacon_int = beacon_interval * 1024;
292
293         /* Next TBTT =
294          *      ((local_current_TSF / beacon_interval) + 1) * beacon_interval
295          */
296         if (beacon_int) {
297                 do_div(tsf, beacon_int);
298                 tsf += 1;
299                 tsf *= beacon_int;
300         }
301
302         return tsf;
303 }
304
305 int vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
306 {
307         u64 next_tbtt = 0;
308         u8 data[8];
309
310         vnt_clear_current_tsf(priv);
311
312         next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval);
313
314         data[0] = (u8)next_tbtt;
315         data[1] = (u8)(next_tbtt >> 8);
316         data[2] = (u8)(next_tbtt >> 16);
317         data[3] = (u8)(next_tbtt >> 24);
318         data[4] = (u8)(next_tbtt >> 32);
319         data[5] = (u8)(next_tbtt >> 40);
320         data[6] = (u8)(next_tbtt >> 48);
321         data[7] = (u8)(next_tbtt >> 56);
322
323         return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
324                                MESSAGE_REQUEST_TBTT, 0, 8, data);
325 }
326
327 int vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
328                          u16 beacon_interval)
329 {
330         u8 data[8];
331         int ret;
332
333         tsf = vnt_get_next_tbtt(tsf, beacon_interval);
334
335         data[0] = (u8)tsf;
336         data[1] = (u8)(tsf >> 8);
337         data[2] = (u8)(tsf >> 16);
338         data[3] = (u8)(tsf >> 24);
339         data[4] = (u8)(tsf >> 32);
340         data[5] = (u8)(tsf >> 40);
341         data[6] = (u8)(tsf >> 48);
342         data[7] = (u8)(tsf >> 56);
343
344         ret = vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
345                               MESSAGE_REQUEST_TBTT, 0, 8, data);
346         if (ret)
347                 return ret;
348
349         dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf);
350         return 0;
351 }
352
353 /*
354  * Description: Turn off Radio power
355  *
356  * Parameters:
357  *  In:
358  *      priv         - The adapter to be turned off
359  *  Out:
360  *      none
361  *
362  * Return Value: true if success; otherwise false
363  *
364  */
365 int vnt_radio_power_off(struct vnt_private *priv)
366 {
367         int ret = 0;
368
369         switch (priv->rf_type) {
370         case RF_AL2230:
371         case RF_AL2230S:
372         case RF_VT3226:
373         case RF_VT3226D0:
374                 ret = vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL,
375                                            (SOFTPWRCTL_SWPE2 |
376                                             SOFTPWRCTL_SWPE3));
377                 break;
378         }
379
380         if (ret)
381                 goto end;
382
383         ret = vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
384         if (ret)
385                 goto end;
386
387         ret = vnt_set_deep_sleep(priv);
388         if (ret)
389                 goto end;
390
391         ret = vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
392
393 end:
394         return ret;
395 }
396
397 /*
398  * Description: Turn on Radio power
399  *
400  * Parameters:
401  *  In:
402  *      priv         - The adapter to be turned on
403  *  Out:
404  *      none
405  *
406  * Return Value: true if success; otherwise false
407  *
408  */
409 int vnt_radio_power_on(struct vnt_private *priv)
410 {
411         int ret = 0;
412
413         ret = vnt_exit_deep_sleep(priv);
414         if (ret)
415                 return ret;
416
417         ret = vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
418         if (ret)
419                 return ret;
420
421         switch (priv->rf_type) {
422         case RF_AL2230:
423         case RF_AL2230S:
424         case RF_VT3226:
425         case RF_VT3226D0:
426                 ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
427                                           (SOFTPWRCTL_SWPE2 |
428                                            SOFTPWRCTL_SWPE3));
429                 if (ret)
430                         return ret;
431         }
432
433         return vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
434 }
435
436 int vnt_set_bss_mode(struct vnt_private *priv)
437 {
438         int ret;
439         unsigned char type = priv->bb_type;
440         unsigned char data = 0;
441         unsigned char bb_vga_0 = 0x1c;
442         unsigned char bb_vga_2_3 = 0x00;
443
444         ret = vnt_mac_set_bb_type(priv, type);
445         if (ret)
446                 return ret;
447
448         priv->packet_type = vnt_get_pkt_type(priv);
449
450         if (priv->bb_type == BB_TYPE_11A) {
451                 data = 0x03;
452                 bb_vga_0 = 0x20;
453                 bb_vga_2_3 = 0x10;
454         } else if (priv->bb_type == BB_TYPE_11B) {
455                 data = 0x02;
456         } else if (priv->bb_type == BB_TYPE_11G) {
457                 data = 0x08;
458         }
459
460         if (data) {
461                 ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
462                                          0x88, data);
463                 if (ret)
464                         return ret;
465         }
466
467         ret = vnt_update_ifs(priv);
468         if (ret)
469                 return ret;
470
471         ret = vnt_set_rspinf(priv, priv->bb_type);
472         if (ret)
473                 return ret;
474
475         priv->bb_vga[2] = bb_vga_2_3;
476         priv->bb_vga[3] = bb_vga_2_3;
477
478         return vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
479 }