日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux stmac网卡代码分析 -- open

發布時間:2023/12/10 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。