net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / hal_hci / hal_sdio.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
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.
8  *
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
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HAL_SDIO_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 #ifndef RTW_HALMAC
26 static void dump_mac_page0(PADAPTER padapter)
27 {
28         char str_out[128];
29         char str_val[8];
30         char *p = NULL;
31         int index = 0, i = 0;
32         u8 val8 = 0, len = 0;
33
34         RTW_ERR("Dump MAC Page0 register:\n");
35         for (index = 0 ; index < 0x100 ; index += 16) {
36                 p = &str_out[0];
37                 len = snprintf(str_val, sizeof(str_val),
38                                "0x%02x: ", index);
39                 strncpy(str_out, str_val, len);
40                 p += len;
41
42                 for (i = 0 ; i < 16 ; i++) {
43                         len = snprintf(str_val, sizeof(str_val), "%02x ",
44                                        rtw_read8(padapter, index + i));
45                         strncpy(p, str_val, len);
46                         p += len;
47                 }
48                 RTW_INFO("%s\n", str_out);
49                 _rtw_memset(&str_out, '\0', sizeof(str_out));
50         }
51 }
52
53 /*
54  * Description:
55  *      Call this function to make sure power on successfully
56  *
57  * Return:
58  *      _SUCCESS        enable success
59  *      _FAIL   enable fail
60  */
61 bool sdio_power_on_check(PADAPTER padapter) {
62         u32 val_offset0, val_offset1, val_offset2, val_offset3;
63         u32 val_mix = 0;
64         u32 res = 0;
65         bool ret = _FAIL;
66         int index = 0;
67
68         val_offset0 = rtw_read8(padapter, REG_CR);
69         val_offset1 = rtw_read8(padapter, REG_CR + 1);
70         val_offset2 = rtw_read8(padapter, REG_CR + 2);
71         val_offset3 = rtw_read8(padapter, REG_CR + 3);
72
73         if (val_offset0 == 0xEA || val_offset1 == 0xEA ||
74             val_offset2 == 0xEA || val_offset3 == 0xEA) {
75                 RTW_INFO("%s: power on fail, do Power on again\n", __func__);
76                 return ret;
77         }
78
79         val_mix = val_offset3 << 24 | val_mix;
80         val_mix = val_offset2 << 16 | val_mix;
81         val_mix = val_offset1 << 8 | val_mix;
82         val_mix = val_offset0 | val_mix;
83
84         res = rtw_read32(padapter, REG_CR);
85
86         RTW_INFO("%s: val_mix:0x%08x, res:0x%08x\n", __func__, val_mix, res);
87
88         while (index < 100) {
89                 if (res == val_mix) {
90                         RTW_INFO("%s: 0x100 the result of cmd52 and cmd53 is the same.\n", __func__);
91                         ret = _SUCCESS;
92                         break;
93                 } else {
94                         RTW_INFO("%s: 0x100 cmd52 and cmd53 is not the same(index:%d).\n", __func__, index);
95                         res = rtw_read32(padapter, REG_CR);
96                         index++;
97                         ret = _FAIL;
98                 }
99         }
100
101         if (ret) {
102                 index = 0;
103                 while (index < 100) {
104                         rtw_write32(padapter, 0x1B8, 0x12345678);
105                         res = rtw_read32(padapter, 0x1B8);
106                         if (res == 0x12345678) {
107                                 RTW_INFO("%s: 0x1B8 test Pass.\n", __func__);
108                                 ret = _SUCCESS;
109                                 break;
110                         } else {
111                                 index++;
112                                 RTW_INFO("%s: 0x1B8 test Fail(index: %d).\n", __func__, index);
113                                 ret = _FAIL;
114                         }
115                 }
116         } else
117                 RTW_INFO("%s: fail at cmd52, cmd53.\n", __func__);
118
119         if (ret == _FAIL)
120                 dump_mac_page0(padapter);
121
122         return ret;
123 }
124
125 u8 rtw_hal_sdio_max_txoqt_free_space(_adapter *padapter)
126 {
127         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
128
129         if (pHalData->SdioTxOQTMaxFreeSpace < 8)
130                 pHalData->SdioTxOQTMaxFreeSpace = 8;
131
132         return pHalData->SdioTxOQTMaxFreeSpace;
133 }
134
135 u8 rtw_hal_sdio_query_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum)
136 {
137         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
138
139         if ((pHalData->SdioTxFIFOFreePage[PageIdx] + pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) >= (RequiredPageNum))
140                 return _TRUE;
141         else
142                 return _FALSE;
143 }
144
145 void rtw_hal_sdio_update_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum)
146 {
147         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
148         u8      DedicatedPgNum = 0;
149         u8      RequiredPublicFreePgNum = 0;
150         /* _irqL irql; */
151
152         /* _enter_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); */
153
154         DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
155         if (RequiredPageNum <= DedicatedPgNum)
156                 pHalData->SdioTxFIFOFreePage[PageIdx] -= RequiredPageNum;
157         else {
158                 pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
159                 RequiredPublicFreePgNum = RequiredPageNum - DedicatedPgNum;
160                 pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
161         }
162
163         /* _exit_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); */
164 }
165
166 void rtw_hal_set_sdio_tx_max_length(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ)
167 {
168         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
169         u32     page_size;
170         u32     lenHQ, lenNQ, lenLQ;
171
172         rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
173
174         lenHQ = ((numHQ + numPubQ) >> 1) * page_size;
175         lenNQ = ((numNQ + numPubQ) >> 1) * page_size;
176         lenLQ = ((numLQ + numPubQ) >> 1) * page_size;
177
178         pHalData->sdio_tx_max_len[HI_QUEUE_IDX] = (lenHQ > MAX_XMITBUF_SZ) ? MAX_XMITBUF_SZ : lenHQ;
179         pHalData->sdio_tx_max_len[MID_QUEUE_IDX] = (lenNQ > MAX_XMITBUF_SZ) ? MAX_XMITBUF_SZ : lenNQ;
180         pHalData->sdio_tx_max_len[LOW_QUEUE_IDX] = (lenLQ > MAX_XMITBUF_SZ) ? MAX_XMITBUF_SZ : lenLQ;
181 }
182
183 u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx)
184 {
185         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
186         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
187         u32     deviceId, max_len;
188
189
190         deviceId = ffaddr2deviceId(pdvobjpriv, queue_idx);
191         switch (deviceId) {
192         case WLAN_TX_HIQ_DEVICE_ID:
193                 max_len = pHalData->sdio_tx_max_len[HI_QUEUE_IDX];
194                 break;
195
196         case WLAN_TX_MIQ_DEVICE_ID:
197                 max_len = pHalData->sdio_tx_max_len[MID_QUEUE_IDX];
198                 break;
199
200         case WLAN_TX_LOQ_DEVICE_ID:
201                 max_len = pHalData->sdio_tx_max_len[LOW_QUEUE_IDX];
202                 break;
203
204         default:
205                 max_len = pHalData->sdio_tx_max_len[MID_QUEUE_IDX];
206                 break;
207         }
208
209         return max_len;
210 }
211
212 #ifdef CONFIG_FW_C2H_REG
213 void sd_c2h_hisr_hdl(_adapter *adapter)
214 {
215         u8 c2h_evt[C2H_REG_LEN] = {0};
216         u8 id, seq, plen;
217         u8 *payload;
218
219         if (rtw_hal_c2h_evt_read(adapter, c2h_evt) != _SUCCESS)
220                 goto exit;
221
222         if (rtw_hal_c2h_reg_hdr_parse(adapter, c2h_evt, &id, &seq, &plen, &payload) != _SUCCESS)
223                 goto exit;
224                 
225         if (rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload)) {
226                 /* Handle directly */
227                 rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
228                 goto exit;
229         }
230
231         if (rtw_c2h_reg_wk_cmd(adapter, c2h_evt) != _SUCCESS)
232                 RTW_ERR("%s rtw_c2h_reg_wk_cmd fail\n", __func__);
233
234 exit:
235         return;
236 }
237 #endif
238
239 #endif /* !RTW_HALMAC */