• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 #include "hieth_phy.h"
17 #include "mdio.h"
18 
19 #include "string.h"
20 #include "eth_drv.h"
21 #include "ctrl.h"
22 #include "asm/dma.h"
23 #include "sys/bus.h"
24 
25 #define PHY_ADDR_SET     0x129B5B3
26 #define PHY_ADDR_NOT_SET 0x5a5aa5a5
27 #define INVALID_PHY_ADDR 0x12F358F
28 #define PHY_MODE_SET     0x12B63D0
29 #define PHY_MODE_NOT_SET 0x5a5aa5a5
30 #define INVALID_PHY_MODE 0x12F5D09
31 
32 #define ETH_STACKSIZE 0x20000
33 
34 #define PHY_ID_INVALID(id) (((id & 0x1fffffff) == 0x1fffffff) ||  \
35                             ((id & 0xfffffff0) == 0xfffffff0) ||  \
36                             (id == 0) ||  \
37                             (id == 0xffff0000) ||  \
38                             (id == 0x0000ffff))
39 
40 static int32_t g_userSetPhyAddr = PHY_ADDR_NOT_SET;
41 static int32_t g_phyAddrVal = INVALID_PHY_ADDR;
42 static int32_t g_userSetPhyMode = PHY_MODE_NOT_SET;
43 static int32_t g_phyModeVal = INVALID_PHY_MODE;
44 
45 struct HiethPlatformData *g_stHiethPlatformData = NULL;
46 OSAL_DECLARE_SPINLOCK(hiethGlbRegLock);
47 extern unsigned long msecs_to_jiffies(const uint32_t msecs);
48 
IsLinkUp(struct EthDevice * ethDevice)49 static bool IsLinkUp(struct EthDevice *ethDevice)
50 {
51     NetIfLinkStatus status;
52 
53     if (NetIfGetLinkStatus(ethDevice->netdev, &status) != 0) {
54         HDF_LOGE("%s: net device is invalid", __func__);
55         return false;
56     }
57     return status == NETIF_LINK_UP;
58 }
59 
RestartTimer(OsalTimer * timer,uint32_t interval,OsalTimerFunc func,uintptr_t arg)60 static void RestartTimer(OsalTimer *timer, uint32_t interval, OsalTimerFunc func, uintptr_t arg)
61 {
62     (void)OsalTimerDelete(timer);
63     if (OsalTimerCreate(timer, interval, func, arg) != HDF_SUCCESS) {
64         HDF_LOGE("create timer failed");
65     } else if (OsalTimerStartOnce(timer) != HDF_SUCCESS) {
66         HDF_LOGE("%s: start timer failed", __func__);
67     }
68 }
69 
PhyStateMachine(uintptr_t arg)70 static void PhyStateMachine(uintptr_t arg)
71 {
72     struct EthDevice *ethDevice = (struct EthDevice *)arg;
73     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
74     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
75     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
76     int32_t linkStatus;
77 
78     linkStatus = MiiphyLink(ld, priv->phy);
79     if (IsLinkUp(ethDevice) && !linkStatus) {
80         NetIfSetLinkStatus(ethDevice->netdev, NETIF_LINK_DOWN);
81     } else if (!IsLinkUp(ethDevice) && linkStatus) {
82         NetIfSetLinkStatus(ethDevice->netdev, NETIF_LINK_UP);
83     }
84 }
85 
HiethMonitorFunc(uintptr_t arg)86 static void HiethMonitorFunc(uintptr_t arg)
87 {
88     struct EthDevice *ethDevice = (struct EthDevice *)arg;
89     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
90     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
91     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
92     int32_t refillCnt;
93 
94     refillCnt = HiethFeedHw(ld, priv);
95     if (!refillCnt) {
96         RestartTimer(&priv->monitorTimer, HIETH_MONITOR_TIME, HiethMonitorFunc, (uintptr_t)ethDevice);
97     }
98 }
99 
EthDrvRecv(struct EthDevice * ethDevice,NetBuf * netBuf)100 static void EthDrvRecv(struct EthDevice *ethDevice, NetBuf *netBuf)
101 {
102     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
103     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
104 
105     priv->rxRelease++;
106     if (priv->rxRelease == HIETH_HWQ_RXQ_DEPTH) {
107         priv->rxRelease = 0;
108     }
109     NetDmaCacheInv(NetBufGetAddress(netBuf, E_DATA_BUF), netBuf->len);
110     NetBufPush(netBuf, E_DATA_BUF, netBuf->len);
111     NetIfRxNi(ethDevice->netdev, netBuf);
112 }
113 
UnRegisterTimerFunction(struct EthDevice * ethDevice)114 void UnRegisterTimerFunction(struct EthDevice *ethDevice)
115 {
116     struct EthDrvSc *drvInfo = (struct EthDrvSc *)(ethDevice->priv);
117     HiethPriv *priv = (HiethPriv *)drvInfo->driverPrivate;
118 
119     (void)OsalTimerDelete(&priv->phyTimer);
120     (void)OsalTimerDelete(&priv->monitorTimer);
121 }
122 
NetDmaCacheInv(void * addr,uint32_t size)123 void NetDmaCacheInv(void *addr, uint32_t size)
124 {
125     uint32_t start = (uintptr_t)addr & ~(CACHE_ALIGNED_SIZE - 1);
126     uint32_t end = (uintptr_t)addr + size;
127 
128     end = ALIGN(end, CACHE_ALIGNED_SIZE);
129     DCacheInvRange(start, end);
130 }
131 
NetDmaCacheClean(void * addr,uint32_t size)132 void NetDmaCacheClean(void *addr, uint32_t size)
133 {
134     uint32_t start = (uintptr_t)addr & ~(CACHE_ALIGNED_SIZE - 1);
135     uint32_t end = (uintptr_t)addr + size;
136 
137     end = ALIGN(end, CACHE_ALIGNED_SIZE);
138     DCacheFlushRange(start, end);
139 }
140 
HisiEthIsr(uint32_t irq,void * data)141 static uint32_t HisiEthIsr(uint32_t irq, void *data)
142 {
143     (void)irq;
144     struct EthDrvSc *drvSc = (struct EthDrvSc *)data;
145     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
146 
147     OsalDisableIrq(priv->vector); // 禁止一个irq;
148     LOS_EventWrite(&(g_stHiethPlatformData[priv->index].stEvent), EVENT_NET_TX_RX);
149     return HDF_SUCCESS;
150 }
151 
HisiEthDsr(void * arg)152 static int32_t HisiEthDsr(void *arg)
153 {
154     uint32_t uwRet;
155     struct EthDevice *ethDevice = (struct EthDevice *)arg;
156     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
157     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
158 
159     while (true) {
160         uwRet = LOS_EventRead(&(g_stHiethPlatformData[priv->index].stEvent), EVENT_NET_TX_RX,
161                               LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
162         if (uwRet & EVENT_NET_TX_RX) {
163             (drvSc->funs->deliver)(ethDevice);
164         }
165     }
166     return HDF_SUCCESS;
167 }
168 
CreateEthIrqThread(struct EthDevice * ethDevice)169 static int32_t CreateEthIrqThread(struct EthDevice *ethDevice)
170 {
171     struct OsalThread thread;
172     struct OsalThreadParam para = {
173         .name = "eth_irq_Task",
174         .stackSize = ETH_STACKSIZE,
175         .priority = OSAL_THREAD_PRI_HIGHEST,
176     };
177 
178     if (OsalThreadCreate(&thread, HisiEthDsr, (void *)ethDevice) != HDF_SUCCESS) {
179         HDF_LOGE("create isr thread failed");
180         return HDF_FAILURE;
181     }
182     if (OsalThreadStart(&thread, &para) != HDF_SUCCESS) {
183         HDF_LOGE("isr thread start failed");
184         return HDF_FAILURE;
185     }
186     return HDF_SUCCESS;
187 }
188 
ScanPhyId(struct HiethNetdevLocal * ld,int32_t addr)189 static uint32_t ScanPhyId(struct HiethNetdevLocal *ld, int32_t addr)
190 {
191     uint32_t phyId, val;
192 
193     val = (uint32_t)HiethMdioRead(ld, addr, PHY_ID1);
194     phyId = val << MAC_ADDR_OFFSET_L16;
195     val = (uint32_t)HiethMdioRead(ld, addr, PHY_ID2);
196     phyId |= val;
197     return phyId;
198 }
199 
HiethCanSend(struct EthDevice * ethDevice)200 static int32_t HiethCanSend(struct EthDevice *ethDevice)
201 {
202     int32_t canSend;
203     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
204     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
205     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
206     uint32_t txqHeadNext;
207 
208     if (!TestXmitQueueReady(ld)) {
209         HiethXmitReleasePkt(ld, priv);
210     }
211 
212     txqHeadNext = ld->txqHead + 1;
213     if (txqHeadNext == ld->qSize) {
214         txqHeadNext = 0;
215     }
216 
217     OsalSpinLockIrq(&(ld->tx_lock));
218     if (!TestXmitQueueReady(ld) ||
219         txqHeadNext == ld->txqTail) {
220         uint32_t uwRet;
221         canSend = 0;
222         ld->txBusy = 1;
223         OsalSpinUnlockIrq(&(ld->tx_lock));
224         OsalEnableIrq(priv->vector);
225         uwRet = LOS_EventRead(&(g_stHiethPlatformData[priv->index].stEvent),
226                               EVENT_NET_CAN_SEND, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, msecs_to_jiffies(40));
227         if (uwRet & EVENT_NET_CAN_SEND) {
228             canSend = 1;
229         }
230         OsalDisableIrq(priv->vector);
231         OsalSpinLockIrq(&(ld->tx_lock));
232     } else {
233         canSend = 1;
234     }
235     OsalSpinUnlockIrq(&(ld->tx_lock));
236     return canSend;
237 }
238 
HiethSend(struct EthDevice * ethDevice,NetBuf * netBuf)239 static void HiethSend(struct EthDevice *ethDevice, NetBuf *netBuf)
240 {
241     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
242     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
243     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
244 
245     OsalSpinLockIrq(&(ld->tx_lock));
246     /* TSO supported */
247     HiethXmitGso(ld, priv, netBuf);
248     ld->txHwCnt++;
249     OsalSpinUnlockIrq(&(ld->tx_lock));
250 }
251 
HiethDeliver(struct EthDevice * ethDevice)252 static void HiethDeliver(struct EthDevice *ethDevice)
253 {
254     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
255     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
256     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
257     uint32_t ints;
258     int32_t refillCnt;
259     uint32_t rxPktInfo;
260     uint32_t rlen;
261     NetBuf *netBuf = NULL;
262 
263     /* mask the all interrupt */
264     /* Add lock for multi-processor */
265     OsalSpinLockIrq(&hiethGlbRegLock);
266     HiethWritelBits(ld, 0, GLB_RW_IRQ_ENA, BITS_IRQS_ENA_ALLPORT);
267     OsalSpinUnlockIrq(&hiethGlbRegLock);
268 
269     HiethXmitReleasePkt(ld, priv);
270     HiethClearIrqstatus(ld, UD_BIT_NAME(HIETH_INT_TXQUE_RDY));
271 
272     ints = HiethReadIrqstatus(ld);
273 
274     if (ints & BITS_IRQS_MASK_U) {
275         if ((ints & UD_BIT_NAME(HIETH_INT_MULTI_RXRDY))) {
276             while (IsRecvPacket(ld)) {
277                 rxPktInfo = HwGetRxpkgInfo(ld);
278                 rlen = (rxPktInfo >> BITS_RXPKG_LEN_OFFSET)
279                        & BITS_RXPKG_LEN_MASK;
280                 rlen -= 4;
281                 if (rlen > HIETH_MAX_FRAME_SIZE) {
282                     HDF_LOGE("ERROR: recv len=%d", rlen);
283                 }
284 
285                 OsalSpinLockIrq(&hiethGlbRegLock);
286                 HwSetRxpkgFinish(ld);
287                 OsalSpinUnlockIrq(&hiethGlbRegLock);
288 
289                 OsalSpinLockIrq(&(ld->rx_lock));
290                 netBuf = priv->ram->rxNetbuf[priv->rxRelease];
291                 netBuf->len = rlen;
292                 OsalSpinUnlockIrq(&(ld->rx_lock));
293                 EthDrvRecv(ethDevice, netBuf);
294             }
295 
296             refillCnt = HiethFeedHw(ld, priv);
297             if (!refillCnt && (priv->rxRelease == priv->rxFeed)) {
298                 RestartTimer(&priv->monitorTimer, HIETH_MONITOR_TIME, HiethMonitorFunc, (uintptr_t)ethDevice);
299             }
300         }
301         HiethClearIrqstatus(ld, (ints & BITS_IRQS_MASK_U));
302         ints &= ~BITS_IRQS_MASK_U;
303     }
304 
305     if (ints & HIETH_INT_TX_ERR_U) {
306         ints &= ~HIETH_INT_TX_ERR_U;
307         HDF_LOGE("HiethDeliver ERROR: HIETH_INT_TX_ERR_U.\n");
308     }
309 
310     if (ints) {
311         HDF_LOGE("unknown ints=0x%.8x", ints);
312         HiethClearIrqstatus(ld, ints);
313     }
314 
315     /* unmask the all interrupt */
316     OsalSpinLockIrq(&hiethGlbRegLock);
317     HiethWritelBits(ld, 1, GLB_RW_IRQ_ENA, BITS_IRQS_ENA_ALLPORT);
318     OsalSpinUnlockIrq(&hiethGlbRegLock);
319 
320     OsalEnableIrq(priv->vector);
321 #ifdef INT_IO_ETH_INT_SUPPORT_REQUIRED
322     drv_interrupt_unmask(priv->vector);
323 #endif
324 }
325 
HiethIntVector(struct EthDevice * ethDevice)326 static int32_t HiethIntVector(struct EthDevice *ethDevice)
327 {
328     return NUM_HAL_INTERRUPT_ETH;
329 }
330 
EthDrvSend(struct EthDevice * ethDevice,NetBuf * netBuf)331 void EthDrvSend(struct EthDevice *ethDevice, NetBuf *netBuf)
332 {
333     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
334     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
335 
336     OsalDisableIrq(priv->vector);
337     if (!(drvSc->funs->canSend)(ethDevice)) {
338         OsalEnableIrq(priv->vector);
339         return;
340     }
341     (drvSc->funs->send)(ethDevice, netBuf);
342     OsalEnableIrq(priv->vector);
343 }
344 
GetPhySpeedString(int32_t speed)345 static const char *GetPhySpeedString(int32_t speed)
346 {
347     switch (speed) {
348         case PHY_SPEED_10:
349             return "10Mbps";
350         case PHY_SPEED_100:
351             return "100Mbps";
352         case PHY_SPEED_1000:
353             return "1Gbps";
354         case PHY_SPEED_UNKNOWN:
355             return "Unknown";
356         default:
357             return "Unsupported";
358     }
359 }
360 
HiethLinkStatusChanged(struct EthDevice * ethDevice)361 void HiethLinkStatusChanged(struct EthDevice *ethDevice)
362 {
363     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
364     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
365     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
366     unsigned long val = 0;
367     int32_t phyMode = 0;
368     int32_t duplex;
369     int32_t speed;
370 
371     duplex = MiiphyDuplex(ld, priv->phy);
372     speed = MiiphySpeed(ld, priv->phy);
373 
374     if (IsLinkUp(ethDevice)) {
375         val |= HIETH_LINKED;
376     }
377 
378     if (duplex) {
379         val |= HIETH_DUP_FULL;
380     }
381 
382     if (speed == PHY_SPEED_100) {
383         val |= HIETH_SPD_100M;
384     }
385 
386     switch (priv->phy->phyMode) {
387         case PHY_INTERFACE_MODE_MII:
388             phyMode = HIETH_PHY_MII_MODE;
389             break;
390         case PHY_INTERFACE_MODE_RMII:
391             phyMode = HIETH_PHY_RMII_MODE;
392             break;
393         default:
394             HDF_LOGE("not supported mode: %d", priv->phy->phyMode);
395             break;
396     }
397 
398     HiethSetLinkStat(ld, val);
399     HiethSetMiiMode(ld, phyMode);
400 
401     if (IsLinkUp(ethDevice)) {
402         PRINTK("Link is Up - %s/%s\n", GetPhySpeedString(speed), (PHY_DUPLEX_FULL == duplex) ? "Full" : "Half");
403     } else {
404         PRINTK("Link is Down\n");
405     }
406 }
407 
HiethSetHwaddr(struct EthDevice * ethDevice,uint8_t * addr,uint8_t len)408 uint8_t HiethSetHwaddr(struct EthDevice *ethDevice, uint8_t *addr, uint8_t len)
409 {
410     HiethPriv *priv = (HiethPriv *)((struct EthDrvSc *)ethDevice->priv)->driverPrivate;
411 
412     if (IsMulticastEtherAddr(addr)) {
413         HDF_LOGE("WARN: config a muticast mac address, please check!");
414         return HDF_FAILURE;
415     }
416 
417     if (len != ETHER_ADDR_LEN) {
418         HDF_LOGE("WARN: config wrong mac address len=%u", len);
419         return HDF_FAILURE;
420     }
421 
422     HiethHwSetMacAddress(&(g_stHiethPlatformData[priv->index].stNetdevLocal), 1, addr);
423     return HDF_SUCCESS;
424 }
425 
HisiEthSetPhyMode(const char * phyMode)426 int32_t HisiEthSetPhyMode(const char *phyMode)
427 {
428     int32_t i;
429 
430     for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
431         if (!strcasecmp(phyMode, PhyModes(i))) {
432             g_userSetPhyMode = PHY_MODE_SET;
433             g_phyModeVal = i;
434             return HDF_SUCCESS;
435         }
436     }
437     return HDF_FAILURE;
438 }
439 
HiethHwInit(struct EthDevice * ethDevice)440 bool HiethHwInit(struct EthDevice *ethDevice)
441 {
442     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
443     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
444     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
445     uint32_t phyState = 0;
446     uint32_t id;
447     int32_t addr;
448 
449     OsalSpinInit(&hiethGlbRegLock);
450 
451     ld->txq = priv->ram->txqInfo;
452     ld->iobase = (char *)((uintptr_t)priv->base);
453 
454     HiethHwMacCoreInit(ld);
455 
456     if (g_userSetPhyMode == PHY_MODE_SET) {
457         priv->phy->phyMode = g_phyModeVal;
458         HDF_LOGE("hisi_eth: User set phy mode=%s", PhyModes(priv->phy->phyMode));
459     } else {
460         priv->phy->phyMode = ld->phyMode;
461         HDF_LOGE("hisi_eth: User did not set phy mode, use default=%s", PhyModes(priv->phy->phyMode));
462     }
463 
464     if (!priv->phy->initDone) {
465         HiethHwExternalPhyReset();
466         mdelay(300);
467         priv->phy->initDone = true;
468 
469         if (g_userSetPhyAddr == PHY_ADDR_SET) {
470             priv->phy->phyAddr = g_phyAddrVal;
471             HDF_LOGE("hisi_eth: User set phy addr=%d", priv->phy->phyAddr);
472 
473             id = ScanPhyId(ld, priv->phy->phyAddr);
474             if (PHY_ID_INVALID(id)) {
475                 HDF_LOGE("Can't find PHY device - id: %x", id);
476                 priv->phy->initDone = false;
477                 goto ERR_OUT;
478             }
479         } else {
480             HDF_LOGE("hisi_eth: User did not set phy addr, auto scan...");
481 
482             for (addr = MAX_PHY_ADDR; addr >= 0; addr--) {
483                 id = ScanPhyId(ld, addr);
484                 if (PHY_ID_INVALID(id)) {
485                     continue;
486                 }
487                 break;
488             }
489 
490             if (addr < 0) {
491                 HDF_LOGE("Can't find PHY device - id: %x", id);
492                 priv->phy->initDone = false;
493                 goto ERR_OUT;
494             }
495 
496             priv->phy->phyAddr = addr;
497         }
498         ld->phyId = id;
499     }
500 
501     HiethHwExternalPhyReset();
502     mdelay(100);
503     HiethFephyTrim(ld, priv->phy);
504     HDF_LOGE("Detected phy addr %d, phyid: 0x%x.", priv->phy->phyAddr, ld->phyId);
505 
506     if (!priv->phy->initDone) {
507         goto ERR_OUT;
508     }
509 
510     HiethGetPhyStat(ld, priv->phy, &phyState);
511 
512     if (OsalRegisterIrq(priv->vector, OSAL_IRQF_TRIGGER_NONE, HisiEthIsr, "ETH", (void *)drvSc) != HDF_SUCCESS) {
513         HDF_LOGE("register irq failed");
514         goto ERR_OUT;
515     }
516     OsalEnableIrq(priv->vector);
517     return true;
518 ERR_OUT:
519     return false;
520 }
521 
RegisterHiethData(struct EthDevice * ethDevice)522 void RegisterHiethData(struct EthDevice *ethDevice)
523 {
524     int32_t ret;
525     uint32_t data;
526 
527     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
528     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
529     struct HiethNetdevLocal *ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
530     ret = CreateEthIrqThread(ethDevice);
531     if (ret != HDF_SUCCESS) {
532         HDF_LOGE("create eth thread failed");
533         return;
534     }
535     /* clear all interrupts */
536     HiethClearIrqstatus(ld, UD_BIT_NAME(BITS_IRQS_MASK));
537     priv->rxFeed = 0;
538     priv->rxRelease = 0;
539     HiethFeedHw(ld, priv);
540 
541     if (OsalTimerCreate(&priv->phyTimer, PHY_STATE_TIME, PhyStateMachine, (uintptr_t)ethDevice) != HDF_SUCCESS) {
542         HDF_LOGE("create phy state machine timer failed");
543         return;
544     }
545     if (OsalTimerStartLoop(&priv->phyTimer) != HDF_SUCCESS) {
546         HDF_LOGE("start phy state machine timer failed");
547         return;
548     }
549 
550     HiethIrqEnable(ld, UD_BIT_NAME(HIETH_INT_MULTI_RXRDY) | UD_BIT_NAME(HIETH_INT_TXQUE_RDY));
551     HiethWritelBits(ld, 1, GLB_RW_IRQ_ENA, UD_BIT_NAME(BITS_IRQS_ENA));
552     HiethWritelBits(ld, 1, GLB_RW_IRQ_ENA, BITS_IRQS_ENA_ALLPORT);
553 #ifdef HIETH_TSO_SUPPORTED
554     HiethIrqEnable(ld, UD_BIT_NAME(HIETH_INT_TX_ERR));
555 #endif
556 
557     data = readl(ld->iobase + 0x210);
558     data |= 0x40000000; /* do CRC check in mac */
559     writel(data, ld->iobase + 0x210);
560 }
561 
562 static struct EthHwrFuns g_stEthnetDrvFun = {
563     .canSend = HiethCanSend,
564     .send = HiethSend,
565     .deliver = HiethDeliver,
566     .intVector = HiethIntVector,
567 };
568 
InitEthnetDrvFun(struct EthDrvSc * drvFun)569 void InitEthnetDrvFun(struct EthDrvSc *drvFun)
570 {
571     if (drvFun == NULL) {
572         HDF_LOGE("%s: input is NULL!", __func__);
573         return;
574     }
575     drvFun->funs = &g_stEthnetDrvFun;
576 }
577 
HiethInit(struct EthDevice * ethDevice)578 int32_t HiethInit(struct EthDevice *ethDevice)
579 {
580     if (ethDevice == NULL) {
581         HDF_LOGE("%s input is NULL!", __func__);
582         return HDF_FAILURE;
583     }
584 
585     g_stHiethPlatformData = (struct HiethPlatformData *)OsalMemCalloc(sizeof(struct HiethPlatformData));
586     if (!g_stHiethPlatformData) {
587         HDF_LOGE("EthDrvSc OsalMemCalloc HiethPlatformData error!");
588         return HDF_FAILURE;
589     }
590     OsalSpinInit(&(g_stHiethPlatformData[0].stNetdevLocal.tx_lock));
591     OsalSpinInit(&(g_stHiethPlatformData[0].stNetdevLocal.rx_lock));
592 
593     struct ConfigEthDevList *config = ethDevice->config;
594     g_stHiethPlatformData[0].stNetdevLocal.port = config->port;
595     g_stHiethPlatformData[0].stNetdevLocal.depth.hwXmitq = config->hwXmitq;
596     g_stHiethPlatformData[0].stNetdevLocal.qSize = config->qSize;
597     g_stHiethPlatformData[0].stNetdevLocal.mdioFrqdiv = config->ethMac.mdioFrqDiv;
598     g_stHiethPlatformData[0].stNetdevLocal.txBusy = config->ethMac.txBusy;
599     g_stHiethPlatformData[0].stNetdevLocal.phyMode = config->ethPhy.phyMode;
600     (void)LOS_EventInit(&(g_stHiethPlatformData[0].stEvent));
601 
602     HiethHwInit(ethDevice);
603     return HDF_SUCCESS;
604 }
605 
GetHiethPlatformData(void)606 struct HiethPlatformData *GetHiethPlatformData(void)
607 {
608     return g_stHiethPlatformData;
609 }
610 
GetHiethNetDevLocal(struct EthDevice * ethDevice)611 struct HiethNetdevLocal *GetHiethNetDevLocal(struct EthDevice *ethDevice)
612 {
613     struct HiethNetdevLocal *ld = NULL;
614     if (ethDevice == NULL) {
615         HDF_LOGE("%s input is NULL", __func__);
616         return NULL;
617     }
618     struct EthDrvSc *drvSc = (struct EthDrvSc *)ethDevice->priv;
619     HiethPriv *priv = (HiethPriv *)drvSc->driverPrivate;
620     ld = &(g_stHiethPlatformData[priv->index].stNetdevLocal);
621     if (ld == NULL) {
622         HDF_LOGE("%s get HiethNetdevLocal fail", __func__);
623         return NULL;
624     }
625     return ld;
626 }
627 
ethnet_hieth_init(struct EthDevice * ethDevice)628 int ethnet_hieth_init(struct EthDevice *ethDevice)
629 {
630     return HDF_SUCCESS;
631 }
632 
get_defaultNetif(struct netif ** pnetif,struct EthDrvSc * drvSc)633 void get_defaultNetif(struct netif **pnetif, struct EthDrvSc *drvSc)
634 {
635     (void)pnetif;
636     (void)drvSc;
637 }
638