11bd4fe43Sopenharmony_ci/*
21bd4fe43Sopenharmony_ci * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
31bd4fe43Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41bd4fe43Sopenharmony_ci * you may not use this file except in compliance with the License.
51bd4fe43Sopenharmony_ci * You may obtain a copy of the License at
61bd4fe43Sopenharmony_ci *
71bd4fe43Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
81bd4fe43Sopenharmony_ci *
91bd4fe43Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101bd4fe43Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111bd4fe43Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121bd4fe43Sopenharmony_ci * See the License for the specific language governing permissions and
131bd4fe43Sopenharmony_ci * limitations under the License.
141bd4fe43Sopenharmony_ci */
151bd4fe43Sopenharmony_ci
161bd4fe43Sopenharmony_ci#include "hieth_phy.h"
171bd4fe43Sopenharmony_ci#include "ctrl.h"
181bd4fe43Sopenharmony_ci#include "eth_phy.h"
191bd4fe43Sopenharmony_ci#include <linux/delay.h>
201bd4fe43Sopenharmony_ci#include "mdio.h"
211bd4fe43Sopenharmony_ci#include <netinet/if_ether.h>
221bd4fe43Sopenharmony_ci#include <netinet/in.h>
231bd4fe43Sopenharmony_ci#include <netinet/ip.h>
241bd4fe43Sopenharmony_ci#include <netinet/tcp.h>
251bd4fe43Sopenharmony_ci#include "net_adapter.h"
261bd4fe43Sopenharmony_ci
271bd4fe43Sopenharmony_ci#define WAIT_LINK_UP_TIMES      100
281bd4fe43Sopenharmony_ci#define WAIT_PHY_AUTO_NEG_TIMES 25
291bd4fe43Sopenharmony_ci#define PRIV_DATA_VECTOR    0x40
301bd4fe43Sopenharmony_ci#define PRIV_DATA_BASE      0x88010000
311bd4fe43Sopenharmony_ci#define ETH_PHY_STAT_LINK   0x0001  /* Link up/down */
321bd4fe43Sopenharmony_ci
331bd4fe43Sopenharmony_ciint32_t CreateHiethPrivData(HiethPriv *pstPrivData)
341bd4fe43Sopenharmony_ci{
351bd4fe43Sopenharmony_ci    pstPrivData->phy = (EthPhyAccess *)OsalMemCalloc(sizeof(EthPhyAccess));
361bd4fe43Sopenharmony_ci    if (pstPrivData->phy == NULL) {
371bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : EthPhyAccess OsalMemCalloc is fail!", __func__);
381bd4fe43Sopenharmony_ci        goto PRIVDATA_PHY_INIT_FAIL;
391bd4fe43Sopenharmony_ci    }
401bd4fe43Sopenharmony_ci    pstPrivData->phy->initDone = false;
411bd4fe43Sopenharmony_ci    pstPrivData->phy->init = NULL;
421bd4fe43Sopenharmony_ci    pstPrivData->phy->reset = NULL;
431bd4fe43Sopenharmony_ci
441bd4fe43Sopenharmony_ci    pstPrivData->ram = (EthRamCfg *)OsalMemCalloc(sizeof(EthRamCfg));
451bd4fe43Sopenharmony_ci    if (pstPrivData->ram == NULL) {
461bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : EthRamCfg OsalMemCalloc is fail!", __func__);
471bd4fe43Sopenharmony_ci        goto PRIVDATA_RAM_INIT_FAIL;
481bd4fe43Sopenharmony_ci    }
491bd4fe43Sopenharmony_ci    pstPrivData->ram->txqInfo = OsalMemCalloc(HIETH_HWQ_TXQ_SIZE * sizeof(struct TxPktInfo));
501bd4fe43Sopenharmony_ci    if (!pstPrivData->ram->txqInfo) {
511bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : TxPktInfo OsalMemCalloc is fail!", __func__);
521bd4fe43Sopenharmony_ci        goto PRIVDATA_TXQ_INFO_INIT_FAIL;
531bd4fe43Sopenharmony_ci    }
541bd4fe43Sopenharmony_ci    pstPrivData->ram->rxNetbuf = OsalMemCalloc(HIETH_HWQ_RXQ_DEPTH * sizeof(NetBuf *));
551bd4fe43Sopenharmony_ci    if (!pstPrivData->ram->rxNetbuf) {
561bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : netBuf OsalMemCalloc is fail!", __func__);
571bd4fe43Sopenharmony_ci        goto PRIVDATA_NETBUFF_INIT_FAIL;
581bd4fe43Sopenharmony_ci    }
591bd4fe43Sopenharmony_ci
601bd4fe43Sopenharmony_ci    pstPrivData->ram->pbufInfo = OsalMemCalloc(HIETH_HWQ_TXQ_SIZE * sizeof(struct PbufInfo));
611bd4fe43Sopenharmony_ci    if (!pstPrivData->ram->pbufInfo) {
621bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : PbufInfo OsalMemCalloc is fail!", __func__);
631bd4fe43Sopenharmony_ci        goto PRIVDATA_PBUF_INFO_INIT_FAIL;
641bd4fe43Sopenharmony_ci    }
651bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
661bd4fe43Sopenharmony_ci
671bd4fe43Sopenharmony_ciPRIVDATA_PBUF_INFO_INIT_FAIL:
681bd4fe43Sopenharmony_ci    OsalMemFree((void *)pstPrivData->ram->rxNetbuf);
691bd4fe43Sopenharmony_ciPRIVDATA_NETBUFF_INIT_FAIL:
701bd4fe43Sopenharmony_ci    OsalMemFree((void *)pstPrivData->ram->txqInfo);
711bd4fe43Sopenharmony_ciPRIVDATA_TXQ_INFO_INIT_FAIL:
721bd4fe43Sopenharmony_ci    OsalMemFree((void *)pstPrivData->ram);
731bd4fe43Sopenharmony_ciPRIVDATA_RAM_INIT_FAIL:
741bd4fe43Sopenharmony_ci    OsalMemFree((void *)pstPrivData->phy);
751bd4fe43Sopenharmony_ciPRIVDATA_PHY_INIT_FAIL:
761bd4fe43Sopenharmony_ci    OsalMemFree((void *)pstPrivData);
771bd4fe43Sopenharmony_ci    return HDF_FAILURE;
781bd4fe43Sopenharmony_ci}
791bd4fe43Sopenharmony_ci
801bd4fe43Sopenharmony_ciint32_t InitHiethDriver(struct EthDevice *ethDevice)
811bd4fe43Sopenharmony_ci{
821bd4fe43Sopenharmony_ci    int32_t ret;
831bd4fe43Sopenharmony_ci    HiethPriv *pstPrivData = NULL;
841bd4fe43Sopenharmony_ci    if (ethDevice == NULL) {
851bd4fe43Sopenharmony_ci        HDF_LOGE("%s input is NULL!", __func__);
861bd4fe43Sopenharmony_ci        return HDF_FAILURE;
871bd4fe43Sopenharmony_ci    }
881bd4fe43Sopenharmony_ci    ret = EthernetInitNetdev(ethDevice->netdev);
891bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
901bd4fe43Sopenharmony_ci        HDF_LOGE("%s failed to init ethernet netDev", __func__);
911bd4fe43Sopenharmony_ci        return HDF_FAILURE;
921bd4fe43Sopenharmony_ci    }
931bd4fe43Sopenharmony_ci
941bd4fe43Sopenharmony_ci    pstPrivData = (HiethPriv *)OsalMemCalloc(sizeof(HiethPriv));
951bd4fe43Sopenharmony_ci    if (pstPrivData == NULL) {
961bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : HiethPriv OsalMemCalloc is fail!", __func__);
971bd4fe43Sopenharmony_ci        return HDF_FAILURE;
981bd4fe43Sopenharmony_ci    }
991bd4fe43Sopenharmony_ci    pstPrivData->index = 0;
1001bd4fe43Sopenharmony_ci    pstPrivData->vector = PRIV_DATA_VECTOR;
1011bd4fe43Sopenharmony_ci    pstPrivData->base = PRIV_DATA_BASE;
1021bd4fe43Sopenharmony_ci
1031bd4fe43Sopenharmony_ci    if (CreateHiethPrivData(pstPrivData) != HDF_SUCCESS) {
1041bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : CreateHiethPrivData is fail!", __func__);
1051bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1061bd4fe43Sopenharmony_ci    }
1071bd4fe43Sopenharmony_ci    struct EthDrvSc *pstDrvInfo = (struct EthDrvSc *)OsalMemCalloc(sizeof(struct EthDrvSc));
1081bd4fe43Sopenharmony_ci    if (pstDrvInfo == NULL) {
1091bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : EthDrvSc OsalMemCalloc error!", __func__);
1101bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1111bd4fe43Sopenharmony_ci    }
1121bd4fe43Sopenharmony_ci    pstDrvInfo->devName = "eth1";
1131bd4fe43Sopenharmony_ci    pstDrvInfo->driverPrivate = (void *)pstPrivData;
1141bd4fe43Sopenharmony_ci    InitEthnetDrvFun(pstDrvInfo);
1151bd4fe43Sopenharmony_ci    ethDevice->priv = pstDrvInfo;
1161bd4fe43Sopenharmony_ci    ret = HiethInit(ethDevice);
1171bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1181bd4fe43Sopenharmony_ci        HDF_LOGE("%s fail : HiethHwInit error!", __func__);
1191bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1201bd4fe43Sopenharmony_ci    }
1211bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1221bd4fe43Sopenharmony_ci}
1231bd4fe43Sopenharmony_ci
1241bd4fe43Sopenharmony_ciint32_t DeinitHiethDriver(struct EthDevice *ethDevice)
1251bd4fe43Sopenharmony_ci{
1261bd4fe43Sopenharmony_ci    if (ethDevice == NULL) {
1271bd4fe43Sopenharmony_ci        HDF_LOGE("%s input ethDevice is NULL!", __func__);
1281bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1291bd4fe43Sopenharmony_ci    }
1301bd4fe43Sopenharmony_ci
1311bd4fe43Sopenharmony_ci    struct EthDrvSc *drvInfo = (struct EthDrvSc *)(ethDevice->priv);
1321bd4fe43Sopenharmony_ci    if (drvInfo == NULL) {
1331bd4fe43Sopenharmony_ci        return HDF_SUCCESS;
1341bd4fe43Sopenharmony_ci    }
1351bd4fe43Sopenharmony_ci    HiethPriv *priv = (HiethPriv *)drvInfo->driverPrivate;
1361bd4fe43Sopenharmony_ci    if (priv == NULL) {
1371bd4fe43Sopenharmony_ci        OsalMemFree(drvInfo);
1381bd4fe43Sopenharmony_ci        return HDF_SUCCESS;
1391bd4fe43Sopenharmony_ci    }
1401bd4fe43Sopenharmony_ci    UnRegisterTimerFunction(ethDevice);
1411bd4fe43Sopenharmony_ci
1421bd4fe43Sopenharmony_ci    if (priv->phy != NULL) {
1431bd4fe43Sopenharmony_ci        OsalMemFree((void *)priv->phy);
1441bd4fe43Sopenharmony_ci    }
1451bd4fe43Sopenharmony_ci    if (priv->ram != NULL) {
1461bd4fe43Sopenharmony_ci        if (priv->ram->txqInfo != NULL) {
1471bd4fe43Sopenharmony_ci            OsalMemFree((void *)priv->ram->txqInfo);
1481bd4fe43Sopenharmony_ci        }
1491bd4fe43Sopenharmony_ci        if (priv->ram->rxNetbuf != NULL) {
1501bd4fe43Sopenharmony_ci            OsalMemFree((void *)priv->ram->rxNetbuf);
1511bd4fe43Sopenharmony_ci        }
1521bd4fe43Sopenharmony_ci        if (priv->ram->pbufInfo != NULL) {
1531bd4fe43Sopenharmony_ci            OsalMemFree((void *)priv->ram->pbufInfo);
1541bd4fe43Sopenharmony_ci        }
1551bd4fe43Sopenharmony_ci        OsalMemFree((void *)priv->ram);
1561bd4fe43Sopenharmony_ci    }
1571bd4fe43Sopenharmony_ci    OsalMemFree(priv);
1581bd4fe43Sopenharmony_ci    OsalMemFree(drvInfo);
1591bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1601bd4fe43Sopenharmony_ci}
161