Linux stmac网卡代码分析----probe

probe

主要分析一下驱动的主要框架,必要地方细致分析下

文件位置:

  • drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
    从文件的最后看起:
    module_pci_driver(stmmac_pci_driver);

stmmac_pci_driver结构体如下,里面包含了id_table、probe、remove。id_table里包含了支持设备的vender id、device id,当扫描到支持的pcie设备时(把venderid 和device id 和table里的id对比)就调用probe函数

static struct pci_driver stmmac_pci_driver = { .name = STMMAC_RESOURCE_NAME,.id_table = stmmac_id_table,.probe = stmmac_pci_probe,.remove = stmmac_pci_remove,.driver         = { .pm     = &stmmac_pm_ops,},  
};

以下是stmmac_pci_probe函数的一些主要调用
在这里插入图片描述
主要执行了以下操作

  1. 为plat_stmmacenet_data分配了空间
  2. 填充plat_stmmacenet_data
  3. 使能pci
  4. 填充plat_stmmacenet_data中一些网卡参数信息
  5. 获取pci的base address
  6. 调用stmmac_dvr_probe

接下来就进入到stmmac_dvr_probe函数,在此函数中主要完成net_device结构体的分配,和填充,填充中最重要的是设置了net_device结构体中的netdev_ops,最后使用register_netdev(ndev)注册到内核

stmmac_dvr_probe

在这里插入图片描述

int stmmac_dvr_probe(struct device *device,struct plat_stmmacenet_data *plat_dat,struct stmmac_resources *res)
{struct net_device *ndev = NULL;struct stmmac_priv *priv;u32 queue, maxq;int ret = 0;ndev = alloc_etherdev_mqs(sizeof(struct stmmac_priv),MTL_MAX_TX_QUEUES,MTL_MAX_RX_QUEUES);SET_NETDEV_DEV(ndev, device);/*对priv的填充*/priv = netdev_priv(ndev);priv->device = device;priv->dev = ndev;//对ethtool的支持stmmac_set_ethtool_ops(ndev);priv->pause = pause;priv->plat = plat_dat;priv->ioaddr = res->addr;priv->dev->base_addr = (unsigned long)res->addr;priv->dev->irq = res->irq;priv->wol_irq = res->wol_irq;priv->lpi_irq = res->lpi_irq;/***************/if (res->mac)memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);dev_set_drvdata(device, priv->dev);/* Verify driver arguments */stmmac_verify_args();/* Allocate workqueue */priv->wq = create_singlethread_workqueue("stmmac_wq");if (!priv->wq) {dev_err(priv->device, "failed to create workqueue\n");ret = -ENOMEM;goto error_wq;}INIT_WORK(&priv->service_task, stmmac_service_task);/* Override with kernel parameters if supplied XXX CRS XXX* this needs to have multiple instances*/if ((phyaddr >= 0) && (phyaddr <= 31))priv->plat->phy_addr = phyaddr;/* Init MAC and get the capabilities */ret = stmmac_hw_init(priv);if (ret)goto error_hw_init;/* Configure real RX and TX queues */netif_set_real_num_rx_queues(ndev, priv->plat->rx_queues_to_use);netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);//设置网卡的opsndev->netdev_ops = &stmmac_netdev_ops;ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |NETIF_F_RXCSUM;ret = stmmac_tc_init(priv, priv);if (!ret) {ndev->hw_features |= NETIF_F_HW_TC;}if ((priv->plat->tso_en) && (priv->dma_cap.tsoen)) {ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;priv->tso = true;dev_info(priv->device, "TSO feature enabled\n");}ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED/* Both mac100 and gmac support receive VLAN tag detection */ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
#endif
priv->msg_enable = netif_msg_init(debug, default_msg_level);/* MTU range: 46 - hw-specific max */ndev->min_mtu = ETH_ZLEN - ETH_HLEN;if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00))ndev->max_mtu = JUMBO_LEN;else if (priv->plat->has_xgmac)ndev->max_mtu = XGMAC_JUMBO_LEN;elsendev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);/* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu* as well as plat->maxmtu < ndev->min_mtu which is a invalid range.*/if ((priv->plat->maxmtu < ndev->max_mtu) &&(priv->plat->maxmtu >= ndev->min_mtu))ndev->max_mtu = priv->plat->maxmtu;else if (priv->plat->maxmtu < ndev->min_mtu)dev_warn(priv->device,"%s: warning: maxmtu having invalid value (%d)\n",__func__, priv->plat->maxmtu);if (flow_ctrl)priv->flow_ctrl = FLOW_AUTO;	/* RX/TX pause on *//* Setup channels NAPI */maxq = max(priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);for (queue = 0; queue < maxq; queue++) {struct stmmac_channel *ch = &priv->channel[queue];ch->priv_data = priv;ch->index = queue;if (queue < priv->plat->rx_queues_to_use)ch->has_rx = true;if (queue < priv->plat->tx_queues_to_use)ch->has_tx = true;netif_napi_add(ndev, &ch->napi, stmmac_napi_poll,NAPI_POLL_WEIGHT);}mutex_init(&priv->lock);/*如果设置了plat->clk_csr那么CSR clock在运行中将会是固定不变的,如果没有设置,那么click会根据csr实际的时钟输入动态的设置*/if (!priv->plat->clk_csr)stmmac_clk_csr_set(priv);elsepriv->clk_csr = priv->plat->clk_csr;//检查是否支持Physical Coding Sublayerstmmac_check_pcs_mode(priv);if (priv->hw->pcs != STMMAC_PCS_RGMII  &&priv->hw->pcs != STMMAC_PCS_TBI &&priv->hw->pcs != STMMAC_PCS_RTBI) {/* MDIO bus Registration */ret = stmmac_mdio_register(ndev);if (ret < 0) {dev_err(priv->device,"%s: MDIO bus (id: %d) registration failed",__func__, priv->plat->bus_id);goto error_mdio_register;}}ret = register_netdev(ndev);return ret;
error_netdev_register:if (priv->hw->pcs != STMMAC_PCS_RGMII &&priv->hw->pcs != STMMAC_PCS_TBI &&priv->hw->pcs != STMMAC_PCS_RTBI)stmmac_mdio_unregister(ndev);
error_mdio_register:for (queue = 0; queue < maxq; queue++) {struct stmmac_channel *ch = &priv->channel[queue];netif_napi_del(&ch->napi);}
error_hw_init:destroy_workqueue(priv->wq);
error_wq:free_netdev(ndev);return ret;
}
EXPORT_SYMBOL_GPL(stmmac_dvr_probe);

