static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata) { struct device *dev = &pdata->pdev->dev; struct xgene_enet_desc_ring *ring; u32 pb, val; int i; pb = 0; for (i = 0; i < pdata->rxq_cnt; i++) { ring = pdata->rx_ring[i]->buf_pool; val = xgene_enet_ring_bufnum(ring->id); pb |= BIT(val - 0x20); } xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPRESET_ADDR, pb); pb = 0; for (i = 0; i < pdata->txq_cnt; i++) { ring = pdata->tx_ring[i]; val = xgene_enet_ring_bufnum(ring->id); pb |= BIT(val); } xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQRESET_ADDR, pb); if (dev->of_node) { if (!IS_ERR(pdata->clk)) clk_disable_unprepare(pdata->clk); } }
static int xgene_cle_set_rss_idt(struct xgene_enet_pdata *pdata) { u32 fpsel, dstqid, nfpsel, idt_reg, idx; int i, ret = 0; u16 pool_id; for (i = 0; i < XGENE_CLE_IDT_ENTRIES; i++) { idx = i % pdata->rxq_cnt; pool_id = pdata->rx_ring[idx]->buf_pool->id; fpsel = xgene_enet_ring_bufnum(pool_id) - 0x20; dstqid = xgene_enet_dst_ring_num(pdata->rx_ring[idx]); nfpsel = 0; idt_reg = 0; xgene_cle_idt_to_hw(dstqid, fpsel, nfpsel, &idt_reg); ret = xgene_cle_dram_wr(&pdata->cle, &idt_reg, 1, i, RSS_IDT, CLE_CMD_WR); if (ret) return ret; } ret = xgene_cle_set_rss_skeys(&pdata->cle); if (ret) return ret; return 0; }
static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p, u32 dst_ring_num, u16 bufpool_id) { u32 data, fpsel; data = CFG_CLE_BYPASS_EN0; xgene_enet_wr_csr(p, CLE_BYPASS_REG0_0_ADDR, data); fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20; data = CFG_CLE_DSTQID0(dst_ring_num) | CFG_CLE_FPSEL0(fpsel); xgene_enet_wr_csr(p, CLE_BYPASS_REG1_0_ADDR, data); }
static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata, u32 dst_ring_num, u16 bufpool_id) { u32 cb, fpsel; xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG0_ADDR, &cb); cb |= CFG_CLE_BYPASS_EN0; CFG_CLE_IP_PROTOCOL0_SET(&cb, 3); xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG0_ADDR, cb); fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20; xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG1_ADDR, &cb); CFG_CLE_DSTQID0_SET(&cb, dst_ring_num); CFG_CLE_FPSEL0_SET(&cb, fpsel); xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG1_ADDR, cb); }
static void xgene_enet_clear(struct xgene_enet_pdata *pdata, struct xgene_enet_desc_ring *ring) { u32 addr, val, data; val = xgene_enet_ring_bufnum(ring->id); if (xgene_enet_is_bufpool(ring->id)) { addr = ENET_CFGSSQMIFPRESET_ADDR; data = BIT(val - 0x20); } else { addr = ENET_CFGSSQMIWQRESET_ADDR; data = BIT(val); } xgene_enet_wr_ring_if(pdata, addr, data); }
static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p, u32 dst_ring_num, u16 bufpool_id) { u32 data, fpsel; u32 cle_bypass_reg0, cle_bypass_reg1; u32 offset = p->port_id * MAC_OFFSET; if (p->enet_id == XGENE_ENET1) { cle_bypass_reg0 = CLE_BYPASS_REG0_0_ADDR; cle_bypass_reg1 = CLE_BYPASS_REG1_0_ADDR; } else { cle_bypass_reg0 = XCLE_BYPASS_REG0_ADDR; cle_bypass_reg1 = XCLE_BYPASS_REG1_ADDR; } data = CFG_CLE_BYPASS_EN0; xgene_enet_wr_csr(p, cle_bypass_reg0 + offset, data); fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20; data = CFG_CLE_DSTQID0(dst_ring_num) | CFG_CLE_FPSEL0(fpsel); xgene_enet_wr_csr(p, cle_bypass_reg1 + offset, data); }