2 ******************************************************************************
6 * @brief ECRNX usb init and management function
8 * Copyright (C) ESWIN 2015-2020
10 ******************************************************************************
13 #include <linux/module.h>
14 #include <linux/kthread.h>
18 #include "ecrnx_utils.h"
19 #include "ecrnx_cmds.h"
20 #include "ecrnx_defs.h"
21 #include "ecrnx_msg_rx.h"
23 #include "ipc_shared.h"
24 #include "ecrnx_events.h"
25 #include "ecrnx_usb.h"
26 #ifdef CONFIG_TEST_ESWIN_USB
29 #ifdef CONFIG_ECRNX_WIFO_CAIL
30 #include "ecrnx_amt.h"
34 #define USB_ADDR_DATA (unsigned int)(0x200)
36 #ifdef CONFIG_ECRNX_SOFTMAC
38 #elif defined CONFIG_ECRNX_FULLMAC
42 #if defined(CONFIG_ECRNX_DEBUGFS_CUSTOM)
43 #include "ecrnx_debugfs_func.h"
46 extern const int nx_txdesc_cnt_msk[];
48 struct vendor_radiotap_hdr {
55 #ifdef CONFIG_WEXT_PRIV
56 extern void priv_copy_data_wakeup(struct ecrnx_hw *ecrnx_hw, struct sk_buff *skb);
60 * @brief: ipc_host_rxdesc_handler: Handle the reception of a Rx Descriptor
61 * Called from general IRQ handler when status %IPC_IRQ_E2A_RXDESC is set
62 * @param {env} pointer to the usb Host environment
63 * @param {skb} received skb data
66 static int usb_host_rxdesc_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
69 // LMAC has triggered an IT saying that a reception has occurred.
70 // Then we first need to check the validity of the current hostbuf, and the validity
71 // of the next hostbufs too, because it is likely that several hostbufs have been
72 // filled within the time needed for this irq handling
73 #ifdef CONFIG_ECRNX_FULLMAC
74 // call the external function to indicate that a RX descriptor is received
75 ret = env->cb.recv_data_ind(env->pthis, skb);
77 // call the external function to indicate that a RX packet is received
78 ret = env->cb.recv_data_ind(env->pthis, skb);
79 #endif //(CONFIG_ECRNX_FULLMAC)
80 //ECRNX_DBG("%s exit!!", __func__);
85 * @brief: usb_host_radar_handler Handle the reception of radar events
86 * @param {env} pointer to the usb Host environment
87 * @param {skb} received skb data
90 static int usb_host_radar_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
94 #ifdef CONFIG_ECRNX_RADAR
95 // LMAC has triggered an IT saying that a radar event has been sent to upper layer.
96 // Then we first need to check the validity of the current msg buf, and the validity
97 // of the next buffers too, because it is likely that several buffers have been
98 // filled within the time needed for this irq handling
99 // call the external function to indicate that a RX packet is received
100 spin_lock(&((struct ecrnx_hw *)env->pthis)->radar.lock);
101 ret = env->cb.recv_radar_ind(env->pthis, skb);
102 spin_unlock(&((struct ecrnx_hw *)env->pthis)->radar.lock);
103 #endif /* CONFIG_ECRNX_RADAR */
108 * @brief: usb_host_unsup_rx_vec_handler Handle the reception of unsupported rx vector
109 * @param {env} pointer to the usb Host environment
110 * @param {skb} received skb data
113 static int usb_host_unsup_rx_vec_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
115 return env->cb.recv_unsup_rx_vec_ind(env->pthis, skb);
119 * @brief: usb_host_msg_handler Handler for firmware message
120 * @param {env} pointer to the usb Host environment
121 * @param {skb} received skb data
124 static int usb_host_msg_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
126 // LMAC has triggered an IT saying that a message has been sent to upper layer.
127 // Then we first need to check the validity of the current msg buf, and the validity
128 // of the next buffers too, because it is likely that several buffers have been
129 // filled within the time needed for this irq handling
130 // call the external function to indicate that a RX packet is received
131 return env->cb.recv_msg_ind(env->pthis, skb->data);
135 * @brief: usb_host_msgack_handler Handle the reception of message acknowledgement
136 * @param {env} pointer to the usb Host environment
137 * @param {skb} received skb data
140 static int usb_host_msgack_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
142 ptr_addr hostid = *(ptr_addr *)skb->data;
146 env->msga2e_hostid = NULL;
147 env->cb.recv_msgack_ind(env->pthis, (void*)hostid);
153 * @brief: usb_host_dbg_handler Handle the reception of Debug event
154 * @param {env} pointer to the usb Host environment
155 * @param {skb} received skb data
158 static int usb_host_dbg_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
160 // LMAC has triggered an IT saying that a DBG message has been sent to upper layer.
161 // Then we first need to check the validity of the current buffer, and the validity
162 // of the next buffers too, because it is likely that several buffers have been
163 // filled within the time needed for this irq handling
164 // call the external function to indicate that a RX packet is received
165 return env->cb.recv_dbg_ind(env->pthis, skb);
169 * @brief: usb_host_tx_cfm_handler Handle the reception of TX confirmation
170 * @param {env} pointer to the usb Host environment
171 * @param {queue_idx} index of the hardware on which the confirmation has been received
172 * @param {user_pos} index of the user position
175 static int usb_host_tx_cfm_handler(struct ipc_host_env_tag *env, struct sk_buff *skb)
178 struct sk_buff *skb_cfm;
179 struct ecrnx_txhdr *txhdr;
181 #ifdef CONFIG_ECRNX_FULLMAC
182 struct tx_cfm_tag *cfm;
184 cfm = (struct tx_cfm_tag *)skb->data;
185 //host_id = cfm->hostid;
186 memcpy((uint8_t *)&host_id, (uint8_t *)cfm->hostid, sizeof(ptr_addr));
191 ECRNX_DBG("%s:hostid(tx_skb):0x%08x, rx_skb: 0x%x \n", __func__, host_id, skb);
192 skb_cfm = (struct sk_buff *)host_id;
193 txhdr = (struct ecrnx_txhdr *)(*((ptr_addr*)skb_cfm->data - 1));
194 memcpy(&txhdr->hw_hdr.cfm, cfm, sizeof(*cfm));
195 #elif defined CONFIG_ECRNX_SOFTMAC
199 return env->cb.send_data_cfm(env->pthis, (void*)txhdr);
202 #ifdef CONFIG_ECRNX_WIFO_CAIL
204 * @brief: usb_host_amt_rx_handler Handle the reception of rx frame
205 * @param {frm_type} received frame type
206 * @param {skb} received skb data
209 void usb_host_amt_rx_handler(uint32_t frm_type, struct sk_buff *skb)
213 ECRNX_DBG("%s enter, frame type: %d!!", __func__, frm_type);
216 ECRNX_ERR("usb_host_amt_rx_handler input param error!! \n!");
220 if (frm_type != USB_FRM_TYPE_RXDESC)
222 skb_pull(skb, SKB_DATA_COM_HD_OFFSET); //delete the frame common header
225 ECRNX_DBG("skb:0x%08x, skb_len:%d, frame type: %d!!", skb->data,skb->len, frm_type);
229 case USB_FRM_TYPE_IWPRIV:
231 /*printk("vif_start:%d, vif_monitor:%d \n", ecrnx_hw->vif_started, ecrnx_hw->monitor_vif);
232 print_hex_dump(KERN_INFO, "iwpriv-cfm:", DUMP_PREFIX_ADDRESS, 32, 1,
233 skb->data, skb->len, false);*/
234 amt_vif.rxlen = skb->len;
235 memset(amt_vif.rxdata, 0, ECRNX_RXSIZE);
236 memcpy(amt_vif.rxdata, skb->data, skb->len);
238 wake_up(&amt_vif.rxdataq);
247 if (need_free && skb) { // free the skb
248 ECRNX_DBG("skb free: 0x%x !! \n", skb);
251 ECRNX_DBG("%s exit!!", __func__);
258 * @brief: usb_host_rx_handler Handle the reception of rx frame
259 * @param {frm_type} received frame type
260 * @param {env} pointer to the usb Host environment
261 * @param {skb} received skb data
264 void usb_host_rx_handler(uint32_t frm_type, struct ipc_host_env_tag *env, struct sk_buff *skb)
268 //ECRNX_DBG("%s enter, frame type: %d!!", __func__, frm_type);
271 ECRNX_ERR("usb_host_rx_handler input param error!! \n!");
275 ((struct ecrnx_hw *)env->pthis)->usb_rx++;
277 if (frm_type != USB_FRM_TYPE_RXDESC)
279 skb_pull(skb, SKB_DATA_COM_HD_OFFSET); //delete the frame common header
282 //ECRNX_DBG("skb:0x%08x, skb_len:%d, frame type: %d!!", skb->data,skb->len, frm_type);
286 case USB_FRM_TYPE_RXDESC:
288 // handle the RX descriptor reception
289 usb_host_rxdesc_handler(env, skb); //just for current only one endpoint test
293 case USB_FRM_TYPE_MSG_ACK:
297 ECRNX_PRINT("MSG_ACK len: 1");
300 ret = usb_host_msgack_handler(env, skb);
304 case USB_FRM_TYPE_MSG:
306 ret = usb_host_msg_handler(env, skb);
310 case USB_FRM_TYPE_TXCFM:
314 ECRNX_ERR("env->pthis ptr error!! \n!");
318 /* add the spinlock which was missed during porting.
319 when skb->len more than 24 and skb contans more than one data cfm.
320 data cfm structure length is 24 byte.
322 spin_lock_bh(&((struct ecrnx_hw *)env->pthis)->tx_lock);
323 while(skb->len > sizeof(struct tx_cfm_tag))
325 ret = usb_host_tx_cfm_handler(env, skb);
326 skb_pull(skb, sizeof(struct tx_cfm_tag));
328 ret = usb_host_tx_cfm_handler(env, skb);
329 spin_unlock_bh(&((struct ecrnx_hw *)env->pthis)->tx_lock);
333 case USB_FRM_TYPE_UNSUP_RX_VEC:
335 // handle the unsupported rx vector reception
336 ret = usb_host_unsup_rx_vec_handler(env, skb);
340 case USB_FRM_TYPE_RADAR:
342 // handle the radar event reception
343 ret = usb_host_radar_handler(env, skb);
347 case USB_FRM_TYPE_TBTT_SEC:
349 env->cb.sec_tbtt_ind(env->pthis);
353 case USB_FRM_TYPE_TBTT_PRIM:
355 env->cb.prim_tbtt_ind(env->pthis);
359 case USB_FRM_TYPE_DBG:
361 ECRNX_DBG("--%s:USB_FRM_TYPE_DBG, len:%d, slave:%s \n", __func__, skb->len, skb->data);
362 ret = usb_host_dbg_handler(env, skb);
365 case USB_FRM_TYPE_IWPRIV:
367 #ifdef CONFIG_WEXT_PRIV
369 struct ecrnx_hw *ecrnx_hw = (struct ecrnx_hw *)env->pthis;
370 struct ecrnx_vif* ecrnx_vif = ecrnx_hw->vif_table[0];
372 printk("vif_start:%d, vif_monitor:%d \n", ecrnx_hw->vif_started, ecrnx_hw->monitor_vif);
373 print_hex_dump(KERN_INFO, "iwpriv-cfm:", DUMP_PREFIX_ADDRESS, 32, 1,
374 skb->data, skb->len, false);
375 ecrnx_vif->rxlen = skb->len;
376 memcpy(ecrnx_vif->rxdata, skb->data, skb->len);
377 ecrnx_vif->rxdatas = 1;
378 wake_up(&ecrnx_vif->rxdataq);
380 priv_copy_data_wakeup((struct ecrnx_hw *)env->pthis, skb);
388 #if defined(CONFIG_ECRNX_DEBUGFS_CUSTOM)
389 case USB_FRM_DEBUG_FS:
391 uint32_t debugfs_type = ((uint32_t*)skb->data)[0];
392 debugfs_resp.debugfs_type = debugfs_type;
395 if((debugfs_type != SLAVE_LOG_LEVEL) && \
396 (debugfs_type < SLAVE_DEBUGFS_MAX)){
398 debugfs_resp.rxlen = skb->len-4;
399 memcpy(debugfs_resp.rxdata, skb->data+4, debugfs_resp.rxlen);
401 ECRNX_DBG("%s - wake_up()\n", __func__);
402 debugfs_resp.rxdatas = 1;
403 wake_up(&debugfs_resp.rxdataq);
414 if (!ret && skb) { // free the skb
415 ECRNX_DBG("skb free: 0x%x, ret: %d!! \n", skb, ret);
418 //ECRNX_DBG("%s exit!!", __func__);
423 * @brief: ecrnx_usb_init Initialize usb interface.
424 * @param {ecrnx_hw} Main driver data
427 u8 ecrnx_usb_init(struct ecrnx_hw *ecrnx_hw)
429 ECRNX_DBG("%s entry!!", __func__);
430 // Save the pointer to the register base
431 ecrnx_hw->ipc_env->pthis = (void*)ecrnx_hw;
433 ECRNX_DBG("%s exit!!", __func__);
438 * @brief: ecrnx_usb_deinit DeInitialize usb interface.
439 * @param {ecrnx_hw} Main driver data
442 void ecrnx_usb_deinit(struct ecrnx_hw *ecrnx_hw)
444 ECRNX_DBG(ECRNX_FN_ENTRY_STR);
446 memset(ecrnx_hw, 0, sizeof(struct ecrnx_hw));