三 Linux 网络驱动-MAC、PHY层驱动框架( 八 )


第 9 行 , 调用函数使能 enet 时钟 。
第 17 行 , 调用 rs 函数申请环形缓冲区  , 此函数里面会调用 和这两个函数分别实现发送队列和接收队 列缓冲区的申请 。
第 22 行 , 重启网络 , 一般连接状态改变、传输超时或者配置网络的时候都会调用函数 。
第 25 行 , 打开网卡的时候调用函数来探测并连接对应的 PHY 设备 。
第 29 行 , 调用函数使能 NAPI 调度 。
第 30 行 , 调用函数开启 PHY 设备 。
第 31 行 , 调用 ueues 函数来激活发送队列 。
函数简析
关闭网卡的时候函数就会执行 , 函数内容如下:
1 static int fec_enet_close(struct net_device *ndev)2 {3struct fec_enet_private *fep = netdev_priv(ndev);4 5phy_stop(fep->phy_dev);6 7if (netif_device_present(ndev)) {8napi_disable(&fep->napi);9netif_tx_disable(ndev);10fec_stop(ndev);11}1213phy_disconnect(fep->phy_dev);14fep->phy_dev = NULL;1516fec_enet_clk_enable(ndev, false);17pm_qos_remove_request(&fep->pm_qos_req);18pinctrl_pm_select_sleep_state(&fep->pdev->dev);19pm_runtime_put_sync_suspend(ndev->dev.parent);20fec_enet_free_buffers(ndev);2122return 0;23 }
第 5 行 , 调用函数停止 PHY 设备 。
第 8 行 , 调用函数关闭 NAPI 调度 。
第 9 行 , 调用函数关闭 NAPI 的发送队列 。
第 10 行 , 调用函数关闭 I. 的 ENET 外设 。
第 13 行 , 调用函数断开与 PHY 设备的连接 。
第 16 行 , 调用函数关闭 ENET 外设时钟 。
第 20 行 , 调用 s 函数释放发送和接收的环形缓冲区内存 。
函数简析
I. 的网络数据发送是通过函数来完成的 , 这个函数将上层传递 过来的中的数据通过硬件发送出去 , 函数源码如下:
1 static netdev_tx_t fec_enet_start_xmit(struct sk_buff *skb,struct net_device *ndev)2 {3struct fec_enet_private *fep = netdev_priv(ndev);4int entries_free;5unsigned short queue;6struct fec_enet_priv_tx_q *txq;7struct netdev_queue *nq;8int ret;9 10queue = skb_get_queue_mapping(skb);11txq = fep->tx_queue[queue];12nq = netdev_get_tx_queue(ndev, queue);1314if (skb_is_gso(skb))15ret = fec_enet_txq_submit_tso(txq, skb, ndev);16else17ret = fec_enet_txq_submit_skb(txq, skb, ndev);18if (ret)19return ret;2021entries_free = fec_enet_get_free_txdesc_num(fep, txq);22if (entries_free <= txq->tx_stop_threshold)23netif_tx_stop_queue(nq);2425return NETDEV_TX_OK;26 }
此函数的参数第一个参数 skb 就是上层应用传递下来的要发送的网络数据 , 第二个参数 ndev 就是要发送数据的设备 。
第 14 行 , 判断 skb 是否为 GSO() , 如果是 GSO 的话就通过 tso 函数发送 , 如果不是的话就通过 skb 发送 。这里简 单讲一下 TSO 和 GSO:
TSO:全称是 TCP , 利用网卡对大数据包进行自动分段处理 , 降低 CPU 负载 。
GSO:全称是 , 在发送数据之前先检查一下网卡是否支持 TSO ,  如果支持的话就让网卡分段 , 不过不支持的话就由协议栈进行分段处理 , 分段处理完成以后再 交给网卡去发送 。
第 21 行 , 通过函数获取剩余的发送描述符数量 。
第 23 行 , 如果剩余的发送描述符的数量小于设置的阈值()的话就调用函数来暂停发送 , 通过暂停发送来通知应用层停止向网络发送 skb , 发送中断中 会重新开启的 。
中断服务函数简析
前面说了 I. 的网络数据接收采用 NAPI 框架 , 所以肯定要用到中断 。函 数会初始化网络中断 , 中断服务函数为  , 函数内容如下: