net:wireless:Support eswin usb wifi ECR6600U
[platform/kernel/linux-starfive.git] / drivers / net / wireless / eswin / eswin_port / eswin_utils.c
1 /**
2  ******************************************************************************
3  *
4  * @file eswin_utils.c
5  *
6  *@brief msg and management frame send functions
7  *
8  * Copyright (C) ESWIN 2015-2020
9  *
10  ******************************************************************************
11  */
12
13 #include <linux/dma-mapping.h>
14 #include <linux/etherdevice.h>
15 #include <net/sock.h>
16
17 #include "ecrnx_defs.h"
18 #include "ecrnx_tx.h"
19 #include "ecrnx_msg_tx.h"
20 #ifdef CONFIG_ECRNX_FULLMAC
21 #include "ecrnx_mesh.h"
22 #endif
23 #include "ecrnx_events.h"
24 #include "ecrnx_compat.h"
25
26 #include "eswin_utils.h"
27
28 #if 0
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"
33 #endif
34 #endif
35
36 typedef int (*fn_send_t)(void * buff, int len, int flag);
37
38
39 fn_send_t   ecrnx_host_send;
40
41
42 void ecrnx_send_handle_register(void * fn)
43 {
44         ecrnx_host_send = (fn_send_t)fn;
45 }
46
47
48 int host_send(void *buff, int len, int flag)
49 {
50         //ECRNX_DBG("%s:len:%d,flag %#x \n", __func__, len, flag);
51         return ecrnx_host_send(buff, len, flag);
52 }
53
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)
56 {
57     u32_l tx_flag;
58     //struct ecrnx_txhdr *txhdr = NULL;
59     struct ecrnx_sw_txhdr *sw_txhdr = NULL;
60
61     ecrnx_hw->data_tx++;
62     //send tx desc
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;
65 #if 0
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;
70 #else
71                 user, hw_queue, tx_flag, tx_desc->host.packet_addr, (u32_l)skb);
72         tx_desc->host.packet_addr = (u32_l)skb;
73 #endif
74 #endif
75
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));
82
83     host_send((void*)data, ECRNX_TX_TXDESC_API_ALIGN + sw_txhdr->frame_len,  tx_flag);
84
85 #elif defined(CONFIG_ECRNX_ESWIN_USB)
86     uint8_t *data;
87     struct ecrnx_txhdr *txhdr = (struct ecrnx_txhdr *)skb->data;
88
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));
93
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);
97 #endif
98
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));
110
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);
115 #endif
116         }
117     }
118 #endif
119     return;
120 }
121
122 static inline void ecrnx_bcn_param_send(struct mm_bcn_change_req *req)
123 {
124     if (req->bcn_ptr && req->bcn_len) {
125         host_send((void*)req->bcn_ptr, req->bcn_len, TX_FLAG_MSG_BEACON_IE);
126     }
127 }
128
129 static inline void ecrnx_scanie_param_send(struct scan_start_req *req)
130 {
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);
133     }
134 }
135
136 static inline void ecrnx_scanuie_param_send(struct scanu_start_req *req)
137 {
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);
140     }
141 }
142
143 static inline void ecrnx_apm_param_send(struct apm_start_req *req)
144 {
145     if (req->bcn_addr && req->bcn_len) {
146         host_send((void*)req->bcn_addr, req->bcn_len, TX_FLAG_MSG_SOFTAP_IE);
147     }
148 }
149
150 void ecrnx_msg_send(struct ecrnx_cmd *cmd, uint16_t len)
151 {
152     void *param = cmd->a2e_msg->param;
153     int param_len = cmd->a2e_msg->param_len;
154
155     //cmd->a2e_msg->hostid = (u64_l)cmd;
156     memcpy(cmd->a2e_msg->hostid, &cmd, sizeof(struct ecrnx_cmd *));
157
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);
162             }
163             break;
164         case SCAN_START_REQ:
165             if (param_len >= sizeof(struct scan_start_req)) {
166                 ecrnx_scanie_param_send((struct scan_start_req *)param);
167             }
168             break;
169         case SCANU_START_REQ:
170             if (param_len >= sizeof(struct scanu_start_req)) {
171                 ecrnx_scanuie_param_send((struct scanu_start_req *)param);
172             }
173             break;
174         case APM_START_REQ:
175             if (param_len >= sizeof(struct apm_start_req)) {
176                 ecrnx_apm_param_send((struct apm_start_req *)param);
177             }
178             break;
179         default:
180             break;
181     }
182
183     host_send((void*)cmd->a2e_msg, len, TX_FLAG_MSG_E);
184 }
185
186 const struct ecrnx_element *cfg80211_find_ecrnx_elem(u8 eid, const u8 *ies, int len)
187 {
188     const struct ecrnx_element *elem;
189     for_each_ecrnx_element(elem, ies, len) {
190         if (elem->id == (eid))
191             return elem;
192     }
193     return NULL;
194 }