mirror of https://gitee.com/openkylin/linux.git
drivers: net: xgene: Add support for Jumbo frame
This patch adds support for jumbo frame, by allocating additional buffer (page) pool and configuring the hardware. Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> Signed-off-by: Quan Nguyen <qnguyen@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d6d489694f
commit
a9380b0f7b
|
@ -679,6 +679,9 @@ static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
|
|||
for (i = 0; i < pdata->rxq_cnt; i++) {
|
||||
ring = pdata->rx_ring[i]->buf_pool;
|
||||
pb |= BIT(xgene_enet_get_fpsel(ring->id));
|
||||
ring = pdata->rx_ring[i]->page_pool;
|
||||
if (ring)
|
||||
pb |= BIT(xgene_enet_get_fpsel(ring->id));
|
||||
|
||||
}
|
||||
xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPRESET_ADDR, pb);
|
||||
|
|
|
@ -37,6 +37,9 @@ static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
|
|||
struct xgene_enet_raw_desc16 *raw_desc;
|
||||
int i;
|
||||
|
||||
if (!buf_pool)
|
||||
return;
|
||||
|
||||
for (i = 0; i < buf_pool->slots; i++) {
|
||||
raw_desc = &buf_pool->raw_desc16[i];
|
||||
|
||||
|
@ -47,6 +50,86 @@ static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
|
|||
}
|
||||
}
|
||||
|
||||
static u16 xgene_enet_get_data_len(u64 bufdatalen)
|
||||
{
|
||||
u16 hw_len, mask;
|
||||
|
||||
hw_len = GET_VAL(BUFDATALEN, bufdatalen);
|
||||
|
||||
if (unlikely(hw_len == 0x7800)) {
|
||||
return 0;
|
||||
} else if (!(hw_len & BIT(14))) {
|
||||
mask = GENMASK(13, 0);
|
||||
return (hw_len & mask) ? (hw_len & mask) : SIZE_16K;
|
||||
} else if (!(hw_len & GENMASK(13, 12))) {
|
||||
mask = GENMASK(11, 0);
|
||||
return (hw_len & mask) ? (hw_len & mask) : SIZE_4K;
|
||||
} else {
|
||||
mask = GENMASK(11, 0);
|
||||
return (hw_len & mask) ? (hw_len & mask) : SIZE_2K;
|
||||
}
|
||||
}
|
||||
|
||||
static u16 xgene_enet_set_data_len(u32 size)
|
||||
{
|
||||
u16 hw_len;
|
||||
|
||||
hw_len = (size == SIZE_4K) ? BIT(14) : 0;
|
||||
|
||||
return hw_len;
|
||||
}
|
||||
|
||||
static int xgene_enet_refill_pagepool(struct xgene_enet_desc_ring *buf_pool,
|
||||
u32 nbuf)
|
||||
{
|
||||
struct xgene_enet_raw_desc16 *raw_desc;
|
||||
struct xgene_enet_pdata *pdata;
|
||||
struct net_device *ndev;
|
||||
dma_addr_t dma_addr;
|
||||
struct device *dev;
|
||||
struct page *page;
|
||||
u32 slots, tail;
|
||||
u16 hw_len;
|
||||
int i;
|
||||
|
||||
if (unlikely(!buf_pool))
|
||||
return 0;
|
||||
|
||||
ndev = buf_pool->ndev;
|
||||
pdata = netdev_priv(ndev);
|
||||
dev = ndev_to_dev(ndev);
|
||||
slots = buf_pool->slots - 1;
|
||||
tail = buf_pool->tail;
|
||||
|
||||
for (i = 0; i < nbuf; i++) {
|
||||
raw_desc = &buf_pool->raw_desc16[tail];
|
||||
|
||||
page = dev_alloc_page();
|
||||
if (unlikely(!page))
|
||||
return -ENOMEM;
|
||||
|
||||
dma_addr = dma_map_page(dev, page, 0,
|
||||
PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
if (unlikely(dma_mapping_error(dev, dma_addr))) {
|
||||
put_page(page);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hw_len = xgene_enet_set_data_len(PAGE_SIZE);
|
||||
raw_desc->m1 = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |
|
||||
SET_VAL(BUFDATALEN, hw_len) |
|
||||
SET_BIT(COHERENT));
|
||||
|
||||
buf_pool->frag_page[tail] = page;
|
||||
tail = (tail + 1) & slots;
|
||||
}
|
||||
|
||||
pdata->ring_ops->wr_cmd(buf_pool, nbuf);
|
||||
buf_pool->tail = tail;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgene_enet_refill_bufpool(struct xgene_enet_desc_ring *buf_pool,
|
||||
u32 nbuf)
|
||||
{
|
||||
|
@ -64,8 +147,9 @@ static int xgene_enet_refill_bufpool(struct xgene_enet_desc_ring *buf_pool,
|
|||
ndev = buf_pool->ndev;
|
||||
dev = ndev_to_dev(buf_pool->ndev);
|
||||
pdata = netdev_priv(ndev);
|
||||
|
||||
bufdatalen = BUF_LEN_CODE_2K | (SKB_BUFFER_SIZE & GENMASK(11, 0));
|
||||
len = XGENE_ENET_MAX_MTU;
|
||||
len = XGENE_ENET_STD_MTU;
|
||||
|
||||
for (i = 0; i < nbuf; i++) {
|
||||
raw_desc = &buf_pool->raw_desc16[tail];
|
||||
|
@ -122,6 +206,25 @@ static void xgene_enet_delete_bufpool(struct xgene_enet_desc_ring *buf_pool)
|
|||
}
|
||||
}
|
||||
|
||||
static void xgene_enet_delete_pagepool(struct xgene_enet_desc_ring *buf_pool)
|
||||
{
|
||||
struct device *dev = ndev_to_dev(buf_pool->ndev);
|
||||
dma_addr_t dma_addr;
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
/* Free up the buffers held by hardware */
|
||||
for (i = 0; i < buf_pool->slots; i++) {
|
||||
page = buf_pool->frag_page[i];
|
||||
if (page) {
|
||||
dma_addr = buf_pool->frag_dma_addr[i];
|
||||
dma_unmap_page(dev, dma_addr, PAGE_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
put_page(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t xgene_enet_rx_irq(const int irq, void *data)
|
||||
{
|
||||
struct xgene_enet_desc_ring *rx_ring = data;
|
||||
|
@ -515,23 +618,66 @@ static void xgene_enet_skip_csum(struct sk_buff *skb)
|
|||
}
|
||||
}
|
||||
|
||||
static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
||||
struct xgene_enet_raw_desc *raw_desc)
|
||||
static void xgene_enet_free_pagepool(struct xgene_enet_desc_ring *buf_pool,
|
||||
struct xgene_enet_raw_desc *raw_desc,
|
||||
struct xgene_enet_raw_desc *exp_desc)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
__le64 *desc = (void *)exp_desc;
|
||||
dma_addr_t dma_addr;
|
||||
struct device *dev;
|
||||
struct xgene_enet_desc_ring *buf_pool;
|
||||
u32 datalen, skb_index;
|
||||
struct page *page;
|
||||
u16 slots, head;
|
||||
u32 frag_size;
|
||||
int i;
|
||||
|
||||
if (!buf_pool || !raw_desc || !exp_desc ||
|
||||
(!GET_VAL(NV, le64_to_cpu(raw_desc->m0))))
|
||||
return;
|
||||
|
||||
dev = ndev_to_dev(buf_pool->ndev);
|
||||
head = buf_pool->head;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
frag_size = xgene_enet_get_data_len(le64_to_cpu(desc[i ^ 1]));
|
||||
if (!frag_size)
|
||||
break;
|
||||
|
||||
dma_addr = GET_VAL(DATAADDR, le64_to_cpu(desc[i ^ 1]));
|
||||
dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
|
||||
page = buf_pool->frag_page[head];
|
||||
put_page(page);
|
||||
|
||||
buf_pool->frag_page[head] = NULL;
|
||||
head = (head + 1) & slots;
|
||||
}
|
||||
buf_pool->head = head;
|
||||
}
|
||||
|
||||
static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
||||
struct xgene_enet_raw_desc *raw_desc,
|
||||
struct xgene_enet_raw_desc *exp_desc)
|
||||
{
|
||||
struct xgene_enet_desc_ring *buf_pool, *page_pool;
|
||||
u32 datalen, frag_size, skb_index;
|
||||
struct net_device *ndev;
|
||||
dma_addr_t dma_addr;
|
||||
struct sk_buff *skb;
|
||||
struct device *dev;
|
||||
struct page *page;
|
||||
u16 slots, head;
|
||||
int i, ret = 0;
|
||||
__le64 *desc;
|
||||
u8 status;
|
||||
int ret = 0;
|
||||
bool nv;
|
||||
|
||||
ndev = rx_ring->ndev;
|
||||
dev = ndev_to_dev(rx_ring->ndev);
|
||||
buf_pool = rx_ring->buf_pool;
|
||||
page_pool = rx_ring->page_pool;
|
||||
|
||||
dma_unmap_single(dev, GET_VAL(DATAADDR, le64_to_cpu(raw_desc->m1)),
|
||||
XGENE_ENET_MAX_MTU, DMA_FROM_DEVICE);
|
||||
XGENE_ENET_STD_MTU, DMA_FROM_DEVICE);
|
||||
skb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0));
|
||||
skb = buf_pool->rx_skb[skb_index];
|
||||
buf_pool->rx_skb[skb_index] = NULL;
|
||||
|
@ -541,6 +687,7 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
|||
GET_VAL(LERR, le64_to_cpu(raw_desc->m0));
|
||||
if (unlikely(status > 2)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
xgene_enet_free_pagepool(page_pool, raw_desc, exp_desc);
|
||||
xgene_enet_parse_error(rx_ring, netdev_priv(rx_ring->ndev),
|
||||
status);
|
||||
ret = -EIO;
|
||||
|
@ -548,11 +695,44 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
|||
}
|
||||
|
||||
/* strip off CRC as HW isn't doing this */
|
||||
datalen = GET_VAL(BUFDATALEN, le64_to_cpu(raw_desc->m1));
|
||||
datalen = (datalen & DATALEN_MASK) - 4;
|
||||
prefetch(skb->data - NET_IP_ALIGN);
|
||||
skb_put(skb, datalen);
|
||||
datalen = xgene_enet_get_data_len(le64_to_cpu(raw_desc->m1));
|
||||
|
||||
nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0));
|
||||
if (!nv)
|
||||
datalen -= 4;
|
||||
|
||||
skb_put(skb, datalen);
|
||||
prefetch(skb->data - NET_IP_ALIGN);
|
||||
|
||||
if (!nv)
|
||||
goto skip_jumbo;
|
||||
|
||||
slots = page_pool->slots - 1;
|
||||
head = page_pool->head;
|
||||
desc = (void *)exp_desc;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
frag_size = xgene_enet_get_data_len(le64_to_cpu(desc[i ^ 1]));
|
||||
if (!frag_size)
|
||||
break;
|
||||
|
||||
dma_addr = GET_VAL(DATAADDR, le64_to_cpu(desc[i ^ 1]));
|
||||
dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
|
||||
page = page_pool->frag_page[head];
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0,
|
||||
frag_size, PAGE_SIZE);
|
||||
|
||||
datalen += frag_size;
|
||||
|
||||
page_pool->frag_page[head] = NULL;
|
||||
head = (head + 1) & slots;
|
||||
}
|
||||
|
||||
page_pool->head = head;
|
||||
rx_ring->npagepool -= skb_shinfo(skb)->nr_frags;
|
||||
|
||||
skip_jumbo:
|
||||
skb_checksum_none_assert(skb);
|
||||
skb->protocol = eth_type_trans(skb, ndev);
|
||||
if (likely((ndev->features & NETIF_F_IP_CSUM) &&
|
||||
|
@ -563,7 +743,15 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
|||
rx_ring->rx_packets++;
|
||||
rx_ring->rx_bytes += datalen;
|
||||
napi_gro_receive(&rx_ring->napi, skb);
|
||||
|
||||
out:
|
||||
if (rx_ring->npagepool <= 0) {
|
||||
ret = xgene_enet_refill_pagepool(page_pool, NUM_NXTBUFPOOL);
|
||||
rx_ring->npagepool = NUM_NXTBUFPOOL;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (--rx_ring->nbufpool == 0) {
|
||||
ret = xgene_enet_refill_bufpool(buf_pool, NUM_BUFPOOL);
|
||||
rx_ring->nbufpool = NUM_BUFPOOL;
|
||||
|
@ -611,7 +799,7 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
|
|||
desc_count++;
|
||||
}
|
||||
if (is_rx_desc(raw_desc)) {
|
||||
ret = xgene_enet_rx_frame(ring, raw_desc);
|
||||
ret = xgene_enet_rx_frame(ring, raw_desc, exp_desc);
|
||||
} else {
|
||||
ret = xgene_enet_tx_completion(ring, raw_desc);
|
||||
is_completion = true;
|
||||
|
@ -854,7 +1042,7 @@ static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring)
|
|||
|
||||
static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct xgene_enet_desc_ring *buf_pool;
|
||||
struct xgene_enet_desc_ring *buf_pool, *page_pool;
|
||||
struct xgene_enet_desc_ring *ring;
|
||||
int i;
|
||||
|
||||
|
@ -867,18 +1055,28 @@ static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)
|
|||
xgene_enet_delete_ring(ring->cp_ring);
|
||||
pdata->tx_ring[i] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < pdata->rxq_cnt; i++) {
|
||||
ring = pdata->rx_ring[i];
|
||||
if (ring) {
|
||||
page_pool = ring->page_pool;
|
||||
if (page_pool) {
|
||||
xgene_enet_delete_pagepool(page_pool);
|
||||
xgene_enet_delete_ring(page_pool);
|
||||
pdata->port_ops->clear(pdata, page_pool);
|
||||
}
|
||||
|
||||
buf_pool = ring->buf_pool;
|
||||
xgene_enet_delete_bufpool(buf_pool);
|
||||
xgene_enet_delete_ring(buf_pool);
|
||||
pdata->port_ops->clear(pdata, buf_pool);
|
||||
|
||||
xgene_enet_delete_ring(ring);
|
||||
pdata->rx_ring[i] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -931,8 +1129,10 @@ static void xgene_enet_free_desc_ring(struct xgene_enet_desc_ring *ring)
|
|||
|
||||
static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct xgene_enet_desc_ring *page_pool;
|
||||
struct device *dev = &pdata->pdev->dev;
|
||||
struct xgene_enet_desc_ring *ring;
|
||||
void *p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pdata->txq_cnt; i++) {
|
||||
|
@ -940,10 +1140,13 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
|
|||
if (ring) {
|
||||
if (ring->cp_ring && ring->cp_ring->cp_skb)
|
||||
devm_kfree(dev, ring->cp_ring->cp_skb);
|
||||
|
||||
if (ring->cp_ring && pdata->cq_cnt)
|
||||
xgene_enet_free_desc_ring(ring->cp_ring);
|
||||
|
||||
xgene_enet_free_desc_ring(ring);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < pdata->rxq_cnt; i++) {
|
||||
|
@ -952,8 +1155,21 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
|
|||
if (ring->buf_pool) {
|
||||
if (ring->buf_pool->rx_skb)
|
||||
devm_kfree(dev, ring->buf_pool->rx_skb);
|
||||
|
||||
xgene_enet_free_desc_ring(ring->buf_pool);
|
||||
}
|
||||
|
||||
page_pool = ring->page_pool;
|
||||
if (page_pool) {
|
||||
p = page_pool->frag_page;
|
||||
if (p)
|
||||
devm_kfree(dev, p);
|
||||
|
||||
p = page_pool->frag_dma_addr;
|
||||
if (p)
|
||||
devm_kfree(dev, p);
|
||||
}
|
||||
|
||||
xgene_enet_free_desc_ring(ring);
|
||||
}
|
||||
}
|
||||
|
@ -1071,19 +1287,20 @@ static u8 xgene_start_cpu_bufnum(struct xgene_enet_pdata *pdata)
|
|||
|
||||
static int xgene_enet_create_desc_rings(struct net_device *ndev)
|
||||
{
|
||||
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
|
||||
struct device *dev = ndev_to_dev(ndev);
|
||||
struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring;
|
||||
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
|
||||
struct xgene_enet_desc_ring *page_pool = NULL;
|
||||
struct xgene_enet_desc_ring *buf_pool = NULL;
|
||||
enum xgene_ring_owner owner;
|
||||
dma_addr_t dma_exp_bufs;
|
||||
u8 cpu_bufnum;
|
||||
struct device *dev = ndev_to_dev(ndev);
|
||||
u8 eth_bufnum = pdata->eth_bufnum;
|
||||
u8 bp_bufnum = pdata->bp_bufnum;
|
||||
u16 ring_num = pdata->ring_num;
|
||||
enum xgene_ring_owner owner;
|
||||
dma_addr_t dma_exp_bufs;
|
||||
u16 ring_id, slots;
|
||||
__le64 *exp_bufs;
|
||||
u16 ring_id;
|
||||
int i, ret, size;
|
||||
u8 cpu_bufnum;
|
||||
|
||||
cpu_bufnum = xgene_start_cpu_bufnum(pdata);
|
||||
|
||||
|
@ -1103,7 +1320,7 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
|
|||
owner = xgene_derive_ring_owner(pdata);
|
||||
ring_id = xgene_enet_get_ring_id(owner, bp_bufnum++);
|
||||
buf_pool = xgene_enet_create_desc_ring(ndev, ring_num++,
|
||||
RING_CFGSIZE_2KB,
|
||||
RING_CFGSIZE_16KB,
|
||||
ring_id);
|
||||
if (!buf_pool) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -1111,7 +1328,7 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
|
|||
}
|
||||
|
||||
rx_ring->nbufpool = NUM_BUFPOOL;
|
||||
rx_ring->buf_pool = buf_pool;
|
||||
rx_ring->npagepool = NUM_NXTBUFPOOL;
|
||||
rx_ring->irq = pdata->irqs[i];
|
||||
buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
|
||||
sizeof(struct sk_buff *),
|
||||
|
@ -1124,6 +1341,42 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
|
|||
buf_pool->dst_ring_num = xgene_enet_dst_ring_num(buf_pool);
|
||||
rx_ring->buf_pool = buf_pool;
|
||||
pdata->rx_ring[i] = rx_ring;
|
||||
|
||||
if ((pdata->enet_id == XGENE_ENET1 && pdata->rxq_cnt > 4) ||
|
||||
(pdata->enet_id == XGENE_ENET2 && pdata->rxq_cnt > 16)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate next buffer pool for jumbo packets */
|
||||
owner = xgene_derive_ring_owner(pdata);
|
||||
ring_id = xgene_enet_get_ring_id(owner, bp_bufnum++);
|
||||
page_pool = xgene_enet_create_desc_ring(ndev, ring_num++,
|
||||
RING_CFGSIZE_16KB,
|
||||
ring_id);
|
||||
if (!page_pool) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
slots = page_pool->slots;
|
||||
page_pool->frag_page = devm_kcalloc(dev, slots,
|
||||
sizeof(struct page *),
|
||||
GFP_KERNEL);
|
||||
if (!page_pool->frag_page) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
page_pool->frag_dma_addr = devm_kcalloc(dev, slots,
|
||||
sizeof(dma_addr_t),
|
||||
GFP_KERNEL);
|
||||
if (!page_pool->frag_dma_addr) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
page_pool->dst_ring_num = xgene_enet_dst_ring_num(page_pool);
|
||||
rx_ring->page_pool = page_pool;
|
||||
}
|
||||
|
||||
for (i = 0; i < pdata->txq_cnt; i++) {
|
||||
|
@ -1523,6 +1776,7 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
|
|||
struct xgene_enet_desc_ring *buf_pool;
|
||||
u16 dst_ring_num, ring_id;
|
||||
int i, ret;
|
||||
u32 count;
|
||||
|
||||
ret = pdata->port_ops->reset(pdata);
|
||||
if (ret)
|
||||
|
@ -1538,9 +1792,18 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
|
|||
for (i = 0; i < pdata->rxq_cnt; i++) {
|
||||
buf_pool = pdata->rx_ring[i]->buf_pool;
|
||||
xgene_enet_init_bufpool(buf_pool);
|
||||
ret = xgene_enet_refill_bufpool(buf_pool, pdata->rx_buff_cnt);
|
||||
page_pool = pdata->rx_ring[i]->page_pool;
|
||||
xgene_enet_init_bufpool(page_pool);
|
||||
|
||||
count = pdata->rx_buff_cnt;
|
||||
ret = xgene_enet_refill_bufpool(buf_pool, count);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = xgene_enet_refill_pagepool(page_pool, count);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
}
|
||||
|
||||
dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
|
||||
|
|
|
@ -41,11 +41,14 @@
|
|||
#include "../../../phy/mdio-xgene.h"
|
||||
|
||||
#define XGENE_DRV_VERSION "v1.0"
|
||||
#define XGENE_ENET_MAX_MTU 1536
|
||||
#define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN)
|
||||
#define XGENE_ENET_STD_MTU 1536
|
||||
#define XGENE_ENET_MAX_MTU 9600
|
||||
#define SKB_BUFFER_SIZE (XGENE_ENET_STD_MTU - NET_IP_ALIGN)
|
||||
|
||||
#define BUFLEN_16K (16 * 1024)
|
||||
#define NUM_PKT_BUF 64
|
||||
#define NUM_PKT_BUF 1024
|
||||
#define NUM_BUFPOOL 32
|
||||
#define NUM_NXTBUFPOOL 8
|
||||
#define MAX_EXP_BUFFS 256
|
||||
#define NUM_MSS_REG 4
|
||||
#define XGENE_MIN_ENET_FRAME_SIZE 60
|
||||
|
@ -88,6 +91,12 @@ enum xgene_enet_id {
|
|||
XGENE_ENET2
|
||||
};
|
||||
|
||||
enum xgene_enet_buf_len {
|
||||
SIZE_2K = 2048,
|
||||
SIZE_4K = 4096,
|
||||
SIZE_16K = 16384
|
||||
};
|
||||
|
||||
/* software context of a descriptor ring */
|
||||
struct xgene_enet_desc_ring {
|
||||
struct net_device *ndev;
|
||||
|
@ -107,11 +116,14 @@ struct xgene_enet_desc_ring {
|
|||
dma_addr_t irq_mbox_dma;
|
||||
void *irq_mbox_addr;
|
||||
u16 dst_ring_num;
|
||||
u8 nbufpool;
|
||||
u16 nbufpool;
|
||||
int npagepool;
|
||||
u8 index;
|
||||
u32 flags;
|
||||
struct sk_buff *(*rx_skb);
|
||||
struct sk_buff *(*cp_skb);
|
||||
dma_addr_t *frag_dma_addr;
|
||||
struct page *(*frag_page);
|
||||
enum xgene_enet_ring_cfgsize cfgsize;
|
||||
struct xgene_enet_desc_ring *cp_ring;
|
||||
struct xgene_enet_desc_ring *buf_pool;
|
||||
|
|
|
@ -119,6 +119,7 @@ static void xgene_enet_set_ring_id(struct xgene_enet_desc_ring *ring)
|
|||
|
||||
ring_id_buf = (ring->num << 9) & GENMASK(18, 9);
|
||||
ring_id_buf |= PREFETCH_BUF_EN;
|
||||
|
||||
if (is_bufpool)
|
||||
ring_id_buf |= IS_BUFFER_POOL;
|
||||
|
||||
|
|
|
@ -536,6 +536,9 @@ static void xgene_enet_shutdown(struct xgene_enet_pdata *p)
|
|||
for (i = 0; i < p->rxq_cnt; i++) {
|
||||
ring = p->rx_ring[i]->buf_pool;
|
||||
pb |= BIT(xgene_enet_get_fpsel(ring->id));
|
||||
ring = p->rx_ring[i]->page_pool;
|
||||
if (ring)
|
||||
pb |= BIT(xgene_enet_get_fpsel(ring->id));
|
||||
}
|
||||
xgene_enet_wr_ring_if(p, ENET_CFGSSQMIFPRESET_ADDR, pb);
|
||||
|
||||
|
|
|
@ -367,6 +367,7 @@ static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata,
|
|||
CFG_CLE_FPSEL0_SET(&cb, fpsel);
|
||||
CFG_CLE_NXTFPSEL0_SET(&cb, nxtfpsel);
|
||||
xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG1_ADDR, cb);
|
||||
pr_info("+ cle_bypass: fpsel: %d nxtfpsel: %d\n", fpsel, nxtfpsel);
|
||||
}
|
||||
|
||||
static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
|
||||
|
@ -380,6 +381,9 @@ static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
|
|||
for (i = 0; i < pdata->rxq_cnt; i++) {
|
||||
ring = pdata->rx_ring[i]->buf_pool;
|
||||
pb |= BIT(xgene_enet_get_fpsel(ring->id));
|
||||
ring = pdata->rx_ring[i]->page_pool;
|
||||
if (ring)
|
||||
pb |= BIT(xgene_enet_get_fpsel(ring->id));
|
||||
}
|
||||
xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPRESET_ADDR, pb);
|
||||
|
||||
|
|
Loading…
Reference in New Issue