zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    平安银行Java面试-社招-五面(2019/09)
    OPPO-Java面试-社招-一面(2019/07)
    记录一次SpringBoot实现AOP编程
    Java-Long类型精度丢失问题
    微众银行Java面试-社招-一面(2019/07)
    Java-根据经纬度计算距离(百度地图距离)
    git 常用命令
    linux命令之文件、文件夹操作
    j2ee爬坑行之二 servlet
    j2ee爬坑行之一:web容器
  • 原文地址:https://www.cnblogs.com/dream397/p/13610279.html
Copyright © 2011-2022 走看看