Path: blob/main/sys/contrib/ncsw/Peripherals/FM/MAC/fman_tgec.c
48524 views
/*1* Copyright 2008-2012 Freescale Semiconductor Inc.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10* * Neither the name of Freescale Semiconductor nor the11* names of its contributors may be used to endorse or promote products12* derived from this software without specific prior written permission.13*14*15* ALTERNATIVELY, this software may be distributed under the terms of the16* GNU General Public License ("GPL") as published by the Free Software17* Foundation, either version 2 of that License or (at your option) any18* later version.19*20* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY21* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED22* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY24* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES25* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;26* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND27* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT28* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS29* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30*/313233#include "fsl_fman_tgec.h"343536void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)37{38uint32_t tmp0, tmp1;3940tmp0 = (uint32_t)(adr[0] |41adr[1] << 8 |42adr[2] << 16 |43adr[3] << 24);44tmp1 = (uint32_t)(adr[4] | adr[5] << 8);45iowrite32be(tmp0, ®s->mac_addr_0);46iowrite32be(tmp1, ®s->mac_addr_1);47}4849void fman_tgec_reset_stat(struct tgec_regs *regs)50{51uint32_t tmp;5253tmp = ioread32be(®s->command_config);5455tmp |= CMD_CFG_STAT_CLR;5657iowrite32be(tmp, ®s->command_config);5859while (ioread32be(®s->command_config) & CMD_CFG_STAT_CLR) ;60}6162#define GET_TGEC_CNTR_64(bn) \63(((uint64_t)ioread32be(®s->bn ## _u) << 32) | \64ioread32be(®s->bn ## _l))6566uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)67{68uint64_t ret_val;6970switch (reg_name) {71case E_TGEC_COUNTER_R64:72ret_val = GET_TGEC_CNTR_64(r64);73break;74case E_TGEC_COUNTER_R127:75ret_val = GET_TGEC_CNTR_64(r127);76break;77case E_TGEC_COUNTER_R255:78ret_val = GET_TGEC_CNTR_64(r255);79break;80case E_TGEC_COUNTER_R511:81ret_val = GET_TGEC_CNTR_64(r511);82break;83case E_TGEC_COUNTER_R1023:84ret_val = GET_TGEC_CNTR_64(r1023);85break;86case E_TGEC_COUNTER_R1518:87ret_val = GET_TGEC_CNTR_64(r1518);88break;89case E_TGEC_COUNTER_R1519X:90ret_val = GET_TGEC_CNTR_64(r1519x);91break;92case E_TGEC_COUNTER_TRFRG:93ret_val = GET_TGEC_CNTR_64(trfrg);94break;95case E_TGEC_COUNTER_TRJBR:96ret_val = GET_TGEC_CNTR_64(trjbr);97break;98case E_TGEC_COUNTER_RDRP:99ret_val = GET_TGEC_CNTR_64(rdrp);100break;101case E_TGEC_COUNTER_RALN:102ret_val = GET_TGEC_CNTR_64(raln);103break;104case E_TGEC_COUNTER_TRUND:105ret_val = GET_TGEC_CNTR_64(trund);106break;107case E_TGEC_COUNTER_TROVR:108ret_val = GET_TGEC_CNTR_64(trovr);109break;110case E_TGEC_COUNTER_RXPF:111ret_val = GET_TGEC_CNTR_64(rxpf);112break;113case E_TGEC_COUNTER_TXPF:114ret_val = GET_TGEC_CNTR_64(txpf);115break;116case E_TGEC_COUNTER_ROCT:117ret_val = GET_TGEC_CNTR_64(roct);118break;119case E_TGEC_COUNTER_RMCA:120ret_val = GET_TGEC_CNTR_64(rmca);121break;122case E_TGEC_COUNTER_RBCA:123ret_val = GET_TGEC_CNTR_64(rbca);124break;125case E_TGEC_COUNTER_RPKT:126ret_val = GET_TGEC_CNTR_64(rpkt);127break;128case E_TGEC_COUNTER_RUCA:129ret_val = GET_TGEC_CNTR_64(ruca);130break;131case E_TGEC_COUNTER_RERR:132ret_val = GET_TGEC_CNTR_64(rerr);133break;134case E_TGEC_COUNTER_TOCT:135ret_val = GET_TGEC_CNTR_64(toct);136break;137case E_TGEC_COUNTER_TMCA:138ret_val = GET_TGEC_CNTR_64(tmca);139break;140case E_TGEC_COUNTER_TBCA:141ret_val = GET_TGEC_CNTR_64(tbca);142break;143case E_TGEC_COUNTER_TUCA:144ret_val = GET_TGEC_CNTR_64(tuca);145break;146case E_TGEC_COUNTER_TERR:147ret_val = GET_TGEC_CNTR_64(terr);148break;149default:150ret_val = 0;151}152153return ret_val;154}155156void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)157{158uint32_t tmp;159160tmp = ioread32be(®s->command_config);161if (apply_rx)162tmp |= CMD_CFG_RX_EN;163if (apply_tx)164tmp |= CMD_CFG_TX_EN;165iowrite32be(tmp, ®s->command_config);166}167168void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)169{170uint32_t tmp_reg_32;171172tmp_reg_32 = ioread32be(®s->command_config);173if (apply_rx)174tmp_reg_32 &= ~CMD_CFG_RX_EN;175if (apply_tx)176tmp_reg_32 &= ~CMD_CFG_TX_EN;177iowrite32be(tmp_reg_32, ®s->command_config);178}179180void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)181{182uint32_t tmp;183184tmp = ioread32be(®s->command_config);185if (val)186tmp |= CMD_CFG_PROMIS_EN;187else188tmp &= ~CMD_CFG_PROMIS_EN;189iowrite32be(tmp, ®s->command_config);190}191192void fman_tgec_reset_filter_table(struct tgec_regs *regs)193{194uint32_t i;195for (i = 0; i < 512; i++)196iowrite32be(i & ~TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl);197}198199void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)200{201uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */202iowrite32be(hash | TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl);203}204205void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)206{207iowrite32be(value, ®s->hashtable_ctrl);208}209210void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)211{212iowrite32be((uint32_t)pause_time, ®s->pause_quant);213}214215void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)216{217uint32_t tmp;218219tmp = ioread32be(®s->command_config);220if (en)221tmp |= CMD_CFG_PAUSE_IGNORE;222else223tmp &= ~CMD_CFG_PAUSE_IGNORE;224iowrite32be(tmp, ®s->command_config);225}226227void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)228{229uint32_t tmp;230231tmp = ioread32be(®s->command_config);232if (en)233tmp |= CMD_CFG_EN_TIMESTAMP;234else235tmp &= ~CMD_CFG_EN_TIMESTAMP;236iowrite32be(tmp, ®s->command_config);237}238239uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)240{241return ioread32be(®s->ievent) & ev_mask;242}243244void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)245{246iowrite32be(ev_mask, ®s->ievent);247}248249uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)250{251return ioread32be(®s->imask);252}253254void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)255{256uint32_t tmp0, tmp1;257258tmp0 = (uint32_t)(adr[0] |259adr[1] << 8 |260adr[2] << 16 |261adr[3] << 24);262tmp1 = (uint32_t)(adr[4] | adr[5] << 8);263iowrite32be(tmp0, ®s->mac_addr_2);264iowrite32be(tmp1, ®s->mac_addr_3);265}266267void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)268{269iowrite32be(0, ®s->mac_addr_2);270iowrite32be(0, ®s->mac_addr_3);271}272273uint32_t fman_tgec_get_revision(struct tgec_regs *regs)274{275return ioread32be(®s->tgec_id);276}277278void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)279{280iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask);281}282283void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)284{285iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask);286}287288uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)289{290return (uint16_t) ioread32be(®s->maxfrm);291}292293void fman_tgec_defconfig(struct tgec_cfg *cfg)294{295cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;296cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;297cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;298cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;299cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;300cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;301cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;302cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;303cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;304cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;305cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;306cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;307cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;308cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;309cfg->pause_quant = DEFAULT_PAUSE_QUANT;310#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004311cfg->skip_fman11_workaround = FALSE;312#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */313}314315int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,316uint32_t exception_mask)317{318uint32_t tmp;319320/* Config */321tmp = 0x40; /* CRC forward */322if (cfg->wan_mode_enable)323tmp |= CMD_CFG_WAN_MODE;324if (cfg->promiscuous_mode_enable)325tmp |= CMD_CFG_PROMIS_EN;326if (cfg->pause_forward_enable)327tmp |= CMD_CFG_PAUSE_FWD;328if (cfg->pause_ignore)329tmp |= CMD_CFG_PAUSE_IGNORE;330if (cfg->tx_addr_ins_enable)331tmp |= CMD_CFG_TX_ADDR_INS;332if (cfg->loopback_enable)333tmp |= CMD_CFG_LOOPBACK_EN;334if (cfg->cmd_frame_enable)335tmp |= CMD_CFG_CMD_FRM_EN;336if (cfg->rx_error_discard)337tmp |= CMD_CFG_RX_ER_DISC;338if (cfg->send_idle_enable)339tmp |= CMD_CFG_SEND_IDLE;340if (cfg->no_length_check_enable)341tmp |= CMD_CFG_NO_LEN_CHK;342if (cfg->time_stamp_enable)343tmp |= CMD_CFG_EN_TIMESTAMP;344iowrite32be(tmp, ®s->command_config);345346/* Max Frame Length */347iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm);348/* Pause Time */349iowrite32be(cfg->pause_quant, ®s->pause_quant);350351/* clear all pending events and set-up interrupts */352fman_tgec_ack_event(regs, 0xffffffff);353fman_tgec_enable_interrupt(regs, exception_mask);354355return 0;356}357358void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)359{360uint32_t tmp;361362/* restore the default tx ipg Length */363tmp = (ioread32be(®s->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;364365iowrite32be(tmp, ®s->tx_ipg_len);366}367368369