2 ******************************************************************************
6 *@brief msg and management frame send functions
8 * Copyright (C) ESWIN 2015-2020
10 ******************************************************************************
13 #include <linux/dma-mapping.h>
14 #include <linux/etherdevice.h>
17 #include "ecrnx_defs.h"
19 #include "ecrnx_msg_tx.h"
20 #ifdef CONFIG_ECRNX_FULLMAC
21 #include "ecrnx_mesh.h"
23 #include "ecrnx_events.h"
24 #include "ecrnx_compat.h"
26 #include "eswin_utils.h"
29 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
30 #include "sdio_host_interface.h"
31 #elif defined(CONFIG_ECRNX_ESWIN_USB)
32 #include "usb_host_interface.h"
36 typedef int (*fn_send_t)(void * buff, int len, int flag);
39 fn_send_t ecrnx_host_send;
42 void ecrnx_send_handle_register(void * fn)
44 ecrnx_host_send = (fn_send_t)fn;
48 int host_send(void *buff, int len, int flag)
50 //ECRNX_DBG("%s:len:%d,flag %#x \n", __func__, len, flag);
51 return ecrnx_host_send(buff, len, flag);
54 void ecrnx_frame_send(struct ecrnx_hw *ecrnx_hw, struct txdesc_api *tx_desc,
55 struct sk_buff *skb, int hw_queue, int user)
58 //struct ecrnx_txhdr *txhdr = NULL;
59 struct ecrnx_sw_txhdr *sw_txhdr = NULL;
63 tx_flag = ((user << FLAG_TXDESC_USER_SHIFT) & FLAG_TXDESC_USER_MASK) | ((hw_queue << FLAG_TXDESC_QUEUE_SHIFT) & FLAG_TXDESC_QUEUE_MASK);
64 tx_flag |= TX_FLAG_TX_DESC & FLAG_MSG_TYPE_MASK;
66 ECRNX_DBG("%s, user %d, queue %d, flag %#x, hostid 0x%08x, skb 0x%08x\n", __func__,
67 #ifdef CONFIG_ECRNX_SPLIT_TX_BUF
68 user, hw_queue, tx_flag, tx_desc->host.packet_addr[0], (u32_l)skb);
69 tx_desc->host.packet_addr[0] = (u32_l)skb;
71 user, hw_queue, tx_flag, tx_desc->host.packet_addr, (u32_l)skb);
72 tx_desc->host.packet_addr = (u32_l)skb;
76 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
77 uint8_t *data = skb->data;
78 sw_txhdr = container_of(tx_desc, struct ecrnx_sw_txhdr, desc);
79 data += sw_txhdr->offset;
80 data -= ECRNX_TX_TXDESC_API_ALIGN;
81 memcpy(data, tx_desc, sizeof(struct txdesc_api));
83 host_send((void*)data, ECRNX_TX_TXDESC_API_ALIGN + sw_txhdr->frame_len, tx_flag);
85 #elif defined(CONFIG_ECRNX_ESWIN_USB)
87 struct ecrnx_txhdr *txhdr = (struct ecrnx_txhdr *)skb->data;
89 sw_txhdr = txhdr->sw_hdr;
90 skb_pull(skb, sw_txhdr->offset - ECRNX_TX_TXDESC_API_ALIGN - sizeof(u32_l));
91 memcpy(skb->data, (char*)&tx_flag, sizeof(u32_l));
92 memcpy((uint8_t *)skb->data + sizeof(u32_l), (char*)tx_desc, sizeof(struct txdesc_api));
94 data = skb->data - sizeof(ptr_addr);
95 memcpy(data, (char*)&txhdr, sizeof(void *)); //store the ecrnx thhdr to the skb, cfm need use it
96 host_send((void *)skb, skb->len, tx_flag);
99 #ifdef CONFIG_ECRNX_AMSDUS_TX
100 //send amsdu sub frame
101 if (sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU) {
102 struct ecrnx_amsdu_txhdr *amsdu_txhdr;
103 printk("...........amsdu tx\n");
104 list_for_each_entry(amsdu_txhdr, &sw_txhdr->amsdu.hdrs, list) {
105 printk("...........amsdu tx: %x, %u\n", amsdu_txhdr->send_pos, amsdu_txhdr->map_len);
106 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
107 host_send((void*)amsdu_txhdr->send_pos, amsdu_txhdr->map_len, tx_flag);
108 #elif defined(CONFIG_ECRNX_ESWIN_USB)
109 struct sk_buff *amsdu_skb = dev_alloc_skb(amsdu_txhdr->map_len + sizeof(int));
111 memcpy(amsdu_skb->data, &tx_flag, sizeof(int));
112 memcpy((char*)amsdu_skb->data + sizeof(int), amsdu_txhdr->send_pos, amsdu_txhdr->map_len);
113 amsdu_skb->len = amsdu_txhdr->map_len + sizeof(int);
114 host_send((void *)amsdu_skb, amsdu_skb->len, tx_flag);
122 static inline void ecrnx_bcn_param_send(struct mm_bcn_change_req *req)
124 if (req->bcn_ptr && req->bcn_len) {
125 host_send((void*)req->bcn_ptr, req->bcn_len, TX_FLAG_MSG_BEACON_IE);
129 static inline void ecrnx_scanie_param_send(struct scan_start_req *req)
131 if (req->add_ies && req->add_ie_len) {
132 host_send((void*)req->add_ies, req->add_ie_len, TX_FLAG_MSG_SCAN_IE);
136 static inline void ecrnx_scanuie_param_send(struct scanu_start_req *req)
138 if (req->add_ies && req->add_ie_len) {
139 host_send((void*)req->add_ies, req->add_ie_len, TX_FLAG_MSG_SCANU_IE);
143 static inline void ecrnx_apm_param_send(struct apm_start_req *req)
145 if (req->bcn_addr && req->bcn_len) {
146 host_send((void*)req->bcn_addr, req->bcn_len, TX_FLAG_MSG_SOFTAP_IE);
150 void ecrnx_msg_send(struct ecrnx_cmd *cmd, uint16_t len)
152 void *param = cmd->a2e_msg->param;
153 int param_len = cmd->a2e_msg->param_len;
155 //cmd->a2e_msg->hostid = (u64_l)cmd;
156 memcpy(cmd->a2e_msg->hostid, &cmd, sizeof(struct ecrnx_cmd *));
158 switch (cmd->a2e_msg->id) {
159 case MM_BCN_CHANGE_REQ:
160 if (param_len >= sizeof(struct mm_bcn_change_req)) {
161 ecrnx_bcn_param_send((struct mm_bcn_change_req *)param);
165 if (param_len >= sizeof(struct scan_start_req)) {
166 ecrnx_scanie_param_send((struct scan_start_req *)param);
169 case SCANU_START_REQ:
170 if (param_len >= sizeof(struct scanu_start_req)) {
171 ecrnx_scanuie_param_send((struct scanu_start_req *)param);
175 if (param_len >= sizeof(struct apm_start_req)) {
176 ecrnx_apm_param_send((struct apm_start_req *)param);
183 host_send((void*)cmd->a2e_msg, len, TX_FLAG_MSG_E);
186 const struct ecrnx_element *cfg80211_find_ecrnx_elem(u8 eid, const u8 *ies, int len)
188 const struct ecrnx_element *elem;
189 for_each_ecrnx_element(elem, ies, len) {
190 if (elem->id == (eid))