net:wireless:Support eswin usb wifi ECR6600U
[platform/kernel/linux-starfive.git] / drivers / net / wireless / eswin / sdio / ecrnx_sdio.c
1 /**
2  ******************************************************************************
3  *
4  * @file ecrnx_sdio.c
5  *
6  * @brief ECRNX sdio init and management function
7  *
8  * Copyright (C) ESWIN 2015-2020
9  *
10  ******************************************************************************
11  */
12
13 #include <linux/module.h>
14 #include <linux/kthread.h>
15 #include <linux/mmc/sdio_func.h>
16 #include <linux/mmc/sdio_ids.h>
17 #include "core.h"
18 //#include "debug.h"
19 #include "ecrnx_utils.h"
20 #include "ecrnx_cmds.h"
21 #include "ecrnx_defs.h"
22 #include "ecrnx_msg_rx.h"
23 #include "ipc_host.h"
24 #include "ipc_shared.h"
25 #include "ecrnx_events.h"
26 #include "ecrnx_sdio.h"
27 #ifdef CONFIG_TEST_ESWIN_SDIO
28 #include "debug.h"
29 #endif
30 #ifdef CONFIG_ECRNX_WIFO_CAIL
31 #include "ecrnx_amt.h"
32 #endif
33
34
35 #define SDIO_ADDR_DATA                  (unsigned int)(0x200)
36
37 #ifdef CONFIG_ECRNX_SOFTMAC
38 #define FW_STR  "lmac"
39 #elif defined CONFIG_ECRNX_FULLMAC
40 #define FW_STR  "fmac"
41 #endif
42
43 sdio_rx_buf_t sdio_rx_buff;
44
45 extern const int nx_txdesc_cnt_msk[];
46
47 struct vendor_radiotap_hdr {
48     u8 oui[3];
49     u8 subns;
50     u16 len;
51     u8 data[];
52 };
53
54 /**
55  * @brief: sdio_rx_buf_init: Initialization the sdio rx buffer
56  * @param {void} void 
57  * @return: none
58  */
59 static void sdio_rx_buf_init(void)
60 {
61     uint8_t i = 0;
62     ECRNX_DBG("%s entry!!", __func__);
63     memset(&sdio_rx_buff, 0, sizeof(sdio_rx_buf_t));
64
65     for(i = 0; i < SDIO_RXBUF_CNT; i++)
66     {
67         sdio_rx_buff.ecrnx_sdio_rx_skb[i].skb = dev_alloc_skb(SDIO_RXBUF_SIZE);
68         skb_put(sdio_rx_buff.ecrnx_sdio_rx_skb[i].skb, SDIO_RXBUF_SIZE);
69     }
70 #ifdef CONFIG_TEST_ESWIN_SDIO
71     sdio_rx_tx_test_schedule();
72 #endif
73     ECRNX_DBG("%s exit!!", __func__);
74 }
75
76 /**
77  * @brief: sdio_rx_buf_deinit: Deinitialization the sdio rx buffer
78  * @param {void} void 
79  * @return: none
80  */
81 static void sdio_rx_buf_deinit(void)
82 {
83     uint8_t i = 0;
84
85     memset(&sdio_rx_buff, 0, sizeof(sdio_rx_buf_t));
86
87     for(i = 0; i < SDIO_RXBUF_CNT; i++)
88     {
89         if(sdio_rx_buff.ecrnx_sdio_rx_skb[i].skb)
90         {
91             dev_kfree_skb(sdio_rx_buff.ecrnx_sdio_rx_skb[i].skb);
92         }
93     }
94 }
95
96 /**
97  * @brief: sdio_rx_buf_push: push a skb element to sdio rx buffer
98  * @param {skb}  skb data need to push
99  * @param {recv_len}  skb data length
100  * @return: sk_buff
101  */
102 struct sk_buff * sdio_rx_buf_push(struct sk_buff *skb, uint16_t recv_len)
103 {
104     uint8_t index = 0;
105
106     ECRNX_DBG("%s enter, skb: %d, skb_data:%d, skb_len:%d", __func__, skb, skb->data, recv_len);
107     if(atomic_read(&sdio_rx_buff.suspend))
108     {
109         return NULL;
110     }
111
112     if(sdio_rx_buff.sdio_host_rx_buff_used >= SDIO_RXBUF_CNT)
113     {
114         ECRNX_PRINT("no enough space \n");
115         return NULL;
116     }
117
118     if((!skb) || (!recv_len) || (recv_len > SDIO_RXBUF_SIZE))
119     {
120         ECRNX_PRINT("rx data is error \n");
121         return NULL;
122     }
123
124     atomic_set(&sdio_rx_buff.suspend, 1);
125
126     do
127     {
128         if(!sdio_rx_buff.ecrnx_sdio_rx_skb[index].flag)  //find a index to store the data
129         {
130             break;
131         }
132         index++;
133     }while(index < SDIO_RXBUF_CNT);
134
135     sdio_rx_buff.sdio_host_rx_buff_used++;
136     sdio_rx_buff.ecrnx_sdio_rx_skb[index].flag = true;
137     sdio_rx_buff.ecrnx_sdio_rx_skb[index].data_len = recv_len;
138     memcpy(sdio_rx_buff.ecrnx_sdio_rx_skb[index].skb->data, skb->data, recv_len);
139     atomic_set(&sdio_rx_buff.suspend, 0);
140
141     return sdio_rx_buff.ecrnx_sdio_rx_skb[index].skb;
142 }
143
144 /**
145  * @brief: sdio_rx_buf_pop: pop a skb element from sdio rx buffer
146  * @param {void} 
147  * @return: sk_buff
148  */
149 struct sk_buff* sdio_rx_buf_pop(void)
150 {
151     uint8_t index = 0;
152     struct sk_buff *skb= NULL;
153
154     if(atomic_read(&sdio_rx_buff.suspend))
155     {
156         ECRNX_PRINT("sdio suspend! \n");
157         return NULL;
158     }
159
160     if(sdio_rx_buff.sdio_host_rx_buff_used <= 0)
161     {
162         ECRNX_PRINT("no data in memory \n");
163         return NULL;
164     }
165
166     atomic_set(&sdio_rx_buff.suspend, 1);
167
168     do
169     {
170         if(sdio_rx_buff.ecrnx_sdio_rx_skb[index].flag)  //find a index to pop the data
171         {
172             break;
173         }
174         index++;
175     }while(index < SDIO_RXBUF_CNT);
176
177     if(index != SDIO_RXBUF_CNT)
178     {
179         skb = sdio_rx_buff.ecrnx_sdio_rx_skb[index].skb;
180         sdio_rx_buff.ecrnx_sdio_rx_skb[index].flag = false;
181         sdio_rx_buff.sdio_host_rx_buff_used = (sdio_rx_buff.sdio_host_rx_buff_used > 0)? sdio_rx_buff.sdio_host_rx_buff_used-1: 0;
182     }
183     atomic_set(&sdio_rx_buff.suspend, 0);
184
185     return skb;
186 }
187
188 /**
189  * @brief: ipc_host_rxdesc_handler: Handle the reception of a Rx Descriptor
190  *  Called from general IRQ handler when status %IPC_IRQ_E2A_RXDESC is set
191  * @param {env} pointer to the sdio Host environment
192  * @param {skb} received skb data
193  * @return: none
194  */
195 static int sdio_host_rxdesc_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
196 {
197         u8 ret = 0;
198     // LMAC has triggered an IT saying that a reception has occurred.
199     // Then we first need to check the validity of the current hostbuf, and the validity
200     // of the next hostbufs too, because it is likely that several hostbufs have been
201     // filled within the time needed for this irq handling
202 #ifdef CONFIG_ECRNX_FULLMAC
203     // call the external function to indicate that a RX descriptor is received
204     ret = env->cb.recv_data_ind(env->pthis, skb);
205 #else
206     // call the external function to indicate that a RX packet is received
207     ret = env->cb.recv_data_ind(env->pthis, skb);
208 #endif //(CONFIG_ECRNX_FULLMAC)
209     ECRNX_DBG("%s exit!!", __func__);
210         return ret;
211 }
212
213 /**
214  * @brief: sdio_host_radar_handler  Handle the reception of radar events
215  * @param {env} pointer to the sdio Host environment
216  * @param {skb} received skb data
217  * @return: none
218  */
219 static int sdio_host_radar_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
220 {
221     int ret = 0;
222     
223 #ifdef CONFIG_ECRNX_RADAR
224     // LMAC has triggered an IT saying that a radar event has been sent to upper layer.
225     // Then we first need to check the validity of the current msg buf, and the validity
226     // of the next buffers too, because it is likely that several buffers have been
227     // filled within the time needed for this irq handling
228     // call the external function to indicate that a RX packet is received
229     spin_lock(&((struct ecrnx_hw *)env->pthis)->radar.lock);
230     ret = env->cb.recv_radar_ind(env->pthis, skb);
231     spin_unlock(&((struct ecrnx_hw *)env->pthis)->radar.lock);
232 #endif /* CONFIG_ECRNX_RADAR */
233     return ret;
234 }
235
236 /**
237  * @brief: sdio_host_unsup_rx_vec_handler  Handle the reception of unsupported rx vector
238  * @param {env} pointer to the sdio Host environment
239  * @param {skb} received skb data
240  * @return: none
241  */
242 static int sdio_host_unsup_rx_vec_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
243 {
244     return env->cb.recv_unsup_rx_vec_ind(env->pthis, skb);
245 }
246
247 /**
248  * @brief: sdio_host_msg_handler  Handler for firmware message
249  * @param {env} pointer to the sdio Host environment
250  * @param {skb} received skb data
251  * @return: none
252  */
253 static int sdio_host_msg_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
254 {
255     // LMAC has triggered an IT saying that a message has been sent to upper layer.
256     // Then we first need to check the validity of the current msg buf, and the validity
257     // of the next buffers too, because it is likely that several buffers have been
258     // filled within the time needed for this irq handling
259     // call the external function to indicate that a RX packet is received
260     return env->cb.recv_msg_ind(env->pthis, skb->data);
261 }
262
263 /**
264  * @brief: sdio_host_msgack_handler  Handle the reception of message acknowledgement
265  * @param {env} pointer to the sdio Host environment
266  * @param {skb} received skb data
267  * @return: none
268  */
269 static int sdio_host_msgack_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
270 {
271     uint64_t hostid = *(uint64_t *)skb->data;
272
273     ASSERT_ERR(hostid);
274
275     env->msga2e_hostid = NULL;
276     env->cb.recv_msgack_ind(env->pthis, hostid);
277
278     return 0;
279 }
280
281 /**
282  * @brief: sdio_host_dbg_handler  Handle the reception of Debug event
283  * @param {env} pointer to the sdio Host environment
284  * @param {skb} received skb data
285  * @return: none
286  */
287 static int sdio_host_dbg_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
288 {
289     // LMAC has triggered an IT saying that a DBG message has been sent to upper layer.
290     // Then we first need to check the validity of the current buffer, and the validity
291     // of the next buffers too, because it is likely that several buffers have been
292     // filled within the time needed for this irq handling
293     // call the external function to indicate that a RX packet is received
294     return env->cb.recv_dbg_ind(env->pthis, skb);
295 }
296
297 /**
298  * @brief: sdio_host_tx_cfm_handler  Handle the reception of TX confirmation
299  * @param {env} pointer to the sdio Host environment
300  * @param {queue_idx} index of the hardware on which the confirmation has been received
301  * @param {user_pos} index of the user position
302  * @return: none
303  */
304 static int sdio_host_tx_cfm_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
305 {
306     ptr_addr host_id;
307     struct sk_buff *skb_cfm;
308     struct ecrnx_txhdr *txhdr;
309
310     ECRNX_DBG("%s, skb: 0x%08x \n", __func__, skb);
311 #ifdef CONFIG_ECRNX_FULLMAC
312     struct tx_cfm_tag *cfm;
313
314     cfm = (struct tx_cfm_tag *)skb->data;
315     memcpy((uint8_t *)&host_id, (uint8_t *)cfm->hostid, sizeof(ptr_addr));
316     ECRNX_DBG("--%s--hostid 0x%08x, skb: 0x%x \n", __func__, host_id, skb);
317     if (host_id == 0) {
318         return 0;
319     }
320
321     skb_cfm = (struct sk_buff *)host_id;
322     txhdr = (struct ecrnx_txhdr *)skb_cfm->data;
323     memcpy(&txhdr->hw_hdr.cfm, cfm, sizeof(*cfm));
324 #elif defined CONFIG_ECRNX_SOFTMAC
325     //TODO:
326 #endif
327
328     return env->cb.send_data_cfm(env->pthis, host_id);
329     //return 0;
330 }
331
332 #ifdef CONFIG_ECRNX_WIFO_CAIL
333 /**
334  * @brief: sdio_host_rx_handler  Handle the reception of rx frame
335  * @param {frm_type} received frame type
336  * @param {skb} received skb data
337  * @return: none
338 **/
339 void sdio_host_amt_rx_handler(uint32_t frm_type, struct sk_buff *skb)
340 {
341     int need_free = 0;
342
343     ECRNX_PRINT("%s enter, frame type: %d, len %d.!!", __func__, frm_type, skb->len);
344     if (frm_type != SDIO_FRM_TYPE_RXDESC)
345     {
346         skb_pull(skb, SKB_DATA_COM_HD_OFFSET); //delete the frame common header
347     }
348
349     switch (frm_type)
350     {
351                 case SDIO_FRM_TYPE_IWPRIV:
352         {
353             /*print_hex_dump(KERN_INFO, "iwpriv-cfm:", DUMP_PREFIX_ADDRESS, 32, 1,
354                         skb->data, skb->len, false);*/
355             amt_vif.rxlen = skb->len;
356                         memset(amt_vif.rxdata, 0, ECRNX_RXSIZE);
357             memcpy(amt_vif.rxdata, skb->data, skb->len > ECRNX_RXSIZE ? ECRNX_RXSIZE : skb->len);
358             amt_vif.rxdatas = 1;
359             wake_up(&amt_vif.rxdataq);
360                         need_free = 1;
361             break;
362         }
363
364         default:
365                         need_free = 1;
366             break;
367     }
368
369     if (need_free && skb) { // free the skb
370                 ECRNX_DBG("skb free: 0x%x, \n", skb);
371         dev_kfree_skb(skb);
372     }
373     ECRNX_DBG("%s exit!!", __func__);
374     return;
375 }
376 #endif
377
378 /**
379  * @brief: sdio_host_rx_handler  Handle the reception of rx frame
380  * @param {frm_type} received frame type
381  * @param {env} pointer to the sdio Host environment
382  * @param {skb} received skb data
383  * @return: none
384  */
385 void sdio_host_rx_handler(uint32_t frm_type, struct ipc_host_env_tag *env, struct sk_buff *skb)
386 {
387     int ret = 1;
388
389     ECRNX_DBG("%s enter, frame type: %d!!", __func__, frm_type);
390     if (frm_type != SDIO_FRM_TYPE_RXDESC)
391     {
392         skb_pull(skb, SKB_DATA_COM_HD_OFFSET); //delete the frame common header
393     }
394
395     switch (frm_type)
396     {
397         case SDIO_FRM_TYPE_RXDESC:
398         {
399             sdio_host_rxdesc_handler(env, skb);
400             break;
401         }
402
403         case SDIO_FRM_TYPE_MSG_ACK:
404         {
405             ret = sdio_host_msgack_handler(env, skb);
406             break;
407         }
408
409         case SDIO_FRM_TYPE_MSG:
410         {
411             ret = sdio_host_msg_handler(env, skb);
412             break;
413         }
414
415         case SDIO_FRM_TYPE_TXCFM:
416         {
417             /* add the spinlock which was missed during porting. */
418             spin_lock_bh(&((struct ecrnx_hw *)env->pthis)->tx_lock);
419             while(skb->len > sizeof(struct tx_cfm_tag))
420             {
421                 ret = sdio_host_tx_cfm_handler(env, skb);
422                 skb_pull(skb, sizeof(struct tx_cfm_tag));
423             }
424             ret = sdio_host_tx_cfm_handler(env, skb);
425             spin_unlock_bh(&((struct ecrnx_hw *)env->pthis)->tx_lock);
426             break;
427         }
428
429         case SDIO_FRM_TYPE_UNSUP_RX_VEC:
430         {
431             // handle the unsupported rx vector reception
432             ret = sdio_host_unsup_rx_vec_handler(env, skb);
433             break;
434         }
435
436         case SDIO_FRM_TYPE_RADAR:
437         {
438             // handle the radar event reception
439             ret = sdio_host_radar_handler(env, skb);
440             break;
441         }
442
443         case SDIO_FRM_TYPE_TBTT_SEC:
444         {
445             env->cb.sec_tbtt_ind(env->pthis);
446             break;
447         }
448
449         case SDIO_FRM_TYPE_TBTT_PRIM:
450         {
451             env->cb.prim_tbtt_ind(env->pthis);
452             break;
453         }
454
455         case SDIO_FRM_TYPE_DBG:
456         {
457             ret = sdio_host_dbg_handler(env, skb);
458             break;
459         }
460
461         case SDIO_FRM_TYPE_UPDATE:
462         {
463             ret = 0;
464             break;
465         }
466         default:
467                 ret = 0;
468             break;
469     }
470
471     if (!ret && skb) { // free the skb
472         ECRNX_DBG("skb free: 0x%x, ret: %d!! \n", skb, ret);
473         dev_kfree_skb(skb);
474     }
475     ECRNX_DBG("%s exit!!", __func__);
476     return;
477 }
478
479 /**
480  * @brief: rcv_skb_convert  convert the sdio received skb to the ecrnx handled skb.
481  * @param {src_rxu_state} received rxu state in skb
482  * @param {src_rxu_state} received rx header in skb
483  * @param {src_rxu_state} handled hw rxhdr in skb
484  * @param {src_rxu_state} handled rx desc tag  in skb
485  * @return: u8
486  */
487 u8 rcv_skb_convert(struct rxu_stat_mm* src_rxu_state, \
488                 struct rx_hd* src_rx_hd, \
489                 struct sk_buff *skb, \
490                 struct hw_rxhdr* dst_hw_rxhdr,\
491                 struct rxdesc_tag* dst_rxdesc_tag)
492 {
493     ECRNX_DBG("%s enter!!", __func__);
494 #if 0
495     uint16_t index = 0;
496
497     if (!skb || !skb->data){
498         ECRNX_PRINT("RX data invalid \n");
499         return -1;
500     }
501
502     //copy the rxu state and rx header, repush process need to used them
503     memcpy(src_rxu_state, skb->data, sizeof(struct rxu_stat_mm));
504     memcpy(src_rx_hd, skb->data + sizeof(struct rxu_stat_mm), sizeof(struct rx_hd));
505
506     /*copy the hw vector and rxu state */
507     memcpy(dst_hw_rxhdr, skb->data + sizeof(struct rxu_stat_mm), sizeof(struct rx_hd));
508     memcpy(&dst_hw_rxhdr->phy_info, \
509         skb->data + SKB_DATA_TAG_OFFSET, \
510         sizeof(struct rxu_stat_mm) - SKB_DATA_TAG_OFFSET);
511
512     memcpy(dst_rxdesc_tag, skb->data + SKB_DATA_COM_HD_OFFSET + 2, sizeof(struct rxdesc_tag)); //two byte msdu_mode
513     /*recove the hdr to skb data*/
514     skb_pull(skb, SKB_DATA_HD_OFFSET); //delete the frame type and amsdu flag
515     skb_push(skb, sizeof(struct hw_rxhdr));
516     memcpy(skb->data, dst_hw_rxhdr, sizeof(struct hw_rxhdr)); //put hw header to skb
517     skb_push(skb, sizeof(struct rxdesc_tag));
518     memcpy(skb->data, dst_rxdesc_tag, sizeof(struct rxdesc_tag)); //put rx desc tag to skb
519
520     for(index = 0; index < sizeof(struct hw_rxhdr) + sizeof(struct rxdesc_tag); index++)
521     {
522         ECRNX_DBG("0x%x ", skb->data[index]);
523     }
524 #endif
525     ECRNX_DBG("%s exit!!", __func__);
526     return 0;
527 }
528
529 /**
530  * @brief: ecrnx_sdio_init  Initialize sdio interface.
531  * @param {ecrnx_hw} Main driver data
532  * @return: u8
533  */
534 u8 ecrnx_sdio_init(struct ecrnx_hw *ecrnx_hw)
535 {
536     ECRNX_DBG("%s entry!!", __func__);
537     // Save the pointer to the register base
538     ecrnx_hw->ipc_env->pthis = (void*)ecrnx_hw;
539     
540 #ifdef CONFIG_TEST_ESWIN_SDIO
541     ecrnx_hw_set((void*)ecrnx_hw);
542 #endif
543     ECRNX_DBG("%s exit!!", __func__);
544     return 0;
545 }
546
547 /**
548  * @brief: ecrnx_sdio_deinit  DeInitialize sdio interface.
549  * @param {ecrnx_hw} Main driver data
550  * @return: none
551  */
552 void ecrnx_sdio_deinit(struct ecrnx_hw *ecrnx_hw)
553 {
554     ECRNX_DBG(ECRNX_FN_ENTRY_STR);
555
556     sdio_rx_buf_deinit();
557     memset(ecrnx_hw, 0, sizeof(struct ecrnx_hw));
558     memset(&sdio_rx_buff, 0, sizeof(sdio_rx_buf_t));
559 }