新路程------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
原创粉丝点击