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