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 "eth_mac.h"
171bd4fe43Sopenharmony_ci#include "hieth_pri.h"
181bd4fe43Sopenharmony_ci
191bd4fe43Sopenharmony_ciextern uint64_t hi_sched_clock(void);
201bd4fe43Sopenharmony_ci#define MICROSECOND_TIME_LONG 1000
211bd4fe43Sopenharmony_ci#define MICROSECOND_TIME_SHORT 100
221bd4fe43Sopenharmony_ci#define MILLISECOND_TIME 200
231bd4fe43Sopenharmony_ci
241bd4fe43Sopenharmony_cistatic int32_t SetLinkStat(struct HiethNetdevLocal *ld, unsigned long mode)
251bd4fe43Sopenharmony_ci{
261bd4fe43Sopenharmony_ci    int32_t old;
271bd4fe43Sopenharmony_ci
281bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSET), BITS_MACSTAT);
291bd4fe43Sopenharmony_ci    HiethWritelBits(ld, mode, UD_REG_NAME(MAC_PORTSET), BITS_MACSTAT);
301bd4fe43Sopenharmony_ci    return old;
311bd4fe43Sopenharmony_ci}
321bd4fe43Sopenharmony_ci
331bd4fe43Sopenharmony_cistatic int32_t SetNegMode(struct HiethNetdevLocal *ld, int32_t mode)
341bd4fe43Sopenharmony_ci{
351bd4fe43Sopenharmony_ci    int32_t old;
361bd4fe43Sopenharmony_ci
371bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSEL), BITS_NEGMODE);
381bd4fe43Sopenharmony_ci    HiethWritelBits(ld, mode, UD_REG_NAME(MAC_PORTSEL), BITS_NEGMODE);
391bd4fe43Sopenharmony_ci    return old;
401bd4fe43Sopenharmony_ci}
411bd4fe43Sopenharmony_ci
421bd4fe43Sopenharmony_cistatic int32_t GetNegMode(struct HiethNetdevLocal *ld)
431bd4fe43Sopenharmony_ci{
441bd4fe43Sopenharmony_ci    return HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSEL), BITS_NEGMODE);
451bd4fe43Sopenharmony_ci}
461bd4fe43Sopenharmony_ci
471bd4fe43Sopenharmony_ciint32_t HiethSetLinkStat(struct HiethNetdevLocal *ld, unsigned long mode)
481bd4fe43Sopenharmony_ci{
491bd4fe43Sopenharmony_ci    return SetLinkStat(ld, mode);
501bd4fe43Sopenharmony_ci}
511bd4fe43Sopenharmony_ci
521bd4fe43Sopenharmony_ciint32_t HiethGetLinkStat(struct HiethNetdevLocal *ld)
531bd4fe43Sopenharmony_ci{
541bd4fe43Sopenharmony_ci    return HiethReadlBits(ld, UD_REG_NAME(MAC_RO_STAT), BITS_MACSTAT);
551bd4fe43Sopenharmony_ci}
561bd4fe43Sopenharmony_ci
571bd4fe43Sopenharmony_ciint32_t HiethSetMacLeadcodeCntLimit(struct HiethNetdevLocal *ld, int32_t cnt)
581bd4fe43Sopenharmony_ci{
591bd4fe43Sopenharmony_ci    int32_t old;
601bd4fe43Sopenharmony_ci
611bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
621bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_PRE_CNT_LIMIT);
631bd4fe43Sopenharmony_ci    HiethWritelBits(ld, cnt, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_PRE_CNT_LIMIT);
641bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
651bd4fe43Sopenharmony_ci    return old;
661bd4fe43Sopenharmony_ci}
671bd4fe43Sopenharmony_ci
681bd4fe43Sopenharmony_ciint32_t HiethSetMacTransIntervalBits(struct HiethNetdevLocal *ld, int32_t nbits)
691bd4fe43Sopenharmony_ci{
701bd4fe43Sopenharmony_ci    int32_t old;
711bd4fe43Sopenharmony_ci    int32_t linkstat, negmode;
721bd4fe43Sopenharmony_ci
731bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
741bd4fe43Sopenharmony_ci
751bd4fe43Sopenharmony_ci    negmode = SetNegMode(ld, HIETH_NEGMODE_CPUSET);
761bd4fe43Sopenharmony_ci    linkstat = SetLinkStat(ld, 0);
771bd4fe43Sopenharmony_ci    udelay(MICROSECOND_TIME_LONG);
781bd4fe43Sopenharmony_ci
791bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_IPG);
801bd4fe43Sopenharmony_ci    HiethWritelBits(ld, nbits, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_IPG);
811bd4fe43Sopenharmony_ci    udelay(MICROSECOND_TIME_SHORT);
821bd4fe43Sopenharmony_ci
831bd4fe43Sopenharmony_ci    SetNegMode(ld, negmode);
841bd4fe43Sopenharmony_ci    SetLinkStat(ld, linkstat);
851bd4fe43Sopenharmony_ci
861bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
871bd4fe43Sopenharmony_ci    return old;
881bd4fe43Sopenharmony_ci}
891bd4fe43Sopenharmony_ci
901bd4fe43Sopenharmony_ciint32_t HiethSetMacFcInterval(struct HiethNetdevLocal *ld, int32_t para)
911bd4fe43Sopenharmony_ci{
921bd4fe43Sopenharmony_ci    int32_t old;
931bd4fe43Sopenharmony_ci
941bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
951bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_FC_INTER);
961bd4fe43Sopenharmony_ci    HiethWritelBits(ld, para, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_FC_INTER);
971bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
981bd4fe43Sopenharmony_ci    return old;
991bd4fe43Sopenharmony_ci}
1001bd4fe43Sopenharmony_ci
1011bd4fe43Sopenharmony_ciint32_t HiethSetNegMode(struct HiethNetdevLocal *ld, int32_t mode)
1021bd4fe43Sopenharmony_ci{
1031bd4fe43Sopenharmony_ci    int32_t old;
1041bd4fe43Sopenharmony_ci
1051bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
1061bd4fe43Sopenharmony_ci    old = SetNegMode(ld, mode);
1071bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
1081bd4fe43Sopenharmony_ci    return old;
1091bd4fe43Sopenharmony_ci}
1101bd4fe43Sopenharmony_ci
1111bd4fe43Sopenharmony_ciint32_t HiethGetNegmode(struct HiethNetdevLocal *ld)
1121bd4fe43Sopenharmony_ci{
1131bd4fe43Sopenharmony_ci    int32_t old;
1141bd4fe43Sopenharmony_ci
1151bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
1161bd4fe43Sopenharmony_ci    old = GetNegMode(ld);
1171bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
1181bd4fe43Sopenharmony_ci    return old;
1191bd4fe43Sopenharmony_ci}
1201bd4fe43Sopenharmony_ci
1211bd4fe43Sopenharmony_ciint32_t HiethSetMiiMode(struct HiethNetdevLocal *ld, int32_t mode)
1221bd4fe43Sopenharmony_ci{
1231bd4fe43Sopenharmony_ci    int32_t old;
1241bd4fe43Sopenharmony_ci
1251bd4fe43Sopenharmony_ci    old = HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSEL), BITS_MII_MODE);
1261bd4fe43Sopenharmony_ci    HiethWritelBits(ld, mode, UD_REG_NAME(MAC_PORTSEL), BITS_MII_MODE);
1271bd4fe43Sopenharmony_ci    return old;
1281bd4fe43Sopenharmony_ci}
1291bd4fe43Sopenharmony_ci
1301bd4fe43Sopenharmony_civoid HiethSetRcvLenMax(struct HiethNetdevLocal *ld, int32_t cnt)
1311bd4fe43Sopenharmony_ci{
1321bd4fe43Sopenharmony_ci    OsalSpinLockIrq(&hiethGlbRegLock);
1331bd4fe43Sopenharmony_ci    HiethWritelBits(ld, cnt, UD_REG_NAME(MAC_SET), BITS_LEN_MAX);
1341bd4fe43Sopenharmony_ci    OsalSpinUnlockIrq(&hiethGlbRegLock);
1351bd4fe43Sopenharmony_ci}
1361bd4fe43Sopenharmony_ci
1371bd4fe43Sopenharmony_ciextern void HiRandomHwInit(void);
1381bd4fe43Sopenharmony_ciextern void HiRandomHwDeinit(void);
1391bd4fe43Sopenharmony_ciextern int32_t HiRandomHwGetInteger(uint32_t *result);
1401bd4fe43Sopenharmony_ci
1411bd4fe43Sopenharmony_civoid EthHisiRandomAddr(uint8_t *addr, int32_t len)
1421bd4fe43Sopenharmony_ci{
1431bd4fe43Sopenharmony_ci    uint32_t randVal;
1441bd4fe43Sopenharmony_ci    int32_t ret;
1451bd4fe43Sopenharmony_ci
1461bd4fe43Sopenharmony_ci    msleep(MILLISECOND_TIME);
1471bd4fe43Sopenharmony_ci    HiRandomHwInit();
1481bd4fe43Sopenharmony_ci    ret = HiRandomHwGetInteger(&randVal);
1491bd4fe43Sopenharmony_ci    if (ret != 0) {
1501bd4fe43Sopenharmony_ci        randVal = (uint32_t)(hi_sched_clock() & 0xffffffff);
1511bd4fe43Sopenharmony_ci    }
1521bd4fe43Sopenharmony_ci    addr[0] = randVal & 0xff;
1531bd4fe43Sopenharmony_ci    addr[1] = (randVal >> MAC_ADDR_OFFSET_L8) & 0xff;
1541bd4fe43Sopenharmony_ci    addr[2] = (randVal >> MAC_ADDR_OFFSET_L16) & 0xff;
1551bd4fe43Sopenharmony_ci    addr[3] = (randVal >> MAC_ADDR_OFFSET_L24) & 0xff;
1561bd4fe43Sopenharmony_ci
1571bd4fe43Sopenharmony_ci    msleep(MILLISECOND_TIME);
1581bd4fe43Sopenharmony_ci    ret = HiRandomHwGetInteger(&randVal);
1591bd4fe43Sopenharmony_ci    if (ret != 0) {
1601bd4fe43Sopenharmony_ci        randVal = (uint32_t)(hi_sched_clock() & 0xffffffff);
1611bd4fe43Sopenharmony_ci    }
1621bd4fe43Sopenharmony_ci    addr[4] = randVal & 0xff;
1631bd4fe43Sopenharmony_ci    addr[5] = ((uint32_t)randVal >> MAC_ADDR_OFFSET_L8) & 0xff;
1641bd4fe43Sopenharmony_ci
1651bd4fe43Sopenharmony_ci    addr[0] &= 0xfe; /* clear multicast bit */
1661bd4fe43Sopenharmony_ci    addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
1671bd4fe43Sopenharmony_ci
1681bd4fe43Sopenharmony_ci    HiRandomHwDeinit();
1691bd4fe43Sopenharmony_ci}
170