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
37uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
38{
39    return ioread32be(&regs->ievent) & ev_mask;
40}
41
42uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
43{
44    return ioread32be(&regs->imask);
45}
46
47void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
48{
49    iowrite32be(ev_mask, &regs->ievent);
50}
51
52void 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
66void 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
78void 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
99void 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
114void 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
129void 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
142void 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
155int 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
240void 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
253void 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
260void 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
265void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
266{
267    iowrite32be(val, &regs->hashtable_ctrl);
268}
269
270uint16_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
280void 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
323void 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
336void 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
354uint64_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
445void 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
486void 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