Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
e780d82b
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e780d82b
编写于
10月 22, 2010
作者:
D
Daniel Hellstrom
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
GRETH: Added autodetection of PHY address, or let BSP hardcode it.
Signed-off-by:
N
Daniel Hellstrom
<
daniel@gaisler.com
>
上级
6644c195
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
55 addition
and
23 deletion
+55
-23
drivers/net/greth.c
drivers/net/greth.c
+55
-23
未找到文件。
drivers/net/greth.c
浏览文件 @
e780d82b
...
...
@@ -42,6 +42,13 @@
#define GRETH_PHY_TIMEOUT_MS 3000
#endif
/* Default to PHY adrress 0 not not specified */
#ifdef CONFIG_SYS_GRLIB_GRETH_PHYADDR
#define GRETH_PHY_ADR_DEFAULT CONFIG_SYS_GRLIB_GRETH_PHYADDR
#else
#define GRETH_PHY_ADR_DEFAULT 0
#endif
/* ByPass Cache when reading regs */
#define GRETH_REGLOAD(addr) SPARC_NOCACHE_READ(addr)
/* Write-through cache ==> no bypassing needed on writes */
...
...
@@ -102,12 +109,12 @@ typedef struct {
}
greth_priv
;
/* Read MII register 'addr' from core 'regs' */
static
int
read_mii
(
int
addr
,
volatile
greth_regs
*
regs
)
static
int
read_mii
(
int
phyaddr
,
int
reg
addr
,
volatile
greth_regs
*
regs
)
{
while
(
GRETH_REGLOAD
(
&
regs
->
mdio
)
&
GRETH_MII_BUSY
)
{
}
GRETH_REGSAVE
(
&
regs
->
mdio
,
(
0
<<
11
)
|
((
addr
&
0x1F
)
<<
6
)
|
2
);
GRETH_REGSAVE
(
&
regs
->
mdio
,
(
(
phyaddr
&
0x1F
)
<<
11
)
|
((
reg
addr
&
0x1F
)
<<
6
)
|
2
);
while
(
GRETH_REGLOAD
(
&
regs
->
mdio
)
&
GRETH_MII_BUSY
)
{
}
...
...
@@ -119,14 +126,14 @@ static int read_mii(int addr, volatile greth_regs * regs)
}
}
static
void
write_mii
(
int
addr
,
int
data
,
volatile
greth_regs
*
regs
)
static
void
write_mii
(
int
phyaddr
,
int
reg
addr
,
int
data
,
volatile
greth_regs
*
regs
)
{
while
(
GRETH_REGLOAD
(
&
regs
->
mdio
)
&
GRETH_MII_BUSY
)
{
}
GRETH_REGSAVE
(
&
regs
->
mdio
,
((
data
&
0xFFFF
)
<<
16
)
|
(
0
<<
11
)
|
((
addr
&
0x1F
)
<<
6
)
|
1
);
((
data
&
0xFFFF
)
<<
16
)
|
(
(
phyaddr
&
0x1F
)
<<
11
)
|
((
regaddr
&
0x1F
)
<<
6
)
|
1
);
while
(
GRETH_REGLOAD
(
&
regs
->
mdio
)
&
GRETH_MII_BUSY
)
{
}
...
...
@@ -214,6 +221,26 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
greth_regs
*
regs
=
dev
->
regs
;
int
tmp
,
tmp1
,
tmp2
,
i
;
unsigned
int
start
,
timeout
;
int
phyaddr
=
GRETH_PHY_ADR_DEFAULT
;
#ifndef CONFIG_SYS_GRLIB_GRETH_PHYADDR
/* If BSP doesn't provide a hardcoded PHY address the driver will
* try to autodetect PHY address by stopping the search on the first
* PHY address which has REG0 implemented.
*/
for
(
i
=
0
;
i
<
32
;
i
++
)
{
tmp
=
read_mii
(
i
,
0
,
regs
);
if
(
(
tmp
!=
0
)
&&
(
tmp
!=
0xffff
)
)
{
phyaddr
=
i
;
break
;
}
}
#endif
/* Save PHY Address */
dev
->
phyaddr
=
phyaddr
;
debug
(
"GRETH PHY ADDRESS: %d
\n
"
,
phyaddr
);
/* X msecs to ticks */
timeout
=
usec2ticks
(
GRETH_PHY_TIMEOUT_MS
*
1000
);
...
...
@@ -225,17 +252,21 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
/* get phy control register default values */
while
((
tmp
=
read_mii
(
0
,
regs
))
&
0x8000
)
{
if
(
get_timer
(
start
)
>
timeout
)
while
((
tmp
=
read_mii
(
phyaddr
,
0
,
regs
))
&
0x8000
)
{
if
(
get_timer
(
start
)
>
timeout
)
{
debug
(
"greth_init_phy: PHY read 1 failed
\n
"
);
return
1
;
/* Fail */
}
}
/* reset PHY and wait for completion */
write_mii
(
0
,
0x8000
|
tmp
,
regs
);
write_mii
(
phyaddr
,
0
,
0x8000
|
tmp
,
regs
);
while
(((
tmp
=
read_mii
(
0
,
regs
)))
&
0x8000
)
{
if
(
get_timer
(
start
)
>
timeout
)
while
(((
tmp
=
read_mii
(
phyaddr
,
0
,
regs
)))
&
0x8000
)
{
if
(
get_timer
(
start
)
>
timeout
)
{
debug
(
"greth_init_phy: PHY read 2 failed
\n
"
);
return
1
;
/* Fail */
}
}
/* Check if PHY is autoneg capable and then determine operating
...
...
@@ -246,16 +277,16 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
dev
->
sp
=
0
;
dev
->
auto_neg
=
0
;
if
(
!
((
tmp
>>
12
)
&
1
))
{
write_mii
(
0
,
0
,
regs
);
write_mii
(
phyaddr
,
0
,
0
,
regs
);
}
else
{
/* wait for auto negotiation to complete and then check operating mode */
dev
->
auto_neg
=
1
;
i
=
0
;
while
(
!
(((
tmp
=
read_mii
(
1
,
regs
))
>>
5
)
&
1
))
{
while
(
!
(((
tmp
=
read_mii
(
phyaddr
,
1
,
regs
))
>>
5
)
&
1
))
{
if
(
get_timer
(
start
)
>
timeout
)
{
printf
(
"Auto negotiation timed out. "
"Selecting default config
\n
"
);
tmp
=
read_mii
(
0
,
regs
);
tmp
=
read_mii
(
phyaddr
,
0
,
regs
);
dev
->
gb
=
((
tmp
>>
6
)
&
1
)
&&
!
((
tmp
>>
13
)
&
1
);
dev
->
sp
=
!
((
tmp
>>
6
)
&
1
)
...
...
@@ -265,8 +296,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
}
}
if
((
tmp
>>
8
)
&
1
)
{
tmp1
=
read_mii
(
9
,
regs
);
tmp2
=
read_mii
(
10
,
regs
);
tmp1
=
read_mii
(
phyaddr
,
9
,
regs
);
tmp2
=
read_mii
(
phyaddr
,
10
,
regs
);
if
((
tmp1
&
GRETH_MII_EXTADV_1000FD
)
&&
(
tmp2
&
GRETH_MII_EXTPRT_1000FD
))
{
dev
->
gb
=
1
;
...
...
@@ -279,8 +310,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
}
}
if
((
dev
->
gb
==
0
)
||
((
dev
->
gb
==
1
)
&&
(
dev
->
gbit_mac
==
0
)))
{
tmp1
=
read_mii
(
4
,
regs
);
tmp2
=
read_mii
(
5
,
regs
);
tmp1
=
read_mii
(
phyaddr
,
4
,
regs
);
tmp2
=
read_mii
(
phyaddr
,
5
,
regs
);
if
((
tmp1
&
GRETH_MII_100TXFD
)
&&
(
tmp2
&
GRETH_MII_100TXFD
))
{
dev
->
sp
=
1
;
...
...
@@ -297,7 +328,7 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
if
((
dev
->
gb
==
1
)
&&
(
dev
->
gbit_mac
==
0
))
{
dev
->
gb
=
0
;
dev
->
fd
=
0
;
write_mii
(
0
,
dev
->
sp
<<
13
,
regs
);
write_mii
(
phyaddr
,
0
,
dev
->
sp
<<
13
,
regs
);
}
}
...
...
@@ -307,8 +338,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
%d Mbps %s duplex
\n
"
,
dev
->
gbit_mac
?
"10/100/1000"
:
"10/100"
,
(
unsigned
int
)(
regs
),
(
unsigned
int
)(
dev
->
irq
),
dev
->
gb
?
1000
:
(
dev
->
sp
?
100
:
10
),
dev
->
fd
?
"full"
:
"half"
);
/* Read out PHY info if extended registers are available */
if
(
tmp
&
1
)
{
tmp1
=
read_mii
(
2
,
regs
);
tmp2
=
read_mii
(
3
,
regs
);
tmp1
=
read_mii
(
phyaddr
,
2
,
regs
);
tmp2
=
read_mii
(
phyaddr
,
3
,
regs
);
tmp1
=
(
tmp1
<<
6
)
|
((
tmp2
>>
10
)
&
0x3F
);
tmp
=
tmp2
&
0xF
;
...
...
@@ -492,8 +523,7 @@ int greth_recv(struct eth_device *dev)
for
(
i
=
0
;
i
<
GRETH_RXBD_CNT
;
i
++
)
{
printf
(
"[%d]: Stat=0x%lx, Addr=0x%lx
\n
"
,
i
,
GRETH_REGLOAD
(
&
greth
->
rxbd_base
[
i
].
stat
),
GRETH_REGLOAD
(
&
greth
->
rxbd_base
[
i
].
addr
));
GRETH_REGLOAD
(
&
greth
->
rxbd_base
[
i
].
addr
));
}
}
else
{
/* Process the incoming packet. */
...
...
@@ -530,7 +560,7 @@ int greth_recv(struct eth_device *dev)
(
unsigned
int
)
greth
->
rxbd_max
)
?
greth
->
rxbd_base
:
(
greth
->
rxbd_curr
+
1
);
}
;
}
if
(
enable
)
{
GRETH_REGORIN
(
&
regs
->
control
,
GRETH_RXEN
);
...
...
@@ -612,6 +642,7 @@ int greth_initialize(bd_t * bis)
/* initiate PHY, select speed/duplex depending on connected PHY */
if
(
greth_init_phy
(
greth
,
bis
))
{
/* Failed to init PHY (timedout) */
debug
(
"GRETH[0x%08x]: Failed to init PHY
\n
"
,
greth
->
regs
);
return
-
1
;
}
...
...
@@ -640,5 +671,6 @@ int greth_initialize(bd_t * bis)
/* set and remember MAC address */
greth_set_hwaddr
(
greth
,
addr
);
debug
(
"GRETH[0x%08x]: Initialized successfully
\n
"
,
greth
->
regs
);
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录