GNU Linux-libre 5.10.153-gnu1
[releases.git] / drivers / staging / vt6656 / baseband.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4  * All rights reserved.
5  *
6  * File: baseband.c
7  *
8  * Purpose: Implement functions to access baseband
9  *
10  * Author: Jerry Chen
11  *
12  * Date: Jun. 5, 2002
13  *
14  * Functions:
15  *      vnt_get_frame_time      - Calculate data frame transmitting time
16  *      vnt_get_phy_field       - Calculate PhyLength, PhyService and Phy
17  *                                Signal parameter for baseband Tx
18  *      vnt_vt3184_init         - VIA VT3184 baseband chip init code
19  *
20  * Revision History:
21  *
22  *
23  */
24
25 #include <linux/bits.h>
26 #include <linux/errno.h>
27 #include <linux/kernel.h>
28 #include "device.h"
29 #include "mac.h"
30 #include "baseband.h"
31 #include "rf.h"
32 #include "usbpipe.h"
33
34 static const u8 vnt_vt3184_agc[] = {
35         0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
36         0x08, 0x08, 0x0a, 0x0a, 0x0c, 0x0c, 0x0e, 0x0e, /* 0x0f */
37         0x10, 0x10, 0x12, 0x12, 0x14, 0x14, 0x16, 0x16,
38         0x18, 0x18, 0x1a, 0x1a, 0x1c, 0x1c, 0x1e, 0x1e, /* 0x1f */
39         0x20, 0x20, 0x22, 0x22, 0x24, 0x24, 0x26, 0x26,
40         0x28, 0x28, 0x2a, 0x2a, 0x2c, 0x2c, 0x2e, 0x2e, /* 0x2f */
41         0x30, 0x30, 0x32, 0x32, 0x34, 0x34, 0x36, 0x36,
42         0x38, 0x38, 0x3a, 0x3a, 0x3c, 0x3c, 0x3e, 0x3e  /* 0x3f */
43 };
44
45 static u8 vnt_vt3184_al2230[] = {
46         0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
47         0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */
48         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49         0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */
50         0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
51         0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */
52         0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
53         0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */
54         0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09,
55         0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */
56         0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57         0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */
58         0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a,
59         0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */
60         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */
62         0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
63         0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */
64         0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
65         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */
66         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
67         0x18, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x18, /* 0xaf */
68         0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2,
69         0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */
70         0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x0e, 0x0a,
71         0x0e, 0x00, 0x82, 0xa7, 0x3c, 0x10, 0x30, 0x05, /* 0xcf */
72         0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a,
73         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */
74         0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12,
75         0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x05, /* 0xef */
76         0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* 0xff */
78 };
79
80 /* {{RobertYu:20060515, new BB setting for VT3226D0 */
81 static const u8 vnt_vt3184_vt3226d0[] = {
82         0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
83         0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */
84         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85         0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */
86         0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
87         0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */
88         0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
89         0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */
90         0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09,
91         0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */
92         0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93         0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */
94         0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a,
95         0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */
96         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */
98         0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
99         0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */
100         0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
101         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */
102         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
103         0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0xaf */
104         0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2,
105         0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */
106         0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x10, 0x0a,
107         0x0e, 0x00, 0x84, 0xa7, 0x3c, 0x10, 0x24, 0x05, /* 0xcf */
108         0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a,
109         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */
110         0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10,
111         0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x08, /* 0xef */
112         0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* 0xff */
114 };
115
116 struct vnt_threshold {
117         u8 bb_pre_ed_rssi;
118         u8 cr_201;
119         u8 cr_206;
120 };
121
122 static const struct vnt_threshold al2230_vnt_threshold[] = {
123         {0, 0x00, 0x30},        /* Max sensitivity */
124         {68, 0x00, 0x36},
125         {67, 0x00, 0x43},
126         {66, 0x00, 0x51},
127         {65, 0x00, 0x62},
128         {64, 0x00, 0x79},
129         {63, 0x00, 0x93},
130         {62, 0x00, 0xb9},
131         {61, 0x00, 0xe3},
132         {60, 0x01, 0x18},
133         {59, 0x01, 0x54},
134         {58, 0x01, 0xa0},
135         {57, 0x02, 0x20},
136         {56, 0x02, 0xa0},
137         {55, 0x03, 0x00},
138         {53, 0x06, 0x00},
139         {51, 0x09, 0x00},
140         {49, 0x0e, 0x00},
141         {47, 0x15, 0x00},
142         {46, 0x1a, 0x00},
143         {45, 0xff, 0x00}
144 };
145
146 static const struct vnt_threshold vt3226_vnt_threshold[] = {
147         {0, 0x00, 0x24},        /* Max sensitivity */
148         {68, 0x00, 0x2d},
149         {67, 0x00, 0x36},
150         {66, 0x00, 0x43},
151         {65, 0x00, 0x52},
152         {64, 0x00, 0x68},
153         {63, 0x00, 0x80},
154         {62, 0x00, 0x9c},
155         {61, 0x00, 0xc0},
156         {60, 0x00, 0xea},
157         {59, 0x01, 0x30},
158         {58, 0x01, 0x70},
159         {57, 0x01, 0xb0},
160         {56, 0x02, 0x30},
161         {55, 0x02, 0xc0},
162         {53, 0x04, 0x00},
163         {51, 0x07, 0x00},
164         {49, 0x0a, 0x00},
165         {47, 0x11, 0x00},
166         {45, 0x18, 0x00},
167         {43, 0x26, 0x00},
168         {42, 0x36, 0x00},
169         {41, 0xff, 0x00}
170 };
171
172 static const struct vnt_threshold vt3342_vnt_threshold[] = {
173         {0, 0x00, 0x38},        /* Max sensitivity */
174         {66, 0x00, 0x43},
175         {65, 0x00, 0x52},
176         {64, 0x00, 0x68},
177         {63, 0x00, 0x80},
178         {62, 0x00, 0x9c},
179         {61, 0x00, 0xc0},
180         {60, 0x00, 0xea},
181         {59, 0x01, 0x30},
182         {58, 0x01, 0x70},
183         {57, 0x01, 0xb0},
184         {56, 0x02, 0x30},
185         {55, 0x02, 0xc0},
186         {53, 0x04, 0x00},
187         {51, 0x07, 0x00},
188         {49, 0x0a, 0x00},
189         {47, 0x11, 0x00},
190         {45, 0x18, 0x00},
191         {43, 0x26, 0x00},
192         {42, 0x36, 0x00},
193         {41, 0xff, 0x00}
194 };
195
196 /*
197  * Description: Set Antenna mode
198  *
199  * Parameters:
200  *  In:
201  *      priv            - Device Structure
202  *      antenna_mode    - Antenna Mode
203  *  Out:
204  *      none
205  *
206  * Return Value: none
207  *
208  */
209 int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode)
210 {
211         switch (antenna_mode) {
212         case ANT_TXA:
213         case ANT_TXB:
214                 break;
215         case ANT_RXA:
216                 priv->bb_rx_conf &= 0xFC;
217                 break;
218         case ANT_RXB:
219                 priv->bb_rx_conf &= 0xFE;
220                 priv->bb_rx_conf |= 0x02;
221                 break;
222         }
223
224         return vnt_control_out(priv, MESSAGE_TYPE_SET_ANTMD,
225                                (u16)antenna_mode, 0, 0, NULL);
226 }
227
228 /*
229  * Description: Set Antenna mode
230  *
231  * Parameters:
232  *  In:
233  *      pDevice          - Device Structure
234  *      byAntennaMode    - Antenna Mode
235  *  Out:
236  *      none
237  *
238  * Return Value: none
239  *
240  */
241
242 int vnt_vt3184_init(struct vnt_private *priv)
243 {
244         int ret;
245         u16 length;
246         u8 *addr = NULL;
247         const u8 *c_addr;
248         u8 data;
249
250         ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, MESSAGE_REQUEST_EEPROM,
251                              EEP_MAX_CONTEXT_SIZE, priv->eeprom);
252         if (ret)
253                 goto end;
254
255         priv->rf_type = priv->eeprom[EEP_OFS_RFTYPE];
256
257         dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
258
259         if ((priv->rf_type == RF_AL2230) ||
260             (priv->rf_type == RF_AL2230S) ||
261             (priv->rf_type == RF_AIROHA7230)) {
262                 priv->bb_rx_conf = vnt_vt3184_al2230[10];
263                 length = sizeof(vnt_vt3184_al2230);
264                 addr = vnt_vt3184_al2230;
265
266                 if (priv->rf_type == RF_AIROHA7230)
267                         addr[0xd7] = 0x06;
268
269                 priv->bb_vga[0] = 0x1c;
270                 priv->bb_vga[1] = 0x10;
271                 priv->bb_vga[2] = 0x0;
272                 priv->bb_vga[3] = 0x0;
273
274         } else if ((priv->rf_type == RF_VT3226) ||
275                    (priv->rf_type == RF_VT3226D0) ||
276                    (priv->rf_type == RF_VT3342A0)) {
277                 priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
278                 length = sizeof(vnt_vt3184_vt3226d0);
279                 c_addr = vnt_vt3184_vt3226d0;
280
281                 priv->bb_vga[0] = 0x20;
282                 priv->bb_vga[1] = 0x10;
283                 priv->bb_vga[2] = 0x0;
284                 priv->bb_vga[3] = 0x0;
285
286                 /* Fix VT3226 DFC system timing issue */
287                 ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
288                                           SOFTPWRCTL_RFLEOPT);
289                 if (ret)
290                         goto end;
291         } else {
292                 goto end;
293         }
294
295         if (addr)
296                 c_addr = addr;
297
298         ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
299                                      MESSAGE_REQUEST_BBREG, length, c_addr);
300         if (ret)
301                 goto end;
302
303         ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
304                               MESSAGE_REQUEST_BBAGC,
305                               sizeof(vnt_vt3184_agc), vnt_vt3184_agc);
306         if (ret)
307                 goto end;
308
309         if ((priv->rf_type == RF_VT3226) ||
310             (priv->rf_type == RF_VT3342A0) ||
311             (priv->rf_type == RF_VT3226D0)) {
312                 data = (priv->rf_type == RF_VT3226D0) ? 0x11 : 0x23;
313
314                 ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
315                                          MAC_REG_ITRTMSET, data);
316                 if (ret)
317                         goto end;
318
319                 ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0));
320                 if (ret)
321                         goto end;
322         }
323
324         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f);
325         if (ret)
326                 goto end;
327
328         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
329         if (ret)
330                 goto end;
331
332         ret = vnt_rf_table_download(priv);
333         if (ret)
334                 goto end;
335
336         /* Fix for TX USB resets from vendors driver */
337         ret = vnt_control_in(priv, MESSAGE_TYPE_READ, USB_REG4,
338                              MESSAGE_REQUEST_MEM, sizeof(data), &data);
339         if (ret)
340                 goto end;
341
342         data |= 0x2;
343
344         ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, USB_REG4,
345                               MESSAGE_REQUEST_MEM, sizeof(data), &data);
346
347 end:
348         return ret;
349 }
350
351 /*
352  * Description: Set ShortSlotTime mode
353  *
354  * Parameters:
355  *  In:
356  *      priv    - Device Structure
357  *  Out:
358  *      none
359  *
360  * Return Value: none
361  *
362  */
363 int vnt_set_short_slot_time(struct vnt_private *priv)
364 {
365         int ret = 0;
366         u8 bb_vga = 0;
367
368         if (priv->short_slot_time)
369                 priv->bb_rx_conf &= 0xdf;
370         else
371                 priv->bb_rx_conf |= 0x20;
372
373         ret = vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga);
374         if (ret)
375                 return ret;
376
377         if (bb_vga == priv->bb_vga[0])
378                 priv->bb_rx_conf |= 0x20;
379
380         return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
381                                   priv->bb_rx_conf);
382 }
383
384 int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data)
385 {
386         int ret;
387
388         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data);
389         if (ret)
390                 return ret;
391
392         /* patch for 3253B0 Baseband with Cardbus module */
393         if (priv->short_slot_time)
394                 priv->bb_rx_conf &= 0xdf; /* 1101 1111 */
395         else
396                 priv->bb_rx_conf |= 0x20; /* 0010 0000 */
397
398         return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
399                                   priv->bb_rx_conf);
400 }
401
402 /*
403  * Description: vnt_set_deep_sleep
404  *
405  * Parameters:
406  *  In:
407  *      priv    - Device Structure
408  *  Out:
409  *      none
410  *
411  * Return Value: none
412  *
413  */
414 int vnt_set_deep_sleep(struct vnt_private *priv)
415 {
416         int ret = 0;
417
418         /* CR12 */
419         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);
420         if (ret)
421                 return ret;
422
423         /* CR13 */
424         return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0xB9);
425 }
426
427 int vnt_exit_deep_sleep(struct vnt_private *priv)
428 {
429         int ret = 0;
430
431         /* CR12 */
432         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x00);
433         if (ret)
434                 return ret;
435
436         /* CR13 */
437         return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
438 }
439
440 int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
441 {
442         const struct vnt_threshold *threshold = NULL;
443         u8 length;
444         u8 cr_201, cr_206;
445         u8 ed_inx;
446         int ret;
447
448         switch (priv->rf_type) {
449         case RF_AL2230:
450         case RF_AL2230S:
451         case RF_AIROHA7230:
452                 threshold = al2230_vnt_threshold;
453                 length = ARRAY_SIZE(al2230_vnt_threshold);
454                 break;
455
456         case RF_VT3226:
457         case RF_VT3226D0:
458                 threshold = vt3226_vnt_threshold;
459                 length = ARRAY_SIZE(vt3226_vnt_threshold);
460                 break;
461
462         case RF_VT3342A0:
463                 threshold = vt3342_vnt_threshold;
464                 length = ARRAY_SIZE(vt3342_vnt_threshold);
465                 break;
466         }
467
468         if (!threshold)
469                 return -EINVAL;
470
471         for (ed_inx = scanning ? 0 : length - 1; ed_inx > 0; ed_inx--) {
472                 if (priv->bb_pre_ed_rssi <= threshold[ed_inx].bb_pre_ed_rssi)
473                         break;
474         }
475
476         cr_201 = threshold[ed_inx].cr_201;
477         cr_206 = threshold[ed_inx].cr_206;
478
479         if (ed_inx == priv->bb_pre_ed_index && !scanning)
480                 return 0;
481
482         priv->bb_pre_ed_index = ed_inx;
483
484         dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n",
485                 __func__, priv->bb_pre_ed_rssi);
486
487         ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201);
488         if (ret)
489                 return ret;
490
491         return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206);
492 }
493