1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "net_bdh_adpater.h"
10 #include <net/cfg80211.h>
11
12 #include <securec.h>
13
14 #include "eapol.h"
15
16 #define HDF_LOG_TAG BDH6Driver
17
18 struct net_device *g_linux_netdev = NULL;
19 struct wiphy *g_linux_wiphy = NULL;
20
set_krn_netdev(struct net_device * netdev)21 void set_krn_netdev(struct net_device *netdev)
22 {
23 g_linux_netdev = (struct net_device *)netdev;
24 }
25
get_krn_netdev(void)26 struct net_device* get_krn_netdev(void)
27 {
28 return g_linux_netdev;
29 }
30
get_krn_wiphy(void)31 struct wiphy* get_krn_wiphy(void)
32 {
33 return g_linux_wiphy;
34 }
35
set_krn_wiphy(struct wiphy * pwiphy)36 void set_krn_wiphy(struct wiphy *pwiphy)
37 {
38 g_linux_wiphy = (struct wiphy *)pwiphy;
39 }
40
41
hdf_bdh6_netdev_init(struct NetDevice * netDev)42 int32_t hdf_bdh6_netdev_init(struct NetDevice *netDev)
43 {
44 HDF_LOGE("%s: start...", __func__);
45 if (netDev == NULL) {
46 HDF_LOGE("%s: netDev null!", __func__);
47 return HDF_FAILURE;
48 }
49
50 HDF_LOGE("%s: netDev->name:%s\n", __func__, netDev->name);
51 netDev->netDeviceIf = wal_get_net_dev_ops();
52 CreateEapolData(netDev);
53
54 return HDF_SUCCESS;
55 }
56
hdf_bdh6_netdev_deinit(struct NetDevice * netDev)57 void hdf_bdh6_netdev_deinit(struct NetDevice *netDev)
58 {
59 HDF_LOGE("%s: start...", __func__);
60 (void)netDev;
61 }
62
hdf_bdh6_netdev_open(struct NetDevice * netDev)63 int32_t hdf_bdh6_netdev_open(struct NetDevice *netDev)
64 {
65 int32_t retVal = 0;
66 const int idx0 = 0, idx1 = 1, idx2 = 2, idx3 = 3, idx4 = 4, idx5 = 5;
67 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
68
69 if (netdev == NULL) {
70 HDF_LOGE("%s: netDev null!", __func__);
71 return HDF_FAILURE;
72 }
73
74 HDF_LOGE("%s: ndo_stop...", __func__);
75 retVal = (int32_t)dhd_ops_pri.ndo_stop(netdev);
76 if (retVal < 0) {
77 HDF_LOGE("%s: hdf net device stop failed! ret = %d", __func__, retVal);
78 }
79
80 retVal = (int32_t)dhd_ops_pri.ndo_open(netdev);
81 if (retVal < 0) {
82 }
83
84 netDev->ieee80211Ptr = netdev->ieee80211_ptr;
85 if (netDev->ieee80211Ptr == NULL) {
86 }
87
88 // update mac addr to NetDevice object
89 memcpy_s(netDev->macAddr, MAC_ADDR_SIZE, netdev->dev_addr, netdev->addr_len);
90 HDF_LOGE("%s: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
91 netDev->macAddr[idx0], netDev->macAddr[idx1], netDev->macAddr[idx2],
92 netDev->macAddr[idx3], netDev->macAddr[idx4], netDev->macAddr[idx5]);
93
94 return retVal;
95 }
96
hdf_bdh6_netdev_stop(struct NetDevice * netDev)97 int32_t hdf_bdh6_netdev_stop(struct NetDevice *netDev)
98 {
99 int32_t retVal = 0;
100 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
101
102 HDF_LOGE("%s: start...", __func__);
103
104 if (netdev == NULL) {
105 HDF_LOGE("%s: netDev null!", __func__);
106 return HDF_FAILURE;
107 }
108
109 retVal = (int32_t)dhd_ops_pri.ndo_stop(netdev);
110 if (retVal < 0) {
111 HDF_LOGE("%s: hdf net device stop failed! ret = %d", __func__, retVal);
112 }
113
114 return retVal;
115 }
116
hdf_bdh6_netdev_xmit(struct NetDevice * netDev,NetBuf * netBuff)117 int32_t hdf_bdh6_netdev_xmit(struct NetDevice *netDev, NetBuf *netBuff)
118 {
119 int32_t retVal = 0;
120 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
121
122 if (netdev == NULL || netBuff == NULL) {
123 HDF_LOGE("%s: netdev or netBuff null!", __func__);
124 return HDF_FAILURE;
125 }
126
127 retVal = (int32_t)dhd_ops_pri.ndo_start_xmit((struct sk_buff *)netBuff, netdev);
128 if (retVal < 0) {
129 HDF_LOGE("%s: hdf net device xmit failed! ret = %d", __func__, retVal);
130 }
131
132 return retVal;
133 }
134
hdf_bdh6_netdev_ioctl(struct NetDevice * netDev,IfReq * req,int32_t cmd)135 int32_t hdf_bdh6_netdev_ioctl(struct NetDevice *netDev, IfReq *req, int32_t cmd)
136 {
137 int32_t retVal = 0;
138 struct ifreq dhd_req = {0};
139 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
140
141 HDF_LOGE("%s: start...", __func__);
142
143 if (netdev == NULL || req == NULL) {
144 HDF_LOGE("%s: netdev or req null!", __func__);
145 return HDF_FAILURE;
146 }
147
148 dhd_req.ifr_ifru.ifru_data = req->ifrData;
149
150 retVal = (int32_t)dhd_ops_pri.ndo_do_ioctl(netdev, &dhd_req, cmd);
151 if (retVal < 0) {
152 HDF_LOGE("%s: hdf net device ioctl failed! ret = %d", __func__, retVal);
153 }
154
155 return retVal;
156 }
157
hdf_bdh6_netdev_setmacaddr(struct NetDevice * netDev,unsigned char * addr)158 int32_t hdf_bdh6_netdev_setmacaddr(struct NetDevice *netDev, unsigned char *addr)
159 {
160 int32_t retVal = 0;
161 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
162
163 HDF_LOGE("%s: start...", __func__);
164
165 if (netdev == NULL || addr == NULL) {
166 HDF_LOGE("%s: netDev or addr null!", __func__);
167 return HDF_FAILURE;
168 }
169
170 retVal = (int32_t)dhd_ops_pri.ndo_set_mac_address(netdev, addr);
171 if (retVal < 0) {
172 HDF_LOGE("%s: hdf net device setmacaddr failed! ret = %d", __func__, retVal);
173 }
174
175 return retVal;
176 }
177
hdf_bdh6_netdev_getstats(struct NetDevice * netDev)178 struct NetDevStats *hdf_bdh6_netdev_getstats(struct NetDevice *netDev)
179 {
180 static struct NetDevStats devStat = {0};
181 struct net_device_stats *kdevStat = NULL;
182 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
183
184 HDF_LOGE("%s: start...", __func__);
185
186 if (netdev == NULL) {
187 HDF_LOGE("%s: netDev null!", __func__);
188 return NULL;
189 }
190
191 kdevStat = dhd_ops_pri.ndo_get_stats(netdev);
192 if (kdevStat == NULL) {
193 HDF_LOGE("%s: ndo_get_stats return null!", __func__);
194 return NULL;
195 }
196
197 devStat.rxPackets = kdevStat->rx_packets;
198 devStat.txPackets = kdevStat->tx_packets;
199 devStat.rxBytes = kdevStat->rx_bytes;
200 devStat.txBytes = kdevStat->tx_bytes;
201 devStat.rxErrors = kdevStat->rx_errors;
202 devStat.txErrors = kdevStat->tx_errors;
203 devStat.rxDropped = kdevStat->rx_dropped;
204 devStat.txDropped = kdevStat->tx_dropped;
205
206 return &devStat;
207 }
208
hdf_bdh6_netdev_setnetifstats(struct NetDevice * netDev,NetIfStatus status)209 void hdf_bdh6_netdev_setnetifstats(struct NetDevice *netDev, NetIfStatus status)
210 {
211 HDF_LOGE("%s: start...", __func__);
212 (void)netDev;
213 (void)status;
214 }
215
hdf_bdh6_netdev_selectqueue(struct NetDevice * netDev,NetBuf * netBuff)216 uint16_t hdf_bdh6_netdev_selectqueue(struct NetDevice *netDev, NetBuf *netBuff)
217 {
218 HDF_LOGE("%s: start...", __func__);
219 (void)netDev;
220 (void)netBuff;
221 return HDF_SUCCESS;
222 }
223
hdf_bdh6_netdev_netifnotify(struct NetDevice * netDev,NetDevNotify * notify)224 uint32_t hdf_bdh6_netdev_netifnotify(struct NetDevice *netDev, NetDevNotify *notify)
225 {
226 HDF_LOGE("%s: start...", __func__);
227 (void)netDev;
228 (void)notify;
229 return HDF_SUCCESS;
230 }
231
hdf_bdh6_netdev_changemtu(struct NetDevice * netDev,int32_t mtu)232 int32_t hdf_bdh6_netdev_changemtu(struct NetDevice *netDev, int32_t mtu)
233 {
234 int32_t retVal = 0;
235 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
236 HDF_LOGE("%s: start...", __func__);
237
238 if (netdev == NULL) {
239 HDF_LOGE("%s: netdev null!", __func__);
240 return HDF_FAILURE;
241 }
242 HDF_LOGE("%s: change mtu to %d\n", __FUNCTION__, mtu);
243 // dengb fixed
244 retVal = (int32_t)dhd_netdev_changemtu_wrapper(netdev, mtu);
245 if (retVal < 0) {
246 HDF_LOGE("%s: hdf net device chg mtu failed! ret = %d", __func__, retVal);
247 }
248
249 return retVal;
250 }
251
hdf_bdh6_netdev_linkstatuschanged(struct NetDevice * netDev)252 void hdf_bdh6_netdev_linkstatuschanged(struct NetDevice *netDev)
253 {
254 HDF_LOGE("%s: start...", __func__);
255 (void)netDev;
256 }
257
258 #define BDH6_SHIFT_BIT 8
259
hdf_bdh6_netdev_specialethertypeprocess(const struct NetDevice * netDev,NetBuf * buff)260 ProcessingResult hdf_bdh6_netdev_specialethertypeprocess(const struct NetDevice *netDev, NetBuf *buff)
261 {
262 struct EtherHeader *header = NULL;
263 const struct Eapol *eapolInstance = NULL;
264 int ret = HDF_SUCCESS;
265 uint16_t protocol;
266 const int pidx0 = 12, pidx1 = 13;
267
268 HDF_LOGE("%s: start...", __func__);
269
270 if (netDev == NULL || buff == NULL) {
271 return PROCESSING_ERROR;
272 }
273
274 header = (struct EtherHeader *)NetBufGetAddress(buff, E_DATA_BUF);
275
276 protocol = (buff->data[pidx0] << BDH6_SHIFT_BIT) | buff->data[pidx1];
277 if (protocol != ETHER_TYPE_PAE) {
278 HDF_LOGE("%s: return PROCESSING_CONTINUE", __func__);
279 NetBufFree(buff);
280 return PROCESSING_CONTINUE;
281 }
282 if (netDev->specialProcPriv == NULL) {
283 HDF_LOGE("%s: return PROCESSING_ERROR", __func__);
284 NetBufFree(buff);
285 return PROCESSING_ERROR;
286 }
287
288 eapolInstance = EapolGetInstance();
289 ret = eapolInstance->eapolOp->writeEapolToQueue(netDev, buff);
290 if (ret != HDF_SUCCESS) {
291 HDF_LOGE("%s: writeEapolToQueue failed", __func__);
292 NetBufFree(buff);
293 }
294 return PROCESSING_COMPLETE;
295 }
296
297
298 struct NetDeviceInterFace g_wal_bdh6_net_dev_ops = {
299 .init = hdf_bdh6_netdev_init,
300 .deInit = hdf_bdh6_netdev_deinit,
301 .open = hdf_bdh6_netdev_open,
302 .stop = hdf_bdh6_netdev_stop,
303 .xmit = hdf_bdh6_netdev_xmit,
304 .ioctl = hdf_bdh6_netdev_ioctl,
305 .setMacAddr = hdf_bdh6_netdev_setmacaddr,
306 .getStats = hdf_bdh6_netdev_getstats,
307 .setNetIfStatus = hdf_bdh6_netdev_setnetifstats,
308 .selectQueue = hdf_bdh6_netdev_selectqueue,
309 .netifNotify = hdf_bdh6_netdev_netifnotify,
310 .changeMtu = hdf_bdh6_netdev_changemtu,
311 .linkStatusChanged = hdf_bdh6_netdev_linkstatuschanged,
312 .specialEtherTypeProcess = hdf_bdh6_netdev_specialethertypeprocess,
313 };
314
wal_get_net_dev_ops(void)315 struct NetDeviceInterFace *wal_get_net_dev_ops(void)
316 {
317 return &g_wal_bdh6_net_dev_ops;
318 }
319
wal_netif_rx_ni(struct sk_buff * skb)320 void wal_netif_rx_ni(struct sk_buff *skb)
321 {
322 NetIfRxNi(g_hdf_netdev, skb);
323 }
324
wal_netif_rx(struct sk_buff * skb)325 void wal_netif_rx(struct sk_buff *skb)
326 {
327 NetIfRx(g_hdf_netdev, skb);
328 }
329
get_bdh6_netDev(void)330 NetDevice* get_bdh6_netDev(void)
331 {
332 return g_hdf_netdev;
333 }
334
335