Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
a08ded4e
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,发现更多精彩内容 >>
提交
a08ded4e
编写于
11月 16, 2007
作者:
W
Wolfgang Denk
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://www.denx.de/git/u-boot-net
上级
1ce55151
1f103105
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
1227 addition
and
179 deletion
+1227
-179
common/cmd_mii.c
common/cmd_mii.c
+6
-2
common/miiphyutil.c
common/miiphyutil.c
+156
-126
drivers/Makefile
drivers/Makefile
+1
-1
drivers/uli526x.c
drivers/uli526x.c
+996
-0
include/miiphy.h
include/miiphy.h
+64
-50
net/eth.c
net/eth.c
+4
-0
未找到文件。
common/cmd_mii.c
浏览文件 @
a08ded4e
...
...
@@ -112,9 +112,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
"OUI = 0x%04X, "
"Model = 0x%02X, "
"Rev = 0x%02X, "
"%3dbase
T
, %s
\n
"
,
"%3dbase
%s
, %s
\n
"
,
j
,
oui
,
model
,
rev
,
miiphy_speed
(
devname
,
j
),
miiphy_is_1000base_x
(
devname
,
j
)
?
"X"
:
"T"
,
(
miiphy_duplex
(
devname
,
j
)
==
FULL
)
?
"FDX"
:
"HDX"
);
}
...
...
@@ -496,9 +498,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
"OUI = 0x%04X, "
"Model = 0x%02X, "
"Rev = 0x%02X, "
"%3dbase
T
, %s
\n
"
,
"%3dbase
%s
, %s
\n
"
,
j
,
oui
,
model
,
rev
,
miiphy_speed
(
devname
,
j
),
miiphy_is_1000base_x
(
devname
,
j
)
?
"X"
:
"T"
,
(
miiphy_duplex
(
devname
,
j
)
==
FULL
)
?
"FDX"
:
"HDX"
);
}
...
...
common/miiphyutil.c
浏览文件 @
a08ded4e
...
...
@@ -49,10 +49,10 @@
struct
mii_dev
{
struct
list_head
link
;
char
*
name
;
int
(
*
read
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
);
int
(
*
write
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
);
int
(
*
read
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
);
int
(
*
write
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
);
};
static
struct
list_head
mii_devs
;
...
...
@@ -62,21 +62,21 @@ static struct mii_dev *current_mii;
*
* Initialize global data. Need to be called before any other miiphy routine.
*/
void
miiphy_init
()
void
miiphy_init
()
{
INIT_LIST_HEAD
(
&
mii_devs
);
current_mii
=
NULL
;
INIT_LIST_HEAD
(
&
mii_devs
);
current_mii
=
NULL
;
}
/*****************************************************************************
*
* Register read and write MII access routines for the device <name>.
*/
void
miiphy_register
(
char
*
name
,
int
(
*
read
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
),
int
(
*
write
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
))
void
miiphy_register
(
char
*
name
,
int
(
*
read
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
),
int
(
*
write
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
))
{
struct
list_head
*
entry
;
struct
mii_dev
*
new_dev
;
...
...
@@ -84,63 +84,64 @@ void miiphy_register(char *name,
unsigned
int
name_len
;
/* check if we have unique name */
list_for_each
(
entry
,
&
mii_devs
)
{
miidev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
if
(
strcmp
(
miidev
->
name
,
name
)
==
0
)
{
printf
(
"miiphy_register: non unique device name '%s'
\n
"
,
name
);
list_for_each
(
entry
,
&
mii_devs
)
{
miidev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
if
(
strcmp
(
miidev
->
name
,
name
)
==
0
)
{
printf
(
"miiphy_register: non unique device name "
"'%s'
\n
"
,
name
);
return
;
}
}
/* allocate memory */
name_len
=
strlen
(
name
);
new_dev
=
(
struct
mii_dev
*
)
malloc
(
sizeof
(
struct
mii_dev
)
+
name_len
+
1
);
name_len
=
strlen
(
name
);
new_dev
=
(
struct
mii_dev
*
)
malloc
(
sizeof
(
struct
mii_dev
)
+
name_len
+
1
);
if
(
new_dev
==
NULL
)
{
printf
(
"miiphy_register: cannot allocate memory for '%s'
\n
"
,
name
);
if
(
new_dev
==
NULL
)
{
printf
(
"miiphy_register: cannot allocate memory for '%s'
\n
"
,
name
);
return
;
}
memset
(
new_dev
,
0
,
sizeof
(
struct
mii_dev
)
+
name_len
);
memset
(
new_dev
,
0
,
sizeof
(
struct
mii_dev
)
+
name_len
);
/* initalize mii_dev struct fields */
INIT_LIST_HEAD
(
&
new_dev
->
link
);
INIT_LIST_HEAD
(
&
new_dev
->
link
);
new_dev
->
read
=
read
;
new_dev
->
write
=
write
;
new_dev
->
name
=
(
char
*
)(
new_dev
+
1
);
strncpy
(
new_dev
->
name
,
name
,
name_len
);
strncpy
(
new_dev
->
name
,
name
,
name_len
);
new_dev
->
name
[
name_len
]
=
'\0'
;
debug
(
"miiphy_register: added '%s', read=0x%08lx, write=0x%08lx
\n
"
,
new_dev
->
name
,
new_dev
->
read
,
new_dev
->
write
);
debug
(
"miiphy_register: added '%s', read=0x%08lx, write=0x%08lx
\n
"
,
new_dev
->
name
,
new_dev
->
read
,
new_dev
->
write
);
/* add it to the list */
list_add_tail
(
&
new_dev
->
link
,
&
mii_devs
);
list_add_tail
(
&
new_dev
->
link
,
&
mii_devs
);
if
(
!
current_mii
)
current_mii
=
new_dev
;
}
int
miiphy_set_current_dev
(
char
*
devname
)
int
miiphy_set_current_dev
(
char
*
devname
)
{
struct
list_head
*
entry
;
struct
mii_dev
*
dev
;
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
if
(
strcmp
(
devname
,
dev
->
name
)
==
0
)
{
if
(
strcmp
(
devname
,
dev
->
name
)
==
0
)
{
current_mii
=
dev
;
return
0
;
}
}
printf
(
"No such device: %s
\n
"
,
devname
);
printf
(
"No such device: %s
\n
"
,
devname
);
return
1
;
}
char
*
miiphy_get_current_dev
()
char
*
miiphy_get_current_dev
()
{
if
(
current_mii
)
return
current_mii
->
name
;
...
...
@@ -156,8 +157,8 @@ char *miiphy_get_current_dev()
* Returns:
* 0 on success
*/
int
miiphy_read
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
)
int
miiphy_read
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
)
{
struct
list_head
*
entry
;
struct
mii_dev
*
dev
;
...
...
@@ -165,22 +166,22 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
int
read_ret
=
0
;
if
(
!
devname
)
{
printf
(
"NULL device name!
\n
"
);
printf
(
"NULL device name!
\n
"
);
return
1
;
}
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
if
(
strcmp
(
devname
,
dev
->
name
)
==
0
)
{
if
(
strcmp
(
devname
,
dev
->
name
)
==
0
)
{
found_dev
=
1
;
read_ret
=
dev
->
read
(
devname
,
addr
,
reg
,
value
);
read_ret
=
dev
->
read
(
devname
,
addr
,
reg
,
value
);
break
;
}
}
if
(
found_dev
==
0
)
printf
(
"No such device: %s
\n
"
,
devname
);
printf
(
"No such device: %s
\n
"
,
devname
);
return
((
found_dev
)
?
read_ret
:
1
);
}
...
...
@@ -193,8 +194,8 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
* Returns:
* 0 on success
*/
int
miiphy_write
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
)
int
miiphy_write
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
)
{
struct
list_head
*
entry
;
struct
mii_dev
*
dev
;
...
...
@@ -202,22 +203,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
int
write_ret
=
0
;
if
(
!
devname
)
{
printf
(
"NULL device name!
\n
"
);
printf
(
"NULL device name!
\n
"
);
return
1
;
}
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
if
(
strcmp
(
devname
,
dev
->
name
)
==
0
)
{
if
(
strcmp
(
devname
,
dev
->
name
)
==
0
)
{
found_dev
=
1
;
write_ret
=
dev
->
write
(
devname
,
addr
,
reg
,
value
);
write_ret
=
dev
->
write
(
devname
,
addr
,
reg
,
value
);
break
;
}
}
if
(
found_dev
==
0
)
printf
(
"No such device: %s
\n
"
,
devname
);
printf
(
"No such device: %s
\n
"
,
devname
);
return
((
found_dev
)
?
write_ret
:
1
);
}
...
...
@@ -226,23 +227,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
*
* Print out list of registered MII capable devices.
*/
void
miiphy_listdev
(
void
)
void
miiphy_listdev
(
void
)
{
struct
list_head
*
entry
;
struct
mii_dev
*
dev
;
puts
(
"MII devices: "
);
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
printf
(
"'%s' "
,
dev
->
name
);
puts
(
"MII devices: "
);
list_for_each
(
entry
,
&
mii_devs
)
{
dev
=
list_entry
(
entry
,
struct
mii_dev
,
link
);
printf
(
"'%s' "
,
dev
->
name
);
}
puts
(
"
\n
"
);
puts
(
"
\n
"
);
if
(
current_mii
)
printf
(
"Current device: '%s'
\n
"
,
current_mii
->
name
);
printf
(
"Current device: '%s'
\n
"
,
current_mii
->
name
);
}
/*****************************************************************************
*
* Read the OUI, manufacture's model number, and revision number.
...
...
@@ -254,9 +254,7 @@ void miiphy_listdev(void)
* Returns:
* 0 on success
*/
int
miiphy_info
(
char
*
devname
,
unsigned
char
addr
,
unsigned
int
*
oui
,
int
miiphy_info
(
char
*
devname
,
unsigned
char
addr
,
unsigned
int
*
oui
,
unsigned
char
*
model
,
unsigned
char
*
rev
)
{
unsigned
int
reg
=
0
;
...
...
@@ -288,13 +286,12 @@ int miiphy_info (char *devname,
#ifdef DEBUG
printf
(
"PHY_PHYIDR[1,2] @ 0x%x = 0x%08x
\n
"
,
addr
,
reg
);
#endif
*
oui
=
(
reg
>>
10
);
*
model
=
(
unsigned
char
)
((
reg
>>
4
)
&
0x0000003F
);
*
rev
=
(
unsigned
char
)
(
reg
&
0x0000000F
);
*
oui
=
(
reg
>>
10
);
*
model
=
(
unsigned
char
)
((
reg
>>
4
)
&
0x0000003F
);
*
rev
=
(
unsigned
char
)(
reg
&
0x0000000F
);
return
(
0
);
}
/*****************************************************************************
*
* Reset the PHY.
...
...
@@ -345,104 +342,138 @@ int miiphy_reset (char *devname, unsigned char addr)
return
(
0
);
}
/*****************************************************************************
*
* Determine the ethernet speed (10/100
)
.
* Determine the ethernet speed (10/100
/1000). Return 10 on error
.
*/
int
miiphy_speed
(
char
*
devname
,
unsigned
char
addr
)
{
u
nsigned
short
reg
;
u
16
bmcr
,
anlpar
;
#if defined(CONFIG_PHY_GIGE)
if
(
miiphy_read
(
devname
,
addr
,
PHY_1000BTSR
,
&
reg
))
{
printf
(
"PHY 1000BT Status read failed
\n
"
);
}
else
{
if
(
reg
!=
0xFFFF
)
{
if
((
reg
&
(
PHY_1000BTSR_1000FD
|
PHY_1000BTSR_1000HD
))
!=
0
)
{
return
(
_1000BASET
);
}
}
u16
btsr
;
/*
* Check for 1000BASE-X. If it is supported, then assume that the speed
* is 1000.
*/
if
(
miiphy_is_1000base_x
(
devname
,
addr
))
{
return
_1000BASET
;
}
/*
* 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
(
"PHY 1000BT status"
);
goto
miiphy_read_failed
;
}
if
(
btsr
!=
0xFFFF
&&
(
btsr
&
(
PHY_1000BTSR_1000FD
|
PHY_1000BTSR_1000HD
)))
{
return
_1000BASET
;
}
#endif
/* CONFIG_PHY_GIGE */
/* Check Basic Management Control Register first. */
if
(
miiphy_read
(
devname
,
addr
,
PHY_BMCR
,
&
reg
))
{
p
uts
(
"PHY speed read failed, assuming 10bT
\n
"
);
return
(
_10BASET
)
;
if
(
miiphy_read
(
devname
,
addr
,
PHY_BMCR
,
&
bmcr
))
{
p
rintf
(
"PHY speed
"
);
goto
miiphy_read_failed
;
}
/* Check if auto-negotiation is on. */
if
(
(
reg
&
PHY_BMCR_AUTON
)
!=
0
)
{
if
(
bmcr
&
PHY_BMCR_AUTON
)
{
/* Get auto-negotiation results. */
if
(
miiphy_read
(
devname
,
addr
,
PHY_ANLPAR
,
&
reg
))
{
puts
(
"PHY AN speed read failed, assuming 10bT
\n
"
);
return
(
_10BASET
);
}
if
((
reg
&
PHY_ANLPAR_100
)
!=
0
)
{
return
(
_100BASET
);
}
else
{
return
(
_10BASET
);
if
(
miiphy_read
(
devname
,
addr
,
PHY_ANLPAR
,
&
anlpar
))
{
printf
(
"PHY AN speed"
);
goto
miiphy_read_failed
;
}
return
(
anlpar
&
PHY_ANLPAR_100
)
?
_100BASET
:
_10BASET
;
}
/* Get speed from basic control settings. */
else
if
(
reg
&
PHY_BMCR_100MB
)
{
return
(
_100BASET
);
}
else
{
return
(
_10BASET
);
}
return
(
bmcr
&
PHY_BMCR_100MB
)
?
_100BASET
:
_10BASET
;
miiphy_read_failed:
printf
(
" read failed, assuming 10BASE-T
\n
"
);
return
_10BASET
;
}
/*****************************************************************************
*
* Determine full/half duplex.
* Determine full/half duplex.
Return half on error.
*/
int
miiphy_duplex
(
char
*
devname
,
unsigned
char
addr
)
{
u
nsigned
short
reg
;
u
16
bmcr
,
anlpar
;
#if defined(CONFIG_PHY_GIGE)
if
(
miiphy_read
(
devname
,
addr
,
PHY_1000BTSR
,
&
reg
))
{
printf
(
"PHY 1000BT Status read failed
\n
"
);
}
else
{
if
(
(
reg
!=
0xFFFF
)
&&
(
reg
&
(
PHY_1000BTSR_1000FD
|
PHY_1000BTSR_1000HD
))
)
{
if
((
reg
&
PHY_1000BTSR_1000FD
)
!=
0
)
{
return
(
FULL
);
}
else
{
return
(
HALF
);
}
u16
btsr
;
/* Check for 1000BASE-X. */
if
(
miiphy_is_1000base_x
(
devname
,
addr
))
{
/* 1000BASE-X */
if
(
miiphy_read
(
devname
,
addr
,
PHY_ANLPAR
,
&
anlpar
))
{
printf
(
"1000BASE-X PHY AN duplex"
);
goto
miiphy_read_failed
;
}
}
/*
* 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
(
"PHY 1000BT status"
);
goto
miiphy_read_failed
;
}
if
(
btsr
!=
0xFFFF
)
{
if
(
btsr
&
PHY_1000BTSR_1000FD
)
{
return
FULL
;
}
else
if
(
btsr
&
PHY_1000BTSR_1000HD
)
{
return
HALF
;
}
}
#endif
/* CONFIG_PHY_GIGE */
/* Check Basic Management Control Register first. */
if
(
miiphy_read
(
devname
,
addr
,
PHY_BMCR
,
&
reg
))
{
puts
(
"PHY duplex
read failed, assuming half duplex
\n
"
);
return
(
HALF
)
;
if
(
miiphy_read
(
devname
,
addr
,
PHY_BMCR
,
&
bmcr
))
{
puts
(
"PHY duplex"
);
goto
miiphy_read_failed
;
}
/* Check if auto-negotiation is on. */
if
(
(
reg
&
PHY_BMCR_AUTON
)
!=
0
)
{
if
(
bmcr
&
PHY_BMCR_AUTON
)
{
/* Get auto-negotiation results. */
if
(
miiphy_read
(
devname
,
addr
,
PHY_ANLPAR
,
&
reg
))
{
puts
(
"PHY AN duplex read failed, assuming half duplex
\n
"
);
return
(
HALF
);
}
if
((
reg
&
(
PHY_ANLPAR_10FD
|
PHY_ANLPAR_TXFD
))
!=
0
)
{
return
(
FULL
);
}
else
{
return
(
HALF
);
if
(
miiphy_read
(
devname
,
addr
,
PHY_ANLPAR
,
&
anlpar
))
{
puts
(
"PHY AN duplex"
);
goto
miiphy_read_failed
;
}
return
(
anlpar
&
(
PHY_ANLPAR_10FD
|
PHY_ANLPAR_TXFD
))
?
FULL
:
HALF
;
}
/* Get speed from basic control settings. */
else
if
(
reg
&
PHY_BMCR_DPLX
)
{
return
(
FULL
);
}
else
{
return
(
HALF
);
}
return
(
bmcr
&
PHY_BMCR_DPLX
)
?
FULL
:
HALF
;
miiphy_read_failed:
printf
(
" read failed, assuming half duplex
\n
"
);
return
HALF
;
}
/*****************************************************************************
*
* Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
* 1000BASE-T, or on error.
*/
int
miiphy_is_1000base_x
(
char
*
devname
,
unsigned
char
addr
)
{
#if defined(CONFIG_PHY_GIGE)
u16
exsr
;
if
(
miiphy_read
(
devname
,
addr
,
PHY_EXSR
,
&
exsr
))
{
printf
(
"PHY extended status read failed, assuming no "
"1000BASE-X
\n
"
);
return
0
;
}
return
0
!=
(
exsr
&
(
PHY_EXSR_1000XF
|
PHY_EXSR_1000XH
));
#else
return
0
;
#endif
}
#ifdef CFG_FAULT_ECHO_LINK_DOWN
...
...
@@ -455,7 +486,7 @@ int miiphy_link (char *devname, unsigned char addr)
unsigned
short
reg
;
/* dummy read; needed to latch some phys */
(
void
)
miiphy_read
(
devname
,
addr
,
PHY_BMSR
,
&
reg
);
(
void
)
miiphy_read
(
devname
,
addr
,
PHY_BMSR
,
&
reg
);
if
(
miiphy_read
(
devname
,
addr
,
PHY_BMSR
,
&
reg
))
{
puts
(
"PHY_BMSR read failed, assuming no link
\n
"
);
return
(
0
);
...
...
@@ -469,5 +500,4 @@ int miiphy_link (char *devname, unsigned char addr)
}
}
#endif
#endif
/* CONFIG_MII */
drivers/Makefile
浏览文件 @
a08ded4e
...
...
@@ -41,7 +41,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o at45.o ata_piix.o \
omap24xx_i2c.o pc_keyb.o
\
pci.o pci_auto.o pci_indirect.o
\
pcnet.o plb2800_eth.o ps2ser.o ps2mult.o pxa_pcmcia.o
\
rpx_pcmcia.o rtl8019.o rtl8139.o rtl8169.o
\
rpx_pcmcia.o rtl8019.o rtl8139.o rtl8169.o
uli526x.o
\
s3c4510b_eth.o s3c4510b_uart.o
\
sed13806.o sed156x.o
\
serial.o serial_max3100.o
\
...
...
drivers/uli526x.c
0 → 100644
浏览文件 @
a08ded4e
/*
* Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
*
* Author: Roy Zang <tie-fei.zang@freescale.com>, Sep, 2007
*
* Description:
* ULI 526x Ethernet port driver.
* Based on the Linux driver: drivers/net/tulip/uli526x.c
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
#include <miiphy.h>
/* some kernel function compatible define */
#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_ULI526X)
#undef DEBUG
/* Board/System/Debug information/definition */
#define ULI_VENDOR_ID 0x10B9
#define ULI5261_DEVICE_ID 0x5261
#define ULI5263_DEVICE_ID 0x5263
/* ULi M5261 ID*/
#define PCI_ULI5261_ID ULI5261_DEVICE_ID << 16 | ULI_VENDOR_ID
/* ULi M5263 ID*/
#define PCI_ULI5263_ID ULI5263_DEVICE_ID << 16 | ULI_VENDOR_ID
#define ULI526X_IO_SIZE 0x100
#define TX_DESC_CNT 0x10
/* Allocated Tx descriptors */
#define RX_DESC_CNT PKTBUFSRX
/* Allocated Rx descriptors */
#define TX_FREE_DESC_CNT (TX_DESC_CNT - 2)
/* Max TX packet count */
#define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3)
/* TX wakeup count */
#define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT)
#define TX_BUF_ALLOC 0x300
#define RX_ALLOC_SIZE PKTSIZE
#define ULI526X_RESET 1
#define CR0_DEFAULT 0
#define CR6_DEFAULT 0x22200000
#define CR7_DEFAULT 0x180c1
#define CR15_DEFAULT 0x06
/* TxJabber RxWatchdog */
#define TDES0_ERR_MASK 0x4302
/* TXJT, LC, EC, FUE */
#define MAX_PACKET_SIZE 1514
#define ULI5261_MAX_MULTICAST 14
#define RX_COPY_SIZE 100
#define MAX_CHECK_PACKET 0x8000
#define ULI526X_10MHF 0
#define ULI526X_100MHF 1
#define ULI526X_10MFD 4
#define ULI526X_100MFD 5
#define ULI526X_AUTO 8
#define ULI526X_TXTH_72 0x400000
/* TX TH 72 byte */
#define ULI526X_TXTH_96 0x404000
/* TX TH 96 byte */
#define ULI526X_TXTH_128 0x0000
/* TX TH 128 byte */
#define ULI526X_TXTH_256 0x4000
/* TX TH 256 byte */
#define ULI526X_TXTH_512 0x8000
/* TX TH 512 byte */
#define ULI526X_TXTH_1K 0xC000
/* TX TH 1K byte */
/* CR9 definition: SROM/MII */
#define CR9_SROM_READ 0x4800
#define CR9_SRCS 0x1
#define CR9_SRCLK 0x2
#define CR9_CRDOUT 0x8
#define SROM_DATA_0 0x0
#define SROM_DATA_1 0x4
#define PHY_DATA_1 0x20000
#define PHY_DATA_0 0x00000
#define MDCLKH 0x10000
#define PHY_POWER_DOWN 0x800
#define SROM_V41_CODE 0x14
#define SROM_CLK_WRITE(data, ioaddr) do { \
outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr); \
udelay(5); \
outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK, ioaddr); \
udelay(5); \
outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr); \
udelay(5); \
} while (0)
/* Structure/enum declaration */
struct
tx_desc
{
u32
tdes0
,
tdes1
,
tdes2
,
tdes3
;
/* Data for the card */
char
*
tx_buf_ptr
;
/* Data for us */
struct
tx_desc
*
next_tx_desc
;
};
struct
rx_desc
{
u32
rdes0
,
rdes1
,
rdes2
,
rdes3
;
/* Data for the card */
char
*
rx_buf_ptr
;
/* Data for us */
struct
rx_desc
*
next_rx_desc
;
};
struct
uli526x_board_info
{
u32
chip_id
;
/* Chip vendor/Device ID */
pci_dev_t
pdev
;
long
ioaddr
;
/* I/O base address */
u32
cr0_data
;
u32
cr5_data
;
u32
cr6_data
;
u32
cr7_data
;
u32
cr15_data
;
/* pointer for memory physical address */
dma_addr_t
buf_pool_dma_ptr
;
/* Tx buffer pool memory */
dma_addr_t
buf_pool_dma_start
;
/* Tx buffer pool align dword */
dma_addr_t
desc_pool_dma_ptr
;
/* descriptor pool memory */
dma_addr_t
first_tx_desc_dma
;
dma_addr_t
first_rx_desc_dma
;
/* descriptor pointer */
unsigned
char
*
buf_pool_ptr
;
/* Tx buffer pool memory */
unsigned
char
*
buf_pool_start
;
/* Tx buffer pool align dword */
unsigned
char
*
desc_pool_ptr
;
/* descriptor pool memory */
struct
tx_desc
*
first_tx_desc
;
struct
tx_desc
*
tx_insert_ptr
;
struct
tx_desc
*
tx_remove_ptr
;
struct
rx_desc
*
first_rx_desc
;
struct
rx_desc
*
rx_ready_ptr
;
/* packet come pointer */
unsigned
long
tx_packet_cnt
;
/* transmitted packet count */
u16
PHY_reg4
;
/* Saved Phyxcer register 4 value */
u8
media_mode
;
/* user specify media mode */
u8
op_mode
;
/* real work dedia mode */
u8
phy_addr
;
/* NIC SROM data */
unsigned
char
srom
[
128
];
};
enum
uli526x_offsets
{
DCR0
=
0x00
,
DCR1
=
0x08
,
DCR2
=
0x10
,
DCR3
=
0x18
,
DCR4
=
0x20
,
DCR5
=
0x28
,
DCR6
=
0x30
,
DCR7
=
0x38
,
DCR8
=
0x40
,
DCR9
=
0x48
,
DCR10
=
0x50
,
DCR11
=
0x58
,
DCR12
=
0x60
,
DCR13
=
0x68
,
DCR14
=
0x70
,
DCR15
=
0x78
};
enum
uli526x_CR6_bits
{
CR6_RXSC
=
0x2
,
CR6_PBF
=
0x8
,
CR6_PM
=
0x40
,
CR6_PAM
=
0x80
,
CR6_FDM
=
0x200
,
CR6_TXSC
=
0x2000
,
CR6_STI
=
0x100000
,
CR6_SFT
=
0x200000
,
CR6_RXA
=
0x40000000
,
CR6_NO_PURGE
=
0x20000000
};
/* Global variable declaration -- */
static
unsigned
char
uli526x_media_mode
=
ULI526X_AUTO
;
static
struct
tx_desc
desc_pool_array
[
DESC_ALL_CNT
+
0x20
]
__attribute__
((
aligned
(
32
)));
static
char
buf_pool
[
TX_BUF_ALLOC
*
TX_DESC_CNT
+
4
];
/* For module input parameter */
static
int
mode
=
8
;
/* function declaration -- */
static
int
uli526x_start_xmit
(
struct
eth_device
*
dev
,
volatile
void
*
packet
,
int
length
);
static
const
struct
ethtool_ops
netdev_ethtool_ops
;
static
u16
read_srom_word
(
long
,
int
);
static
void
uli526x_descriptor_init
(
struct
uli526x_board_info
*
,
unsigned
long
);
static
void
allocate_rx_buffer
(
struct
uli526x_board_info
*
);
static
void
update_cr6
(
u32
,
unsigned
long
);
static
u16
phy_read
(
unsigned
long
,
u8
,
u8
,
u32
);
static
u16
phy_readby_cr10
(
unsigned
long
,
u8
,
u8
);
static
void
phy_write
(
unsigned
long
,
u8
,
u8
,
u16
,
u32
);
static
void
phy_writeby_cr10
(
unsigned
long
,
u8
,
u8
,
u16
);
static
void
phy_write_1bit
(
unsigned
long
,
u32
,
u32
);
static
u16
phy_read_1bit
(
unsigned
long
,
u32
);
static
int
uli526x_rx_packet
(
struct
eth_device
*
);
static
void
uli526x_free_tx_pkt
(
struct
eth_device
*
,
struct
uli526x_board_info
*
);
static
void
uli526x_reuse_buf
(
struct
rx_desc
*
);
static
void
uli526x_init
(
struct
eth_device
*
);
static
void
uli526x_set_phyxcer
(
struct
uli526x_board_info
*
);
static
int
uli526x_init_one
(
struct
eth_device
*
,
bd_t
*
);
static
void
uli526x_disable
(
struct
eth_device
*
);
static
void
set_mac_addr
(
struct
eth_device
*
);
static
struct
pci_device_id
uli526x_pci_tbl
[]
=
{
{
ULI_VENDOR_ID
,
ULI5261_DEVICE_ID
},
/* 5261 device */
{
ULI_VENDOR_ID
,
ULI5263_DEVICE_ID
},
/* 5263 device */
{}
};
/* ULI526X network board routine */
/*
* Search ULI526X board, register it
*/
int
uli526x_initialize
(
bd_t
*
bis
)
{
pci_dev_t
devno
;
int
card_number
=
0
;
struct
eth_device
*
dev
;
struct
uli526x_board_info
*
db
;
/* board information structure */
u32
iobase
;
int
idx
=
0
;
while
(
1
)
{
/* Find PCI device */
devno
=
pci_find_devices
(
uli526x_pci_tbl
,
idx
++
);
if
(
devno
<
0
)
break
;
pci_read_config_dword
(
devno
,
PCI_BASE_ADDRESS_1
,
&
iobase
);
iobase
&=
~
0xf
;
dev
=
(
struct
eth_device
*
)
malloc
(
sizeof
*
dev
);
sprintf
(
dev
->
name
,
"uli526x#%d
\n
"
,
card_number
);
db
=
(
struct
uli526x_board_info
*
)
malloc
(
sizeof
(
struct
uli526x_board_info
));
dev
->
priv
=
db
;
db
->
pdev
=
devno
;
dev
->
iobase
=
iobase
;
dev
->
init
=
uli526x_init_one
;
dev
->
halt
=
uli526x_disable
;
dev
->
send
=
uli526x_start_xmit
;
dev
->
recv
=
uli526x_rx_packet
;
/* init db */
db
->
ioaddr
=
dev
->
iobase
;
/* get chip id */
pci_read_config_dword
(
devno
,
PCI_VENDOR_ID
,
&
db
->
chip_id
);
#ifdef DEBUG
printf
(
"uli526x: uli526x @0x%x
\n
"
,
iobase
);
printf
(
"uli526x: chip_id%x
\n
"
,
db
->
chip_id
);
#endif
eth_register
(
dev
);
card_number
++
;
pci_write_config_byte
(
devno
,
PCI_LATENCY_TIMER
,
0x20
);
udelay
(
10
*
1000
);
}
return
card_number
;
}
static
int
uli526x_init_one
(
struct
eth_device
*
dev
,
bd_t
*
bis
)
{
struct
uli526x_board_info
*
db
=
dev
->
priv
;
int
i
;
switch
(
mode
)
{
case
ULI526X_10MHF
:
case
ULI526X_100MHF
:
case
ULI526X_10MFD
:
case
ULI526X_100MFD
:
uli526x_media_mode
=
mode
;
break
;
default:
uli526x_media_mode
=
ULI526X_AUTO
;
break
;
}
/* Allocate Tx/Rx descriptor memory */
db
->
desc_pool_ptr
=
(
uchar
*
)
&
desc_pool_array
[
0
];
db
->
desc_pool_dma_ptr
=
(
dma_addr_t
)
&
desc_pool_array
[
0
];
if
(
db
->
desc_pool_ptr
==
NULL
)
return
0
;
db
->
buf_pool_ptr
=
&
buf_pool
[
0
];
db
->
buf_pool_dma_ptr
=
(
dma_addr_t
)
&
buf_pool
[
0
];
if
(
db
->
buf_pool_ptr
==
NULL
)
return
0
;
db
->
first_tx_desc
=
(
struct
tx_desc
*
)
db
->
desc_pool_ptr
;
db
->
first_tx_desc_dma
=
db
->
desc_pool_dma_ptr
;
db
->
buf_pool_start
=
db
->
buf_pool_ptr
;
db
->
buf_pool_dma_start
=
db
->
buf_pool_dma_ptr
;
#ifdef DEBUG
printf
(
"%s(): db->ioaddr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
ioaddr
);
printf
(
"%s(): media_mode= 0x%x
\n
"
,
__FUNCTION__
,
uli526x_media_mode
);
printf
(
"%s(): db->desc_pool_ptr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
desc_pool_ptr
);
printf
(
"%s(): db->desc_pool_dma_ptr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
desc_pool_dma_ptr
);
printf
(
"%s(): db->buf_pool_ptr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
buf_pool_ptr
);
printf
(
"%s(): db->buf_pool_dma_ptr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
buf_pool_dma_ptr
);
#endif
/* read 64 word srom data */
for
(
i
=
0
;
i
<
64
;
i
++
)
((
u16
*
)
db
->
srom
)[
i
]
=
cpu_to_le16
(
read_srom_word
(
db
->
ioaddr
,
i
));
/* Set Node address */
if
(((
u16
*
)
db
->
srom
)[
0
]
==
0xffff
||
((
u16
*
)
db
->
srom
)[
0
]
==
0
)
/* SROM absent, so write MAC address to ID Table */
set_mac_addr
(
dev
);
else
{
/*Exist SROM*/
for
(
i
=
0
;
i
<
6
;
i
++
)
dev
->
enetaddr
[
i
]
=
db
->
srom
[
20
+
i
];
}
#ifdef DEBUG
for
(
i
=
0
;
i
<
6
;
i
++
)
printf
(
"%c%02x"
,
i
?
':'
:
' '
,
dev
->
enetaddr
[
i
]);
#endif
db
->
PHY_reg4
=
0x1e0
;
/* system variable init */
db
->
cr6_data
=
CR6_DEFAULT
;
db
->
cr6_data
|=
ULI526X_TXTH_256
;
db
->
cr0_data
=
CR0_DEFAULT
;
uli526x_init
(
dev
);
return
1
;
}
static
void
uli526x_disable
(
struct
eth_device
*
dev
)
{
#ifdef DEBUG
printf
(
"uli526x_disable
\n
"
);
#endif
struct
uli526x_board_info
*
db
=
dev
->
priv
;
if
(
!
((
inl
(
db
->
ioaddr
+
DCR12
))
&
0x8
))
{
/* Reset & stop ULI526X board */
outl
(
ULI526X_RESET
,
db
->
ioaddr
+
DCR0
);
udelay
(
5
);
phy_write
(
db
->
ioaddr
,
db
->
phy_addr
,
0
,
0x8000
,
db
->
chip_id
);
/* reset the board */
db
->
cr6_data
&=
~
(
CR6_RXSC
|
CR6_TXSC
);
/* Disable Tx/Rx */
update_cr6
(
db
->
cr6_data
,
dev
->
iobase
);
outl
(
0
,
dev
->
iobase
+
DCR7
);
/* Disable Interrupt */
outl
(
inl
(
dev
->
iobase
+
DCR5
),
dev
->
iobase
+
DCR5
);
}
}
/* Initialize ULI526X board
* Reset ULI526X board
* Initialize TX/Rx descriptor chain structure
* Send the set-up frame
* Enable Tx/Rx machine
*/
static
void
uli526x_init
(
struct
eth_device
*
dev
)
{
struct
uli526x_board_info
*
db
=
dev
->
priv
;
u8
phy_tmp
;
u16
phy_value
;
u16
phy_reg_reset
;
/* Reset M526x MAC controller */
outl
(
ULI526X_RESET
,
db
->
ioaddr
+
DCR0
);
/* RESET MAC */
udelay
(
100
);
outl
(
db
->
cr0_data
,
db
->
ioaddr
+
DCR0
);
udelay
(
5
);
/* Phy addr : In some boards,M5261/M5263 phy address != 1 */
db
->
phy_addr
=
1
;
db
->
tx_packet_cnt
=
0
;
for
(
phy_tmp
=
0
;
phy_tmp
<
32
;
phy_tmp
++
)
{
/* peer add */
phy_value
=
phy_read
(
db
->
ioaddr
,
phy_tmp
,
3
,
db
->
chip_id
);
if
(
phy_value
!=
0xffff
&&
phy_value
!=
0
)
{
db
->
phy_addr
=
phy_tmp
;
break
;
}
}
#ifdef DEBUG
printf
(
"%s(): db->ioaddr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
ioaddr
);
printf
(
"%s(): db->phy_addr= 0x%x
\n
"
,
__FUNCTION__
,
db
->
phy_addr
);
#endif
if
(
phy_tmp
==
32
)
printf
(
"Can not find the phy address!!!"
);
/* Parser SROM and media mode */
db
->
media_mode
=
uli526x_media_mode
;
if
(
!
(
inl
(
db
->
ioaddr
+
DCR12
)
&
0x8
))
{
/* Phyxcer capability setting */
phy_reg_reset
=
phy_read
(
db
->
ioaddr
,
db
->
phy_addr
,
0
,
db
->
chip_id
);
phy_reg_reset
=
(
phy_reg_reset
|
0x8000
);
phy_write
(
db
->
ioaddr
,
db
->
phy_addr
,
0
,
phy_reg_reset
,
db
->
chip_id
);
udelay
(
500
);
/* Process Phyxcer Media Mode */
uli526x_set_phyxcer
(
db
);
}
/* Media Mode Process */
if
(
!
(
db
->
media_mode
&
ULI526X_AUTO
))
db
->
op_mode
=
db
->
media_mode
;
/* Force Mode */
/* Initialize Transmit/Receive decriptor and CR3/4 */
uli526x_descriptor_init
(
db
,
db
->
ioaddr
);
/* Init CR6 to program M526X operation */
update_cr6
(
db
->
cr6_data
,
db
->
ioaddr
);
/* Init CR7, interrupt active bit */
db
->
cr7_data
=
CR7_DEFAULT
;
outl
(
db
->
cr7_data
,
db
->
ioaddr
+
DCR7
);
/* Init CR15, Tx jabber and Rx watchdog timer */
outl
(
db
->
cr15_data
,
db
->
ioaddr
+
DCR15
);
/* Enable ULI526X Tx/Rx function */
db
->
cr6_data
|=
CR6_RXSC
|
CR6_TXSC
;
update_cr6
(
db
->
cr6_data
,
db
->
ioaddr
);
while
(
!
(
inl
(
db
->
ioaddr
+
DCR12
)
&
0x8
))
udelay
(
10
);
}
/*
* Hardware start transmission.
* Send a packet to media from the upper layer.
*/
static
int
uli526x_start_xmit
(
struct
eth_device
*
dev
,
volatile
void
*
packet
,
int
length
)
{
struct
uli526x_board_info
*
db
=
dev
->
priv
;
struct
tx_desc
*
txptr
;
unsigned
int
len
=
length
;
/* Too large packet check */
if
(
len
>
MAX_PACKET_SIZE
)
{
printf
(
": big packet = %d
\n
"
,
len
);
return
0
;
}
/* No Tx resource check, it never happen nromally */
if
(
db
->
tx_packet_cnt
>=
TX_FREE_DESC_CNT
)
{
printf
(
"No Tx resource %ld
\n
"
,
db
->
tx_packet_cnt
);
return
0
;
}
/* Disable NIC interrupt */
outl
(
0
,
dev
->
iobase
+
DCR7
);
/* transmit this packet */
txptr
=
db
->
tx_insert_ptr
;
memcpy
((
char
*
)
txptr
->
tx_buf_ptr
,
(
char
*
)
packet
,
(
int
)
length
);
txptr
->
tdes1
=
cpu_to_le32
(
0xe1000000
|
length
);
/* Point to next transmit free descriptor */
db
->
tx_insert_ptr
=
txptr
->
next_tx_desc
;
/* Transmit Packet Process */
if
((
db
->
tx_packet_cnt
<
TX_DESC_CNT
))
{
txptr
->
tdes0
=
cpu_to_le32
(
0x80000000
);
/* Set owner bit */
db
->
tx_packet_cnt
++
;
/* Ready to send */
outl
(
0x1
,
dev
->
iobase
+
DCR1
);
/* Issue Tx polling */
}
/* Got ULI526X status */
db
->
cr5_data
=
inl
(
db
->
ioaddr
+
DCR5
);
outl
(
db
->
cr5_data
,
db
->
ioaddr
+
DCR5
);
#ifdef TX_DEBUG
printf
(
"%s(): length = 0x%x
\n
"
,
__FUNCTION__
,
length
);
printf
(
"%s(): cr5_data=%x
\n
"
,
__FUNCTION__
,
db
->
cr5_data
);
#endif
outl
(
db
->
cr7_data
,
dev
->
iobase
+
DCR7
);
uli526x_free_tx_pkt
(
dev
,
db
);
return
length
;
}
/*
* Free TX resource after TX complete
*/
static
void
uli526x_free_tx_pkt
(
struct
eth_device
*
dev
,
struct
uli526x_board_info
*
db
)
{
struct
tx_desc
*
txptr
;
u32
tdes0
;
txptr
=
db
->
tx_remove_ptr
;
while
(
db
->
tx_packet_cnt
)
{
tdes0
=
le32_to_cpu
(
txptr
->
tdes0
);
/* printf(DRV_NAME ": tdes0=%x\n", tdes0); */
if
(
tdes0
&
0x80000000
)
break
;
/* A packet sent completed */
db
->
tx_packet_cnt
--
;
if
(
tdes0
!=
0x7fffffff
)
{
#ifdef TX_DEBUG
printf
(
"%s()tdes0=%x
\n
"
,
__FUNCTION__
,
tdes0
);
#endif
if
(
tdes0
&
TDES0_ERR_MASK
)
{
if
(
tdes0
&
0x0002
)
{
/* UnderRun */
if
(
!
(
db
->
cr6_data
&
CR6_SFT
))
{
db
->
cr6_data
=
db
->
cr6_data
|
CR6_SFT
;
update_cr6
(
db
->
cr6_data
,
db
->
ioaddr
);
}
}
}
}
txptr
=
txptr
->
next_tx_desc
;
}
/* End of while */
/* Update TX remove pointer to next */
db
->
tx_remove_ptr
=
txptr
;
}
/*
* Receive the come packet and pass to upper layer
*/
static
int
uli526x_rx_packet
(
struct
eth_device
*
dev
)
{
struct
uli526x_board_info
*
db
=
dev
->
priv
;
struct
rx_desc
*
rxptr
;
int
rxlen
=
0
;
u32
rdes0
;
rxptr
=
db
->
rx_ready_ptr
;
rdes0
=
le32_to_cpu
(
rxptr
->
rdes0
);
#ifdef RX_DEBUG
printf
(
"%s(): rxptr->rdes0=%x:%x
\n
"
,
__FUNCTION__
,
rxptr
->
rdes0
);
#endif
if
(
!
(
rdes0
&
0x80000000
))
{
/* packet owner check */
if
((
rdes0
&
0x300
)
!=
0x300
)
{
/* A packet without First/Last flag */
/* reuse this buf */
printf
(
"A packet without First/Last flag"
);
uli526x_reuse_buf
(
rxptr
);
}
else
{
/* A packet with First/Last flag */
rxlen
=
((
rdes0
>>
16
)
&
0x3fff
)
-
4
;
#ifdef RX_DEBUG
printf
(
"%s(): rxlen =%x
\n
"
,
__FUNCTION__
,
rxlen
);
#endif
/* error summary bit check */
if
(
rdes0
&
0x8000
)
{
/* This is a error packet */
printf
(
"Eroor: rdes0: %lx
\n
"
,
rdes0
);
}
if
(
!
(
rdes0
&
0x8000
)
||
((
db
->
cr6_data
&
CR6_PM
)
&&
(
rxlen
>
6
)))
{
#ifdef RX_DEBUG
printf
(
"%s(): rx_skb_ptr =%x
\n
"
,
__FUNCTION__
,
rxptr
->
rx_buf_ptr
);
printf
(
"%s(): rxlen =%x
\n
"
,
__FUNCTION__
,
rxlen
);
printf
(
"%s(): buf addr =%x
\n
"
,
__FUNCTION__
,
rxptr
->
rx_buf_ptr
);
printf
(
"%s(): rxlen =%x
\n
"
,
__FUNCTION__
,
rxlen
);
int
i
;
for
(
i
=
0
;
i
<
0x20
;
i
++
)
printf
(
"%s(): data[%x] =%x
\n
"
,
__FUNCTION__
,
i
,
rxptr
->
rx_buf_ptr
[
i
]);
#endif
NetReceive
(
rxptr
->
rx_buf_ptr
,
rxlen
);
uli526x_reuse_buf
(
rxptr
);
}
else
{
/* Reuse SKB buffer when the packet is error */
printf
(
"Reuse buffer, rdes0"
);
uli526x_reuse_buf
(
rxptr
);
}
}
rxptr
=
rxptr
->
next_rx_desc
;
}
db
->
rx_ready_ptr
=
rxptr
;
return
rxlen
;
}
/*
* Reuse the RX buffer
*/
static
void
uli526x_reuse_buf
(
struct
rx_desc
*
rxptr
)
{
if
(
!
(
rxptr
->
rdes0
&
cpu_to_le32
(
0x80000000
)))
rxptr
->
rdes0
=
cpu_to_le32
(
0x80000000
);
else
printf
(
"Buffer reuse method error"
);
}
/*
* Initialize transmit/Receive descriptor
* Using Chain structure, and allocate Tx/Rx buffer
*/
static
void
uli526x_descriptor_init
(
struct
uli526x_board_info
*
db
,
unsigned
long
ioaddr
)
{
struct
tx_desc
*
tmp_tx
;
struct
rx_desc
*
tmp_rx
;
unsigned
char
*
tmp_buf
;
dma_addr_t
tmp_tx_dma
,
tmp_rx_dma
;
dma_addr_t
tmp_buf_dma
;
int
i
;
/* tx descriptor start pointer */
db
->
tx_insert_ptr
=
db
->
first_tx_desc
;
db
->
tx_remove_ptr
=
db
->
first_tx_desc
;
outl
(
db
->
first_tx_desc_dma
,
ioaddr
+
DCR4
);
/* TX DESC address */
/* rx descriptor start pointer */
db
->
first_rx_desc
=
(
void
*
)
db
->
first_tx_desc
+
sizeof
(
struct
tx_desc
)
*
TX_DESC_CNT
;
db
->
first_rx_desc_dma
=
db
->
first_tx_desc_dma
+
sizeof
(
struct
tx_desc
)
*
TX_DESC_CNT
;
db
->
rx_ready_ptr
=
db
->
first_rx_desc
;
outl
(
db
->
first_rx_desc_dma
,
ioaddr
+
DCR3
);
/* RX DESC address */
#ifdef DEBUG
printf
(
"%s(): db->first_tx_desc= 0x%x
\n
"
,
__FUNCTION__
,
db
->
first_tx_desc
);
printf
(
"%s(): db->first_rx_desc_dma= 0x%x
\n
"
,
__FUNCTION__
,
db
->
first_rx_desc_dma
);
#endif
/* Init Transmit chain */
tmp_buf
=
db
->
buf_pool_start
;
tmp_buf_dma
=
db
->
buf_pool_dma_start
;
tmp_tx_dma
=
db
->
first_tx_desc_dma
;
for
(
tmp_tx
=
db
->
first_tx_desc
,
i
=
0
;
i
<
TX_DESC_CNT
;
i
++
,
tmp_tx
++
)
{
tmp_tx
->
tx_buf_ptr
=
tmp_buf
;
tmp_tx
->
tdes0
=
cpu_to_le32
(
0
);
tmp_tx
->
tdes1
=
cpu_to_le32
(
0x81000000
);
/* IC, chain */
tmp_tx
->
tdes2
=
cpu_to_le32
(
tmp_buf_dma
);
tmp_tx_dma
+=
sizeof
(
struct
tx_desc
);
tmp_tx
->
tdes3
=
cpu_to_le32
(
tmp_tx_dma
);
tmp_tx
->
next_tx_desc
=
tmp_tx
+
1
;
tmp_buf
=
tmp_buf
+
TX_BUF_ALLOC
;
tmp_buf_dma
=
tmp_buf_dma
+
TX_BUF_ALLOC
;
}
(
--
tmp_tx
)
->
tdes3
=
cpu_to_le32
(
db
->
first_tx_desc_dma
);
tmp_tx
->
next_tx_desc
=
db
->
first_tx_desc
;
/* Init Receive descriptor chain */
tmp_rx_dma
=
db
->
first_rx_desc_dma
;
for
(
tmp_rx
=
db
->
first_rx_desc
,
i
=
0
;
i
<
RX_DESC_CNT
;
i
++
,
tmp_rx
++
)
{
tmp_rx
->
rdes0
=
cpu_to_le32
(
0
);
tmp_rx
->
rdes1
=
cpu_to_le32
(
0x01000600
);
tmp_rx_dma
+=
sizeof
(
struct
rx_desc
);
tmp_rx
->
rdes3
=
cpu_to_le32
(
tmp_rx_dma
);
tmp_rx
->
next_rx_desc
=
tmp_rx
+
1
;
}
(
--
tmp_rx
)
->
rdes3
=
cpu_to_le32
(
db
->
first_rx_desc_dma
);
tmp_rx
->
next_rx_desc
=
db
->
first_rx_desc
;
/* pre-allocate Rx buffer */
allocate_rx_buffer
(
db
);
}
/*
* Update CR6 value
* Firstly stop ULI526X, then written value and start
*/
static
void
update_cr6
(
u32
cr6_data
,
unsigned
long
ioaddr
)
{
outl
(
cr6_data
,
ioaddr
+
DCR6
);
udelay
(
5
);
}
/*
* Allocate rx buffer,
*/
static
void
allocate_rx_buffer
(
struct
uli526x_board_info
*
db
)
{
int
index
;
struct
rx_desc
*
rxptr
;
rxptr
=
db
->
first_rx_desc
;
u32
addr
;
for
(
index
=
0
;
index
<
RX_DESC_CNT
;
index
++
)
{
addr
=
(
u32
)
NetRxPackets
[
index
];
addr
+=
(
16
-
(
addr
&
15
));
rxptr
->
rx_buf_ptr
=
(
char
*
)
addr
;
rxptr
->
rdes2
=
cpu_to_le32
(
addr
);
rxptr
->
rdes0
=
cpu_to_le32
(
0x80000000
);
#ifdef DEBUG
printf
(
"%s(): Number 0x%x:
\n
"
,
__FUNCTION__
,
index
);
printf
(
"%s(): addr 0x%x:
\n
"
,
__FUNCTION__
,
addr
);
printf
(
"%s(): rxptr address = 0x%x
\n
"
,
__FUNCTION__
,
rxptr
);
printf
(
"%s(): rxptr buf address = 0x%x
\n
"
,
\
__FUNCTION__
,
rxptr
->
rx_buf_ptr
);
printf
(
"%s(): rdes2 = 0x%x
\n
"
,
__FUNCTION__
,
rxptr
->
rdes2
);
#endif
rxptr
=
rxptr
->
next_rx_desc
;
}
}
/*
* Read one word data from the serial ROM
*/
static
u16
read_srom_word
(
long
ioaddr
,
int
offset
)
{
int
i
;
u16
srom_data
=
0
;
long
cr9_ioaddr
=
ioaddr
+
DCR9
;
outl
(
CR9_SROM_READ
,
cr9_ioaddr
);
outl
(
CR9_SROM_READ
|
CR9_SRCS
,
cr9_ioaddr
);
/* Send the Read Command 110b */
SROM_CLK_WRITE
(
SROM_DATA_1
,
cr9_ioaddr
);
SROM_CLK_WRITE
(
SROM_DATA_1
,
cr9_ioaddr
);
SROM_CLK_WRITE
(
SROM_DATA_0
,
cr9_ioaddr
);
/* Send the offset */
for
(
i
=
5
;
i
>=
0
;
i
--
)
{
srom_data
=
(
offset
&
(
1
<<
i
))
?
SROM_DATA_1
:
SROM_DATA_0
;
SROM_CLK_WRITE
(
srom_data
,
cr9_ioaddr
);
}
outl
(
CR9_SROM_READ
|
CR9_SRCS
,
cr9_ioaddr
);
for
(
i
=
16
;
i
>
0
;
i
--
)
{
outl
(
CR9_SROM_READ
|
CR9_SRCS
|
CR9_SRCLK
,
cr9_ioaddr
);
udelay
(
5
);
srom_data
=
(
srom_data
<<
1
)
|
((
inl
(
cr9_ioaddr
)
&
CR9_CRDOUT
)
?
1
:
0
);
outl
(
CR9_SROM_READ
|
CR9_SRCS
,
cr9_ioaddr
);
udelay
(
5
);
}
outl
(
CR9_SROM_READ
,
cr9_ioaddr
);
return
srom_data
;
}
/*
* Set 10/100 phyxcer capability
* AUTO mode : phyxcer register4 is NIC capability
* Force mode: phyxcer register4 is the force media
*/
static
void
uli526x_set_phyxcer
(
struct
uli526x_board_info
*
db
)
{
u16
phy_reg
;
/* Phyxcer capability setting */
phy_reg
=
phy_read
(
db
->
ioaddr
,
db
->
phy_addr
,
4
,
db
->
chip_id
)
&
~
0x01e0
;
if
(
db
->
media_mode
&
ULI526X_AUTO
)
{
/* AUTO Mode */
phy_reg
|=
db
->
PHY_reg4
;
}
else
{
/* Force Mode */
switch
(
db
->
media_mode
)
{
case
ULI526X_10MHF
:
phy_reg
|=
0x20
;
break
;
case
ULI526X_10MFD
:
phy_reg
|=
0x40
;
break
;
case
ULI526X_100MHF
:
phy_reg
|=
0x80
;
break
;
case
ULI526X_100MFD
:
phy_reg
|=
0x100
;
break
;
}
}
/* Write new capability to Phyxcer Reg4 */
if
(
!
(
phy_reg
&
0x01e0
))
{
phy_reg
|=
db
->
PHY_reg4
;
db
->
media_mode
|=
ULI526X_AUTO
;
}
phy_write
(
db
->
ioaddr
,
db
->
phy_addr
,
4
,
phy_reg
,
db
->
chip_id
);
/* Restart Auto-Negotiation */
phy_write
(
db
->
ioaddr
,
db
->
phy_addr
,
0
,
0x1200
,
db
->
chip_id
);
udelay
(
50
);
}
/*
* Write a word to Phy register
*/
static
void
phy_write
(
unsigned
long
iobase
,
u8
phy_addr
,
u8
offset
,
u16
phy_data
,
u32
chip_id
)
{
u16
i
;
unsigned
long
ioaddr
;
if
(
chip_id
==
PCI_ULI5263_ID
)
{
phy_writeby_cr10
(
iobase
,
phy_addr
,
offset
,
phy_data
);
return
;
}
/* M5261/M5263 Chip */
ioaddr
=
iobase
+
DCR9
;
/* Send 33 synchronization clock to Phy controller */
for
(
i
=
0
;
i
<
35
;
i
++
)
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
/* Send start command(01) to Phy */
phy_write_1bit
(
ioaddr
,
PHY_DATA_0
,
chip_id
);
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
/* Send write command(01) to Phy */
phy_write_1bit
(
ioaddr
,
PHY_DATA_0
,
chip_id
);
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
/* Send Phy address */
for
(
i
=
0x10
;
i
>
0
;
i
=
i
>>
1
)
phy_write_1bit
(
ioaddr
,
phy_addr
&
i
?
PHY_DATA_1
:
PHY_DATA_0
,
chip_id
);
/* Send register address */
for
(
i
=
0x10
;
i
>
0
;
i
=
i
>>
1
)
phy_write_1bit
(
ioaddr
,
offset
&
i
?
PHY_DATA_1
:
PHY_DATA_0
,
chip_id
);
/* written trasnition */
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
phy_write_1bit
(
ioaddr
,
PHY_DATA_0
,
chip_id
);
/* Write a word data to PHY controller */
for
(
i
=
0x8000
;
i
>
0
;
i
>>=
1
)
phy_write_1bit
(
ioaddr
,
phy_data
&
i
?
PHY_DATA_1
:
PHY_DATA_0
,
chip_id
);
}
/*
* Read a word data from phy register
*/
static
u16
phy_read
(
unsigned
long
iobase
,
u8
phy_addr
,
u8
offset
,
u32
chip_id
)
{
int
i
;
u16
phy_data
;
unsigned
long
ioaddr
;
if
(
chip_id
==
PCI_ULI5263_ID
)
return
phy_readby_cr10
(
iobase
,
phy_addr
,
offset
);
/* M5261/M5263 Chip */
ioaddr
=
iobase
+
DCR9
;
/* Send 33 synchronization clock to Phy controller */
for
(
i
=
0
;
i
<
35
;
i
++
)
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
/* Send start command(01) to Phy */
phy_write_1bit
(
ioaddr
,
PHY_DATA_0
,
chip_id
);
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
/* Send read command(10) to Phy */
phy_write_1bit
(
ioaddr
,
PHY_DATA_1
,
chip_id
);
phy_write_1bit
(
ioaddr
,
PHY_DATA_0
,
chip_id
);
/* Send Phy address */
for
(
i
=
0x10
;
i
>
0
;
i
=
i
>>
1
)
phy_write_1bit
(
ioaddr
,
phy_addr
&
i
?
PHY_DATA_1
:
PHY_DATA_0
,
chip_id
);
/* Send register address */
for
(
i
=
0x10
;
i
>
0
;
i
=
i
>>
1
)
phy_write_1bit
(
ioaddr
,
offset
&
i
?
PHY_DATA_1
:
PHY_DATA_0
,
chip_id
);
/* Skip transition state */
phy_read_1bit
(
ioaddr
,
chip_id
);
/* read 16bit data */
for
(
phy_data
=
0
,
i
=
0
;
i
<
16
;
i
++
)
{
phy_data
<<=
1
;
phy_data
|=
phy_read_1bit
(
ioaddr
,
chip_id
);
}
return
phy_data
;
}
static
u16
phy_readby_cr10
(
unsigned
long
iobase
,
u8
phy_addr
,
u8
offset
)
{
unsigned
long
ioaddr
,
cr10_value
;
ioaddr
=
iobase
+
DCR10
;
cr10_value
=
phy_addr
;
cr10_value
=
(
cr10_value
<<
5
)
+
offset
;
cr10_value
=
(
cr10_value
<<
16
)
+
0x08000000
;
outl
(
cr10_value
,
ioaddr
);
udelay
(
1
);
while
(
1
)
{
cr10_value
=
inl
(
ioaddr
);
if
(
cr10_value
&
0x10000000
)
break
;
}
return
(
cr10_value
&
0x0ffff
);
}
static
void
phy_writeby_cr10
(
unsigned
long
iobase
,
u8
phy_addr
,
u8
offset
,
u16
phy_data
)
{
unsigned
long
ioaddr
,
cr10_value
;
ioaddr
=
iobase
+
DCR10
;
cr10_value
=
phy_addr
;
cr10_value
=
(
cr10_value
<<
5
)
+
offset
;
cr10_value
=
(
cr10_value
<<
16
)
+
0x04000000
+
phy_data
;
outl
(
cr10_value
,
ioaddr
);
udelay
(
1
);
}
/*
* Write one bit data to Phy Controller
*/
static
void
phy_write_1bit
(
unsigned
long
ioaddr
,
u32
phy_data
,
u32
chip_id
)
{
outl
(
phy_data
,
ioaddr
);
/* MII Clock Low */
udelay
(
1
);
outl
(
phy_data
|
MDCLKH
,
ioaddr
);
/* MII Clock High */
udelay
(
1
);
outl
(
phy_data
,
ioaddr
);
/* MII Clock Low */
udelay
(
1
);
}
/*
* Read one bit phy data from PHY controller
*/
static
u16
phy_read_1bit
(
unsigned
long
ioaddr
,
u32
chip_id
)
{
u16
phy_data
;
outl
(
0x50000
,
ioaddr
);
udelay
(
1
);
phy_data
=
(
inl
(
ioaddr
)
>>
19
)
&
0x1
;
outl
(
0x40000
,
ioaddr
);
udelay
(
1
);
return
phy_data
;
}
/*
* Set MAC address to ID Table
*/
static
void
set_mac_addr
(
struct
eth_device
*
dev
)
{
int
i
;
u16
addr
;
struct
uli526x_board_info
*
db
=
dev
->
priv
;
outl
(
0x10000
,
db
->
ioaddr
+
DCR0
);
/* Diagnosis mode */
/* Reset dianostic pointer port */
outl
(
0x1c0
,
db
->
ioaddr
+
DCR13
);
outl
(
0
,
db
->
ioaddr
+
DCR14
);
/* Clear reset port */
outl
(
0x10
,
db
->
ioaddr
+
DCR14
);
/* Reset ID Table pointer */
outl
(
0
,
db
->
ioaddr
+
DCR14
);
/* Clear reset port */
outl
(
0
,
db
->
ioaddr
+
DCR13
);
/* Clear CR13 */
/* Select ID Table access port */
outl
(
0x1b0
,
db
->
ioaddr
+
DCR13
);
/* Read MAC address from CR14 */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
addr
=
dev
->
enetaddr
[
2
*
i
]
|
(
dev
->
enetaddr
[
2
*
i
+
1
]
<<
8
);
outl
(
addr
,
db
->
ioaddr
+
DCR14
);
}
/* write end */
outl
(
0
,
db
->
ioaddr
+
DCR13
);
/* Clear CR13 */
outl
(
0
,
db
->
ioaddr
+
DCR0
);
/* Clear CR0 */
udelay
(
10
);
return
;
}
#endif
include/miiphy.h
浏览文件 @
a08ded4e
...
...
@@ -26,56 +26,49 @@
|
| Author: Mark Wisner
|
| Change Activity-
|
| Date Description of Change BY
| --------- --------------------- ---
| 04-May-99 Created MKW
| 07-Jul-99 Added full duplex support MKW
| 08-Sep-01 Tweaks gvb
|
+----------------------------------------------------------------------------*/
#ifndef _miiphy_h_
#define _miiphy_h_
#include <net.h>
int
miiphy_read
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
);
int
miiphy_write
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
);
int
miiphy_info
(
char
*
devname
,
unsigned
char
addr
,
unsigned
int
*
oui
,
unsigned
char
*
model
,
unsigned
char
*
rev
);
int
miiphy_reset
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_speed
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_duplex
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_read
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
);
int
miiphy_write
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
);
int
miiphy_info
(
char
*
devname
,
unsigned
char
addr
,
unsigned
int
*
oui
,
unsigned
char
*
model
,
unsigned
char
*
rev
);
int
miiphy_reset
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_speed
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_duplex
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_is_1000base_x
(
char
*
devname
,
unsigned
char
addr
);
#ifdef CFG_FAULT_ECHO_LINK_DOWN
int
miiphy_link
(
char
*
devname
,
unsigned
char
addr
);
int
miiphy_link
(
char
*
devname
,
unsigned
char
addr
);
#endif
void
miiphy_init
(
void
);
void
miiphy_init
(
void
);
void
miiphy_register
(
char
*
devname
,
int
(
*
read
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
),
int
(
*
write
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
));
void
miiphy_register
(
char
*
devname
,
int
(
*
read
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
),
int
(
*
write
)
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
));
int
miiphy_set_current_dev
(
char
*
devname
);
char
*
miiphy_get_current_dev
(
void
);
int
miiphy_set_current_dev
(
char
*
devname
);
char
*
miiphy_get_current_dev
(
void
);
void
miiphy_listdev
(
void
);
void
miiphy_listdev
(
void
);
#define BB_MII_DEVNAME "bbmii"
int
bb_miiphy_read
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
*
value
);
unsigned
char
reg
,
unsigned
short
*
value
);
int
bb_miiphy_write
(
char
*
devname
,
unsigned
char
addr
,
unsigned
char
reg
,
unsigned
short
value
);
unsigned
char
reg
,
unsigned
short
value
);
/* phy seed setup */
#define AUTO 99
#define _1000BASET
1000
#define _1000BASET
1000
#define _100BASET 100
#define _10BASET 10
#define HALF 22
...
...
@@ -90,9 +83,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,
#define PHY_ANLPAR 0x05
#define PHY_ANER 0x06
#define PHY_ANNPTR 0x07
#define PHY_ANLPNP 0x08
#define PHY_1000BTCR 0x09
#define PHY_1000BTSR 0x0A
#define PHY_ANLPNP 0x08
#define PHY_1000BTCR 0x09
#define PHY_1000BTSR 0x0A
#define PHY_EXSR 0x0F
#define PHY_PHYSTS 0x10
#define PHY_MIPSCR 0x11
#define PHY_MIPGSR 0x12
...
...
@@ -115,10 +109,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,
#define PHY_BMCR_DPLX 0x0100
#define PHY_BMCR_COL_TST 0x0080
#define PHY_BMCR_SPEED_MASK
0x2040
#define PHY_BMCR_1000_MBPS
0x0040
#define PHY_BMCR_100_MBPS
0x2000
#define PHY_BMCR_10_MBPS
0x0000
#define PHY_BMCR_SPEED_MASK
0x2040
#define PHY_BMCR_1000_MBPS
0x0040
#define PHY_BMCR_100_MBPS
0x2000
#define PHY_BMCR_10_MBPS
0x0000
/* phy BMSR */
#define PHY_BMSR_100T4 0x8000
...
...
@@ -126,6 +120,7 @@ int bb_miiphy_write (char *devname, unsigned char addr,
#define PHY_BMSR_100TXH 0x2000
#define PHY_BMSR_10TF 0x1000
#define PHY_BMSR_10TH 0x0800
#define PHY_BMSR_EXT_STAT 0x0100
#define PHY_BMSR_PRE_SUP 0x0040
#define PHY_BMSR_AUTN_COMP 0x0020
#define PHY_BMSR_RF 0x0010
...
...
@@ -138,23 +133,42 @@ int bb_miiphy_write (char *devname, unsigned char addr,
#define PHY_ANLPAR_NP 0x8000
#define PHY_ANLPAR_ACK 0x4000
#define PHY_ANLPAR_RF 0x2000
#define PHY_ANLPAR_ASYMP 0x0800
#define PHY_ANLPAR_PAUSE 0x0400
#define PHY_ANLPAR_T4 0x0200
#define PHY_ANLPAR_TXFD 0x0100
#define PHY_ANLPAR_TX 0x0080
#define PHY_ANLPAR_10FD 0x0040
#define PHY_ANLPAR_10 0x0020
#define PHY_ANLPAR_100 0x0380
/* we can run at 100 */
#define PHY_ANLPAR_PSB_MASK 0x001f
#define PHY_ANLPAR_PSB_802_3 0x0001
#define PHY_ANLPAR_PSB_802_9 0x0002
/* PHY_1000BTSR */
#define PHY_1000BTSR_MSCF 0x8000
#define PHY_1000BTSR_MSCR 0x4000
#define PHY_1000BTSR_LRS 0x2000
#define PHY_1000BTSR_RRS 0x1000
#define PHY_1000BTSR_1000FD 0x0800
#define PHY_1000BTSR_1000HD 0x0400
#define PHY_ANLPAR_100 0x0380
/* we can run at 100 */
/* phy ANLPAR 1000BASE-X */
#define PHY_X_ANLPAR_NP 0x8000
#define PHY_X_ANLPAR_ACK 0x4000
#define PHY_X_ANLPAR_RF_MASK 0x3000
#define PHY_X_ANLPAR_PAUSE_MASK 0x0180
#define PHY_X_ANLPAR_HD 0x0040
#define PHY_X_ANLPAR_FD 0x0020
#define PHY_ANLPAR_PSB_MASK 0x001f
#define PHY_ANLPAR_PSB_802_3 0x0001
#define PHY_ANLPAR_PSB_802_9 0x0002
/* phy 1000BTCR */
#define PHY_1000BTCR_1000FD 0x0200
#define PHY_1000BTCR_1000HD 0x0100
/* phy 1000BTSR */
#define PHY_1000BTSR_MSCF 0x8000
#define PHY_1000BTSR_MSCR 0x4000
#define PHY_1000BTSR_LRS 0x2000
#define PHY_1000BTSR_RRS 0x1000
#define PHY_1000BTSR_1000FD 0x0800
#define PHY_1000BTSR_1000HD 0x0400
/* phy EXSR */
#define PHY_EXSR_1000XF 0x8000
#define PHY_EXSR_1000XH 0x4000
#define PHY_EXSR_1000TF 0x2000
#define PHY_EXSR_1000TH 0x1000
#endif
net/eth.c
浏览文件 @
a08ded4e
...
...
@@ -54,6 +54,7 @@ extern int rtl8169_initialize(bd_t*);
extern
int
scc_initialize
(
bd_t
*
);
extern
int
skge_initialize
(
bd_t
*
);
extern
int
tsi108_eth_initialize
(
bd_t
*
);
extern
int
uli526x_initialize
(
bd_t
*
);
extern
int
tsec_initialize
(
bd_t
*
,
int
,
char
*
);
extern
int
npe_initialize
(
bd_t
*
);
extern
int
uec_initialize
(
int
);
...
...
@@ -238,6 +239,9 @@ int eth_initialize(bd_t *bis)
#if defined(CONFIG_TSI108_ETH)
tsi108_eth_initialize
(
bis
);
#endif
#if defined(CONFIG_ULI526X)
uli526x_initialize
(
bis
);
#endif
#if defined(CONFIG_RTL8139)
rtl8139_initialize
(
bis
);
#endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录