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/kernel.h>
27 #include "mac.h"
28 #include "baseband.h"
29 #include "rf.h"
30 #include "usbpipe.h"
31 
32 static 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 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 static const u16 vnt_frame_time[MAX_RATE] = {
115 	10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216
116 };
117 
118 /*
119  * Description: Calculate data frame transmitting time
120  *
121  * Parameters:
122  *  In:
123  *	preamble_type	- Preamble Type
124  *	pkt_type	- PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA
125  *	frame_length	- Baseband Type
126  *	tx_rate		- Tx Rate
127  *  Out:
128  *
129  * Return Value: FrameTime
130  *
131  */
132 unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type,
133 				unsigned int frame_length, u16 tx_rate)
134 {
135 	unsigned int frame_time;
136 	unsigned int preamble;
137 	unsigned int rate = 0;
138 
139 	if (tx_rate > RATE_54M)
140 		return 0;
141 
142 	rate = (unsigned int)vnt_frame_time[tx_rate];
143 
144 	if (tx_rate <= 3) {
145 		if (preamble_type == 1)
146 			preamble = 96;
147 		else
148 			preamble = 192;
149 
150 		frame_time = DIV_ROUND_UP(frame_length * 80, rate);
151 		return preamble + frame_time;
152 	}
153 
154 	frame_time = DIV_ROUND_UP(frame_length * 8 + 22, rate);
155 	frame_time = frame_time * 4;
156 
157 	if (pkt_type != PK_TYPE_11A)
158 		frame_time += 6;
159 	return 20 + frame_time;
160 }
161 
162 /*
163  * Description: Calculate Length, Service, and Signal fields of Phy for Tx
164  *
165  * Parameters:
166  *  In:
167  *      priv         - Device Structure
168  *      frame_length   - Tx Frame Length
169  *      tx_rate           - Tx Rate
170  *  Out:
171  *	struct vnt_phy_field *phy
172  *		- pointer to Phy Length field
173  *		- pointer to Phy Service field
174  *		- pointer to Phy Signal field
175  *
176  * Return Value: none
177  *
178  */
179 void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
180 		       u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy)
181 {
182 	u32 bit_count;
183 	u32 count = 0;
184 	u32 tmp;
185 	int ext_bit;
186 	u8 preamble_type = priv->preamble_type;
187 
188 	bit_count = frame_length * 8;
189 	ext_bit = false;
190 
191 	switch (tx_rate) {
192 	case RATE_1M:
193 		count = bit_count;
194 
195 		phy->signal = 0x00;
196 
197 		break;
198 	case RATE_2M:
199 		count = bit_count / 2;
200 
201 		if (preamble_type == 1)
202 			phy->signal = 0x09;
203 		else
204 			phy->signal = 0x01;
205 
206 		break;
207 	case RATE_5M:
208 		count = DIV_ROUND_UP(bit_count * 10, 55);
209 
210 		if (preamble_type == 1)
211 			phy->signal = 0x0a;
212 		else
213 			phy->signal = 0x02;
214 
215 		break;
216 	case RATE_11M:
217 		count = bit_count / 11;
218 		tmp = count * 11;
219 
220 		if (tmp != bit_count) {
221 			count++;
222 
223 			if ((bit_count - tmp) <= 3)
224 				ext_bit = true;
225 		}
226 
227 		if (preamble_type == 1)
228 			phy->signal = 0x0b;
229 		else
230 			phy->signal = 0x03;
231 
232 		break;
233 	case RATE_6M:
234 		if (pkt_type == PK_TYPE_11A)
235 			phy->signal = 0x9b;
236 		else
237 			phy->signal = 0x8b;
238 
239 		break;
240 	case RATE_9M:
241 		if (pkt_type == PK_TYPE_11A)
242 			phy->signal = 0x9f;
243 		else
244 			phy->signal = 0x8f;
245 
246 		break;
247 	case RATE_12M:
248 		if (pkt_type == PK_TYPE_11A)
249 			phy->signal = 0x9a;
250 		else
251 			phy->signal = 0x8a;
252 
253 		break;
254 	case RATE_18M:
255 		if (pkt_type == PK_TYPE_11A)
256 			phy->signal = 0x9e;
257 		else
258 			phy->signal = 0x8e;
259 
260 		break;
261 	case RATE_24M:
262 		if (pkt_type == PK_TYPE_11A)
263 			phy->signal = 0x99;
264 		else
265 			phy->signal = 0x89;
266 
267 		break;
268 	case RATE_36M:
269 		if (pkt_type == PK_TYPE_11A)
270 			phy->signal = 0x9d;
271 		else
272 			phy->signal = 0x8d;
273 
274 		break;
275 	case RATE_48M:
276 		if (pkt_type == PK_TYPE_11A)
277 			phy->signal = 0x98;
278 		else
279 			phy->signal = 0x88;
280 
281 		break;
282 	case RATE_54M:
283 		if (pkt_type == PK_TYPE_11A)
284 			phy->signal = 0x9c;
285 		else
286 			phy->signal = 0x8c;
287 		break;
288 	default:
289 		if (pkt_type == PK_TYPE_11A)
290 			phy->signal = 0x9c;
291 		else
292 			phy->signal = 0x8c;
293 		break;
294 	}
295 
296 	if (pkt_type == PK_TYPE_11B) {
297 		phy->service = 0x00;
298 		if (ext_bit)
299 			phy->service |= 0x80;
300 		phy->len = cpu_to_le16((u16)count);
301 	} else {
302 		phy->service = 0x00;
303 		phy->len = cpu_to_le16((u16)frame_length);
304 	}
305 }
306 
307 /*
308  * Description: Set Antenna mode
309  *
310  * Parameters:
311  *  In:
312  *	priv		- Device Structure
313  *	antenna_mode	- Antenna Mode
314  *  Out:
315  *      none
316  *
317  * Return Value: none
318  *
319  */
320 int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode)
321 {
322 	switch (antenna_mode) {
323 	case ANT_TXA:
324 	case ANT_TXB:
325 		break;
326 	case ANT_RXA:
327 		priv->bb_rx_conf &= 0xFC;
328 		break;
329 	case ANT_RXB:
330 		priv->bb_rx_conf &= 0xFE;
331 		priv->bb_rx_conf |= 0x02;
332 		break;
333 	}
334 
335 	return vnt_control_out(priv, MESSAGE_TYPE_SET_ANTMD,
336 			       (u16)antenna_mode, 0, 0, NULL);
337 }
338 
339 /*
340  * Description: Set Antenna mode
341  *
342  * Parameters:
343  *  In:
344  *      pDevice          - Device Structure
345  *      byAntennaMode    - Antenna Mode
346  *  Out:
347  *      none
348  *
349  * Return Value: none
350  *
351  */
352 
353 int vnt_vt3184_init(struct vnt_private *priv)
354 {
355 	int ret = 0;
356 	u16 length;
357 	u8 *addr;
358 	u8 data;
359 
360 	ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, MESSAGE_REQUEST_EEPROM,
361 			     EEP_MAX_CONTEXT_SIZE, priv->eeprom);
362 	if (ret)
363 		goto end;
364 
365 	priv->rf_type = priv->eeprom[EEP_OFS_RFTYPE];
366 
367 	dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
368 
369 	if (priv->rf_type == RF_AL2230 ||
370 	    priv->rf_type == RF_AL2230S) {
371 		priv->bb_rx_conf = vnt_vt3184_al2230[10];
372 		length = sizeof(vnt_vt3184_al2230);
373 		addr = vnt_vt3184_al2230;
374 
375 		priv->bb_vga[0] = 0x1C;
376 		priv->bb_vga[1] = 0x10;
377 		priv->bb_vga[2] = 0x0;
378 		priv->bb_vga[3] = 0x0;
379 
380 	} else if (priv->rf_type == RF_AIROHA7230) {
381 		priv->bb_rx_conf = vnt_vt3184_al2230[10];
382 		length = sizeof(vnt_vt3184_al2230);
383 		addr = vnt_vt3184_al2230;
384 
385 		addr[0xd7] = 0x06;
386 
387 		priv->bb_vga[0] = 0x1c;
388 		priv->bb_vga[1] = 0x10;
389 		priv->bb_vga[2] = 0x0;
390 		priv->bb_vga[3] = 0x0;
391 
392 	} else if ((priv->rf_type == RF_VT3226) ||
393 			(priv->rf_type == RF_VT3226D0)) {
394 		priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
395 		length = sizeof(vnt_vt3184_vt3226d0);
396 		addr = vnt_vt3184_vt3226d0;
397 
398 		priv->bb_vga[0] = 0x20;
399 		priv->bb_vga[1] = 0x10;
400 		priv->bb_vga[2] = 0x0;
401 		priv->bb_vga[3] = 0x0;
402 
403 		/* Fix VT3226 DFC system timing issue */
404 		ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
405 					  SOFTPWRCTL_RFLEOPT);
406 		if (ret)
407 			goto end;
408 	} else if (priv->rf_type == RF_VT3342A0) {
409 		priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
410 		length = sizeof(vnt_vt3184_vt3226d0);
411 		addr = vnt_vt3184_vt3226d0;
412 
413 		priv->bb_vga[0] = 0x20;
414 		priv->bb_vga[1] = 0x10;
415 		priv->bb_vga[2] = 0x0;
416 		priv->bb_vga[3] = 0x0;
417 
418 		/* Fix VT3226 DFC system timing issue */
419 		ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
420 					  SOFTPWRCTL_RFLEOPT);
421 		if (ret)
422 			goto end;
423 	} else {
424 		goto end;
425 	}
426 
427 	ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
428 				     MESSAGE_REQUEST_BBREG, length, addr);
429 	if (ret)
430 		goto end;
431 
432 	ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
433 			      MESSAGE_REQUEST_BBAGC,
434 			      sizeof(vnt_vt3184_agc), vnt_vt3184_agc);
435 	if (ret)
436 		goto end;
437 
438 	if (priv->rf_type == RF_VT3226 ||
439 	    priv->rf_type == RF_VT3342A0) {
440 		ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
441 					 MAC_REG_ITRTMSET, 0x23);
442 		if (ret)
443 			goto end;
444 
445 		ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0));
446 		if (ret)
447 			goto end;
448 	} else if (priv->rf_type == RF_VT3226D0) {
449 		ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
450 					 MAC_REG_ITRTMSET, 0x11);
451 		if (ret)
452 			goto end;
453 
454 		ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0));
455 		if (ret)
456 			goto end;
457 	}
458 
459 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f);
460 	if (ret)
461 		goto end;
462 
463 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
464 	if (ret)
465 		goto end;
466 
467 	ret = vnt_rf_table_download(priv);
468 	if (ret)
469 		goto end;
470 
471 	/* Fix for TX USB resets from vendors driver */
472 	ret = vnt_control_in(priv, MESSAGE_TYPE_READ, USB_REG4,
473 			     MESSAGE_REQUEST_MEM, sizeof(data), &data);
474 	if (ret)
475 		goto end;
476 
477 	data |= 0x2;
478 
479 	ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, USB_REG4,
480 			      MESSAGE_REQUEST_MEM, sizeof(data), &data);
481 
482 end:
483 	return ret;
484 }
485 
486 /*
487  * Description: Set ShortSlotTime mode
488  *
489  * Parameters:
490  *  In:
491  *	priv	- Device Structure
492  *  Out:
493  *      none
494  *
495  * Return Value: none
496  *
497  */
498 int vnt_set_short_slot_time(struct vnt_private *priv)
499 {
500 	int ret = 0;
501 	u8 bb_vga = 0;
502 
503 	if (priv->short_slot_time)
504 		priv->bb_rx_conf &= 0xdf;
505 	else
506 		priv->bb_rx_conf |= 0x20;
507 
508 	ret = vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga);
509 	if (ret)
510 		goto end;
511 
512 	if (bb_vga == priv->bb_vga[0])
513 		priv->bb_rx_conf |= 0x20;
514 
515 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
516 				 priv->bb_rx_conf);
517 
518 end:
519 	return ret;
520 }
521 
522 void vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data)
523 {
524 	vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data);
525 
526 	/* patch for 3253B0 Baseband with Cardbus module */
527 	if (priv->short_slot_time)
528 		priv->bb_rx_conf &= 0xdf; /* 1101 1111 */
529 	else
530 		priv->bb_rx_conf |= 0x20; /* 0010 0000 */
531 
532 	vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, priv->bb_rx_conf);
533 }
534 
535 /*
536  * Description: vnt_set_deep_sleep
537  *
538  * Parameters:
539  *  In:
540  *	priv	- Device Structure
541  *  Out:
542  *      none
543  *
544  * Return Value: none
545  *
546  */
547 int vnt_set_deep_sleep(struct vnt_private *priv)
548 {
549 	int ret = 0;
550 
551 	/* CR12 */
552 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);
553 	if (ret)
554 		return ret;
555 
556 	/* CR13 */
557 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0xB9);
558 }
559 
560 int vnt_exit_deep_sleep(struct vnt_private *priv)
561 {
562 	int ret = 0;
563 
564 	/* CR12 */
565 	ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x00);
566 	if (ret)
567 		return ret;
568 
569 	/* CR13 */
570 	return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
571 }
572 
573 void vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
574 {
575 	u8 cr_201 = 0x0, cr_206 = 0x0;
576 	u8 ed_inx = priv->bb_pre_ed_index;
577 
578 	switch (priv->rf_type) {
579 	case RF_AL2230:
580 	case RF_AL2230S:
581 	case RF_AIROHA7230:
582 		if (scanning) { /* Max sensitivity */
583 			ed_inx = 0;
584 			cr_206 = 0x30;
585 			break;
586 		}
587 
588 		if (priv->bb_pre_ed_rssi <= 45) {
589 			ed_inx = 20;
590 			cr_201 = 0xff;
591 		} else if (priv->bb_pre_ed_rssi <= 46) {
592 			ed_inx = 19;
593 			cr_201 = 0x1a;
594 		} else if (priv->bb_pre_ed_rssi <= 47) {
595 			ed_inx = 18;
596 			cr_201 = 0x15;
597 		} else if (priv->bb_pre_ed_rssi <= 49) {
598 			ed_inx = 17;
599 			cr_201 = 0xe;
600 		} else if (priv->bb_pre_ed_rssi <= 51) {
601 			ed_inx = 16;
602 			cr_201 = 0x9;
603 		} else if (priv->bb_pre_ed_rssi <= 53) {
604 			ed_inx = 15;
605 			cr_201 = 0x6;
606 		} else if (priv->bb_pre_ed_rssi <= 55) {
607 			ed_inx = 14;
608 			cr_201 = 0x3;
609 		} else if (priv->bb_pre_ed_rssi <= 56) {
610 			ed_inx = 13;
611 			cr_201 = 0x2;
612 			cr_206 = 0xa0;
613 		} else if (priv->bb_pre_ed_rssi <= 57) {
614 			ed_inx = 12;
615 			cr_201 = 0x2;
616 			cr_206 = 0x20;
617 		} else if (priv->bb_pre_ed_rssi <= 58) {
618 			ed_inx = 11;
619 			cr_201 = 0x1;
620 			cr_206 = 0xa0;
621 		} else if (priv->bb_pre_ed_rssi <= 59) {
622 			ed_inx = 10;
623 			cr_201 = 0x1;
624 			cr_206 = 0x54;
625 		} else if (priv->bb_pre_ed_rssi <= 60) {
626 			ed_inx = 9;
627 			cr_201 = 0x1;
628 			cr_206 = 0x18;
629 		} else if (priv->bb_pre_ed_rssi <= 61) {
630 			ed_inx = 8;
631 			cr_206 = 0xe3;
632 		} else if (priv->bb_pre_ed_rssi <= 62) {
633 			ed_inx = 7;
634 			cr_206 = 0xb9;
635 		} else if (priv->bb_pre_ed_rssi <= 63) {
636 			ed_inx = 6;
637 			cr_206 = 0x93;
638 		} else if (priv->bb_pre_ed_rssi <= 64) {
639 			ed_inx = 5;
640 			cr_206 = 0x79;
641 		} else if (priv->bb_pre_ed_rssi <= 65) {
642 			ed_inx = 4;
643 			cr_206 = 0x62;
644 		} else if (priv->bb_pre_ed_rssi <= 66) {
645 			ed_inx = 3;
646 			cr_206 = 0x51;
647 		} else if (priv->bb_pre_ed_rssi <= 67) {
648 			ed_inx = 2;
649 			cr_206 = 0x43;
650 		} else if (priv->bb_pre_ed_rssi <= 68) {
651 			ed_inx = 1;
652 			cr_206 = 0x36;
653 		} else {
654 			ed_inx = 0;
655 			cr_206 = 0x30;
656 		}
657 		break;
658 
659 	case RF_VT3226:
660 	case RF_VT3226D0:
661 		if (scanning)	{ /* Max sensitivity */
662 			ed_inx = 0;
663 			cr_206 = 0x24;
664 			break;
665 		}
666 
667 		if (priv->bb_pre_ed_rssi <= 41) {
668 			ed_inx = 22;
669 			cr_201 = 0xff;
670 		} else if (priv->bb_pre_ed_rssi <= 42) {
671 			ed_inx = 21;
672 			cr_201 = 0x36;
673 		} else if (priv->bb_pre_ed_rssi <= 43) {
674 			ed_inx = 20;
675 			cr_201 = 0x26;
676 		} else if (priv->bb_pre_ed_rssi <= 45) {
677 			ed_inx = 19;
678 			cr_201 = 0x18;
679 		} else if (priv->bb_pre_ed_rssi <= 47) {
680 			ed_inx = 18;
681 			cr_201 = 0x11;
682 		} else if (priv->bb_pre_ed_rssi <= 49) {
683 			ed_inx = 17;
684 			cr_201 = 0xa;
685 		} else if (priv->bb_pre_ed_rssi <= 51) {
686 			ed_inx = 16;
687 			cr_201 = 0x7;
688 		} else if (priv->bb_pre_ed_rssi <= 53) {
689 			ed_inx = 15;
690 			cr_201 = 0x4;
691 		} else if (priv->bb_pre_ed_rssi <= 55) {
692 			ed_inx = 14;
693 			cr_201 = 0x2;
694 			cr_206 = 0xc0;
695 		} else if (priv->bb_pre_ed_rssi <= 56) {
696 			ed_inx = 13;
697 			cr_201 = 0x2;
698 			cr_206 = 0x30;
699 		} else if (priv->bb_pre_ed_rssi <= 57) {
700 			ed_inx = 12;
701 			cr_201 = 0x1;
702 			cr_206 = 0xb0;
703 		} else if (priv->bb_pre_ed_rssi <= 58) {
704 			ed_inx = 11;
705 			cr_201 = 0x1;
706 			cr_206 = 0x70;
707 		} else if (priv->bb_pre_ed_rssi <= 59) {
708 			ed_inx = 10;
709 			cr_201 = 0x1;
710 			cr_206 = 0x30;
711 		} else if (priv->bb_pre_ed_rssi <= 60) {
712 			ed_inx = 9;
713 			cr_206 = 0xea;
714 		} else if (priv->bb_pre_ed_rssi <= 61) {
715 			ed_inx = 8;
716 			cr_206 = 0xc0;
717 		} else if (priv->bb_pre_ed_rssi <= 62) {
718 			ed_inx = 7;
719 			cr_206 = 0x9c;
720 		} else if (priv->bb_pre_ed_rssi <= 63) {
721 			ed_inx = 6;
722 			cr_206 = 0x80;
723 		} else if (priv->bb_pre_ed_rssi <= 64) {
724 			ed_inx = 5;
725 			cr_206 = 0x68;
726 		} else if (priv->bb_pre_ed_rssi <= 65) {
727 			ed_inx = 4;
728 			cr_206 = 0x52;
729 		} else if (priv->bb_pre_ed_rssi <= 66) {
730 			ed_inx = 3;
731 			cr_206 = 0x43;
732 		} else if (priv->bb_pre_ed_rssi <= 67) {
733 			ed_inx = 2;
734 			cr_206 = 0x36;
735 		} else if (priv->bb_pre_ed_rssi <= 68) {
736 			ed_inx = 1;
737 			cr_206 = 0x2d;
738 		} else {
739 			ed_inx = 0;
740 			cr_206 = 0x24;
741 		}
742 		break;
743 
744 	case RF_VT3342A0:
745 		if (scanning) { /* need Max sensitivity */
746 			ed_inx = 0;
747 			cr_206 = 0x38;
748 			break;
749 		}
750 
751 		if (priv->bb_pre_ed_rssi <= 41) {
752 			ed_inx = 20;
753 			cr_201 = 0xff;
754 		} else if (priv->bb_pre_ed_rssi <= 42) {
755 			ed_inx = 19;
756 			cr_201 = 0x36;
757 		} else if (priv->bb_pre_ed_rssi <= 43) {
758 			ed_inx = 18;
759 			cr_201 = 0x26;
760 		} else if (priv->bb_pre_ed_rssi <= 45) {
761 			ed_inx = 17;
762 			cr_201 = 0x18;
763 		} else if (priv->bb_pre_ed_rssi <= 47) {
764 			ed_inx = 16;
765 			cr_201 = 0x11;
766 		} else if (priv->bb_pre_ed_rssi <= 49) {
767 			ed_inx = 15;
768 			cr_201 = 0xa;
769 		} else if (priv->bb_pre_ed_rssi <= 51) {
770 			ed_inx = 14;
771 			cr_201 = 0x7;
772 		} else if (priv->bb_pre_ed_rssi <= 53) {
773 			ed_inx = 13;
774 			cr_201 = 0x4;
775 		} else if (priv->bb_pre_ed_rssi <= 55) {
776 			ed_inx = 12;
777 			cr_201 = 0x2;
778 			cr_206 = 0xc0;
779 		} else if (priv->bb_pre_ed_rssi <= 56) {
780 			ed_inx = 11;
781 			cr_201 = 0x2;
782 			cr_206 = 0x30;
783 		} else if (priv->bb_pre_ed_rssi <= 57) {
784 			ed_inx = 10;
785 			cr_201 = 0x1;
786 			cr_206 = 0xb0;
787 		} else if (priv->bb_pre_ed_rssi <= 58) {
788 			ed_inx = 9;
789 			cr_201 = 0x1;
790 			cr_206 = 0x70;
791 		} else if (priv->bb_pre_ed_rssi <= 59) {
792 			ed_inx = 8;
793 			cr_201 = 0x1;
794 			cr_206 = 0x30;
795 		} else if (priv->bb_pre_ed_rssi <= 60) {
796 			ed_inx = 7;
797 			cr_206 = 0xea;
798 		} else if (priv->bb_pre_ed_rssi <= 61) {
799 			ed_inx = 6;
800 			cr_206 = 0xc0;
801 		} else if (priv->bb_pre_ed_rssi <= 62) {
802 			ed_inx = 5;
803 			cr_206 = 0x9c;
804 		} else if (priv->bb_pre_ed_rssi <= 63) {
805 			ed_inx = 4;
806 			cr_206 = 0x80;
807 		} else if (priv->bb_pre_ed_rssi <= 64) {
808 			ed_inx = 3;
809 			cr_206 = 0x68;
810 		} else if (priv->bb_pre_ed_rssi <= 65) {
811 			ed_inx = 2;
812 			cr_206 = 0x52;
813 		} else if (priv->bb_pre_ed_rssi <= 66) {
814 			ed_inx = 1;
815 			cr_206 = 0x43;
816 		} else {
817 			ed_inx = 0;
818 			cr_206 = 0x38;
819 		}
820 		break;
821 	}
822 
823 	if (ed_inx == priv->bb_pre_ed_index && !scanning)
824 		return;
825 
826 	priv->bb_pre_ed_index = ed_inx;
827 
828 	dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n",
829 		__func__, priv->bb_pre_ed_rssi);
830 
831 	if (!cr_201 && !cr_206)
832 		return;
833 
834 	vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201);
835 	vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206);
836 }
837 
838