- 收藏
- 点赞
- 分享
- 举报
【已解决Kernel以及Uboot】HI3535 U-boot添加网卡AR8035支持
[i=s] 本帖最后由 ngswfx 于 2016-5-23 10:37 编辑 [/i]
这几天搞5百万解码 雄迈主板,3535芯片,AR8035网络芯片。
哪位大侠做过,给点思路,只要是做过非芯片内网络的即可,都一样,我希望知道流程。另外哪位大侠有适合AR8035用的驱动C文件能否贡献一下,我从网上找的感觉不是给这个东西用的,一点点摸索太费劲。
目前我的初步计划是,编译好所有的3535 bin文件,然后在rootfs中,通过ko的方法,先测试我从网上找到的AR8035 ko是否能用,如果可以用,我在研究源码,往U-boot里面添加移植。 ////////////////////////////////
U-boot已经编译完成,准备弄kernel了,目前由于没有U-boot网络支持,不能TFTP只能通过USB方式,
fatload usb 0 0x81050000 3535_uimage_full.bin 装载刷flash /////////////////////////////////////////////////////////////////2016_5_10
2016_5_11进度 已经在3536中发现了at803x.c文件 1、将3536中的/home/ngs/Hi3536_SDK_V2.0.2.0/osdrv/opensource/kernel/linux-3.10.y/drivers/net/phy/at803x.c文件拷贝到3535对应目录 2、修改/home/ngs/Hi3536_SDK_V2.0.2.0/osdrv/opensource/kernel/linux-3.10.y/drivers/net/phy中的makefile,添加一行,仿照3536中做即可。
obj-$(CONFIG_AT803X_PHY) += at803x.o
3、在/home/ngs/Hi3535_SDK_V1.0.2.0/osdrv/kernel/linux-3.4.y/arch/arm/configs目录下, hi3535_mini_defconfig hi3535_full_defconfig hi3535_full_slave_defconfig三个文件中 添加一行 CONFIG_AT803X_PHY=y
4、还是这个目录下/home/ngs/Hi3535_SDK_V1.0.2.0/osdrv/kernel/linux-3.4.y/arch/arm/configs,Kconfig文件,仿照添加
config AT803X_PHY tristate "Drivers for the AT803X PHYs" ---help--- Currently supports the AT803X //////////////////////////////////////////////////////////////////暂时只搞到这里,让menuConfig有8035选项了,其他部分还在研究,主要是让代码走到8035里面
[color=Red]kernel部分已经搞定。 U-boot暂没有迫切需求,放弃。[/color]
kernel解决过程帖子 http://www.ebaina.com/bbs/forum.php?mod=viewthread&tid=11266&extra=page%3D1%26filter%3Ddigest%26digest%3D1
U-boot协助解决帖子:http://www.ebaina.com/bbs/forum.php?mod=viewthread&tid=11380&page=1&extra=#pid30448
/////////////////////////////////////////////////////////////////////////////[color=Red]2016_5_21 U-boot 8035调通[/color] ///////////////////////////////////最主要是: [color=Red]/home/ngs/Hi3535_SDK_V1.0.2.0/osdrv/uboot/u-boot-2010.06/common/miiphyutil.c[/color] 文件中的miiphy_speed函数,对8035的判断失效了,判断不准,不论插入100M网络还是1000m网络,都返回了1000M的结果,为此需要针对8035做特殊判断。
我这边8035的0xa,如果是百兆,这个值为0,如果是千兆,寄存器里面有数据,3C00,可以研究用正规的方法,判断更加准确一些。
但由于这个原因的存在,导致调试异常费劲。 ////////////////////////////////////////////////////////////[color=Red]miiphy_speed[/color]的结果,将直接导致对3535 STMMAC寄存器配置成百兆还是千兆,这就使得无法通讯。 //当然,上述仅仅是针对百兆千兆,一个关键点。
int miiphy_speed (char devname, unsigned char addr) { u16 bmcr, anlpar; u16 btsr, val; [color=Red] //针对8035判断当前连接是100M还是1000M 0xa的值在千兆百兆时比较特殊,如果百兆,这个值可能是0或者1 //应该有更优雅准确的判断方法,这是临时写的,当然,直接按照8035的文档,判断才会准确 //也可以仔细研究miiphy_speed内部的流程判断,针对8035做调整[/color] miiphy_read(devname,addr,PHY_1000BTSR,&val); if(val==0x0||val==0x1) return _100BASET; ///////////////////////////////////////////////////////////////////////////////////// miiphy_read(devname,addr,PHY_BMSR,&val); if(val & BMSR_ESTATEN){ [color=Blue]/ /或者将下面这几行取消掉,目前我就是这么干的 //if (miiphy_is_1000base_x (devname, addr)) { // printf ("HY 1000BASE-X status\n"); // return _1000BASET; //}[/color] /
- No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set. / / Check for 1000BASE-T. */ if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) { printf ("HY 1000BT status\n"); goto miiphy_read_failed; } if (btsr != 0xFFFF &&(btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) { return _1000BASET; } } ..........省略.......................... ////////////////////////////////////////////// 这个百兆千兆,如果没有判断对,将直接导致无法通信,因为8035芯片本身自己会判断(也就是插入100M或者千兆网线,好多寄存器不一样)。但此时3535可不知道(必须主动读取,然后判断)。如果判断错误,8035按照网口百兆交互,3535按照千兆,造成通信不对。
stmmac.c当中,stmmac_net_adjust_link函数内,会读取PHY芯片的寄存器判断是什么网络类型,然后,会写3535的寄存器,写入的数据是不一样的。
千兆写入:
writel(0x280c, ld->iobase_gmac + MAC_CTRL_REG);
百兆写入:
ifdef CONFIG_TNK
newval |= 0x3;
endif
writel(0xe80c, ld->iobase_gmac + MAC_CTRL_REG);
所以调试这个8035,一定连接一个千兆交换机调试,否则采用海斯默认的SDK uboot修改的话,累死你,也找不到原因。我这边正好2种交换机都有,所以尝试了一下,发现了问题。
///////////////////////////////////////////////////////////////////////////////// //////////////////mdio.c当中,找到8035 PHY后,需要配置一下
////////////////////////////////////////////////
define BIT(x) (1 << (x))
define AT803X_WOL_ENABLE 0x01
define AT803X_INTR_ENABLE 0x12
define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13)
define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
define AT803X_INTR_ENABLE_WOL BIT(0)
define AT803X_INTR_STATUS 0x13
define AT803X_SMART_SPEED 0x14
define AT803X_INTR_ENABLE 0x12
define AT803X_WOL_ENABLE 0x01
define AT803X_DEVICE_ADDR 0x03
define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
define AT803X_MMD_ACCESS_CONTROL 0x0D
define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
define AT803X_FUNC_DATA 0x4003
define AT803X_DEBUG_ADDR 0x1D
define AT803X_DEBUG_DATA 0x1E
define AT803X_DEBUG_REG_0 0x00
define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
define AT803X_DEBUG_REG_5 0x05
define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
include "mdio.h"
include "ctrl.h"
include "stmmac.h"
struct stmmac_mdio_local stmmac_mdio_local_device;
static int at803x_debug_reg_read( unsigned char phyaddr,u16 reg) { int ret; ret = stmmac_mdio_write(&stmmac_mdio_local_device,phyaddr, AT803X_DEBUG_ADDR, reg); if (ret < 0) return ret; return stmmac_mdio_read(&stmmac_mdio_local_device,phyaddr, AT803X_DEBUG_DATA); } static int at803x_debug_reg_mask( unsigned char phyaddr,u16 reg,u16 clear, u16 set) { u16 val; int ret; ret = at803x_debug_reg_read(phyaddr,reg); if (ret < 0) return ret; val = ret & 0xffff; val &= ~clear; val |= set; return stmmac_mdio_write(&stmmac_mdio_local_device,phyaddr, AT803X_DEBUG_DATA, val); } static inline int at803x_enable_rx_delay( unsigned char phyaddr) { return at803x_debug_reg_mask(phyaddr, AT803X_DEBUG_REG_0, 0, AT803X_DEBUG_RX_CLK_DLY_EN); }
static inline int at803x_enable_tx_delay( unsigned char phyaddr) { return at803x_debug_reg_mask(phyaddr,AT803X_DEBUG_REG_5, 0,AT803X_DEBUG_TX_CLK_DLY_EN); } static int at803x_init(char devname, unsigned char phyaddr) { printf("at803x_init!\n"); const u8 mac; int ret; //const u8 *devname="0:2"; //const u8 phyaddr=0x02;
unsigned int offsets[] = {
AT803X_LOC_MAC_ADDR_32_47_OFFSET,
AT803X_LOC_MAC_ADDR_16_31_OFFSET,
AT803X_LOC_MAC_ADDR_0_15_OFFSET,
};
if 1
printf("config device %s \n",devname);
int i=0;
for (i = 0; i < 3; i++) {
miiphy_write(devname, phyaddr, AT803X_MMD_ACCESS_CONTROL,AT803X_DEVICE_ADDR);
miiphy_write(devname, phyaddr, AT803X_MMD_ACCESS_CONTROL_DATA,offsets);
miiphy_write(devname, phyaddr, AT803X_MMD_ACCESS_CONTROL,AT803X_FUNC_DATA);
miiphy_write(devname, phyaddr, AT803X_MMD_ACCESS_CONTROL_DATA,mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
}
short unsigned int value;
miiphy_read(devname, phyaddr, AT803X_INTR_ENABLE, &value);
value |= AT803X_INTR_ENABLE_WOL;
value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
value |= AT803X_INTR_ENABLE_LINK_FAIL;
value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
ret = miiphy_write(devname, phyaddr, AT803X_INTR_ENABLE, value);
//miiphy_write(devname, phyaddr, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE);
//miiphy_write(devname, phyaddr, AT803X_SMART_SPEED, context->smart_speed);
[color=Red]//下面这2句非常关键,必须有,否则不通[/color]
at803x_enable_rx_delay(phyaddr);
at803x_enable_tx_delay(phyaddr);
endif
if 0
miiphy_write(devname, phyaddr,0xA,0x3C00);
miiphy_write(devname, phyaddr,0xD,0x0000);
miiphy_write(devname, phyaddr,0xE,0x0000);
miiphy_write(devname, phyaddr,0x11,0xBC5C);
miiphy_write(devname, phyaddr,0x1E,0x0100); //2D47
endif
return 0;
}
////////////////////////我这里放到了get_phy_device里面
unsigned int get_phy_device(char *devname, unsigned char phyaddr) { u32 phy_id; u16 id1, id2; printf("get_phy_device devname: %s phyaddr:%x \n",devname,phyaddr);
miiphy_read(devname, phyaddr, PHY_PHYIDR1, &id1);
miiphy_read(devname, phyaddr, PHY_PHYIDR2, &id2);
phy_id = (id1 & 0xffff) << 16;
phy_id |= (id2 & 0xffff);
/* If the phy_id is all Fs, there is no device there */
if (0xffffffff == phy_id || 0 == phy_id|| phy_id == 0xFFFF || phy_id == 0xFFFF0000)
return 1;
printf("get_phy_device devname: %s phy_id:0x%x \n",devname,phy_id);
[color=Red] if(phy_id==0x4dd072){
at803x_init(devname, phyaddr);
} [/color]
return 0;
}
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
-
2016-05-20 16:38:42
-
2016-06-22 17:29:40
-
2017-10-11 09:45:08
-
2016-05-09 19:53:56
-
2015-07-01 15:59:31
-
2018-05-11 10:13:42
-
2018-10-19 15:20:12
-
2016-04-29 13:38:58
-
2016-01-16 11:26:31
-
2019-04-24 18:05:16
-
2017-05-10 19:29:46
-
2016-05-11 02:26:40
-
12015-07-17 14:56:20
-
02014-12-30 11:43:20
-
12015-07-17 14:10:05
-
22014-06-24 15:25:44
-
2016-10-13 17:31:22
-
2022-03-28 17:26:25
-
2015-03-03 15:29:43
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明