Path: blob/main/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.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_dtsec.h"343536void fman_dtsec_stop_rx(struct dtsec_regs *regs)37{38/* Assert the graceful stop bit */39iowrite32be(ioread32be(®s->rctrl) | RCTRL_GRS, ®s->rctrl);40}4142void fman_dtsec_stop_tx(struct dtsec_regs *regs)43{44/* Assert the graceful stop bit */45iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_GTS, ®s->tctrl);46}4748void fman_dtsec_start_tx(struct dtsec_regs *regs)49{50/* clear the graceful stop bit */51iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_GTS, ®s->tctrl);52}5354void fman_dtsec_start_rx(struct dtsec_regs *regs)55{56/* clear the graceful stop bit */57iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_GRS, ®s->rctrl);58}5960void fman_dtsec_defconfig(struct dtsec_cfg *cfg)61{62cfg->halfdup_on = DEFAULT_HALFDUP_ON;63cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;64cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;65cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;66cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;67cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;68cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;69cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;70cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;71cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;72cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;73cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;74cfg->tx_crc = DEFAULT_TX_CRC;75cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;76cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;77cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/78cfg->rx_prepend = DEFAULT_RX_PREPEND;79cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;80cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;81cfg->preamble_len = DEFAULT_PREAMBLE_LEN;82cfg->rx_preamble = DEFAULT_RX_PREAMBLE;83cfg->tx_preamble = DEFAULT_TX_PREAMBLE;84cfg->loopback = DEFAULT_LOOPBACK;85cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;86cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;87cfg->rx_flow = DEFAULT_RX_FLOW;88cfg->tx_flow = DEFAULT_TX_FLOW;89cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;90cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;91cfg->rx_promisc = DEFAULT_RX_PROMISC;92cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;93cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;94cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;95cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;96cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;97cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;98cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;99}100101int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,102enum enet_interface iface_mode,103enum enet_speed iface_speed,104uint8_t *macaddr,105uint8_t fm_rev_maj,106uint8_t fm_rev_min,107uint32_t exception_mask)108{109bool is_rgmii = FALSE;110bool is_sgmii = FALSE;111bool is_qsgmii = FALSE;112int i;113uint32_t tmp;114115UNUSED(fm_rev_maj);UNUSED(fm_rev_min);116117/* let's start with a soft reset */118iowrite32be(MACCFG1_SOFT_RESET, ®s->maccfg1);119iowrite32be(0, ®s->maccfg1);120121/*************dtsec_id2******************/122tmp = ioread32be(®s->tsec_id2);123124/* check RGMII support */125if (iface_mode == E_ENET_IF_RGMII ||126iface_mode == E_ENET_IF_RMII)127if (tmp & DTSEC_ID2_INT_REDUCED_OFF)128return -EINVAL;129130if (iface_mode == E_ENET_IF_SGMII ||131iface_mode == E_ENET_IF_MII)132if (tmp & DTSEC_ID2_INT_REDUCED_OFF)133return -EINVAL;134135/***************ECNTRL************************/136137is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);138is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);139is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);140141tmp = 0;142if (is_rgmii || iface_mode == E_ENET_IF_GMII)143tmp |= DTSEC_ECNTRL_GMIIM;144if (is_sgmii)145tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);146if (is_qsgmii)147tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |148DTSEC_ECNTRL_QSGMIIM);149if (is_rgmii)150tmp |= DTSEC_ECNTRL_RPM;151if (iface_speed == E_ENET_SPEED_100)152tmp |= DTSEC_ECNTRL_R100M;153154iowrite32be(tmp, ®s->ecntrl);155/***************ECNTRL************************/156157/***************TCTRL************************/158tmp = 0;159if (cfg->halfdup_on)160tmp |= DTSEC_TCTRL_THDF;161if (cfg->tx_time_stamp_en)162tmp |= DTSEC_TCTRL_TTSE;163164iowrite32be(tmp, ®s->tctrl);165166/***************TCTRL************************/167168/***************PTV************************/169tmp = 0;170171#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1172if ((fm_rev_maj == 1) && (fm_rev_min == 0))173cfg->tx_pause_time += 2;174#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */175176if (cfg->tx_pause_time)177tmp |= cfg->tx_pause_time;178if (cfg->tx_pause_time_extd)179tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;180iowrite32be(tmp, ®s->ptv);181182/***************RCTRL************************/183tmp = 0;184tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;185if (cfg->rx_ctrl_acc)186tmp |= RCTRL_CFA;187if (cfg->rx_group_hash_exd)188tmp |= RCTRL_GHTX;189if (cfg->rx_time_stamp_en)190tmp |= RCTRL_RTSE;191if (cfg->rx_drop_bcast)192tmp |= RCTRL_BC_REJ;193if (cfg->rx_short_frm)194tmp |= RCTRL_RSF;195if (cfg->rx_promisc)196tmp |= RCTRL_PROM;197198iowrite32be(tmp, ®s->rctrl);199/***************RCTRL************************/200201/*202* Assign a Phy Address to the TBI (TBIPA).203* Done also in cases where TBI is not selected to avoid conflict with204* the external PHY's Physical address205*/206iowrite32be(cfg->tbipa, ®s->tbipa);207208/***************TMR_CTL************************/209iowrite32be(0, ®s->tmr_ctrl);210211if (cfg->ptp_tsu_en) {212tmp = 0;213tmp |= TMR_PEVENT_TSRE;214iowrite32be(tmp, ®s->tmr_pevent);215216if (cfg->ptp_exception_en) {217tmp = 0;218tmp |= TMR_PEMASK_TSREEN;219iowrite32be(tmp, ®s->tmr_pemask);220}221}222223/***************MACCFG1***********************/224tmp = 0;225if (cfg->loopback)226tmp |= MACCFG1_LOOPBACK;227if (cfg->rx_flow)228tmp |= MACCFG1_RX_FLOW;229if (cfg->tx_flow)230tmp |= MACCFG1_TX_FLOW;231iowrite32be(tmp, ®s->maccfg1);232233/***************MACCFG1***********************/234235/***************MACCFG2***********************/236tmp = 0;237238if (iface_speed < E_ENET_SPEED_1000)239tmp |= MACCFG2_NIBBLE_MODE;240else if (iface_speed == E_ENET_SPEED_1000)241tmp |= MACCFG2_BYTE_MODE;242243tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)244<< PREAMBLE_LENGTH_SHIFT;245246if (cfg->rx_preamble)247tmp |= MACCFG2_PRE_AM_Rx_EN;248if (cfg->tx_preamble)249tmp |= MACCFG2_PRE_AM_Tx_EN;250if (cfg->rx_len_check)251tmp |= MACCFG2_LENGTH_CHECK;252if (cfg->tx_pad_crc)253tmp |= MACCFG2_PAD_CRC_EN;254if (cfg->tx_crc)255tmp |= MACCFG2_CRC_EN;256if (!cfg->halfdup_on)257tmp |= MACCFG2_FULL_DUPLEX;258iowrite32be(tmp, ®s->maccfg2);259260/***************MACCFG2***********************/261262/***************IPGIFG************************/263tmp = (((cfg->non_back_to_back_ipg1 <<264IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)265& IPGIFG_NON_BACK_TO_BACK_IPG_1)266| ((cfg->non_back_to_back_ipg2 <<267IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)268& IPGIFG_NON_BACK_TO_BACK_IPG_2)269| ((cfg->min_ifg_enforcement <<270IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)271& IPGIFG_MIN_IFG_ENFORCEMENT)272| (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));273iowrite32be(tmp, ®s->ipgifg);274275/***************IPGIFG************************/276277/***************HAFDUP************************/278tmp = 0;279280if (cfg->halfdup_alt_backoff_en)281tmp = (uint32_t)(HAFDUP_ALT_BEB |282((cfg->halfdup_alt_backoff_val & 0x0000000f)283<< HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));284if (cfg->halfdup_bp_no_backoff)285tmp |= HAFDUP_BP_NO_BACKOFF;286if (cfg->halfdup_no_backoff)287tmp |= HAFDUP_NO_BACKOFF;288if (cfg->halfdup_excess_defer)289tmp |= HAFDUP_EXCESS_DEFER;290tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)291& HAFDUP_RETRANSMISSION_MAX);292tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);293294iowrite32be(tmp, ®s->hafdup);295/***************HAFDUP************************/296297/***************MAXFRM************************/298/* Initialize MAXFRM */299iowrite32be(cfg->maximum_frame, ®s->maxfrm);300301/***************MAXFRM************************/302303/***************CAM1************************/304iowrite32be(0xffffffff, ®s->cam1);305iowrite32be(0xffffffff, ®s->cam2);306307/***************IMASK************************/308iowrite32be(exception_mask, ®s->imask);309/***************IMASK************************/310311/***************IEVENT************************/312iowrite32be(0xffffffff, ®s->ievent);313314/***************MACSTNADDR1/2*****************/315316tmp = (uint32_t)((macaddr[5] << 24) |317(macaddr[4] << 16) |318(macaddr[3] << 8) |319macaddr[2]);320iowrite32be(tmp, ®s->macstnaddr1);321322tmp = (uint32_t)((macaddr[1] << 24) |323(macaddr[0] << 16));324iowrite32be(tmp, ®s->macstnaddr2);325326/***************MACSTNADDR1/2*****************/327328/*****************HASH************************/329for (i = 0; i < NUM_OF_HASH_REGS ; i++) {330/* Initialize IADDRx */331iowrite32be(0, ®s->igaddr[i]);332/* Initialize GADDRx */333iowrite32be(0, ®s->gaddr[i]);334}335336fman_dtsec_reset_stat(regs);337338return 0;339}340341uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)342{343return (uint16_t)ioread32be(®s->maxfrm);344}345346void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)347{348iowrite32be(length, ®s->maxfrm);349}350351void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)352{353uint32_t tmp;354355tmp = (uint32_t)((adr[5] << 24) |356(adr[4] << 16) |357(adr[3] << 8) |358adr[2]);359iowrite32be(tmp, ®s->macstnaddr1);360361tmp = (uint32_t)((adr[1] << 24) |362(adr[0] << 16));363iowrite32be(tmp, ®s->macstnaddr2);364}365366void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)367{368uint32_t tmp1, tmp2;369370tmp1 = ioread32be(®s->macstnaddr1);371tmp2 = ioread32be(®s->macstnaddr2);372373macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);374macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);375macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);376macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);377macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);378macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);379}380381void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)382{383int32_t bucket;384if (ghtx)385bucket = (int32_t)((crc >> 23) & 0x1ff);386else {387bucket = (int32_t)((crc >> 24) & 0xff);388/* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */389if (mcast)390bucket += 0x100;391}392fman_dtsec_set_bucket(regs, bucket, TRUE);393}394395void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)396{397int reg_idx = (bucket >> 5) & 0xf;398int bit_idx = bucket & 0x1f;399uint32_t bit_mask = 0x80000000 >> bit_idx;400uint32_t *reg;401402if (reg_idx > 7)403reg = ®s->gaddr[reg_idx-8];404else405reg = ®s->igaddr[reg_idx];406407if (enable)408iowrite32be(ioread32be(reg) | bit_mask, reg);409else410iowrite32be(ioread32be(reg) & (~bit_mask), reg);411}412413void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)414{415int i;416bool ghtx;417418ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);419420if (ucast || (ghtx && mcast)) {421for (i = 0; i < NUM_OF_HASH_REGS; i++)422iowrite32be(0, ®s->igaddr[i]);423}424if (mcast) {425for (i = 0; i < NUM_OF_HASH_REGS; i++)426iowrite32be(0, ®s->gaddr[i]);427}428}429430int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,431uint8_t addr)432{433if (addr > 0 && addr < 32)434iowrite32be(addr, ®s->tbipa);435else436return -EINVAL;437438return 0;439}440441void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)442{443uint32_t tmp;444445tmp = ioread32be(®s->maccfg2);446if (en)447tmp |= MACCFG2_MAGIC_PACKET_EN;448else449tmp &= ~MACCFG2_MAGIC_PACKET_EN;450iowrite32be(tmp, ®s->maccfg2);451}452453int fman_dtsec_adjust_link(struct dtsec_regs *regs,454enum enet_interface iface_mode,455enum enet_speed speed, bool full_dx)456{457uint32_t tmp;458459UNUSED(iface_mode);460461if ((speed == E_ENET_SPEED_1000) && !full_dx)462return -EINVAL;463464tmp = ioread32be(®s->maccfg2);465if (!full_dx)466tmp &= ~MACCFG2_FULL_DUPLEX;467else468tmp |= MACCFG2_FULL_DUPLEX;469470tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);471if (speed < E_ENET_SPEED_1000)472tmp |= MACCFG2_NIBBLE_MODE;473else if (speed == E_ENET_SPEED_1000)474tmp |= MACCFG2_BYTE_MODE;475iowrite32be(tmp, ®s->maccfg2);476477tmp = ioread32be(®s->ecntrl);478if (speed == E_ENET_SPEED_100)479tmp |= DTSEC_ECNTRL_R100M;480else481tmp &= ~DTSEC_ECNTRL_R100M;482iowrite32be(tmp, ®s->ecntrl);483484return 0;485}486487void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)488{489uint32_t tmp;490491tmp = ioread32be(®s->rctrl);492493if (enable)494tmp |= RCTRL_UPROM;495else496tmp &= ~RCTRL_UPROM;497498iowrite32be(tmp, ®s->rctrl);499}500501void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)502{503uint32_t tmp;504505tmp = ioread32be(®s->rctrl);506507if (enable)508tmp |= RCTRL_MPROM;509else510tmp &= ~RCTRL_MPROM;511512iowrite32be(tmp, ®s->rctrl);513}514515bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,516uint32_t *car1, uint32_t *car2)517{518/* read carry registers */519*car1 = ioread32be(®s->car1);520*car2 = ioread32be(®s->car2);521/* clear carry registers */522if (*car1)523iowrite32be(*car1, ®s->car1);524if (*car2)525iowrite32be(*car2, ®s->car2);526527return (bool)((*car1 | *car2) ? TRUE : FALSE);528}529530void fman_dtsec_reset_stat(struct dtsec_regs *regs)531{532/* clear HW counters */533iowrite32be(ioread32be(®s->ecntrl) |534DTSEC_ECNTRL_CLRCNT, ®s->ecntrl);535}536537int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)538{539switch (level) {540case E_MAC_STAT_NONE:541iowrite32be(0xffffffff, ®s->cam1);542iowrite32be(0xffffffff, ®s->cam2);543iowrite32be(ioread32be(®s->ecntrl) & ~DTSEC_ECNTRL_STEN,544®s->ecntrl);545iowrite32be(ioread32be(®s->imask) & ~DTSEC_IMASK_MSROEN,546®s->imask);547break;548case E_MAC_STAT_PARTIAL:549iowrite32be(CAM1_ERRORS_ONLY, ®s->cam1);550iowrite32be(CAM2_ERRORS_ONLY, ®s->cam2);551iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN,552®s->ecntrl);553iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN,554®s->imask);555break;556case E_MAC_STAT_MIB_GRP1:557iowrite32be((uint32_t)~CAM1_MIB_GRP_1, ®s->cam1);558iowrite32be((uint32_t)~CAM2_MIB_GRP_1, ®s->cam2);559iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN,560®s->ecntrl);561iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN,562®s->imask);563break;564case E_MAC_STAT_FULL:565iowrite32be(0, ®s->cam1);566iowrite32be(0, ®s->cam2);567iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN,568®s->ecntrl);569iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN,570®s->imask);571break;572default:573return -EINVAL;574}575576return 0;577}578579void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)580{581if (en) {582iowrite32be(ioread32be(®s->rctrl) | RCTRL_RTSE,583®s->rctrl);584iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_TTSE,585®s->tctrl);586} else {587iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_RTSE,588®s->rctrl);589iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_TTSE,590®s->tctrl);591}592}593594void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)595{596uint32_t tmp;597598tmp = ioread32be(®s->maccfg1);599600if (apply_rx)601tmp |= MACCFG1_RX_EN ;602603if (apply_tx)604tmp |= MACCFG1_TX_EN ;605606iowrite32be(tmp, ®s->maccfg1);607}608609void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)610{611iowrite32be(0, ®s->macaddr[paddr_num].exact_match1);612iowrite32be(0, ®s->macaddr[paddr_num].exact_match2);613}614615void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,616uint64_t addr,617uint8_t paddr_num)618{619uint32_t tmp;620621tmp = (uint32_t)(addr);622/* swap */623tmp = (((tmp & 0x000000FF) << 24) |624((tmp & 0x0000FF00) << 8) |625((tmp & 0x00FF0000) >> 8) |626((tmp & 0xFF000000) >> 24));627iowrite32be(tmp, ®s->macaddr[paddr_num].exact_match1);628629tmp = (uint32_t)(addr>>32);630/* swap */631tmp = (((tmp & 0x000000FF) << 24) |632((tmp & 0x0000FF00) << 8) |633((tmp & 0x00FF0000) >> 8) |634((tmp & 0xFF000000) >> 24));635iowrite32be(tmp, ®s->macaddr[paddr_num].exact_match2);636}637638void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)639{640uint32_t tmp;641642tmp = ioread32be(®s->maccfg1);643644if (apply_rx)645tmp &= ~MACCFG1_RX_EN;646647if (apply_tx)648tmp &= ~MACCFG1_TX_EN;649650iowrite32be(tmp, ®s->maccfg1);651}652653void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)654{655uint32_t ptv = 0;656657/* fixme: don't enable tx pause for half-duplex */658659if (time) {660ptv = ioread32be(®s->ptv);661ptv &= 0xffff0000;662ptv |= time & 0x0000ffff;663iowrite32be(ptv, ®s->ptv);664665/* trigger the transmission of a flow-control pause frame */666iowrite32be(ioread32be(®s->maccfg1) | MACCFG1_TX_FLOW,667®s->maccfg1);668} else669iowrite32be(ioread32be(®s->maccfg1) & ~MACCFG1_TX_FLOW,670®s->maccfg1);671}672673void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)674{675uint32_t tmp;676677/* todo: check if mac is set to full-duplex */678679tmp = ioread32be(®s->maccfg1);680if (en)681tmp |= MACCFG1_RX_FLOW;682else683tmp &= ~MACCFG1_RX_FLOW;684iowrite32be(tmp, ®s->maccfg1);685}686687uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)688{689return ioread32be(®s->rctrl);690}691692uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)693{694return ioread32be(®s->tsec_id);695}696697uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)698{699return ioread32be(®s->ievent) & ev_mask;700}701702void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)703{704iowrite32be(ev_mask, ®s->ievent);705}706707uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)708{709return ioread32be(®s->imask);710}711712uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)713{714uint32_t event;715716event = ioread32be(®s->tmr_pevent);717event &= ioread32be(®s->tmr_pemask);718719if (event)720iowrite32be(event, ®s->tmr_pevent);721return event;722}723724void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)725{726iowrite32be(ioread32be(®s->tmr_pemask) | TMR_PEMASK_TSREEN,727®s->tmr_pemask);728}729730void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)731{732iowrite32be(ioread32be(®s->tmr_pemask) & ~TMR_PEMASK_TSREEN,733®s->tmr_pemask);734}735736void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)737{738iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask);739}740741void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)742{743iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask);744}745746uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,747enum dtsec_stat_counters reg_name)748{749uint32_t ret_val;750751switch (reg_name) {752case E_DTSEC_STAT_TR64:753ret_val = ioread32be(®s->tr64);754break;755case E_DTSEC_STAT_TR127:756ret_val = ioread32be(®s->tr127);757break;758case E_DTSEC_STAT_TR255:759ret_val = ioread32be(®s->tr255);760break;761case E_DTSEC_STAT_TR511:762ret_val = ioread32be(®s->tr511);763break;764case E_DTSEC_STAT_TR1K:765ret_val = ioread32be(®s->tr1k);766break;767case E_DTSEC_STAT_TRMAX:768ret_val = ioread32be(®s->trmax);769break;770case E_DTSEC_STAT_TRMGV:771ret_val = ioread32be(®s->trmgv);772break;773case E_DTSEC_STAT_RBYT:774ret_val = ioread32be(®s->rbyt);775break;776case E_DTSEC_STAT_RPKT:777ret_val = ioread32be(®s->rpkt);778break;779case E_DTSEC_STAT_RMCA:780ret_val = ioread32be(®s->rmca);781break;782case E_DTSEC_STAT_RBCA:783ret_val = ioread32be(®s->rbca);784break;785case E_DTSEC_STAT_RXPF:786ret_val = ioread32be(®s->rxpf);787break;788case E_DTSEC_STAT_RALN:789ret_val = ioread32be(®s->raln);790break;791case E_DTSEC_STAT_RFLR:792ret_val = ioread32be(®s->rflr);793break;794case E_DTSEC_STAT_RCDE:795ret_val = ioread32be(®s->rcde);796break;797case E_DTSEC_STAT_RCSE:798ret_val = ioread32be(®s->rcse);799break;800case E_DTSEC_STAT_RUND:801ret_val = ioread32be(®s->rund);802break;803case E_DTSEC_STAT_ROVR:804ret_val = ioread32be(®s->rovr);805break;806case E_DTSEC_STAT_RFRG:807ret_val = ioread32be(®s->rfrg);808break;809case E_DTSEC_STAT_RJBR:810ret_val = ioread32be(®s->rjbr);811break;812case E_DTSEC_STAT_RDRP:813ret_val = ioread32be(®s->rdrp);814break;815case E_DTSEC_STAT_TFCS:816ret_val = ioread32be(®s->tfcs);817break;818case E_DTSEC_STAT_TBYT:819ret_val = ioread32be(®s->tbyt);820break;821case E_DTSEC_STAT_TPKT:822ret_val = ioread32be(®s->tpkt);823break;824case E_DTSEC_STAT_TMCA:825ret_val = ioread32be(®s->tmca);826break;827case E_DTSEC_STAT_TBCA:828ret_val = ioread32be(®s->tbca);829break;830case E_DTSEC_STAT_TXPF:831ret_val = ioread32be(®s->txpf);832break;833case E_DTSEC_STAT_TNCL:834ret_val = ioread32be(®s->tncl);835break;836case E_DTSEC_STAT_TDRP:837ret_val = ioread32be(®s->tdrp);838break;839default:840ret_val = 0;841}842843return ret_val;844}845846847