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 "ctrl.h"
171bd4fe43Sopenharmony_ci#include "eth_drv.h"
181bd4fe43Sopenharmony_ci#include "hieth_pri.h"
191bd4fe43Sopenharmony_ci#include "hdf_netbuf.h"
201bd4fe43Sopenharmony_ci#include "mdio.h"
211bd4fe43Sopenharmony_ci#include <linux/delay.h>
221bd4fe43Sopenharmony_ci#include <netinet/ip.h>
231bd4fe43Sopenharmony_ci#include <netinet/in.h>
241bd4fe43Sopenharmony_ci#include <netinet/tcp.h>
251bd4fe43Sopenharmony_ci#include <netinet/if_ether.h>
261bd4fe43Sopenharmony_ci
271bd4fe43Sopenharmony_cistatic inline int32_t FephyExpandedRead(struct HiethNetdevLocal *ld, int32_t phyAddr, int32_t regNum)
281bd4fe43Sopenharmony_ci{
291bd4fe43Sopenharmony_ci    HiethMdioWrite(ld, phyAddr, MII_EXPMA, regNum);
301bd4fe43Sopenharmony_ci    return HiethMdioRead(ld, phyAddr, MII_EXPMD);
311bd4fe43Sopenharmony_ci}
321bd4fe43Sopenharmony_ci
331bd4fe43Sopenharmony_cistatic inline int32_t FephyExpandedWrite(struct HiethNetdevLocal *ld, int32_t phyAddr, int32_t regNum, int32_t val)
341bd4fe43Sopenharmony_ci{
351bd4fe43Sopenharmony_ci    HiethMdioWrite(ld, phyAddr, MII_EXPMA, regNum);
361bd4fe43Sopenharmony_ci    return HiethMdioWrite(ld, phyAddr, MII_EXPMD, val);
371bd4fe43Sopenharmony_ci}
381bd4fe43Sopenharmony_ci
391bd4fe43Sopenharmony_cistatic void HiethFephyUseDefaultTrim(struct HiethNetdevLocal *ld, const EthPhyAccess *phyAccess)
401bd4fe43Sopenharmony_ci{
411bd4fe43Sopenharmony_ci    uint16_t val;
421bd4fe43Sopenharmony_ci    int32_t timeout = 3;
431bd4fe43Sopenharmony_ci
441bd4fe43Sopenharmony_ci    do {
451bd4fe43Sopenharmony_ci        msleep(250);
461bd4fe43Sopenharmony_ci        val = FephyExpandedRead(ld, phyAccess->phyAddr, REG_DEF_ATE);
471bd4fe43Sopenharmony_ci        val &= BIT_AUTOTRIM_DONE;  /* (0x1 << 0) */
481bd4fe43Sopenharmony_ci    } while (!val && --timeout);
491bd4fe43Sopenharmony_ci
501bd4fe43Sopenharmony_ci    if (!timeout) {
511bd4fe43Sopenharmony_ci        HDF_LOGE("festa PHY wait autotrim done timeout!");
521bd4fe43Sopenharmony_ci    }
531bd4fe43Sopenharmony_ci    mdelay(5);
541bd4fe43Sopenharmony_ci}
551bd4fe43Sopenharmony_ci
561bd4fe43Sopenharmony_civoid HiethFephyTrim(struct HiethNetdevLocal *ld, const EthPhyAccess *phyAccess)
571bd4fe43Sopenharmony_ci{
581bd4fe43Sopenharmony_ci    uint32_t val;
591bd4fe43Sopenharmony_ci    int32_t timeout = 50;
601bd4fe43Sopenharmony_ci    uint8_t ldSet, ldoSet, tuning;
611bd4fe43Sopenharmony_ci
621bd4fe43Sopenharmony_ci    val = readl(SYS_CTRL_REG_BASE + 0x8024);
631bd4fe43Sopenharmony_ci    ldSet = (val >> BIT_OFFSET_LD_SET) & BIT_MASK_LD_SET;
641bd4fe43Sopenharmony_ci    ldoSet = (val >> BIT_OFFSET_LDO_SET) & BIT_MASK_LDO_SET;
651bd4fe43Sopenharmony_ci    tuning = (val >> BIT_OFFSET_R_TUNING) & BIT_MASK_R_TUNING;
661bd4fe43Sopenharmony_ci    if ((!ldSet) && (!ldoSet) && (!tuning)) {
671bd4fe43Sopenharmony_ci        HiethFephyUseDefaultTrim(ld, phyAccess);
681bd4fe43Sopenharmony_ci        return;
691bd4fe43Sopenharmony_ci    }
701bd4fe43Sopenharmony_ci    val = FephyExpandedRead(ld, phyAccess->phyAddr, REG_LD_AM);
711bd4fe43Sopenharmony_ci    val = (val & ~BIT_MASK_LD_SET) | (ldSet & BIT_MASK_LD_SET);
721bd4fe43Sopenharmony_ci    FephyExpandedWrite(ld, phyAccess->phyAddr, REG_LD_AM, val);
731bd4fe43Sopenharmony_ci
741bd4fe43Sopenharmony_ci    val = FephyExpandedRead(ld, phyAccess->phyAddr, REG_LDO_AM);
751bd4fe43Sopenharmony_ci    val = (val & ~BIT_MASK_LDO_SET) | (ldoSet & BIT_MASK_LDO_SET);
761bd4fe43Sopenharmony_ci    FephyExpandedWrite(ld, phyAccess->phyAddr, REG_LDO_AM, val);
771bd4fe43Sopenharmony_ci
781bd4fe43Sopenharmony_ci    val = FephyExpandedRead(ld, phyAccess->phyAddr, REG_R_TUNING);
791bd4fe43Sopenharmony_ci    val = (val & ~BIT_MASK_R_TUNING) | (tuning & BIT_MASK_R_TUNING);
801bd4fe43Sopenharmony_ci    FephyExpandedWrite(ld, phyAccess->phyAddr, REG_R_TUNING, val);
811bd4fe43Sopenharmony_ci
821bd4fe43Sopenharmony_ci    val = FephyExpandedRead(ld, phyAccess->phyAddr, REG_WR_DONE);
831bd4fe43Sopenharmony_ci    if (val & BIT_CFG_ACK) {
841bd4fe43Sopenharmony_ci        HDF_LOGE("festa PHY 0x3053 bit CFG_ACK value: 1");
851bd4fe43Sopenharmony_ci    }
861bd4fe43Sopenharmony_ci    val = val | BIT_CFG_DONE;
871bd4fe43Sopenharmony_ci
881bd4fe43Sopenharmony_ci    FephyExpandedWrite(ld, phyAccess->phyAddr, REG_WR_DONE, val);
891bd4fe43Sopenharmony_ci
901bd4fe43Sopenharmony_ci    do {
911bd4fe43Sopenharmony_ci        msleep(5);
921bd4fe43Sopenharmony_ci        val = FephyExpandedRead(ld, phyAccess->phyAddr, REG_WR_DONE);
931bd4fe43Sopenharmony_ci        val &= BIT_CFG_ACK;
941bd4fe43Sopenharmony_ci    } while (!val && --timeout);
951bd4fe43Sopenharmony_ci
961bd4fe43Sopenharmony_ci    if (!timeout) {
971bd4fe43Sopenharmony_ci        HDF_LOGE("festa PHY 0x3053 wait bit CFG_ACK timeout!\n");
981bd4fe43Sopenharmony_ci    }
991bd4fe43Sopenharmony_ci
1001bd4fe43Sopenharmony_ci    mdelay(5);
1011bd4fe43Sopenharmony_ci}
1021bd4fe43Sopenharmony_ci
1031bd4fe43Sopenharmony_cistatic inline void HiethEnableRxcsumDrop(struct HiethNetdevLocal *ld, bool drop)
1041bd4fe43Sopenharmony_ci{
1051bd4fe43Sopenharmony_ci    HiethWritelBits(ld, drop, UD_REG_NAME(GLB_RX_COE_CTRL), BITS_COE_IPHDR_DROP);
1061bd4fe43Sopenharmony_ci    HiethWritelBits(ld, false, UD_REG_NAME(GLB_RX_COE_CTRL), BITS_COE_PAYLOAD_DROP);
1071bd4fe43Sopenharmony_ci    HiethWritelBits(ld, drop, UD_REG_NAME(GLB_RX_COE_CTRL), BITS_COE_IPV6_UDP_ZERO_DROP);
1081bd4fe43Sopenharmony_ci}
1091bd4fe43Sopenharmony_ci
1101bd4fe43Sopenharmony_civoid HiethHwMacCoreInit(struct HiethNetdevLocal *ld)
1111bd4fe43Sopenharmony_ci{
1121bd4fe43Sopenharmony_ci    OsalSpinInit(&(ld->tx_lock));
1131bd4fe43Sopenharmony_ci    OsalSpinInit(&(ld->rx_lock));
1141bd4fe43Sopenharmony_ci
1151bd4fe43Sopenharmony_ci#ifdef HIETH_RXCSUM_SUPPORTED
1161bd4fe43Sopenharmony_ci    HiethEnableRxcsumDrop(ld, true);
1171bd4fe43Sopenharmony_ci#endif
1181bd4fe43Sopenharmony_ci
1191bd4fe43Sopenharmony_ci#ifdef HIETH_TSO_SUPPORTED
1201bd4fe43Sopenharmony_ci    ld->sgHead = ld->sgTail = 0;
1211bd4fe43Sopenharmony_ci    ld->txqHead = ld->txqTail = 0;
1221bd4fe43Sopenharmony_ci#endif
1231bd4fe43Sopenharmony_ci    ld->txHwCnt = 0;
1241bd4fe43Sopenharmony_ci
1251bd4fe43Sopenharmony_ci    /* setup hardware */
1261bd4fe43Sopenharmony_ci    (void)HiethSetHwqDepth(ld);
1271bd4fe43Sopenharmony_ci}
1281bd4fe43Sopenharmony_ci
1291bd4fe43Sopenharmony_civoid HiethHwExternalPhyReset(void)
1301bd4fe43Sopenharmony_ci{
1311bd4fe43Sopenharmony_ci    uint32_t val;
1321bd4fe43Sopenharmony_ci
1331bd4fe43Sopenharmony_ci    READ_UINT32(val, HIETH_CRG_IOBASE);
1341bd4fe43Sopenharmony_ci    val |= ETH_PHY_RESET;
1351bd4fe43Sopenharmony_ci    WRITE_UINT32(val, HIETH_CRG_IOBASE);
1361bd4fe43Sopenharmony_ci
1371bd4fe43Sopenharmony_ci    LOS_Msleep(20);
1381bd4fe43Sopenharmony_ci
1391bd4fe43Sopenharmony_ci    READ_UINT32(val, HIETH_CRG_IOBASE);
1401bd4fe43Sopenharmony_ci    val &= ~ETH_PHY_RESET;
1411bd4fe43Sopenharmony_ci    WRITE_UINT32(val, HIETH_CRG_IOBASE);
1421bd4fe43Sopenharmony_ci
1431bd4fe43Sopenharmony_ci    LOS_Msleep(30);
1441bd4fe43Sopenharmony_ci}
1451bd4fe43Sopenharmony_ci
1461bd4fe43Sopenharmony_cistatic inline int32_t IrqEnable(struct HiethNetdevLocal *ld, int32_t irqs)
1471bd4fe43Sopenharmony_ci{
1481bd4fe43Sopenharmony_ci    unsigned long old;
1491bd4fe43Sopenharmony_ci
1501bd4fe43Sopenharmony_ci    old = HiethRead(ld, GLB_RW_IRQ_ENA);
1511bd4fe43Sopenharmony_ci    HiethWrite(ld, old | (unsigned long)irqs, GLB_RW_IRQ_ENA);
1521bd4fe43Sopenharmony_ci    old = HiethRead(ld, GLB_RW_IRQ_ENA);
1531bd4fe43Sopenharmony_ci    return old;
1541bd4fe43Sopenharmony_ci}
1551bd4fe43Sopenharmony_ci
1561bd4fe43Sopenharmony_cistatic inline int32_t IrqDisable(struct HiethNetdevLocal *ld, int32_t irqs)
1571bd4fe43Sopenharmony_ci{
1581bd4fe43Sopenharmony_ci    unsigned long old;
1591bd4fe43Sopenharmony_ci
1601bd4fe43Sopenharmony_ci    old = HiethRead(ld, GLB_RW_IRQ_ENA);
1611bd4fe43Sopenharmony_ci    HiethWrite(ld, old & (~(unsigned long)irqs), GLB_RW_IRQ_ENA);
1621bd4fe43Sopenharmony_ci    return old;
1631bd4fe43Sopenharmony_ci}
1641bd4fe43Sopenharmony_ci
1651bd4fe43Sopenharmony_cistatic inline int32_t ReadIrqstatus(struct HiethNetdevLocal *ld)
1661bd4fe43Sopenharmony_ci{
1671bd4fe43Sopenharmony_ci    int32_t status;
1681bd4fe43Sopenharmony_ci
1691bd4fe43Sopenharmony_ci    status = HiethRead(ld, GLB_RO_IRQ_STAT);
1701bd4fe43Sopenharmony_ci    return status;
1711bd4fe43Sopenharmony_ci}
1721bd4fe43Sopenharmony_ci
1731bd4fe43Sopenharmony_ciint32_t HiethHwSetMacAddress(struct HiethNetdevLocal *ld, int32_t ena, const uint8_t *mac)
1741bd4fe43Sopenharmony_ci{
1751bd4fe43Sopenharmony_ci    unsigned long reg;
1761bd4fe43Sopenharmony_ci
1771bd4fe43Sopenharmony_ci    if (ld->port == DOWN_PORT) {
1781bd4fe43Sopenharmony_ci        HiethWritelBits(ld, 1, GLB_DN_HOSTMAC_ENA, BITS_DN_HOST_ENA);
1791bd4fe43Sopenharmony_ci    }
1801bd4fe43Sopenharmony_ci
1811bd4fe43Sopenharmony_ci    reg = mac[1] | (mac[0] << 8);
1821bd4fe43Sopenharmony_ci    if (ld->port == UP_PORT) {
1831bd4fe43Sopenharmony_ci        HiethWrite(ld, reg, GLB_HOSTMAC_H16);
1841bd4fe43Sopenharmony_ci    } else {
1851bd4fe43Sopenharmony_ci        HiethWrite(ld, reg, GLB_DN_HOSTMAC_H16);
1861bd4fe43Sopenharmony_ci    }
1871bd4fe43Sopenharmony_ci
1881bd4fe43Sopenharmony_ci    reg = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24);
1891bd4fe43Sopenharmony_ci    if (ld->port == UP_PORT) {
1901bd4fe43Sopenharmony_ci        HiethWrite(ld, reg, GLB_HOSTMAC_L32);
1911bd4fe43Sopenharmony_ci    } else {
1921bd4fe43Sopenharmony_ci        HiethWrite(ld, reg, GLB_DN_HOSTMAC_L32);
1931bd4fe43Sopenharmony_ci    }
1941bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1951bd4fe43Sopenharmony_ci}
1961bd4fe43Sopenharmony_ci
1971bd4fe43Sopenharmony_ciint32_t HiethHwGetMacAddress(struct HiethNetdevLocal *ld, uint8_t *mac)
1981bd4fe43Sopenharmony_ci{
1991bd4fe43Sopenharmony_ci    unsigned long reg;
2001bd4fe43Sopenharmony_ci
2011bd4fe43Sopenharmony_ci    if (ld->port == UP_PORT) {
2021bd4fe43Sopenharmony_ci        reg = HiethRead(ld, GLB_HOSTMAC_H16);
2031bd4fe43Sopenharmony_ci    } else {
2041bd4fe43Sopenharmony_ci        reg = HiethRead(ld, GLB_DN_HOSTMAC_H16);
2051bd4fe43Sopenharmony_ci    }
2061bd4fe43Sopenharmony_ci    mac[0] = (reg >> 8) & 0xff;
2071bd4fe43Sopenharmony_ci    mac[1] = reg & 0xff;
2081bd4fe43Sopenharmony_ci
2091bd4fe43Sopenharmony_ci    if (ld->port == UP_PORT) {
2101bd4fe43Sopenharmony_ci        reg = HiethRead(ld, GLB_HOSTMAC_L32);
2111bd4fe43Sopenharmony_ci    } else {
2121bd4fe43Sopenharmony_ci        reg = HiethRead(ld, GLB_DN_HOSTMAC_L32);
2131bd4fe43Sopenharmony_ci    }
2141bd4fe43Sopenharmony_ci    mac[2] = (reg >> 24) & 0xff;
2151bd4fe43Sopenharmony_ci    mac[3] = (reg >> 16) & 0xff;
2161bd4fe43Sopenharmony_ci    mac[4] = (reg >> 8) & 0xff;
2171bd4fe43Sopenharmony_ci    mac[5] = reg & 0xff;
2181bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2191bd4fe43Sopenharmony_ci}
2201bd4fe43Sopenharmony_ci
2211bd4fe43Sopenharmony_ciint32_t TestXmitQueueReady(struct HiethNetdevLocal *ld)
2221bd4fe43Sopenharmony_ci{
2231bd4fe43Sopenharmony_ci    return HiethReadlBits(ld, UD_REG_NAME(GLB_RO_QUEUE_STAT), BITS_XMITQ_RDY);
2241bd4fe43Sopenharmony_ci}
2251bd4fe43Sopenharmony_ci
2261bd4fe43Sopenharmony_ciint32_t HiethIrqEnable(struct HiethNetdevLocal *ld, int32_t irqs)
2271bd4fe43Sopenharmony_ci{
2281bd4fe43Sopenharmony_ci    int32_t old;
2291bd4fe43Sopenharmony_ci
2301bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
2311bd4fe43Sopenharmony_ci    old = IrqEnable(ld, irqs);
2321bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
2331bd4fe43Sopenharmony_ci    return old;
2341bd4fe43Sopenharmony_ci}
2351bd4fe43Sopenharmony_ci
2361bd4fe43Sopenharmony_ciint32_t HiethIrqDisable(struct HiethNetdevLocal *ld, int32_t irqs)
2371bd4fe43Sopenharmony_ci{
2381bd4fe43Sopenharmony_ci    int32_t old;
2391bd4fe43Sopenharmony_ci
2401bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
2411bd4fe43Sopenharmony_ci    old = IrqDisable(ld, irqs);
2421bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
2431bd4fe43Sopenharmony_ci    return old;
2441bd4fe43Sopenharmony_ci}
2451bd4fe43Sopenharmony_ci
2461bd4fe43Sopenharmony_ciint32_t HiethReadIrqstatus(struct HiethNetdevLocal *ld)
2471bd4fe43Sopenharmony_ci{
2481bd4fe43Sopenharmony_ci    return ReadIrqstatus(ld);
2491bd4fe43Sopenharmony_ci}
2501bd4fe43Sopenharmony_ci
2511bd4fe43Sopenharmony_ciint32_t HiethClearIrqstatus(struct HiethNetdevLocal *ld, int32_t irqs)
2521bd4fe43Sopenharmony_ci{
2531bd4fe43Sopenharmony_ci    int32_t status;
2541bd4fe43Sopenharmony_ci
2551bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
2561bd4fe43Sopenharmony_ci    HiethWrite(ld, irqs, GLB_RW_IRQ_RAW);
2571bd4fe43Sopenharmony_ci    status = ReadIrqstatus(ld);
2581bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
2591bd4fe43Sopenharmony_ci    return status;
2601bd4fe43Sopenharmony_ci}
2611bd4fe43Sopenharmony_ci
2621bd4fe43Sopenharmony_ciint32_t HiethSetEndianMode(struct HiethNetdevLocal *ld, int32_t mode)
2631bd4fe43Sopenharmony_ci{
2641bd4fe43Sopenharmony_ci    int32_t old;
2651bd4fe43Sopenharmony_ci
2661bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, GLB_ENDIAN_MOD, BITS_ENDIAN);
2671bd4fe43Sopenharmony_ci    HiethWritelBits(ld, mode, GLB_ENDIAN_MOD, BITS_ENDIAN);
2681bd4fe43Sopenharmony_ci    return old;
2691bd4fe43Sopenharmony_ci}
2701bd4fe43Sopenharmony_ci
2711bd4fe43Sopenharmony_ciint32_t HiethSetHwqDepth(struct HiethNetdevLocal *ld)
2721bd4fe43Sopenharmony_ci{
2731bd4fe43Sopenharmony_ci    HiethAssert(ld->depth.hwXmitq > 0 && ld->depth.hwXmitq <= HIETH_MAX_QUEUE_DEPTH);
2741bd4fe43Sopenharmony_ci    if ((ld->depth.hwXmitq) > HIETH_MAX_QUEUE_DEPTH) {
2751bd4fe43Sopenharmony_ci        BUG();
2761bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2771bd4fe43Sopenharmony_ci    }
2781bd4fe43Sopenharmony_ci    HiethWritelBits(ld, ld->depth.hwXmitq, UD_REG_NAME(GLB_QLEN_SET), BITS_TXQ_DEP);
2791bd4fe43Sopenharmony_ci    HiethWritelBits(ld, HIETH_MAX_QUEUE_DEPTH - ld->depth.hwXmitq, UD_REG_NAME(GLB_QLEN_SET), BITS_RXQ_DEP);
2801bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2811bd4fe43Sopenharmony_ci}
2821bd4fe43Sopenharmony_ci
2831bd4fe43Sopenharmony_ciint32_t HiethXmitReleasePkt(struct HiethNetdevLocal *ld, const HiethPriv *priv)
2841bd4fe43Sopenharmony_ci{
2851bd4fe43Sopenharmony_ci    int32_t ret = 0;
2861bd4fe43Sopenharmony_ci    struct TxPktInfo *txqCur = NULL;
2871bd4fe43Sopenharmony_ci    int32_t txReclaimCnt = 0;
2881bd4fe43Sopenharmony_ci    struct PbufInfo *pbuf = NULL;
2891bd4fe43Sopenharmony_ci
2901bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&(ld->tx_lock));
2911bd4fe43Sopenharmony_ci
2921bd4fe43Sopenharmony_ci    while (HwXmitqCntInUse(ld) < ld->txHwCnt) {
2931bd4fe43Sopenharmony_ci        HiethAssert(ld->txHwCnt);
2941bd4fe43Sopenharmony_ci
2951bd4fe43Sopenharmony_ci        txqCur = ld->txq + ld->txqTail;
2961bd4fe43Sopenharmony_ci        if (txqCur->txAddr == 0) {
2971bd4fe43Sopenharmony_ci            HDF_LOGE("%s: txAddr is invalid.", __func__);
2981bd4fe43Sopenharmony_ci        }
2991bd4fe43Sopenharmony_ci        pbuf = priv->ram->pbufInfo + ld->txqTail;
3001bd4fe43Sopenharmony_ci        if (pbuf->sgLen != 1) {
3011bd4fe43Sopenharmony_ci            HDF_LOGE("%s: pbuf info sg len is not 1.", __func__);
3021bd4fe43Sopenharmony_ci        }
3031bd4fe43Sopenharmony_ci        pbuf->dmaInfo[0] = NULL;
3041bd4fe43Sopenharmony_ci        NetBufFree(pbuf->buf);
3051bd4fe43Sopenharmony_ci
3061bd4fe43Sopenharmony_ci        txqCur->txAddr = 0;
3071bd4fe43Sopenharmony_ci
3081bd4fe43Sopenharmony_ci        ld->txqTail++;
3091bd4fe43Sopenharmony_ci        if (ld->txqTail == ld->qSize) {
3101bd4fe43Sopenharmony_ci            ld->txqTail = 0;
3111bd4fe43Sopenharmony_ci        }
3121bd4fe43Sopenharmony_ci
3131bd4fe43Sopenharmony_ci        txReclaimCnt++;
3141bd4fe43Sopenharmony_ci        ld->txHwCnt--;
3151bd4fe43Sopenharmony_ci    }
3161bd4fe43Sopenharmony_ci
3171bd4fe43Sopenharmony_ci    if (txReclaimCnt && ld->txBusy) {
3181bd4fe43Sopenharmony_ci        ld->txBusy = 0;
3191bd4fe43Sopenharmony_ci        struct HiethPlatformData *hiethPlatformData = GetHiethPlatformData();
3201bd4fe43Sopenharmony_ci        LOS_EventWrite(&(hiethPlatformData[priv->index].stEvent), EVENT_NET_CAN_SEND);
3211bd4fe43Sopenharmony_ci    }
3221bd4fe43Sopenharmony_ci
3231bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&(ld->tx_lock));
3241bd4fe43Sopenharmony_ci    return ret;
3251bd4fe43Sopenharmony_ci}
3261bd4fe43Sopenharmony_ci
3271bd4fe43Sopenharmony_ciint32_t HiethXmitGso(struct HiethNetdevLocal *ld, const HiethPriv *priv, NetBuf *netBuf)
3281bd4fe43Sopenharmony_ci{
3291bd4fe43Sopenharmony_ci    struct TxPktInfo *txqCur = NULL;
3301bd4fe43Sopenharmony_ci    int32_t sendPktLen, sgLen;
3311bd4fe43Sopenharmony_ci    struct PbufInfo *pbInfo = NULL;
3321bd4fe43Sopenharmony_ci
3331bd4fe43Sopenharmony_ci    if (netBuf == NULL) {
3341bd4fe43Sopenharmony_ci        HDF_LOGE("%sL netBuf is NULL", __func__);
3351bd4fe43Sopenharmony_ci        return HDF_FAILURE;
3361bd4fe43Sopenharmony_ci    }
3371bd4fe43Sopenharmony_ci
3381bd4fe43Sopenharmony_ci    sendPktLen = NetBufGetDataLen(netBuf);
3391bd4fe43Sopenharmony_ci    if (sendPktLen > HIETH_MAX_FRAME_SIZE) {
3401bd4fe43Sopenharmony_ci        HDF_LOGE("%s: xmit error len=%d", __func__, sendPktLen);
3411bd4fe43Sopenharmony_ci    }
3421bd4fe43Sopenharmony_ci
3431bd4fe43Sopenharmony_ci    pbInfo = &(priv->ram->pbufInfo[ld->txqHead]);
3441bd4fe43Sopenharmony_ci    sgLen = 0;
3451bd4fe43Sopenharmony_ci    pbInfo->dmaInfo[sgLen] = (void *)NetBufGetAddress(netBuf, E_DATA_BUF);
3461bd4fe43Sopenharmony_ci    sgLen++;
3471bd4fe43Sopenharmony_ci    pbInfo->sgLen = sgLen;
3481bd4fe43Sopenharmony_ci    pbInfo->buf = netBuf;
3491bd4fe43Sopenharmony_ci
3501bd4fe43Sopenharmony_ci    txqCur = ld->txq + ld->txqHead;
3511bd4fe43Sopenharmony_ci    txqCur->tx.val = 0;
3521bd4fe43Sopenharmony_ci
3531bd4fe43Sopenharmony_ci    /* default config, default closed checksum offload function */
3541bd4fe43Sopenharmony_ci    txqCur->tx.info.tsoFlag = HIETH_CSUM_DISABLE;
3551bd4fe43Sopenharmony_ci    txqCur->tx.info.coeFlag = HIETH_CSUM_DISABLE;
3561bd4fe43Sopenharmony_ci    if (sgLen == 1) {
3571bd4fe43Sopenharmony_ci        txqCur->tx.info.sgFlag = 0;
3581bd4fe43Sopenharmony_ci        NetDmaCacheClean((void *)NetBufGetAddress(netBuf, E_DATA_BUF), sendPktLen);
3591bd4fe43Sopenharmony_ci        txqCur->txAddr = (uintptr_t)NetBufGetAddress(netBuf, E_DATA_BUF);
3601bd4fe43Sopenharmony_ci    } else {
3611bd4fe43Sopenharmony_ci        HDF_LOGE("sg len is not 1");
3621bd4fe43Sopenharmony_ci        NetBufFree(netBuf);
3631bd4fe43Sopenharmony_ci        return HDF_FAILURE;
3641bd4fe43Sopenharmony_ci    }
3651bd4fe43Sopenharmony_ci
3661bd4fe43Sopenharmony_ci    txqCur->tx.info.dataLen = sendPktLen + FCS_BYTES;
3671bd4fe43Sopenharmony_ci
3681bd4fe43Sopenharmony_ci    HwXmitqPkg(ld, VMM_TO_DMA_ADDR(txqCur->txAddr), txqCur->tx.val);
3691bd4fe43Sopenharmony_ci    ld->txqHead++;
3701bd4fe43Sopenharmony_ci    if (ld->txqHead == ld->qSize) {
3711bd4fe43Sopenharmony_ci        ld->txqHead = 0;
3721bd4fe43Sopenharmony_ci    }
3731bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3741bd4fe43Sopenharmony_ci}
3751bd4fe43Sopenharmony_ci
3761bd4fe43Sopenharmony_ciint32_t HiethFeedHw(struct HiethNetdevLocal *ld, HiethPriv *priv)
3771bd4fe43Sopenharmony_ci{
3781bd4fe43Sopenharmony_ci    int32_t cnt = 0;
3791bd4fe43Sopenharmony_ci    NetBuf *netBuf = NULL;
3801bd4fe43Sopenharmony_ci    uint32_t rxFeedNext;
3811bd4fe43Sopenharmony_ci
3821bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&(ld->rx_lock));
3831bd4fe43Sopenharmony_ci
3841bd4fe43Sopenharmony_ci    while (HiethReadlBits(ld, UD_REG_NAME(GLB_RO_QUEUE_STAT), BITS_RECVQ_RDY)) {
3851bd4fe43Sopenharmony_ci        rxFeedNext = priv->rxFeed + 1;
3861bd4fe43Sopenharmony_ci        if (rxFeedNext == HIETH_HWQ_RXQ_DEPTH) {
3871bd4fe43Sopenharmony_ci            rxFeedNext = 0;
3881bd4fe43Sopenharmony_ci        }
3891bd4fe43Sopenharmony_ci        if (rxFeedNext == priv->rxRelease) {
3901bd4fe43Sopenharmony_ci            break;
3911bd4fe43Sopenharmony_ci        }
3921bd4fe43Sopenharmony_ci
3931bd4fe43Sopenharmony_ci        netBuf = NetBufAlloc(ALIGN(HIETH_MAX_FRAME_SIZE + ETH_PAD_SIZE + CACHE_ALIGNED_SIZE, CACHE_ALIGNED_SIZE));
3941bd4fe43Sopenharmony_ci        if (netBuf == NULL) {
3951bd4fe43Sopenharmony_ci            HDF_LOGE("%sL netBuf alloc fail", __func__);
3961bd4fe43Sopenharmony_ci            break;
3971bd4fe43Sopenharmony_ci        }
3981bd4fe43Sopenharmony_ci
3991bd4fe43Sopenharmony_ci        /* drop some bytes for making alignment of net dma cache */
4001bd4fe43Sopenharmony_ci        netBuf->bufs[E_DATA_BUF].offset += (ALIGN((uintptr_t)NetBufGetAddress(netBuf, E_DATA_BUF),
4011bd4fe43Sopenharmony_ci            CACHE_ALIGNED_SIZE) - (uintptr_t)NetBufGetAddress(netBuf, E_DATA_BUF));
4021bd4fe43Sopenharmony_ci
4031bd4fe43Sopenharmony_ci#if ETH_PAD_SIZE
4041bd4fe43Sopenharmony_ci        /* drop the padding word */
4051bd4fe43Sopenharmony_ci        netBuf->bufs[E_DATA_BUF].offset += ETH_PAD_SIZE;
4061bd4fe43Sopenharmony_ci#endif
4071bd4fe43Sopenharmony_ci
4081bd4fe43Sopenharmony_ci        priv->ram->rxNetbuf[priv->rxFeed] = netBuf;
4091bd4fe43Sopenharmony_ci        NetDmaCacheInv(NetBufGetAddress(netBuf, E_DATA_BUF), HIETH_MAX_FRAME_SIZE);
4101bd4fe43Sopenharmony_ci
4111bd4fe43Sopenharmony_ci        HiethWrite(ld, VMM_TO_DMA_ADDR((UINTPTR)NetBufGetAddress(netBuf, E_DATA_BUF)), UD_REG_NAME(GLB_IQ_ADDR));
4121bd4fe43Sopenharmony_ci        priv->rxFeed = rxFeedNext;
4131bd4fe43Sopenharmony_ci        cnt++;
4141bd4fe43Sopenharmony_ci    }
4151bd4fe43Sopenharmony_ci
4161bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&(ld->rx_lock));
4171bd4fe43Sopenharmony_ci    return cnt;
4181bd4fe43Sopenharmony_ci}
419