• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*
17  * Simple virtio-net driver using HDF WIFI framework without real WIFI functions.
18  */
19 
20 #include "los_hw_cpu.h"
21 #include "los_vm_iomap.h"
22 #include "los_vm_zone.h"
23 #include "netinet/if_ether.h"
24 #include "arpa/inet.h"
25 #include "hdf_device_desc.h"
26 #include "wifi/hdf_wlan_chipdriver_manager.h"
27 #include "wifi/wifi_mac80211_ops.h"
28 #include "osal.h"
29 #include "osal_io.h"
30 #include "eapol.h"
31 #include "virtmmio.h"
32 
33 #define HDF_LOG_TAG HDF_VIRTIO_NET
34 
35 #define VIRTIO_NET_F_MTU                    (1 << 3)
36 #define VIRTIO_NET_F_MAC                    (1 << 5)
37 struct VirtnetConfig {
38     uint8_t mac[6];
39     uint16_t status;
40     uint16_t maxVirtqPairs;
41     uint16_t mtu;
42 };
43 
44 #define VIRTMMIO_NETIF_NAME                 "virtnet"
45 #define VIRTMMIO_NETIF_DFT_GW               "10.0.2.2"
46 #define VIRTMMIO_NETIF_DFT_MASK             "255.255.255.0"
47 
48 /* This struct is actually ignored by this simple driver */
49 struct VirtnetHdr {
50     uint8_t flag;
51     uint8_t gsoType;
52     uint16_t hdrLen;
53     uint16_t gsoSize;
54     uint16_t csumStart;
55     uint16_t csumOffset;
56     uint16_t numBuffers;
57 };
58 
59 /*
60  * We use two queues for Tx/Rx respectively. When Tx, we record outgoing NetBuf
61  * and free it when QEMU done. When Rx, we use fixed buffers, then allocate &
62  * copy to a NetBuf, and then HDF will consume & free the NetBuf.
63  * Every NetBuf is a solo packet, no chaining like LWIP pbuf. So every outgoing
64  * packet always occupy two desc items: one for VirtnetHdr, the other for NetBuf.
65  * Tx/Rx queues memory layout:
66  *                         Rx queue                                Tx queue
67  * +-----------------+------------------+------------------++------+-------+------+
68  * | desc: 16B align | avail: 2B align  | used: 4B align   || desc | avail | used |
69  * | 16∗(Queue Size) | 4+2∗(Queue Size) | 4+8∗(Queue Size) ||      |       |      |
70  * +-----------------+------------------+------------------++------+-------+------+
71  */
72 #define VIRTQ_RX_QSZ        16
73 #define VIRTQ_TX_QSZ        32
74 #define PER_TX_ENTRIES      2
75 #define PER_RXBUF_SIZE      (sizeof(struct VirtnetHdr) + ETH_FRAME_LEN)
76 
77 struct VirtNetif {
78     struct VirtmmioDev  dev;
79 
80     uint16_t            tFreeHdr;   /* head of Tx free desc entries list */
81     uint16_t            tFreeNum;
82     NetBuf*             tbufRec[VIRTQ_TX_QSZ];
83     OSAL_DECLARE_SPINLOCK(transLock);
84 
85     uint8_t             rbuf[VIRTQ_RX_QSZ][PER_RXBUF_SIZE];
86 
87     struct VirtnetHdr   vnHdr;
88 };
89 
GetVirtnetIf(const NetDevice * netDev)90 static inline struct VirtNetif *GetVirtnetIf(const NetDevice *netDev)
91 {
92     return (struct VirtNetif *)GET_NET_DEV_PRIV(netDev);
93 }
94 
Feature0(uint32_t features,uint32_t * supported,void * dev)95 static bool Feature0(uint32_t features, uint32_t *supported, void *dev)
96 {
97     NetDevice *netDev = dev;
98     struct VirtNetif *nic = GetVirtnetIf(netDev);
99     struct VirtnetConfig *conf = (struct VirtnetConfig *)(nic->dev.base + VIRTMMIO_REG_CONFIG);
100     int i;
101 
102     if (features & VIRTIO_NET_F_MTU) {
103         if (conf->mtu > WLAN_MAX_MTU || conf->mtu < WLAN_MIN_MTU) {
104             HDF_LOGE("[%s]unsupported backend net MTU: %u", __func__, conf->mtu);
105             return false;
106         }
107         netDev->mtu = conf->mtu;
108         *supported |= VIRTIO_NET_F_MTU;
109     } else {
110         netDev->mtu = DEFAULT_MTU;
111     }
112 
113     if ((features & VIRTIO_NET_F_MAC) == 0) {
114         HDF_LOGE("[%s]no MAC feature found", __func__);
115         return false;
116     }
117     for (i = 0; i < MAC_ADDR_SIZE; i++) {
118         netDev->macAddr[i] = conf->mac[i];
119     }
120     netDev->addrLen = MAC_ADDR_SIZE;
121     *supported |= VIRTIO_NET_F_MAC;
122 
123     return true;
124 }
125 
Feature1(uint32_t features,uint32_t * supported,void * dev)126 static bool Feature1(uint32_t features, uint32_t *supported, void *dev)
127 {
128     (void)dev;
129     if (features & VIRTIO_F_VERSION_1) {
130         *supported |= VIRTIO_F_VERSION_1;
131     } else {
132         HDF_LOGE("[%s]net device has no VERSION_1 feature", __func__);
133         return false;
134     }
135 
136     return true;
137 }
138 
InitTxFreelist(struct VirtNetif * nic)139 static int32_t InitTxFreelist(struct VirtNetif *nic)
140 {
141     int i;
142 
143     for (i = 0; i < nic->dev.vq[1].qsz - 1; i++) {
144         nic->dev.vq[1].desc[i].flag = VIRTQ_DESC_F_NEXT;
145         nic->dev.vq[1].desc[i].next = i + 1;
146     }
147     nic->tFreeHdr = 0;
148     nic->tFreeNum = nic->dev.vq[1].qsz;
149 
150     return OsalSpinInit(&nic->transLock);
151 }
152 
FreeTxEntry(struct VirtNetif * nic,uint16_t head)153 static void FreeTxEntry(struct VirtNetif *nic, uint16_t head)
154 {
155     struct Virtq *q = &nic->dev.vq[1];
156     uint16_t idx = q->desc[head].next;
157     NetBuf *nb = NULL;
158 
159     /* keep track of virt queue free entries */
160     OsalSpinLock(&nic->transLock);
161     if (nic->tFreeNum > 0) {
162         q->desc[idx].next = nic->tFreeHdr;
163         q->desc[idx].flag = VIRTQ_DESC_F_NEXT;
164     }
165     nic->tFreeNum += PER_TX_ENTRIES;
166     nic->tFreeHdr = head;
167     nb = nic->tbufRec[idx];
168     OsalSpinUnlock(&nic->transLock);
169 
170     /* We free upstream Tx NetBuf! */
171     NetBufFree(nb);
172 }
173 
PopulateRxBuffer(struct VirtNetif * nic)174 static void PopulateRxBuffer(struct VirtNetif *nic)
175 {
176     uint32_t i;
177     PADDR_T paddr;
178     struct Virtq *q = &nic->dev.vq[0];
179 
180     for (i = 0; i < q->qsz; i++) {
181         paddr = VMM_TO_DMA_ADDR((VADDR_T)nic->rbuf[i]);
182 
183         q->desc[i].pAddr = paddr;
184         q->desc[i].len = PER_RXBUF_SIZE;
185         q->desc[i].flag = VIRTQ_DESC_F_WRITE;
186 
187         q->avail->ring[i] = i;
188     }
189 }
190 
ConfigQueue(struct VirtNetif * nic)191 static int32_t ConfigQueue(struct VirtNetif *nic)
192 {
193     VADDR_T base;
194     uint16_t qsz[VIRTQ_NUM];
195 
196     base = ALIGN((VADDR_T)nic + sizeof(struct VirtNetif), VIRTQ_ALIGN_DESC);
197     qsz[0] = VIRTQ_RX_QSZ;
198     qsz[1] = VIRTQ_TX_QSZ;
199     if (VirtmmioConfigQueue(&nic->dev, base, qsz, VIRTQ_NUM) == 0) {
200         return HDF_DEV_ERR_DEV_INIT_FAIL;
201     }
202 
203     PopulateRxBuffer(nic);
204 
205     return InitTxFreelist(nic);
206 }
207 
GetTxFreeEntry(struct VirtNetif * nic)208 static uint16_t GetTxFreeEntry(struct VirtNetif *nic)
209 {
210     uint32_t intSave;
211     uint16_t head, idx;
212     bool logged = false;
213 
214 RETRY:
215     OsalSpinLockIrqSave(&nic->transLock, &intSave);
216     if (PER_TX_ENTRIES > nic->tFreeNum) {
217         OsalSpinUnlockIrqRestore(&nic->transLock, &intSave);
218         if (!logged) {
219             HDF_LOGW("[%s]transmit queue is full", __func__);
220             logged = true;
221         }
222         LOS_TaskYield();
223         goto RETRY;
224     }
225 
226     nic->tFreeNum -= PER_TX_ENTRIES;
227     head = nic->tFreeHdr;
228     idx = nic->dev.vq[1].desc[head].next;
229     /* new tFreeHdr may be invalid if list is empty, but tFreeNum must be valid: 0 */
230     nic->tFreeHdr = nic->dev.vq[1].desc[idx].next;
231     OsalSpinUnlockIrqRestore(&nic->transLock, &intSave);
232     nic->dev.vq[1].desc[idx].flag &= ~VIRTQ_DESC_F_NEXT;
233 
234     return head;
235 }
236 
LowLevelOutput(NetDevice * netDev,NetBuf * p)237 static NetDevTxResult LowLevelOutput(NetDevice *netDev, NetBuf *p)
238 {
239     uint16_t idx, head;
240     struct VirtNetif *nic = GetVirtnetIf(netDev);
241     struct Virtq *trans = &nic->dev.vq[1];
242 
243     head = GetTxFreeEntry(nic);
244     trans->desc[head].pAddr = VMM_TO_DMA_ADDR((PADDR_T)&nic->vnHdr);
245     trans->desc[head].len = sizeof(struct VirtnetHdr);
246     idx = trans->desc[head].next;
247     trans->desc[idx].pAddr = LOS_PaddrQuery(NetBufGetAddress(p, E_DATA_BUF));
248     trans->desc[idx].len = NetBufGetDataLen(p);
249 
250     nic->tbufRec[idx] = p;
251 
252     trans->avail->ring[trans->avail->index % trans->qsz] = head;
253     DSB;
254     trans->avail->index++;
255     if (trans->used->flag != VIRTQ_USED_F_NO_NOTIFY) {
256         OSAL_WRITEL(1, nic->dev.base + VIRTMMIO_REG_QUEUENOTIFY);
257     }
258 
259     return NETDEV_TX_OK;
260 }
261 
LowLevelInput(const NetDevice * netDev,const struct VirtqUsedElem * e)262 static NetBuf *LowLevelInput(const NetDevice *netDev, const struct VirtqUsedElem *e)
263 {
264     struct VirtNetif *nic = GetVirtnetIf(netDev);
265     uint16_t len;
266     uint8_t *payload = NULL;
267     NetBuf *nb = NULL;
268 
269     /* we allocate Rx NetBuf & fill in received packet */
270     len = e->len - sizeof(struct VirtnetHdr);
271     nb = NetBufDevAlloc(netDev, len);
272     if (nb == NULL) {
273         HDF_LOGE("[%s]allocate NetBuf failed, drop 1 packet", __func__);
274         return NULL;
275     }
276     payload = NetBufPush(nb, E_DATA_BUF, len);  /* here always succeed */
277     (void)memcpy_s(payload, len, nic->rbuf[e->id] + sizeof(struct VirtnetHdr), len);
278 
279     return nb;
280 }
281 
VirtnetRxHandle(NetDevice * netDev)282 static void VirtnetRxHandle(NetDevice *netDev)
283 {
284     struct VirtNetif *nic = GetVirtnetIf(netDev);
285     struct Virtq *q = &nic->dev.vq[0];
286     NetBuf *nb = NULL;
287     struct VirtqUsedElem *e = NULL;
288     uint16_t add = 0;
289 
290     q->avail->flag = VIRTQ_AVAIL_F_NO_INTERRUPT;
291     while (1) {
292         if (q->last == q->used->index) {
293             q->avail->flag = 0;
294             /* recheck if new one come in between empty ring and enable interrupt */
295             DSB;
296             if (q->last == q->used->index) {
297                 break;
298             }
299             q->avail->flag = VIRTQ_AVAIL_F_NO_INTERRUPT;
300         }
301 
302         DSB;
303         e = &q->used->ring[q->last % q->qsz];
304         nb = LowLevelInput(netDev, e);
305         if (nb && NetIfRx(netDev, nb) != 0) {   /* Upstream free Rx NetBuf! */
306             HDF_LOGE("[%s]NetIfRx failed, drop 1 packet", __func__);
307             NetBufFree(nb);
308         }
309 
310         /*
311          * Our fixed receive buffers always sit in the appropriate desc[].
312          * We only need to update the available ring to QEMU.
313          */
314         q->avail->ring[(q->avail->index + add++) % q->qsz] = e->id;
315         q->last++;
316     }
317     DSB;
318     q->avail->index += add;
319 
320     if (q->used->flag != VIRTQ_USED_F_NO_NOTIFY) {
321         OSAL_WRITEL(0, nic->dev.base + VIRTMMIO_REG_QUEUENOTIFY);
322     }
323 }
324 
VirtnetTxHandle(struct VirtNetif * nic)325 static void VirtnetTxHandle(struct VirtNetif *nic)
326 {
327     struct Virtq *q = &nic->dev.vq[1];
328     struct VirtqUsedElem *e = NULL;
329 
330     /* Bypass recheck as VirtnetRxHandle */
331     q->avail->flag = VIRTQ_AVAIL_F_NO_INTERRUPT;
332     while (q->last != q->used->index) {
333         DSB;
334         e = &q->used->ring[q->last % q->qsz];
335         FreeTxEntry(nic, e->id);
336         q->last++;
337     }
338     q->avail->flag = 0;
339 }
340 
VirtnetIRQhandle(int swIrq,void * pDevId)341 static void VirtnetIRQhandle(int swIrq, void *pDevId)
342 {
343     (void)swIrq;
344     NetDevice *netDev = pDevId;
345     struct VirtNetif *nic = GetVirtnetIf(netDev);
346 
347     if (!(OSAL_READL(nic->dev.base + VIRTMMIO_REG_INTERRUPTSTATUS) & VIRTMMIO_IRQ_NOTIFY_USED)) {
348         return;
349     }
350 
351     VirtnetRxHandle(netDev);
352 
353     VirtnetTxHandle(nic);
354 
355     OSAL_WRITEL(VIRTMMIO_IRQ_NOTIFY_USED, nic->dev.base + VIRTMMIO_REG_INTERRUPTACK);
356 }
357 
358 /*
359  * The whole initialization is complex, here is the main point.
360  *  -factory-    FakeWifiInit/Release: alloc, set & register HdfChipDriverFactory
361  *  -chip-       FakeFactoryInitChip/Release: alloc & set HdfChipDriver
362  *  -NetDevice-  VirtNetDeviceInit/DeInit: set & add NetDevice
363  *  -virtnet-    VirtnetInit/DeInit: virtio-net driver
364  */
365 
VirtnetInit(NetDevice * netDev)366 static int32_t VirtnetInit(NetDevice *netDev)
367 {
368     int32_t ret, len;
369     struct VirtNetif *nic = NULL;
370 
371     /* NOTE: For simplicity, alloc all these data from physical continuous memory. */
372     len = sizeof(struct VirtNetif) + VirtqSize(VIRTQ_RX_QSZ) + VirtqSize(VIRTQ_TX_QSZ);
373     nic = LOS_DmaMemAlloc(NULL, len, sizeof(void *), DMA_CACHE);
374     if (nic == NULL) {
375         HDF_LOGE("[%s]alloc nic memory failed", __func__);
376         return HDF_ERR_MALLOC_FAIL;
377     }
378     memset_s(nic, len, 0, len);
379     GET_NET_DEV_PRIV(netDev) = nic;
380 
381     if (!VirtmmioDiscover(VIRTMMIO_DEVICE_ID_NET, &nic->dev)) {
382         return HDF_DEV_ERR_NO_DEVICE;
383     }
384 
385     VirtmmioInitBegin(&nic->dev);
386 
387     if (!VirtmmioNegotiate(&nic->dev, Feature0, Feature1, netDev)) {
388         ret = HDF_DEV_ERR_DEV_INIT_FAIL;
389         goto ERR_OUT;
390     }
391 
392     if ((ret = ConfigQueue(nic)) != HDF_SUCCESS) {
393         goto ERR_OUT;
394     }
395 
396     ret = OsalRegisterIrq(nic->dev.irq, OSAL_IRQF_TRIGGER_NONE, (OsalIRQHandle)VirtnetIRQhandle,
397                           VIRTMMIO_NETIF_NAME, netDev);
398     if (ret != HDF_SUCCESS) {
399         HDF_LOGE("[%s]register IRQ failed: %d", __func__, ret);
400         goto ERR_OUT;
401     }
402     nic->dev.irq |= ~_IRQ_MASK;
403 
404     VritmmioInitEnd(&nic->dev);
405     return HDF_SUCCESS;
406 
407 ERR_OUT:
408     VirtmmioInitFailed(&nic->dev);
409     return ret;
410 }
411 
VirtnetDeInit(NetDevice * netDev)412 static void VirtnetDeInit(NetDevice *netDev)
413 {
414     struct VirtNetif *nic = GetVirtnetIf(netDev);
415 
416     if (nic && (nic->dev.irq & ~_IRQ_MASK)) {
417         OsalUnregisterIrq(nic->dev.irq & _IRQ_MASK, netDev);
418     }
419     if (nic) {
420         LOS_DmaMemFree(nic);
421     }
422     GET_NET_DEV_PRIV(netDev) = NULL;
423 }
424 
VirtNetDeviceSetMacAddr(NetDevice * netDev,void * addr)425 static int32_t VirtNetDeviceSetMacAddr(NetDevice *netDev, void *addr)
426 {
427     uint8_t *p = addr;
428     for (int i = 0; i < netDev->addrLen; i++) {
429         netDev->macAddr[i] = p[i];
430     }
431     return HDF_SUCCESS;
432 }
433 
434 static struct NetDeviceInterFace g_netDevOps = {
435     .setMacAddr = VirtNetDeviceSetMacAddr,
436     /*
437      * Link layer packet transmission chain:
438      *   LWIP netif->linkoutput = driverif_output, in kernel, pbuf
439      *       KHDF netif->drv_send = LwipSend, in HDF adapter, NetBuf
440      *           NetDevice .xmit = our driver, NetBuf
441      */
442     .xmit = LowLevelOutput,
443 };
444 
445 #define VN_RANDOM_IP_MASK   0xFF    /* 255.255.255.0 subnet */
446 #define VN_RANDOM_IP_SHF    24      /* network byte order */
447 
448 /* fake WIFI have to UP interface, assign IP by hand */
VirtNetDeviceInitDone(NetDevice * netDev)449 static int32_t VirtNetDeviceInitDone(NetDevice *netDev)
450 {
451     IpV4Addr ip, mask, gw;
452     uint32_t h, l;
453     int32_t ret;
454 
455     if ((ret = NetIfSetStatus(netDev, NETIF_UP)) != HDF_SUCCESS) {
456         return ret;
457     }
458 
459     /* odd way hope to get ~distinct~ IP for different guests */
460     LOS_GetCpuCycle(&h, &l);
461     l &= VN_RANDOM_IP_MASK;
462     if (l == 0 || l == (1 << 1)) {          /* avoid 10.0.2.0, 10.0.2.2 */
463         l++;
464     } else if (l == VN_RANDOM_IP_MASK) {    /* avoid 10.0.2.255 */
465         l--;
466     }
467     l <<= VN_RANDOM_IP_SHF;
468     ip.addr = (inet_addr(VIRTMMIO_NETIF_DFT_MASK) & inet_addr(VIRTMMIO_NETIF_DFT_GW)) | l;
469     mask.addr = inet_addr(VIRTMMIO_NETIF_DFT_MASK);
470     gw.addr = inet_addr(VIRTMMIO_NETIF_DFT_GW);
471     return NetIfSetAddr(netDev, &ip, &mask, &gw);
472 }
473 
VirtNetDeviceInit(struct HdfChipDriver * chipDriver,NetDevice * netDev)474 static int32_t VirtNetDeviceInit(struct HdfChipDriver *chipDriver, NetDevice *netDev)
475 {
476     (void)chipDriver;
477     int32_t ret;
478 
479     /* VirtnetInit also set netDev->macAddr, mtu, addrLen */
480     if ((ret = VirtnetInit(netDev)) != HDF_SUCCESS) {
481         return ret;
482     }
483     netDev->flags = NET_DEVICE_IFF_RUNNING;
484     netDev->neededHeadRoom = 0;
485     netDev->neededTailRoom = 0;
486     netDev->funType.wlanType = PROTOCOL_80211_IFTYPE_STATION;
487     netDev->netDeviceIf = &g_netDevOps;
488     if ((ret = NetDeviceAdd(netDev)) != HDF_SUCCESS) {
489         goto ERR_OUT;
490     }
491     if ((ret = CreateEapolData(netDev)) != HDF_SUCCESS) {
492         goto ERR_OUT;
493     }
494 
495     /* everything is ready, now notify device the receive buffers */
496     struct VirtNetif *nic = GetVirtnetIf(netDev);
497     nic->dev.vq[0].avail->index = nic->dev.vq[0].qsz;
498     OSAL_WRITEL(0, nic->dev.base + VIRTMMIO_REG_QUEUENOTIFY);
499 
500     return VirtNetDeviceInitDone(netDev);
501 
502 ERR_OUT:
503     VirtnetDeInit(netDev);
504     return ret;
505 }
506 
VirtNetDeviceDeInit(struct HdfChipDriver * chipDriver,NetDevice * netDev)507 static int32_t VirtNetDeviceDeInit(struct HdfChipDriver *chipDriver, NetDevice *netDev)
508 {
509     (void)chipDriver;
510 
511     DestroyEapolData(netDev);
512 
513     if (GetVirtnetIf(netDev)) {
514         VirtnetDeInit(netDev);
515     }
516 
517     return NetDeviceDelete(netDev);
518 }
519 
520 
521 /*
522  * Followings are mainly fake data & funcs to mimic a wireless card.
523  *
524  * Here is fake MAC80211 base operations.
525  */
FakeWalSetMode(NetDevice * netDev,enum WlanWorkMode mode)526 static int32_t FakeWalSetMode(NetDevice *netDev, enum WlanWorkMode mode)
527 {
528     (void)netDev;
529     if (mode != WLAN_WORKMODE_STA) {
530         HDF_LOGE("[%s]unsupported WLAN mode: %u", __func__, mode);
531         return HDF_ERR_NOT_SUPPORT;
532     }
533     return HDF_SUCCESS;
534 }
FakeWalAddKey(NetDevice * netDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr,struct KeyParams * params)535 static int32_t FakeWalAddKey(NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr,
536                              struct KeyParams *params)
537 {
538     (void)netDev;
539     (void)keyIndex;
540     (void)pairwise;
541     (void)macAddr;
542     (void)params;
543     return HDF_SUCCESS;
544 }
FakeWalDelKey(NetDevice * netDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr)545 static int32_t FakeWalDelKey(NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr)
546 {
547     (void)netDev;
548     (void)keyIndex;
549     (void)pairwise;
550     (void)macAddr;
551     return HDF_SUCCESS;
552 }
FakeWalSetDefaultKey(NetDevice * netDev,uint8_t keyIndex,bool unicast,bool multicas)553 static int32_t FakeWalSetDefaultKey(NetDevice *netDev, uint8_t keyIndex, bool unicast, bool multicas)
554 {
555     (void)netDev;
556     (void)keyIndex;
557     (void)unicast;
558     (void)multicas;
559     return HDF_SUCCESS;
560 }
FakeWalGetDeviceMacAddr(NetDevice * netDev,int32_t type,uint8_t * mac,uint8_t len)561 static int32_t FakeWalGetDeviceMacAddr(NetDevice *netDev, int32_t type, uint8_t *mac, uint8_t len)
562 {
563     (void)netDev;
564     (void)type;
565 
566     for (int i = 0; i < len && i < netDev->addrLen; i++) {
567         mac[i] = netDev->macAddr[i];
568     }
569 
570     return HDF_SUCCESS;
571 }
FakeWalSetMacAddr(NetDevice * netDev,uint8_t * mac,uint8_t len)572 static int32_t FakeWalSetMacAddr(NetDevice *netDev, uint8_t *mac, uint8_t len)
573 {
574     (void)netDev;
575 
576     for (int i = 0; i < len && i < netDev->addrLen; i++) {
577         netDev->macAddr[i] = mac[i];
578     }
579 
580     return HDF_SUCCESS;
581 }
FakeWalSetTxPower(NetDevice * netDev,int32_t power)582 static int32_t FakeWalSetTxPower(NetDevice *netDev, int32_t power)
583 {
584     (void)netDev;
585     (void)power;
586     return HDF_SUCCESS;
587 }
588 #define FAKE_MAGIC_BAND     20
589 #define FAKE_MAGIC_FREQ     2412
590 #define FAKE_MAGIC_CAPS     20
591 #define FAKE_MAGIC_RATE     100
FakeWalGetValidFreqsWithBand(NetDevice * netDev,int32_t band,int32_t * freqs,uint32_t * num)592 static int32_t FakeWalGetValidFreqsWithBand(NetDevice *netDev, int32_t band, int32_t *freqs, uint32_t *num)
593 {
594     (void)netDev;
595 
596     if (band != FAKE_MAGIC_BAND) {
597         HDF_LOGE("[%s]unsupported WLAN band: %dMHz", __func__, band);
598         return HDF_ERR_NOT_SUPPORT;
599     }
600 
601     *freqs = FAKE_MAGIC_FREQ; /* MHz, channel 1 */
602     *num = 1;
603     return HDF_SUCCESS;
604 }
605 struct MemAllocForWlanHwCapability {
606     struct WlanHwCapability cap;
607     struct WlanBand band;
608     struct WlanChannel ch;
609     uint16_t rate;
610 };
FakeWalHwCapabilityRelease(struct WlanHwCapability * self)611 static void FakeWalHwCapabilityRelease(struct WlanHwCapability *self)
612 {
613     OsalMemFree(self);
614 }
FakeWalGetHwCapability(NetDevice * netDev,struct WlanHwCapability ** capability)615 static int32_t FakeWalGetHwCapability(NetDevice *netDev, struct WlanHwCapability **capability)
616 {
617     (void)netDev;
618 
619     struct MemAllocForWlanHwCapability *p = OsalMemCalloc(sizeof(struct MemAllocForWlanHwCapability));
620     if (p == NULL) {
621         HDF_LOGE("[%s]alloc memory failed", __func__);
622         return HDF_ERR_MALLOC_FAIL;
623     }
624     p->cap.Release = FakeWalHwCapabilityRelease;
625     p->cap.bands[0] = &p->band;
626     p->cap.htCapability = FAKE_MAGIC_CAPS;
627     p->cap.supportedRateCount = 1;
628     p->cap.supportedRates = &p->rate;
629     p->band.channelCount = 1;
630     p->ch.channelId = 1;
631     p->ch.centerFreq = FAKE_MAGIC_FREQ;
632     p->ch.flags = WLAN_CHANNEL_FLAG_NO_IR | WLAN_CHANNEL_FLAG_DFS_UNAVAILABLE;
633     p->rate = FAKE_MAGIC_RATE;
634 
635     *capability = &p->cap;
636     return HDF_SUCCESS;
637 }
638 static struct HdfMac80211BaseOps g_fakeBaseOps = {
639     .SetMode = FakeWalSetMode,
640     .AddKey = FakeWalAddKey,
641     .DelKey = FakeWalDelKey,
642     .SetDefaultKey = FakeWalSetDefaultKey,
643     .GetDeviceMacAddr = FakeWalGetDeviceMacAddr,
644     .SetMacAddr = FakeWalSetMacAddr,
645     .SetTxPower = FakeWalSetTxPower,
646     .GetValidFreqsWithBand = FakeWalGetValidFreqsWithBand,
647     .GetHwCapability = FakeWalGetHwCapability
648 };
649 
650 
651 /*
652  * Fake STA operations.
653  */
FakeStaConnect(NetDevice * netDev,WlanConnectParams * param)654 static int32_t FakeStaConnect(NetDevice *netDev, WlanConnectParams *param)
655 {
656     (void)netDev;
657     (void)param;
658     return HDF_SUCCESS;
659 }
FakeStaDisonnect(NetDevice * netDev,uint16_t reasonCode)660 static int32_t FakeStaDisonnect(NetDevice *netDev, uint16_t reasonCode)
661 {
662     (void)netDev;
663     (void)reasonCode;
664     return HDF_SUCCESS;
665 }
FakeStaStartScan(NetDevice * netDev,struct WlanScanRequest * param)666 static int32_t FakeStaStartScan(NetDevice *netDev, struct WlanScanRequest *param)
667 {
668     (void)netDev;
669     (void)param;
670     return HDF_SUCCESS;
671 }
FakeStaAbortScan(NetDevice * netDev)672 static int32_t FakeStaAbortScan(NetDevice *netDev)
673 {
674     (void)netDev;
675     return HDF_SUCCESS;
676 }
FakeStaSetScanningMacAddress(NetDevice * netDev,unsigned char * mac,uint32_t len)677 static int32_t FakeStaSetScanningMacAddress(NetDevice *netDev, unsigned char *mac, uint32_t len)
678 {
679     (void)netDev;
680     (void)mac;
681     (void)len;
682     return HDF_SUCCESS;
683 }
684 static struct HdfMac80211STAOps g_fakeStaOps = {
685     .Connect = FakeStaConnect,
686     .Disconnect = FakeStaDisonnect,
687     .StartScan = FakeStaStartScan,
688     .AbortScan = FakeStaAbortScan,
689     .SetScanningMacAddress = FakeStaSetScanningMacAddress,
690 };
691 
692 
693 /*
694  * Fake factory & chip functions.
695  */
FakeFactoryInitChip(struct HdfWlanDevice * device,uint8_t ifIndex)696 static struct HdfChipDriver *FakeFactoryInitChip(struct HdfWlanDevice *device, uint8_t ifIndex)
697 {
698     struct HdfChipDriver *chipDriver = NULL;
699     if (device == NULL || ifIndex > 0) {
700         HDF_LOGE("[%s]HdfWlanDevice is NULL or ifIndex>0", __func__);
701         return NULL;
702     }
703     chipDriver = OsalMemCalloc(sizeof(struct HdfChipDriver));
704     if (chipDriver == NULL) {
705         HDF_LOGE("[%s]alloc memory failed", __func__);
706         return NULL;
707     }
708 
709     if (strcpy_s(chipDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, VIRTMMIO_NETIF_NAME) != EOK) {
710         HDF_LOGE("[%s]strcpy_s failed", __func__);
711         OsalMemFree(chipDriver);
712         return NULL;
713     }
714     chipDriver->init = VirtNetDeviceInit;
715     chipDriver->deinit = VirtNetDeviceDeInit;
716     chipDriver->ops = &g_fakeBaseOps;
717     chipDriver->staOps = &g_fakeStaOps;
718 
719     return chipDriver;
720 }
FakeFactoryReleaseChip(struct HdfChipDriver * chipDriver)721 static void FakeFactoryReleaseChip(struct HdfChipDriver *chipDriver)
722 {
723     if (chipDriver == NULL) {
724         return;
725     }
726     if (strcmp(chipDriver->name, VIRTMMIO_NETIF_NAME) != 0) {
727         HDF_LOGE("[%s]not my driver: %s", __func__, chipDriver->name);
728         return;
729     }
730     OsalMemFree(chipDriver);
731 }
FakeFactoryGetMaxIFCount(struct HdfChipDriverFactory * factory)732 static uint8_t FakeFactoryGetMaxIFCount(struct HdfChipDriverFactory *factory)
733 {
734     (void)factory;
735     return 1;
736 }
FakeFactoryRelease(struct HdfChipDriverFactory * factory)737 static void FakeFactoryRelease(struct HdfChipDriverFactory *factory)
738 {
739     OsalMemFree(factory);
740 }
FakeFactoryInit(void)741 static int32_t FakeFactoryInit(void)
742 {
743     struct HdfChipDriverManager *driverMgr = NULL;
744     struct HdfChipDriverFactory *tmpFactory = NULL;
745     int32_t ret;
746 
747     tmpFactory = OsalMemCalloc(sizeof(struct HdfChipDriverFactory));
748     if (tmpFactory == NULL) {
749         HDF_LOGE("[%s]alloc memory failed", __func__);
750         return HDF_ERR_MALLOC_FAIL;
751     }
752 
753     driverMgr = HdfWlanGetChipDriverMgr();
754     if (driverMgr == NULL || driverMgr->RegChipDriver == NULL) {
755         HDF_LOGE("[%s]driverMgr or its RegChipDriver is NULL!", __func__);
756         OsalMemFree(tmpFactory);
757         return HDF_FAILURE;
758     }
759 
760 #define VIRTMMIO_WIFI_NAME  "fakewifi"  /* must match wlan_chip_virtnet.hcs::driverName */
761     tmpFactory->driverName = VIRTMMIO_WIFI_NAME;
762     tmpFactory->ReleaseFactory = FakeFactoryRelease;
763     tmpFactory->Build = FakeFactoryInitChip;
764     tmpFactory->Release = FakeFactoryReleaseChip;
765     tmpFactory->GetMaxIFCount = FakeFactoryGetMaxIFCount;
766     if ((ret = driverMgr->RegChipDriver(tmpFactory)) != HDF_SUCCESS) {
767         HDF_LOGE("[%s]register chip driver failed: %d", __func__, ret);
768         OsalMemFree(tmpFactory);
769         return ret;
770     }
771 
772     return HDF_SUCCESS;
773 }
774 
775 
776 /*
777  * HDF entry.
778  */
779 
FakeWifiInit(struct HdfDeviceObject * device)780 static int32_t FakeWifiInit(struct HdfDeviceObject *device)
781 {
782     struct VirtmmioDev dev;
783 
784     if (device == NULL) {
785         HDF_LOGE("[%s]device is null", __func__);
786         return HDF_ERR_INVALID_PARAM;
787     }
788 
789     /* only when virtio-net do exist, we go on the other lots of work */
790     if (!VirtmmioDiscover(VIRTMMIO_DEVICE_ID_NET, &dev)) {
791         return HDF_ERR_INVALID_OBJECT;
792     }
793 
794     return FakeFactoryInit();
795 }
796 
FakeWifiRelease(struct HdfDeviceObject * deviceObject)797 static void FakeWifiRelease(struct HdfDeviceObject *deviceObject)
798 {
799     if (deviceObject) {
800         (void)ChipDriverMgrDeInit();
801     }
802 }
803 
804 struct HdfDriverEntry g_fakeWifiEntry = {
805     .moduleVersion = 1,
806     .Init = FakeWifiInit,
807     .Release = FakeWifiRelease,
808     .moduleName = "HDF_FAKE_WIFI"
809 };
810 
811 HDF_INIT(g_fakeWifiEntry);
812