
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBFE17 CVE: NA -------------------------------- Implement some hardware init functions to set default hardware settings, including PHY control, Vlan related config, RX coalescing, and other basic function control. Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com> --- .../ethernet/motorcomm/yt6801/yt6801_main.c | 546 ++++++++++++++++++ .../ethernet/motorcomm/yt6801/yt6801_type.h | 193 +++++++ 2 files changed, 739 insertions(+) diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c b/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c index cdcdadb74..80657021c 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c +++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c @@ -484,6 +484,325 @@ static void fxgmac_enable_msix_irqs(struct fxgmac_pdata *priv) fxgmac_enable_msix_one_irq(priv, intid); } +static void __fxgmac_set_mac_address(struct fxgmac_pdata *priv, u8 *addr) +{ + u32 mac_hi, mac_lo; + + mac_lo = (u32)addr[0] | ((u32)addr[1] << 8) | ((u32)addr[2] << 16) | + ((u32)addr[3] << 24); + + mac_hi = (u32)addr[4] | ((u32)addr[5] << 8); + + fxgmac_io_wr(priv, MAC_MACA0LR, mac_lo); + fxgmac_io_wr(priv, MAC_MACA0HR, mac_hi); +} + +static void fxgmac_config_mac_address(struct fxgmac_pdata *priv) +{ + __fxgmac_set_mac_address(priv, priv->mac_addr); + fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HPF, 1); + fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HUC, 1); + fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HMC, 1); +} + +static void fxgmac_config_crc_check_en(struct fxgmac_pdata *priv) +{ + fxgmac_io_wr_bits(priv, MAC_ECR, MAC_ECR_DCRCC, 1); +} + +static void fxgmac_config_checksum_offload(struct fxgmac_pdata *priv) +{ + if (priv->ndev->features & NETIF_F_RXCSUM) + fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_IPC, 1); + else + fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_IPC, 0); +} + +static void fxgmac_set_promiscuous_mode(struct fxgmac_pdata *priv, + unsigned int enable) +{ + fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_PR, enable); +} + +static void fxgmac_enable_rx_broadcast(struct fxgmac_pdata *priv, + unsigned int enable) +{ + fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_DBF, enable); +} + +static void fxgmac_set_all_multicast_mode(struct fxgmac_pdata *priv, + unsigned int enable) +{ + fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_PM, enable); +} + +static void fxgmac_config_rx_mode(struct fxgmac_pdata *priv) +{ + u32 pr_mode, am_mode, bd_mode; + + pr_mode = ((priv->ndev->flags & IFF_PROMISC) != 0); + am_mode = ((priv->ndev->flags & IFF_ALLMULTI) != 0); + bd_mode = ((priv->ndev->flags & IFF_BROADCAST) != 0); + + fxgmac_enable_rx_broadcast(priv, bd_mode); + fxgmac_set_promiscuous_mode(priv, pr_mode); + fxgmac_set_all_multicast_mode(priv, am_mode); +} + +static void fxgmac_config_tx_flow_control(struct fxgmac_pdata *priv) +{ + /* Set MTL flow control */ + for (u32 i = 0; i < priv->rx_q_count; i++) + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_EHFC, + priv->tx_pause); + + /* Set MAC flow control */ + fxgmac_io_wr_bits(priv, MAC_Q0TFCR, MAC_Q0TFCR_TFE, priv->tx_pause); + + if (priv->tx_pause == 1) /* Set pause time */ + fxgmac_io_wr_bits(priv, MAC_Q0TFCR, MAC_Q0TFCR_PT, 0xffff); +} + +static void fxgmac_config_rx_flow_control(struct fxgmac_pdata *priv) +{ + fxgmac_io_wr_bits(priv, MAC_RFCR, MAC_RFCR_RFE, priv->rx_pause); +} + +static void fxgmac_config_rx_coalesce(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + + for (u32 i = 0; i < priv->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + fxgmac_dma_wr_bits(channel, DMA_CH_RIWT, DMA_CH_RIWT_RWT, + priv->rx_riwt); + } +} + +static void fxgmac_config_rx_fep_disable(struct fxgmac_pdata *priv) +{ + /* Enable the rx queue forward packet with error status + * (crc error,gmii_er, watch dog timeout.or overflow) + */ + for (u32 i = 0; i < priv->rx_q_count; i++) + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_FEP, 1); +} + +static void fxgmac_config_rx_fup_enable(struct fxgmac_pdata *priv) +{ + for (u32 i = 0; i < priv->rx_q_count; i++) + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_FUP, 1); +} + +static void fxgmac_config_rx_buffer_size(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + + for (u32 i = 0; i < priv->channel_count; i++, channel++) + fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_RBSZ, + priv->rx_buf_size); +} + +static void fxgmac_config_tso_mode(struct fxgmac_pdata *priv) +{ + fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_TSE, + priv->hw_feat.tso); +} + +static void fxgmac_config_sph_mode(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + + for (u32 i = 0; i < priv->channel_count; i++, channel++) + fxgmac_dma_wr_bits(channel, DMA_CH_CR, DMA_CH_CR_SPH, 0); + + fxgmac_io_wr_bits(priv, MAC_ECR, MAC_ECR_HDSMS, MAC_ECR_HDSMS_512B); +} + +static void fxgmac_config_rx_threshold(struct fxgmac_pdata *priv, + unsigned int set_val) +{ + for (u32 i = 0; i < priv->rx_q_count; i++) + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RTC, + set_val); +} + +static void fxgmac_config_mtl_mode(struct fxgmac_pdata *priv) +{ + /* Set Tx to weighted round robin scheduling algorithm */ + fxgmac_io_wr_bits(priv, MTL_OMR, MTL_OMR_ETSALG, MTL_ETSALG_WRR); + + /* Set Tx traffic classes to use WRR algorithm with equal weights */ + fxgmac_mtl_wr_bits(priv, 0, MTL_TC_QWR, MTL_TC_QWR_QW, 1); + + /* Set Rx to strict priority algorithm */ + fxgmac_io_wr_bits(priv, MTL_OMR, MTL_OMR_RAA, MTL_RAA_SP); +} + +static void fxgmac_config_queue_mapping(struct fxgmac_pdata *priv) +{ + unsigned int ppq, ppq_extra, prio_queues; + unsigned int __maybe_unused prio; + unsigned int reg, val, mask; + + /* Map the 8 VLAN priority values to available MTL Rx queues */ + prio_queues = + min_t(unsigned int, IEEE_8021QAZ_MAX_TCS, priv->rx_q_count); + ppq = IEEE_8021QAZ_MAX_TCS / prio_queues; + ppq_extra = IEEE_8021QAZ_MAX_TCS % prio_queues; + + reg = MAC_RQC2R; + for (u32 i = 0, prio = 0; i < prio_queues;) { + val = 0; + mask = 0; + for (u32 j = 0; j < ppq; j++) { + mask |= (1 << prio); + prio++; + } + + if (i < ppq_extra) { + mask |= (1 << prio); + prio++; + } + + val |= (mask << ((i++ % MAC_RQC2_Q_PER_REG) << 3)); + + if ((i % MAC_RQC2_Q_PER_REG) && i != prio_queues) + continue; + + fxgmac_io_wr(priv, reg, val); + reg += MAC_RQC2_INC; + } + + /* Configure one to one, MTL Rx queue to DMA Rx channel mapping + * ie Q0 <--> CH0, Q1 <--> CH1 ... Q7 <--> CH7 + */ + val = fxgmac_io_rd(priv, MTL_RQDCM0R); + val |= (MTL_RQDCM0R_Q0MDMACH | MTL_RQDCM0R_Q1MDMACH | + MTL_RQDCM0R_Q2MDMACH | MTL_RQDCM0R_Q3MDMACH); + fxgmac_io_wr(priv, MTL_RQDCM0R, val); + + val = fxgmac_io_rd(priv, MTL_RQDCM0R + MTL_RQDCM_INC); + val |= (MTL_RQDCM1R_Q4MDMACH | MTL_RQDCM1R_Q5MDMACH | + MTL_RQDCM1R_Q6MDMACH | MTL_RQDCM1R_Q7MDMACH); + fxgmac_io_wr(priv, MTL_RQDCM0R + MTL_RQDCM_INC, val); +} + +static unsigned int fxgmac_calculate_per_queue_fifo(unsigned int fifo_size, + unsigned int queue_count) +{ + u32 q_fifo_size, p_fifo; + + /* Calculate the configured fifo size */ + q_fifo_size = 1 << (fifo_size + 7); + +#define FXGMAC_MAX_FIFO 81920 + /* The configured value may not be the actual amount of fifo RAM */ + q_fifo_size = min_t(unsigned int, FXGMAC_MAX_FIFO, q_fifo_size); + q_fifo_size = q_fifo_size / queue_count; + + /* Each increment in the queue fifo size represents 256 bytes of + * fifo, with 0 representing 256 bytes. Distribute the fifo equally + * between the queues. + */ + p_fifo = q_fifo_size / 256; + if (p_fifo) + p_fifo--; + + return p_fifo; +} + +static void fxgmac_config_tx_fifo_size(struct fxgmac_pdata *priv) +{ + u32 fifo_size; + + fifo_size = fxgmac_calculate_per_queue_fifo(priv->hw_feat.tx_fifo_size, + FXGMAC_TX_1_Q); + fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TQS, fifo_size); +} + +static void fxgmac_config_rx_fifo_size(struct fxgmac_pdata *priv) +{ + u32 fifo_size; + + fifo_size = fxgmac_calculate_per_queue_fifo(priv->hw_feat.rx_fifo_size, + priv->rx_q_count); + + for (u32 i = 0; i < priv->rx_q_count; i++) + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RQS, + fifo_size); +} + +static void fxgmac_config_flow_control_threshold(struct fxgmac_pdata *priv) +{ + for (u32 i = 0; i < priv->rx_q_count; i++) { + /* Activate flow control when less than 4k left in fifo */ + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RFA, 6); + /* De-activate flow control when more than 6k left in fifo */ + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RFD, 10); + } +} + +static void fxgmac_config_tx_threshold(struct fxgmac_pdata *priv, + unsigned int set_val) +{ + fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TTC, set_val); +} + +static void fxgmac_config_rsf_mode(struct fxgmac_pdata *priv, + unsigned int set_val) +{ + for (u32 i = 0; i < priv->rx_q_count; i++) + fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RSF, + set_val); +} + +static void fxgmac_config_tsf_mode(struct fxgmac_pdata *priv, + unsigned int set_val) +{ + fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TSF, set_val); +} + +static void fxgmac_config_osp_mode(struct fxgmac_pdata *priv) +{ + fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_OSP, + priv->tx_osp_mode); +} + +static void fxgmac_config_pblx8(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + + for (u32 i = 0; i < priv->channel_count; i++, channel++) + fxgmac_dma_wr_bits(channel, DMA_CH_CR, DMA_CH_CR_PBLX8, + priv->pblx8); +} + +static void fxgmac_config_tx_pbl_val(struct fxgmac_pdata *priv) +{ + fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_PBL, + priv->tx_pbl); +} + +static void fxgmac_config_rx_pbl_val(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + + for (u32 i = 0; i < priv->channel_count; i++, channel++) + fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_PBL, + priv->rx_pbl); +} + +static void fxgmac_config_mmc(struct fxgmac_pdata *priv) +{ + /* Set counters to reset on read, Reset the counters */ + fxgmac_io_wr_bits(priv, MMC_CR, MMC_CR_ROR, 1); + fxgmac_io_wr_bits(priv, MMC_CR, MMC_CR_CR, 1); + + fxgmac_io_wr(priv, MMC_IPC_RXINT_MASK, 0xffffffff); +} + static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *priv) { struct fxgmac_channel *channel = priv->channel_head; @@ -514,6 +833,233 @@ static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *priv) } } +static void fxgmac_enable_mtl_interrupts(struct fxgmac_pdata *priv) +{ + unsigned int mtl_q_isr; + + for (u32 i = 0; i < priv->hw_feat.rx_q_cnt; i++) { + /* Clear all the interrupts which are set */ + mtl_q_isr = fxgmac_mtl_io_rd(priv, i, MTL_Q_IR); + fxgmac_mtl_io_wr(priv, i, MTL_Q_IR, mtl_q_isr); + + /* No MTL interrupts to be enabled */ + fxgmac_mtl_io_wr(priv, i, MTL_Q_IR, 0); + } +} + +static void fxgmac_enable_mac_interrupts(struct fxgmac_pdata *priv) +{ + /* Disable Timestamp interrupt */ + fxgmac_io_wr_bits(priv, MAC_IER, MAC_IER_TSIE, 0); + + fxgmac_io_wr_bits(priv, MMC_RIER, MMC_RIER_ALL_INTERRUPTS, 0); + fxgmac_io_wr_bits(priv, MMC_TIER, MMC_TIER_ALL_INTERRUPTS, 0); +} + +static int fxgmac_flush_tx_queues(struct fxgmac_pdata *priv) +{ + u32 val, count = 2000; + + fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_FTQ, 1); + do { + fsleep(20); + val = fxgmac_mtl_io_rd(priv, 0, MTL_Q_TQOMR); + val = FIELD_GET(MTL_Q_TQOMR_FTQ, val); + + } while (--count && val); + + if (val) + return -EBUSY; + + return 0; +} + +static void fxgmac_config_dma_bus(struct fxgmac_pdata *priv) +{ + u32 val = fxgmac_io_rd(priv, DMA_SBMR); + + val &= ~(DMA_SBMR_EAME | DMA_SBMR_RD_OSR_LMT | + DMA_SBMR_WR_OSR_LMT | DMA_SBMR_FB); + + /* Set enhanced addressing mode */ + val |= DMA_SBMR_EAME; + + /* Out standing read/write requests */ + val |= FIELD_PREP(DMA_SBMR_RD_OSR_LMT, 0x7); + val |= FIELD_PREP(DMA_SBMR_WR_OSR_LMT, 0x7); + + /* Set the System Bus mode */ + val |= (DMA_SBMR_BLEN_4 | DMA_SBMR_BLEN_8 | + DMA_SBMR_BLEN_16 | DMA_SBMR_BLEN_32); + + fxgmac_io_wr(priv, DMA_SBMR, val); +} + +static void fxgmac_desc_rx_channel_init(struct fxgmac_channel *channel) +{ + struct fxgmac_ring *ring = channel->rx_ring; + unsigned int start_index = ring->cur; + struct fxgmac_desc_data *desc_data; + + /* Initialize all descriptors */ + for (u32 i = 0; i < ring->dma_desc_count; i++) { + desc_data = FXGMAC_GET_DESC_DATA(ring, i); + fxgmac_desc_rx_reset(desc_data); /* Initialize Rx descriptor */ + } + + /* Update the total number of Rx descriptors */ + fxgmac_dma_io_wr(channel, DMA_CH_RDRLR, ring->dma_desc_count - 1); + + /* Update the starting address of descriptor ring */ + desc_data = FXGMAC_GET_DESC_DATA(ring, start_index); + + fxgmac_dma_io_wr(channel, DMA_CH_RDLR_HI, + upper_32_bits(desc_data->dma_desc_addr)); + fxgmac_dma_io_wr(channel, DMA_CH_RDLR_LO, + lower_32_bits(desc_data->dma_desc_addr)); + + /* Update the Rx Descriptor Tail Pointer */ + desc_data = FXGMAC_GET_DESC_DATA(ring, start_index + + ring->dma_desc_count - 1); + fxgmac_dma_io_wr(channel, DMA_CH_RDTR_LO, + lower_32_bits(desc_data->dma_desc_addr)); +} + +static void fxgmac_desc_rx_init(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + struct fxgmac_desc_data *desc_data; + struct fxgmac_dma_desc *dma_desc; + dma_addr_t dma_desc_addr; + struct fxgmac_ring *ring; + + for (u32 i = 0; i < priv->channel_count; i++, channel++) { + ring = channel->rx_ring; + dma_desc = ring->dma_desc_head; + dma_desc_addr = ring->dma_desc_head_addr; + + for (u32 j = 0; j < ring->dma_desc_count; j++) { + desc_data = FXGMAC_GET_DESC_DATA(ring, j); + desc_data->dma_desc = dma_desc; + desc_data->dma_desc_addr = dma_desc_addr; + if (fxgmac_rx_buffe_map(priv, ring, desc_data)) + break; + + dma_desc++; + dma_desc_addr += sizeof(struct fxgmac_dma_desc); + } + + ring->cur = 0; + ring->dirty = 0; + + fxgmac_desc_rx_channel_init(channel); + } +} + +static void fxgmac_desc_tx_channel_init(struct fxgmac_channel *channel) +{ + struct fxgmac_ring *ring = channel->tx_ring; + struct fxgmac_desc_data *desc_data; + int start_index = ring->cur; + + /* Initialize all descriptors */ + for (u32 i = 0; i < ring->dma_desc_count; i++) { + desc_data = FXGMAC_GET_DESC_DATA(ring, i); + fxgmac_desc_tx_reset(desc_data); /* Initialize Tx descriptor */ + } + + /* Update the total number of Tx descriptors */ + fxgmac_dma_io_wr(channel, DMA_CH_TDRLR, + channel->priv->tx_desc_count - 1); + + /* Update the starting address of descriptor ring */ + desc_data = FXGMAC_GET_DESC_DATA(ring, start_index); + + fxgmac_dma_io_wr(channel, DMA_CH_TDLR_HI, + upper_32_bits(desc_data->dma_desc_addr)); + fxgmac_dma_io_wr(channel, DMA_CH_TDLR_LO, + lower_32_bits(desc_data->dma_desc_addr)); +} + +static void fxgmac_desc_tx_init(struct fxgmac_pdata *priv) +{ + struct fxgmac_channel *channel = priv->channel_head; + struct fxgmac_ring *ring = channel->tx_ring; + struct fxgmac_desc_data *desc_data; + struct fxgmac_dma_desc *dma_desc; + dma_addr_t dma_desc_addr; + + dma_desc = ring->dma_desc_head; + dma_desc_addr = ring->dma_desc_head_addr; + + for (u32 j = 0; j < ring->dma_desc_count; j++) { + desc_data = FXGMAC_GET_DESC_DATA(ring, j); + desc_data->dma_desc = dma_desc; + desc_data->dma_desc_addr = dma_desc_addr; + + dma_desc++; + dma_desc_addr += sizeof(struct fxgmac_dma_desc); + } + + ring->cur = 0; + ring->dirty = 0; + memset(&ring->tx, 0, sizeof(ring->tx)); + fxgmac_desc_tx_channel_init(priv->channel_head); +} + +static int fxgmac_hw_init(struct fxgmac_pdata *priv) +{ + int ret; + + ret = fxgmac_flush_tx_queues(priv); /* Flush Tx queues */ + if (ret < 0) { + dev_err(priv->dev, "%s, flush tx queue failed:%d\n", + __func__, ret); + return ret; + } + + /* Initialize DMA related features */ + fxgmac_config_dma_bus(priv); + fxgmac_config_osp_mode(priv); + fxgmac_config_pblx8(priv); + fxgmac_config_tx_pbl_val(priv); + fxgmac_config_rx_pbl_val(priv); + fxgmac_config_rx_coalesce(priv); + fxgmac_config_rx_buffer_size(priv); + fxgmac_config_tso_mode(priv); + fxgmac_config_sph_mode(priv); + fxgmac_desc_tx_init(priv); + fxgmac_desc_rx_init(priv); + fxgmac_enable_dma_interrupts(priv); + + /* Initialize MTL related features */ + fxgmac_config_mtl_mode(priv); + fxgmac_config_queue_mapping(priv); + fxgmac_config_tsf_mode(priv, priv->tx_sf_mode); + fxgmac_config_rsf_mode(priv, priv->rx_sf_mode); + fxgmac_config_tx_threshold(priv, priv->tx_threshold); + fxgmac_config_rx_threshold(priv, priv->rx_threshold); + fxgmac_config_tx_fifo_size(priv); + fxgmac_config_rx_fifo_size(priv); + fxgmac_config_flow_control_threshold(priv); + fxgmac_config_rx_fep_disable(priv); + fxgmac_config_rx_fup_enable(priv); + fxgmac_enable_mtl_interrupts(priv); + + /* Initialize MAC related features */ + fxgmac_config_mac_address(priv); + fxgmac_config_crc_check_en(priv); + fxgmac_config_rx_mode(priv); + fxgmac_config_tx_flow_control(priv); + fxgmac_config_rx_flow_control(priv); + fxgmac_config_mac_speed(priv); + fxgmac_config_checksum_offload(priv); + fxgmac_config_mmc(priv); + fxgmac_enable_mac_interrupts(priv); + + return 0; +} + static void fxgmac_dismiss_all_int(struct fxgmac_pdata *priv) { struct fxgmac_channel *channel = priv->channel_head; diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h b/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h index b54fc6169..228e0fa56 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h +++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h @@ -135,6 +135,33 @@ #define MAC_CR_IPC BIT(27) #define MAC_CR_ARPEN BIT(31) +#define MAC_ECR 0x2004 +#define MAC_ECR_DCRCC BIT(16) +#define MAC_ECR_HDSMS GENMASK(22, 20) +#define MAC_ECR_HDSMS_64B 0 +#define MAC_ECR_HDSMS_128B 1 +#define MAC_ECR_HDSMS_256B 2 +#define MAC_ECR_HDSMS_512B 3 +#define MAC_ECR_HDSMS_1023B 4 + +#define MAC_PFR 0x3008 +#define MAC_PFR_PR BIT(0) /* Promiscuous Mode. */ +#define MAC_PFR_HUC BIT(1) /* Hash Unicast Mode. */ +#define MAC_PFR_HMC BIT(2) +#define MAC_PFR_PM BIT(4) /* Pass all Multicast. */ +#define MAC_PFR_DBF BIT(5) /* Disable Broadcast Packets. */ +#define MAC_PFR_HPF BIT(10) +#define MAC_PFR_VTFE BIT(16) + +#define MAC_Q0TFCR 0x2070 +#define MAC_Q0TFCR_TFE BIT(1) +#define MAC_Q0TFCR_PT GENMASK(31, 16) + +#define MAC_RFCR 0x2090 +#define MAC_RFCR_RFE BIT(0) +#define MAC_RFCR_UP BIT(1) +#define MAC_RFCR_PFCE BIT(8) + #define MAC_RQC0R 0x20a0 #define MAC_RQC1R 0x20a4 #define MAC_RQC2R 0x20a8 @@ -231,6 +258,60 @@ #define MAC_MDIO_DATA_GD GENMASK(15, 0) #define MAC_MDIO_DATA_RA GENMASK(31, 16) +#define MAC_GPIO_CR 0x2208 +#define MAC_GPIO_SR 0x220c +#define MAC_ARP_PROTO_ADDR 0x2210 +#define MAC_CSR_SW_CTRL 0x2230 +#define MAC_MACA0HR 0x2300 +#define MAC_MACA0LR 0x2304 +#define MAC_MACA1HR 0x2308 +#define MAC_MACA1LR 0x230c + +/* MMC registers */ +#define MMC_CR 0x2700 +#define MMC_CR_CR BIT(0) +#define MMC_CR_CSR BIT(1) +#define MMC_CR_ROR BIT(2) +#define MMC_CR_MCF BIT(3) + +#define MMC_RISR 0x2704 +#define MMC_TISR 0x2708 + +#define MMC_RIER 0x270c +#define MMC_RIER_ALL_INTERRUPTS GENMASK(27, 0) + +#define MMC_TIER 0x2710 +#define MMC_TIER_ALL_INTERRUPTS GENMASK(27, 0) + +#define MMC_IPC_RXINT_MASK 0x2800 +#define MMC_IPC_RXINT 0x2808 + +/* MTL registers */ +#define MTL_OMR 0x2c00 +#define MTL_OMR_RAA BIT(2) +#define MTL_OMR_ETSALG GENMASK(6, 5) + +#define MTL_FDCR 0x2c08 +#define MTL_FDSR 0x2c0c +#define MTL_FDDR 0x2c10 +#define MTL_INT_SR 0x2c20 + +#define MTL_RQDCM_INC 4 +#define MTL_RQDCM_Q_PER_REG 4 + +#define MTL_RQDCM0R 0x2c30 +#define MTL_RQDCM0R_Q0MDMACH 0x0 +#define MTL_RQDCM0R_Q1MDMACH 0x00000100 +#define MTL_RQDCM0R_Q2MDMACH 0x00020000 +#define MTL_RQDCM0R_Q3MDMACH 0x03000000 + +#define MTL_ECC_INT_SR 0x2ccc + +#define MTL_RQDCM1R_Q4MDMACH 0x00000004 +#define MTL_RQDCM1R_Q5MDMACH 0x00000500 +#define MTL_RQDCM1R_Q6MDMACH 0x00060000 +#define MTL_RQDCM1R_Q7MDMACH 0x07000000 + /* MTL queue registers */ #define MTL_Q_BASE 0x2d00 #define MTL_Q_INC 0x40 @@ -243,11 +324,69 @@ #define MTL_Q_EN_IF_AV 0x01 #define MTL_Q_ENABLED 0x02 +#define MTL_Q_TQOMR_TTC GENMASK(6, 4) +#define MTL_Q_TQOMR_TTC_THRESHOLD_32 0x00 +#define MTL_Q_TQOMR_TTC_THRESHOLD_64 0x01 +#define MTL_Q_TQOMR_TTC_THRESHOLD_96 0x02 +#define MTL_Q_TQOMR_TTC_THRESHOLD_128 0x03 +#define MTL_Q_TQOMR_TTC_THRESHOLD_192 0x04 +#define MTL_Q_TQOMR_TTC_THRESHOLD_256 0x05 +#define MTL_Q_TQOMR_TTC_THRESHOLD_384 0x06 +#define MTL_Q_TQOMR_TTC_THRESHOLD_512 0x07 + +#define MTL_Q_TQOMR_TQS GENMASK(22, 16) + +#define MTL_Q_TQUR 0x04 +#define MTL_Q_TXDEG 0x08 /* Transmit debug */ #define MTL_Q_IR 0x2c /* Interrupt control status */ + +#define MTL_Q_RQOMR 0x30 +#define MTL_Q_RQOMR_RTC GENMASK(1, 0) +#define MTL_Q_RQOMR_RTC_THRESHOLD_64 0x00 +#define MTL_Q_RQOMR_RTC_THRESHOLD_32 0x01 +#define MTL_Q_RQOMR_RTC_THRESHOLD_96 0x02 +#define MTL_Q_RQOMR_RTC_THRESHOLD_128 0x03 + +#define MTL_Q_RQOMR_FUP BIT(3) +#define MTL_Q_RQOMR_FEP BIT(4) +#define MTL_Q_RQOMR_RSF BIT(5) +#define MTL_Q_RQOMR_EHFC BIT(7) +#define MTL_Q_RQOMR_RFA GENMASK(13, 8) +#define MTL_Q_RQOMR_RFD GENMASK(19, 14) +#define MTL_Q_RQOMR_RQS GENMASK(28, 20) + +#define MTL_Q_RQMPOCR 0x34 + #define MTL_Q_RQDR 0x38 #define MTL_Q_RQDR_RXQSTS GENMASK(5, 4) #define MTL_Q_RQDR_PRXQ GENMASK(29, 16) +#define MTL_Q_RQCR 0x3c + +/* MTL queue registers */ +#define MTL_ETSALG_WRR 0x00 +#define MTL_ETSALG_WFQ 0x01 +#define MTL_ETSALG_DWRR 0x02 +#define MTL_ETSALG_SP 0x03 + +#define MTL_RAA_SP 0x00 +#define MTL_RAA_WSP 0x01 + +/* MTL traffic class registers */ +#define MTL_TC_BASE MTL_Q_BASE +#define MTL_TC_INC MTL_Q_INC + +#define MTL_TC_TQDR 0x08 +#define MTL_TC_TQDR_TRCSTS GENMASK(2, 1) +#define MTL_TC_TQDR_TXQSTS BIT(4) + +#define MTL_TC_ETSCR 0x10 +#define MTL_TC_ETSCR_TSA GENMASK(1, 0) + +#define MTL_TC_ETSSR 0x14 +#define MTL_TC_QWR 0x18 +#define MTL_TC_QWR_QW GENMASK(20, 0) + /* DMA registers */ #define DMA_MR 0x3000 #define DMA_MR_SWR BIT(0) @@ -257,16 +396,50 @@ #define DMA_MR_TNDF GENMASK(21, 20) #define DMA_MR_RNDF GENMASK(23, 22) +#define DMA_SBMR 0x3004 +#define DMA_SBMR_FB BIT(0) +#define DMA_SBMR_BLEN_4 BIT(1) +#define DMA_SBMR_BLEN_8 BIT(2) +#define DMA_SBMR_BLEN_16 BIT(3) +#define DMA_SBMR_BLEN_32 BIT(4) +#define DMA_SBMR_BLEN_64 BIT(5) +#define DMA_SBMR_BLEN_128 BIT(6) +#define DMA_SBMR_BLEN_256 BIT(7) +#define DMA_SBMR_AALE BIT(10) +#define DMA_SBMR_EAME BIT(11) +#define DMA_SBMR_AAL BIT(12) +#define DMA_SBMR_RD_OSR_LMT GENMASK(23, 16) +#define DMA_SBMR_WR_OSR_LMT GENMASK(29, 24) +#define DMA_SBMR_LPI_XIT_PKT BIT(30) +#define DMA_SBMR_EN_LPI BIT(31) + +#define DMA_ISR 0x3008 +#define DMA_ISR_MTLIS BIT(16) +#define DMA_ISR_MACIS BIT(17) + #define DMA_DSRX_INC 4 #define DMA_DSR0 0x300c #define DMA_DSR0_TPS GENMASK(15, 12) #define DMA_TPS_STOPPED 0x00 #define DMA_TPS_SUSPENDED 0x06 +#define DMA_DSR1 0x3010 +#define DMA_DSR2 0x3014 +#define DMA_AXIARCR 0x3020 +#define DMA_AXIAWCR 0x3024 +#define DMA_AXIAWRCR 0x3028 +#define DMA_SAFE_ISR 0x3080 +#define DMA_ECC_IE 0x3084 +#define DMA_ECC_INT_SR 0x3088 + /* DMA channel registers */ #define DMA_CH_BASE 0x3100 #define DMA_CH_INC 0x80 +#define DMA_CH_CR 0x00 +#define DMA_CH_CR_PBLX8 BIT(16) +#define DMA_CH_CR_SPH BIT(24) + #define DMA_CH_TCR 0x04 #define DMA_CH_TCR_ST BIT(0) #define DMA_CH_TCR_OSP BIT(4) @@ -287,6 +460,15 @@ #define DMA_CH_RCR_RBSZ GENMASK(14, 1) #define DMA_CH_RCR_PBL GENMASK(21, 16) +#define DMA_CH_TDLR_HI 0x10 +#define DMA_CH_TDLR_LO 0x14 +#define DMA_CH_RDLR_HI 0x18 +#define DMA_CH_RDLR_LO 0x1c +#define DMA_CH_TDTR_LO 0x20 +#define DMA_CH_RDTR_LO 0x28 +#define DMA_CH_TDRLR 0x2c +#define DMA_CH_RDRLR 0x30 + #define DMA_CH_IER 0x34 #define DMA_CH_IER_TIE BIT(0) #define DMA_CH_IER_TXSE BIT(1) @@ -298,6 +480,16 @@ #define DMA_CH_IER_AIE BIT(14) #define DMA_CH_IER_NIE BIT(15) +#define DMA_CH_RIWT 0x38 +#define DMA_CH_RIWT_RWT GENMASK(7, 0) + +#define DMA_CH_CATDR_LO 0x44 +#define DMA_CH_CARDR_LO 0x4c +#define DMA_CH_CATBR_HI 0x50 +#define DMA_CH_CATBR_LO 0x54 +#define DMA_CH_CARBR_HI 0x58 +#define DMA_CH_CARBR_LO 0x5c + #define DMA_CH_SR 0x60 #define DMA_CH_SR_TI BIT(0) #define DMA_CH_SR_TPS BIT(1) @@ -559,6 +751,7 @@ struct fxgmac_pdata { /* ndev related settings */ unsigned char mac_addr[ETH_ALEN]; + struct napi_struct napi; int mac_speed; int mac_duplex; -- 2.34.1