Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
bcde82a2
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,发现更多精彩内容 >>
提交
bcde82a2
编写于
11月 19, 2010
作者:
W
Wolfgang Denk
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'net' of
git://git.denx.de/u-boot-sparc
上级
635d1b3e
64394660
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
94 addition
and
70 deletion
+94
-70
drivers/net/greth.c
drivers/net/greth.c
+94
-70
未找到文件。
drivers/net/greth.c
浏览文件 @
bcde82a2
...
...
@@ -24,6 +24,8 @@
* MA 02111-1307 USA
*/
/* #define DEBUG */
#include <common.h>
#include <command.h>
#include <net.h>
...
...
@@ -33,8 +35,6 @@
#include <ambapp.h>
#include <asm/leon.h>
/* #define DEBUG */
#include "greth.h"
/* Default to 3s timeout on autonegotiation */
...
...
@@ -42,10 +42,17 @@
#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 */
#define GRETH_REGSAVE(addr,data)
(*(
unsigned int *)(addr) = (data))
#define GRETH_REGSAVE(addr,data)
(*(volatile
unsigned int *)(addr) = (data))
#define GRETH_REGORIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)|data)
#define GRETH_REGANDIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)&data)
...
...
@@ -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
)
{
}
...
...
@@ -142,11 +149,18 @@ int greth_init(struct eth_device *dev, bd_t * bis)
greth_priv
*
greth
=
dev
->
priv
;
greth_regs
*
regs
=
greth
->
regs
;
#ifdef DEBUG
printf
(
"greth_init
\n
"
);
#endif
GRETH_REGSAVE
(
&
regs
->
control
,
0
);
debug
(
"greth_init
\n
"
);
/* Reset core */
GRETH_REGSAVE
(
&
regs
->
control
,
(
GRETH_RESET
|
(
greth
->
gb
<<
8
)
|
(
greth
->
sp
<<
7
)
|
(
greth
->
fd
<<
4
)));
/* Wait for Reset to complete */
while
(
GRETH_REGLOAD
(
&
regs
->
control
)
&
GRETH_RESET
)
;
GRETH_REGSAVE
(
&
regs
->
control
,
((
greth
->
gb
<<
8
)
|
(
greth
->
sp
<<
7
)
|
(
greth
->
fd
<<
4
)));
if
(
!
greth
->
rxbd_base
)
{
...
...
@@ -154,7 +168,7 @@ int greth_init(struct eth_device *dev, bd_t * bis)
greth
->
rxbd_base
=
(
greth_bd
*
)
memalign
(
0x1000
,
GRETH_RXBD_CNT
*
sizeof
(
greth_bd
));
greth
->
txbd_base
=
(
greth_bd
*
)
memalign
(
0x1000
,
GRETH_
R
XBD_CNT
*
sizeof
(
greth_bd
));
memalign
(
0x1000
,
GRETH_
T
XBD_CNT
*
sizeof
(
greth_bd
));
/* allocate buffers to all descriptors */
greth
->
rxbuf_base
=
...
...
@@ -186,7 +200,7 @@ int greth_init(struct eth_device *dev, bd_t * bis)
for
(
i
=
0
;
i
<
GRETH_TXBD_CNT
;
i
++
)
{
greth
->
txbd_base
[
i
].
addr
=
0
;
/* enable desciptor & set wrap bit if last descriptor */
if
(
i
>=
(
GRETH_
R
XBD_CNT
-
1
))
{
if
(
i
>=
(
GRETH_
T
XBD_CNT
-
1
))
{
greth
->
txbd_base
[
i
].
stat
=
GRETH_BD_WR
;
}
else
{
greth
->
txbd_base
[
i
].
stat
=
0
;
...
...
@@ -201,9 +215,7 @@ int greth_init(struct eth_device *dev, bd_t * bis)
/* Enable Transmitter, GRETH will now scan descriptors for packets
* to transmitt */
#ifdef DEBUG
printf
(
"greth_init: enabling receiver
\n
"
);
#endif
debug
(
"greth_init: enabling receiver
\n
"
);
GRETH_REGORIN
(
&
regs
->
control
,
GRETH_RXEN
);
return
0
;
...
...
@@ -219,6 +231,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
);
...
...
@@ -230,17 +262,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
...
...
@@ -251,16 +287,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
)
...
...
@@ -270,8 +306,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
;
...
...
@@ -284,8 +320,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
;
...
...
@@ -302,28 +338,24 @@ 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
);
}
}
}
auto_neg_done:
#ifdef DEBUG
printf
(
"%s GRETH Ethermac at [0x%x] irq %d. Running \
debug
(
"%s GRETH Ethermac at [0x%x] irq %d. Running \
%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"
);
#endif
/* 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
;
tmp2
=
(
tmp2
>>
4
)
&
0x3F
;
#ifdef DEBUG
printf
(
"PHY: Vendor %x Device %x Revision %d
\n
"
,
tmp1
,
debug
(
"PHY: Vendor %x Device %x Revision %d
\n
"
,
tmp1
,
tmp2
,
tmp
);
#endif
}
else
{
printf
(
"PHY info not available
\n
"
);
}
...
...
@@ -340,9 +372,9 @@ void greth_halt(struct eth_device *dev)
greth_priv
*
greth
;
greth_regs
*
regs
;
int
i
;
#ifdef DEBUG
printf
(
"greth_halt
\n
"
);
#endif
debug
(
"greth_halt
\n
"
);
if
(
!
dev
||
!
dev
->
priv
)
return
;
...
...
@@ -378,9 +410,9 @@ int greth_send(struct eth_device *dev, volatile void *eth_data, int data_length)
greth_bd
*
txbd
;
void
*
txbuf
;
unsigned
int
status
;
#ifdef DEBUG
printf
(
"greth_send
\n
"
);
#endif
debug
(
"greth_send
\n
"
);
/* send data, wait for data to be sent, then return */
if
(((
unsigned
int
)
eth_data
&
(
GRETH_BUF_ALIGN
-
1
))
&&
!
greth
->
gbit_mac
)
{
...
...
@@ -389,9 +421,6 @@ int greth_send(struct eth_device *dev, volatile void *eth_data, int data_length)
*/
if
(
!
greth
->
txbuf
)
{
greth
->
txbuf
=
malloc
(
GRETH_RXBUF_SIZE
);
#ifdef DEBUG
printf
(
"GRETH: allocated aligned tx-buf
\n
"
);
#endif
}
txbuf
=
greth
->
txbuf
;
...
...
@@ -457,9 +486,7 @@ int greth_recv(struct eth_device *dev)
unsigned
char
*
d
;
int
enable
=
0
;
int
i
;
#ifdef DEBUG
/* printf("greth_recv\n"); */
#endif
/* Receive One packet only, but clear as many error packets as there are
* available.
*/
...
...
@@ -476,10 +503,9 @@ int greth_recv(struct eth_device *dev)
if
(
status
&
GRETH_BD_EN
)
{
goto
done
;
}
#ifdef DEBUG
printf
(
"greth_recv: packet 0x%lx, 0x%lx, len: %d
\n
"
,
debug
(
"greth_recv: packet 0x%lx, 0x%lx, len: %d
\n
"
,
(
unsigned
int
)
rxbd
,
status
,
status
&
GRETH_BD_LEN
);
#endif
/* Check status for errors.
*/
...
...
@@ -507,19 +533,18 @@ 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. */
len
=
status
&
GRETH_BD_LEN
;
d
=
(
char
*
)
rxbd
->
addr
;
#ifdef DEBUG
printf
debug
(
"greth_recv: new packet, length: %d. data: %x %x %x %x %x %x %x %x
\n
"
,
len
,
d
[
0
],
d
[
1
],
d
[
2
],
d
[
3
],
d
[
4
],
d
[
5
],
d
[
6
],
d
[
7
]);
#endif
/* flush all data cache to make sure we're not reading old packet data */
sparc_dcache_flush_all
();
...
...
@@ -545,7 +570,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
);
...
...
@@ -567,10 +592,9 @@ void greth_set_hwaddr(greth_priv * greth, unsigned char *mac)
greth
->
regs
->
esa_msb
=
(
mac
[
0
]
<<
8
)
|
mac
[
1
];
greth
->
regs
->
esa_lsb
=
(
mac
[
2
]
<<
24
)
|
(
mac
[
3
]
<<
16
)
|
(
mac
[
4
]
<<
8
)
|
mac
[
5
];
#ifdef DEBUG
printf
(
"GRETH: New MAC address: %02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
debug
(
"GRETH: New MAC address: %02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
],
mac
[
4
],
mac
[
5
]);
#endif
}
int
greth_initialize
(
bd_t
*
bis
)
...
...
@@ -581,9 +605,9 @@ int greth_initialize(bd_t * bis)
int
i
;
char
*
addr_str
,
*
end
;
unsigned
char
addr
[
6
];
#ifdef DEBUG
printf
(
"Scanning for GRETH
\n
"
);
#endif
debug
(
"Scanning for GRETH
\n
"
);
/* Find Device & IRQ via AMBA Plug&Play information */
if
(
ambapp_apb_first
(
VENDOR_GAISLER
,
GAISLER_ETHMAC
,
&
apbdev
)
!=
1
)
{
return
-
1
;
/* GRETH not found */
...
...
@@ -596,9 +620,7 @@ int greth_initialize(bd_t * bis)
greth
->
regs
=
(
greth_regs
*
)
apbdev
.
address
;
greth
->
irq
=
apbdev
.
irq
;
#ifdef DEBUG
printf
(
"Found GRETH at 0x%lx, irq %d
\n
"
,
greth
->
regs
,
greth
->
irq
);
#endif
debug
(
"Found GRETH at 0x%lx, irq %d
\n
"
,
greth
->
regs
,
greth
->
irq
);
dev
->
priv
=
(
void
*
)
greth
;
dev
->
iobase
=
(
unsigned
int
)
greth
->
regs
;
dev
->
init
=
greth_init
;
...
...
@@ -622,14 +644,15 @@ int greth_initialize(bd_t * bis)
/* Make descriptor string */
if
(
greth
->
gbit_mac
)
{
sprintf
(
dev
->
name
,
"GRETH
10/100/GB"
);
sprintf
(
dev
->
name
,
"GRETH
_
10/100/GB"
);
}
else
{
sprintf
(
dev
->
name
,
"GRETH
10/100"
);
sprintf
(
dev
->
name
,
"GRETH
_
10/100"
);
}
/* 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
;
}
...
...
@@ -658,5 +681,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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录