Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
819b3114
Commit
819b3114
authored
Jan 03, 2003
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[netdrvr e100] better debugging for command failures/timeouts
Contributed by Scott Feldman @ Intel
parent
9e9c6725
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
144 additions
and
75 deletions
+144
-75
drivers/net/e100/e100.h
drivers/net/e100/e100.h
+10
-3
drivers/net/e100/e100_main.c
drivers/net/e100/e100_main.c
+134
-72
No files found.
drivers/net/e100/e100.h
View file @
819b3114
...
@@ -268,6 +268,7 @@ struct driver_stats {
...
@@ -268,6 +268,7 @@ struct driver_stats {
#define SCB_CUC_NOOP 0
#define SCB_CUC_NOOP 0
#define SCB_CUC_START BIT_4
/* CU Start */
#define SCB_CUC_START BIT_4
/* CU Start */
#define SCB_CUC_RESUME BIT_5
/* CU Resume */
#define SCB_CUC_RESUME BIT_5
/* CU Resume */
#define SCB_CUC_UNKNOWN BIT_7
/* CU unknown command */
/* Changed for 82558 enhancements */
/* Changed for 82558 enhancements */
#define SCB_CUC_STATIC_RESUME (BIT_5 | BIT_7)
/* 82558/9 Static Resume */
#define SCB_CUC_STATIC_RESUME (BIT_5 | BIT_7)
/* 82558/9 Static Resume */
#define SCB_CUC_DUMP_ADDR BIT_6
/* CU Dump Counters Address */
#define SCB_CUC_DUMP_ADDR BIT_6
/* CU Dump Counters Address */
...
@@ -953,6 +954,10 @@ struct e100_private {
...
@@ -953,6 +954,10 @@ struct e100_private {
u32
pci_state
[
16
];
u32
pci_state
[
16
];
#endif
#endif
char
ifname
[
IFNAMSIZ
];
char
ifname
[
IFNAMSIZ
];
#ifdef E100_CU_DEBUG
u8
last_cmd
;
u8
last_sub_cmd
;
#endif
};
};
#define E100_AUTONEG 0
#define E100_AUTONEG 0
...
@@ -964,7 +969,7 @@ struct e100_private {
...
@@ -964,7 +969,7 @@ struct e100_private {
/********* function prototypes *************/
/********* function prototypes *************/
extern
void
e100_isolate_driver
(
struct
e100_private
*
bdp
);
extern
void
e100_isolate_driver
(
struct
e100_private
*
bdp
);
extern
void
e100_sw_reset
(
struct
e100_private
*
bdp
,
u32
reset_cmd
);
extern
void
e100_sw_reset
(
struct
e100_private
*
bdp
,
u32
reset_cmd
);
extern
void
e100_start_cu
(
struct
e100_private
*
bdp
,
tcb_t
*
tcb
);
extern
u8
e100_start_cu
(
struct
e100_private
*
bdp
,
tcb_t
*
tcb
);
extern
void
e100_free_non_tx_cmd
(
struct
e100_private
*
bdp
,
extern
void
e100_free_non_tx_cmd
(
struct
e100_private
*
bdp
,
nxmit_cb_entry_t
*
non_tx_cmd
);
nxmit_cb_entry_t
*
non_tx_cmd
);
extern
nxmit_cb_entry_t
*
e100_alloc_non_tx_cmd
(
struct
e100_private
*
bdp
);
extern
nxmit_cb_entry_t
*
e100_alloc_non_tx_cmd
(
struct
e100_private
*
bdp
);
...
@@ -976,8 +981,10 @@ extern unsigned char e100_get_link_state(struct e100_private *bdp);
...
@@ -976,8 +981,10 @@ extern unsigned char e100_get_link_state(struct e100_private *bdp);
extern
unsigned
char
e100_wait_scb
(
struct
e100_private
*
bdp
);
extern
unsigned
char
e100_wait_scb
(
struct
e100_private
*
bdp
);
extern
void
e100_deisolate_driver
(
struct
e100_private
*
bdp
,
u8
full_reset
);
extern
void
e100_deisolate_driver
(
struct
e100_private
*
bdp
,
u8
full_reset
);
extern
unsigned
char
e100_hw_reset_recover
(
struct
e100_private
*
bdp
,
extern
unsigned
char
e100_configure_device
(
struct
e100_private
*
bdp
);
u32
reset_cmd
);
#ifdef E100_CU_DEBUG
extern
unsigned
char
e100_cu_unknown_state
(
struct
e100_private
*
bdp
);
#endif
#define ROM_TEST_FAIL 0x01
#define ROM_TEST_FAIL 0x01
#define REGISTER_TEST_FAIL 0x02
#define REGISTER_TEST_FAIL 0x02
...
...
drivers/net/e100/e100_main.c
View file @
819b3114
...
@@ -224,7 +224,7 @@ static void e100_check_options(int board, struct e100_private *bdp);
...
@@ -224,7 +224,7 @@ static void e100_check_options(int board, struct e100_private *bdp);
static
void
e100_set_int_option
(
int
*
,
int
,
int
,
int
,
int
,
char
*
);
static
void
e100_set_int_option
(
int
*
,
int
,
int
,
int
,
int
,
char
*
);
static
void
e100_set_bool_option
(
struct
e100_private
*
bdp
,
int
,
u32
,
int
,
static
void
e100_set_bool_option
(
struct
e100_private
*
bdp
,
int
,
u32
,
int
,
char
*
);
char
*
);
unsigned
char
e100_wait_exec_cmplx
(
struct
e100_private
*
,
u32
,
u8
);
unsigned
char
e100_wait_exec_cmplx
(
struct
e100_private
*
,
u32
,
u8
,
u8
);
void
e100_exec_cmplx
(
struct
e100_private
*
,
u32
,
u8
);
void
e100_exec_cmplx
(
struct
e100_private
*
,
u32
,
u8
);
/**
/**
...
@@ -443,9 +443,21 @@ e100_wait_exec_simple(struct e100_private *bdp, u8 scb_cmd_low)
...
@@ -443,9 +443,21 @@ e100_wait_exec_simple(struct e100_private *bdp, u8 scb_cmd_low)
if
(
!
e100_wait_scb
(
bdp
))
{
if
(
!
e100_wait_scb
(
bdp
))
{
printk
(
KERN_DEBUG
"e100: %s: e100_wait_exec_simple: failed
\n
"
,
printk
(
KERN_DEBUG
"e100: %s: e100_wait_exec_simple: failed
\n
"
,
bdp
->
device
->
name
);
bdp
->
device
->
name
);
#ifdef E100_CU_DEBUG
printk
(
KERN_ERR
"e100: %s: Last command (%x/%x) "
"timeout
\n
"
,
bdp
->
device
->
name
,
bdp
->
last_cmd
,
bdp
->
last_sub_cmd
);
printk
(
KERN_ERR
"e100: %s: Current simple command (%x) "
"can't be executed
\n
"
,
bdp
->
device
->
name
,
scb_cmd_low
);
#endif
return
false
;
return
false
;
}
}
e100_exec_cmd
(
bdp
,
scb_cmd_low
);
e100_exec_cmd
(
bdp
,
scb_cmd_low
);
#ifdef E100_CU_DEBUG
bdp
->
last_cmd
=
scb_cmd_low
;
bdp
->
last_sub_cmd
=
0
;
#endif
return
true
;
return
true
;
}
}
...
@@ -458,12 +470,24 @@ e100_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd)
...
@@ -458,12 +470,24 @@ e100_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd)
}
}
unsigned
char
unsigned
char
e100_wait_exec_cmplx
(
struct
e100_private
*
bdp
,
u32
phys_addr
,
u8
cmd
)
e100_wait_exec_cmplx
(
struct
e100_private
*
bdp
,
u32
phys_addr
,
u8
cmd
,
u8
sub_cmd
)
{
{
if
(
!
e100_wait_scb
(
bdp
))
{
if
(
!
e100_wait_scb
(
bdp
))
{
#ifdef E100_CU_DEBUG
printk
(
KERN_ERR
"e100: %s: Last command (%x/%x) "
"timeout
\n
"
,
bdp
->
device
->
name
,
bdp
->
last_cmd
,
bdp
->
last_sub_cmd
);
printk
(
KERN_ERR
"e100: %s: Current complex command "
"(%x/%x) can't be executed
\n
"
,
bdp
->
device
->
name
,
cmd
,
sub_cmd
);
#endif
return
false
;
return
false
;
}
}
e100_exec_cmplx
(
bdp
,
phys_addr
,
cmd
);
e100_exec_cmplx
(
bdp
,
phys_addr
,
cmd
);
#ifdef E100_CU_DEBUG
bdp
->
last_cmd
=
cmd
;
bdp
->
last_sub_cmd
=
sub_cmd
;
#endif
return
true
;
return
true
;
}
}
...
@@ -494,18 +518,23 @@ e100_wait_cus_idle(struct e100_private *bdp)
...
@@ -494,18 +518,23 @@ e100_wait_cus_idle(struct e100_private *bdp)
}
}
/**
/**
* e100_dis
_intr - disable
interrupts
* e100_dis
able_clear_intr - disable and clear/ack
interrupts
* @bdp: atapter's private data struct
* @bdp: atapter's private data struct
*
*
* This routine disables interrupts at the hardware, by setting
* This routine disables interrupts at the hardware, by setting
* the M (mask) bit in the adapter's CSR SCB command word.
* the M (mask) bit in the adapter's CSR SCB command word.
* It also clear/ack interrupts.
*/
*/
static
inline
void
static
inline
void
e100_dis_intr
(
struct
e100_private
*
bdp
)
e100_dis
able_clear
_intr
(
struct
e100_private
*
bdp
)
{
{
u16
intr_status
;
/* Disable interrupts on our PCI board by setting the mask bit */
/* Disable interrupts on our PCI board by setting the mask bit */
writeb
(
SCB_INT_MASK
,
&
bdp
->
scb
->
scb_cmd_hi
);
writeb
(
SCB_INT_MASK
,
&
bdp
->
scb
->
scb_cmd_hi
);
readw
(
&
(
bdp
->
scb
->
scb_status
));
/* flushes last write, read-safe */
intr_status
=
readw
(
&
bdp
->
scb
->
scb_status
);
/* ack and clear intrs */
writew
(
intr_status
,
&
bdp
->
scb
->
scb_status
);
readw
(
&
bdp
->
scb
->
scb_status
);
}
}
/**
/**
...
@@ -958,12 +987,12 @@ e100_open(struct net_device *dev)
...
@@ -958,12 +987,12 @@ e100_open(struct net_device *dev)
goto
err_exit
;
goto
err_exit
;
}
}
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
))
{
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
,
0
))
{
rc
=
-
EAGAIN
;
rc
=
-
EAGAIN
;
goto
err_exit
;
goto
err_exit
;
}
}
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
))
{
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
,
0
))
{
rc
=
-
EAGAIN
;
rc
=
-
EAGAIN
;
goto
err_exit
;
goto
err_exit
;
}
}
...
@@ -1240,7 +1269,8 @@ e100_init(struct e100_private *bdp)
...
@@ -1240,7 +1269,8 @@ e100_init(struct e100_private *bdp)
printk
(
KERN_ERR
"e100: hw init failed
\n
"
);
printk
(
KERN_ERR
"e100: hw init failed
\n
"
);
return
false
;
return
false
;
}
}
e100_dis_intr
(
bdp
);
/* Interrupts are enabled after device reset */
e100_disable_clear_intr
(
bdp
);
return
true
;
return
true
;
}
}
...
@@ -1308,10 +1338,10 @@ e100_hw_init(struct e100_private *bdp, u32 reset_cmd)
...
@@ -1308,10 +1338,10 @@ e100_hw_init(struct e100_private *bdp, u32 reset_cmd)
e100_sw_reset
(
bdp
,
reset_cmd
);
e100_sw_reset
(
bdp
,
reset_cmd
);
/* Load the CU BASE (set to 0, because we use linear mode) */
/* Load the CU BASE (set to 0, because we use linear mode) */
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
))
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
,
0
))
return
false
;
return
false
;
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
))
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
,
0
))
return
false
;
return
false
;
/* Load interrupt microcode */
/* Load interrupt microcode */
...
@@ -1595,6 +1625,12 @@ e100_watchdog(struct net_device *dev)
...
@@ -1595,6 +1625,12 @@ e100_watchdog(struct net_device *dev)
{
{
struct
e100_private
*
bdp
=
dev
->
priv
;
struct
e100_private
*
bdp
=
dev
->
priv
;
#ifdef E100_CU_DEBUG
if
(
e100_cu_unknown_state
(
bdp
))
{
printk
(
KERN_ERR
"e100: %s: CU unknown state in e100_watchdog
\n
"
,
dev
->
name
);
}
#endif
if
(
!
netif_running
(
dev
))
{
if
(
!
netif_running
(
dev
))
{
return
;
return
;
}
}
...
@@ -1651,7 +1687,8 @@ e100_watchdog(struct net_device *dev)
...
@@ -1651,7 +1687,8 @@ e100_watchdog(struct net_device *dev)
if
(
netif_running
(
dev
))
if
(
netif_running
(
dev
))
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
else
{
}
else
{
netif_stop_queue
(
dev
);
if
(
netif_running
(
dev
))
netif_stop_queue
(
dev
);
}
}
rmb
();
rmb
();
...
@@ -1779,11 +1816,8 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
...
@@ -1779,11 +1816,8 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
return
;
return
;
}
}
/* disable intr before we ack & after identifying the intr as ours */
/* disable and ack intr */
e100_dis_intr
(
bdp
);
e100_disable_clear_intr
(
bdp
);
writew
(
intr_status
,
&
bdp
->
scb
->
scb_status
);
/* ack intrs */
readw
(
&
bdp
->
scb
->
scb_status
);
/* the device is closed, don't continue or else bad things may happen. */
/* the device is closed, don't continue or else bad things may happen. */
if
(
!
netif_running
(
dev
))
{
if
(
!
netif_running
(
dev
))
{
...
@@ -2213,10 +2247,11 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
...
@@ -2213,10 +2247,11 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
*
*
* e100_start_cu must be called while holding the tx_lock !
* e100_start_cu must be called while holding the tx_lock !
*/
*/
void
u8
e100_start_cu
(
struct
e100_private
*
bdp
,
tcb_t
*
tcb
)
e100_start_cu
(
struct
e100_private
*
bdp
,
tcb_t
*
tcb
)
{
{
unsigned
long
lock_flag
;
unsigned
long
lock_flag
;
u8
ret
=
true
;
spin_lock_irqsave
(
&
(
bdp
->
bd_lock
),
lock_flag
);
spin_lock_irqsave
(
&
(
bdp
->
bd_lock
),
lock_flag
);
switch
(
bdp
->
next_cu_cmd
)
{
switch
(
bdp
->
next_cu_cmd
)
{
...
@@ -2247,12 +2282,13 @@ e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
...
@@ -2247,12 +2282,13 @@ e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
"e100: %s: cu_start: timeout waiting for cu
\n
"
,
"e100: %s: cu_start: timeout waiting for cu
\n
"
,
bdp
->
device
->
name
);
bdp
->
device
->
name
);
if
(
!
e100_wait_exec_cmplx
(
bdp
,
(
u32
)
(
tcb
->
tcb_phys
),
if
(
!
e100_wait_exec_cmplx
(
bdp
,
(
u32
)
(
tcb
->
tcb_phys
),
SCB_CUC_START
))
{
SCB_CUC_START
,
CB_TRANSMIT
))
{
printk
(
KERN_DEBUG
printk
(
KERN_DEBUG
"e100: %s: cu_start: timeout waiting for scb
\n
"
,
"e100: %s: cu_start: timeout waiting for scb
\n
"
,
bdp
->
device
->
name
);
bdp
->
device
->
name
);
e100_exec_cmplx
(
bdp
,
(
u32
)
(
tcb
->
tcb_phys
),
e100_exec_cmplx
(
bdp
,
(
u32
)
(
tcb
->
tcb_phys
),
SCB_CUC_START
);
SCB_CUC_START
);
ret
=
false
;
}
}
bdp
->
next_cu_cmd
=
RESUME_WAIT
;
bdp
->
next_cu_cmd
=
RESUME_WAIT
;
...
@@ -2264,6 +2300,7 @@ e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
...
@@ -2264,6 +2300,7 @@ e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
bdp
->
last_tcb
=
tcb
;
bdp
->
last_tcb
=
tcb
;
spin_unlock_irqrestore
(
&
(
bdp
->
bd_lock
),
lock_flag
);
spin_unlock_irqrestore
(
&
(
bdp
->
bd_lock
),
lock_flag
);
return
ret
;
}
}
/* ====================================================================== */
/* ====================================================================== */
...
@@ -2311,8 +2348,9 @@ e100_selftest(struct e100_private *bdp, u32 *st_timeout, u32 *st_result)
...
@@ -2311,8 +2348,9 @@ e100_selftest(struct e100_private *bdp, u32 *st_timeout, u32 *st_result)
set_current_state
(
TASK_UNINTERRUPTIBLE
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
100
+
1
);
schedule_timeout
(
HZ
/
100
+
1
);
/* disable interrupts since the're now enabled */
/* disable interrupts since they are enabled */
e100_dis_intr
(
bdp
);
/* after device reset during selftest */
e100_disable_clear_intr
(
bdp
);
/* if The First Self Test DWORD Still Zero, We've timed out. If the
/* if The First Self Test DWORD Still Zero, We've timed out. If the
* second DWORD is not zero then we have an error. */
* second DWORD is not zero then we have an error. */
...
@@ -2410,7 +2448,7 @@ e100_start_ru(struct e100_private *bdp)
...
@@ -2410,7 +2448,7 @@ e100_start_ru(struct e100_private *bdp)
spin_lock
(
&
bdp
->
bd_lock
);
spin_lock
(
&
bdp
->
bd_lock
);
if
(
!
e100_wait_exec_cmplx
(
bdp
,
rx_struct
->
dma_addr
,
SCB_RUC_START
))
{
if
(
!
e100_wait_exec_cmplx
(
bdp
,
rx_struct
->
dma_addr
,
SCB_RUC_START
,
0
))
{
printk
(
KERN_DEBUG
printk
(
KERN_DEBUG
"e100: %s: start_ru: wait_scb failed
\n
"
,
"e100: %s: start_ru: wait_scb failed
\n
"
,
bdp
->
device
->
name
);
bdp
->
device
->
name
);
...
@@ -2478,7 +2516,7 @@ e100_clr_cntrs(struct e100_private *bdp)
...
@@ -2478,7 +2516,7 @@ e100_clr_cntrs(struct e100_private *bdp)
*
pcmd_complete
=
0
;
*
pcmd_complete
=
0
;
wmb
();
wmb
();
if
(
!
e100_wait_exec_cmplx
(
bdp
,
bdp
->
stat_cnt_phys
,
SCB_CUC_DUMP_ADDR
))
if
(
!
e100_wait_exec_cmplx
(
bdp
,
bdp
->
stat_cnt_phys
,
SCB_CUC_DUMP_ADDR
,
0
))
return
false
;
return
false
;
/* wait 10 microseconds for the command to complete */
/* wait 10 microseconds for the command to complete */
...
@@ -2600,8 +2638,10 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
...
@@ -2600,8 +2638,10 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
unsigned
long
lock_flag
;
unsigned
long
lock_flag
;
unsigned
long
expiration_time
;
unsigned
long
expiration_time
;
unsigned
char
rc
=
true
;
unsigned
char
rc
=
true
;
u8
sub_cmd
;
ntcb_hdr
=
(
cb_header_t
*
)
command
->
non_tx_cmd
;
/* get hdr of non tcb cmd */
ntcb_hdr
=
(
cb_header_t
*
)
command
->
non_tx_cmd
;
/* get hdr of non tcb cmd */
sub_cmd
=
cpu_to_le16
(
ntcb_hdr
->
cb_cmd
);
/* Set the Command Block to be the last command block */
/* Set the Command Block to be the last command block */
ntcb_hdr
->
cb_cmd
|=
__constant_cpu_to_le16
(
CB_EL_BIT
);
ntcb_hdr
->
cb_cmd
|=
__constant_cpu_to_le16
(
CB_EL_BIT
);
...
@@ -2634,7 +2674,7 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
...
@@ -2634,7 +2674,7 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
spin_lock_irqsave
(
&
bdp
->
bd_lock
,
lock_flag
);
spin_lock_irqsave
(
&
bdp
->
bd_lock
,
lock_flag
);
if
(
!
e100_wait_exec_cmplx
(
bdp
,
command
->
dma_addr
,
SCB_CUC_START
))
{
if
(
!
e100_wait_exec_cmplx
(
bdp
,
command
->
dma_addr
,
SCB_CUC_START
,
sub_cmd
))
{
spin_unlock_irqrestore
(
&
(
bdp
->
bd_lock
),
lock_flag
);
spin_unlock_irqrestore
(
&
(
bdp
->
bd_lock
),
lock_flag
);
rc
=
false
;
rc
=
false
;
goto
exit
;
goto
exit
;
...
@@ -2654,6 +2694,10 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
...
@@ -2654,6 +2694,10 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
yield
();
yield
();
spin_lock_bh
(
&
(
bdp
->
bd_non_tx_lock
));
spin_lock_bh
(
&
(
bdp
->
bd_non_tx_lock
));
}
else
{
}
else
{
#ifdef E100_CU_DEBUG
printk
(
KERN_ERR
"e100: %s: non-TX command (%x) "
"timeout
\n
"
,
bdp
->
device
->
name
,
sub_cmd
);
#endif
rc
=
false
;
rc
=
false
;
goto
exit
;
goto
exit
;
}
}
...
@@ -2699,7 +2743,12 @@ e100_sw_reset(struct e100_private *bdp, u32 reset_cmd)
...
@@ -2699,7 +2743,12 @@ e100_sw_reset(struct e100_private *bdp, u32 reset_cmd)
}
}
/* Mask off our interrupt line -- its unmasked after reset */
/* Mask off our interrupt line -- its unmasked after reset */
e100_dis_intr
(
bdp
);
e100_disable_clear_intr
(
bdp
);
#ifdef E100_CU_DEBUG
bdp
->
last_cmd
=
0
;
bdp
->
last_sub_cmd
=
0
;
#endif
}
}
/**
/**
...
@@ -3055,63 +3104,51 @@ e100_tcb_add_C_bit(struct e100_private *bdp)
...
@@ -3055,63 +3104,51 @@ e100_tcb_add_C_bit(struct e100_private *bdp)
}
}
/*
/*
* Procedure: e100_
hw_reset_recover
* Procedure: e100_
configure_device
*
*
* Description: This routine will
recover the hw after reset.
* Description: This routine will
configure device
*
*
* Arguments:
* Arguments:
* bdp - Ptr to this card's e100_bdconfig structure
* bdp - Ptr to this card's e100_bdconfig structure
* reset_cmd - s/w reset or selective reset.
*
*
* Returns:
* Returns:
* true upon success
* true upon success
* false upon failure
* false upon failure
*/
*/
unsigned
char
unsigned
char
e100_
hw_reset_recover
(
struct
e100_private
*
bdp
,
u32
reset_cmd
)
e100_
configure_device
(
struct
e100_private
*
bdp
)
{
{
bdp
->
last_tcb
=
NULL
;
/*load CU & RU base */
if
(
reset_cmd
==
PORT_SOFTWARE_RESET
)
{
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
,
0
))
return
false
;
/*load CU & RU base */
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
))
{
return
false
;
}
if
(
e100_load_microcode
(
bdp
))
{
if
(
e100_load_microcode
(
bdp
))
bdp
->
flags
|=
DF_UCODE_LOADED
;
bdp
->
flags
|=
DF_UCODE_LOADED
;
}
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
))
{
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
,
0
))
return
false
;
return
false
;
}
/* Issue the load dump counters address command */
/* Issue the load dump counters address command */
if
(
!
e100_wait_exec_cmplx
(
bdp
,
bdp
->
stat_cnt_phys
,
if
(
!
e100_wait_exec_cmplx
(
bdp
,
bdp
->
stat_cnt_phys
,
SCB_CUC_DUMP_ADDR
,
0
))
SCB_CUC_DUMP_ADDR
))
{
return
false
;
return
false
;
}
if
(
!
e100_setup_iaaddr
(
bdp
,
bdp
->
device
->
dev_addr
))
{
if
(
!
e100_setup_iaaddr
(
bdp
,
bdp
->
device
->
dev_addr
))
{
printk
(
KERN_ERR
printk
(
KERN_ERR
"e100: e100_configure_device: "
"e100: e100_hw_reset_recover: "
"setup iaaddr failed
\n
"
);
"setup iaaddr failed
\n
"
);
return
false
;
return
false
;
}
}
e100_set_multi_exec
(
bdp
->
device
);
e100_set_multi_exec
(
bdp
->
device
);
/* Change for 82558 enhancement */
/* If 82558/9 and if the user has enabled flow control, set up * the
* Flow Control Reg. in the CSR */
if
((
bdp
->
flags
&
IS_BACHELOR
)
&&
(
bdp
->
params
.
b_params
&
PRM_FC
))
{
writeb
(
DFLT_FC_THLD
,
&
bdp
->
scb
->
scb_ext
.
d101_scb
.
scb_fc_thld
);
writeb
(
DFLT_FC_CMD
,
&
bdp
->
scb
->
scb_ext
.
d101_scb
.
scb_fc_xon_xoff
);
}
/* Change for 82558 enhancement */
/* If 82558/9 and if the user has enabled flow control, set up */
/* flow Control Reg. in the CSR */
if
((
bdp
->
flags
&
IS_BACHELOR
)
&&
(
bdp
->
params
.
b_params
&
PRM_FC
))
{
writeb
(
DFLT_FC_THLD
,
&
bdp
->
scb
->
scb_ext
.
d101_scb
.
scb_fc_thld
);
writeb
(
DFLT_FC_CMD
,
&
bdp
->
scb
->
scb_ext
.
d101_scb
.
scb_fc_xon_xoff
);
}
}
e100_force_config
(
bdp
);
e100_force_config
(
bdp
);
...
@@ -3125,7 +3162,7 @@ e100_deisolate_driver(struct e100_private *bdp, u8 full_reset)
...
@@ -3125,7 +3162,7 @@ e100_deisolate_driver(struct e100_private *bdp, u8 full_reset)
u32
cmd
=
full_reset
?
PORT_SOFTWARE_RESET
:
PORT_SELECTIVE_RESET
;
u32
cmd
=
full_reset
?
PORT_SOFTWARE_RESET
:
PORT_SELECTIVE_RESET
;
e100_sw_reset
(
bdp
,
cmd
);
e100_sw_reset
(
bdp
,
cmd
);
if
(
cmd
==
PORT_SOFTWARE_RESET
)
{
if
(
cmd
==
PORT_SOFTWARE_RESET
)
{
if
(
!
e100_
hw_reset_recover
(
bdp
,
cmd
))
if
(
!
e100_
configure_device
(
bdp
))
printk
(
KERN_ERR
"e100: e100_deisolate_driver:"
printk
(
KERN_ERR
"e100: e100_deisolate_driver:"
" device configuration failed
\n
"
);
" device configuration failed
\n
"
);
}
}
...
@@ -3948,6 +3985,8 @@ e100_non_tx_background(unsigned long ptr)
...
@@ -3948,6 +3985,8 @@ e100_non_tx_background(unsigned long ptr)
struct
e100_private
*
bdp
=
(
struct
e100_private
*
)
ptr
;
struct
e100_private
*
bdp
=
(
struct
e100_private
*
)
ptr
;
nxmit_cb_entry_t
*
active_command
;
nxmit_cb_entry_t
*
active_command
;
int
restart
=
true
;
int
restart
=
true
;
cb_header_t
*
non_tx_cmd
;
u8
sub_cmd
;
spin_lock_bh
(
&
(
bdp
->
bd_non_tx_lock
));
spin_lock_bh
(
&
(
bdp
->
bd_non_tx_lock
));
...
@@ -3975,6 +4014,15 @@ e100_non_tx_background(unsigned long ptr)
...
@@ -3975,6 +4014,15 @@ e100_non_tx_background(unsigned long ptr)
&&
time_before
(
jiffies
,
active_command
->
expiration_time
))
{
&&
time_before
(
jiffies
,
active_command
->
expiration_time
))
{
goto
exit
;
goto
exit
;
}
else
{
}
else
{
non_tx_cmd
=
(
cb_header_t
*
)
active_command
->
non_tx_cmd
;
sub_cmd
=
CB_CMD_MASK
&
le16_to_cpu
(
non_tx_cmd
->
cb_cmd
);
#ifdef E100_CU_DEBUG
if
(
!
(
non_tx_cmd
->
cb_status
&
__constant_cpu_to_le16
(
CB_STATUS_COMPLETE
)))
printk
(
KERN_ERR
"e100: %s: Queued "
"command (%x) timeout
\n
"
,
bdp
->
device
->
name
,
sub_cmd
);
#endif
list_del
(
&
(
active_command
->
list_elem
));
list_del
(
&
(
active_command
->
list_elem
));
e100_free_non_tx_cmd
(
bdp
,
active_command
);
e100_free_non_tx_cmd
(
bdp
,
active_command
);
}
}
...
@@ -3997,9 +4045,10 @@ e100_non_tx_background(unsigned long ptr)
...
@@ -3997,9 +4045,10 @@ e100_non_tx_background(unsigned long ptr)
bdp
->
non_tx_command_state
=
E100_WAIT_NON_TX_FINISH
;
bdp
->
non_tx_command_state
=
E100_WAIT_NON_TX_FINISH
;
active_command
=
list_entry
(
bdp
->
non_tx_cmd_list
.
next
,
active_command
=
list_entry
(
bdp
->
non_tx_cmd_list
.
next
,
nxmit_cb_entry_t
,
list_elem
);
nxmit_cb_entry_t
,
list_elem
);
sub_cmd
=
((
cb_header_t
*
)
active_command
->
non_tx_cmd
)
->
cb_cmd
;
spin_lock_irq
(
&
(
bdp
->
bd_lock
));
spin_lock_irq
(
&
(
bdp
->
bd_lock
));
e100_wait_exec_cmplx
(
bdp
,
active_command
->
dma_addr
,
e100_wait_exec_cmplx
(
bdp
,
active_command
->
dma_addr
,
SCB_CUC_START
);
SCB_CUC_START
,
sub_cmd
);
spin_unlock_irq
(
&
(
bdp
->
bd_lock
));
spin_unlock_irq
(
&
(
bdp
->
bd_lock
));
active_command
->
expiration_time
=
jiffies
+
HZ
;
active_command
->
expiration_time
=
jiffies
+
HZ
;
cmd_type
=
CB_CMD_MASK
&
cmd_type
=
CB_CMD_MASK
&
...
@@ -4092,17 +4141,13 @@ e100_resume(struct pci_dev *pcid)
...
@@ -4092,17 +4141,13 @@ e100_resume(struct pci_dev *pcid)
{
{
struct
net_device
*
netdev
=
pci_get_drvdata
(
pcid
);
struct
net_device
*
netdev
=
pci_get_drvdata
(
pcid
);
struct
e100_private
*
bdp
=
netdev
->
priv
;
struct
e100_private
*
bdp
=
netdev
->
priv
;
u8
full_reset
=
false
;
pci_set_power_state
(
pcid
,
0
);
pci_set_power_state
(
pcid
,
0
);
pci_enable_wake
(
pcid
,
0
,
0
);
/* Clear PME status and disable PME */
pci_enable_wake
(
pcid
,
0
,
0
);
/* Clear PME status and disable PME */
pci_restore_state
(
pcid
,
bdp
->
pci_state
);
pci_restore_state
(
pcid
,
bdp
->
pci_state
);
if
(
bdp
->
wolopts
&
(
WAKE_UCAST
|
WAKE_ARP
))
{
/* Also do device full reset because device was in D3 state */
full_reset
=
true
;
e100_deisolate_driver
(
bdp
,
true
);
}
e100_deisolate_driver
(
bdp
,
full_reset
);
return
0
;
return
0
;
}
}
...
@@ -4229,3 +4274,20 @@ static void e100_hwi_restore(struct e100_private *bdp)
...
@@ -4229,3 +4274,20 @@ static void e100_hwi_restore(struct e100_private *bdp)
e100_mdi_write
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
control
);
e100_mdi_write
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
control
);
return
;
return
;
}
}
#ifdef E100_CU_DEBUG
unsigned
char
e100_cu_unknown_state
(
struct
e100_private
*
bdp
)
{
u8
scb_cmd_low
;
u16
scb_status
;
scb_cmd_low
=
bdp
->
scb
->
scb_cmd_low
;
scb_status
=
le16_to_cpu
(
bdp
->
scb
->
scb_status
);
/* If CU is active and executing unknown cmd */
if
(
scb_status
&
SCB_CUS_ACTIVE
&&
scb_cmd_low
&
SCB_CUC_UNKNOWN
)
return
true
;
else
return
false
;
}
#endif
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