1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2016 Realtek Corporation.
5 *
6 * Contact Information:
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9 * Hsinchu 300, Taiwan.
10 *
11 * Larry Finger <Larry.Finger@lwfinger.net>
12 *
13 *****************************************************************************/
14 #include "halmac_88xx_cfg.h"
15
16 /**
17 * halmac_init_usb_cfg_88xx() - init USB
18 * @halmac_adapter : the adapter of halmac
19 * Author : KaiYuan Chang/Ivan Lin
20 * Return : enum halmac_ret_status
21 * More details of status code can be found in prototype document
22 */
23 enum halmac_ret_status
halmac_init_usb_cfg_88xx(struct halmac_adapter * halmac_adapter)24 halmac_init_usb_cfg_88xx(struct halmac_adapter *halmac_adapter)
25 {
26 void *driver_adapter = NULL;
27 u8 value8 = 0;
28
29 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
30 return HALMAC_RET_ADAPTER_INVALID;
31
32 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
33 return HALMAC_RET_API_INVALID;
34
35 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_USB_CFG);
36
37 driver_adapter = halmac_adapter->driver_adapter;
38
39 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
40 "%s ==========>\n", __func__);
41
42 value8 |= (BIT_DMA_MODE |
43 (0x3 << BIT_SHIFT_BURST_CNT)); /* burst number = 4 */
44
45 if (PLATFORM_REG_READ_8(driver_adapter, REG_SYS_CFG2 + 3) ==
46 0x20) { /* usb3.0 */
47 value8 |= (HALMAC_USB_BURST_SIZE_3_0 << BIT_SHIFT_BURST_SIZE);
48 } else {
49 if ((PLATFORM_REG_READ_8(driver_adapter, REG_USB_USBSTAT) &
50 0x3) == 0x1) /* usb2.0 */
51 value8 |= HALMAC_USB_BURST_SIZE_2_0_HSPEED
52 << BIT_SHIFT_BURST_SIZE;
53 else /* usb1.1 */
54 value8 |= HALMAC_USB_BURST_SIZE_2_0_FSPEED
55 << BIT_SHIFT_BURST_SIZE;
56 }
57
58 PLATFORM_REG_WRITE_8(driver_adapter, REG_RXDMA_MODE, value8);
59 PLATFORM_REG_WRITE_16(
60 driver_adapter, REG_TXDMA_OFFSET_CHK,
61 PLATFORM_REG_READ_16(driver_adapter, REG_TXDMA_OFFSET_CHK) |
62 BIT_DROP_DATA_EN);
63
64 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
65 "%s <==========\n", __func__);
66
67 return HALMAC_RET_SUCCESS;
68 }
69
70 /**
71 * halmac_deinit_usb_cfg_88xx() - deinit USB
72 * @halmac_adapter : the adapter of halmac
73 * Author : KaiYuan Chang/Ivan Lin
74 * Return : enum halmac_ret_status
75 * More details of status code can be found in prototype document
76 */
77 enum halmac_ret_status
halmac_deinit_usb_cfg_88xx(struct halmac_adapter * halmac_adapter)78 halmac_deinit_usb_cfg_88xx(struct halmac_adapter *halmac_adapter)
79 {
80 void *driver_adapter = NULL;
81
82 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
83 return HALMAC_RET_ADAPTER_INVALID;
84
85 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
86 return HALMAC_RET_API_INVALID;
87
88 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEINIT_USB_CFG);
89
90 driver_adapter = halmac_adapter->driver_adapter;
91
92 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
93 "%s ==========>\n", __func__);
94
95 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
96 "%s <==========\n", __func__);
97
98 return HALMAC_RET_SUCCESS;
99 }
100
101 /**
102 * halmac_cfg_rx_aggregation_88xx_usb() - config rx aggregation
103 * @halmac_adapter : the adapter of halmac
104 * @halmac_rx_agg_mode
105 * Author : KaiYuan Chang/Ivan Lin
106 * Return : enum halmac_ret_status
107 * More details of status code can be found in prototype document
108 */
109 enum halmac_ret_status
halmac_cfg_rx_aggregation_88xx_usb(struct halmac_adapter * halmac_adapter,struct halmac_rxagg_cfg * phalmac_rxagg_cfg)110 halmac_cfg_rx_aggregation_88xx_usb(struct halmac_adapter *halmac_adapter,
111 struct halmac_rxagg_cfg *phalmac_rxagg_cfg)
112 {
113 u8 dma_usb_agg;
114 u8 size = 0, timeout = 0, agg_enable = 0;
115 void *driver_adapter = NULL;
116 struct halmac_api *halmac_api;
117
118 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
119 return HALMAC_RET_ADAPTER_INVALID;
120
121 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
122 return HALMAC_RET_API_INVALID;
123
124 halmac_api_record_id_88xx(halmac_adapter,
125 HALMAC_API_CFG_RX_AGGREGATION);
126
127 driver_adapter = halmac_adapter->driver_adapter;
128 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
129
130 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
131 "%s ==========>\n", __func__);
132
133 dma_usb_agg =
134 HALMAC_REG_READ_8(halmac_adapter, REG_RXDMA_AGG_PG_TH + 3);
135 agg_enable = HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP);
136
137 switch (phalmac_rxagg_cfg->mode) {
138 case HALMAC_RX_AGG_MODE_NONE:
139 agg_enable &= ~BIT_RXDMA_AGG_EN;
140 break;
141 case HALMAC_RX_AGG_MODE_DMA:
142 agg_enable |= BIT_RXDMA_AGG_EN;
143 dma_usb_agg |= BIT(7);
144 break;
145
146 case HALMAC_RX_AGG_MODE_USB:
147 agg_enable |= BIT_RXDMA_AGG_EN;
148 dma_usb_agg &= ~BIT(7);
149 break;
150 default:
151 pr_err("%s switch case not support\n", __func__);
152 agg_enable &= ~BIT_RXDMA_AGG_EN;
153 break;
154 }
155
156 if (!phalmac_rxagg_cfg->threshold.drv_define) {
157 if (PLATFORM_REG_READ_8(driver_adapter, REG_SYS_CFG2 + 3) ==
158 0x20) {
159 /* usb3.0 */
160 size = 0x5;
161 timeout = 0xA;
162 } else {
163 /* usb2.0 */
164 size = 0x5;
165 timeout = 0x20;
166 }
167 } else {
168 size = phalmac_rxagg_cfg->threshold.size;
169 timeout = phalmac_rxagg_cfg->threshold.timeout;
170 }
171
172 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP, agg_enable);
173 HALMAC_REG_WRITE_8(halmac_adapter, REG_RXDMA_AGG_PG_TH + 3,
174 dma_usb_agg);
175 HALMAC_REG_WRITE_16(halmac_adapter, REG_RXDMA_AGG_PG_TH,
176 (u16)(size | (timeout << BIT_SHIFT_DMA_AGG_TO)));
177
178 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
179 "%s <==========\n", __func__);
180
181 return HALMAC_RET_SUCCESS;
182 }
183
184 /**
185 * halmac_reg_read_8_usb_88xx() - read 1byte register
186 * @halmac_adapter : the adapter of halmac
187 * @halmac_offset : register offset
188 * Author : KaiYuan Chang/Ivan Lin
189 * Return : enum halmac_ret_status
190 * More details of status code can be found in prototype document
191 */
halmac_reg_read_8_usb_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset)192 u8 halmac_reg_read_8_usb_88xx(struct halmac_adapter *halmac_adapter,
193 u32 halmac_offset)
194 {
195 u8 value8;
196 void *driver_adapter = NULL;
197 struct halmac_api *halmac_api;
198
199 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
200 return HALMAC_RET_ADAPTER_INVALID;
201
202 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
203 return HALMAC_RET_API_INVALID;
204
205 driver_adapter = halmac_adapter->driver_adapter;
206 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
207
208 value8 = PLATFORM_REG_READ_8(driver_adapter, halmac_offset);
209
210 return value8;
211 }
212
213 /**
214 * halmac_reg_write_8_usb_88xx() - write 1byte register
215 * @halmac_adapter : the adapter of halmac
216 * @halmac_offset : register offset
217 * @halmac_data : register value
218 * Author : KaiYuan Chang/Ivan Lin
219 * Return : enum halmac_ret_status
220 * More details of status code can be found in prototype document
221 */
222 enum halmac_ret_status
halmac_reg_write_8_usb_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset,u8 halmac_data)223 halmac_reg_write_8_usb_88xx(struct halmac_adapter *halmac_adapter,
224 u32 halmac_offset, u8 halmac_data)
225 {
226 void *driver_adapter = NULL;
227 struct halmac_api *halmac_api;
228
229 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
230 return HALMAC_RET_ADAPTER_INVALID;
231
232 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
233 return HALMAC_RET_API_INVALID;
234
235 driver_adapter = halmac_adapter->driver_adapter;
236 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
237
238 PLATFORM_REG_WRITE_8(driver_adapter, halmac_offset, halmac_data);
239
240 return HALMAC_RET_SUCCESS;
241 }
242
243 /**
244 * halmac_reg_read_16_usb_88xx() - read 2byte register
245 * @halmac_adapter : the adapter of halmac
246 * @halmac_offset : register offset
247 * Author : KaiYuan Chang/Ivan Lin
248 * Return : enum halmac_ret_status
249 * More details of status code can be found in prototype document
250 */
halmac_reg_read_16_usb_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset)251 u16 halmac_reg_read_16_usb_88xx(struct halmac_adapter *halmac_adapter,
252 u32 halmac_offset)
253 {
254 void *driver_adapter = NULL;
255 struct halmac_api *halmac_api;
256
257 union {
258 u16 word;
259 u8 byte[2];
260 } value16 = {0x0000};
261
262 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
263 return HALMAC_RET_ADAPTER_INVALID;
264
265 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
266 return HALMAC_RET_API_INVALID;
267
268 driver_adapter = halmac_adapter->driver_adapter;
269 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
270
271 value16.word = PLATFORM_REG_READ_16(driver_adapter, halmac_offset);
272
273 return value16.word;
274 }
275
276 /**
277 * halmac_reg_write_16_usb_88xx() - write 2byte register
278 * @halmac_adapter : the adapter of halmac
279 * @halmac_offset : register offset
280 * @halmac_data : register value
281 * Author : KaiYuan Chang/Ivan Lin
282 * Return : enum halmac_ret_status
283 * More details of status code can be found in prototype document
284 */
285 enum halmac_ret_status
halmac_reg_write_16_usb_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset,u16 halmac_data)286 halmac_reg_write_16_usb_88xx(struct halmac_adapter *halmac_adapter,
287 u32 halmac_offset, u16 halmac_data)
288 {
289 void *driver_adapter = NULL;
290 struct halmac_api *halmac_api;
291
292 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
293 return HALMAC_RET_ADAPTER_INVALID;
294
295 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
296 return HALMAC_RET_API_INVALID;
297
298 driver_adapter = halmac_adapter->driver_adapter;
299 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
300
301 PLATFORM_REG_WRITE_16(driver_adapter, halmac_offset, halmac_data);
302
303 return HALMAC_RET_SUCCESS;
304 }
305
306 /**
307 * halmac_reg_read_32_usb_88xx() - read 4byte register
308 * @halmac_adapter : the adapter of halmac
309 * @halmac_offset : register offset
310 * Author : KaiYuan Chang/Ivan Lin
311 * Return : enum halmac_ret_status
312 * More details of status code can be found in prototype document
313 */
halmac_reg_read_32_usb_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset)314 u32 halmac_reg_read_32_usb_88xx(struct halmac_adapter *halmac_adapter,
315 u32 halmac_offset)
316 {
317 void *driver_adapter = NULL;
318 struct halmac_api *halmac_api;
319
320 union {
321 u32 dword;
322 u8 byte[4];
323 } value32 = {0x00000000};
324
325 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
326 return HALMAC_RET_ADAPTER_INVALID;
327
328 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
329 return HALMAC_RET_API_INVALID;
330
331 driver_adapter = halmac_adapter->driver_adapter;
332 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
333
334 value32.dword = PLATFORM_REG_READ_32(driver_adapter, halmac_offset);
335
336 return value32.dword;
337 }
338
339 /**
340 * halmac_reg_write_32_usb_88xx() - write 4byte register
341 * @halmac_adapter : the adapter of halmac
342 * @halmac_offset : register offset
343 * @halmac_data : register value
344 * Author : KaiYuan Chang/Ivan Lin
345 * Return : enum halmac_ret_status
346 * More details of status code can be found in prototype document
347 */
348 enum halmac_ret_status
halmac_reg_write_32_usb_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset,u32 halmac_data)349 halmac_reg_write_32_usb_88xx(struct halmac_adapter *halmac_adapter,
350 u32 halmac_offset, u32 halmac_data)
351 {
352 void *driver_adapter = NULL;
353 struct halmac_api *halmac_api;
354
355 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
356 return HALMAC_RET_ADAPTER_INVALID;
357
358 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
359 return HALMAC_RET_API_INVALID;
360
361 driver_adapter = halmac_adapter->driver_adapter;
362 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
363
364 PLATFORM_REG_WRITE_32(driver_adapter, halmac_offset, halmac_data);
365
366 return HALMAC_RET_SUCCESS;
367 }
368
369 /**
370 * halmac_set_bulkout_num_usb_88xx() - inform bulk-out num
371 * @halmac_adapter : the adapter of halmac
372 * @bulkout_num : usb bulk-out number
373 * Author : KaiYuan Chang
374 * Return : enum halmac_ret_status
375 * More details of status code can be found in prototype document
376 */
377 enum halmac_ret_status
halmac_set_bulkout_num_88xx(struct halmac_adapter * halmac_adapter,u8 bulkout_num)378 halmac_set_bulkout_num_88xx(struct halmac_adapter *halmac_adapter,
379 u8 bulkout_num)
380 {
381 void *driver_adapter = NULL;
382 struct halmac_api *halmac_api;
383
384 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
385 return HALMAC_RET_ADAPTER_INVALID;
386
387 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
388 return HALMAC_RET_API_INVALID;
389
390 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SET_BULKOUT_NUM);
391
392 driver_adapter = halmac_adapter->driver_adapter;
393 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
394
395 halmac_adapter->halmac_bulkout_num = bulkout_num;
396
397 return HALMAC_RET_SUCCESS;
398 }
399
400 /**
401 * halmac_get_usb_bulkout_id_usb_88xx() - get bulk out id for the TX packet
402 * @halmac_adapter : the adapter of halmac
403 * @halmac_buf : tx packet, include txdesc
404 * @halmac_size : tx packet size
405 * @bulkout_id : usb bulk-out id
406 * Author : KaiYuan Chang
407 * Return : enum halmac_ret_status
408 * More details of status code can be found in prototype document
409 */
410 enum halmac_ret_status
halmac_get_usb_bulkout_id_88xx(struct halmac_adapter * halmac_adapter,u8 * halmac_buf,u32 halmac_size,u8 * bulkout_id)411 halmac_get_usb_bulkout_id_88xx(struct halmac_adapter *halmac_adapter,
412 u8 *halmac_buf, u32 halmac_size, u8 *bulkout_id)
413 {
414 void *driver_adapter = NULL;
415 struct halmac_api *halmac_api;
416 enum halmac_queue_select queue_sel;
417 enum halmac_dma_mapping dma_mapping;
418
419 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
420 return HALMAC_RET_ADAPTER_INVALID;
421
422 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
423 return HALMAC_RET_API_INVALID;
424
425 halmac_api_record_id_88xx(halmac_adapter,
426 HALMAC_API_GET_USB_BULKOUT_ID);
427
428 driver_adapter = halmac_adapter->driver_adapter;
429 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
430
431 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
432 "%s ==========>\n", __func__);
433
434 if (!halmac_buf) {
435 pr_err("halmac_buf is NULL!!\n");
436 return HALMAC_RET_DATA_BUF_NULL;
437 }
438
439 if (halmac_size == 0) {
440 pr_err("halmac_size is 0!!\n");
441 return HALMAC_RET_DATA_SIZE_INCORRECT;
442 }
443
444 queue_sel = (enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf);
445
446 switch (queue_sel) {
447 case HALMAC_QUEUE_SELECT_VO:
448 case HALMAC_QUEUE_SELECT_VO_V2:
449 dma_mapping =
450 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
451 break;
452 case HALMAC_QUEUE_SELECT_VI:
453 case HALMAC_QUEUE_SELECT_VI_V2:
454 dma_mapping =
455 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
456 break;
457 case HALMAC_QUEUE_SELECT_BE:
458 case HALMAC_QUEUE_SELECT_BE_V2:
459 dma_mapping =
460 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
461 break;
462 case HALMAC_QUEUE_SELECT_BK:
463 case HALMAC_QUEUE_SELECT_BK_V2:
464 dma_mapping =
465 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
466 break;
467 case HALMAC_QUEUE_SELECT_MGNT:
468 dma_mapping =
469 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
470 break;
471 case HALMAC_QUEUE_SELECT_HIGH:
472 case HALMAC_QUEUE_SELECT_BCN:
473 case HALMAC_QUEUE_SELECT_CMD:
474 dma_mapping = HALMAC_DMA_MAPPING_HIGH;
475 break;
476 default:
477 pr_err("Qsel is out of range\n");
478 return HALMAC_RET_QSEL_INCORRECT;
479 }
480
481 switch (dma_mapping) {
482 case HALMAC_DMA_MAPPING_HIGH:
483 *bulkout_id = 0;
484 break;
485 case HALMAC_DMA_MAPPING_NORMAL:
486 *bulkout_id = 1;
487 break;
488 case HALMAC_DMA_MAPPING_LOW:
489 *bulkout_id = 2;
490 break;
491 case HALMAC_DMA_MAPPING_EXTRA:
492 *bulkout_id = 3;
493 break;
494 default:
495 pr_err("DmaMapping is out of range\n");
496 return HALMAC_RET_DMA_MAP_INCORRECT;
497 }
498
499 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
500 "%s <==========\n", __func__);
501
502 return HALMAC_RET_SUCCESS;
503 }
504
505 /**
506 * halmac_cfg_tx_agg_align_usb_88xx() -config sdio bus tx agg alignment
507 * @halmac_adapter : the adapter of halmac
508 * @enable : function enable(1)/disable(0)
509 * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
510 * Author : Soar Tu
511 * Return : enum halmac_ret_status
512 * More details of status code can be found in prototype document
513 */
halmac_cfg_tx_agg_align_usb_not_support_88xx(struct halmac_adapter * halmac_adapter,u8 enable,u16 align_size)514 enum halmac_ret_status halmac_cfg_tx_agg_align_usb_not_support_88xx(
515 struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size)
516 {
517 struct halmac_api *halmac_api;
518 void *driver_adapter = NULL;
519
520 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
521 return HALMAC_RET_ADAPTER_INVALID;
522
523 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
524 return HALMAC_RET_API_INVALID;
525
526 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
527
528 driver_adapter = halmac_adapter->driver_adapter;
529 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
530
531 HALMAC_RT_TRACE(
532 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
533 "%s ==========>\n", __func__);
534
535 HALMAC_RT_TRACE(
536 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
537 "%s not support\n", __func__);
538 HALMAC_RT_TRACE(
539 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
540 "%s <==========\n", __func__);
541
542 return HALMAC_RET_SUCCESS;
543 }
544