Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
90937231
Commit
90937231
authored
Jan 28, 2009
by
David Woodhouse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
solos: First attempt at DMA support
Signed-off-by:
David Woodhouse
<
David.Woodhouse@intel.com
>
parent
c0fe3026
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
28 deletions
+90
-28
drivers/atm/solos-pci.c
drivers/atm/solos-pci.c
+90
-28
No files found.
drivers/atm/solos-pci.c
View file @
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment