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_dtsec.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_dtsec.h"
35
36
37
void fman_dtsec_stop_rx(struct dtsec_regs *regs)
38
{
39
/* Assert the graceful stop bit */
40
iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
41
}
42
43
void fman_dtsec_stop_tx(struct dtsec_regs *regs)
44
{
45
/* Assert the graceful stop bit */
46
iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
47
}
48
49
void fman_dtsec_start_tx(struct dtsec_regs *regs)
50
{
51
/* clear the graceful stop bit */
52
iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
53
}
54
55
void fman_dtsec_start_rx(struct dtsec_regs *regs)
56
{
57
/* clear the graceful stop bit */
58
iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
59
}
60
61
void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
62
{
63
cfg->halfdup_on = DEFAULT_HALFDUP_ON;
64
cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
65
cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
66
cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
67
cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
68
cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
69
cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
70
cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
71
cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
72
cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
73
cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
74
cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
75
cfg->tx_crc = DEFAULT_TX_CRC;
76
cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
77
cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
78
cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
79
cfg->rx_prepend = DEFAULT_RX_PREPEND;
80
cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
81
cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
82
cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
83
cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
84
cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
85
cfg->loopback = DEFAULT_LOOPBACK;
86
cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
87
cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
88
cfg->rx_flow = DEFAULT_RX_FLOW;
89
cfg->tx_flow = DEFAULT_TX_FLOW;
90
cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
91
cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
92
cfg->rx_promisc = DEFAULT_RX_PROMISC;
93
cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
94
cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
95
cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
96
cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
97
cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
98
cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
99
cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
100
}
101
102
int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
103
enum enet_interface iface_mode,
104
enum enet_speed iface_speed,
105
uint8_t *macaddr,
106
uint8_t fm_rev_maj,
107
uint8_t fm_rev_min,
108
uint32_t exception_mask)
109
{
110
bool is_rgmii = FALSE;
111
bool is_sgmii = FALSE;
112
bool is_qsgmii = FALSE;
113
int i;
114
uint32_t tmp;
115
116
UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
117
118
/* let's start with a soft reset */
119
iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
120
iowrite32be(0, &regs->maccfg1);
121
122
/*************dtsec_id2******************/
123
tmp = ioread32be(&regs->tsec_id2);
124
125
/* check RGMII support */
126
if (iface_mode == E_ENET_IF_RGMII ||
127
iface_mode == E_ENET_IF_RMII)
128
if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
129
return -EINVAL;
130
131
if (iface_mode == E_ENET_IF_SGMII ||
132
iface_mode == E_ENET_IF_MII)
133
if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
134
return -EINVAL;
135
136
/***************ECNTRL************************/
137
138
is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
139
is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
140
is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
141
142
tmp = 0;
143
if (is_rgmii || iface_mode == E_ENET_IF_GMII)
144
tmp |= DTSEC_ECNTRL_GMIIM;
145
if (is_sgmii)
146
tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
147
if (is_qsgmii)
148
tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
149
DTSEC_ECNTRL_QSGMIIM);
150
if (is_rgmii)
151
tmp |= DTSEC_ECNTRL_RPM;
152
if (iface_speed == E_ENET_SPEED_100)
153
tmp |= DTSEC_ECNTRL_R100M;
154
155
iowrite32be(tmp, &regs->ecntrl);
156
/***************ECNTRL************************/
157
158
/***************TCTRL************************/
159
tmp = 0;
160
if (cfg->halfdup_on)
161
tmp |= DTSEC_TCTRL_THDF;
162
if (cfg->tx_time_stamp_en)
163
tmp |= DTSEC_TCTRL_TTSE;
164
165
iowrite32be(tmp, &regs->tctrl);
166
167
/***************TCTRL************************/
168
169
/***************PTV************************/
170
tmp = 0;
171
172
#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
173
if ((fm_rev_maj == 1) && (fm_rev_min == 0))
174
cfg->tx_pause_time += 2;
175
#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
176
177
if (cfg->tx_pause_time)
178
tmp |= cfg->tx_pause_time;
179
if (cfg->tx_pause_time_extd)
180
tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
181
iowrite32be(tmp, &regs->ptv);
182
183
/***************RCTRL************************/
184
tmp = 0;
185
tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
186
if (cfg->rx_ctrl_acc)
187
tmp |= RCTRL_CFA;
188
if (cfg->rx_group_hash_exd)
189
tmp |= RCTRL_GHTX;
190
if (cfg->rx_time_stamp_en)
191
tmp |= RCTRL_RTSE;
192
if (cfg->rx_drop_bcast)
193
tmp |= RCTRL_BC_REJ;
194
if (cfg->rx_short_frm)
195
tmp |= RCTRL_RSF;
196
if (cfg->rx_promisc)
197
tmp |= RCTRL_PROM;
198
199
iowrite32be(tmp, &regs->rctrl);
200
/***************RCTRL************************/
201
202
/*
203
* Assign a Phy Address to the TBI (TBIPA).
204
* Done also in cases where TBI is not selected to avoid conflict with
205
* the external PHY's Physical address
206
*/
207
iowrite32be(cfg->tbipa, &regs->tbipa);
208
209
/***************TMR_CTL************************/
210
iowrite32be(0, &regs->tmr_ctrl);
211
212
if (cfg->ptp_tsu_en) {
213
tmp = 0;
214
tmp |= TMR_PEVENT_TSRE;
215
iowrite32be(tmp, &regs->tmr_pevent);
216
217
if (cfg->ptp_exception_en) {
218
tmp = 0;
219
tmp |= TMR_PEMASK_TSREEN;
220
iowrite32be(tmp, &regs->tmr_pemask);
221
}
222
}
223
224
/***************MACCFG1***********************/
225
tmp = 0;
226
if (cfg->loopback)
227
tmp |= MACCFG1_LOOPBACK;
228
if (cfg->rx_flow)
229
tmp |= MACCFG1_RX_FLOW;
230
if (cfg->tx_flow)
231
tmp |= MACCFG1_TX_FLOW;
232
iowrite32be(tmp, &regs->maccfg1);
233
234
/***************MACCFG1***********************/
235
236
/***************MACCFG2***********************/
237
tmp = 0;
238
239
if (iface_speed < E_ENET_SPEED_1000)
240
tmp |= MACCFG2_NIBBLE_MODE;
241
else if (iface_speed == E_ENET_SPEED_1000)
242
tmp |= MACCFG2_BYTE_MODE;
243
244
tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
245
<< PREAMBLE_LENGTH_SHIFT;
246
247
if (cfg->rx_preamble)
248
tmp |= MACCFG2_PRE_AM_Rx_EN;
249
if (cfg->tx_preamble)
250
tmp |= MACCFG2_PRE_AM_Tx_EN;
251
if (cfg->rx_len_check)
252
tmp |= MACCFG2_LENGTH_CHECK;
253
if (cfg->tx_pad_crc)
254
tmp |= MACCFG2_PAD_CRC_EN;
255
if (cfg->tx_crc)
256
tmp |= MACCFG2_CRC_EN;
257
if (!cfg->halfdup_on)
258
tmp |= MACCFG2_FULL_DUPLEX;
259
iowrite32be(tmp, &regs->maccfg2);
260
261
/***************MACCFG2***********************/
262
263
/***************IPGIFG************************/
264
tmp = (((cfg->non_back_to_back_ipg1 <<
265
IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
266
& IPGIFG_NON_BACK_TO_BACK_IPG_1)
267
| ((cfg->non_back_to_back_ipg2 <<
268
IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
269
& IPGIFG_NON_BACK_TO_BACK_IPG_2)
270
| ((cfg->min_ifg_enforcement <<
271
IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
272
& IPGIFG_MIN_IFG_ENFORCEMENT)
273
| (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
274
iowrite32be(tmp, &regs->ipgifg);
275
276
/***************IPGIFG************************/
277
278
/***************HAFDUP************************/
279
tmp = 0;
280
281
if (cfg->halfdup_alt_backoff_en)
282
tmp = (uint32_t)(HAFDUP_ALT_BEB |
283
((cfg->halfdup_alt_backoff_val & 0x0000000f)
284
<< HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
285
if (cfg->halfdup_bp_no_backoff)
286
tmp |= HAFDUP_BP_NO_BACKOFF;
287
if (cfg->halfdup_no_backoff)
288
tmp |= HAFDUP_NO_BACKOFF;
289
if (cfg->halfdup_excess_defer)
290
tmp |= HAFDUP_EXCESS_DEFER;
291
tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
292
& HAFDUP_RETRANSMISSION_MAX);
293
tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
294
295
iowrite32be(tmp, &regs->hafdup);
296
/***************HAFDUP************************/
297
298
/***************MAXFRM************************/
299
/* Initialize MAXFRM */
300
iowrite32be(cfg->maximum_frame, &regs->maxfrm);
301
302
/***************MAXFRM************************/
303
304
/***************CAM1************************/
305
iowrite32be(0xffffffff, &regs->cam1);
306
iowrite32be(0xffffffff, &regs->cam2);
307
308
/***************IMASK************************/
309
iowrite32be(exception_mask, &regs->imask);
310
/***************IMASK************************/
311
312
/***************IEVENT************************/
313
iowrite32be(0xffffffff, &regs->ievent);
314
315
/***************MACSTNADDR1/2*****************/
316
317
tmp = (uint32_t)((macaddr[5] << 24) |
318
(macaddr[4] << 16) |
319
(macaddr[3] << 8) |
320
macaddr[2]);
321
iowrite32be(tmp, &regs->macstnaddr1);
322
323
tmp = (uint32_t)((macaddr[1] << 24) |
324
(macaddr[0] << 16));
325
iowrite32be(tmp, &regs->macstnaddr2);
326
327
/***************MACSTNADDR1/2*****************/
328
329
/*****************HASH************************/
330
for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
331
/* Initialize IADDRx */
332
iowrite32be(0, &regs->igaddr[i]);
333
/* Initialize GADDRx */
334
iowrite32be(0, &regs->gaddr[i]);
335
}
336
337
fman_dtsec_reset_stat(regs);
338
339
return 0;
340
}
341
342
uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
343
{
344
return (uint16_t)ioread32be(&regs->maxfrm);
345
}
346
347
void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
348
{
349
iowrite32be(length, &regs->maxfrm);
350
}
351
352
void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
353
{
354
uint32_t tmp;
355
356
tmp = (uint32_t)((adr[5] << 24) |
357
(adr[4] << 16) |
358
(adr[3] << 8) |
359
adr[2]);
360
iowrite32be(tmp, &regs->macstnaddr1);
361
362
tmp = (uint32_t)((adr[1] << 24) |
363
(adr[0] << 16));
364
iowrite32be(tmp, &regs->macstnaddr2);
365
}
366
367
void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
368
{
369
uint32_t tmp1, tmp2;
370
371
tmp1 = ioread32be(&regs->macstnaddr1);
372
tmp2 = ioread32be(&regs->macstnaddr2);
373
374
macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
375
macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
376
macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
377
macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
378
macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
379
macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
380
}
381
382
void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
383
{
384
int32_t bucket;
385
if (ghtx)
386
bucket = (int32_t)((crc >> 23) & 0x1ff);
387
else {
388
bucket = (int32_t)((crc >> 24) & 0xff);
389
/* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
390
if (mcast)
391
bucket += 0x100;
392
}
393
fman_dtsec_set_bucket(regs, bucket, TRUE);
394
}
395
396
void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
397
{
398
int reg_idx = (bucket >> 5) & 0xf;
399
int bit_idx = bucket & 0x1f;
400
uint32_t bit_mask = 0x80000000 >> bit_idx;
401
uint32_t *reg;
402
403
if (reg_idx > 7)
404
reg = &regs->gaddr[reg_idx-8];
405
else
406
reg = &regs->igaddr[reg_idx];
407
408
if (enable)
409
iowrite32be(ioread32be(reg) | bit_mask, reg);
410
else
411
iowrite32be(ioread32be(reg) & (~bit_mask), reg);
412
}
413
414
void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
415
{
416
int i;
417
bool ghtx;
418
419
ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
420
421
if (ucast || (ghtx && mcast)) {
422
for (i = 0; i < NUM_OF_HASH_REGS; i++)
423
iowrite32be(0, &regs->igaddr[i]);
424
}
425
if (mcast) {
426
for (i = 0; i < NUM_OF_HASH_REGS; i++)
427
iowrite32be(0, &regs->gaddr[i]);
428
}
429
}
430
431
int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
432
uint8_t addr)
433
{
434
if (addr > 0 && addr < 32)
435
iowrite32be(addr, &regs->tbipa);
436
else
437
return -EINVAL;
438
439
return 0;
440
}
441
442
void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
443
{
444
uint32_t tmp;
445
446
tmp = ioread32be(&regs->maccfg2);
447
if (en)
448
tmp |= MACCFG2_MAGIC_PACKET_EN;
449
else
450
tmp &= ~MACCFG2_MAGIC_PACKET_EN;
451
iowrite32be(tmp, &regs->maccfg2);
452
}
453
454
int fman_dtsec_adjust_link(struct dtsec_regs *regs,
455
enum enet_interface iface_mode,
456
enum enet_speed speed, bool full_dx)
457
{
458
uint32_t tmp;
459
460
UNUSED(iface_mode);
461
462
if ((speed == E_ENET_SPEED_1000) && !full_dx)
463
return -EINVAL;
464
465
tmp = ioread32be(&regs->maccfg2);
466
if (!full_dx)
467
tmp &= ~MACCFG2_FULL_DUPLEX;
468
else
469
tmp |= MACCFG2_FULL_DUPLEX;
470
471
tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
472
if (speed < E_ENET_SPEED_1000)
473
tmp |= MACCFG2_NIBBLE_MODE;
474
else if (speed == E_ENET_SPEED_1000)
475
tmp |= MACCFG2_BYTE_MODE;
476
iowrite32be(tmp, &regs->maccfg2);
477
478
tmp = ioread32be(&regs->ecntrl);
479
if (speed == E_ENET_SPEED_100)
480
tmp |= DTSEC_ECNTRL_R100M;
481
else
482
tmp &= ~DTSEC_ECNTRL_R100M;
483
iowrite32be(tmp, &regs->ecntrl);
484
485
return 0;
486
}
487
488
void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
489
{
490
uint32_t tmp;
491
492
tmp = ioread32be(&regs->rctrl);
493
494
if (enable)
495
tmp |= RCTRL_UPROM;
496
else
497
tmp &= ~RCTRL_UPROM;
498
499
iowrite32be(tmp, &regs->rctrl);
500
}
501
502
void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
503
{
504
uint32_t tmp;
505
506
tmp = ioread32be(&regs->rctrl);
507
508
if (enable)
509
tmp |= RCTRL_MPROM;
510
else
511
tmp &= ~RCTRL_MPROM;
512
513
iowrite32be(tmp, &regs->rctrl);
514
}
515
516
bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
517
uint32_t *car1, uint32_t *car2)
518
{
519
/* read carry registers */
520
*car1 = ioread32be(&regs->car1);
521
*car2 = ioread32be(&regs->car2);
522
/* clear carry registers */
523
if (*car1)
524
iowrite32be(*car1, &regs->car1);
525
if (*car2)
526
iowrite32be(*car2, &regs->car2);
527
528
return (bool)((*car1 | *car2) ? TRUE : FALSE);
529
}
530
531
void fman_dtsec_reset_stat(struct dtsec_regs *regs)
532
{
533
/* clear HW counters */
534
iowrite32be(ioread32be(&regs->ecntrl) |
535
DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
536
}
537
538
int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
539
{
540
switch (level) {
541
case E_MAC_STAT_NONE:
542
iowrite32be(0xffffffff, &regs->cam1);
543
iowrite32be(0xffffffff, &regs->cam2);
544
iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
545
&regs->ecntrl);
546
iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
547
&regs->imask);
548
break;
549
case E_MAC_STAT_PARTIAL:
550
iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
551
iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
552
iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
553
&regs->ecntrl);
554
iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
555
&regs->imask);
556
break;
557
case E_MAC_STAT_MIB_GRP1:
558
iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
559
iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
560
iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
561
&regs->ecntrl);
562
iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
563
&regs->imask);
564
break;
565
case E_MAC_STAT_FULL:
566
iowrite32be(0, &regs->cam1);
567
iowrite32be(0, &regs->cam2);
568
iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
569
&regs->ecntrl);
570
iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
571
&regs->imask);
572
break;
573
default:
574
return -EINVAL;
575
}
576
577
return 0;
578
}
579
580
void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
581
{
582
if (en) {
583
iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
584
&regs->rctrl);
585
iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
586
&regs->tctrl);
587
} else {
588
iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
589
&regs->rctrl);
590
iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
591
&regs->tctrl);
592
}
593
}
594
595
void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
596
{
597
uint32_t tmp;
598
599
tmp = ioread32be(&regs->maccfg1);
600
601
if (apply_rx)
602
tmp |= MACCFG1_RX_EN ;
603
604
if (apply_tx)
605
tmp |= MACCFG1_TX_EN ;
606
607
iowrite32be(tmp, &regs->maccfg1);
608
}
609
610
void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
611
{
612
iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
613
iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
614
}
615
616
void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
617
uint64_t addr,
618
uint8_t paddr_num)
619
{
620
uint32_t tmp;
621
622
tmp = (uint32_t)(addr);
623
/* swap */
624
tmp = (((tmp & 0x000000FF) << 24) |
625
((tmp & 0x0000FF00) << 8) |
626
((tmp & 0x00FF0000) >> 8) |
627
((tmp & 0xFF000000) >> 24));
628
iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
629
630
tmp = (uint32_t)(addr>>32);
631
/* swap */
632
tmp = (((tmp & 0x000000FF) << 24) |
633
((tmp & 0x0000FF00) << 8) |
634
((tmp & 0x00FF0000) >> 8) |
635
((tmp & 0xFF000000) >> 24));
636
iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
637
}
638
639
void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
640
{
641
uint32_t tmp;
642
643
tmp = ioread32be(&regs->maccfg1);
644
645
if (apply_rx)
646
tmp &= ~MACCFG1_RX_EN;
647
648
if (apply_tx)
649
tmp &= ~MACCFG1_TX_EN;
650
651
iowrite32be(tmp, &regs->maccfg1);
652
}
653
654
void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
655
{
656
uint32_t ptv = 0;
657
658
/* fixme: don't enable tx pause for half-duplex */
659
660
if (time) {
661
ptv = ioread32be(&regs->ptv);
662
ptv &= 0xffff0000;
663
ptv |= time & 0x0000ffff;
664
iowrite32be(ptv, &regs->ptv);
665
666
/* trigger the transmission of a flow-control pause frame */
667
iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
668
&regs->maccfg1);
669
} else
670
iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
671
&regs->maccfg1);
672
}
673
674
void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
675
{
676
uint32_t tmp;
677
678
/* todo: check if mac is set to full-duplex */
679
680
tmp = ioread32be(&regs->maccfg1);
681
if (en)
682
tmp |= MACCFG1_RX_FLOW;
683
else
684
tmp &= ~MACCFG1_RX_FLOW;
685
iowrite32be(tmp, &regs->maccfg1);
686
}
687
688
uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
689
{
690
return ioread32be(&regs->rctrl);
691
}
692
693
uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
694
{
695
return ioread32be(&regs->tsec_id);
696
}
697
698
uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
699
{
700
return ioread32be(&regs->ievent) & ev_mask;
701
}
702
703
void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
704
{
705
iowrite32be(ev_mask, &regs->ievent);
706
}
707
708
uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
709
{
710
return ioread32be(&regs->imask);
711
}
712
713
uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
714
{
715
uint32_t event;
716
717
event = ioread32be(&regs->tmr_pevent);
718
event &= ioread32be(&regs->tmr_pemask);
719
720
if (event)
721
iowrite32be(event, &regs->tmr_pevent);
722
return event;
723
}
724
725
void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
726
{
727
iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
728
&regs->tmr_pemask);
729
}
730
731
void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
732
{
733
iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
734
&regs->tmr_pemask);
735
}
736
737
void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
738
{
739
iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
740
}
741
742
void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
743
{
744
iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
745
}
746
747
uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
748
enum dtsec_stat_counters reg_name)
749
{
750
uint32_t ret_val;
751
752
switch (reg_name) {
753
case E_DTSEC_STAT_TR64:
754
ret_val = ioread32be(&regs->tr64);
755
break;
756
case E_DTSEC_STAT_TR127:
757
ret_val = ioread32be(&regs->tr127);
758
break;
759
case E_DTSEC_STAT_TR255:
760
ret_val = ioread32be(&regs->tr255);
761
break;
762
case E_DTSEC_STAT_TR511:
763
ret_val = ioread32be(&regs->tr511);
764
break;
765
case E_DTSEC_STAT_TR1K:
766
ret_val = ioread32be(&regs->tr1k);
767
break;
768
case E_DTSEC_STAT_TRMAX:
769
ret_val = ioread32be(&regs->trmax);
770
break;
771
case E_DTSEC_STAT_TRMGV:
772
ret_val = ioread32be(&regs->trmgv);
773
break;
774
case E_DTSEC_STAT_RBYT:
775
ret_val = ioread32be(&regs->rbyt);
776
break;
777
case E_DTSEC_STAT_RPKT:
778
ret_val = ioread32be(&regs->rpkt);
779
break;
780
case E_DTSEC_STAT_RMCA:
781
ret_val = ioread32be(&regs->rmca);
782
break;
783
case E_DTSEC_STAT_RBCA:
784
ret_val = ioread32be(&regs->rbca);
785
break;
786
case E_DTSEC_STAT_RXPF:
787
ret_val = ioread32be(&regs->rxpf);
788
break;
789
case E_DTSEC_STAT_RALN:
790
ret_val = ioread32be(&regs->raln);
791
break;
792
case E_DTSEC_STAT_RFLR:
793
ret_val = ioread32be(&regs->rflr);
794
break;
795
case E_DTSEC_STAT_RCDE:
796
ret_val = ioread32be(&regs->rcde);
797
break;
798
case E_DTSEC_STAT_RCSE:
799
ret_val = ioread32be(&regs->rcse);
800
break;
801
case E_DTSEC_STAT_RUND:
802
ret_val = ioread32be(&regs->rund);
803
break;
804
case E_DTSEC_STAT_ROVR:
805
ret_val = ioread32be(&regs->rovr);
806
break;
807
case E_DTSEC_STAT_RFRG:
808
ret_val = ioread32be(&regs->rfrg);
809
break;
810
case E_DTSEC_STAT_RJBR:
811
ret_val = ioread32be(&regs->rjbr);
812
break;
813
case E_DTSEC_STAT_RDRP:
814
ret_val = ioread32be(&regs->rdrp);
815
break;
816
case E_DTSEC_STAT_TFCS:
817
ret_val = ioread32be(&regs->tfcs);
818
break;
819
case E_DTSEC_STAT_TBYT:
820
ret_val = ioread32be(&regs->tbyt);
821
break;
822
case E_DTSEC_STAT_TPKT:
823
ret_val = ioread32be(&regs->tpkt);
824
break;
825
case E_DTSEC_STAT_TMCA:
826
ret_val = ioread32be(&regs->tmca);
827
break;
828
case E_DTSEC_STAT_TBCA:
829
ret_val = ioread32be(&regs->tbca);
830
break;
831
case E_DTSEC_STAT_TXPF:
832
ret_val = ioread32be(&regs->txpf);
833
break;
834
case E_DTSEC_STAT_TNCL:
835
ret_val = ioread32be(&regs->tncl);
836
break;
837
case E_DTSEC_STAT_TDRP:
838
ret_val = ioread32be(&regs->tdrp);
839
break;
840
default:
841
ret_val = 0;
842
}
843
844
return ret_val;
845
}
846
847