Lines Matching +full:num +full:- +full:rxq

1 // SPDX-License-Identifier: GPL-2.0
5 * U-Boot version:
6 * Copyright (C) 2014-2015 Stefan Roese <sr@denx.de>
12 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
30 #include <asm-generic/gpio.h>
142 * bits 8..15 = RXQ OCCUP, one bit per queue.
143 * bits 16..23 = RXQ FREE, one bit per queue.
148 #define MVNETA_TX_INTR_MASK(nr_txqs) (((1 << nr_txqs) - 1) << 0)
150 #define MVNETA_RX_INTR_MASK(nr_rxqs) (((1 << nr_rxqs) - 1) << 8)
220 (((index) < (q)->last_desc) ? ((index) + 1) : 0)
318 u32 reserved2; /* hw_cmd - (for future use, PMT) */
319 u32 reserved3[4]; /* Reserved - (for future use) */
324 u16 reserved1; /* pnc_info - (for future use, PnC) */
332 u16 reserved4; /* csum_l4 - (for future use, PnC) */
339 /* Number of this TX queue, in the range 0-7 */
365 /* rx queue number, in the range 0-7 */
368 /* num of rx descriptors in the rx descriptor ring */
384 /* U-Boot doesn't use the queues, so set the number to 1 */
421 writel(data, pp->base + offset); in mvreg_write()
427 return readl(pp->base + offset); in mvreg_read()
455 struct mvneta_rx_queue *rxq, in mvneta_rxq_non_occup_desc_add() argument
462 mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), in mvneta_rxq_non_occup_desc_add()
465 ndescs -= MVNETA_RXQ_ADD_NON_OCCUPIED_MAX; in mvneta_rxq_non_occup_desc_add()
468 mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), in mvneta_rxq_non_occup_desc_add()
474 struct mvneta_rx_queue *rxq) in mvneta_rxq_busy_desc_num_get() argument
478 val = mvreg_read(pp, MVNETA_RXQ_STATUS_REG(rxq->id)); in mvneta_rxq_busy_desc_num_get()
482 /* Update num of rx desc called upon return from rx path or
486 struct mvneta_rx_queue *rxq, in mvneta_rxq_desc_num_update() argument
494 mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), val); in mvneta_rxq_desc_num_update()
505 rx_done -= 0xff; in mvneta_rxq_desc_num_update()
512 rx_filled -= 0xff; in mvneta_rxq_desc_num_update()
514 mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), val); in mvneta_rxq_desc_num_update()
520 mvneta_rxq_next_desc_get(struct mvneta_rx_queue *rxq) in mvneta_rxq_next_desc_get() argument
522 int rx_desc = rxq->next_desc_to_proc; in mvneta_rxq_next_desc_get()
524 rxq->next_desc_to_proc = MVNETA_QUEUE_NEXT_DESC(rxq, rx_desc); in mvneta_rxq_next_desc_get()
525 return rxq->descs + rx_desc; in mvneta_rxq_next_desc_get()
541 mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val); in mvneta_txq_pend_desc_add()
548 int tx_desc = txq->next_desc_to_proc; in mvneta_txq_next_desc_get()
550 txq->next_desc_to_proc = MVNETA_QUEUE_NEXT_DESC(txq, tx_desc); in mvneta_txq_next_desc_get()
551 return txq->descs + tx_desc; in mvneta_txq_next_desc_get()
554 /* Set rxq buf size */
556 struct mvneta_rx_queue *rxq, in mvneta_rxq_buf_size_set() argument
561 val = mvreg_read(pp, MVNETA_RXQ_SIZE_REG(rxq->id)); in mvneta_rxq_buf_size_set()
566 mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), val); in mvneta_rxq_buf_size_set()
572 return pp->phyaddr > PHY_MAX_ADDR; in mvneta_port_is_fixed_link()
586 struct mvneta_tx_queue *txq = &pp->txqs[queue]; in mvneta_port_up()
587 if (txq->descs != NULL) in mvneta_port_up()
595 struct mvneta_rx_queue *rxq = &pp->rxqs[queue]; in mvneta_port_up() local
596 if (rxq->descs != NULL) in mvneta_port_up()
620 netdev_warn(pp->dev, in mvneta_port_down()
643 netdev_warn(pp->dev, in mvneta_port_down()
659 netdev_warn(pp->dev, in mvneta_port_down()
699 /* Set all entries in Unicast MAC Table; queue==-1 means reject all */
705 if (queue == -1) { in mvneta_set_ucast_table()
716 /* Set all entries in Special Multicast MAC Table; queue==-1 means reject all */
722 if (queue == -1) { in mvneta_set_special_mcast_table()
733 /* Set all entries in Other Multicast MAC Table. queue==-1 means reject all */
739 if (queue == -1) { in mvneta_set_other_mcast_table()
740 memset(pp->mcast_count, 0, sizeof(pp->mcast_count)); in mvneta_set_other_mcast_table()
743 memset(pp->mcast_count, 1, sizeof(pp->mcast_count)); in mvneta_set_other_mcast_table()
781 /* Set CPU queue access map - all CPUs have access to all RX in mvneta_defaults_set()
826 /* Enable PHY polling in hardware if not in fixed-link mode */ in mvneta_defaults_set()
833 mvneta_set_ucast_table(pp, -1); in mvneta_defaults_set()
834 mvneta_set_special_mcast_table(pp, -1); in mvneta_defaults_set()
835 mvneta_set_other_mcast_table(pp, -1); in mvneta_defaults_set()
857 if (queue == -1) { in mvneta_set_ucast_addr()
875 if (queue != -1) { in mvneta_mac_addr_set()
891 ((struct eth_pdata *)dev_get_platdata(dev))->enetaddr, in mvneta_write_hwaddr()
901 rx_desc->buf_cookie = cookie; in mvneta_rx_desc_fill()
902 rx_desc->buf_phys_addr = phys_addr; in mvneta_rx_desc_fill()
915 mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val); in mvneta_txq_sent_desc_dec()
916 sent_desc = sent_desc - 0xff; in mvneta_txq_sent_desc_dec()
920 mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val); in mvneta_txq_sent_desc_dec()
930 val = mvreg_read(pp, MVNETA_TXQ_STATUS_REG(txq->id)); in mvneta_txq_sent_desc_num_get()
941 u32 status = rx_desc->status; in mvneta_rx_error()
944 netdev_err(pp->dev, in mvneta_rx_error()
946 status, rx_desc->data_size); in mvneta_rx_error()
952 netdev_err(pp->dev, "bad rx status %08x (crc error), size=%d\n", in mvneta_rx_error()
953 status, rx_desc->data_size); in mvneta_rx_error()
956 netdev_err(pp->dev, "bad rx status %08x (overrun error), size=%d\n", in mvneta_rx_error()
957 status, rx_desc->data_size); in mvneta_rx_error()
960 netdev_err(pp->dev, "bad rx status %08x (max frame length error), size=%d\n", in mvneta_rx_error()
961 status, rx_desc->data_size); in mvneta_rx_error()
964 netdev_err(pp->dev, "bad rx status %08x (resource error), size=%d\n", in mvneta_rx_error()
965 status, rx_desc->data_size); in mvneta_rx_error()
971 int rxq) in mvneta_rxq_handle_get() argument
973 return &pp->rxqs[rxq]; in mvneta_rxq_handle_get()
977 /* Drop packets received by the RXQ and free buffers */
979 struct mvneta_rx_queue *rxq) in mvneta_rxq_drop_pkts() argument
983 rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq); in mvneta_rxq_drop_pkts()
985 mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); in mvneta_rxq_drop_pkts()
988 /* Handle rxq fill: allocates rxq skbs; called when initializing a port */
989 static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, in mvneta_rxq_fill() argument
990 int num) in mvneta_rxq_fill() argument
994 for (i = 0; i < num; i++) { in mvneta_rxq_fill()
997 /* U-Boot special: Fill in the rx buffer addresses */ in mvneta_rxq_fill()
999 mvneta_rx_desc_fill(rxq->descs + i, addr, addr); in mvneta_rxq_fill()
1005 mvneta_rxq_non_occup_desc_add(pp, rxq, i); in mvneta_rxq_fill()
1014 struct mvneta_rx_queue *rxq) in mvneta_rxq_init() argument
1017 rxq->size = pp->rx_ring_size; in mvneta_rxq_init()
1020 rxq->descs_phys = (dma_addr_t)rxq->descs; in mvneta_rxq_init()
1021 if (rxq->descs == NULL) in mvneta_rxq_init()
1022 return -ENOMEM; in mvneta_rxq_init()
1024 WARN_ON(rxq->descs != PTR_ALIGN(rxq->descs, ARCH_DMA_MINALIGN)); in mvneta_rxq_init()
1026 rxq->last_desc = rxq->size - 1; in mvneta_rxq_init()
1029 mvreg_write(pp, MVNETA_RXQ_BASE_ADDR_REG(rxq->id), rxq->descs_phys); in mvneta_rxq_init()
1030 mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), rxq->size); in mvneta_rxq_init()
1032 /* Fill RXQ with buffers from RX pool */ in mvneta_rxq_init()
1033 mvneta_rxq_buf_size_set(pp, rxq, RX_BUFFER_SIZE); in mvneta_rxq_init()
1034 mvneta_rxq_fill(pp, rxq, rxq->size); in mvneta_rxq_init()
1041 struct mvneta_rx_queue *rxq) in mvneta_rxq_deinit() argument
1043 mvneta_rxq_drop_pkts(pp, rxq); in mvneta_rxq_deinit()
1045 rxq->descs = NULL; in mvneta_rxq_deinit()
1046 rxq->last_desc = 0; in mvneta_rxq_deinit()
1047 rxq->next_desc_to_proc = 0; in mvneta_rxq_deinit()
1048 rxq->descs_phys = 0; in mvneta_rxq_deinit()
1055 txq->size = pp->tx_ring_size; in mvneta_txq_init()
1058 txq->descs_phys = (dma_addr_t)txq->descs; in mvneta_txq_init()
1059 if (txq->descs == NULL) in mvneta_txq_init()
1060 return -ENOMEM; in mvneta_txq_init()
1062 WARN_ON(txq->descs != PTR_ALIGN(txq->descs, ARCH_DMA_MINALIGN)); in mvneta_txq_init()
1064 txq->last_desc = txq->size - 1; in mvneta_txq_init()
1067 mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff); in mvneta_txq_init()
1068 mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff); in mvneta_txq_init()
1071 mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys); in mvneta_txq_init()
1072 mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size); in mvneta_txq_init()
1081 txq->descs = NULL; in mvneta_txq_deinit()
1082 txq->last_desc = 0; in mvneta_txq_deinit()
1083 txq->next_desc_to_proc = 0; in mvneta_txq_deinit()
1084 txq->descs_phys = 0; in mvneta_txq_deinit()
1087 mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0); in mvneta_txq_deinit()
1088 mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0); in mvneta_txq_deinit()
1091 mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), 0); in mvneta_txq_deinit()
1092 mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), 0); in mvneta_txq_deinit()
1101 mvneta_txq_deinit(pp, &pp->txqs[queue]); in mvneta_cleanup_txqs()
1110 mvneta_rxq_deinit(pp, &pp->rxqs[queue]); in mvneta_cleanup_rxqs()
1120 int err = mvneta_rxq_init(pp, &pp->rxqs[queue]); in mvneta_setup_rxqs()
1122 netdev_err(pp->dev, "%s: can't create rxq=%d\n", in mvneta_setup_rxqs()
1138 int err = mvneta_txq_init(pp, &pp->txqs[queue]); in mvneta_setup_txqs()
1140 netdev_err(pp->dev, "%s: can't create txq=%d\n", in mvneta_setup_txqs()
1159 struct phy_device *phydev = pp->phydev; in mvneta_adjust_link()
1167 if (phydev->link) { in mvneta_adjust_link()
1168 if ((pp->speed != phydev->speed) || in mvneta_adjust_link()
1169 (pp->duplex != phydev->duplex)) { in mvneta_adjust_link()
1179 if (phydev->duplex) in mvneta_adjust_link()
1182 if (phydev->speed == SPEED_1000) in mvneta_adjust_link()
1189 pp->duplex = phydev->duplex; in mvneta_adjust_link()
1190 pp->speed = phydev->speed; in mvneta_adjust_link()
1194 if (phydev->link != pp->link) { in mvneta_adjust_link()
1195 if (!phydev->link) { in mvneta_adjust_link()
1196 pp->duplex = -1; in mvneta_adjust_link()
1197 pp->speed = 0; in mvneta_adjust_link()
1200 pp->link = phydev->link; in mvneta_adjust_link()
1205 if (phydev->link) { in mvneta_adjust_link()
1248 pp->txqs = kzalloc(txq_number * sizeof(struct mvneta_tx_queue), in mvneta_init2()
1250 if (!pp->txqs) in mvneta_init2()
1251 return -ENOMEM; in mvneta_init2()
1253 /* U-Boot special: use preallocated area */ in mvneta_init2()
1254 pp->txqs[0].descs = buffer_loc.tx_descs; in mvneta_init2()
1258 struct mvneta_tx_queue *txq = &pp->txqs[queue]; in mvneta_init2()
1259 txq->id = queue; in mvneta_init2()
1260 txq->size = pp->tx_ring_size; in mvneta_init2()
1263 pp->rxqs = kzalloc(rxq_number * sizeof(struct mvneta_rx_queue), in mvneta_init2()
1265 if (!pp->rxqs) { in mvneta_init2()
1266 kfree(pp->txqs); in mvneta_init2()
1267 return -ENOMEM; in mvneta_init2()
1270 /* U-Boot special: use preallocated area */ in mvneta_init2()
1271 pp->rxqs[0].descs = buffer_loc.rx_descs; in mvneta_init2()
1275 struct mvneta_rx_queue *rxq = &pp->rxqs[queue]; in mvneta_init2() local
1276 rxq->id = queue; in mvneta_init2()
1277 rxq->size = pp->rx_ring_size; in mvneta_init2()
1302 clrbits_le32(pp->base + MVNETA_BASE_ADDR_ENABLE, in mvneta_bypass_mbus_windows()
1306 setbits_le32(pp->base + MVNETA_PORT_ACCESS_PROTECT, in mvneta_bypass_mbus_windows()
1329 for (i = 0; i < dram->num_cs; i++) { in mvneta_conf_mbus_windows()
1330 const struct mbus_dram_window *cs = dram->cs + i; in mvneta_conf_mbus_windows()
1331 mvreg_write(pp, MVNETA_WIN_BASE(i), (cs->base & 0xffff0000) | in mvneta_conf_mbus_windows()
1332 (cs->mbus_attr << 8) | dram->mbus_dram_target_id); in mvneta_conf_mbus_windows()
1335 (cs->size - 1) & 0xffff0000); in mvneta_conf_mbus_windows()
1371 return -EINVAL; in mvneta_port_power_up()
1392 pp->tx_ring_size = MVNETA_MAX_TXD; in mvneta_init()
1393 pp->rx_ring_size = MVNETA_MAX_RXD; in mvneta_init()
1397 dev_err(&pdev->dev, "can't init eth hal\n"); in mvneta_init()
1401 mvneta_mac_addr_set(pp, pdata->enetaddr, rxq_def); in mvneta_init()
1403 err = mvneta_port_power_up(pp, pp->phy_interface); in mvneta_init()
1405 dev_err(&pdev->dev, "can't power up port\n"); in mvneta_init()
1415 /* U-Boot only functions follow here */
1428 if (timeout-- == 0) { in smi_wait_ready()
1430 return -EFAULT; in smi_wait_ready()
1438 * mvneta_mdio_read - miiphy_read callback function.
1444 struct mvneta_port *pp = bus->priv; in mvneta_mdio_read()
1451 return -EFAULT; in mvneta_mdio_read()
1456 return -EFAULT; in mvneta_mdio_read()
1461 return -EFAULT; in mvneta_mdio_read()
1477 if (timeout-- == 0) { in mvneta_mdio_read()
1479 return -EFAULT; in mvneta_mdio_read()
1491 * mvneta_mdio_write - miiphy_write callback function.
1493 * Returns 0 if write succeed, -EINVAL on bad parameters
1494 * -ETIME on timeout
1499 struct mvneta_port *pp = bus->priv; in mvneta_mdio_write()
1505 return -EFAULT; in mvneta_mdio_write()
1510 return -EFAULT; in mvneta_mdio_write()
1515 return -EFAULT; in mvneta_mdio_write()
1534 mvneta_port_power_up(pp, pp->phy_interface); in mvneta_start()
1536 if (!pp->init || pp->link == 0) { in mvneta_start()
1540 pp->init = 1; in mvneta_start()
1541 pp->link = 1; in mvneta_start()
1550 if (pp->duplex) in mvneta_start()
1553 if (pp->speed == SPEED_1000) in mvneta_start()
1555 else if (pp->speed == SPEED_100) in mvneta_start()
1561 mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr); in mvneta_start()
1563 phydev = phy_connect(pp->bus, pp->phyaddr, dev, in mvneta_start()
1564 pp->phy_interface); in mvneta_start()
1567 return -ENODEV; in mvneta_start()
1570 pp->phydev = phydev; in mvneta_start()
1573 if (!phydev->link) { in mvneta_start()
1574 printf("%s: No link.\n", phydev->dev->name); in mvneta_start()
1575 return -1; in mvneta_start()
1580 pp->init = 1; in mvneta_start()
1595 struct mvneta_tx_queue *txq = &pp->txqs[0]; in mvneta_send()
1603 tx_desc->buf_phys_addr = (u32)(uintptr_t)packet; in mvneta_send()
1604 tx_desc->data_size = length; in mvneta_send()
1609 tx_desc->command = MVNETA_TX_L4_CSUM_NOT | MVNETA_TXD_FLZ_DESC; in mvneta_send()
1617 return -1; in mvneta_send()
1622 /* txDone has increased - hw sent packet */ in mvneta_send()
1632 struct mvneta_rx_queue *rxq; in mvneta_recv() local
1636 rxq = mvneta_rxq_handle_get(pp, rxq_def); in mvneta_recv()
1637 rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq); in mvneta_recv()
1648 rx_desc = mvneta_rxq_next_desc_get(rxq); in mvneta_recv()
1650 rx_status = rx_desc->status; in mvneta_recv()
1655 return -EIO; in mvneta_recv()
1659 rx_bytes = rx_desc->data_size - 6; in mvneta_recv()
1661 /* give packet to stack - skip on first 2 bytes */ in mvneta_recv()
1662 data = (u8 *)(uintptr_t)rx_desc->buf_cookie + 2; in mvneta_recv()
1673 mvneta_rxq_desc_num_update(pp, rxq, 1, 1); in mvneta_recv()
1683 void *blob = (void *)gd->fdt_blob; in mvneta_probe()
1694 * be active. Make this area DMA safe by disabling the D-cache in mvneta_probe()
1715 pp->base = (void __iomem *)pdata->iobase; in mvneta_probe()
1718 if (device_is_compatible(dev, "marvell,armada-3700-neta")) in mvneta_probe()
1724 pp->phy_interface = pdata->phy_interface; in mvneta_probe()
1726 /* fetch 'fixed-link' property from 'neta' node */ in mvneta_probe()
1727 fl_node = fdt_subnode_offset(blob, node, "fixed-link"); in mvneta_probe()
1728 if (fl_node != -FDT_ERR_NOTFOUND) { in mvneta_probe()
1730 pp->phyaddr = PHY_MAX_ADDR + 1; in mvneta_probe()
1731 pp->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex"); in mvneta_probe()
1732 pp->speed = fdtdec_get_int(blob, fl_node, "speed", 0); in mvneta_probe()
1737 pp->phyaddr = fdtdec_get_int(blob, addr, "reg", 0); in mvneta_probe()
1743 return -ENOMEM; in mvneta_probe()
1746 bus->read = mvneta_mdio_read; in mvneta_probe()
1747 bus->write = mvneta_mdio_write; in mvneta_probe()
1748 snprintf(bus->name, sizeof(bus->name), dev->name); in mvneta_probe()
1749 bus->priv = (void *)pp; in mvneta_probe()
1750 pp->bus = bus; in mvneta_probe()
1757 gpio_request_by_name(dev, "phy-reset-gpios", 0, in mvneta_probe()
1758 &pp->phy_reset_gpio, GPIOD_IS_OUT); in mvneta_probe()
1760 if (dm_gpio_is_valid(&pp->phy_reset_gpio)) { in mvneta_probe()
1761 dm_gpio_set_value(&pp->phy_reset_gpio, 1); in mvneta_probe()
1763 dm_gpio_set_value(&pp->phy_reset_gpio, 0); in mvneta_probe()
1791 pdata->iobase = devfdt_get_addr(dev); in mvneta_ofdata_to_platdata()
1793 /* Get phy-mode / phy_interface from DT */ in mvneta_ofdata_to_platdata()
1794 pdata->phy_interface = -1; in mvneta_ofdata_to_platdata()
1795 phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", in mvneta_ofdata_to_platdata()
1798 pdata->phy_interface = phy_get_interface_by_name(phy_mode); in mvneta_ofdata_to_platdata()
1799 if (pdata->phy_interface == -1) { in mvneta_ofdata_to_platdata()
1801 return -EINVAL; in mvneta_ofdata_to_platdata()
1808 { .compatible = "marvell,armada-370-neta" },
1809 { .compatible = "marvell,armada-xp-neta" },
1810 { .compatible = "marvell,armada-3700-neta" },