ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:96.18KB ,
资源ID:22192698      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/22192698.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(千兆网口Freescale ETSEC + Marvell 88E1111 uboot Linux 驱动分析Word格式.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

千兆网口Freescale ETSEC + Marvell 88E1111 uboot Linux 驱动分析Word格式.docx

1、如果CPU与PHY之间是RTBI接口,那么PCS层的工作在ETSEC中已经做完了,ETSEC中的TBI模块可以做PCS层的工作,PHY只需要做PMA和PMD的工作即可;如果CPU与PHY之间是SGMII接口,那么PHY只需要完成PMD的工作,ETSEC中的PCS由TBI完成,而PMA由CPU自带的Serdes模块完成。3 BD表结构在千兆以太网的驱动中,现在一般都使用一个叫BD表的东西来管理MAC层发送和接收的内存区域,如下图所示:在IMMR映射的寄存器空间中有两组寄存器TBASEn和RBASEn,分别为TxBD Ringn和RxBD Ringn的指针。MPC8314的ETSEC允许有8个Tx

2、BD Ring和8个RxBD Ring,他们都存放在内存的某个区域中。每个Buffer Descriptor都是有8个字节构成,两个字节的状态,两个字节的数据长度和四个字节的数据指针,这个指针指向内存的另一块地方,这才是真正存储发送接收数据的地方。Buffer Descriptor必须在网口初始化的时候初始化,并将自己的地址赋给TBASEn和RBASEn。在网口驱动程序中可以看到,每个BD Ring中的BD数量是可变的(我们设为64),而他们之间并没有指针连接,只是一段连续的空间,顺序下来的,所谓的环只是一个虚拟的概念,在最后一个BD时,需要将BD状态位中的W位(Wrap)置一,表示这是最后一

3、个BD,他的下一个BD就是第一个BD。如下图所示:下面一节将结合uboot源码分析一下网口初始化以及PHY配置的过程,再下一节会分析内核中的驱动。为什么先说uboot,因为在我看来,驱动程序就是分为两个部分,1按照Datasheet的说明去配置寄存器,2添加符合操作系统规范去融入操作系统。在uboot下系统很简单,代码一目了然,所以我们应该在boot下先把寄存器配置好,再去分析复杂的多的内核代码。这节分析uboot中的网口驱动代码。网口驱动函数列表函数名函数用途tsec_initialize()网口初始化函数tsec_init()网口启动函数tsec_local_mdio_write()MDI

4、O口写函数tsec_local_mdio_read()MDIO口读函数tsec_send()网口发送函数tsec_recv()网口接收函数tsec_configure_serdes()配置TBI PHY的函数fsl_serdes_init()Serdes模块初始化函数init_phy()PHY初始化函数adjust_link()根据PHY状态配置MAC的函数2 tsec_initialize()函数该函数为ETSEC的初始化函数,在该函数中要初始化eth_device结构和私有的tsec_private结构,并初始化PHY。int tsec_initialize(bd_t * bis, int

5、 index, char *devname)struct eth_device *dev;int i;struct tsec_private *priv;/*为dev分配空间*/dev = (struct eth_device *)malloc(sizeof *dev);if (NULL = dev)return 0;memset(dev, 0, sizeof *dev);/*为priv分配空间*/priv = (struct tsec_private *)malloc(sizeof(*priv);if (NULL = priv)/*从tsec_info 数组中取合适的值去初始化私有结构tse

6、c_private*/privlistnum_tsecs+ = priv;priv-regs = tsec_infoindex.regs;/每个tsec寄存器的基址phyregs = tsec_infoindex.miiregs;/PHY MDIO读写状态寄存器基址/*TBI PHY的MDIO读写状态寄存器基址*/phyregs_sgmii = tsec_infoindex.miiregs_sgmii;phyaddr = tsec_infoindex.phyaddr;/PHY 地址flags = tsec_infoindex.flags;ID = index;/*使用将priv结构体挂到dev

7、结构体下,挂载tsec的打开、关闭、发送、接收函数*/sprintf(dev-name, tsec_infoindex.devname);dev-iobase = 0;priv = priv;init = tsec_init;halt = tsec_halt;send = tsec_send;recv = tsec_recv;/*初始化IP地址*/for (i = 0; i maccfg1 |= MACCFG1_SOFT_RESET;udelay(2);/* Soft Reset must be asserted for 3 TX clocks */maccfg1 &= (MACCFG1_SO

8、FT_RESET);/*挂载MII口的读写函数*/#if defined(CONFIG_MII) | defined(CONFIG_CMD_MII) /& !defined(BITBANGMII)miiphy_register(dev-name, tsec_miiphy_read, tsec_miiphy_write);#endif/* 初始化PHY,并返回 */return init_phy(dev);3 init_phy()static int init_phy(struct eth_device *dev)struct tsec_private *priv = (struct tsec_

9、private *)dev-priv;struct phy_info *curphy;volatile tsec_t *regs = priv-regs;/*在TBIPA的寄存器中写入TBI PHY的地址*/tbipa = CONFIG_SYS_TBIPA_VALUE + priv-ID;asm(sync);/* 重启MII接口 */phyregs-miimcfg = MIIMCFG_RESET;miimcfg = MIIMCFG_INIT_VALUE;while (priv-miimind & MIIMIND_BUSY) ;/* 通过读PHY的2号3号寄存器获得该ETSEC外连的PHY的ID

10、,搜索phy_info数组,找到符合ID的PHY信息返回。 */curphy = get_phy_info(dev);if (curphy = NULL)phyinfo = NULL;printf(%s: No PHY found/n, dev-name);/*如果是SGMII的接口,需要使用TBI PHY,初始化TBI PHY,注意这里名字竟然叫serdes配置,Linux里面也这么叫,真是误人子弟啊。*/if (regs-ecntrl & ECNTRL_SGMII_MODE)tsec_configure_serdes(priv);/*在符合条件的PHY的phy_info数组中调用其初始化配

11、置函数*/phyinfo = curphy;phy_run_commands(priv, priv-phyinfo-config);return 1;4 phy_info结构Uboot中使用这个结构来完成phy的操作,所有的phy都要使用这个结构表示,下面是88E1111的phy_info结构:struct phy_info phy_info_M88E1111S = 0x01410cc,/ PHY IDMarvell 88E1111S,/ PHY名称4,(struct phy_cmd)/* 配置数组,在调用priv-config时将依次调用下面的内容,每个大括号内,第一个为PHY寄存器地址,第

12、二个为value*/* Reset and configure the PHY */MIIM_CONTROL, MIIM_CONTROL_RESET, NULL,/* Delay RGMII TX and RX */MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL,MIIM_ANAR, MIIM_ANAR_INIT, NULL,MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init,miim_end,/* 启动数组,在ETSEC启动的时候要依次调用。/* Status is read once to clear

13、old link state */MIIM_STATUS, miim_read, NULL,/* Auto-negotiate */MIIM_STATUS, miim_read, &mii_parse_sr,/* Read the status */MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr,miim_end,/* shutdown */,;需要注意的是,这个数组时uboot的源码中提供的,但是由于PHY与MAC之间接口使用的不同,这个数组中的内容需要根据需要,参考相应PHY的datasheet作出一定的修改。5 tse

14、c_init()该函数不会在初始化的时候调用,它在每当你使用网口的时候被调用,使用网口,不管是ping,还是tftp。int tsec_init(struct eth_device *dev, bd_t * bd)uint tempval;char tmpbufMAC_ADDR_LEN;/* 初始化MACCFG2和ECNTRL两个寄存器,这两个寄存器非常重要,它们主要是用来是配置MAC对PHY的接口。在这里先给个初始化的值,默认为GMII。*/tsec_halt(dev);maccfg2 = MACCFG2_INIT_SETTINGS;ecntrl = ECNTRL_INIT_SETTINGS

15、;/* 配置MAC地址。 MAC_ADDR_LEN; i+)tmpbufMAC_ADDR_LEN - 1 - i = dev-enetaddri;tempval = (tmpbuf0 24) | (tmpbuf1 16) | (tmpbuf2 link ? 0 : -1);6 startup_tsec()static void startup_tsec(struct eth_device *dev)/* 初始化BD表基址指针 */tbase = (unsigned int)(&rtx.txbdtxIdx);rbase = (unsigned int)(&rtx.rxbdrxIdx);/* 初始

16、化RX BD*/ PKTBUFSRX; i+) rtx.rxbdi.status =( RXBD_EMPTY | RXBD_INTERRUPT);rtx.rxbdi.length = 0;rtx.rxbdi.bufPtr = (uint) NetRxPacketsi;rtx.rxbdPKTBUFSRX - 1.status |= RXBD_WRAP;/*初始化TX BD*/ TX_BUF_CNT;rtx.txbdi.status = 0;rtx.txbdi.length = 0;rtx.txbdi.bufPtr = 0;rtx.txbdTX_BUF_CNT - 1.status |= TXBD

17、_WRAP;/*又要去找phy_info数组了,这次调用的是startup中的命令和函数*/if(priv-phyinfo)startup);/*根据PHY的Copper侧值配置MAC寄存器*/adjust_link(dev);/* 使能MACCFG1中的发送接收使能 */maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);/* 让DMA知道可以准备搬运了这里的DMA是ETSEC内部的,并不是CPU中的DMA单元。dmactrl |= DMACTRL_INIT_SETTINGS;tstat = TSTAT_CLEAR_THALT;dmactrl &= (DMACTRL_GRS | DMACTRL_GTS);参照上面的phy_info数组的startup中的内容得知这里phy_run_commands(priv, priv-st

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1