dpdk + ixgbe adater _ hw 通过pci_map_resource 读写dma寄存器 + 总线地址 + 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

 IXGBE_WRITE_REG

 

 

 

#define IXGBE_PCI_REG_WRITE(reg, value)                 \
        rte_write32((rte_cpu_to_le_32(value)), reg)

 

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 */
        ...
    }
    ...
}

 

 

ixgbe_dev_rx_queue_setup
        rz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
                                      RX_RING_SZ, IXGBE_ALIGN, socket_id)
        rxq->rx_ring_phys_addr = rz->iova;
        rxq->rx_ring = (union ixgbe_adv_rx_desc *) rz->addr;
        
static inline rte_iova_t
rte_mbuf_data_iova_default(const struct rte_mbuf *mb)
{
        return mb->buf_iova + RTE_PKTMBUF_HEADROOM;
}

__rte_deprecated
static inline phys_addr_t
rte_mbuf_data_dma_addr_default(const struct rte_mbuf *mb)
{
        return rte_mbuf_data_iova_default(mb);
}

 

nmb = rte_mbuf_raw_alloc(rxq->mb_pool);
dma_addr =rte_cpu_to_le_64(rte_mbuf_data_dma_addr_default(nmb)); /* 得到新mbuf的总线地址 */
rxdp->read.hdr_addr = 0; /* 清零新mbuf对应的desc的DD,后续网卡会读desc */
rxdp->read.pkt_addr = dma_addr

 

posted on 2020-09-03 20:00  tycoon3  阅读(667)  评论(0编辑  收藏  举报

导航