Linux stmac网卡代码分析 -- open
生活随笔
收集整理的這篇文章主要介紹了
Linux stmac网卡代码分析 -- open
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Open
stmmac_open是在stmmac_netdev_ops結構體里的,這個ops在probe時就已經注冊到了net_device結構體里,在網卡對于stmmac_open函數調用的時間我還不確定是否是在網卡link up時
下面看看stmmac_open函數,文件位置: drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
在open函數中主要完成了以下操作
-
連接到PHY,設置好合適的速率
-
申請、初始化dma 描述符資源和隊列,在后面初始化網卡的dma 引擎時會將用到
-
初始化DMA
-
初始化MAC
-
申請、初始化中斷資源
-
enable、start隊列
下面來實際看看代碼
static int stmmac_open(struct net_device *dev) {struct stmmac_priv *priv = netdev_priv(dev);u32 chan;int ret;if (priv->hw->pcs != STMMAC_PCS_RGMII &&priv->hw->pcs != STMMAC_PCS_TBI &&priv->hw->pcs != STMMAC_PCS_RTBI) {ret = stmmac_init_phy(dev);if (ret) {netdev_err(priv->dev,"%s: Cannot attach to PHY (error: %d)\n",__func__, ret);return ret;}}/* Extra statistics */memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));priv->xstats.threshold = tc;priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);priv->rx_copybreak = STMMAC_RX_COPYBREAK;//分配描述符資源放到priv->rx_queue[queue] priv->tx_queue[queue]ret = alloc_dma_desc_resources(priv);if (ret < 0) {netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n",__func__);goto dma_desc_error;}//初始化接收和發送描述符資源隊列ret = init_dma_desc_rings(dev, GFP_KERNEL);if (ret < 0) {netdev_err(priv->dev, "%s: DMA descriptors initialization failed\n",__func__);goto init_error;}//初始化DMA、MACret = stmmac_hw_setup(dev, true);if (ret < 0) {netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);goto init_error;}stmmac_init_tx_coalesce(priv);//if (dev->phydev)phy_start(dev->phydev);/* Request the IRQ lines */ret = request_irq(dev->irq, stmmac_interrupt,IRQF_SHARED, dev->name, dev);if (unlikely(ret < 0)) {netdev_err(priv->dev,"%s: ERROR: allocating the IRQ %d (error: %d)\n",__func__, dev->irq, ret);goto irq_error;}/* Request the Wake IRQ in case of another line is used for WoL */if (priv->wol_irq != dev->irq) {ret = request_irq(priv->wol_irq, stmmac_interrupt,IRQF_SHARED, dev->name, dev);if (unlikely(ret < 0)) {netdev_err(priv->dev,"%s: ERROR: allocating the WoL IRQ %d (%d)\n",__func__, priv->wol_irq, ret);goto wolirq_error;}}/* Request the IRQ lines */if (priv->lpi_irq > 0) {ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED,dev->name, dev);if (unlikely(ret < 0)) {netdev_err(priv->dev,"%s: ERROR: allocating the LPI IRQ %d (%d)\n",__func__, priv->lpi_irq, ret);goto lpiirq_error;}}stmmac_enable_all_queues(priv);stmmac_start_all_queues(priv);return 0;再看看對硬件操作比較多的stmmac_hw_setup(dev, true); 這個函數中主要初始化了DMA和MAC,并使能了DMA
static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)-> ret = stmmac_init_dma_engine(priv);-> stmmac_reset(priv, priv->ioaddr);-> stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds);-> stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);-> stmmac_init_rx/tx_chan()-> stmmac_set_rx/tx_tail_ptr(priv, priv->ioaddr,rx_q->rx_tail_addr, chan) 把收發隊列地址配置到網卡-> stmmac_core_init(priv, priv->hw, dev); //這是個回調函數 對應的是 dwmac1000_dma_init(),在probe時注冊的-> stmmac_mac_set(priv, priv->ioaddr, true);-> stmmac_dma_operation_mode(priv);-> stmmac_set_rings_length(priv);-> stmmac_start_all_dma(priv);對于DMA和MAC的初始化我整理成了流程圖表
下面是對MAC的初始化流程
總結
以上是生活随笔為你收集整理的Linux stmac网卡代码分析 -- open的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dpdk18.11 收发包流程分析
- 下一篇: MFC - PreTranslateMe