xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.c (revision f81cdf24ba5436367377f7c8e8f51f6df2a75ca7)
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