Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
90937231
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
90937231
编写于
1月 28, 2009
作者:
D
David Woodhouse
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
solos: First attempt at DMA support
Signed-off-by:
N
David Woodhouse
<
David.Woodhouse@intel.com
>
上级
c0fe3026
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
90 addition
and
28 deletion
+90
-28
drivers/atm/solos-pci.c
drivers/atm/solos-pci.c
+90
-28
未找到文件。
drivers/atm/solos-pci.c
浏览文件 @
90937231
...
...
@@ -55,6 +55,8 @@
#define FLASH_BUSY 0x60
#define FPGA_MODE 0x5C
#define FLASH_MODE 0x58
#define TX_DMA_ADDR(port) (0x40 + (4 * (port)))
#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
#define DATA_RAM_SIZE 32768
#define BUF_SIZE 4096
...
...
@@ -78,6 +80,14 @@ struct pkt_hdr {
__le16
type
;
};
struct
solos_skb_cb
{
struct
atm_vcc
*
vcc
;
uint32_t
dma_addr
;
};
#define SKB_CB(skb) ((struct solos_skb_cb *)skb->cb)
#define PKT_DATA 0
#define PKT_COMMAND 1
#define PKT_POPEN 3
...
...
@@ -98,8 +108,11 @@ struct solos_card {
struct
list_head
param_queue
;
struct
sk_buff_head
tx_queue
[
4
];
struct
sk_buff_head
cli_queue
[
4
];
struct
sk_buff
*
tx_skb
[
4
];
struct
sk_buff
*
rx_skb
[
4
];
wait_queue_head_t
param_wq
;
wait_queue_head_t
fw_wq
;
int
using_dma
;
};
...
...
@@ -588,44 +601,64 @@ void solos_bh(unsigned long card_arg)
for
(
port
=
0
;
port
<
card
->
nr_ports
;
port
++
)
{
if
(
card_flags
&
(
0x10
<<
port
))
{
struct
pkt_hdr
header
;
struct
pkt_hdr
_hdr
,
*
header
;
struct
sk_buff
*
skb
;
struct
atm_vcc
*
vcc
;
int
size
;
rx_done
|=
0x10
<<
port
;
if
(
card
->
using_dma
)
{
skb
=
card
->
rx_skb
[
port
];
pci_unmap_single
(
card
->
dev
,
SKB_CB
(
skb
)
->
dma_addr
,
skb
->
len
,
PCI_DMA_FROMDEVICE
);
card
->
rx_skb
[
port
]
=
alloc_skb
(
2048
,
GFP_ATOMIC
);
if
(
card
->
rx_skb
[
port
])
{
SKB_CB
(
card
->
rx_skb
[
port
])
->
dma_addr
=
pci_map_single
(
card
->
dev
,
skb
->
data
,
skb
->
len
,
PCI_DMA_FROMDEVICE
);
iowrite32
(
SKB_CB
(
card
->
rx_skb
[
port
])
->
dma_addr
,
card
->
config_regs
+
RX_DMA_ADDR
(
port
));
}
header
=
(
void
*
)
skb
->
data
;
size
=
le16_to_cpu
(
header
->
size
);
skb_put
(
skb
,
size
+
sizeof
(
*
header
));
skb_pull
(
skb
,
sizeof
(
*
header
));
}
else
{
header
=
&
_hdr
;
memcpy_fromio
(
&
header
,
RX_BUF
(
card
,
port
),
sizeof
(
header
))
;
rx_done
|=
0x10
<<
port
;
size
=
le16_to_cpu
(
header
.
size
);
memcpy_fromio
(
header
,
RX_BUF
(
card
,
port
),
sizeof
(
*
header
)
);
skb
=
alloc_skb
(
size
+
1
,
GFP_ATOMIC
);
if
(
!
skb
)
{
if
(
net_ratelimit
())
dev_warn
(
&
card
->
dev
->
dev
,
"Failed to allocate sk_buff for RX
\n
"
);
continue
;
}
size
=
le16_to_cpu
(
header
->
size
);
memcpy_fromio
(
skb_put
(
skb
,
size
),
RX_BUF
(
card
,
port
)
+
sizeof
(
header
),
size
);
skb
=
alloc_skb
(
size
+
1
,
GFP_ATOMIC
);
if
(
!
skb
)
{
if
(
net_ratelimit
())
dev_warn
(
&
card
->
dev
->
dev
,
"Failed to allocate sk_buff for RX
\n
"
);
continue
;
}
memcpy_fromio
(
skb_put
(
skb
,
size
),
RX_BUF
(
card
,
port
)
+
sizeof
(
*
header
),
size
);
}
if
(
atmdebug
)
{
dev_info
(
&
card
->
dev
->
dev
,
"Received: device %d
\n
"
,
port
);
dev_info
(
&
card
->
dev
->
dev
,
"size: %d VPI: %d VCI: %d
\n
"
,
size
,
le16_to_cpu
(
header
.
vpi
),
le16_to_cpu
(
header
.
vci
));
size
,
le16_to_cpu
(
header
->
vpi
),
le16_to_cpu
(
header
->
vci
));
print_buffer
(
skb
);
}
switch
(
le16_to_cpu
(
header
.
type
))
{
switch
(
le16_to_cpu
(
header
->
type
))
{
case
PKT_DATA
:
vcc
=
find_vcc
(
card
->
atmdev
[
port
],
le16_to_cpu
(
header
.
vpi
),
le16_to_cpu
(
header
.
vci
));
vcc
=
find_vcc
(
card
->
atmdev
[
port
],
le16_to_cpu
(
header
->
vpi
),
le16_to_cpu
(
header
->
vci
));
if
(
!
vcc
)
{
if
(
net_ratelimit
())
dev_warn
(
&
card
->
dev
->
dev
,
"Received packet for unknown VCI.VPI %d.%d on port %d
\n
"
,
le16_to_cpu
(
header
.
vci
),
le16_to_cpu
(
header
.
vpi
),
le16_to_cpu
(
header
->
vci
),
le16_to_cpu
(
header
->
vpi
),
port
);
continue
;
}
...
...
@@ -839,7 +872,7 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
{
int
old_len
;
*
(
void
**
)
skb
->
cb
=
vcc
;
SKB_CB
(
skb
)
->
vcc
=
vcc
;
spin_lock
(
&
card
->
tx_queue_lock
);
old_len
=
skb_queue_len
(
&
card
->
tx_queue
[
port
]);
...
...
@@ -881,17 +914,37 @@ static int fpga_tx(struct solos_card *card)
port
);
print_buffer
(
skb
);
}
memcpy_toio
(
TX_BUF
(
card
,
port
),
skb
->
data
,
skb
->
len
);
if
(
card
->
using_dma
)
{
if
(
card
->
tx_skb
[
port
])
{
struct
sk_buff
*
oldskb
=
card
->
tx_skb
[
port
];
vcc
=
*
(
void
**
)
skb
->
cb
;
pci_unmap_single
(
card
->
dev
,
SKB_CB
(
oldskb
)
->
dma_addr
,
oldskb
->
len
,
PCI_DMA_TODEVICE
);
if
(
vcc
)
{
atomic_inc
(
&
vcc
->
stats
->
tx
);
solos_pop
(
vcc
,
skb
);
}
else
dev_kfree_skb_irq
(
skb
);
vcc
=
SKB_CB
(
oldskb
)
->
vcc
;
tx_started
|=
1
<<
port
;
//Set TX full flag
if
(
vcc
)
{
atomic_inc
(
&
vcc
->
stats
->
tx
);
solos_pop
(
vcc
,
oldskb
);
}
else
dev_kfree_skb_irq
(
oldskb
);
}
SKB_CB
(
skb
)
->
dma_addr
=
pci_map_single
(
card
->
dev
,
skb
->
data
,
skb
->
len
,
PCI_DMA_TODEVICE
);
iowrite32
(
SKB_CB
(
skb
)
->
dma_addr
,
card
->
config_regs
+
TX_DMA_ADDR
(
port
));
}
else
{
memcpy_toio
(
TX_BUF
(
card
,
port
),
skb
->
data
,
skb
->
len
);
tx_started
|=
1
<<
port
;
//Set TX full flag
vcc
=
SKB_CB
(
skb
)
->
vcc
;
if
(
vcc
)
{
atomic_inc
(
&
vcc
->
stats
->
tx
);
solos_pop
(
vcc
,
skb
);
}
else
dev_kfree_skb_irq
(
skb
);
}
}
}
if
(
tx_started
)
...
...
@@ -999,6 +1052,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto
out
;
}
err
=
pci_set_dma_mask
(
dev
,
DMA_32BIT_MASK
);
if
(
err
)
{
dev_warn
(
&
dev
->
dev
,
"Failed to set 32-bit DMA mask
\n
"
);
goto
out
;
}
err
=
pci_request_regions
(
dev
,
"solos"
);
if
(
err
)
{
dev_warn
(
&
dev
->
dev
,
"Failed to request regions
\n
"
);
...
...
@@ -1035,6 +1094,9 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
dev_info
(
&
dev
->
dev
,
"Solos FPGA Version %d.%02d svn-%d
\n
"
,
major_ver
,
minor_ver
,
fpga_ver
);
if
(
fpga_ver
>
27
)
card
->
using_dma
=
1
;
card
->
nr_ports
=
2
;
/* FIXME: Detect daughterboard */
pci_set_drvdata
(
dev
,
card
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录