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