xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac.c (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
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_memac.h"
35 
36 
37 uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
38 {
39     return ioread32be(&regs->ievent) & ev_mask;
40 }
41 
42 uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
43 {
44     return ioread32be(&regs->imask);
45 }
46 
47 void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
48 {
49     iowrite32be(ev_mask, &regs->ievent);
50 }
51 
52 void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
53 {
54     uint32_t tmp;
55 
56     tmp = ioread32be(&regs->command_config);
57 
58     if (val)
59         tmp |= CMD_CFG_PROMIS_EN;
60     else
61         tmp &= ~CMD_CFG_PROMIS_EN;
62 
63     iowrite32be(tmp, &regs->command_config);
64 }
65 
66 void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
67                     uint8_t paddr_num)
68 {
69     if (paddr_num == 0) {
70         iowrite32be(0, &regs->mac_addr0.mac_addr_l);
71         iowrite32be(0, &regs->mac_addr0.mac_addr_u);
72     } else {
73         iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
74         iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
75     }
76 }
77 
78 void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
79                     uint8_t *adr,
80                     uint8_t paddr_num)
81 {
82     uint32_t tmp0, tmp1;
83 
84     tmp0 = (uint32_t)(adr[0] |
85             adr[1] << 8 |
86             adr[2] << 16 |
87             adr[3] << 24);
88     tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
89 
90     if (paddr_num == 0) {
91         iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
92         iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
93     } else {
94         iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
95         iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
96     }
97 }
98 
99 void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
100 {
101     uint32_t tmp;
102 
103     tmp = ioread32be(&regs->command_config);
104 
105     if (apply_rx)
106         tmp |= CMD_CFG_RX_EN;
107 
108     if (apply_tx)
109         tmp |= CMD_CFG_TX_EN;
110 
111     iowrite32be(tmp, &regs->command_config);
112 }
113 
114 void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
115 {
116     uint32_t tmp;
117 
118     tmp = ioread32be(&regs->command_config);
119 
120     if (apply_rx)
121         tmp &= ~CMD_CFG_RX_EN;
122 
123     if (apply_tx)
124         tmp &= ~CMD_CFG_TX_EN;
125 
126     iowrite32be(tmp, &regs->command_config);
127 }
128 
129 void fman_memac_reset_stat(struct memac_regs *regs)
130 {
131     uint32_t tmp;
132 
133     tmp = ioread32be(&regs->statn_config);
134 
135     tmp |= STATS_CFG_CLR;
136 
137     iowrite32be(tmp, &regs->statn_config);
138 
139     while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
140 }
141 
142 void fman_memac_reset(struct memac_regs *regs)
143 {
144     uint32_t tmp;
145 
146     tmp = ioread32be(&regs->command_config);
147 
148     tmp |= CMD_CFG_SW_RESET;
149 
150     iowrite32be(tmp, &regs->command_config);
151 
152     while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
153 }
154 
155 int fman_memac_init(struct memac_regs *regs,
156         struct memac_cfg *cfg,
157         enum enet_interface enet_interface,
158         enum enet_speed enet_speed,
159 	bool slow_10g_if,
160         uint32_t exceptions)
161 {
162     uint32_t    tmp;
163 
164     /* Config */
165     tmp = 0;
166     if (cfg->wan_mode_enable)
167         tmp |= CMD_CFG_WAN_MODE;
168     if (cfg->promiscuous_mode_enable)
169         tmp |= CMD_CFG_PROMIS_EN;
170     if (cfg->pause_forward_enable)
171         tmp |= CMD_CFG_PAUSE_FWD;
172     if (cfg->pause_ignore)
173         tmp |= CMD_CFG_PAUSE_IGNORE;
174     if (cfg->tx_addr_ins_enable)
175         tmp |= CMD_CFG_TX_ADDR_INS;
176     if (cfg->loopback_enable)
177         tmp |= CMD_CFG_LOOPBACK_EN;
178     if (cfg->cmd_frame_enable)
179         tmp |= CMD_CFG_CNT_FRM_EN;
180     if (cfg->send_idle_enable)
181         tmp |= CMD_CFG_SEND_IDLE;
182     if (cfg->no_length_check_enable)
183         tmp |= CMD_CFG_NO_LEN_CHK;
184     if (cfg->rx_sfd_any)
185         tmp |= CMD_CFG_SFD_ANY;
186     if (cfg->pad_enable)
187         tmp |= CMD_CFG_TX_PAD_EN;
188     if (cfg->wake_on_lan)
189         tmp |= CMD_CFG_MG;
190 
191     tmp |= CMD_CFG_CRC_FWD;
192 
193     iowrite32be(tmp, &regs->command_config);
194 
195     /* Max Frame Length */
196     iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
197 
198     /* Pause Time */
199     iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
200     iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
201 
202     /* IF_MODE */
203     tmp = 0;
204     switch (enet_interface) {
205     case E_ENET_IF_XGMII:
206     case E_ENET_IF_XFI:
207         tmp |= IF_MODE_XGMII;
208         break;
209     default:
210         tmp |= IF_MODE_GMII;
211         if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
212             tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
213     }
214     iowrite32be(tmp, &regs->if_mode);
215 
216 	/* TX_FIFO_SECTIONS */
217 	tmp = 0;
218 	if (enet_interface == E_ENET_IF_XGMII ||
219 		enet_interface == E_ENET_IF_XFI) {
220 		if(slow_10g_if) {
221 			tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
222 				TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
223 		} else {
224 			tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
225 				TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
226 		}
227 	} else {
228 		tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
229 				TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
230 	}
231 	iowrite32be(tmp, &regs->tx_fifo_sections);
232 
233     /* clear all pending events and set-up interrupts */
234     fman_memac_ack_event(regs, 0xffffffff);
235     fman_memac_set_exception(regs, exceptions, TRUE);
236 
237     return 0;
238 }
239 
240 void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
241 {
242     uint32_t tmp;
243 
244     tmp = ioread32be(&regs->imask);
245     if (enable)
246         tmp |= val;
247     else
248         tmp &= ~val;
249 
250     iowrite32be(tmp, &regs->imask);
251 }
252 
253 void fman_memac_reset_filter_table(struct memac_regs *regs)
254 {
255 	uint32_t i;
256 	for (i = 0; i < 64; i++)
257 		iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
258 }
259 
260 void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
261 {
262 	iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
263 }
264 
265 void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
266 {
267     iowrite32be(val, &regs->hashtable_ctrl);
268 }
269 
270 uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
271 {
272     uint32_t tmp;
273 
274     tmp = ioread32be(&regs->maxfrm);
275 
276     return(uint16_t)tmp;
277 }
278 
279 
280 void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
281                 uint8_t priority,
282                 uint16_t pause_time,
283                 uint16_t thresh_time)
284 {
285     uint32_t tmp;
286 
287 	tmp = ioread32be(&regs->tx_fifo_sections);
288 
289 	if (priority == 0xff) {
290 		GET_TX_EMPTY_DEFAULT_VALUE(tmp);
291 		iowrite32be(tmp, &regs->tx_fifo_sections);
292 
293 		tmp = ioread32be(&regs->command_config);
294 		tmp &= ~CMD_CFG_PFC_MODE;
295 		priority = 0;
296 	} else {
297 		GET_TX_EMPTY_PFC_VALUE(tmp);
298 		iowrite32be(tmp, &regs->tx_fifo_sections);
299 
300 		tmp = ioread32be(&regs->command_config);
301 		tmp |= CMD_CFG_PFC_MODE;
302     }
303 
304     iowrite32be(tmp, &regs->command_config);
305 
306     tmp = ioread32be(&regs->pause_quanta[priority / 2]);
307     if (priority % 2)
308         tmp &= 0x0000FFFF;
309     else
310         tmp &= 0xFFFF0000;
311     tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
312     iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
313 
314     tmp = ioread32be(&regs->pause_thresh[priority / 2]);
315     if (priority % 2)
316             tmp &= 0x0000FFFF;
317     else
318             tmp &= 0xFFFF0000;
319     tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
320     iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
321 }
322 
323 void fman_memac_set_rx_ignore_pause_frames(struct memac_regs    *regs,bool enable)
324 {
325     uint32_t tmp;
326 
327     tmp = ioread32be(&regs->command_config);
328     if (enable)
329         tmp |= CMD_CFG_PAUSE_IGNORE;
330     else
331         tmp &= ~CMD_CFG_PAUSE_IGNORE;
332 
333     iowrite32be(tmp, &regs->command_config);
334 }
335 
336 void fman_memac_set_wol(struct memac_regs *regs, bool enable)
337 {
338     uint32_t tmp;
339 
340     tmp = ioread32be(&regs->command_config);
341 
342     if (enable)
343         tmp |= CMD_CFG_MG;
344     else
345         tmp &= ~CMD_CFG_MG;
346 
347     iowrite32be(tmp, &regs->command_config);
348 }
349 
350 #define GET_MEMAC_CNTR_64(bn) \
351         (ioread32be(&regs->bn ## _l) | \
352         ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
353 
354 uint64_t fman_memac_get_counter(struct memac_regs *regs,
355                 enum memac_counters reg_name)
356 {
357     uint64_t ret_val;
358 
359     switch (reg_name) {
360     case E_MEMAC_COUNTER_R64:
361         ret_val = GET_MEMAC_CNTR_64(r64);
362         break;
363     case E_MEMAC_COUNTER_R127:
364         ret_val = GET_MEMAC_CNTR_64(r127);
365         break;
366     case E_MEMAC_COUNTER_R255:
367         ret_val = GET_MEMAC_CNTR_64(r255);
368         break;
369     case E_MEMAC_COUNTER_R511:
370         ret_val = GET_MEMAC_CNTR_64(r511);
371         break;
372     case E_MEMAC_COUNTER_R1023:
373         ret_val = GET_MEMAC_CNTR_64(r1023);
374         break;
375     case E_MEMAC_COUNTER_R1518:
376         ret_val = GET_MEMAC_CNTR_64(r1518);
377         break;
378     case E_MEMAC_COUNTER_R1519X:
379         ret_val = GET_MEMAC_CNTR_64(r1519x);
380         break;
381     case E_MEMAC_COUNTER_RFRG:
382         ret_val = GET_MEMAC_CNTR_64(rfrg);
383         break;
384     case E_MEMAC_COUNTER_RJBR:
385         ret_val = GET_MEMAC_CNTR_64(rjbr);
386         break;
387     case E_MEMAC_COUNTER_RDRP:
388         ret_val = GET_MEMAC_CNTR_64(rdrp);
389         break;
390     case E_MEMAC_COUNTER_RALN:
391         ret_val = GET_MEMAC_CNTR_64(raln);
392         break;
393     case E_MEMAC_COUNTER_TUND:
394         ret_val = GET_MEMAC_CNTR_64(tund);
395         break;
396     case E_MEMAC_COUNTER_ROVR:
397         ret_val = GET_MEMAC_CNTR_64(rovr);
398         break;
399     case E_MEMAC_COUNTER_RXPF:
400         ret_val = GET_MEMAC_CNTR_64(rxpf);
401         break;
402     case E_MEMAC_COUNTER_TXPF:
403         ret_val = GET_MEMAC_CNTR_64(txpf);
404         break;
405     case E_MEMAC_COUNTER_ROCT:
406         ret_val = GET_MEMAC_CNTR_64(roct);
407         break;
408     case E_MEMAC_COUNTER_RMCA:
409         ret_val = GET_MEMAC_CNTR_64(rmca);
410         break;
411     case E_MEMAC_COUNTER_RBCA:
412         ret_val = GET_MEMAC_CNTR_64(rbca);
413         break;
414     case E_MEMAC_COUNTER_RPKT:
415         ret_val = GET_MEMAC_CNTR_64(rpkt);
416         break;
417     case E_MEMAC_COUNTER_RUCA:
418         ret_val = GET_MEMAC_CNTR_64(ruca);
419         break;
420     case E_MEMAC_COUNTER_RERR:
421         ret_val = GET_MEMAC_CNTR_64(rerr);
422         break;
423     case E_MEMAC_COUNTER_TOCT:
424         ret_val = GET_MEMAC_CNTR_64(toct);
425         break;
426     case E_MEMAC_COUNTER_TMCA:
427         ret_val = GET_MEMAC_CNTR_64(tmca);
428         break;
429     case E_MEMAC_COUNTER_TBCA:
430         ret_val = GET_MEMAC_CNTR_64(tbca);
431         break;
432     case E_MEMAC_COUNTER_TUCA:
433         ret_val = GET_MEMAC_CNTR_64(tuca);
434         break;
435     case E_MEMAC_COUNTER_TERR:
436         ret_val = GET_MEMAC_CNTR_64(terr);
437         break;
438     default:
439         ret_val = 0;
440     }
441 
442     return ret_val;
443 }
444 
445 void fman_memac_adjust_link(struct memac_regs *regs,
446         enum enet_interface iface_mode,
447         enum enet_speed speed, bool full_dx)
448 {
449     uint32_t    tmp;
450 
451     tmp = ioread32be(&regs->if_mode);
452 
453     if (full_dx)
454         tmp &= ~IF_MODE_HD;
455     else
456         tmp |= IF_MODE_HD;
457 
458     if (iface_mode == E_ENET_IF_RGMII) {
459         /* Configure RGMII in manual mode */
460         tmp &= ~IF_MODE_RGMII_AUTO;
461         tmp &= ~IF_MODE_RGMII_SP_MASK;
462 
463         if (full_dx)
464             tmp |= IF_MODE_RGMII_FD;
465         else
466             tmp &= ~IF_MODE_RGMII_FD;
467 
468         switch (speed) {
469         case E_ENET_SPEED_1000:
470             tmp |= IF_MODE_RGMII_1000;
471             break;
472         case E_ENET_SPEED_100:
473             tmp |= IF_MODE_RGMII_100;
474             break;
475         case E_ENET_SPEED_10:
476             tmp |= IF_MODE_RGMII_10;
477             break;
478         default:
479             break;
480         }
481     }
482 
483     iowrite32be(tmp, &regs->if_mode);
484 }
485 
486 void fman_memac_defconfig(struct memac_cfg *cfg)
487 {
488     cfg->reset_on_init		= FALSE;
489     cfg->wan_mode_enable		= FALSE;
490     cfg->promiscuous_mode_enable	= FALSE;
491     cfg->pause_forward_enable	= FALSE;
492     cfg->pause_ignore		= FALSE;
493     cfg->tx_addr_ins_enable		= FALSE;
494     cfg->loopback_enable		= FALSE;
495     cfg->cmd_frame_enable		= FALSE;
496     cfg->rx_error_discard		= FALSE;
497     cfg->send_idle_enable		= FALSE;
498     cfg->no_length_check_enable	= TRUE;
499     cfg->lgth_check_nostdr		= FALSE;
500     cfg->time_stamp_enable		= FALSE;
501     cfg->tx_ipg_length		= DEFAULT_TX_IPG_LENGTH;
502     cfg->max_frame_length		= DEFAULT_FRAME_LENGTH;
503     cfg->pause_quanta		= DEFAULT_PAUSE_QUANTA;
504     cfg->pad_enable			= TRUE;
505     cfg->phy_tx_ena_on		= FALSE;
506     cfg->rx_sfd_any			= FALSE;
507     cfg->rx_pbl_fwd			= FALSE;
508     cfg->tx_pbl_fwd			= FALSE;
509     cfg->debug_mode			= FALSE;
510     cfg->wake_on_lan        = FALSE;
511 }
512