下面看看stmmac_hw_init(priv),这里有硬件相关的设置,特别是设置了操作硬件的ops,函数中主要调用了stmmac_hwif_init函数。

int stmmac_hwif_init(struct stmmac_priv *priv)
{bool needs_xgmac = priv->plat->has_xgmac;bool needs_gmac4 = priv->plat->has_gmac4;bool needs_gmac = priv->plat->has_gmac;const struct stmmac_hwif_entry *entry;struct mac_device_info *mac;bool needs_setup = true;int i, ret;u32 id;if (needs_gmac) {id = stmmac_get_id(priv, GMAC_VERSION);} else if (needs_gmac4 || needs_xgmac) {id = stmmac_get_id(priv, GMAC4_VERSION);} else {id = 0;}/* Save ID for later use */priv->synopsys_id = id;/* Lets assume some safe values first */priv->ptpaddr = priv->ioaddr +(needs_gmac4 ? PTP_GMAC4_OFFSET : PTP_GMAC3_X_OFFSET);priv->mmcaddr = priv->ioaddr +(needs_gmac4 ? MMC_GMAC4_OFFSET : MMC_GMAC3_X_OFFSET);/* Check for HW specific setup first */if (priv->plat->setup) {mac = priv->plat->setup(priv);needs_setup = false;} else {mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);}if (!mac)return -ENOMEM;/* 为网卡设置硬件操作相关的回调函数*/for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) {/*在stmmac_hw数组中选取一个entry*/entry = &stmmac_hw[i];/*进行筛选*/if (needs_gmac ^ entry->gmac)continue;if (needs_gmac4 ^ entry->gmac4)continue;if (needs_xgmac ^ entry->xgmac)continue;/* Use synopsys_id var because some setups can override this */if (priv->synopsys_id < entry->min_id)continue;/* 到这里表示已经选到合适的entry,将它保存到mac结构体 */mac->desc = mac->desc ? : entry->desc;mac->dma = mac->dma ? : entry->dma;mac->mac = mac->mac ? : entry->mac;mac->ptp = mac->ptp ? : entry->hwtimestamp;mac->mode = mac->mode ? : entry->mode;mac->tc = mac->tc ? : entry->tc;/*把mac挂接到priv->hw*/priv->hw = mac;priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off;priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off;/* Save quirks, if needed for posterior use */priv->hwif_quirks = entry->quirks;return 0;}dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n",id, needs_gmac, needs_gmac4);return -EINVAL;
}

