| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874 |
- /*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: fxmac.c
- * Date: 2022-04-06 14:46:52
- * LastEditTime: 2022-04-06 14:46:58
- * Description: This file is for
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- */
- #include "fxmac.h"
- #include "ftypes.h"
- #include "fxmac_hw.h"
- #include "stdio.h"
- #include "fdebug.h"
- #define FXMAC_DEBUG_TAG "FXMAC"
- #define FXMAC_PRINT_E(format, ...) FT_DEBUG_PRINT_E(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FXMAC_PRINT_I(format, ...) FT_DEBUG_PRINT_I(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FXMAC_PRINT_D(format, ...) FT_DEBUG_PRINT_D(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FXMAC_PRINT_W(format, ...) FT_DEBUG_PRINT_W(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__)
- static void FXmacReset(FXmac *instance_p);
- extern FError FXmacSetTypeIdCheck(FXmac *instance_p, u32 id_check, u8 index);
- /**
- * @name: FXmacSelectClk
- * @msg: Determine the driver clock configuration based on the media independent interface
- * @param {FXmac} *instance_p is a pointer to the instance to be worked on.
- * @param {u32} speed interface speed
- * @return {*}
- */
- void FXmacSelectClk(FXmac *instance_p)
- {
- u32 reg_value;
- s32 set_speed = 0;
- u32 speed = instance_p->config.speed;
- FASSERT(instance_p != NULL);
- FASSERT((speed == FXMAC_SPEED_10) || (speed == FXMAC_SPEED_100) || (speed == FXMAC_SPEED_1000) || (speed == FXMAC_SPEED_2500) || (speed == FXMAC_SPEED_10000));
- if ((instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_USXGMII) || (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_XGMII))
- {
- if (speed == FXMAC_SPEED_10000)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x4);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x1);
- }
- }
- else if (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII)
- {
- FXMAC_PRINT_I("FXMAC_PHY_INTERFACE_MODE_SGMII init");
- if (speed == FXMAC_SPEED_2500)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SRC_SEL_LN, 0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x0); /*0x1c70*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x0); /*0x1c7c*/
- }
- else if (speed == FXMAC_SPEED_1000)
- {
- FXMAC_PRINT_I("sgmii FXMAC_SPEED_1000 \r\n ");
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SRC_SEL_LN, 1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x4);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x8);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x0); /*0x1c70*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x0); /*0x1c7c*/
- }
- else if ((speed == FXMAC_SPEED_100) || (speed == FXMAC_SPEED_10))
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x4);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x8);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x1); /*0x1c70*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x1); /*0x1c7c*/
- }
- }
- else if (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RGMII)
- {
- FXMAC_PRINT_I("FXMAC_PHY_INTERFACE_MODE_RGMII init");
- if (speed == FXMAC_SPEED_1000)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_MII_SELECT, 0x1); /*0x1c18*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SEL_MII_ON_RGMII, 0x0); /*0x1c1c*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x0); /*0x1c2c*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x0); /*0x1c30*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x1); /*0x1c34*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_CLK_250M_DIV10_DIV100_SEL,
- 0x0); /*0x1c38*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RGMII_TX_CLK_SEL0, 0x1); /*0x1c80*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RGMII_TX_CLK_SEL1, 0x0); /*0x1c84*/
- }
- else if (speed == FXMAC_SPEED_100)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SEL_MII_ON_RGMII, 0x0); /*0x1c1c*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x0); /*0x1c2c*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x0); /*0x1c30*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x1); /*0x1c34*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_CLK_250M_DIV10_DIV100_SEL,
- 0x0); /*0x1c38*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RGMII_TX_CLK_SEL0, 0x0); /*0x1c80*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RGMII_TX_CLK_SEL1, 0x0); /*0x1c84*/
- }
- else
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SEL_MII_ON_RGMII, 0x0); /*0x1c1c*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x0); /*0x1c2c*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x0); /*0x1c30*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x1); /*0x1c34*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_CLK_250M_DIV10_DIV100_SEL,
- 0x1); /*0x1c38*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RGMII_TX_CLK_SEL0, 0x0); /*0x1c80*/
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RGMII_TX_CLK_SEL1, 0x0); /*0x1c84*/
- }
- }
- else if (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RMII)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
- }
- switch (speed)
- {
- case FXMAC_SPEED_25000:
- set_speed = 2;
- break;
- case FXMAC_SPEED_10000:
- set_speed = 4;
- break;
- case FXMAC_SPEED_5000:
- set_speed = 3;
- break;
- case FXMAC_SPEED_2500:
- set_speed = 2;
- break;
- case FXMAC_SPEED_1000:
- set_speed = 1;
- break;
- default:
- set_speed = 0;
- break;
- }
- /*GEM_HSMAC(0x0050) provide rate to the external*/
- reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC);
- reg_value &= ~FXMAC_GEM_HSMACSPEED_MASK;
- reg_value |= (set_speed) &FXMAC_GEM_HSMACSPEED_MASK;
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC, reg_value);
- reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC);
- FXMAC_PRINT_I("FXMAC_GEM_HSMAC is %x \r\n ", reg_value);
- }
- /**
- * Start the Ethernet controller as follows:
- * - Enable transmitter if FXMAC_TRANSMIT_ENABLE_OPTION is set
- * - Enable receiver if FXMAC_RECEIVER_ENABLE_OPTION is set
- * - Start the SG DMA send and receive channels and enable the device
- * interrupt
- *
- * @param instance_p is a pointer to the instance to be worked on.
- *
- * @return N/A
- *
- * @note
- * Hardware is configured with scatter-gather DMA, the driver expects to start
- * the scatter-gather channels and expects that the user has previously set up
- * the buffer descriptor lists.
- *
- * This function makes use of internal resources that are shared between the
- * Start, Stop, and Set/ClearOptions functions. So if one task might be setting
- * device options while another is trying to start the device, the user is
- * required to provide protection of this shared data (typically using a
- * semaphore).
- *
- * This function must not be preempted by an interrupt that may service the
- * device.
- *
- */
- void FXmacStart(FXmac *instance_p)
- {
- u32 reg_val;
- u32 reg = 0;
- /* Assert bad arguments and conditions */
- FASSERT(instance_p != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- /* Start DMA */
- /* When starting the DMA channels, both transmit and receive sides
- * need an initialized BD list.
- */
- FASSERT(instance_p->rx_bd_queue.bdring.base_bd_addr != 0);
- reg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_RXQBASE_OFFSET);
- reg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_TXQBASE_OFFSET);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_RXQBASE_OFFSET,
- instance_p->rx_bd_queue.bdring.base_bd_addr);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_TXQBASE_OFFSET,
- instance_p->tx_bd_queue.bdring.base_bd_addr);
- reg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_RXQBASE_OFFSET);
- reg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_TXQBASE_OFFSET);
- /* clear any existed int status */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET,
- FXMAC_IXR_ALL_MASK);
- /* Enable transmitter if not already enabled */
- if ((instance_p->config.network_default_config & (u32)FXMAC_TRANSMITTER_ENABLE_OPTION) != 0x00000000U)
- {
- reg_val = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET);
- if ((!(reg_val & FXMAC_NWCTRL_TXEN_MASK)) == TRUE)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET,
- reg_val | (u32)FXMAC_NWCTRL_TXEN_MASK);
- }
- }
- /* Enable receiver if not already enabled */
- if ((instance_p->config.network_default_config & FXMAC_RECEIVER_ENABLE_OPTION) != 0x00000000U)
- {
- reg_val = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET);
- FXMAC_PRINT_I("endable receiver 0x%x \r\n ", reg_val);
- if ((!(reg_val & FXMAC_NWCTRL_RXEN_MASK)) == TRUE)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET,
- reg_val | (u32)FXMAC_NWCTRL_RXEN_MASK);
- }
- }
- FXMAC_PRINT_I("FXMAC_NWCTRL_OFFSET is 0x%x \r\n", FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET));
- /* Enable TX and RX interrupt */
- FXMAC_INT_ENABLE(instance_p, FXMAC_IXR_LINKCHANGE_MASK | FXMAC_IXR_TX_ERR_MASK | FXMAC_IXR_RX_ERR_MASK | FXMAC_IXR_RXCOMPL_MASK | FXMAC_IXR_TXCOMPL_MASK);
- /* Mark as started */
- instance_p->is_started = FT_COMPONENT_IS_STARTED;
- return;
- }
- /**
- * Gracefully stop the Ethernet MAC as follows:
- * - Disable all interrupts from this device
- * - Stop DMA channels
- * - Disable the tansmitter and receiver
- *
- * Device options currently in effect are not changed.
- *
- * This function will disable all interrupts. Default interrupts settings that
- * had been enabled will be restored when FXmacStart() is called.
- *
- * @param instance_p is a pointer to the instance to be worked on.
- *
- * @note
- * This function makes use of internal resources that are shared between the
- * Start, Stop, Setoptions, and Clearoptions functions. So if one task might be
- * setting device options while another is trying to start the device, the user
- * is required to provide protection of this shared data (typically using a
- * semaphore).
- *
- * Stopping the DMA channels causes this function to block until the DMA
- * operation is complete.
- *
- */
- void FXmacStop(FXmac *instance_p)
- {
- u32 reg_val;
- FASSERT(instance_p != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- /* Disable all interrupts */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_IDR_OFFSET,
- FXMAC_IXR_ALL_MASK);
- /* Disable the receiver & transmitter */
- reg_val = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET);
- reg_val &= (u32)(~FXMAC_NWCTRL_RXEN_MASK);
- reg_val &= (u32)(~FXMAC_NWCTRL_TXEN_MASK);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET, reg_val);
- /* Mark as stopped */
- instance_p->is_started = 0U;
- }
- static u32 FXmacClkDivGet(FXmac *instance_p)
- {
- FXmacConfig *config_p;
- config_p = &instance_p->config;
- if (config_p->pclk_hz <= 20000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV8_MASK;
- }
- else if (config_p->pclk_hz <= 40000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV16_MASK;
- }
- else if (config_p->pclk_hz <= 80000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV32_MASK;
- }
- else if (instance_p->moudle_id >= 2)
- {
- if (config_p->pclk_hz <= 120000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV48_MASK;
- }
- else if (config_p->pclk_hz <= 160000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV64_MASK;
- }
- else if (config_p->pclk_hz <= 240000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV96_MASK;
- }
- else if (config_p->pclk_hz <= 320000000)
- {
- return FXMAC_NWCFG_CLOCK_DIV128_MASK;
- }
- else
- {
- return FXMAC_NWCFG_CLOCK_DIV224_MASK;
- }
- }
- else
- {
- return FXMAC_NWCFG_CLOCK_DIV64_MASK;
- }
- }
- static u32 FXmacDmaWidth(FXmac *instance_p)
- {
- u32 read_regs = 0;
- FXmacConfig *config_p;
- config_p = &instance_p->config;
- if (instance_p->moudle_id < 2)
- {
- return FXMAC_NWCFG_BUS_WIDTH_32_MASK;
- }
- read_regs = FXMAC_READREG32(config_p->base_address, FXMAC_DESIGNCFG_DEBUG1_OFFSET);
- switch ((read_regs & FXMAC_DESIGNCFG_DEBUG1_BUS_WIDTH_MASK) >> 25)
- {
- case 4:
- FXMAC_PRINT_I("bus width is 128");
- return FXMAC_NWCFG_BUS_WIDTH_128_MASK;
- case 2:
- FXMAC_PRINT_I("bus width is 64");
- return FXMAC_NWCFG_BUS_WIDTH_64_MASK;
- default:
- FXMAC_PRINT_I("bus width is 32");
- return FXMAC_NWCFG_BUS_WIDTH_32_MASK;
- }
- }
- static void FXmacDmaReset(FXmac *instance_p)
- {
- u32 queue = 0;
- FXmacConfig *config_p;
- config_p = &instance_p->config;
- u32 dmacfg = 0;
- u32 rx_buf_size = 0;
- rx_buf_size = instance_p->max_frame_size / FXMAC_RX_BUF_UNIT;
- rx_buf_size += ((instance_p->max_frame_size % FXMAC_RX_BUF_UNIT) != 0) ? 1 : 0; /* roundup */
- if (instance_p->moudle_id >= 2)
- {
- for (queue = 0; queue < config_p->max_queue_num; queue++)
- {
- dmacfg = 0;
- FXmacSetQueuePtr(instance_p, (uintptr)NULL, queue, (u16)FXMAC_SEND);
- FXmacSetQueuePtr(instance_p, (uintptr)NULL, queue, (u16)FXMAC_RECV);
- if (queue)
- {
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_RXBUFQX_SIZE_OFFSET(queue), rx_buf_size);
- }
- else /* queue is 0 */
- {
- dmacfg |= ((u32)FXMAC_DMACR_RXBUF_MASK & (rx_buf_size << FXMAC_DMACR_RXBUF_SHIFT));
- }
- }
- dmacfg |= (config_p->dma_brust_length & FXMAC_DMACR_BLENGTH_MASK);
- dmacfg &= ~FXMAC_DMACR_ENDIAN_MASK;
- dmacfg &= ~FXMAC_DMACR_SWAP_MANAGEMENT_MASK; /* 选择小端 */
- dmacfg &= ~FXMAC_DMACR_TCPCKSUM_MASK; /* close transmitter checksum generation engine */
- dmacfg &= ~FXMAC_DMACR_ADDR_WIDTH_64;
- dmacfg |= FXMAC_DMACR_RXSIZE_MASK | FXMAC_DMACR_TXSIZE_MASK;
- #if defined(__aarch64__) || defined(__arch64__)
- dmacfg |= FXMAC_DMACR_ADDR_WIDTH_64;
- #endif
- }
- else
- {
- FXmacSetQueuePtr(instance_p, (uintptr)NULL, 0, (u16)FXMAC_SEND);
- FXmacSetQueuePtr(instance_p, (uintptr)NULL, 0, (u16)FXMAC_RECV);
- dmacfg |= ((u32)FXMAC_DMACR_RXBUF_MASK & (rx_buf_size << FXMAC_DMACR_RXBUF_SHIFT));
- dmacfg |= (config_p->dma_brust_length & FXMAC_DMACR_BLENGTH_MASK);
- dmacfg &= ~FXMAC_DMACR_ENDIAN_MASK;
- dmacfg &= ~FXMAC_DMACR_SWAP_MANAGEMENT_MASK; /* 选择小端 */
- dmacfg &= ~FXMAC_DMACR_TCPCKSUM_MASK; /* close transmitter checksum generation engine */
- dmacfg &= ~FXMAC_DMACR_ADDR_WIDTH_64;
- dmacfg |= FXMAC_DMACR_RXSIZE_MASK | FXMAC_DMACR_TXSIZE_MASK;
- #if defined(__aarch64__) || defined(__arch64__)
- dmacfg |= FXMAC_DMACR_ADDR_WIDTH_64;
- #endif
- }
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_DMACR_OFFSET, dmacfg);
- }
- /**
- * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
- * transmitter, and the receiver.
- *
- * Steps to reset
- * - Stops transmit and receive channels
- * - Stops DMA
- * - Configure transmit and receive buffer size to default
- * - Clear transmit and receive status register and counters
- * - Clear all interrupt sources
- * - Clear phy (if there is any previously detected) address
- * - Clear MAC addresses (1-4) as well as Type IDs and hash value
- *
- * All options are placed in their default state. Any frames in the
- * descriptor lists will remain in the lists. The side effect of doing
- * this is that after a reset and following a restart of the device, frames
- * were in the list before the reset may be transmitted or received.
- *
- * The upper layer software is responsible for re-configuring (if necessary)
- * and restarting the MAC after the reset. Note also that driver statistics
- * are not cleared on reset. It is up to the upper layer software to clear the
- * statistics if needed.
- *
- * When a reset is required, the driver notifies the upper layer software of
- * this need through the ErrorHandler callback and specific status codes.
- * The upper layer software is responsible for calling this Reset function
- * and then re-configuring the device.
- *
- * @param instance_p is a pointer to the instance to be worked on.
- *
- */
- static void FXmacReset(FXmac *instance_p)
- {
- u32 reg_val, write_reg = 0;
- u8 i;
- s8 mac_addr[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
- u32 rx_buf_num;
- FASSERT(instance_p != NULL);
- /* Stop the device and reset hardware */
- FXmacStop(instance_p);
- instance_p->moudle_id = (FXMAC_READREG32(instance_p->config.base_address, FXMAC_REVISION_REG_OFFSET) & FXMAC_IDENTIFICATION_MASK) >> 16;
- FXMAC_PRINT_I("instance_p->moudle_id is %d \r\n", instance_p->moudle_id);
- instance_p->max_mtu_size = FXMAC_MTU;
- instance_p->max_frame_size = FXMAC_MTU + FXMAC_HDR_SIZE + FXMAC_TRL_SIZE;
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET,
- ((FXMAC_NWCTRL_STATCLR_MASK) & (u32)(~FXMAC_NWCTRL_LOOPEN_MASK)) | FXMAC_NWCTRL_MDEN_MASK);
- write_reg = FXmacClkDivGet(instance_p); /* mdio clock division */
- write_reg |= FXmacDmaWidth(instance_p); /* 位宽 */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_NWCFG_OFFSET, write_reg);
- FXmacDmaReset(instance_p);
- /* This register, when read provides details of the status of the receive path. */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_RXSR_OFFSET, FXMAC_SR_ALL_MASK);
- /* write 1 ro the relavant bit location disable that particular interrupt */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_IDR_OFFSET, FXMAC_IXR_ALL_MASK);
- reg_val = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_ISR_OFFSET);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET,
- reg_val);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_TXSR_OFFSET, FXMAC_SR_ALL_MASK);
- FXmacClearHash(instance_p);
- /* set default mac address */
- for (i = 0U; i < 4U; i++)
- {
- (void)FXmacSetMacAddress(instance_p, mac_addr, i);
- (void)FXmacGetMacAddress(instance_p, mac_addr, i);
- (void)FXmacSetTypeIdCheck(instance_p, 0x00000000U, i);
- }
- /* clear all counters */
- for (i = 0U; i < (u8)((FXMAC_LAST_OFFSET - FXMAC_OCTTXL_OFFSET) / 4U);
- i++)
- {
- (void)FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_OCTTXL_OFFSET + (u32)(((u32)i) * ((u32)4)));
- }
- /* Sync default options with hardware but leave receiver and
- * transmitter disabled. They get enabled with FXmacStart() if
- * FXMAC_TRANSMITTER_ENABLE_OPTION and
- * FXMAC_RECEIVER_ENABLE_OPTION are set.
- */
- FXmacSetOptions(instance_p, instance_p->config.network_default_config & ~((u32)FXMAC_TRANSMITTER_ENABLE_OPTION | (u32)FXMAC_RECEIVER_ENABLE_OPTION), 0);
- FXmacClearOptions(instance_p, ~instance_p->config.network_default_config, 0);
- }
- /**
- * @name: FXmacInitInterface
- * @msg: Initialize the MAC controller configuration based on the PHY interface type
- * @note:
- * @param {FXmac} *instance_p is a pointer to the instance to be worked on.
- */
- void FXmacInitInterface(FXmac *instance_p)
- {
- u32 config, control;
- FXmacConfig *config_p;
- config_p = &instance_p->config;
- if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_XGMII)
- {
- config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET);
- config &= ~FXMAC_NWCFG_PCSSEL_MASK;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config);
- control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
- control |= FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control);
- config_p->duplex = 1;
- }
- else if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_USXGMII)
- {
- config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET);
- config |= FXMAC_NWCFG_PCSSEL_MASK;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config);
- control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
- control |= FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control);
- control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET);
- control &= ~(FXMAC_GEM_USX_TX_SCR_BYPASS | FXMAC_GEM_USX_RX_SCR_BYPASS);
- control |= FXMAC_GEM_USX_RX_SYNC_RESET;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control);
- control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET);
- control &= ~FXMAC_GEM_USX_RX_SYNC_RESET;
- control |= FXMAC_GEM_USX_TX_DATAPATH_EN;
- control |= FXMAC_GEM_USX_SIGNAL_OK;
- if (config_p->speed == FXMAC_SPEED_10000)
- {
- control |= FXMAC_GEM_USX_HS_MAC_SPEED_10G;
- }
- else if (config_p->speed == FXMAC_SPEED_25000)
- {
- control |= FXMAC_GEM_USX_HS_MAC_SPEED_2_5G;
- }
- else if (config_p->speed == FXMAC_SPEED_1000)
- {
- control |= FXMAC_GEM_USX_HS_MAC_SPEED_1G;
- }
- else if (config_p->speed == FXMAC_SPEED_100)
- {
- control |= FXMAC_GEM_USX_HS_MAC_SPEED_100M;
- }
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control);
- config_p->duplex = 1;
- }
- else if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_SGMII)
- {
- config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET);
- config |= FXMAC_NWCFG_PCSSEL_MASK | FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK;
- config &= ~(FXMAC_NWCFG_100_MASK | FXMAC_NWCFG_FDEN_MASK);
- if (instance_p->moudle_id >= 2)
- {
- config &= ~FXMAC_NWCFG_1000_MASK;
- }
- if (config_p->duplex)
- {
- config |= FXMAC_NWCFG_FDEN_MASK;
- }
- if (config_p->speed == FXMAC_SPEED_100)
- {
- config |= FXMAC_NWCFG_100_MASK;
- }
- else if (config_p->speed == FXMAC_SPEED_1000)
- {
- config |= FXMAC_NWCFG_1000_MASK;
- }
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config);
- if (config_p->speed == FXMAC_SPEED_2500)
- {
- control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
- control |= FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control);
- }
- else
- {
- control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
- control &= ~FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control);
- }
- control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
- control &= ~FXMAC_NWCTRL_ENABLE_HS_MAC_MASK;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control);
- control = FXMAC_READREG32(config_p->base_address, FXMAC_PCS_CONTROL_OFFSET);
- control |= FXMAC_PCS_CONTROL_ENABLE_AUTO_NEG;
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_PCS_CONTROL_OFFSET, control);
- }
- else
- {
- config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET);
- FXMAC_PRINT_I("select rgmii \r\n");
- config &= ~FXMAC_NWCFG_PCSSEL_MASK;
- config &= ~(FXMAC_NWCFG_100_MASK | FXMAC_NWCFG_FDEN_MASK);
- if (instance_p->moudle_id >= 2)
- {
- config &= ~FXMAC_NWCFG_1000_MASK;
- }
- if (config_p->duplex)
- {
- config |= FXMAC_NWCFG_FDEN_MASK;
- }
- if (config_p->speed == FXMAC_SPEED_100)
- {
- config |= FXMAC_NWCFG_100_MASK;
- }
- else if (config_p->speed == FXMAC_SPEED_1000)
- {
- config |= FXMAC_NWCFG_1000_MASK;
- }
- if (config_p->duplex)
- {
- config |= FXMAC_NWCFG_FDEN_MASK;
- }
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config);
- control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
- control &= ~FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control);
- }
- }
- static void FXmacIrqStubHandler(void)
- {
- FASSERT_MSG(0, "Please register the interrupt callback function");
- }
- /**
- * @name: FXmacCfgInitialize
- * @msg: Initialize a specific fxmac instance/driver.
- * @note:
- * @param {FXmac} *instance_p is a pointer to the instance to be worked on.
- * @param {FXmacConfig} *config_p is the device configuration structure containing required
- * hardware build data.
- * @return {FT_SUCCESS} if initialization was successful
- */
- FError FXmacCfgInitialize(FXmac *instance_p, const FXmacConfig *config_p)
- {
- /* Verify arguments */
- FASSERT(instance_p != NULL);
- FASSERT(config_p != NULL);
- instance_p->config = *config_p;
- instance_p->link_status = FXMAC_LINKDOWN;
- /* Reset the hardware and set default options */
- instance_p->is_ready = FT_COMPONENT_IS_READY;
- FXmacReset(instance_p);
- instance_p->send_irq_handler = (FXmacIrqHandler)FXmacIrqStubHandler;
- instance_p->send_args = NULL;
- instance_p->recv_irq_handler = (FXmacIrqHandler)FXmacIrqStubHandler;
- instance_p->recv_args = NULL;
- instance_p->error_irq_handler = (FXmacErrorIrqHandler)FXmacIrqStubHandler;
- instance_p->error_args = NULL;
- instance_p->link_change_handler = (FXmacIrqHandler)FXmacIrqStubHandler;
- instance_p->link_change_args = NULL;
- instance_p->restart_handler = (FXmacIrqHandler)FXmacIrqStubHandler;
- instance_p->restart_args = NULL;
- return FT_SUCCESS;
- }
- /**
- * This function sets the start address of the transmit/receive buffer queue.
- *
- * @param instance_p is a pointer to the instance to be worked on.
- * @param queue_p is the address of the Queue to be written
- * @param queue_num is the Buffer Queue Index
- * @param direction indicates Transmit/Receive
- *
- * @note
- * The buffer queue addresses has to be set before starting the transfer, so
- * this function has to be called in prior to FXmacStart()
- *
- */
- void FXmacSetQueuePtr(FXmac *instance_p, uintptr queue_p, u8 queue_num,
- u32 direction)
- {
- /* Assert bad arguments and conditions */
- FASSERT(instance_p != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- /* If already started, then there is nothing to do */
- if (instance_p->is_started == (u32)FT_COMPONENT_IS_STARTED)
- {
- return;
- }
- if (queue_num == 0x00U)
- {
- if (direction == FXMAC_SEND)
- {
- /* set base start address of TX buffer queue (tx buffer descriptor list) */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_TXQBASE_OFFSET,
- (queue_p & ULONG64_LO_MASK) | (((queue_p == (uintptr)0)) ? 1 : 0));
- }
- else
- {
- /* set base start address of RX buffer queue (rx buffer descriptor list) */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_RXQBASE_OFFSET,
- (queue_p & ULONG64_LO_MASK) | (((queue_p == (uintptr)0)) ? 1 : 0));
- }
- }
- else
- {
- if (direction == FXMAC_SEND)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_TXQ1BASE_OFFSET, queue_num),
- (queue_p & ULONG64_LO_MASK) | (((queue_p == (uintptr)0)) ? 1 : 0));
- }
- else
- {
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_TXQ1BASE_OFFSET, queue_num),
- (queue_p & ULONG64_LO_MASK) | (((queue_p == (uintptr)0)) ? 1 : 0));
- }
- }
- #ifdef __aarch64__
- if (direction == FXMAC_SEND)
- {
- /* Set the MSB of TX Queue start address */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_MSBBUF_TXQBASE_OFFSET,
- (u32)((queue_p & ULONG64_HI_MASK) >> 32U));
- }
- else
- {
- /* Set the MSB of RX Queue start address */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_MSBBUF_RXQBASE_OFFSET,
- (u32)((queue_p & ULONG64_HI_MASK) >> 32U));
- }
- #endif
- }
|