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 /*
171  * Description: Set Antenna mode
172  *
173  * Parameters:
174  *  In:
175  *	priv		- Device Structure
176  *	antenna_mode	- Antenna Mode
177  *  Out:
178  *      none
179  *
180  * Return Value: none
181  *
182  */
vnt_set_antenna_mode(struct vnt_private * priv,u8 antenna_mode)183 int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode)
184 {
185 	switch (antenna_mode) {
186 	case ANT_TXA:
187 	case ANT_TXB:
188 		break;
189 	case ANT_RXA:
190 		priv->bb_rx_conf &= 0xFC;
191 		break;
192 	case ANT_RXB:
193 		priv->bb_rx_conf &= 0xFE;
194 		priv->bb_rx_conf |= 0x02;
195 		break;
196 	}
197 
198 	return vnt_control_out(priv, MESSAGE_TYPE_SET_ANTMD,
199 			       (u16)antenna_mode, 0, 0, NULL);
200 }
201 
202 /*
203  * Description: Set Antenna mode
204  *
205  * Parameters:
206  *  In:
207  *      pDevice          - Device Structure
208  *      byAntennaMode    - Antenna Mode
209  *  Out:
210  *      none
211  *
212  * Return Value: none
213  *
214  */
215 
vnt_vt3184_init(struct vnt_private * priv)216 int vnt_vt3184_init(struct vnt_private *priv)
217 {
218 	int ret;
219 	u16 length;
220 	u8 *addr = NULL;
221 	const u8 *c_addr;
222 	u8 data;
223 
224 	ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, MESSAGE_REQUEST_EEPROM,
225 			     EEP_MAX_CONTEXT_SIZE, priv->eeprom);
226 	if (ret)
227 		goto end;
228 
229 	priv->rf_type = priv->eeprom[EEP_OFS_RFTYPE];
230 
231 	dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
232 
233 	if ((priv->rf_type == RF_AL2230) ||
234 	    (priv->rf_type == RF_AL2230S)) {
235 		priv->bb_rx_conf = vnt_vt3184_al2230[10];
236 		length = sizeof(vnt_vt3184_al2230);
237 		addr = vnt_vt3184_al2230;
238 
239 		priv->bb_vga[0] = 0x1c;
240 		priv->bb_vga[1] = 0x10;
241 		priv->bb_vga[2] = 0x0;
242 		priv->bb_vga[3] = 0x0;
243 
244 	} else if ((priv->rf_type == RF_VT3226) ||
245 		   (priv->rf_type == RF_VT3226D0)) {
246 		priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
247 		length = sizeof(vnt_vt3184_vt3226d0);
248 		c_addr = vnt_vt3184_vt3226d0;
249 
250 		priv->bb_vga[0] = 0x20;
251 		priv->bb_vga[1] = 0x10;
252 		priv->bb_vga[2] = 0x0;
253 		priv->bb_vga[3] = 0x0;
254 
255 		/* Fix VT3226 DFC system timing issue */
256 		ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
257 					  SOFTPWRCTL_RFLEOPT);
258 		if (ret)
259 			goto end;
260 	} else {
261 		goto end;
262 	}
263 
264 	if (addr)
265 		c_addr = addr;
266 
267 	ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
268 				     MESSAGE_REQUEST_BBREG, length, c_addr);
269 	if (ret)
270 		goto end;
271 
272 	ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
273 			      MESSAGE_REQUEST_BBAGC,
274 			      sizeof(vnt_vt3184_agc), vnt_vt3184_agc);
275 	if (ret)
276 		goto end;
277 
278 	if ((priv->rf_type == RF_VT3226) ||
279 	    (priv->rf_type == RF_VT3226D0)) {
280 		data = (priv->rf_type == RF_VT3226D0) ? 0x11 : 0x23;
281 
282 		ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
283 					 MAC_REG_ITRTMSET, data);
284 		if (ret)
285 			goto end;
286 
287 		ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0));
288 		if (ret)
289 			goto end;
290 	}
291 
292 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f);
293 	if (ret)
294 		goto end;
295 
296 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
297 	if (ret)
298 		goto end;
299 
300 	ret = vnt_rf_table_download(priv);
301 	if (ret)
302 		goto end;
303 
304 	/* Fix for TX USB resets from vendors driver */
305 	ret = vnt_control_in(priv, MESSAGE_TYPE_READ, USB_REG4,
306 			     MESSAGE_REQUEST_MEM, sizeof(data), &data);
307 	if (ret)
308 		goto end;
309 
310 	data |= 0x2;
311 
312 	ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, USB_REG4,
313 			      MESSAGE_REQUEST_MEM, sizeof(data), &data);
314 
315 end:
316 	return ret;
317 }
318 
319 /*
320  * Description: Set ShortSlotTime mode
321  *
322  * Parameters:
323  *  In:
324  *	priv	- Device Structure
325  *  Out:
326  *      none
327  *
328  * Return Value: none
329  *
330  */
vnt_set_short_slot_time(struct vnt_private * priv)331 int vnt_set_short_slot_time(struct vnt_private *priv)
332 {
333 	int ret = 0;
334 	u8 bb_vga = 0;
335 
336 	if (priv->short_slot_time)
337 		priv->bb_rx_conf &= 0xdf;
338 	else
339 		priv->bb_rx_conf |= 0x20;
340 
341 	ret = vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga);
342 	if (ret)
343 		return ret;
344 
345 	if (bb_vga == priv->bb_vga[0])
346 		priv->bb_rx_conf |= 0x20;
347 
348 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
349 				  priv->bb_rx_conf);
350 }
351 
vnt_set_vga_gain_offset(struct vnt_private * priv,u8 data)352 int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data)
353 {
354 	int ret;
355 
356 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data);
357 	if (ret)
358 		return ret;
359 
360 	/* patch for 3253B0 Baseband with Cardbus module */
361 	if (priv->short_slot_time)
362 		priv->bb_rx_conf &= 0xdf; /* 1101 1111 */
363 	else
364 		priv->bb_rx_conf |= 0x20; /* 0010 0000 */
365 
366 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
367 				  priv->bb_rx_conf);
368 }
369 
370 /*
371  * Description: vnt_set_deep_sleep
372  *
373  * Parameters:
374  *  In:
375  *	priv	- Device Structure
376  *  Out:
377  *      none
378  *
379  * Return Value: none
380  *
381  */
vnt_set_deep_sleep(struct vnt_private * priv)382 int vnt_set_deep_sleep(struct vnt_private *priv)
383 {
384 	int ret = 0;
385 
386 	/* CR12 */
387 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);
388 	if (ret)
389 		return ret;
390 
391 	/* CR13 */
392 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0xB9);
393 }
394 
vnt_exit_deep_sleep(struct vnt_private * priv)395 int vnt_exit_deep_sleep(struct vnt_private *priv)
396 {
397 	int ret = 0;
398 
399 	/* CR12 */
400 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x00);
401 	if (ret)
402 		return ret;
403 
404 	/* CR13 */
405 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
406 }
407 
vnt_update_pre_ed_threshold(struct vnt_private * priv,int scanning)408 int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
409 {
410 	const struct vnt_threshold *threshold = NULL;
411 	u8 length;
412 	u8 cr_201, cr_206;
413 	u8 ed_inx;
414 	int ret;
415 
416 	switch (priv->rf_type) {
417 	case RF_AL2230:
418 	case RF_AL2230S:
419 		threshold = al2230_vnt_threshold;
420 		length = ARRAY_SIZE(al2230_vnt_threshold);
421 		break;
422 
423 	case RF_VT3226:
424 	case RF_VT3226D0:
425 		threshold = vt3226_vnt_threshold;
426 		length = ARRAY_SIZE(vt3226_vnt_threshold);
427 		break;
428 	}
429 
430 	if (!threshold)
431 		return -EINVAL;
432 
433 	for (ed_inx = scanning ? 0 : length - 1; ed_inx > 0; ed_inx--) {
434 		if (priv->bb_pre_ed_rssi <= threshold[ed_inx].bb_pre_ed_rssi)
435 			break;
436 	}
437 
438 	cr_201 = threshold[ed_inx].cr_201;
439 	cr_206 = threshold[ed_inx].cr_206;
440 
441 	if (ed_inx == priv->bb_pre_ed_index && !scanning)
442 		return 0;
443 
444 	priv->bb_pre_ed_index = ed_inx;
445 
446 	dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n",
447 		__func__, priv->bb_pre_ed_rssi);
448 
449 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201);
450 	if (ret)
451 		return ret;
452 
453 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206);
454 }
455 
456