Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/ncsw/Peripherals/FM/MAC/fman_tgec.c
48524 views
1
/*
2
* Copyright 2008-2012 Freescale Semiconductor Inc.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
* * Redistributions of source code must retain the above copyright
7
* notice, this list of conditions and the following disclaimer.
8
* * Redistributions in binary form must reproduce the above copyright
9
* notice, this list of conditions and the following disclaimer in the
10
* documentation and/or other materials provided with the distribution.
11
* * Neither the name of Freescale Semiconductor nor the
12
* names of its contributors may be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
*
16
* ALTERNATIVELY, this software may be distributed under the terms of the
17
* GNU General Public License ("GPL") as published by the Free Software
18
* Foundation, either version 2 of that License or (at your option) any
19
* later version.
20
*
21
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
34
#include "fsl_fman_tgec.h"
35
36
37
void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
38
{
39
uint32_t tmp0, tmp1;
40
41
tmp0 = (uint32_t)(adr[0] |
42
adr[1] << 8 |
43
adr[2] << 16 |
44
adr[3] << 24);
45
tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
46
iowrite32be(tmp0, &regs->mac_addr_0);
47
iowrite32be(tmp1, &regs->mac_addr_1);
48
}
49
50
void fman_tgec_reset_stat(struct tgec_regs *regs)
51
{
52
uint32_t tmp;
53
54
tmp = ioread32be(&regs->command_config);
55
56
tmp |= CMD_CFG_STAT_CLR;
57
58
iowrite32be(tmp, &regs->command_config);
59
60
while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
61
}
62
63
#define GET_TGEC_CNTR_64(bn) \
64
(((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
65
ioread32be(&regs->bn ## _l))
66
67
uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
68
{
69
uint64_t ret_val;
70
71
switch (reg_name) {
72
case E_TGEC_COUNTER_R64:
73
ret_val = GET_TGEC_CNTR_64(r64);
74
break;
75
case E_TGEC_COUNTER_R127:
76
ret_val = GET_TGEC_CNTR_64(r127);
77
break;
78
case E_TGEC_COUNTER_R255:
79
ret_val = GET_TGEC_CNTR_64(r255);
80
break;
81
case E_TGEC_COUNTER_R511:
82
ret_val = GET_TGEC_CNTR_64(r511);
83
break;
84
case E_TGEC_COUNTER_R1023:
85
ret_val = GET_TGEC_CNTR_64(r1023);
86
break;
87
case E_TGEC_COUNTER_R1518:
88
ret_val = GET_TGEC_CNTR_64(r1518);
89
break;
90
case E_TGEC_COUNTER_R1519X:
91
ret_val = GET_TGEC_CNTR_64(r1519x);
92
break;
93
case E_TGEC_COUNTER_TRFRG:
94
ret_val = GET_TGEC_CNTR_64(trfrg);
95
break;
96
case E_TGEC_COUNTER_TRJBR:
97
ret_val = GET_TGEC_CNTR_64(trjbr);
98
break;
99
case E_TGEC_COUNTER_RDRP:
100
ret_val = GET_TGEC_CNTR_64(rdrp);
101
break;
102
case E_TGEC_COUNTER_RALN:
103
ret_val = GET_TGEC_CNTR_64(raln);
104
break;
105
case E_TGEC_COUNTER_TRUND:
106
ret_val = GET_TGEC_CNTR_64(trund);
107
break;
108
case E_TGEC_COUNTER_TROVR:
109
ret_val = GET_TGEC_CNTR_64(trovr);
110
break;
111
case E_TGEC_COUNTER_RXPF:
112
ret_val = GET_TGEC_CNTR_64(rxpf);
113
break;
114
case E_TGEC_COUNTER_TXPF:
115
ret_val = GET_TGEC_CNTR_64(txpf);
116
break;
117
case E_TGEC_COUNTER_ROCT:
118
ret_val = GET_TGEC_CNTR_64(roct);
119
break;
120
case E_TGEC_COUNTER_RMCA:
121
ret_val = GET_TGEC_CNTR_64(rmca);
122
break;
123
case E_TGEC_COUNTER_RBCA:
124
ret_val = GET_TGEC_CNTR_64(rbca);
125
break;
126
case E_TGEC_COUNTER_RPKT:
127
ret_val = GET_TGEC_CNTR_64(rpkt);
128
break;
129
case E_TGEC_COUNTER_RUCA:
130
ret_val = GET_TGEC_CNTR_64(ruca);
131
break;
132
case E_TGEC_COUNTER_RERR:
133
ret_val = GET_TGEC_CNTR_64(rerr);
134
break;
135
case E_TGEC_COUNTER_TOCT:
136
ret_val = GET_TGEC_CNTR_64(toct);
137
break;
138
case E_TGEC_COUNTER_TMCA:
139
ret_val = GET_TGEC_CNTR_64(tmca);
140
break;
141
case E_TGEC_COUNTER_TBCA:
142
ret_val = GET_TGEC_CNTR_64(tbca);
143
break;
144
case E_TGEC_COUNTER_TUCA:
145
ret_val = GET_TGEC_CNTR_64(tuca);
146
break;
147
case E_TGEC_COUNTER_TERR:
148
ret_val = GET_TGEC_CNTR_64(terr);
149
break;
150
default:
151
ret_val = 0;
152
}
153
154
return ret_val;
155
}
156
157
void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
158
{
159
uint32_t tmp;
160
161
tmp = ioread32be(&regs->command_config);
162
if (apply_rx)
163
tmp |= CMD_CFG_RX_EN;
164
if (apply_tx)
165
tmp |= CMD_CFG_TX_EN;
166
iowrite32be(tmp, &regs->command_config);
167
}
168
169
void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
170
{
171
uint32_t tmp_reg_32;
172
173
tmp_reg_32 = ioread32be(&regs->command_config);
174
if (apply_rx)
175
tmp_reg_32 &= ~CMD_CFG_RX_EN;
176
if (apply_tx)
177
tmp_reg_32 &= ~CMD_CFG_TX_EN;
178
iowrite32be(tmp_reg_32, &regs->command_config);
179
}
180
181
void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
182
{
183
uint32_t tmp;
184
185
tmp = ioread32be(&regs->command_config);
186
if (val)
187
tmp |= CMD_CFG_PROMIS_EN;
188
else
189
tmp &= ~CMD_CFG_PROMIS_EN;
190
iowrite32be(tmp, &regs->command_config);
191
}
192
193
void fman_tgec_reset_filter_table(struct tgec_regs *regs)
194
{
195
uint32_t i;
196
for (i = 0; i < 512; i++)
197
iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
198
}
199
200
void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
201
{
202
uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
203
iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
204
}
205
206
void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
207
{
208
iowrite32be(value, &regs->hashtable_ctrl);
209
}
210
211
void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
212
{
213
iowrite32be((uint32_t)pause_time, &regs->pause_quant);
214
}
215
216
void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
217
{
218
uint32_t tmp;
219
220
tmp = ioread32be(&regs->command_config);
221
if (en)
222
tmp |= CMD_CFG_PAUSE_IGNORE;
223
else
224
tmp &= ~CMD_CFG_PAUSE_IGNORE;
225
iowrite32be(tmp, &regs->command_config);
226
}
227
228
void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
229
{
230
uint32_t tmp;
231
232
tmp = ioread32be(&regs->command_config);
233
if (en)
234
tmp |= CMD_CFG_EN_TIMESTAMP;
235
else
236
tmp &= ~CMD_CFG_EN_TIMESTAMP;
237
iowrite32be(tmp, &regs->command_config);
238
}
239
240
uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
241
{
242
return ioread32be(&regs->ievent) & ev_mask;
243
}
244
245
void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
246
{
247
iowrite32be(ev_mask, &regs->ievent);
248
}
249
250
uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
251
{
252
return ioread32be(&regs->imask);
253
}
254
255
void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
256
{
257
uint32_t tmp0, tmp1;
258
259
tmp0 = (uint32_t)(adr[0] |
260
adr[1] << 8 |
261
adr[2] << 16 |
262
adr[3] << 24);
263
tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
264
iowrite32be(tmp0, &regs->mac_addr_2);
265
iowrite32be(tmp1, &regs->mac_addr_3);
266
}
267
268
void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
269
{
270
iowrite32be(0, &regs->mac_addr_2);
271
iowrite32be(0, &regs->mac_addr_3);
272
}
273
274
uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
275
{
276
return ioread32be(&regs->tgec_id);
277
}
278
279
void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
280
{
281
iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
282
}
283
284
void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
285
{
286
iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
287
}
288
289
uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
290
{
291
return (uint16_t) ioread32be(&regs->maxfrm);
292
}
293
294
void fman_tgec_defconfig(struct tgec_cfg *cfg)
295
{
296
cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
297
cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
298
cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
299
cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
300
cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
301
cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
302
cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
303
cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
304
cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
305
cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
306
cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
307
cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
308
cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
309
cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
310
cfg->pause_quant = DEFAULT_PAUSE_QUANT;
311
#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
312
cfg->skip_fman11_workaround = FALSE;
313
#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
314
}
315
316
int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
317
uint32_t exception_mask)
318
{
319
uint32_t tmp;
320
321
/* Config */
322
tmp = 0x40; /* CRC forward */
323
if (cfg->wan_mode_enable)
324
tmp |= CMD_CFG_WAN_MODE;
325
if (cfg->promiscuous_mode_enable)
326
tmp |= CMD_CFG_PROMIS_EN;
327
if (cfg->pause_forward_enable)
328
tmp |= CMD_CFG_PAUSE_FWD;
329
if (cfg->pause_ignore)
330
tmp |= CMD_CFG_PAUSE_IGNORE;
331
if (cfg->tx_addr_ins_enable)
332
tmp |= CMD_CFG_TX_ADDR_INS;
333
if (cfg->loopback_enable)
334
tmp |= CMD_CFG_LOOPBACK_EN;
335
if (cfg->cmd_frame_enable)
336
tmp |= CMD_CFG_CMD_FRM_EN;
337
if (cfg->rx_error_discard)
338
tmp |= CMD_CFG_RX_ER_DISC;
339
if (cfg->send_idle_enable)
340
tmp |= CMD_CFG_SEND_IDLE;
341
if (cfg->no_length_check_enable)
342
tmp |= CMD_CFG_NO_LEN_CHK;
343
if (cfg->time_stamp_enable)
344
tmp |= CMD_CFG_EN_TIMESTAMP;
345
iowrite32be(tmp, &regs->command_config);
346
347
/* Max Frame Length */
348
iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
349
/* Pause Time */
350
iowrite32be(cfg->pause_quant, &regs->pause_quant);
351
352
/* clear all pending events and set-up interrupts */
353
fman_tgec_ack_event(regs, 0xffffffff);
354
fman_tgec_enable_interrupt(regs, exception_mask);
355
356
return 0;
357
}
358
359
void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
360
{
361
uint32_t tmp;
362
363
/* restore the default tx ipg Length */
364
tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
365
366
iowrite32be(tmp, &regs->tx_ipg_len);
367
}
368
369