X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fmvpp2.c;h=e75979b37a3562e28f360ab8e184b96efec107d7;hb=b8c8e6ffac5bc5ce01b562b4506650e6629815b6;hp=88e88b903b3fc63757b0ed46312ef96a7c84f6a6;hpb=e160f7d430f163bc42757aff3bf2bcac0a459f02;p=u-boot diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index 88e88b903b..e75979b37a 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -91,9 +91,11 @@ do { \ #define MVPP2_SNOOP_PKT_SIZE_MASK 0x1ff #define MVPP2_SNOOP_BUF_HDR_MASK BIT(9) #define MVPP2_RXQ_POOL_SHORT_OFFS 20 -#define MVPP2_RXQ_POOL_SHORT_MASK 0x700000 +#define MVPP21_RXQ_POOL_SHORT_MASK 0x700000 +#define MVPP22_RXQ_POOL_SHORT_MASK 0xf00000 #define MVPP2_RXQ_POOL_LONG_OFFS 24 -#define MVPP2_RXQ_POOL_LONG_MASK 0x7000000 +#define MVPP21_RXQ_POOL_LONG_MASK 0x7000000 +#define MVPP22_RXQ_POOL_LONG_MASK 0xf000000 #define MVPP2_RXQ_PACKET_OFFSET_OFFS 28 #define MVPP2_RXQ_PACKET_OFFSET_MASK 0x70000000 #define MVPP2_RXQ_DISABLE_MASK BIT(31) @@ -251,14 +253,23 @@ do { \ #define MVPP2_BM_PHY_ALLOC_REG(pool) (0x6400 + ((pool) * 4)) #define MVPP2_BM_PHY_ALLOC_GRNTD_MASK BIT(0) #define MVPP2_BM_VIRT_ALLOC_REG 0x6440 +#define MVPP2_BM_ADDR_HIGH_ALLOC 0x6444 +#define MVPP2_BM_ADDR_HIGH_PHYS_MASK 0xff +#define MVPP2_BM_ADDR_HIGH_VIRT_MASK 0xff00 +#define MVPP2_BM_ADDR_HIGH_VIRT_SHIFT 8 #define MVPP2_BM_PHY_RLS_REG(pool) (0x6480 + ((pool) * 4)) #define MVPP2_BM_PHY_RLS_MC_BUFF_MASK BIT(0) #define MVPP2_BM_PHY_RLS_PRIO_EN_MASK BIT(1) #define MVPP2_BM_PHY_RLS_GRNTD_MASK BIT(2) #define MVPP2_BM_VIRT_RLS_REG 0x64c0 -#define MVPP2_BM_MC_RLS_REG 0x64c4 +#define MVPP21_BM_MC_RLS_REG 0x64c4 #define MVPP2_BM_MC_ID_MASK 0xfff #define MVPP2_BM_FORCE_RELEASE_MASK BIT(12) +#define MVPP22_BM_ADDR_HIGH_RLS_REG 0x64c4 +#define MVPP22_BM_ADDR_HIGH_PHYS_RLS_MASK 0xff +#define MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK 0xff00 +#define MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT 8 +#define MVPP22_BM_MC_RLS_REG 0x64d4 /* TX Scheduler registers */ #define MVPP2_TXP_SCHED_PORT_INDEX_REG 0x8000 @@ -294,12 +305,8 @@ do { \ #define MVPP2_SRC_ADDR_HIGH 0x28 #define MVPP2_PHY_AN_CFG0_REG 0x34 #define MVPP2_PHY_AN_STOP_SMI0_MASK BIT(7) -#define MVPP2_MIB_COUNTERS_BASE(port) (0x1000 + ((port) >> 1) * \ - 0x400 + (port) * 0x400) -#define MVPP2_MIB_LATE_COLLISION 0x7c -#define MVPP2_ISR_SUM_MASK_REG 0x220c #define MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG 0x305c -#define MVPP2_EXT_GLOBAL_CTRL_DEFAULT 0x27 +#define MVPP2_EXT_GLOBAL_CTRL_DEFAULT 0x27 /* Per-port registers */ #define MVPP2_GMAC_CTRL_0_REG 0x0 @@ -576,28 +583,28 @@ enum mvpp2_tag_type { /* Sram result info bits assignment */ #define MVPP2_PRS_RI_MAC_ME_MASK 0x1 #define MVPP2_PRS_RI_DSA_MASK 0x2 -#define MVPP2_PRS_RI_VLAN_MASK 0xc -#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3)) +#define MVPP2_PRS_RI_VLAN_MASK (BIT(2) | BIT(3)) +#define MVPP2_PRS_RI_VLAN_NONE 0x0 #define MVPP2_PRS_RI_VLAN_SINGLE BIT(2) #define MVPP2_PRS_RI_VLAN_DOUBLE BIT(3) #define MVPP2_PRS_RI_VLAN_TRIPLE (BIT(2) | BIT(3)) #define MVPP2_PRS_RI_CPU_CODE_MASK 0x70 #define MVPP2_PRS_RI_CPU_CODE_RX_SPEC BIT(4) -#define MVPP2_PRS_RI_L2_CAST_MASK 0x600 -#define MVPP2_PRS_RI_L2_UCAST ~(BIT(9) | BIT(10)) +#define MVPP2_PRS_RI_L2_CAST_MASK (BIT(9) | BIT(10)) +#define MVPP2_PRS_RI_L2_UCAST 0x0 #define MVPP2_PRS_RI_L2_MCAST BIT(9) #define MVPP2_PRS_RI_L2_BCAST BIT(10) #define MVPP2_PRS_RI_PPPOE_MASK 0x800 -#define MVPP2_PRS_RI_L3_PROTO_MASK 0x7000 -#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14)) +#define MVPP2_PRS_RI_L3_PROTO_MASK (BIT(12) | BIT(13) | BIT(14)) +#define MVPP2_PRS_RI_L3_UN 0x0 #define MVPP2_PRS_RI_L3_IP4 BIT(12) #define MVPP2_PRS_RI_L3_IP4_OPT BIT(13) #define MVPP2_PRS_RI_L3_IP4_OTHER (BIT(12) | BIT(13)) #define MVPP2_PRS_RI_L3_IP6 BIT(14) #define MVPP2_PRS_RI_L3_IP6_EXT (BIT(12) | BIT(14)) #define MVPP2_PRS_RI_L3_ARP (BIT(13) | BIT(14)) -#define MVPP2_PRS_RI_L3_ADDR_MASK 0x18000 -#define MVPP2_PRS_RI_L3_UCAST ~(BIT(15) | BIT(16)) +#define MVPP2_PRS_RI_L3_ADDR_MASK (BIT(15) | BIT(16)) +#define MVPP2_PRS_RI_L3_UCAST 0x0 #define MVPP2_PRS_RI_L3_MCAST BIT(15) #define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16)) #define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000 @@ -711,6 +718,9 @@ struct mvpp2 { /* Tclk value */ u32 tclk; + /* HW version */ + enum { MVPP21, MVPP22 } hw_version; + struct mii_dev *bus; }; @@ -798,22 +808,24 @@ struct mvpp2_port { #define MVPP2_RXD_L3_IP6 BIT(30) #define MVPP2_RXD_BUF_HDR BIT(31) -struct mvpp2_tx_desc { +/* HW TX descriptor for PPv2.1 */ +struct mvpp21_tx_desc { u32 command; /* Options used by HW for packet transmitting.*/ u8 packet_offset; /* the offset from the buffer beginning */ u8 phys_txq; /* destination queue ID */ u16 data_size; /* data size of transmitted packet in bytes */ - u32 buf_phys_addr; /* physical addr of transmitted buffer */ + u32 buf_dma_addr; /* physical addr of transmitted buffer */ u32 buf_cookie; /* cookie for access to TX buffer in tx path */ u32 reserved1[3]; /* hw_cmd (for future use, BM, PON, PNC) */ u32 reserved2; /* reserved (for future use) */ }; -struct mvpp2_rx_desc { +/* HW RX descriptor for PPv2.1 */ +struct mvpp21_rx_desc { u32 status; /* info about received packet */ u16 reserved1; /* parser_info (for future use, PnC) */ u16 data_size; /* size of received packet in bytes */ - u32 buf_phys_addr; /* physical address of the buffer */ + u32 buf_dma_addr; /* physical address of the buffer */ u32 buf_cookie; /* cookie for access to RX buffer in rx path */ u16 reserved2; /* gem_port_id (for future use, PON) */ u16 reserved3; /* csum_l4 (for future use, PnC) */ @@ -824,6 +836,45 @@ struct mvpp2_rx_desc { u32 reserved8; }; +/* HW TX descriptor for PPv2.2 */ +struct mvpp22_tx_desc { + u32 command; + u8 packet_offset; + u8 phys_txq; + u16 data_size; + u64 reserved1; + u64 buf_dma_addr_ptp; + u64 buf_cookie_misc; +}; + +/* HW RX descriptor for PPv2.2 */ +struct mvpp22_rx_desc { + u32 status; + u16 reserved1; + u16 data_size; + u32 reserved2; + u32 reserved3; + u64 buf_dma_addr_key_hash; + u64 buf_cookie_misc; +}; + +/* Opaque type used by the driver to manipulate the HW TX and RX + * descriptors + */ +struct mvpp2_tx_desc { + union { + struct mvpp21_tx_desc pp21; + struct mvpp22_tx_desc pp22; + }; +}; + +struct mvpp2_rx_desc { + union { + struct mvpp21_rx_desc pp21; + struct mvpp22_rx_desc pp22; + }; +}; + /* Per-CPU Tx queue control */ struct mvpp2_txq_pcpu { int cpu; @@ -868,7 +919,7 @@ struct mvpp2_tx_queue { struct mvpp2_tx_desc *descs; /* DMA address of the Tx DMA descriptors array */ - dma_addr_t descs_phys; + dma_addr_t descs_dma; /* Index of the last Tx DMA descriptor */ int last_desc; @@ -891,7 +942,7 @@ struct mvpp2_rx_queue { struct mvpp2_rx_desc *descs; /* DMA address of the RX DMA descriptors array */ - dma_addr_t descs_phys; + dma_addr_t descs_dma; /* Index of the last RX DMA descriptor */ int last_desc; @@ -963,9 +1014,9 @@ struct mvpp2_bm_pool { int pkt_size; /* BPPE virtual base address */ - u32 *virt_addr; - /* BPPE physical base address */ - dma_addr_t phys_addr; + unsigned long *virt_addr; + /* BPPE DMA base address */ + dma_addr_t dma_addr; /* Ports using BM pool */ u32 port_map; @@ -974,22 +1025,6 @@ struct mvpp2_bm_pool { int in_use_thresh; }; -struct mvpp2_buff_hdr { - u32 next_buff_phys_addr; - u32 next_buff_virt_addr; - u16 byte_count; - u16 info; - u8 reserved1; /* bm_qset (for future use, BM) */ -}; - -/* Buffer header info bits */ -#define MVPP2_B_HDR_INFO_MC_ID_MASK 0xfff -#define MVPP2_B_HDR_INFO_MC_ID(info) ((info) & MVPP2_B_HDR_INFO_MC_ID_MASK) -#define MVPP2_B_HDR_INFO_LAST_OFFS 12 -#define MVPP2_B_HDR_INFO_LAST_MASK BIT(12) -#define MVPP2_B_HDR_INFO_IS_LAST(info) \ - ((info & MVPP2_B_HDR_INFO_LAST_MASK) >> MVPP2_B_HDR_INFO_LAST_OFFS) - /* Static declaractions */ /* Number of RXQs used by single port */ @@ -1007,8 +1042,8 @@ struct buffer_location { struct mvpp2_tx_desc *aggr_tx_descs; struct mvpp2_tx_desc *tx_descs; struct mvpp2_rx_desc *rx_descs; - u32 *bm_pool[MVPP2_BM_POOLS_NUM]; - u32 *rx_buffer[MVPP2_BM_LONG_BUF_NUM]; + unsigned long *bm_pool[MVPP2_BM_POOLS_NUM]; + unsigned long *rx_buffer[MVPP2_BM_LONG_BUF_NUM]; int first_rxq; }; @@ -1036,6 +1071,96 @@ static u32 mvpp2_read(struct mvpp2 *priv, u32 offset) return readl(priv->base + offset); } +static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port, + struct mvpp2_tx_desc *tx_desc, + dma_addr_t dma_addr) +{ + if (port->priv->hw_version == MVPP21) { + tx_desc->pp21.buf_dma_addr = dma_addr; + } else { + u64 val = (u64)dma_addr; + + tx_desc->pp22.buf_dma_addr_ptp &= ~GENMASK_ULL(40, 0); + tx_desc->pp22.buf_dma_addr_ptp |= val; + } +} + +static void mvpp2_txdesc_size_set(struct mvpp2_port *port, + struct mvpp2_tx_desc *tx_desc, + size_t size) +{ + if (port->priv->hw_version == MVPP21) + tx_desc->pp21.data_size = size; + else + tx_desc->pp22.data_size = size; +} + +static void mvpp2_txdesc_txq_set(struct mvpp2_port *port, + struct mvpp2_tx_desc *tx_desc, + unsigned int txq) +{ + if (port->priv->hw_version == MVPP21) + tx_desc->pp21.phys_txq = txq; + else + tx_desc->pp22.phys_txq = txq; +} + +static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port, + struct mvpp2_tx_desc *tx_desc, + unsigned int command) +{ + if (port->priv->hw_version == MVPP21) + tx_desc->pp21.command = command; + else + tx_desc->pp22.command = command; +} + +static void mvpp2_txdesc_offset_set(struct mvpp2_port *port, + struct mvpp2_tx_desc *tx_desc, + unsigned int offset) +{ + if (port->priv->hw_version == MVPP21) + tx_desc->pp21.packet_offset = offset; + else + tx_desc->pp22.packet_offset = offset; +} + +static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port, + struct mvpp2_rx_desc *rx_desc) +{ + if (port->priv->hw_version == MVPP21) + return rx_desc->pp21.buf_dma_addr; + else + return rx_desc->pp22.buf_dma_addr_key_hash & GENMASK_ULL(40, 0); +} + +static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port, + struct mvpp2_rx_desc *rx_desc) +{ + if (port->priv->hw_version == MVPP21) + return rx_desc->pp21.buf_cookie; + else + return rx_desc->pp22.buf_cookie_misc & GENMASK_ULL(40, 0); +} + +static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port, + struct mvpp2_rx_desc *rx_desc) +{ + if (port->priv->hw_version == MVPP21) + return rx_desc->pp21.data_size; + else + return rx_desc->pp22.data_size; +} + +static u32 mvpp2_rxdesc_status_get(struct mvpp2_port *port, + struct mvpp2_rx_desc *rx_desc) +{ + if (port->priv->hw_version == MVPP21) + return rx_desc->pp21.status; + else + return rx_desc->pp22.status; +} + static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu) { txq_pcpu->txq_get_index++; @@ -2218,19 +2343,26 @@ static int mvpp2_bm_pool_create(struct udevice *dev, { u32 val; + /* Number of buffer pointers must be a multiple of 16, as per + * hardware constraints + */ + if (!IS_ALIGNED(size, 16)) + return -EINVAL; + bm_pool->virt_addr = buffer_loc.bm_pool[bm_pool->id]; - bm_pool->phys_addr = (dma_addr_t)buffer_loc.bm_pool[bm_pool->id]; + bm_pool->dma_addr = (dma_addr_t)buffer_loc.bm_pool[bm_pool->id]; if (!bm_pool->virt_addr) return -ENOMEM; - if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVPP2_BM_POOL_PTR_ALIGN)) { + if (!IS_ALIGNED((unsigned long)bm_pool->virt_addr, + MVPP2_BM_POOL_PTR_ALIGN)) { dev_err(&pdev->dev, "BM pool %d is not %d bytes aligned\n", bm_pool->id, MVPP2_BM_POOL_PTR_ALIGN); return -ENOMEM; } mvpp2_write(priv, MVPP2_BM_POOL_BASE_REG(bm_pool->id), - bm_pool->phys_addr); + lower_32_bits(bm_pool->dma_addr)); mvpp2_write(priv, MVPP2_BM_POOL_SIZE_REG(bm_pool->id), size); val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id)); @@ -2337,17 +2469,20 @@ static int mvpp2_bm_init(struct udevice *dev, struct mvpp2 *priv) static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port, int lrxq, int long_pool) { - u32 val; + u32 val, mask; int prxq; /* Get queue physical ID */ prxq = port->rxqs[lrxq]->id; - val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq)); - val &= ~MVPP2_RXQ_POOL_LONG_MASK; - val |= ((long_pool << MVPP2_RXQ_POOL_LONG_OFFS) & - MVPP2_RXQ_POOL_LONG_MASK); + if (port->priv->hw_version == MVPP21) + mask = MVPP21_RXQ_POOL_LONG_MASK; + else + mask = MVPP22_RXQ_POOL_LONG_MASK; + val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq)); + val &= ~mask; + val |= (long_pool << MVPP2_RXQ_POOL_LONG_OFFS) & mask; mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val); } @@ -2363,26 +2498,48 @@ static inline u32 mvpp2_bm_cookie_pool_set(u32 cookie, int pool) } /* Get pool number from a BM cookie */ -static inline int mvpp2_bm_cookie_pool_get(u32 cookie) +static inline int mvpp2_bm_cookie_pool_get(unsigned long cookie) { return (cookie >> MVPP2_BM_COOKIE_POOL_OFFS) & 0xFF; } /* Release buffer to BM */ static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool, - u32 buf_phys_addr, u32 buf_virt_addr) + dma_addr_t buf_dma_addr, + unsigned long buf_phys_addr) { - mvpp2_write(port->priv, MVPP2_BM_VIRT_RLS_REG, buf_virt_addr); - mvpp2_write(port->priv, MVPP2_BM_PHY_RLS_REG(pool), buf_phys_addr); + if (port->priv->hw_version == MVPP22) { + u32 val = 0; + + if (sizeof(dma_addr_t) == 8) + val |= upper_32_bits(buf_dma_addr) & + MVPP22_BM_ADDR_HIGH_PHYS_RLS_MASK; + + if (sizeof(phys_addr_t) == 8) + val |= (upper_32_bits(buf_phys_addr) + << MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT) & + MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK; + + mvpp2_write(port->priv, MVPP22_BM_ADDR_HIGH_RLS_REG, val); + } + + /* MVPP2_BM_VIRT_RLS_REG is not interpreted by HW, and simply + * returned in the "cookie" field of the RX + * descriptor. Instead of storing the virtual address, we + * store the physical address + */ + mvpp2_write(port->priv, MVPP2_BM_VIRT_RLS_REG, buf_phys_addr); + mvpp2_write(port->priv, MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr); } /* Refill BM pool */ static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm, - u32 phys_addr, u32 cookie) + dma_addr_t dma_addr, + phys_addr_t phys_addr) { int pool = mvpp2_bm_cookie_pool_get(bm); - mvpp2_bm_pool_put(port, pool, phys_addr, cookie); + mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); } /* Allocate buffers for the pool */ @@ -2390,7 +2547,6 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port, struct mvpp2_bm_pool *bm_pool, int buf_num) { int i; - u32 bm; if (buf_num < 0 || (buf_num + bm_pool->buf_num > bm_pool->size)) { @@ -2400,10 +2556,11 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port, return 0; } - bm = mvpp2_bm_cookie_pool_set(0, bm_pool->id); for (i = 0; i < buf_num; i++) { - mvpp2_pool_refill(port, bm, (u32)buffer_loc.rx_buffer[i], - (u32)buffer_loc.rx_buffer[i]); + mvpp2_bm_pool_put(port, bm_pool->id, + (dma_addr_t)buffer_loc.rx_buffer[i], + (unsigned long)buffer_loc.rx_buffer[i]); + } /* Update BM driver with number of buffers added to pool */ @@ -2598,16 +2755,18 @@ static void mvpp2_defaults_set(struct mvpp2_port *port) { int tx_port_num, val, queue, ptxq, lrxq; - /* Configure port to loopback if needed */ - if (port->flags & MVPP2_F_LOOPBACK) - mvpp2_port_loopback_set(port); - - /* Update TX FIFO MIN Threshold */ - val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG); - val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK; - /* Min. TX threshold must be less than minimal packet length */ - val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(64 - 4 - 2); - writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG); + if (port->priv->hw_version == MVPP21) { + /* Configure port to loopback if needed */ + if (port->flags & MVPP2_F_LOOPBACK) + mvpp2_port_loopback_set(port); + + /* Update TX FIFO MIN Threshold */ + val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG); + val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK; + /* Min. TX threshold must be less than minimal packet length */ + val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(64 - 4 - 2); + writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG); + } /* Disable Legacy WRR, Disable EJP, Release from reset */ tx_port_num = mvpp2_egress_port(port); @@ -2791,11 +2950,15 @@ static void mvpp2_rxq_offset_set(struct mvpp2_port *port, } /* Obtain BM cookie information from descriptor */ -static u32 mvpp2_bm_cookie_build(struct mvpp2_rx_desc *rx_desc) +static u32 mvpp2_bm_cookie_build(struct mvpp2_port *port, + struct mvpp2_rx_desc *rx_desc) { - int pool = (rx_desc->status & MVPP2_RXD_BM_POOL_ID_MASK) >> - MVPP2_RXD_BM_POOL_ID_OFFS; int cpu = smp_processor_id(); + int pool; + + pool = (mvpp2_rxdesc_status_get(port, rx_desc) & + MVPP2_RXD_BM_POOL_ID_MASK) >> + MVPP2_RXD_BM_POOL_ID_OFFS; return ((pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS) | ((cpu & 0xFF) << MVPP2_BM_COOKIE_CPU_OFFS); @@ -2946,7 +3109,7 @@ static int mvpp2_aggr_txq_init(struct udevice *dev, { /* Allocate memory for TX descriptors */ aggr_txq->descs = buffer_loc.aggr_tx_descs; - aggr_txq->descs_phys = (dma_addr_t)buffer_loc.aggr_tx_descs; + aggr_txq->descs_dma = (dma_addr_t)buffer_loc.aggr_tx_descs; if (!aggr_txq->descs) return -ENOMEM; @@ -2963,7 +3126,7 @@ static int mvpp2_aggr_txq_init(struct udevice *dev, /* Set Tx descriptors queue starting address */ /* indirect access */ mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu), - aggr_txq->descs_phys); + aggr_txq->descs_dma); mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_SIZE_REG(cpu), desc_num); return 0; @@ -2978,7 +3141,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port, /* Allocate memory for RX descriptors */ rxq->descs = buffer_loc.rx_descs; - rxq->descs_phys = (dma_addr_t)buffer_loc.rx_descs; + rxq->descs_dma = (dma_addr_t)buffer_loc.rx_descs; if (!rxq->descs) return -ENOMEM; @@ -2992,7 +3155,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port, /* Set Rx descriptors queue starting address - indirect access */ mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id); - mvpp2_write(port->priv, MVPP2_RXQ_DESC_ADDR_REG, rxq->descs_phys); + mvpp2_write(port->priv, MVPP2_RXQ_DESC_ADDR_REG, rxq->descs_dma); mvpp2_write(port->priv, MVPP2_RXQ_DESC_SIZE_REG, rxq->size); mvpp2_write(port->priv, MVPP2_RXQ_INDEX_REG, 0); @@ -3017,10 +3180,11 @@ static void mvpp2_rxq_drop_pkts(struct mvpp2_port *port, for (i = 0; i < rx_received; i++) { struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq); - u32 bm = mvpp2_bm_cookie_build(rx_desc); + u32 bm = mvpp2_bm_cookie_build(port, rx_desc); - mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr, - rx_desc->buf_cookie); + mvpp2_pool_refill(port, bm, + mvpp2_rxdesc_dma_addr_get(port, rx_desc), + mvpp2_rxdesc_cookie_get(port, rx_desc)); } mvpp2_rxq_status_update(port, rxq->id, rx_received, rx_received); } @@ -3034,7 +3198,7 @@ static void mvpp2_rxq_deinit(struct mvpp2_port *port, rxq->descs = NULL; rxq->last_desc = 0; rxq->next_desc_to_proc = 0; - rxq->descs_phys = 0; + rxq->descs_dma = 0; /* Clear Rx descriptors queue starting address and size; * free descriptor number @@ -3057,7 +3221,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port, /* Allocate memory for Tx descriptors */ txq->descs = buffer_loc.tx_descs; - txq->descs_phys = (dma_addr_t)buffer_loc.tx_descs; + txq->descs_dma = (dma_addr_t)buffer_loc.tx_descs; if (!txq->descs) return -ENOMEM; @@ -3069,7 +3233,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port, /* Set Tx descriptors queue starting address - indirect access */ mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id); - mvpp2_write(port->priv, MVPP2_TXQ_DESC_ADDR_REG, txq->descs_phys); + mvpp2_write(port->priv, MVPP2_TXQ_DESC_ADDR_REG, txq->descs_dma); mvpp2_write(port->priv, MVPP2_TXQ_DESC_SIZE_REG, txq->size & MVPP2_TXQ_DESC_SIZE_MASK); mvpp2_write(port->priv, MVPP2_TXQ_INDEX_REG, 0); @@ -3121,7 +3285,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port, txq->descs = NULL; txq->last_desc = 0; txq->next_desc_to_proc = 0; - txq->descs_phys = 0; + txq->descs_dma = 0; /* Set minimum bandwidth for disabled TXQs */ mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0); @@ -3314,20 +3478,21 @@ static void mvpp2_link_event(struct mvpp2_port *port) static void mvpp2_rx_error(struct mvpp2_port *port, struct mvpp2_rx_desc *rx_desc) { - u32 status = rx_desc->status; + u32 status = mvpp2_rxdesc_status_get(port, rx_desc); + size_t sz = mvpp2_rxdesc_size_get(port, rx_desc); switch (status & MVPP2_RXD_ERR_CODE_MASK) { case MVPP2_RXD_ERR_CRC: - netdev_err(port->dev, "bad rx status %08x (crc error), size=%d\n", - status, rx_desc->data_size); + netdev_err(port->dev, "bad rx status %08x (crc error), size=%zu\n", + status, sz); break; case MVPP2_RXD_ERR_OVERRUN: - netdev_err(port->dev, "bad rx status %08x (overrun error), size=%d\n", - status, rx_desc->data_size); + netdev_err(port->dev, "bad rx status %08x (overrun error), size=%zu\n", + status, sz); break; case MVPP2_RXD_ERR_RESOURCE: - netdev_err(port->dev, "bad rx status %08x (resource error), size=%d\n", - status, rx_desc->data_size); + netdev_err(port->dev, "bad rx status %08x (resource error), size=%zu\n", + status, sz); break; } } @@ -3335,9 +3500,9 @@ static void mvpp2_rx_error(struct mvpp2_port *port, /* Reuse skb if possible, or allocate a new skb and add it to BM pool */ static int mvpp2_rx_refill(struct mvpp2_port *port, struct mvpp2_bm_pool *bm_pool, - u32 bm, u32 phys_addr) + u32 bm, dma_addr_t dma_addr) { - mvpp2_pool_refill(port, bm, phys_addr, phys_addr); + mvpp2_pool_refill(port, bm, dma_addr, (unsigned long)dma_addr); return 0; } @@ -3856,7 +4021,7 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) struct mvpp2_port *port = dev_get_priv(dev); struct mvpp2_rx_desc *rx_desc; struct mvpp2_bm_pool *bm_pool; - dma_addr_t phys_addr; + dma_addr_t dma_addr; u32 bm, rx_status; int pool, rx_bytes, err; int rx_received; @@ -3885,18 +4050,15 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) return 0; rx_desc = mvpp2_rxq_next_desc_get(rxq); - rx_status = rx_desc->status; - rx_bytes = rx_desc->data_size - MVPP2_MH_SIZE; - phys_addr = rx_desc->buf_phys_addr; + rx_status = mvpp2_rxdesc_status_get(port, rx_desc); + rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc); + rx_bytes -= MVPP2_MH_SIZE; + dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc); - bm = mvpp2_bm_cookie_build(rx_desc); + bm = mvpp2_bm_cookie_build(port, rx_desc); pool = mvpp2_bm_cookie_pool_get(bm); bm_pool = &port->priv->bm_pools[pool]; - /* Check if buffer header is used */ - if (rx_status & MVPP2_RXD_BUF_HDR) - return 0; - /* In case of an error, release the requested buffer pointer * to the Buffer Manager. This request process is controlled * by the hardware, and the information about the buffer is @@ -3905,12 +4067,11 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) if (rx_status & MVPP2_RXD_ERR_SUMMARY) { mvpp2_rx_error(port, rx_desc); /* Return the buffer to the pool */ - mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr, - rx_desc->buf_cookie); + mvpp2_pool_refill(port, bm, dma_addr, dma_addr); return 0; } - err = mvpp2_rx_refill(port, bm_pool, bm, phys_addr); + err = mvpp2_rx_refill(port, bm_pool, bm, dma_addr); if (err) { netdev_err(port->dev, "failed to refill BM pools\n"); return 0; @@ -3921,7 +4082,7 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) mvpp2_rxq_status_update(port, rxq->id, 1, 1); /* give packet to stack - skip on first n bytes */ - data = (u8 *)phys_addr + 2 + 32; + data = (u8 *)dma_addr + 2 + 32; if (rx_bytes <= 0) return 0; @@ -3963,16 +4124,20 @@ static int mvpp2_send(struct udevice *dev, void *packet, int length) /* Get a descriptor for the first part of the packet */ tx_desc = mvpp2_txq_next_desc_get(aggr_txq); - tx_desc->phys_txq = txq->id; - tx_desc->data_size = length; - tx_desc->packet_offset = (u32)packet & MVPP2_TX_DESC_ALIGN; - tx_desc->buf_phys_addr = (u32)packet & ~MVPP2_TX_DESC_ALIGN; + mvpp2_txdesc_txq_set(port, tx_desc, txq->id); + mvpp2_txdesc_size_set(port, tx_desc, length); + mvpp2_txdesc_offset_set(port, tx_desc, + (dma_addr_t)packet & MVPP2_TX_DESC_ALIGN); + mvpp2_txdesc_dma_addr_set(port, tx_desc, + (dma_addr_t)packet & ~MVPP2_TX_DESC_ALIGN); /* First and Last descriptor */ - tx_desc->command = MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE - | MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC; + mvpp2_txdesc_cmd_set(port, tx_desc, + MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE + | MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC); /* Flush tx data */ - flush_dcache_range((u32)packet, (u32)packet + length); + flush_dcache_range((unsigned long)packet, + (unsigned long)packet + ALIGN(length, PKTALIGN)); /* Enable transmit */ mb(); @@ -4079,6 +4244,9 @@ static int mvpp2_base_probe(struct udevice *dev) u32 size = 0; int i; + /* Save hw-version */ + priv->hw_version = dev_get_driver_data(dev); + /* * U-Boot special buffer handling: * @@ -4089,24 +4257,32 @@ static int mvpp2_base_probe(struct udevice *dev) /* Align buffer area for descs and rx_buffers to 1MiB */ bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE); - mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE, DCACHE_OFF); + mmu_set_region_dcache_behaviour((unsigned long)bd_space, + BD_SPACE, DCACHE_OFF); buffer_loc.aggr_tx_descs = (struct mvpp2_tx_desc *)bd_space; size += MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE; - buffer_loc.tx_descs = (struct mvpp2_tx_desc *)((u32)bd_space + size); + buffer_loc.tx_descs = + (struct mvpp2_tx_desc *)((unsigned long)bd_space + size); size += MVPP2_MAX_TXD * MVPP2_DESC_ALIGNED_SIZE; - buffer_loc.rx_descs = (struct mvpp2_rx_desc *)((u32)bd_space + size); + buffer_loc.rx_descs = + (struct mvpp2_rx_desc *)((unsigned long)bd_space + size); size += MVPP2_MAX_RXD * MVPP2_DESC_ALIGNED_SIZE; for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { - buffer_loc.bm_pool[i] = (u32 *)((u32)bd_space + size); - size += MVPP2_BM_POOL_SIZE_MAX * sizeof(u32); + buffer_loc.bm_pool[i] = + (unsigned long *)((unsigned long)bd_space + size); + if (priv->hw_version == MVPP21) + size += MVPP2_BM_POOL_SIZE_MAX * 2 * sizeof(u32); + else + size += MVPP2_BM_POOL_SIZE_MAX * 2 * sizeof(u64); } for (i = 0; i < MVPP2_BM_LONG_BUF_NUM; i++) { - buffer_loc.rx_buffer[i] = (u32 *)((u32)bd_space + size); + buffer_loc.rx_buffer[i] = + (unsigned long *)((unsigned long)bd_space + size); size += RX_BUFFER_SIZE; } @@ -4176,7 +4352,10 @@ static int mvpp2_base_bind(struct udevice *parent) } static const struct udevice_id mvpp2_ids[] = { - { .compatible = "marvell,armada-375-pp2" }, + { + .compatible = "marvell,armada-375-pp2", + .data = MVPP21, + }, { } };