diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.c | 156 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.h | 16 |
2 files changed, 119 insertions, 53 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 83c0cb323e0c..275be56fd324 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c | |||
@@ -1363,16 +1363,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) | |||
1363 | } | 1363 | } |
1364 | 1364 | ||
1365 | dma_unmap_addr_set(cb, dma_addr, mapping); | 1365 | dma_unmap_addr_set(cb, dma_addr, mapping); |
1366 | /* assign packet, prepare descriptor, and advance pointer */ | 1366 | dmadesc_set_addr(priv, cb->bd_addr, mapping); |
1367 | |||
1368 | dmadesc_set_addr(priv, priv->rx_bd_assign_ptr, mapping); | ||
1369 | |||
1370 | /* turn on the newly assigned BD for DMA to use */ | ||
1371 | priv->rx_bd_assign_index++; | ||
1372 | priv->rx_bd_assign_index &= (priv->num_rx_bds - 1); | ||
1373 | |||
1374 | priv->rx_bd_assign_ptr = priv->rx_bds + | ||
1375 | (priv->rx_bd_assign_index * DMA_DESC_SIZE); | ||
1376 | 1367 | ||
1377 | return 0; | 1368 | return 0; |
1378 | } | 1369 | } |
@@ -1381,8 +1372,10 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) | |||
1381 | * this could be called from bottom half, or from NAPI polling method. | 1372 | * this could be called from bottom half, or from NAPI polling method. |
1382 | */ | 1373 | */ |
1383 | static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, | 1374 | static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, |
1375 | unsigned int index, | ||
1384 | unsigned int budget) | 1376 | unsigned int budget) |
1385 | { | 1377 | { |
1378 | struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; | ||
1386 | struct net_device *dev = priv->dev; | 1379 | struct net_device *dev = priv->dev; |
1387 | struct enet_cb *cb; | 1380 | struct enet_cb *cb; |
1388 | struct sk_buff *skb; | 1381 | struct sk_buff *skb; |
@@ -1393,21 +1386,21 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, | |||
1393 | unsigned int p_index; | 1386 | unsigned int p_index; |
1394 | unsigned int chksum_ok = 0; | 1387 | unsigned int chksum_ok = 0; |
1395 | 1388 | ||
1396 | p_index = bcmgenet_rdma_ring_readl(priv, DESC_INDEX, RDMA_PROD_INDEX); | 1389 | p_index = bcmgenet_rdma_ring_readl(priv, index, RDMA_PROD_INDEX); |
1397 | p_index &= DMA_P_INDEX_MASK; | 1390 | p_index &= DMA_P_INDEX_MASK; |
1398 | 1391 | ||
1399 | if (p_index < priv->rx_c_index) | 1392 | if (likely(p_index >= ring->c_index)) |
1400 | rxpkttoprocess = (DMA_C_INDEX_MASK + 1) - | 1393 | rxpkttoprocess = p_index - ring->c_index; |
1401 | priv->rx_c_index + p_index; | ||
1402 | else | 1394 | else |
1403 | rxpkttoprocess = p_index - priv->rx_c_index; | 1395 | rxpkttoprocess = (DMA_C_INDEX_MASK + 1) - ring->c_index + |
1396 | p_index; | ||
1404 | 1397 | ||
1405 | netif_dbg(priv, rx_status, dev, | 1398 | netif_dbg(priv, rx_status, dev, |
1406 | "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess); | 1399 | "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess); |
1407 | 1400 | ||
1408 | while ((rxpktprocessed < rxpkttoprocess) && | 1401 | while ((rxpktprocessed < rxpkttoprocess) && |
1409 | (rxpktprocessed < budget)) { | 1402 | (rxpktprocessed < budget)) { |
1410 | cb = &priv->rx_cbs[priv->rx_read_ptr]; | 1403 | cb = &priv->rx_cbs[ring->read_ptr]; |
1411 | skb = cb->skb; | 1404 | skb = cb->skb; |
1412 | 1405 | ||
1413 | /* We do not have a backing SKB, so we do not have a | 1406 | /* We do not have a backing SKB, so we do not have a |
@@ -1430,10 +1423,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, | |||
1430 | 1423 | ||
1431 | if (!priv->desc_64b_en) { | 1424 | if (!priv->desc_64b_en) { |
1432 | dma_length_status = | 1425 | dma_length_status = |
1433 | dmadesc_get_length_status(priv, | 1426 | dmadesc_get_length_status(priv, cb->bd_addr); |
1434 | priv->rx_bds + | ||
1435 | (priv->rx_read_ptr * | ||
1436 | DMA_DESC_SIZE)); | ||
1437 | } else { | 1427 | } else { |
1438 | struct status_64 *status; | 1428 | struct status_64 *status; |
1439 | 1429 | ||
@@ -1449,8 +1439,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, | |||
1449 | 1439 | ||
1450 | netif_dbg(priv, rx_status, dev, | 1440 | netif_dbg(priv, rx_status, dev, |
1451 | "%s:p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n", | 1441 | "%s:p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n", |
1452 | __func__, p_index, priv->rx_c_index, | 1442 | __func__, p_index, ring->c_index, |
1453 | priv->rx_read_ptr, dma_length_status); | 1443 | ring->read_ptr, dma_length_status); |
1454 | 1444 | ||
1455 | if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { | 1445 | if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { |
1456 | netif_err(priv, rx_status, dev, | 1446 | netif_err(priv, rx_status, dev, |
@@ -1528,25 +1518,31 @@ refill: | |||
1528 | } | 1518 | } |
1529 | 1519 | ||
1530 | rxpktprocessed++; | 1520 | rxpktprocessed++; |
1531 | priv->rx_read_ptr++; | 1521 | if (likely(ring->read_ptr < ring->end_ptr)) |
1532 | priv->rx_read_ptr &= (priv->num_rx_bds - 1); | 1522 | ring->read_ptr++; |
1523 | else | ||
1524 | ring->read_ptr = ring->cb_ptr; | ||
1525 | |||
1526 | ring->c_index = (ring->c_index + 1) & DMA_C_INDEX_MASK; | ||
1527 | bcmgenet_rdma_ring_writel(priv, index, ring->c_index, RDMA_CONS_INDEX); | ||
1533 | } | 1528 | } |
1534 | 1529 | ||
1535 | return rxpktprocessed; | 1530 | return rxpktprocessed; |
1536 | } | 1531 | } |
1537 | 1532 | ||
1538 | /* Assign skb to RX DMA descriptor. */ | 1533 | /* Assign skb to RX DMA descriptor. */ |
1539 | static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv) | 1534 | static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, |
1535 | struct bcmgenet_rx_ring *ring) | ||
1540 | { | 1536 | { |
1541 | struct enet_cb *cb; | 1537 | struct enet_cb *cb; |
1542 | int ret = 0; | 1538 | int ret = 0; |
1543 | int i; | 1539 | int i; |
1544 | 1540 | ||
1545 | netif_dbg(priv, hw, priv->dev, "%s:\n", __func__); | 1541 | netif_dbg(priv, hw, priv->dev, "%s\n", __func__); |
1546 | 1542 | ||
1547 | /* loop here for each buffer needing assign */ | 1543 | /* loop here for each buffer needing assign */ |
1548 | for (i = 0; i < priv->num_rx_bds; i++) { | 1544 | for (i = 0; i < ring->size; i++) { |
1549 | cb = &priv->rx_cbs[priv->rx_bd_assign_index]; | 1545 | cb = ring->cbs + i; |
1550 | if (cb->skb) | 1546 | if (cb->skb) |
1551 | continue; | 1547 | continue; |
1552 | 1548 | ||
@@ -1778,20 +1774,24 @@ static void bcmgenet_fini_tx_ring(struct bcmgenet_priv *priv, | |||
1778 | 1774 | ||
1779 | /* Initialize a RDMA ring */ | 1775 | /* Initialize a RDMA ring */ |
1780 | static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, | 1776 | static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, |
1781 | unsigned int index, unsigned int size) | 1777 | unsigned int index, unsigned int size, |
1778 | unsigned int start_ptr, unsigned int end_ptr) | ||
1782 | { | 1779 | { |
1780 | struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; | ||
1783 | u32 words_per_bd = WORDS_PER_BD(priv); | 1781 | u32 words_per_bd = WORDS_PER_BD(priv); |
1784 | int ret; | 1782 | int ret; |
1785 | 1783 | ||
1786 | priv->rx_bd_assign_ptr = priv->rx_bds; | 1784 | ring->index = index; |
1787 | priv->rx_bd_assign_index = 0; | 1785 | ring->cbs = priv->rx_cbs + start_ptr; |
1788 | priv->rx_c_index = 0; | 1786 | ring->size = size; |
1789 | priv->rx_read_ptr = 0; | 1787 | ring->c_index = 0; |
1788 | ring->read_ptr = start_ptr; | ||
1789 | ring->cb_ptr = start_ptr; | ||
1790 | ring->end_ptr = end_ptr - 1; | ||
1790 | 1791 | ||
1791 | ret = bcmgenet_alloc_rx_buffers(priv); | 1792 | ret = bcmgenet_alloc_rx_buffers(priv, ring); |
1792 | if (ret) { | 1793 | if (ret) |
1793 | return ret; | 1794 | return ret; |
1794 | } | ||
1795 | 1795 | ||
1796 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); | 1796 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); |
1797 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); | 1797 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); |
@@ -1805,10 +1805,13 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, | |||
1805 | DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH); | 1805 | DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH); |
1806 | 1806 | ||
1807 | /* Set start and end address, read and write pointers */ | 1807 | /* Set start and end address, read and write pointers */ |
1808 | bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); | 1808 | bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, |
1809 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR); | 1809 | DMA_START_ADDR); |
1810 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); | 1810 | bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, |
1811 | bcmgenet_rdma_ring_writel(priv, index, words_per_bd * size - 1, | 1811 | RDMA_READ_PTR); |
1812 | bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, | ||
1813 | RDMA_WRITE_PTR); | ||
1814 | bcmgenet_rdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, | ||
1812 | DMA_END_ADDR); | 1815 | DMA_END_ADDR); |
1813 | 1816 | ||
1814 | return ret; | 1817 | return ret; |
@@ -1883,6 +1886,66 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) | |||
1883 | bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); | 1886 | bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); |
1884 | } | 1887 | } |
1885 | 1888 | ||
1889 | /* Initialize Rx queues | ||
1890 | * | ||
1891 | * Queues 0-15 are priority queues. Hardware Filtering Block (HFB) can be | ||
1892 | * used to direct traffic to these queues. | ||
1893 | * | ||
1894 | * Queue 16 is the default Rx queue with GENET_Q16_RX_BD_CNT descriptors. | ||
1895 | */ | ||
1896 | static int bcmgenet_init_rx_queues(struct net_device *dev) | ||
1897 | { | ||
1898 | struct bcmgenet_priv *priv = netdev_priv(dev); | ||
1899 | u32 i; | ||
1900 | u32 dma_enable; | ||
1901 | u32 dma_ctrl; | ||
1902 | u32 ring_cfg; | ||
1903 | int ret; | ||
1904 | |||
1905 | dma_ctrl = bcmgenet_rdma_readl(priv, DMA_CTRL); | ||
1906 | dma_enable = dma_ctrl & DMA_EN; | ||
1907 | dma_ctrl &= ~DMA_EN; | ||
1908 | bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL); | ||
1909 | |||
1910 | dma_ctrl = 0; | ||
1911 | ring_cfg = 0; | ||
1912 | |||
1913 | /* Initialize Rx priority queues */ | ||
1914 | for (i = 0; i < priv->hw_params->rx_queues; i++) { | ||
1915 | ret = bcmgenet_init_rx_ring(priv, i, | ||
1916 | priv->hw_params->rx_bds_per_q, | ||
1917 | i * priv->hw_params->rx_bds_per_q, | ||
1918 | (i + 1) * | ||
1919 | priv->hw_params->rx_bds_per_q); | ||
1920 | if (ret) | ||
1921 | return ret; | ||
1922 | |||
1923 | ring_cfg |= (1 << i); | ||
1924 | dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); | ||
1925 | } | ||
1926 | |||
1927 | /* Initialize Rx default queue 16 */ | ||
1928 | ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, GENET_Q16_RX_BD_CNT, | ||
1929 | priv->hw_params->rx_queues * | ||
1930 | priv->hw_params->rx_bds_per_q, | ||
1931 | TOTAL_DESC); | ||
1932 | if (ret) | ||
1933 | return ret; | ||
1934 | |||
1935 | ring_cfg |= (1 << DESC_INDEX); | ||
1936 | dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); | ||
1937 | |||
1938 | /* Enable rings */ | ||
1939 | bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG); | ||
1940 | |||
1941 | /* Configure ring as descriptor ring and re-enable DMA if enabled */ | ||
1942 | if (dma_enable) | ||
1943 | dma_ctrl |= DMA_EN; | ||
1944 | bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL); | ||
1945 | |||
1946 | return 0; | ||
1947 | } | ||
1948 | |||
1886 | static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) | 1949 | static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) |
1887 | { | 1950 | { |
1888 | int ret = 0; | 1951 | int ret = 0; |
@@ -1990,10 +2053,10 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) | |||
1990 | cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; | 2053 | cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; |
1991 | } | 2054 | } |
1992 | 2055 | ||
1993 | /* Initialize Rx default queue 16 */ | 2056 | /* Initialize Rx queues */ |
1994 | ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, TOTAL_DESC); | 2057 | ret = bcmgenet_init_rx_queues(priv->dev); |
1995 | if (ret) { | 2058 | if (ret) { |
1996 | netdev_err(priv->dev, "failed to initialize RX ring\n"); | 2059 | netdev_err(priv->dev, "failed to initialize Rx queues\n"); |
1997 | bcmgenet_free_rx_buffers(priv); | 2060 | bcmgenet_free_rx_buffers(priv); |
1998 | kfree(priv->rx_cbs); | 2061 | kfree(priv->rx_cbs); |
1999 | return ret; | 2062 | return ret; |
@@ -2030,13 +2093,8 @@ static int bcmgenet_poll(struct napi_struct *napi, int budget) | |||
2030 | struct bcmgenet_priv, napi); | 2093 | struct bcmgenet_priv, napi); |
2031 | unsigned int work_done; | 2094 | unsigned int work_done; |
2032 | 2095 | ||
2033 | work_done = bcmgenet_desc_rx(priv, budget); | 2096 | work_done = bcmgenet_desc_rx(priv, DESC_INDEX, budget); |
2034 | 2097 | ||
2035 | /* Advancing our consumer index*/ | ||
2036 | priv->rx_c_index += work_done; | ||
2037 | priv->rx_c_index &= DMA_C_INDEX_MASK; | ||
2038 | bcmgenet_rdma_ring_writel(priv, DESC_INDEX, | ||
2039 | priv->rx_c_index, RDMA_CONS_INDEX); | ||
2040 | if (work_done < budget) { | 2098 | if (work_done < budget) { |
2041 | napi_complete(napi); | 2099 | napi_complete(napi); |
2042 | bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE, | 2100 | bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE, |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 5684e8529ecc..17443db8dc53 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h | |||
@@ -540,6 +540,16 @@ struct bcmgenet_tx_ring { | |||
540 | struct bcmgenet_priv *priv; | 540 | struct bcmgenet_priv *priv; |
541 | }; | 541 | }; |
542 | 542 | ||
543 | struct bcmgenet_rx_ring { | ||
544 | unsigned int index; /* Rx ring index */ | ||
545 | struct enet_cb *cbs; /* Rx ring buffer control block */ | ||
546 | unsigned int size; /* Rx ring size */ | ||
547 | unsigned int c_index; /* Rx last consumer index */ | ||
548 | unsigned int read_ptr; /* Rx ring read pointer */ | ||
549 | unsigned int cb_ptr; /* Rx ring initial CB ptr */ | ||
550 | unsigned int end_ptr; /* Rx ring end CB ptr */ | ||
551 | }; | ||
552 | |||
543 | /* device context */ | 553 | /* device context */ |
544 | struct bcmgenet_priv { | 554 | struct bcmgenet_priv { |
545 | void __iomem *base; | 555 | void __iomem *base; |
@@ -560,13 +570,11 @@ struct bcmgenet_priv { | |||
560 | 570 | ||
561 | /* receive variables */ | 571 | /* receive variables */ |
562 | void __iomem *rx_bds; | 572 | void __iomem *rx_bds; |
563 | void __iomem *rx_bd_assign_ptr; | ||
564 | int rx_bd_assign_index; | ||
565 | struct enet_cb *rx_cbs; | 573 | struct enet_cb *rx_cbs; |
566 | unsigned int num_rx_bds; | 574 | unsigned int num_rx_bds; |
567 | unsigned int rx_buf_len; | 575 | unsigned int rx_buf_len; |
568 | unsigned int rx_read_ptr; | 576 | |
569 | unsigned int rx_c_index; | 577 | struct bcmgenet_rx_ring rx_rings[DESC_INDEX + 1]; |
570 | 578 | ||
571 | /* other misc variables */ | 579 | /* other misc variables */ |
572 | struct bcmgenet_hw_params *hw_params; | 580 | struct bcmgenet_hw_params *hw_params; |