1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
14 #include "halmac_88xx_cfg.h"
17 * halmac_init_sdio_cfg_88xx() - init SDIO
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
23 enum halmac_ret_status
24 halmac_init_sdio_cfg_88xx(struct halmac_adapter *halmac_adapter)
26 void *driver_adapter = NULL;
27 struct halmac_api *halmac_api;
29 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
30 return HALMAC_RET_ADAPTER_INVALID;
32 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
33 return HALMAC_RET_API_INVALID;
35 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SDIO_CFG);
37 driver_adapter = halmac_adapter->driver_adapter;
38 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
40 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
41 "%s ==========>\n", __func__);
43 HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
44 HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL, 0x00000000);
46 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
47 "%s <==========\n", __func__);
49 return HALMAC_RET_SUCCESS;
53 * halmac_deinit_sdio_cfg_88xx() - deinit SDIO
54 * @halmac_adapter : the adapter of halmac
55 * Author : KaiYuan Chang/Ivan Lin
56 * Return : enum halmac_ret_status
57 * More details of status code can be found in prototype document
59 enum halmac_ret_status
60 halmac_deinit_sdio_cfg_88xx(struct halmac_adapter *halmac_adapter)
62 void *driver_adapter = NULL;
64 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
65 return HALMAC_RET_ADAPTER_INVALID;
67 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
68 return HALMAC_RET_API_INVALID;
70 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEINIT_SDIO_CFG);
72 driver_adapter = halmac_adapter->driver_adapter;
74 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
75 "%s ==========>\n", __func__);
77 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
78 "%s <==========\n", __func__);
80 return HALMAC_RET_SUCCESS;
84 * halmac_cfg_rx_aggregation_88xx_sdio() - config rx aggregation
85 * @halmac_adapter : the adapter of halmac
87 * Author : KaiYuan Chang/Ivan Lin
88 * Return : enum halmac_ret_status
89 * More details of status code can be found in prototype document
91 enum halmac_ret_status
92 halmac_cfg_rx_aggregation_88xx_sdio(struct halmac_adapter *halmac_adapter,
93 struct halmac_rxagg_cfg *phalmac_rxagg_cfg)
96 u8 size = 0, timeout = 0, agg_enable = 0;
97 void *driver_adapter = NULL;
98 struct halmac_api *halmac_api;
100 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
101 return HALMAC_RET_ADAPTER_INVALID;
103 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
104 return HALMAC_RET_API_INVALID;
106 halmac_api_record_id_88xx(halmac_adapter,
107 HALMAC_API_CFG_RX_AGGREGATION);
109 driver_adapter = halmac_adapter->driver_adapter;
110 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
112 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
113 "%s ==========>\n", __func__);
115 agg_enable = HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP);
117 switch (phalmac_rxagg_cfg->mode) {
118 case HALMAC_RX_AGG_MODE_NONE:
119 agg_enable &= ~(BIT_RXDMA_AGG_EN);
121 case HALMAC_RX_AGG_MODE_DMA:
122 case HALMAC_RX_AGG_MODE_USB:
123 agg_enable |= BIT_RXDMA_AGG_EN;
126 pr_err("halmac_cfg_rx_aggregation_88xx_usb switch case not support\n");
127 agg_enable &= ~BIT_RXDMA_AGG_EN;
131 if (!phalmac_rxagg_cfg->threshold.drv_define) {
135 size = phalmac_rxagg_cfg->threshold.size;
136 timeout = phalmac_rxagg_cfg->threshold.timeout;
139 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP, agg_enable);
140 HALMAC_REG_WRITE_16(halmac_adapter, REG_RXDMA_AGG_PG_TH,
141 (u16)(size | (timeout << BIT_SHIFT_DMA_AGG_TO)));
143 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RXDMA_MODE);
144 if ((agg_enable & BIT_RXDMA_AGG_EN) != 0)
145 HALMAC_REG_WRITE_8(halmac_adapter, REG_RXDMA_MODE,
146 value8 | BIT_DMA_MODE);
148 HALMAC_REG_WRITE_8(halmac_adapter, REG_RXDMA_MODE,
149 value8 & ~(BIT_DMA_MODE));
151 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
152 "%s <==========\n", __func__);
154 return HALMAC_RET_SUCCESS;
158 * halmac_reg_read_8_sdio_88xx() - read 1byte register
159 * @halmac_adapter : the adapter of halmac
160 * @halmac_offset : register offset
161 * Author : KaiYuan Chang/Ivan Lin
162 * Return : enum halmac_ret_status
163 * More details of status code can be found in prototype document
165 u8 halmac_reg_read_8_sdio_88xx(struct halmac_adapter *halmac_adapter,
169 void *driver_adapter = NULL;
170 struct halmac_api *halmac_api;
171 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
173 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
174 return HALMAC_RET_ADAPTER_INVALID;
176 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
177 return HALMAC_RET_API_INVALID;
179 driver_adapter = halmac_adapter->driver_adapter;
180 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
182 if ((halmac_offset & 0xFFFF0000) == 0)
183 halmac_offset |= WLAN_IOREG_OFFSET;
185 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
188 if (status != HALMAC_RET_SUCCESS) {
189 pr_err("%s error = %x\n", __func__, status);
193 value8 = PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
199 * halmac_reg_write_8_sdio_88xx() - write 1byte register
200 * @halmac_adapter : the adapter of halmac
201 * @halmac_offset : register offset
202 * @halmac_data : register value
203 * Author : KaiYuan Chang/Ivan Lin
204 * Return : enum halmac_ret_status
205 * More details of status code can be found in prototype document
207 enum halmac_ret_status
208 halmac_reg_write_8_sdio_88xx(struct halmac_adapter *halmac_adapter,
209 u32 halmac_offset, u8 halmac_data)
211 void *driver_adapter = NULL;
212 struct halmac_api *halmac_api;
213 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
215 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
216 return HALMAC_RET_ADAPTER_INVALID;
218 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
219 return HALMAC_RET_API_INVALID;
221 driver_adapter = halmac_adapter->driver_adapter;
222 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
224 if ((halmac_offset & 0xFFFF0000) == 0)
225 halmac_offset |= WLAN_IOREG_OFFSET;
227 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
230 if (status != HALMAC_RET_SUCCESS) {
231 pr_err("%s error = %x\n", __func__, status);
235 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, halmac_data);
237 return HALMAC_RET_SUCCESS;
241 * halmac_reg_read_16_sdio_88xx() - read 2byte register
242 * @halmac_adapter : the adapter of halmac
243 * @halmac_offset : register offset
244 * Author : KaiYuan Chang/Ivan Lin
245 * Return : enum halmac_ret_status
246 * More details of status code can be found in prototype document
248 u16 halmac_reg_read_16_sdio_88xx(struct halmac_adapter *halmac_adapter,
251 void *driver_adapter = NULL;
252 struct halmac_api *halmac_api;
253 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
259 } value16 = {0x0000};
261 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
262 return HALMAC_RET_ADAPTER_INVALID;
264 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
265 return HALMAC_RET_API_INVALID;
267 driver_adapter = halmac_adapter->driver_adapter;
268 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
270 if ((halmac_offset & 0xFFFF0000) == 0)
271 halmac_offset |= WLAN_IOREG_OFFSET;
273 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
276 if (status != HALMAC_RET_SUCCESS) {
277 pr_err("%s error = %x\n", __func__, status);
281 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
282 (halmac_offset & (2 - 1)) != 0 ||
283 halmac_adapter->sdio_cmd53_4byte ==
284 HALMAC_SDIO_CMD53_4BYTE_MODE_RW ||
285 halmac_adapter->sdio_cmd53_4byte ==
286 HALMAC_SDIO_CMD53_4BYTE_MODE_R) {
288 PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
289 value16.byte[1] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
291 value16.word = le16_to_cpu(value16.le_word);
293 #if (PLATFORM_SD_CLK > HALMAC_SD_CLK_THRESHOLD_88XX)
294 if ((halmac_offset & 0xffffef00) == 0x00000000) {
295 value16.byte[0] = PLATFORM_SDIO_CMD52_READ(
296 driver_adapter, halmac_offset);
297 value16.byte[1] = PLATFORM_SDIO_CMD52_READ(
298 driver_adapter, halmac_offset + 1);
299 value16.word = le16_to_cpu(value16.word);
301 value16.word = PLATFORM_SDIO_CMD53_READ_16(
302 driver_adapter, halmac_offset);
305 value16.word = PLATFORM_SDIO_CMD53_READ_16(driver_adapter,
314 * halmac_reg_write_16_sdio_88xx() - write 2byte register
315 * @halmac_adapter : the adapter of halmac
316 * @halmac_offset : register offset
317 * @halmac_data : register value
318 * Author : KaiYuan Chang/Ivan Lin
319 * Return : enum halmac_ret_status
320 * More details of status code can be found in prototype document
322 enum halmac_ret_status
323 halmac_reg_write_16_sdio_88xx(struct halmac_adapter *halmac_adapter,
324 u32 halmac_offset, u16 halmac_data)
326 void *driver_adapter = NULL;
327 struct halmac_api *halmac_api;
328 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
330 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
331 return HALMAC_RET_ADAPTER_INVALID;
333 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
334 return HALMAC_RET_API_INVALID;
336 driver_adapter = halmac_adapter->driver_adapter;
337 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
339 if ((halmac_offset & 0xFFFF0000) == 0)
340 halmac_offset |= WLAN_IOREG_OFFSET;
342 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
345 if (status != HALMAC_RET_SUCCESS) {
346 pr_err("%s error = %x\n", __func__, status);
350 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
351 (halmac_offset & (2 - 1)) != 0 ||
352 halmac_adapter->sdio_cmd53_4byte ==
353 HALMAC_SDIO_CMD53_4BYTE_MODE_RW ||
354 halmac_adapter->sdio_cmd53_4byte ==
355 HALMAC_SDIO_CMD53_4BYTE_MODE_W) {
356 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
357 (u8)(halmac_data & 0xFF));
358 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
359 (u8)((halmac_data & 0xFF00) >> 8));
361 PLATFORM_SDIO_CMD53_WRITE_16(driver_adapter, halmac_offset,
365 return HALMAC_RET_SUCCESS;
369 * halmac_reg_read_32_sdio_88xx() - read 4byte register
370 * @halmac_adapter : the adapter of halmac
371 * @halmac_offset : register offset
372 * Author : KaiYuan Chang/Ivan Lin
373 * Return : enum halmac_ret_status
374 * More details of status code can be found in prototype document
376 u32 halmac_reg_read_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
379 void *driver_adapter = NULL;
380 struct halmac_api *halmac_api;
381 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
382 u32 halmac_offset_old = 0;
388 } value32 = {0x00000000};
390 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
391 return HALMAC_RET_ADAPTER_INVALID;
393 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
394 return HALMAC_RET_API_INVALID;
396 driver_adapter = halmac_adapter->driver_adapter;
397 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
399 halmac_offset_old = halmac_offset;
401 if ((halmac_offset & 0xFFFF0000) == 0)
402 halmac_offset |= WLAN_IOREG_OFFSET;
404 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
406 if (status != HALMAC_RET_SUCCESS) {
407 pr_err("%s error = %x\n", __func__, status);
411 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
412 (halmac_offset & (4 - 1)) != 0) {
414 PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
415 value32.byte[1] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
417 value32.byte[2] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
419 value32.byte[3] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
421 value32.dword = le32_to_cpu(value32.le_dword);
423 #if (PLATFORM_SD_CLK > HALMAC_SD_CLK_THRESHOLD_88XX)
424 if ((halmac_offset_old & 0xffffef00) == 0x00000000) {
425 value32.byte[0] = PLATFORM_SDIO_CMD52_READ(
426 driver_adapter, halmac_offset);
427 value32.byte[1] = PLATFORM_SDIO_CMD52_READ(
428 driver_adapter, halmac_offset + 1);
429 value32.byte[2] = PLATFORM_SDIO_CMD52_READ(
430 driver_adapter, halmac_offset + 2);
431 value32.byte[3] = PLATFORM_SDIO_CMD52_READ(
432 driver_adapter, halmac_offset + 3);
433 value32.dword = le32_to_cpu(value32.dword);
435 value32.dword = PLATFORM_SDIO_CMD53_READ_32(
436 driver_adapter, halmac_offset);
439 value32.dword = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
444 return value32.dword;
448 * halmac_reg_write_32_sdio_88xx() - write 4byte register
449 * @halmac_adapter : the adapter of halmac
450 * @halmac_offset : register offset
451 * @halmac_data : register value
452 * Author : KaiYuan Chang/Ivan Lin
453 * Return : enum halmac_ret_status
454 * More details of status code can be found in prototype document
456 enum halmac_ret_status
457 halmac_reg_write_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
458 u32 halmac_offset, u32 halmac_data)
460 void *driver_adapter = NULL;
461 struct halmac_api *halmac_api;
462 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
464 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
465 return HALMAC_RET_ADAPTER_INVALID;
467 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
468 return HALMAC_RET_API_INVALID;
470 driver_adapter = halmac_adapter->driver_adapter;
471 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
473 if ((halmac_offset & 0xFFFF0000) == 0)
474 halmac_offset |= WLAN_IOREG_OFFSET;
476 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
479 if (status != HALMAC_RET_SUCCESS) {
480 pr_err("%s error = %x\n", __func__, status);
484 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
485 (halmac_offset & (4 - 1)) != 0) {
486 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
487 (u8)(halmac_data & 0xFF));
488 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
489 (u8)((halmac_data & 0xFF00) >> 8));
490 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
491 (u8)((halmac_data & 0xFF0000) >> 16));
492 PLATFORM_SDIO_CMD52_WRITE(
493 driver_adapter, halmac_offset + 3,
494 (u8)((halmac_data & 0xFF000000) >> 24));
496 PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
500 return HALMAC_RET_SUCCESS;
504 * halmac_reg_read_nbyte_sdio_88xx() - read n byte register
505 * @halmac_adapter : the adapter of halmac
506 * @halmac_offset : register offset
507 * @halmac_size : register value size
508 * @halmac_data : register value
510 * Return : enum halmac_ret_status
511 * More details of status code can be found in prototype document
513 u8 halmac_reg_read_nbyte_sdio_88xx(struct halmac_adapter *halmac_adapter,
514 u32 halmac_offset, u32 halmac_size,
517 void *driver_adapter = NULL;
518 struct halmac_api *halmac_api;
519 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
521 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
522 return HALMAC_RET_ADAPTER_INVALID;
524 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
525 return HALMAC_RET_API_INVALID;
527 driver_adapter = halmac_adapter->driver_adapter;
528 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
530 if ((halmac_offset & 0xFFFF0000) == 0) {
531 pr_err("halmac_offset error = 0x%x\n", halmac_offset);
532 return HALMAC_RET_FAIL;
535 status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
537 if (status != HALMAC_RET_SUCCESS) {
538 pr_err("%s error = %x\n", __func__, status);
542 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF) {
543 pr_err("halmac_state error = 0x%x\n",
544 halmac_adapter->halmac_state.mac_power);
545 return HALMAC_RET_FAIL;
548 PLATFORM_SDIO_CMD53_READ_N(driver_adapter, halmac_offset, halmac_size,
551 return HALMAC_RET_SUCCESS;
555 * halmac_get_sdio_tx_addr_sdio_88xx() - get CMD53 addr for the TX packet
556 * @halmac_adapter : the adapter of halmac
557 * @halmac_buf : tx packet, include txdesc
558 * @halmac_size : tx packet size
559 * @pcmd53_addr : cmd53 addr value
560 * Author : KaiYuan Chang/Ivan Lin
561 * Return : enum halmac_ret_status
562 * More details of status code can be found in prototype document
564 enum halmac_ret_status
565 halmac_get_sdio_tx_addr_88xx(struct halmac_adapter *halmac_adapter,
566 u8 *halmac_buf, u32 halmac_size, u32 *pcmd53_addr)
569 void *driver_adapter = NULL;
570 struct halmac_api *halmac_api;
571 enum halmac_queue_select queue_sel;
572 enum halmac_dma_mapping dma_mapping;
574 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
575 return HALMAC_RET_ADAPTER_INVALID;
577 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
578 return HALMAC_RET_API_INVALID;
580 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_SDIO_TX_ADDR);
582 driver_adapter = halmac_adapter->driver_adapter;
583 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
585 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
586 "%s ==========>\n", __func__);
589 pr_err("halmac_buf is NULL!!\n");
590 return HALMAC_RET_DATA_BUF_NULL;
593 if (halmac_size == 0) {
594 pr_err("halmac_size is 0!!\n");
595 return HALMAC_RET_DATA_SIZE_INCORRECT;
598 queue_sel = (enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf);
601 case HALMAC_QUEUE_SELECT_VO:
602 case HALMAC_QUEUE_SELECT_VO_V2:
604 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
606 case HALMAC_QUEUE_SELECT_VI:
607 case HALMAC_QUEUE_SELECT_VI_V2:
609 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
611 case HALMAC_QUEUE_SELECT_BE:
612 case HALMAC_QUEUE_SELECT_BE_V2:
614 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
616 case HALMAC_QUEUE_SELECT_BK:
617 case HALMAC_QUEUE_SELECT_BK_V2:
619 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
621 case HALMAC_QUEUE_SELECT_MGNT:
623 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
625 case HALMAC_QUEUE_SELECT_HIGH:
626 case HALMAC_QUEUE_SELECT_BCN:
627 case HALMAC_QUEUE_SELECT_CMD:
629 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
632 pr_err("Qsel is out of range\n");
633 return HALMAC_RET_QSEL_INCORRECT;
636 four_byte_len = (halmac_size >> 2) + ((halmac_size & (4 - 1)) ? 1 : 0);
638 switch (dma_mapping) {
639 case HALMAC_DMA_MAPPING_HIGH:
640 *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_HIGH;
642 case HALMAC_DMA_MAPPING_NORMAL:
643 *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_NORMAL;
645 case HALMAC_DMA_MAPPING_LOW:
646 *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_LOW;
648 case HALMAC_DMA_MAPPING_EXTRA:
649 *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_EXTRA;
652 pr_err("DmaMapping is out of range\n");
653 return HALMAC_RET_DMA_MAP_INCORRECT;
656 *pcmd53_addr = (*pcmd53_addr << 13) |
657 (four_byte_len & HALMAC_SDIO_4BYTE_LEN_MASK);
659 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
660 "%s <==========\n", __func__);
662 return HALMAC_RET_SUCCESS;
666 * halmac_cfg_tx_agg_align_sdio_88xx() -config sdio bus tx agg alignment
667 * @halmac_adapter : the adapter of halmac
668 * @enable : function enable(1)/disable(0)
669 * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
671 * Return : enum halmac_ret_status
672 * More details of status code can be found in prototype document
674 enum halmac_ret_status
675 halmac_cfg_tx_agg_align_sdio_88xx(struct halmac_adapter *halmac_adapter,
676 u8 enable, u16 align_size)
678 struct halmac_api *halmac_api;
679 void *driver_adapter = NULL;
680 u8 i, align_size_ok = 0;
682 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
683 return HALMAC_RET_ADAPTER_INVALID;
685 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
686 return HALMAC_RET_API_INVALID;
688 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
690 driver_adapter = halmac_adapter->driver_adapter;
691 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
693 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
694 "%s ==========>\n", __func__);
696 if ((align_size & 0xF000) != 0) {
697 pr_err("Align size is out of range\n");
698 return HALMAC_RET_FAIL;
701 for (i = 3; i <= 11; i++) {
702 if (align_size == 1 << i) {
707 if (align_size_ok == 0) {
708 pr_err("Align size is not 2^3 ~ 2^11\n");
709 return HALMAC_RET_FAIL;
712 /*Keep sdio tx agg alignment size for driver query*/
713 halmac_adapter->hw_config_info.tx_align_size = align_size;
716 HALMAC_REG_WRITE_16(halmac_adapter, REG_RQPN_CTRL_2,
717 0x8000 | align_size);
719 HALMAC_REG_WRITE_16(halmac_adapter, REG_RQPN_CTRL_2,
722 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
723 "%s <==========\n", __func__);
725 return HALMAC_RET_SUCCESS;
728 enum halmac_ret_status halmac_cfg_tx_agg_align_sdio_not_support_88xx(
729 struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size)
731 struct halmac_api *halmac_api;
732 void *driver_adapter = NULL;
734 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
735 return HALMAC_RET_ADAPTER_INVALID;
737 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
738 return HALMAC_RET_API_INVALID;
740 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
742 driver_adapter = halmac_adapter->driver_adapter;
743 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
746 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
747 "%s ==========>\n", __func__);
750 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
751 "%s not support\n", __func__);
753 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
754 "%s <==========\n", __func__);
756 return HALMAC_RET_SUCCESS;
760 * halmac_tx_allowed_sdio_88xx() - check tx status
761 * @halmac_adapter : the adapter of halmac
762 * @halmac_buf : tx packet, include txdesc
763 * @halmac_size : tx packet size, include txdesc
765 * Return : enum halmac_ret_status
766 * More details of status code can be found in prototype document
768 enum halmac_ret_status
769 halmac_tx_allowed_sdio_88xx(struct halmac_adapter *halmac_adapter,
770 u8 *halmac_buf, u32 halmac_size)
773 u16 *curr_free_space;
775 u32 tx_agg_num, packet_size = 0;
776 u32 tx_required_page_num, total_required_page_num = 0;
777 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
778 void *driver_adapter = NULL;
779 enum halmac_dma_mapping dma_mapping;
781 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
782 return HALMAC_RET_ADAPTER_INVALID;
784 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
785 return HALMAC_RET_API_INVALID;
787 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_TX_ALLOWED_SDIO);
789 driver_adapter = halmac_adapter->driver_adapter;
791 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
792 "%s ==========>\n", __func__);
794 tx_agg_num = GET_TX_DESC_DMA_TXAGG_NUM(halmac_buf);
795 curr_packet = halmac_buf;
797 tx_agg_num = tx_agg_num == 0 ? 1 : tx_agg_num;
799 switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(curr_packet)) {
800 case HALMAC_QUEUE_SELECT_VO:
801 case HALMAC_QUEUE_SELECT_VO_V2:
803 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
805 case HALMAC_QUEUE_SELECT_VI:
806 case HALMAC_QUEUE_SELECT_VI_V2:
808 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
810 case HALMAC_QUEUE_SELECT_BE:
811 case HALMAC_QUEUE_SELECT_BE_V2:
813 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
815 case HALMAC_QUEUE_SELECT_BK:
816 case HALMAC_QUEUE_SELECT_BK_V2:
818 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
820 case HALMAC_QUEUE_SELECT_MGNT:
822 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
824 case HALMAC_QUEUE_SELECT_HIGH:
826 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
828 case HALMAC_QUEUE_SELECT_BCN:
829 case HALMAC_QUEUE_SELECT_CMD:
830 return HALMAC_RET_SUCCESS;
832 pr_err("Qsel is out of range\n");
833 return HALMAC_RET_QSEL_INCORRECT;
836 switch (dma_mapping) {
837 case HALMAC_DMA_MAPPING_HIGH:
839 &halmac_adapter->sdio_free_space.high_queue_number;
841 case HALMAC_DMA_MAPPING_NORMAL:
843 &halmac_adapter->sdio_free_space.normal_queue_number;
845 case HALMAC_DMA_MAPPING_LOW:
847 &halmac_adapter->sdio_free_space.low_queue_number;
849 case HALMAC_DMA_MAPPING_EXTRA:
851 &halmac_adapter->sdio_free_space.extra_queue_number;
854 pr_err("DmaMapping is out of range\n");
855 return HALMAC_RET_DMA_MAP_INCORRECT;
858 for (i = 0; i < tx_agg_num; i++) {
859 packet_size = GET_TX_DESC_TXPKTSIZE(curr_packet) +
860 GET_TX_DESC_OFFSET(curr_packet) +
861 (GET_TX_DESC_PKT_OFFSET(curr_packet) << 3);
862 tx_required_page_num =
864 halmac_adapter->hw_config_info.page_size_2_power) +
866 (halmac_adapter->hw_config_info.page_size - 1)) ?
869 total_required_page_num += tx_required_page_num;
871 packet_size = HALMAC_ALIGN(packet_size, 8);
873 curr_packet += packet_size;
878 if ((u32)(*curr_free_space +
879 halmac_adapter->sdio_free_space.public_queue_number) >
880 total_required_page_num) {
881 if (*curr_free_space >= total_required_page_num) {
883 (u16)total_required_page_num;
885 halmac_adapter->sdio_free_space
886 .public_queue_number -=
887 (u16)(total_required_page_num -
889 *curr_free_space = 0;
892 status = halmac_check_oqt_88xx(halmac_adapter,
893 tx_agg_num, halmac_buf);
895 if (status != HALMAC_RET_SUCCESS)
901 halmac_update_sdio_free_page_88xx(halmac_adapter);
905 return HALMAC_RET_FREE_SPACE_NOT_ENOUGH;
908 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
909 "%s <==========\n", __func__);
911 return HALMAC_RET_SUCCESS;
915 * halmac_reg_read_indirect_32_sdio_88xx() - read MAC reg by SDIO reg
916 * @halmac_adapter : the adapter of halmac
917 * @halmac_offset : register offset
919 * Return : enum halmac_ret_status
920 * More details of status code can be found in prototype document
922 u32 halmac_reg_read_indirect_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
927 void *driver_adapter = NULL;
932 } value32 = {0x00000000};
934 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
935 return HALMAC_RET_ADAPTER_INVALID;
937 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
938 return HALMAC_RET_API_INVALID;
940 driver_adapter = halmac_adapter->driver_adapter;
942 PLATFORM_SDIO_CMD53_WRITE_32(
944 (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
945 (REG_SDIO_INDIRECT_REG_CFG & HALMAC_SDIO_LOCAL_MSK),
946 halmac_offset | BIT(19) | BIT(17));
949 rtemp = PLATFORM_SDIO_CMD52_READ(
951 (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
952 ((REG_SDIO_INDIRECT_REG_CFG + 2) &
953 HALMAC_SDIO_LOCAL_MSK));
955 } while ((rtemp & BIT(4)) != 0 && counter > 0);
957 value32.dword = PLATFORM_SDIO_CMD53_READ_32(
959 (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
960 (REG_SDIO_INDIRECT_REG_DATA & HALMAC_SDIO_LOCAL_MSK));
962 return value32.dword;