以下是对上述代码用到的数据结构的一个整理,以便于把握整体脉络
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面向对象(1) —— 封装

目录一、封装的概念二、类的封装以及使用三、访问修饰符四、属性封装的实现五、方法封装的实现六、UML类图七、类的构造方法与可重载八、this关键字九、static关键字十、方法重载&#xff1a;overload十一、包&#xff1a;package一、封装的概念 将字段&#xff08;C结构体中的…

太阳能板清洗机器人科沃斯_科沃斯推出水清洗扫地机器人 要把打扫做的更彻底...

传统的扫地机器人只能对家里的灰尘做简单清扫&#xff0c;要想打扫的更彻底&#xff0c;还是得靠周末自己拿上工具水洗一遍。现在科沃斯就推出了可以帮你用水清洗地面的扫地机器人&#xff0c;不用再担心地面清洁不干净。科沃斯扫地机器人的水清洁方式一共分为五步&#xff0c;…

linux下源码软件包的安装

我们在使用linux做服务器的时候&#xff0c;因为linux自带的软件包都有些老&#xff0c;不是最新的&#xff0c;但是有时候我们为了使用最新的软件&#xff0c;会使用最新的软件的源码来进行安装。所以我们需要用心去做了...在我们拿到一个软件的源码时&#xff0c;源码一般都是…

react-native 打包apk 并解决 图片 不出现问题

react-native官网打包apk方法&#xff1a;https://reactnative.cn/docs/signed-apk-android/ 解决办法&#xff1a; 找到项目 android目录下 gradle.properties文件 打开加入如下代码&#xff1a; android.enableAapt2false这段代码非常重要 官网缺少 。不然打包apk图片不出现。…

龙芯派2亚克力外壳

0x0 龙芯派自带的亚克力顶板没有风扇的孔位&#xff0c;在长时间运行时亚克力板很烫&#xff0c;因此我设计了个带风扇孔位的亚克力顶板 效果如下&#xff1a; 风扇规格 4X4风扇 供电由龙芯派的GPIO上的5V管脚供电 使用方法 1.某宝搜索亚克力板定制 2. 将本文件发送给店家…

Java面向对象(2) —— 继承

目录前言继承的概念和实现extends关键字super关键字继承过来的属性和方法的权限研究方法重写OverrideObject根类常见方法toString()常把toString()方法重写后应用equals()重写&#xff1a;判断两个对象p1和p2特征是否相同IDEA的重写模板&#xff1a;敲equals可选择的方案之一St…

linux下达梦数据库启动_linux 平台 达梦DM 7 数据库 启动与关闭

在之前的博客我们了解了Linux 平台下DM7的安装&#xff0c;如下&#xff1a;在本篇博客里我们了解一下DM7的启动和关闭。1 背景知识说明1.1 DM DB的启动过程DM的启动主要按如下三个步骤进行&#xff1a;1.读取配置文件(.ini)2.读取控制文件(dm.ctl)3.读取重做日志文件(.log) 和…

a与a:link、a:visited、a:hover、a:active

起因&#xff1a; a与a:link的CSS代码处&#xff0c;忽觉茫茫然不知所以然&#xff1a;这a的CSS和a:link什么关系&#xff1f;貌似有些冲突啊&#xff1f;还有这a:link、 a:visited、a:hover、a:active伪类之间有没有相互制约和继承关系&#xff1f; 过程&#xff1a; 使用软件…

dpdk18.11 收发包流程分析

