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