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