1 /******************************************************************************
3 * Copyright(c) 2016 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
25 #include "halmac_2_platform.h"
26 #include "halmac_type.h"
27 #include "halmac_88xx/halmac_api_88xx.h"
28 #include "halmac_88xx/halmac_88xx_cfg.h"
30 #include "halmac_88xx/halmac_8822b/halmac_8822b_cfg.h"
32 static enum halmac_ret_status
33 halmac_check_platform_api(void *driver_adapter,
34 enum halmac_interface halmac_interface,
35 struct halmac_platform_api *halmac_platform_api)
37 void *adapter_local = NULL;
39 adapter_local = driver_adapter;
41 if (!halmac_platform_api)
42 return HALMAC_RET_PLATFORM_API_NULL;
44 if (halmac_interface == HALMAC_INTERFACE_SDIO) {
45 if (!halmac_platform_api->SDIO_CMD52_READ) {
46 pr_err("(!halmac_platform_api->SDIO_CMD52_READ)\n");
47 return HALMAC_RET_PLATFORM_API_NULL;
49 if (!halmac_platform_api->SDIO_CMD53_READ_8) {
50 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_8)\n");
51 return HALMAC_RET_PLATFORM_API_NULL;
53 if (!halmac_platform_api->SDIO_CMD53_READ_16) {
54 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_16)\n");
55 return HALMAC_RET_PLATFORM_API_NULL;
57 if (!halmac_platform_api->SDIO_CMD53_READ_32) {
58 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_32)\n");
59 return HALMAC_RET_PLATFORM_API_NULL;
61 if (!halmac_platform_api->SDIO_CMD53_READ_N) {
62 pr_err("(!halmac_platform_api->SDIO_CMD53_READ_N)\n");
63 return HALMAC_RET_PLATFORM_API_NULL;
65 if (!halmac_platform_api->SDIO_CMD52_WRITE) {
66 pr_err("(!halmac_platform_api->SDIO_CMD52_WRITE)\n");
67 return HALMAC_RET_PLATFORM_API_NULL;
69 if (!halmac_platform_api->SDIO_CMD53_WRITE_8) {
70 pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_8)\n");
71 return HALMAC_RET_PLATFORM_API_NULL;
73 if (!halmac_platform_api->SDIO_CMD53_WRITE_16) {
74 pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_16)\n");
75 return HALMAC_RET_PLATFORM_API_NULL;
77 if (!halmac_platform_api->SDIO_CMD53_WRITE_32) {
78 pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_32)\n");
79 return HALMAC_RET_PLATFORM_API_NULL;
83 if (halmac_interface == HALMAC_INTERFACE_USB ||
84 halmac_interface == HALMAC_INTERFACE_PCIE) {
85 if (!halmac_platform_api->REG_READ_8) {
86 pr_err("(!halmac_platform_api->REG_READ_8)\n");
87 return HALMAC_RET_PLATFORM_API_NULL;
89 if (!halmac_platform_api->REG_READ_16) {
90 pr_err("(!halmac_platform_api->REG_READ_16)\n");
91 return HALMAC_RET_PLATFORM_API_NULL;
93 if (!halmac_platform_api->REG_READ_32) {
94 pr_err("(!halmac_platform_api->REG_READ_32)\n");
95 return HALMAC_RET_PLATFORM_API_NULL;
97 if (!halmac_platform_api->REG_WRITE_8) {
98 pr_err("(!halmac_platform_api->REG_WRITE_8)\n");
99 return HALMAC_RET_PLATFORM_API_NULL;
101 if (!halmac_platform_api->REG_WRITE_16) {
102 pr_err("(!halmac_platform_api->REG_WRITE_16)\n");
103 return HALMAC_RET_PLATFORM_API_NULL;
105 if (!halmac_platform_api->REG_WRITE_32) {
106 pr_err("(!halmac_platform_api->REG_WRITE_32)\n");
107 return HALMAC_RET_PLATFORM_API_NULL;
111 if (!halmac_platform_api->EVENT_INDICATION) {
112 pr_err("(!halmac_platform_api->EVENT_INDICATION)\n");
113 return HALMAC_RET_PLATFORM_API_NULL;
116 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
117 "%s ==========>\n", __func__);
119 return HALMAC_RET_SUCCESS;
122 static enum halmac_ret_status
123 halmac_convert_to_sdio_bus_offset(u32 *halmac_offset)
125 switch ((*halmac_offset) & 0xFFFF0000) {
126 case WLAN_IOREG_OFFSET:
127 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
128 (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
130 case SDIO_LOCAL_OFFSET:
131 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
132 (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
135 *halmac_offset = 0xFFFFFFFF;
136 return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
139 return HALMAC_RET_SUCCESS;
143 platform_reg_read_8_sdio(void *driver_adapter,
144 struct halmac_platform_api *halmac_platform_api,
148 u32 halmac_offset = offset;
149 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
151 if ((halmac_offset & 0xFFFF0000) == 0)
152 halmac_offset |= WLAN_IOREG_OFFSET;
154 status = halmac_convert_to_sdio_bus_offset(&halmac_offset);
155 if (status != HALMAC_RET_SUCCESS) {
156 pr_err("%s error = %x\n", __func__, status);
160 value8 = halmac_platform_api->SDIO_CMD52_READ(driver_adapter,
166 static enum halmac_ret_status
167 platform_reg_write_8_sdio(void *driver_adapter,
168 struct halmac_platform_api *halmac_platform_api,
171 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
172 u32 halmac_offset = offset;
174 if ((halmac_offset & 0xFFFF0000) == 0)
175 halmac_offset |= WLAN_IOREG_OFFSET;
177 status = halmac_convert_to_sdio_bus_offset(&halmac_offset);
179 if (status != HALMAC_RET_SUCCESS) {
180 pr_err("halmac_reg_write_8_sdio_88xx error = %x\n", status);
183 halmac_platform_api->SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
186 return HALMAC_RET_SUCCESS;
189 static enum halmac_ret_status
190 halmac_get_chip_info(void *driver_adapter,
191 struct halmac_platform_api *halmac_platform_api,
192 enum halmac_interface halmac_interface,
193 struct halmac_adapter *halmac_adapter)
195 struct halmac_api *halmac_api = (struct halmac_api *)NULL;
196 u8 chip_id, chip_version;
199 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
201 /* Get Chip_id and Chip_version */
202 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
203 platform_reg_write_8_sdio(
204 driver_adapter, halmac_platform_api, REG_SDIO_HSUS_CTRL,
205 platform_reg_read_8_sdio(driver_adapter,
207 REG_SDIO_HSUS_CTRL) &
210 polling_count = 10000;
211 while (!(platform_reg_read_8_sdio(driver_adapter,
213 REG_SDIO_HSUS_CTRL) &
216 if (polling_count == 0)
217 return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
220 chip_id = platform_reg_read_8_sdio(
221 driver_adapter, halmac_platform_api, REG_SYS_CFG2);
222 chip_version = platform_reg_read_8_sdio(driver_adapter,
227 chip_id = halmac_platform_api->REG_READ_8(driver_adapter,
229 chip_version = halmac_platform_api->REG_READ_8(
230 driver_adapter, REG_SYS_CFG1 + 1) >>
234 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
235 "[TRACE]Chip id : 0x%X\n", chip_id);
236 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
237 "[TRACE]Chip version : 0x%X\n", chip_version);
239 halmac_adapter->chip_version = (enum halmac_chip_ver)chip_version;
241 if (chip_id == HALMAC_CHIP_ID_HW_DEF_8822B)
242 halmac_adapter->chip_id = HALMAC_CHIP_ID_8822B;
243 else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8821C)
244 halmac_adapter->chip_id = HALMAC_CHIP_ID_8821C;
245 else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8814B)
246 halmac_adapter->chip_id = HALMAC_CHIP_ID_8814B;
247 else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8197F)
248 halmac_adapter->chip_id = HALMAC_CHIP_ID_8197F;
250 halmac_adapter->chip_id = HALMAC_CHIP_ID_UNDEFINE;
252 if (halmac_adapter->chip_id == HALMAC_CHIP_ID_UNDEFINE)
253 return HALMAC_RET_CHIP_NOT_SUPPORT;
255 return HALMAC_RET_SUCCESS;
259 * halmac_init_adapter() - init halmac_adapter
260 * @driver_adapter : the adapter of caller
261 * @halmac_platform_api : the platform APIs which is used in halmac APIs
262 * @halmac_interface : bus interface
263 * @pp_halmac_adapter : the adapter of halmac
264 * @pp_halmac_api : the function pointer of APIs, caller shall call APIs by
266 * Author : KaiYuan Chang / Ivan Lin
267 * Return : enum halmac_ret_status
268 * More details of status code can be found in prototype document
270 enum halmac_ret_status
271 halmac_init_adapter(void *driver_adapter,
272 struct halmac_platform_api *halmac_platform_api,
273 enum halmac_interface halmac_interface,
274 struct halmac_adapter **pp_halmac_adapter,
275 struct halmac_api **pp_halmac_api)
277 struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
278 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
283 } ENDIAN_CHECK = {0x01000000};
285 status = halmac_check_platform_api(driver_adapter, halmac_interface,
286 halmac_platform_api);
287 if (status != HALMAC_RET_SUCCESS)
289 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
290 HALMAC_SVN_VER "\n");
291 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
292 "HALMAC_MAJOR_VER = %x\n", HALMAC_MAJOR_VER);
293 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
294 "HALMAC_PROTOTYPE_VER = %x\n", HALMAC_PROTOTYPE_VER);
295 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
296 "HALMAC_MINOR_VER = %x\n", HALMAC_MINOR_VER);
297 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
298 "HALMAC_PATCH_VER = %x\n", HALMAC_PATCH_VER);
300 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
301 "halmac_init_adapter_88xx ==========>\n");
303 /* Check endian setting - Little endian : 1, Big endian : 0*/
304 if (ENDIAN_CHECK.x[0] == HALMAC_SYSTEM_ENDIAN) {
305 pr_err("Endian setting Err!!\n");
306 return HALMAC_RET_ENDIAN_ERR;
309 halmac_adapter = kzalloc(sizeof(*halmac_adapter), GFP_KERNEL);
310 if (!halmac_adapter) {
312 return HALMAC_RET_MALLOC_FAIL;
315 /* return halmac adapter address to caller */
316 *pp_halmac_adapter = halmac_adapter;
318 /* Record caller info */
319 halmac_adapter->halmac_platform_api = halmac_platform_api;
320 halmac_adapter->driver_adapter = driver_adapter;
321 halmac_interface = halmac_interface == HALMAC_INTERFACE_AXI ?
322 HALMAC_INTERFACE_PCIE :
324 halmac_adapter->halmac_interface = halmac_interface;
326 spin_lock_init(&halmac_adapter->efuse_lock);
327 spin_lock_init(&halmac_adapter->h2c_seq_lock);
330 if (halmac_get_chip_info(driver_adapter, halmac_platform_api,
332 halmac_adapter) != HALMAC_RET_SUCCESS) {
333 pr_err("HALMAC_RET_CHIP_NOT_SUPPORT\n");
334 return HALMAC_RET_CHIP_NOT_SUPPORT;
337 /* Assign function pointer to halmac API */
338 halmac_init_adapter_para_88xx(halmac_adapter);
339 status = halmac_mount_api_88xx(halmac_adapter);
341 /* Return halmac API function pointer */
342 *pp_halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
344 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
345 "halmac_init_adapter_88xx <==========\n");
351 * halmac_halt_api() - stop halmac_api action
352 * @halmac_adapter : the adapter of halmac
354 * Return : enum halmac_ret_status
355 * More details of status code can be found in prototype document
357 enum halmac_ret_status halmac_halt_api(struct halmac_adapter *halmac_adapter)
359 void *driver_adapter = NULL;
360 struct halmac_platform_api *halmac_platform_api =
361 (struct halmac_platform_api *)NULL;
363 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
364 return HALMAC_RET_ADAPTER_INVALID;
366 driver_adapter = halmac_adapter->driver_adapter;
367 halmac_platform_api = halmac_adapter->halmac_platform_api;
369 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
370 "%s ==========>\n", __func__);
371 halmac_adapter->halmac_state.api_state = HALMAC_API_STATE_HALT;
372 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
373 "%s ==========>\n", __func__);
374 return HALMAC_RET_SUCCESS;
378 * halmac_deinit_adapter() - deinit halmac adapter
379 * @halmac_adapter : the adapter of halmac
380 * Author : KaiYuan Chang / Ivan Lin
381 * Return : enum halmac_ret_status
382 * More details of status code can be found in prototype document
384 enum halmac_ret_status
385 halmac_deinit_adapter(struct halmac_adapter *halmac_adapter)
387 void *driver_adapter = NULL;
389 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
390 return HALMAC_RET_ADAPTER_INVALID;
392 driver_adapter = halmac_adapter->driver_adapter;
394 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
395 "[TRACE]halmac_deinit_adapter_88xx ==========>\n");
397 kfree(halmac_adapter->hal_efuse_map);
398 halmac_adapter->hal_efuse_map = (u8 *)NULL;
400 kfree(halmac_adapter->halmac_state.psd_set.data);
401 halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
403 kfree(halmac_adapter->halmac_api);
404 halmac_adapter->halmac_api = NULL;
406 halmac_adapter->hal_adapter_backup = NULL;
407 kfree(halmac_adapter);
409 return HALMAC_RET_SUCCESS;
413 * halmac_get_version() - get HALMAC version
414 * @version : return version of major, prototype and minor information
415 * Author : KaiYuan Chang / Ivan Lin
416 * Return : enum halmac_ret_status
417 * More details of status code can be found in prototype document
419 enum halmac_ret_status halmac_get_version(struct halmac_ver *version)
421 version->major_ver = (u8)HALMAC_MAJOR_VER;
422 version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
423 version->minor_ver = (u8)HALMAC_MINOR_VER;
425 return HALMAC_RET_SUCCESS;