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 "ctrl.h"
18 #include "eth_phy.h"
19 #include <linux/delay.h>
20 #include "mdio.h"
21 #include <netinet/if_ether.h>
22 #include <netinet/in.h>
23 #include <netinet/ip.h>
24 #include <netinet/tcp.h>
25 #include "net_adapter.h"
26
27 #define WAIT_LINK_UP_TIMES 100
28 #define WAIT_PHY_AUTO_NEG_TIMES 25
29 #define PRIV_DATA_VECTOR 0x40
30 #define PRIV_DATA_BASE 0x88010000
31 #define ETH_PHY_STAT_LINK 0x0001 /* Link up/down */
32
CreateHiethPrivData(HiethPriv * pstPrivData)33 int32_t CreateHiethPrivData(HiethPriv *pstPrivData)
34 {
35 pstPrivData->phy = (EthPhyAccess *)OsalMemCalloc(sizeof(EthPhyAccess));
36 if (pstPrivData->phy == NULL) {
37 HDF_LOGE("%s fail : EthPhyAccess OsalMemCalloc is fail!", __func__);
38 goto PRIVDATA_PHY_INIT_FAIL;
39 }
40 pstPrivData->phy->initDone = false;
41 pstPrivData->phy->init = NULL;
42 pstPrivData->phy->reset = NULL;
43
44 pstPrivData->ram = (EthRamCfg *)OsalMemCalloc(sizeof(EthRamCfg));
45 if (pstPrivData->ram == NULL) {
46 HDF_LOGE("%s fail : EthRamCfg OsalMemCalloc is fail!", __func__);
47 goto PRIVDATA_RAM_INIT_FAIL;
48 }
49 pstPrivData->ram->txqInfo = OsalMemCalloc(HIETH_HWQ_TXQ_SIZE * sizeof(struct TxPktInfo));
50 if (!pstPrivData->ram->txqInfo) {
51 HDF_LOGE("%s fail : TxPktInfo OsalMemCalloc is fail!", __func__);
52 goto PRIVDATA_TXQ_INFO_INIT_FAIL;
53 }
54 pstPrivData->ram->rxNetbuf = OsalMemCalloc(HIETH_HWQ_RXQ_DEPTH * sizeof(NetBuf *));
55 if (!pstPrivData->ram->rxNetbuf) {
56 HDF_LOGE("%s fail : netBuf OsalMemCalloc is fail!", __func__);
57 goto PRIVDATA_NETBUFF_INIT_FAIL;
58 }
59
60 pstPrivData->ram->pbufInfo = OsalMemCalloc(HIETH_HWQ_TXQ_SIZE * sizeof(struct PbufInfo));
61 if (!pstPrivData->ram->pbufInfo) {
62 HDF_LOGE("%s fail : PbufInfo OsalMemCalloc is fail!", __func__);
63 goto PRIVDATA_PBUF_INFO_INIT_FAIL;
64 }
65 return HDF_SUCCESS;
66
67 PRIVDATA_PBUF_INFO_INIT_FAIL:
68 OsalMemFree((void *)pstPrivData->ram->rxNetbuf);
69 PRIVDATA_NETBUFF_INIT_FAIL:
70 OsalMemFree((void *)pstPrivData->ram->txqInfo);
71 PRIVDATA_TXQ_INFO_INIT_FAIL:
72 OsalMemFree((void *)pstPrivData->ram);
73 PRIVDATA_RAM_INIT_FAIL:
74 OsalMemFree((void *)pstPrivData->phy);
75 PRIVDATA_PHY_INIT_FAIL:
76 OsalMemFree((void *)pstPrivData);
77 return HDF_FAILURE;
78 }
79
InitHiethDriver(struct EthDevice * ethDevice)80 int32_t InitHiethDriver(struct EthDevice *ethDevice)
81 {
82 int32_t ret;
83 HiethPriv *pstPrivData = NULL;
84 if (ethDevice == NULL) {
85 HDF_LOGE("%s input is NULL!", __func__);
86 return HDF_FAILURE;
87 }
88 ret = EthernetInitNetdev(ethDevice->netdev);
89 if (ret != HDF_SUCCESS) {
90 HDF_LOGE("%s failed to init ethernet netDev", __func__);
91 return HDF_FAILURE;
92 }
93
94 pstPrivData = (HiethPriv *)OsalMemCalloc(sizeof(HiethPriv));
95 if (pstPrivData == NULL) {
96 HDF_LOGE("%s fail : HiethPriv OsalMemCalloc is fail!", __func__);
97 return HDF_FAILURE;
98 }
99 pstPrivData->index = 0;
100 pstPrivData->vector = PRIV_DATA_VECTOR;
101 pstPrivData->base = PRIV_DATA_BASE;
102
103 if (CreateHiethPrivData(pstPrivData) != HDF_SUCCESS) {
104 HDF_LOGE("%s fail : CreateHiethPrivData is fail!", __func__);
105 return HDF_FAILURE;
106 }
107 struct EthDrvSc *pstDrvInfo = (struct EthDrvSc *)OsalMemCalloc(sizeof(struct EthDrvSc));
108 if (pstDrvInfo == NULL) {
109 HDF_LOGE("%s fail : EthDrvSc OsalMemCalloc error!", __func__);
110 return HDF_FAILURE;
111 }
112 pstDrvInfo->devName = "eth1";
113 pstDrvInfo->driverPrivate = (void *)pstPrivData;
114 InitEthnetDrvFun(pstDrvInfo);
115 ethDevice->priv = pstDrvInfo;
116 ret = HiethInit(ethDevice);
117 if (ret != HDF_SUCCESS) {
118 HDF_LOGE("%s fail : HiethHwInit error!", __func__);
119 return HDF_FAILURE;
120 }
121 return HDF_SUCCESS;
122 }
123
DeinitHiethDriver(struct EthDevice * ethDevice)124 int32_t DeinitHiethDriver(struct EthDevice *ethDevice)
125 {
126 if (ethDevice == NULL) {
127 HDF_LOGE("%s input ethDevice is NULL!", __func__);
128 return HDF_FAILURE;
129 }
130
131 struct EthDrvSc *drvInfo = (struct EthDrvSc *)(ethDevice->priv);
132 if (drvInfo == NULL) {
133 return HDF_SUCCESS;
134 }
135 HiethPriv *priv = (HiethPriv *)drvInfo->driverPrivate;
136 if (priv == NULL) {
137 OsalMemFree(drvInfo);
138 return HDF_SUCCESS;
139 }
140 UnRegisterTimerFunction(ethDevice);
141
142 if (priv->phy != NULL) {
143 OsalMemFree((void *)priv->phy);
144 }
145 if (priv->ram != NULL) {
146 if (priv->ram->txqInfo != NULL) {
147 OsalMemFree((void *)priv->ram->txqInfo);
148 }
149 if (priv->ram->rxNetbuf != NULL) {
150 OsalMemFree((void *)priv->ram->rxNetbuf);
151 }
152 if (priv->ram->pbufInfo != NULL) {
153 OsalMemFree((void *)priv->ram->pbufInfo);
154 }
155 OsalMemFree((void *)priv->ram);
156 }
157 OsalMemFree(priv);
158 OsalMemFree(drvInfo);
159 return HDF_SUCCESS;
160 }
161