新路程------imx6 网卡驱动(1)
来源:互联网 发布:pdf文档编辑软件 编辑:程序博客网 时间:2024/06/05 05:04
imx6芯片手册上已经写了fec.c是网卡驱动,那么就顺着网卡驱动看看网络设备是怎么建立起来的
static int __devinitfec_probe(struct platform_device *pdev){struct fec_enet_private *fep;struct fec_platform_data *pdata;struct net_device *ndev; //网络设备的结构体出现了int i, irq, ret = 0;struct resource *r;r = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (!r)return -ENXIO;r = request_mem_region(r->start, resource_size(r), pdev->name);if (!r)return -EBUSY;/* Init network device */初始化网络设备ndev = alloc_etherdev(sizeof(struct fec_enet_private));
*alloc_netdev_mqs - allocate network device *@sizeof_priv:size of private data to allocate space for *@name:device name format string *@setup:callback to initialize device *@txqs:the number of TX subqueues to allocate *@rxqs:the number of RX subqueues to allocateif (!ndev) {ret = -ENOMEM;goto failed_alloc_etherdev;}SET_NETDEV_DEV(ndev, &pdev->dev);/* setup board info structure */fep = netdev_priv(ndev);fep->hwp = ioremap(r->start, resource_size(r));fep->pdev = pdev;if (!fep->hwp) {ret = -ENOMEM;goto failed_ioremap;}platform_set_drvdata(pdev, ndev);pdata = pdev->dev.platform_data;if (pdata)fep->phy_interface = pdata->phy;if (pdata->gpio_irq > 0) {gpio_request(pdata->gpio_irq, "gpio_enet_irq");gpio_direction_input(pdata->gpio_irq);irq = gpio_to_irq(pdata->gpio_irq);ret = request_irq(irq, fec_enet_interrupt,IRQF_TRIGGER_RISING, pdev->name, ndev);}}fep->clk = clk_get(&pdev->dev, "fec_clk");fep->mdc_clk = clk_get(&pdev->dev, "fec_mdc_clk");clk_enable(fep->clk);ret = fec_enet_init(ndev); //获取eth地址,rx,tx的buffer起始地址ret = fec_enet_mii_init(pdev); //配置mii busif (fec_ptp_malloc_priv(&(fep->ptp_priv))) {if (fep->ptp_priv) {fep->ptp_priv->hwp = fep->hwp;ret = fec_ptp_init(fep->ptp_priv, pdev->id);if (ret)printk(KERN_WARNING "IEEE1588: ptp-timer is unavailable\n");elsefep->ptimer_present = 1;} }/* Carrier starts down, phylib will bring it up */netif_carrier_off(ndev);clk_disable(fep->clk);INIT_DELAYED_WORK(&fep->fixup_trigger_tx, fixup_trigger_tx_func);ret = register_netdev(ndev); //网络设备注册return 0;return ret;}
这里mii bus已经ok了,要把mii bus和phy链接起来的函数是
static intfec_enet_open(struct net_device *ndev){struct fec_enet_private *fep = netdev_priv(ndev);struct fec_platform_data *pdata = fep->pdev->dev.platform_data;int ret;if (fep->use_napi)napi_enable(&fep->napi);/* I should reset the ring buffers here, but I don't yet know * a simple way to do that. */clk_enable(fep->clk);ret = fec_enet_alloc_buffers(ndev);if (ret)return ret;/* Probe and connect to PHY when open the interface */ //链接到phyret = fec_enet_mii_probe(ndev);if (ret) {fec_enet_free_buffers(ndev);return ret;}phy_start(fep->phy_dev);netif_start_queue(ndev);fep->opened = 1;ret = -EINVAL;if (pdata->init && pdata->init(fep->phy_dev))return ret;return 0;}
这个函数执行之后,数据链路层和物理层就联系起来了
看看这个probe
static int fec_enet_mii_probe(struct net_device *ndev){struct fec_enet_private *fep = netdev_priv(ndev);struct phy_device *phy_dev = NULL;char mdio_bus_id[MII_BUS_ID_SIZE];char phy_name[MII_BUS_ID_SIZE + 3];int phy_id;int dev_id = fep->pdev->id;fep->phy_dev = NULL;/* check for attached phy */for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {if ((fep->mii_bus->phy_mask & (1 << phy_id)))continue;if (fep->mii_bus->phy_map[phy_id] == NULL)continue;if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)continue;if (dev_id--)continue;strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);break;}if (phy_id >= PHY_MAX_ADDR) {printk(KERN_INFO "%s: no PHY, assuming direct connection ""to switch\n", ndev->name);strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE);phy_id = 0;}snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);printk("matt===============fec.c\n");phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0, //这个就是链接函数fep->phy_interface);/* enable phy pause frame for any platform */phy_dev->supported |= ADVERTISED_Pause;phy_dev->advertising = phy_dev->supported;fep->phy_dev = phy_dev;fep->link = 0;fep->full_duplex = 0;printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] ""(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name,fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),fep->phy_dev->irq);return 0;}
暂时先写这么多,关于网络设备的那些配置信息怎么来的将后面再写
0 0
- 新路程------imx6 网卡驱动(1)
- 新路程------imx6测试网卡phy
- 新路程------英飞凌imx6的lvds驱动
- 新路程------imx6的uart小结(1)
- 新路程------imx6 uart和串口(1)
- 新路程------imx6 lvds ioctl
- 新路程------imx6关闭屏保
- 新路程------imx6 gpio设置
- 新路程------imx6 wtd摘要
- 新路程------imx6 uboot环境变量的初始化(1)
- 新路程------imx6的sd 和emmc部分(1)
- 新路程------imx6 uart和串口(4)
- 新路程------imx6 lvds屏设置fbinfo
- 新路程------imx6动态修改lvds channel
- 新路程------imx6动态修改fb参数
- 新路程------imx6 编译c可执行文件
- 新路程------imx6 sd卡部分摘要
- 新路程------imx6 内核层读写寄存器
- jquery下拉模糊搜索
- httpclient post 传json返回json
- Linux下用SCP无需输入密码获取文件
- devstack安装
- LayoutInflater 实例的三种方式获得方式
- 新路程------imx6 网卡驱动(1)
- 从程序员到项目经理
- 实时搜索 elasticsearch vs solr
- STM32-StdPeriph函数库使用的预备知识
- CAD2009开发笔记(一)
- Linux下MySQL数据库操作的常用命令行
- Android Fragment getActivity返回null解决
- Discuz!论坛教程之设置帖子被支持/反对(顶/踩)后自动提升主题
- Linux常用工具安装和vim设置的命令实现