pci probe RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd); 宏注册了net_ixgbe driver到pci bus rte_ixgbe_pmd 的定义如下 static struct rte_pci_driver rte_ixgbe_pmd {.id_table pci_id_ixgbe_map,.drv_flags RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,.pr…

人工智能芯片龙头之一gti概念股_AI芯片龙头寒武纪IPO价格定了!概念股全名单收好...

寒武纪披露首次公开发行股票并在科创板上市发行公告&#xff0c;确定发行价格为64.39元/股&#xff0c;本次科创板上市发行剔除无效报价和最高报价后剩余报价拟申购总量为3,405,910万股&#xff0c;整体申购倍数为回拨前网下初始发行规模的1327.12倍。战略配售投资者包含中信证…

x86汇编语言-从实模式到保护模式----第五章

注释由;开始。将显存映射到地址空间里&#xff0c;0xB8000~0xBFFFF。Intel的处理器不允许将一个立即数传送到段寄存器&#xff0c;只允许这样的指令&#xff1a;mov 段寄存器&#xff0c;通用寄存器 mov 段寄存器&#xff0c;内存单元 为了方便&#xff0c;多数汇编语言编译器允…

Java面向对象(3) —— 抽象类、接口、内部类、匿名内部类

目录抽象类&#xff08;abstract&#xff09;抽象类的使用方法抽象类的应用&#xff1a;模板方法模式接口接口的概念接口的特点接口的使用接口实现与抽象类继承的区别接口的多继承内部类概念成员内部类&#xff08;使用较多&#xff09;及应用创建成员内部类的实例在成员内部类…

Kohana和Zencart

2019独角兽企业重金招聘Python工程师标准>>> 我有一个Kohana php框架但是客户求和zencart系统结合。我有一个想法是Kohana重新zencart 有没有人用过&#xff1f;应该没有吧 Kohana 是一款纯 PHP5 的框架&#xff0c;基于 MVC 模式开发&#xff0c; 它的特点就是高安…

Linux stmac网卡代码分析 -- open

Open stmmac_open是在stmmac_netdev_ops结构体里的&#xff0c;这个ops在probe时就已经注册到了net_device结构体里&#xff0c;在网卡对于stmmac_open函数调用的时间我还不确定是否是在网卡link up时 下面看看stmmac_open函数&#xff0c;文件位置&#xff1a; drivers/net/…

g++ linux 编译开栈_方舟编译器编译hello world踩坑全记录

闲来无事&#xff0c;看到方舟编译器完整开源&#xff0c;于是打算拿来试着编译一个东西来&#xff0c;接下来把踩过的一些坑记录一下。参考文档方舟编译器的官网是OpenArkCompiler​www.openarkcompiler.cn但是这个网站上的文档其实是过时的&#xff0c;没有更新过的&#xff…

绘制自定义键盘

先看下微信当中的自带的数字键盘 这种实现方式比较简单&#xff0c;可以直接用inline-block标签&#xff0c;设置每行平均宽度&#xff0c;比如一行要放4个按钮&#xff0c;可以那么宽度就可以设为25%&#xff0c;同时要注意设置css样式为box-sizing: border-box,这样在设置边框…

配置管理小报100329:脚本中ftp命令无法自动输入密码怎么办?

为什么80%的码农都做不了架构师&#xff1f;>>> 知识点&#xff1a; 作者&#xff1a;王&#xff08;zbwangjian.cn&#xff09; 脚本中ftp命令无法自动输入密码怎么办&#xff1f;参考&#xff1a; http://www.linji.cn/post/1620/ http://www.hamo…

linux下使用网易邮箱发邮件

0x0 最近要写个脚本监视系统运行情况&#xff0c;有异常及时通过邮件通知我。 本次测试中使用网易的邮箱作为邮件发送服务器&#xff08;邮箱账号需要开启smtp服务如下图&#xff09;&#xff0c;由于网易邮箱验证比较严格&#xff0c;需要进行一些额外操作才可以正常发送邮件…

Java面向对象(4) ——多态

目录多态的概念对象上下转型多态应用之打印机多态的概念 多态是指同一个操作作用于某一类对象&#xff0c;可以有不同的解释&#xff0c;产生不同的执行结果。比如&#xff1a;猫吃鱼、狗吃肉、人吃米饭。 多态存在的三个必要条件: 需要存在继承&#xff08;extends&#xf…

ffmpeg 转换flv压缩大小_ffmpeg转换参数和压缩输出大小的比率 参考 最新版本FFMPEG...

https://blog.cnlabs.NET/3668.htmlffmpeg 转换压缩比例FFMPEG如果是压缩为FLV文件 3个编码可选1. -c:v flv 标准FLV编码 这个好处是速度快 清晰度高的话 视频文件会比较大2. -c:v vp6 VP6编码 这个大家都很少使用 其实这个也算不错3. -c:v libx264 H.264编码 估计使用这个的比…