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, ¶) != 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