Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
726fa62d
提交
726fa62d
12月 29, 2011
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
E1000 locking
上级
2ada02f9
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
25 行增加
和
14 行删除
+25
-14
e1000.c
e1000.c
+25
-14
没有找到文件。
e1000.c
浏览文件 @
726fa62d
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
#include "amd64.h"
#include "amd64.h"
#include "kernel.h"
#include "kernel.h"
#include "pci.h"
#include "pci.h"
#include "spinlock.h"
#include "e1000reg.h"
#include "e1000reg.h"
#define TX_RING_SIZE 64
#define TX_RING_SIZE 64
...
@@ -14,16 +15,18 @@ static struct {
...
@@ -14,16 +15,18 @@ static struct {
u32
iobase
;
u32
iobase
;
u16
pcidevid
;
u16
pcidevid
;
u32
txclean
;
volatile
u32
txclean
;
u32
txinuse
;
volatile
u32
txinuse
;
u32
rxclean
;
volatile
u32
rxclean
;
u32
rxuse
;
volatile
u32
rxuse
;
u8
hwaddr
[
6
];
u8
hwaddr
[
6
];
struct
wiseman_txdesc
txd
[
TX_RING_SIZE
]
__attribute__
((
aligned
(
16
)));
struct
wiseman_txdesc
txd
[
TX_RING_SIZE
]
__attribute__
((
aligned
(
16
)));
struct
wiseman_rxdesc
rxd
[
RX_RING_SIZE
]
__attribute__
((
aligned
(
16
)));
struct
wiseman_rxdesc
rxd
[
RX_RING_SIZE
]
__attribute__
((
aligned
(
16
)));
struct
spinlock
lk
;
}
e1000
;
}
e1000
;
static
inline
u32
static
inline
u32
...
@@ -79,24 +82,27 @@ e1000tx(void *buf, u32 len)
...
@@ -79,24 +82,27 @@ e1000tx(void *buf, u32 len)
struct
wiseman_txdesc
*
desc
;
struct
wiseman_txdesc
*
desc
;
u32
tail
;
u32
tail
;
acquire
(
&
e1000
.
lk
);
// WMREG_TDT should only equal WMREG_TDH when we have
// WMREG_TDT should only equal WMREG_TDH when we have
// nothing to transmit. Therefore, we can accomodate
// nothing to transmit. Therefore, we can accomodate
// TX_RING_SIZE-1 buffers.
// TX_RING_SIZE-1 buffers.
if
(
e1000
.
txinuse
==
TX_RING_SIZE
-
1
)
{
if
(
e1000
.
txinuse
==
TX_RING_SIZE
-
1
)
{
cprintf
(
"TX ring overflow
\n
"
);
cprintf
(
"TX ring overflow
\n
"
);
release
(
&
e1000
.
lk
);
return
-
1
;
return
-
1
;
}
}
tail
=
erd
(
WMREG_TDT
);
tail
=
erd
(
WMREG_TDT
);
desc
=
&
e1000
.
txd
[
tail
];
desc
=
&
e1000
.
txd
[
tail
];
if
(
!
(
desc
->
wtx_fields
.
wtxu_status
&
WTX_ST_DD
))
if
(
!
(
desc
->
wtx_fields
.
wtxu_status
&
WTX_ST_DD
))
panic
(
"
oops
"
);
panic
(
"
e1000tx
"
);
desc
->
wtx_addr
=
v2p
(
buf
);
desc
->
wtx_addr
=
v2p
(
buf
);
desc
->
wtx_cmdlen
=
len
|
WTX_CMD_RS
|
WTX_CMD_EOP
|
WTX_CMD_IFCS
;
desc
->
wtx_cmdlen
=
len
|
WTX_CMD_RS
|
WTX_CMD_EOP
|
WTX_CMD_IFCS
;
memset
(
&
desc
->
wtx_fields
,
0
,
sizeof
(
&
desc
->
wtx_fields
));
memset
(
&
desc
->
wtx_fields
,
0
,
sizeof
(
desc
->
wtx_fields
));
ewr
(
WMREG_TDT
,
(
tail
+
1
)
%
TX_RING_SIZE
);
ewr
(
WMREG_TDT
,
(
tail
+
1
)
%
TX_RING_SIZE
);
e1000
.
txinuse
++
;
e1000
.
txinuse
++
;
release
(
&
e1000
.
lk
);
return
0
;
return
0
;
}
}
...
@@ -107,6 +113,7 @@ cleantx(void)
...
@@ -107,6 +113,7 @@ cleantx(void)
struct
wiseman_txdesc
*
desc
;
struct
wiseman_txdesc
*
desc
;
void
*
va
;
void
*
va
;
acquire
(
&
e1000
.
lk
);
while
(
e1000
.
txinuse
)
{
while
(
e1000
.
txinuse
)
{
desc
=
&
e1000
.
txd
[
e1000
.
txclean
];
desc
=
&
e1000
.
txd
[
e1000
.
txclean
];
if
(
!
(
desc
->
wtx_fields
.
wtxu_status
&
WTX_ST_DD
))
if
(
!
(
desc
->
wtx_fields
.
wtxu_status
&
WTX_ST_DD
))
...
@@ -114,12 +121,13 @@ cleantx(void)
...
@@ -114,12 +121,13 @@ cleantx(void)
va
=
p2v
(
desc
->
wtx_addr
);
va
=
p2v
(
desc
->
wtx_addr
);
netfree
(
va
);
netfree
(
va
);
desc
->
wtx_fields
.
wtxu_status
=
0
;
desc
->
wtx_fields
.
wtxu_status
=
WTX_ST_DD
;
e1000
.
txclean
=
(
e1000
.
txclean
+
1
)
%
TX_RING_SIZE
;
e1000
.
txclean
=
(
e1000
.
txclean
+
1
)
%
TX_RING_SIZE
;
desc
=
&
e1000
.
txd
[
e1000
.
txclean
];
desc
=
&
e1000
.
txd
[
e1000
.
txclean
];
e1000
.
txinuse
--
;
e1000
.
txinuse
--
;
}
}
release
(
&
e1000
.
lk
);
}
}
static
void
static
void
...
@@ -147,23 +155,25 @@ cleanrx(void)
...
@@ -147,23 +155,25 @@ cleanrx(void)
struct
wiseman_rxdesc
*
desc
;
struct
wiseman_rxdesc
*
desc
;
void
*
va
;
void
*
va
;
u16
len
;
u16
len
;
u32
i
;
i
=
e1000
.
rxclean
;
desc
=
&
e1000
.
rxd
[
i
];
acquire
(
&
e1000
.
lk
);
desc
=
&
e1000
.
rxd
[
e1000
.
rxclean
];
while
(
desc
->
wrx_status
&
WRX_ST_DD
)
{
while
(
desc
->
wrx_status
&
WRX_ST_DD
)
{
va
=
p2v
(
desc
->
wrx_addr
);
va
=
p2v
(
desc
->
wrx_addr
);
len
=
desc
->
wrx_len
;
len
=
desc
->
wrx_len
;
desc
->
wrx_status
=
0
;
desc
->
wrx_status
=
0
;
allocrx
();
allocrx
();
e1000
.
rxclean
=
(
e1000
.
rxclean
+
1
)
%
RX_RING_SIZE
;
release
(
&
e1000
.
lk
);
netrx
(
va
,
len
);
netrx
(
va
,
len
);
acquire
(
&
e1000
.
lk
);
i
=
(
i
+
1
)
%
RX_RING_SIZE
;
desc
=
&
e1000
.
rxd
[
e1000
.
rxclean
];
desc
=
&
e1000
.
rxd
[
i
];
}
}
e1000
.
rxclean
=
i
;
release
(
&
e1000
.
lk
)
;
}
}
void
void
...
@@ -254,6 +264,7 @@ e1000attach(struct pci_func *pcif)
...
@@ -254,6 +264,7 @@ e1000attach(struct pci_func *pcif)
pci_func_enable
(
pcif
);
pci_func_enable
(
pcif
);
initlock
(
&
e1000
.
lk
,
"e1000"
);
e1000
.
membase
=
pcif
->
reg_base
[
0
];
e1000
.
membase
=
pcif
->
reg_base
[
0
];
e1000
.
iobase
=
pcif
->
reg_base
[
2
];
e1000
.
iobase
=
pcif
->
reg_base
[
2
];
e1000
.
pcidevid
=
pcif
->
dev_id
;
e1000
.
pcidevid
=
pcif
->
dev_id
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论