Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
83
Issues
83
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Software
Commits
79e38916
Commit
79e38916
authored
Mar 12, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wr-nic: move rx management in soft-irq context
parent
b79fb98e
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
22 additions
and
4 deletions
+22
-4
device.c
kernel/wr_nic/device.c
+2
-1
nic-core.c
kernel/wr_nic/nic-core.c
+13
-3
wr-nic.h
kernel/wr_nic/wr-nic.h
+7
-0
No files found.
kernel/wr_nic/device.c
View file @
79e38916
...
...
@@ -120,6 +120,7 @@ static int __devinit wrn_probe(struct platform_device *pdev)
wrn
->
txd
=
((
void
*
)
wrn
->
regs
)
+
0x80
;
/* was: TX1_D1 */
wrn
->
rxd
=
((
void
*
)
wrn
->
regs
)
+
0x100
;
/* was: RX1_D1 */
wrn
->
databuf
=
(
void
*
)
wrn
->
regs
+
offsetof
(
struct
NIC_WB
,
MEM
);
tasklet_init
(
&
wrn
->
rx_tlet
,
wrn_rx_interrupt
,
(
unsigned
long
)
wrn
);
printk
(
"regs %p, txd %p, rxd %p, buffer %p
\n
"
,
wrn
->
regs
,
wrn
->
txd
,
wrn
->
rxd
,
wrn
->
databuf
);
...
...
@@ -188,7 +189,7 @@ static int __devinit wrn_probe(struct platform_device *pdev)
wrn
->
next_tx_head
=
wrn
->
next_tx_tail
=
wrn
->
next_rx
=
0
;
writel
(
NIC_CR_RX_EN
|
NIC_CR_TX_EN
,
&
wrn
->
regs
->
CR
);
writel
(
~
0
,
(
void
*
)
wrn
->
regs
+
0x24
/* EIC_IER */
);
writel
(
WRN_IRQ_ALL
,
(
void
*
)
wrn
->
regs
+
0x24
/* EIC_IER */
);
printk
(
"imr: %08x
\n
"
,
readl
((
void
*
)
wrn
->
regs
+
0x28
/* EIC_IMR */
));
wrn_tstamp_init
(
wrn
);
...
...
kernel/wr_nic/nic-core.c
View file @
79e38916
...
...
@@ -379,9 +379,11 @@ static void __wrn_rx_descriptor(struct wrn_dev *wrn, int desc)
netif_receive_skb
(
skb
);
}
static
void
wrn_rx_interrupt
(
struct
wrn_dev
*
wrn
)
/* This function is called in soft-irq context */
void
wrn_rx_interrupt
(
unsigned
long
arg
)
{
int
desc
;
struct
wrn_dev
*
wrn
=
(
void
*
)
arg
;
struct
wrn_rxd
__iomem
*
rx
;
u32
reg
;
...
...
@@ -390,12 +392,14 @@ static void wrn_rx_interrupt(struct wrn_dev *wrn)
rx
=
wrn
->
rxd
+
desc
;
reg
=
readl
(
&
rx
->
rx1
);
if
(
reg
&
NIC_RX1_D1_EMPTY
)
return
;
break
;
__wrn_rx_descriptor
(
wrn
,
desc
);
wrn
->
next_rx
=
__wrn_next_desc
(
desc
);
}
writel
(
WRN_IRQ_ALL
,
(
void
*
)
wrn
->
regs
+
0x24
/* IER */
);
}
/* This, lazily, remains in hard-irq context */
static
void
wrn_tx_interrupt
(
struct
wrn_dev
*
wrn
)
{
struct
wrn_txd
*
tx
;
...
...
@@ -454,8 +458,14 @@ irqreturn_t wrn_interrupt(int irq, void *dev_id)
}
if
(
irqs
&
NIC_EIC_ISR_RCOMP
)
{
pr_debug
(
"%s: RX complete
\n
"
,
__func__
);
wrn_rx_interrupt
(
wrn
);
/*
* This must be processed in soft-irq context, as this is
* what is needed for socket processing. So disable
* the interrupt first, then run the tasklet
*/
writel
(
WRN_IRQ_ALL_BUT_RX
,
(
void
*
)
wrn
->
regs
+
0x24
/* IER */
);
writel
(
NIC_EIC_ISR_RCOMP
,
(
void
*
)
regs
+
0x2c
);
tasklet_schedule
(
&
wrn
->
rx_tlet
);
}
return
IRQ_HANDLED
;
}
kernel/wr_nic/wr-nic.h
View file @
79e38916
...
...
@@ -73,6 +73,7 @@ struct wrn_dev {
struct
PPSG_WB
__iomem
*
ppsg_regs
;
/* ... */
spinlock_t
lock
;
struct
tasklet_struct
rx_tlet
;
struct
wrn_txd
__iomem
*
txd
;
struct
wrn_rxd
__iomem
*
rxd
;
void
__iomem
*
databuf
;
/* void to ease pointer arith */
...
...
@@ -98,6 +99,11 @@ struct wrn_dev {
int
irq_registered
;
};
/* We need to disable the rx-complete interrupt, so get the masks */
#define WRN_IRQ_ALL (~0)
#define WRN_IRQ_ALL_BUT_RX (~NIC_EIC_IER_RCOMP)
#define WRN_IRQ_NONE 0
/* Each network device (endpoint) has one such priv structure */
struct
wrn_ep
{
struct
wrn_dev
*
wrn
;
...
...
@@ -201,6 +207,7 @@ struct wrn_phase_req {
/* Following functions are in nic-core.c */
extern
irqreturn_t
wrn_interrupt
(
int
irq
,
void
*
dev_id
);
extern
int
wrn_netops_init
(
struct
net_device
*
netdev
);
extern
void
wrn_rx_interrupt
(
unsigned
long
arg
);
/* tasklet */
/* Following data in device.c */
struct
platform_driver
;
...
...
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