1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Description: Control hieth register
18 */
19
20
21 #define HIETH_SFV300
22
23 #include "hieth.h"
24 #include "ctrl.h"
25
_hieth_irq_enable(struct hieth_netdev_local * ld,u32 irqs)26 static inline u32 _hieth_irq_enable(struct hieth_netdev_local *ld, u32 irqs)
27 {
28 u32 old = hieth_readl(ld, GLB_RW_IRQ_ENA);
29
30 hieth_writel(ld, old | irqs, GLB_RW_IRQ_ENA);
31
32 return old;
33 }
34
_hieth_irq_disable(struct hieth_netdev_local * ld,u32 irqs)35 static inline u32 _hieth_irq_disable(struct hieth_netdev_local *ld, u32 irqs)
36 {
37 u32 old = hieth_readl(ld, GLB_RW_IRQ_ENA);
38
39 hieth_writel(ld, old & (~irqs), GLB_RW_IRQ_ENA);
40
41 return old;
42 }
43
_hieth_read_irqstatus(struct hieth_netdev_local * ld)44 static inline u32 _hieth_read_irqstatus(struct hieth_netdev_local *ld)
45 {
46 u32 status;
47
48 status = hieth_readl(ld, GLB_RO_IRQ_STAT);
49
50 return status;
51 }
52
_test_xmit_queue_ready(struct hieth_netdev_local * ld)53 static inline int _test_xmit_queue_ready(struct hieth_netdev_local *ld)
54 {
55 return hieth_readl_bits(ld, ud_reg_name(GLB_RO_QUEUE_STAT),
56 BITS_XMITQ_RDY);
57 }
58
_test_recv_queue_ready(struct hieth_netdev_local * ld)59 static inline int _test_recv_queue_ready(struct hieth_netdev_local *ld)
60 {
61 return hieth_readl_bits(ld, ud_reg_name(GLB_RO_QUEUE_STAT),
62 BITS_RECVQ_RDY);
63 }
64
hieth_irq_enable(struct hieth_netdev_local * ld,u32 irqs)65 u32 hieth_irq_enable(struct hieth_netdev_local *ld, u32 irqs)
66 {
67 u32 old;
68
69 local_lock(ld);
70 old = _hieth_irq_enable(ld, irqs);
71 local_unlock(ld);
72
73 return old;
74 }
75
hieth_irq_disable(struct hieth_netdev_local * ld,u32 irqs)76 u32 hieth_irq_disable(struct hieth_netdev_local *ld, u32 irqs)
77 {
78 u32 old;
79
80 local_lock(ld);
81 old = _hieth_irq_disable(ld, irqs);
82 local_unlock(ld);
83
84 return old;
85 }
86
hieth_read_irqstatus(struct hieth_netdev_local * ld)87 u32 hieth_read_irqstatus(struct hieth_netdev_local *ld)
88 {
89 u32 status;
90
91 local_lock(ld);
92 status = _hieth_read_irqstatus(ld);
93 local_unlock(ld);
94
95 return status;
96 }
97
hieth_read_raw_irqstatus(struct hieth_netdev_local * ld)98 u32 hieth_read_raw_irqstatus(struct hieth_netdev_local *ld)
99 {
100 u32 status;
101
102 local_lock(ld);
103 status = hieth_readl(ld, GLB_RO_IRQ_STAT);
104 local_unlock(ld);
105
106 return status;
107 }
108
hieth_clear_irqstatus(struct hieth_netdev_local * ld,u32 irqs)109 u32 hieth_clear_irqstatus(struct hieth_netdev_local *ld, u32 irqs)
110 {
111 u32 status;
112
113 local_lock(ld);
114 hieth_writel(ld, irqs, GLB_RW_IRQ_RAW);
115 status = _hieth_read_irqstatus(ld);
116 local_unlock(ld);
117
118 return status;
119 }
120
hieth_set_endian_mode(struct hieth_netdev_local * ld,u32 mode)121 u32 hieth_set_endian_mode(struct hieth_netdev_local *ld, u32 mode)
122 {
123 u32 old;
124
125 local_lock(ld);
126 old = hieth_readl_bits(ld, GLB_ENDIAN_MOD, BITS_ENDIAN);
127 hieth_writel_bits(ld, mode, GLB_ENDIAN_MOD, BITS_ENDIAN);
128 local_unlock(ld);
129
130 return old;
131 }
132
hw_xmitq_setfd(struct hieth_netdev_local * ld,struct hieth_frame_desc fd)133 void hw_xmitq_setfd(struct hieth_netdev_local *ld, struct hieth_frame_desc fd)
134 {
135 hieth_writel(ld, fd.frm_addr, ud_reg_name(GLB_EQ_ADDR));
136 hieth_writel_bits(ld, fd.frm_len, ud_reg_name(GLB_EQFRM_LEN), BITS_TXINQ_LEN);
137 }
138
hieth_readl(struct hieth_netdev_local * ld,u32 ofs)139 u32 hieth_readl(struct hieth_netdev_local *ld, u32 ofs)
140 {
141 u32 reg = _readl((uintptr_t)(ld->iobase_phys + ofs));
142 hieth_trace(HIETH_TRACE_ETH, "_readl(0x%08X) = 0x%08X",
143 (u32)(ld->iobase_phys + ofs), reg);
144 return reg;
145 }
146
hieth_writel(struct hieth_netdev_local * ld,u32 v,u32 ofs)147 void hieth_writel(struct hieth_netdev_local *ld, u32 v, u32 ofs)
148 {
149 _writel(v, (uintptr_t)(ld->iobase_phys + ofs));
150 hieth_trace(HIETH_TRACE_ETH, "_writel(0x%08X) = 0x%08X",
151 (u32)(ld->iobase_phys + ofs), v);
152 }
153
154
hieth_readl_bits(struct hieth_netdev_local * ld,u32 ofs,u32 bits_desc)155 u32 hieth_readl_bits(struct hieth_netdev_local *ld, u32 ofs, u32 bits_desc)
156 {
157 u32 _bits_desc = bits_desc;
158 u32 _shift = _bits_desc >> 16; /* shift 16 bit */
159 u32 _mask = ((1 << (_bits_desc & 0x1F)) - 1) << _shift;
160 u32 reg = (hieth_readl(ld, ofs) & _mask) >> _shift;
161 return reg;
162 }
163
hieth_writel_bits(struct hieth_netdev_local * ld,u32 v,u32 ofs,u32 bits_desc)164 void hieth_writel_bits(struct hieth_netdev_local *ld, u32 v, u32 ofs, u32 bits_desc)
165 {
166 u32 _bits_desc = bits_desc;
167 u32 _shift = _bits_desc >> 16; /* shift 16 bit */
168 u32 _reg = hieth_readl(ld, ofs);
169 u32 _mask = ((1 << (_bits_desc & 0x1F)) - 1) << _shift;
170 hieth_writel(ld, (_reg & (~_mask)) | ((v << _shift) & _mask), ofs);
171 }
172
hieth_trace(int level,const char * fmt,...)173 void hieth_trace(int level, const char *fmt, ...)
174 {
175 if (level >= HIETH_TRACE_LEVEL) {
176 va_list args;
177 va_start(args, fmt);
178 printf("hieth_trace:");
179 printf(fmt, args);
180 printf("\n");
181 va_end(args);
182 }
183 }
184
hieth_error(const char * fmt,...)185 void hieth_error(const char *fmt, ...)
186 {
187 va_list args;
188 va_start(args, fmt);
189 printf("hieth:");
190 printf(fmt, args);
191 printf("\n");
192 va_end(args);
193 }
194
hieth_assert(bool cond)195 void hieth_assert(bool cond)
196 {
197 if (!cond)
198 printf("Assert:hieth:%s:%d\n", __FILE__, __LINE__);
199 }
200