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_2_platform.h"
15 #include "halmac_type.h"
16 #include "halmac_88xx/halmac_api_88xx.h"
17 #include "halmac_88xx/halmac_88xx_cfg.h"
19 #include "halmac_88xx/halmac_8822b/halmac_8822b_cfg.h"
21 static enum halmac_ret_status
22 halmac_check_platform_api(void *driver_adapter,
23 enum halmac_interface halmac_interface,
24 struct halmac_platform_api *halmac_platform_api)
26 void *adapter_local = NULL;
28 adapter_local = driver_adapter;
30 if (!halmac_platform_api)
31 return HALMAC_RET_PLATFORM_API_NULL;
33 if (halmac_interface == HALMAC_INTERFACE_SDIO) {
34 if (!halmac_platform_api->SDIO_CMD52_READ) {
35 pr_err("(!halmac_platform_api->SDIO_CMD52_READ)\n");
36 return HALMAC_RET_PLATFORM_API_NULL;
38 if (!halmac_platform_api->SDIO_CMD53_READ_8) {
39 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_8)\n");
40 return HALMAC_RET_PLATFORM_API_NULL;
42 if (!halmac_platform_api->SDIO_CMD53_READ_16) {
43 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_16)\n");
44 return HALMAC_RET_PLATFORM_API_NULL;
46 if (!halmac_platform_api->SDIO_CMD53_READ_32) {
47 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_32)\n");
48 return HALMAC_RET_PLATFORM_API_NULL;
50 if (!halmac_platform_api->SDIO_CMD53_READ_N) {
51 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_N)\n");
52 return HALMAC_RET_PLATFORM_API_NULL;
54 if (!halmac_platform_api->SDIO_CMD52_WRITE) {
55 pr_err("(!halmac_platform_api->SDIO_CMD52_WRITE)\n");
56 return HALMAC_RET_PLATFORM_API_NULL;
58 if (!halmac_platform_api->SDIO_CMD53_WRITE_8) {
59 pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_8)\n");
60 return HALMAC_RET_PLATFORM_API_NULL;
62 if (!halmac_platform_api->SDIO_CMD53_WRITE_16) {
63 pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_16)\n");
64 return HALMAC_RET_PLATFORM_API_NULL;
66 if (!halmac_platform_api->SDIO_CMD53_WRITE_32) {
67 pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_32)\n");
68 return HALMAC_RET_PLATFORM_API_NULL;
72 if (halmac_interface == HALMAC_INTERFACE_USB ||
73 halmac_interface == HALMAC_INTERFACE_PCIE) {
74 if (!halmac_platform_api->REG_READ_8) {
75 pr_err("(!halmac_platform_api->REG_READ_8)\n");
76 return HALMAC_RET_PLATFORM_API_NULL;
78 if (!halmac_platform_api->REG_READ_16) {
79 pr_err("(!halmac_platform_api->REG_READ_16)\n");
80 return HALMAC_RET_PLATFORM_API_NULL;
82 if (!halmac_platform_api->REG_READ_32) {
83 pr_err("(!halmac_platform_api->REG_READ_32)\n");
84 return HALMAC_RET_PLATFORM_API_NULL;
86 if (!halmac_platform_api->REG_WRITE_8) {
87 pr_err("(!halmac_platform_api->REG_WRITE_8)\n");
88 return HALMAC_RET_PLATFORM_API_NULL;
90 if (!halmac_platform_api->REG_WRITE_16) {
91 pr_err("(!halmac_platform_api->REG_WRITE_16)\n");
92 return HALMAC_RET_PLATFORM_API_NULL;
94 if (!halmac_platform_api->REG_WRITE_32) {
95 pr_err("(!halmac_platform_api->REG_WRITE_32)\n");
96 return HALMAC_RET_PLATFORM_API_NULL;
100 if (!halmac_platform_api->EVENT_INDICATION) {
101 pr_err("(!halmac_platform_api->EVENT_INDICATION)\n");
102 return HALMAC_RET_PLATFORM_API_NULL;
105 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
106 "%s ==========>\n", __func__);
108 return HALMAC_RET_SUCCESS;
111 static enum halmac_ret_status
112 halmac_convert_to_sdio_bus_offset(u32 *halmac_offset)
114 switch ((*halmac_offset) & 0xFFFF0000) {
115 case WLAN_IOREG_OFFSET:
116 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
117 (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
119 case SDIO_LOCAL_OFFSET:
120 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
121 (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
124 *halmac_offset = 0xFFFFFFFF;
125 return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
128 return HALMAC_RET_SUCCESS;
132 platform_reg_read_8_sdio(void *driver_adapter,
133 struct halmac_platform_api *halmac_platform_api,
137 u32 halmac_offset = offset;
138 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
140 if ((halmac_offset & 0xFFFF0000) == 0)
141 halmac_offset |= WLAN_IOREG_OFFSET;
143 status = halmac_convert_to_sdio_bus_offset(&halmac_offset);
144 if (status != HALMAC_RET_SUCCESS) {
145 pr_err("%s error = %x\n", __func__, status);
149 value8 = halmac_platform_api->SDIO_CMD52_READ(driver_adapter,
155 static enum halmac_ret_status
156 platform_reg_write_8_sdio(void *driver_adapter,
157 struct halmac_platform_api *halmac_platform_api,
160 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
161 u32 halmac_offset = offset;
163 if ((halmac_offset & 0xFFFF0000) == 0)
164 halmac_offset |= WLAN_IOREG_OFFSET;
166 status = halmac_convert_to_sdio_bus_offset(&halmac_offset);
168 if (status != HALMAC_RET_SUCCESS) {
169 pr_err("halmac_reg_write_8_sdio_88xx error = %x\n", status);
172 halmac_platform_api->SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
175 return HALMAC_RET_SUCCESS;
178 static enum halmac_ret_status
179 halmac_get_chip_info(void *driver_adapter,
180 struct halmac_platform_api *halmac_platform_api,
181 enum halmac_interface halmac_interface,
182 struct halmac_adapter *halmac_adapter)
184 struct halmac_api *halmac_api = (struct halmac_api *)NULL;
185 u8 chip_id, chip_version;
188 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
190 /* Get Chip_id and Chip_version */
191 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
192 platform_reg_write_8_sdio(
193 driver_adapter, halmac_platform_api, REG_SDIO_HSUS_CTRL,
194 platform_reg_read_8_sdio(driver_adapter,
196 REG_SDIO_HSUS_CTRL) &
199 polling_count = 10000;
200 while (!(platform_reg_read_8_sdio(driver_adapter,
202 REG_SDIO_HSUS_CTRL) &
205 if (polling_count == 0)
206 return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
209 chip_id = platform_reg_read_8_sdio(
210 driver_adapter, halmac_platform_api, REG_SYS_CFG2);
211 chip_version = platform_reg_read_8_sdio(driver_adapter,
216 chip_id = halmac_platform_api->REG_READ_8(driver_adapter,
218 chip_version = halmac_platform_api->REG_READ_8(
219 driver_adapter, REG_SYS_CFG1 + 1) >>
223 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
224 "[TRACE]Chip id : 0x%X\n", chip_id);
225 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
226 "[TRACE]Chip version : 0x%X\n", chip_version);
228 halmac_adapter->chip_version = (enum halmac_chip_ver)chip_version;
230 if (chip_id == HALMAC_CHIP_ID_HW_DEF_8822B)
231 halmac_adapter->chip_id = HALMAC_CHIP_ID_8822B;
232 else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8821C)
233 halmac_adapter->chip_id = HALMAC_CHIP_ID_8821C;
234 else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8814B)
235 halmac_adapter->chip_id = HALMAC_CHIP_ID_8814B;
236 else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8197F)
237 halmac_adapter->chip_id = HALMAC_CHIP_ID_8197F;
239 halmac_adapter->chip_id = HALMAC_CHIP_ID_UNDEFINE;
241 if (halmac_adapter->chip_id == HALMAC_CHIP_ID_UNDEFINE)
242 return HALMAC_RET_CHIP_NOT_SUPPORT;
244 return HALMAC_RET_SUCCESS;
248 * halmac_init_adapter() - init halmac_adapter
249 * @driver_adapter : the adapter of caller
250 * @halmac_platform_api : the platform APIs which is used in halmac APIs
251 * @halmac_interface : bus interface
252 * @pp_halmac_adapter : the adapter of halmac
253 * @pp_halmac_api : the function pointer of APIs, caller shall call APIs by
255 * Author : KaiYuan Chang / Ivan Lin
256 * Return : enum halmac_ret_status
257 * More details of status code can be found in prototype document
259 enum halmac_ret_status
260 halmac_init_adapter(void *driver_adapter,
261 struct halmac_platform_api *halmac_platform_api,
262 enum halmac_interface halmac_interface,
263 struct halmac_adapter **pp_halmac_adapter,
264 struct halmac_api **pp_halmac_api)
266 struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
267 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
272 } ENDIAN_CHECK = {0x01000000};
274 status = halmac_check_platform_api(driver_adapter, halmac_interface,
275 halmac_platform_api);
276 if (status != HALMAC_RET_SUCCESS)
278 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
279 HALMAC_SVN_VER "\n");
280 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
281 "HALMAC_MAJOR_VER = %x\n", HALMAC_MAJOR_VER);
282 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
283 "HALMAC_PROTOTYPE_VER = %x\n", HALMAC_PROTOTYPE_VER);
284 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
285 "HALMAC_MINOR_VER = %x\n", HALMAC_MINOR_VER);
286 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
287 "HALMAC_PATCH_VER = %x\n", HALMAC_PATCH_VER);
289 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
290 "halmac_init_adapter_88xx ==========>\n");
292 /* Check endian setting - Little endian : 1, Big endian : 0*/
293 if (ENDIAN_CHECK.x[0] == HALMAC_SYSTEM_ENDIAN) {
294 pr_err("Endian setting Err!!\n");
295 return HALMAC_RET_ENDIAN_ERR;
298 halmac_adapter = kzalloc(sizeof(*halmac_adapter), GFP_KERNEL);
299 if (!halmac_adapter) {
301 return HALMAC_RET_MALLOC_FAIL;
304 /* return halmac adapter address to caller */
305 *pp_halmac_adapter = halmac_adapter;
307 /* Record caller info */
308 halmac_adapter->halmac_platform_api = halmac_platform_api;
309 halmac_adapter->driver_adapter = driver_adapter;
310 halmac_interface = halmac_interface == HALMAC_INTERFACE_AXI ?
311 HALMAC_INTERFACE_PCIE :
313 halmac_adapter->halmac_interface = halmac_interface;
315 spin_lock_init(&halmac_adapter->efuse_lock);
316 spin_lock_init(&halmac_adapter->h2c_seq_lock);
319 if (halmac_get_chip_info(driver_adapter, halmac_platform_api,
321 halmac_adapter) != HALMAC_RET_SUCCESS) {
322 pr_err("HALMAC_RET_CHIP_NOT_SUPPORT\n");
323 return HALMAC_RET_CHIP_NOT_SUPPORT;
326 /* Assign function pointer to halmac API */
327 halmac_init_adapter_para_88xx(halmac_adapter);
328 status = halmac_mount_api_88xx(halmac_adapter);
330 /* Return halmac API function pointer */
331 *pp_halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
333 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
334 "halmac_init_adapter_88xx <==========\n");
340 * halmac_halt_api() - stop halmac_api action
341 * @halmac_adapter : the adapter of halmac
343 * Return : enum halmac_ret_status
344 * More details of status code can be found in prototype document
346 enum halmac_ret_status halmac_halt_api(struct halmac_adapter *halmac_adapter)
348 void *driver_adapter = NULL;
349 struct halmac_platform_api *halmac_platform_api =
350 (struct halmac_platform_api *)NULL;
352 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
353 return HALMAC_RET_ADAPTER_INVALID;
355 driver_adapter = halmac_adapter->driver_adapter;
356 halmac_platform_api = halmac_adapter->halmac_platform_api;
358 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
359 "%s ==========>\n", __func__);
360 halmac_adapter->halmac_state.api_state = HALMAC_API_STATE_HALT;
361 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
362 "%s ==========>\n", __func__);
363 return HALMAC_RET_SUCCESS;
367 * halmac_deinit_adapter() - deinit halmac adapter
368 * @halmac_adapter : the adapter of halmac
369 * Author : KaiYuan Chang / Ivan Lin
370 * Return : enum halmac_ret_status
371 * More details of status code can be found in prototype document
373 enum halmac_ret_status
374 halmac_deinit_adapter(struct halmac_adapter *halmac_adapter)
376 void *driver_adapter = NULL;
378 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
379 return HALMAC_RET_ADAPTER_INVALID;
381 driver_adapter = halmac_adapter->driver_adapter;
383 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
384 "[TRACE]halmac_deinit_adapter_88xx ==========>\n");
386 kfree(halmac_adapter->hal_efuse_map);
387 halmac_adapter->hal_efuse_map = (u8 *)NULL;
389 kfree(halmac_adapter->halmac_state.psd_set.data);
390 halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
392 kfree(halmac_adapter->halmac_api);
393 halmac_adapter->halmac_api = NULL;
395 halmac_adapter->hal_adapter_backup = NULL;
396 kfree(halmac_adapter);
398 return HALMAC_RET_SUCCESS;
402 * halmac_get_version() - get HALMAC version
403 * @version : return version of major, prototype and minor information
404 * Author : KaiYuan Chang / Ivan Lin
405 * Return : enum halmac_ret_status
406 * More details of status code can be found in prototype document
408 enum halmac_ret_status halmac_get_version(struct halmac_ver *version)
410 version->major_ver = (u8)HALMAC_MAJOR_VER;
411 version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
412 version->minor_ver = (u8)HALMAC_MINOR_VER;
414 return HALMAC_RET_SUCCESS;