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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

stmmac 中断处理

發布時間:2023/12/15 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stmmac 中断处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.?發送中斷

1.1.?DMA發送完數據后產生中斷,調用 stmmac_interrupt服務程序

?

1.2. stmmac_interrupt?通過調用?stmmac_dma_interrupt?處理DMA相關中斷(包括發送和接收)。在stmmac_dma_interrupt中,通過NAPI機制觸發軟中斷,調用stmmac_poll處理相關事件。

?

1.3.?stmmac_poll調用stmmac_tx_clean回收資源,以及queue操作

1)通過dma_unmap_single解除dma映射

dma_unmap_single(priv->device, tx_q->tx_skbuff_dma[entry].buf, tx_q->tx_skbuff_dma[entry].len, DMA_TO_DEVICE);

2)釋放skb

dev_consume_skb_any(skb);

3)清空descriptor:des2和des3,?將其賦值0

release_tx_desc()

4)設置queue的狀態?,如果queue是停止狀態(__QUEUE_STATE_STACK_XOFF?或?__QUEUE_STATE_DRV_XOFF被置位),但是現在已經滿足開啟條件,則喚醒queue。? ?

在stmmac_xmit發送時如果停止了queue,現在如果條件滿足,會重新恢復queue。

netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue),pkts_compl, bytes_compl);if (unlikely(netif_tx_queue_stopped(netdev_get_tx_queue(priv->dev,queue))) &&stmmac_tx_avail(priv, queue) > STMMAC_TX_THRESH) {netif_dbg(priv, tx_done, priv->dev,"%s: restart transmit\n", __func__);netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue));}

在netdev_tx_completed_queue中,test_and_clear_bit(__QUEUE_STATE_STACK_XOFF, &dev_queue->state),如果test_and_clear_bit返回真,調用 netif_schedule_queue(q)重新開始調度queue

在netif_tx_wake_queue中,test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state),如果test_and_clear_bit返回真,調用 __netif_schedule(q)重新開始調度queue

?

?

2.?接收中斷

2.1.?DMA產生中斷,調用 stmmac_interrupt服務程序

?

2.2. stmmac_interrupt?通過調用?stmmac_dma_interrupt?處理DMA相關中斷(包括發送和接收)。在stmmac_dma_interrupt中,通過NAPI機制觸發軟中斷,調用stmmac_poll接收數據包。

?

2.3. 在stmmac_poll中調用如下代碼收數據包

work_done = stmmac_rx(priv, budget, rx_q->queue_index);if (work_done < budget) {napi_complete_done(napi, work_done);stmmac_enable_dma_irq(priv, chan);}return work_done;

1)調用stmmac_rx接收,budget為循環讀取dma?descriptor(通過處理descriptor來獲取數據包,每個descriptor對應一個數據包)的最大次數,work_done為實際循環的次數。

2)if (work_done < budget) 代表實際循環讀取dma?descriptor的次數小于最大次數budget,代表已經處理完所有需要被處理的descriptor,取完所有的數據包。這時,調用stmmac_enable_dma_irq()開啟中斷,再次接收數據。如果work_done = budget,代表可能還有數據包需要處理,那么這些數據包留到net_rx_action再次調用stmmac_poll時處理。

3)return work_done;?該返回值會被net_rx_action使用。

?

2.4. 在stmmac_rx中,循環收包,循環次數while (count < limit)。每次循環以DMA?descriptor為處理單位,即每次循環時從一個descriptor指定的buffer讀取一個數據包,再通過 napi_gro_receive?送給協議層,處理完后count++。這里limit = budget。

?

2.5. 調用 stmmac_rx_refill重新填充descriptor。

在觸發DMA中斷前,DMA已經將網卡收到的數據包搬到descriptor指定的buffer,而這個buffer又采用了zero-copy機制,所以直接將該buffer的地址copy給一個skb,再將此skb送到協議層處理,最后再調用 stmmac_rx_refill重新填充descriptor并設置buffer。之前descriptor指定的buffer地址已經被賦值給skb,由協議層負責該skb(buffer)的管理(釋放內存等)。

?

2.6.?總結:

這里有三種“一次獲取多個數據包”的情況

1)一次軟中斷可能會多次調用net_rx_action

2)net_rx_action可能會多次調用stmmac_poll

3)stmmac_poll處理多個descriptor

?

?

總結

以上是生活随笔為你收集整理的stmmac 中断处理的全部內容,希望文章能夠幫你解決所遇到的問題。

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