1 /*
2 * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "eth_mac.h"
17 #include "hieth_pri.h"
18
19 extern uint64_t hi_sched_clock(void);
20 #define MICROSECOND_TIME_LONG 1000
21 #define MICROSECOND_TIME_SHORT 100
22 #define MILLISECOND_TIME 200
23
SetLinkStat(struct HiethNetdevLocal * ld,unsigned long mode)24 static int32_t SetLinkStat(struct HiethNetdevLocal *ld, unsigned long mode)
25 {
26 int32_t old;
27
28 old = HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSET), BITS_MACSTAT);
29 HiethWritelBits(ld, mode, UD_REG_NAME(MAC_PORTSET), BITS_MACSTAT);
30 return old;
31 }
32
SetNegMode(struct HiethNetdevLocal * ld,int32_t mode)33 static int32_t SetNegMode(struct HiethNetdevLocal *ld, int32_t mode)
34 {
35 int32_t old;
36
37 old = HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSEL), BITS_NEGMODE);
38 HiethWritelBits(ld, mode, UD_REG_NAME(MAC_PORTSEL), BITS_NEGMODE);
39 return old;
40 }
41
GetNegMode(struct HiethNetdevLocal * ld)42 static int32_t GetNegMode(struct HiethNetdevLocal *ld)
43 {
44 return HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSEL), BITS_NEGMODE);
45 }
46
HiethSetLinkStat(struct HiethNetdevLocal * ld,unsigned long mode)47 int32_t HiethSetLinkStat(struct HiethNetdevLocal *ld, unsigned long mode)
48 {
49 return SetLinkStat(ld, mode);
50 }
51
HiethGetLinkStat(struct HiethNetdevLocal * ld)52 int32_t HiethGetLinkStat(struct HiethNetdevLocal *ld)
53 {
54 return HiethReadlBits(ld, UD_REG_NAME(MAC_RO_STAT), BITS_MACSTAT);
55 }
56
HiethSetMacLeadcodeCntLimit(struct HiethNetdevLocal * ld,int32_t cnt)57 int32_t HiethSetMacLeadcodeCntLimit(struct HiethNetdevLocal *ld, int32_t cnt)
58 {
59 int32_t old;
60
61 OsalSpinLockIrq(&hiethGlbRegLock);
62 old = HiethReadlBits(ld, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_PRE_CNT_LIMIT);
63 HiethWritelBits(ld, cnt, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_PRE_CNT_LIMIT);
64 OsalSpinUnlockIrq(&hiethGlbRegLock);
65 return old;
66 }
67
HiethSetMacTransIntervalBits(struct HiethNetdevLocal * ld,int32_t nbits)68 int32_t HiethSetMacTransIntervalBits(struct HiethNetdevLocal *ld, int32_t nbits)
69 {
70 int32_t old;
71 int32_t linkstat, negmode;
72
73 OsalSpinLockIrq(&hiethGlbRegLock);
74
75 negmode = SetNegMode(ld, HIETH_NEGMODE_CPUSET);
76 linkstat = SetLinkStat(ld, 0);
77 udelay(MICROSECOND_TIME_LONG);
78
79 old = HiethReadlBits(ld, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_IPG);
80 HiethWritelBits(ld, nbits, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_IPG);
81 udelay(MICROSECOND_TIME_SHORT);
82
83 SetNegMode(ld, negmode);
84 SetLinkStat(ld, linkstat);
85
86 OsalSpinUnlockIrq(&hiethGlbRegLock);
87 return old;
88 }
89
HiethSetMacFcInterval(struct HiethNetdevLocal * ld,int32_t para)90 int32_t HiethSetMacFcInterval(struct HiethNetdevLocal *ld, int32_t para)
91 {
92 int32_t old;
93
94 OsalSpinLockIrq(&hiethGlbRegLock);
95 old = HiethReadlBits(ld, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_FC_INTER);
96 HiethWritelBits(ld, para, UD_REG_NAME(MAC_TX_IPGCTRL), BITS_FC_INTER);
97 OsalSpinUnlockIrq(&hiethGlbRegLock);
98 return old;
99 }
100
HiethSetNegMode(struct HiethNetdevLocal * ld,int32_t mode)101 int32_t HiethSetNegMode(struct HiethNetdevLocal *ld, int32_t mode)
102 {
103 int32_t old;
104
105 OsalSpinLockIrq(&hiethGlbRegLock);
106 old = SetNegMode(ld, mode);
107 OsalSpinUnlockIrq(&hiethGlbRegLock);
108 return old;
109 }
110
HiethGetNegmode(struct HiethNetdevLocal * ld)111 int32_t HiethGetNegmode(struct HiethNetdevLocal *ld)
112 {
113 int32_t old;
114
115 OsalSpinLockIrq(&hiethGlbRegLock);
116 old = GetNegMode(ld);
117 OsalSpinUnlockIrq(&hiethGlbRegLock);
118 return old;
119 }
120
HiethSetMiiMode(struct HiethNetdevLocal * ld,int32_t mode)121 int32_t HiethSetMiiMode(struct HiethNetdevLocal *ld, int32_t mode)
122 {
123 int32_t old;
124
125 old = HiethReadlBits(ld, UD_REG_NAME(MAC_PORTSEL), BITS_MII_MODE);
126 HiethWritelBits(ld, mode, UD_REG_NAME(MAC_PORTSEL), BITS_MII_MODE);
127 return old;
128 }
129
HiethSetRcvLenMax(struct HiethNetdevLocal * ld,int32_t cnt)130 void HiethSetRcvLenMax(struct HiethNetdevLocal *ld, int32_t cnt)
131 {
132 OsalSpinLockIrq(&hiethGlbRegLock);
133 HiethWritelBits(ld, cnt, UD_REG_NAME(MAC_SET), BITS_LEN_MAX);
134 OsalSpinUnlockIrq(&hiethGlbRegLock);
135 }
136
137 extern void HiRandomHwInit(void);
138 extern void HiRandomHwDeinit(void);
139 extern int32_t HiRandomHwGetInteger(uint32_t *result);
140
EthHisiRandomAddr(uint8_t * addr,int32_t len)141 void EthHisiRandomAddr(uint8_t *addr, int32_t len)
142 {
143 uint32_t randVal;
144 int32_t ret;
145
146 msleep(MILLISECOND_TIME);
147 HiRandomHwInit();
148 ret = HiRandomHwGetInteger(&randVal);
149 if (ret != 0) {
150 randVal = (uint32_t)(hi_sched_clock() & 0xffffffff);
151 }
152 addr[0] = randVal & 0xff;
153 addr[1] = (randVal >> MAC_ADDR_OFFSET_L8) & 0xff;
154 addr[2] = (randVal >> MAC_ADDR_OFFSET_L16) & 0xff;
155 addr[3] = (randVal >> MAC_ADDR_OFFSET_L24) & 0xff;
156
157 msleep(MILLISECOND_TIME);
158 ret = HiRandomHwGetInteger(&randVal);
159 if (ret != 0) {
160 randVal = (uint32_t)(hi_sched_clock() & 0xffffffff);
161 }
162 addr[4] = randVal & 0xff;
163 addr[5] = ((uint32_t)randVal >> MAC_ADDR_OFFSET_L8) & 0xff;
164
165 addr[0] &= 0xfe; /* clear multicast bit */
166 addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
167
168 HiRandomHwDeinit();
169 }
170