1. 程式人生 > 實用技巧 >dpdk + ixgbe 通過pci_map_resource 讀寫dma暫存器

dpdk + ixgbe 通過pci_map_resource 讀寫dma暫存器

一般驅動

https://www.cnblogs.com/codestack/p/12906441.html

static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
// 分配net_device和ixgbe_adapter,傳送佇列數為MAX_TX_QUEUE
    if (!netdev) {
        err = -ENOMEM;
        goto err_alloc_etherdev;
    }

    SET_NETDEV_DEV(netdev, 
&pdev->dev); adapter = netdev_priv(netdev);// 得到ixgbe_adapter的指標 adapter->netdev = netdev; adapter->pdev = pdev; hw = &adapter->hw;// 得到ixgbe_hw的指標 hw->back = adapter; adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); // 將BAR0中的匯流排地址對映成記憶體地址,賦給hw->hw_addr,允許網絡卡驅動通過hw->hw_addr訪問網絡卡的BAR0對應的Memory空間
hw->hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); adapter->io_addr = hw->hw_addr;

dpdk

eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
{
    struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
    
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); eth_dev->dev_ops = &ixgbe_eth_dev_ops; eth_dev->rx_pkt_burst = &ixgbe_recv_pkts; eth_dev->tx_pkt_burst = &ixgbe_xmit_pkts; eth_dev->tx_pkt_prepare = &ixgbe_prep_pkts; hw->device_id = pci_dev->id.device_id; hw->vendor_id = pci_dev->id.vendor_id; hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; } int __attribute__((cold)) ixgbe_dev_rx_init(struct rte_eth_dev *dev) { struct ixgbe_adapter *adapter = dev->data->dev_private; struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); ... for (i = 0; i < dev->data->nb_rx_queues; i++) { rxq = dev->data->rx_queues[i]; ... bus_addr = rxq->rx_ring_phys_addr; /* desc陣列的匯流排地址 */ /* 將desc陣列的匯流排地址寫入網絡卡暫存器 * RDBAL(RX Descriptor Base Address Low) * RDBAH(RX Descriptor Base Address High) * RDLEN(RX Descriptor Length) * RDH(RX Descriptor Head) * RDT(RX Descriptor Tail) * #define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \ * (0x0D000 + (((_i) - 64) * 0x40))) * #define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \ * (0x0D004 + (((_i) - 64) * 0x40))) * #define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \ * (0x0D008 + (((_i) - 64) * 0x40))) * #define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \ * (0x0D010 + (((_i) - 64) * 0x40))) * #define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \ * (0x0D018 + (((_i) - 64) * 0x40))) */ IXGBE_WRITE_REG(hw, IXGBE_RDBAL(rxq->reg_idx), (uint32_t)(bus_addr & 0x00000000ffffffffULL)); IXGBE_WRITE_REG(hw, IXGBE_RDBAH(rxq->reg_idx), (uint32_t)(bus_addr >> 32)); IXGBE_WRITE_REG(hw, IXGBE_RDLEN(rxq->reg_idx), rxq->nb_rx_desc * sizeof(union ixgbe_adv_rx_desc)); /* desc陣列的長度 */ IXGBE_WRITE_REG(hw, IXGBE_RDH(rxq->reg_idx), 0); /* 寫RDH為0 */ IXGBE_WRITE_REG(hw, IXGBE_RDT(rxq->reg_idx), 0); /* 寫RDT為0 */ ... } ... }