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
a19d03a3
Commit
a19d03a3
authored
Mar 20, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge 2.4.x Sun GEM/HME net driver fixes.
parent
71c54597
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
306 additions
and
75 deletions
+306
-75
drivers/net/sungem.c
drivers/net/sungem.c
+287
-73
drivers/net/sungem.h
drivers/net/sungem.h
+5
-0
drivers/net/sunhme.c
drivers/net/sunhme.c
+14
-2
No files found.
drivers/net/sungem.c
View file @
a19d03a3
...
@@ -16,6 +16,8 @@
...
@@ -16,6 +16,8 @@
* I can at least detect gigabit with autoneg.
* I can at least detect gigabit with autoneg.
*/
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
...
@@ -35,9 +37,10 @@
...
@@ -35,9 +37,10 @@
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
#include <linux/random.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/bitops.h>
...
@@ -293,19 +296,119 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
...
@@ -293,19 +296,119 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
return
0
;
return
0
;
}
}
/* When we get a RX fifo overflow, the RX unit in GEM is probably hung
* so we do the following.
*
* If any part of the reset goes wrong, we return 1 and that causes the
* whole chip to be reset.
*/
static
int
gem_rxmac_reset
(
struct
gem
*
gp
)
{
struct
net_device
*
dev
=
gp
->
dev
;
int
limit
,
i
;
u64
desc_dma
;
u32
val
;
/* First, reset MAC RX. */
writel
(
gp
->
mac_rx_cfg
&
~
MAC_RXCFG_ENAB
,
gp
->
regs
+
MAC_RXCFG
);
for
(
limit
=
0
;
limit
<
5000
;
limit
++
)
{
if
(
!
(
readl
(
gp
->
regs
+
MAC_RXCFG
)
&
MAC_RXCFG_ENAB
))
break
;
udelay
(
10
);
}
if
(
limit
==
5000
)
{
printk
(
KERN_ERR
"%s: RX MAC will not disable, resetting whole "
"chip.
\n
"
,
dev
->
name
);
return
1
;
}
/* Second, disable RX DMA. */
writel
(
0
,
gp
->
regs
+
RXDMA_CFG
);
for
(
limit
=
0
;
limit
<
5000
;
limit
++
)
{
if
(
!
(
readl
(
gp
->
regs
+
RXDMA_CFG
)
&
RXDMA_CFG_ENABLE
))
break
;
udelay
(
10
);
}
if
(
limit
==
5000
)
{
printk
(
KERN_ERR
"%s: RX DMA will not disable, resetting whole "
"chip.
\n
"
,
dev
->
name
);
return
1
;
}
udelay
(
5000
);
/* Execute RX reset command. */
writel
(
gp
->
swrst_base
|
GREG_SWRST_RXRST
,
gp
->
regs
+
GREG_SWRST
);
for
(
limit
=
0
;
limit
<
5000
;
limit
++
)
{
if
(
!
(
readl
(
gp
->
regs
+
GREG_SWRST
)
&
GREG_SWRST_RXRST
))
break
;
udelay
(
10
);
}
if
(
limit
==
5000
)
{
printk
(
KERN_ERR
"%s: RX reset command will not execute, resetting "
"whole chip.
\n
"
,
dev
->
name
);
return
1
;
}
/* Refresh the RX ring. */
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
struct
gem_rxd
*
rxd
=
&
gp
->
init_block
->
rxd
[
i
];
if
(
gp
->
rx_skbs
[
i
]
==
NULL
)
{
printk
(
KERN_ERR
"%s: Parts of RX ring empty, resetting "
"whole chip.
\n
"
,
dev
->
name
);
return
1
;
}
rxd
->
status_word
=
cpu_to_le64
(
RXDCTRL_FRESH
(
gp
));
}
gp
->
rx_new
=
gp
->
rx_old
=
0
;
/* Now we must reprogram the rest of RX unit. */
desc_dma
=
(
u64
)
gp
->
gblock_dvma
;
desc_dma
+=
(
INIT_BLOCK_TX_RING_SIZE
*
sizeof
(
struct
gem_txd
));
writel
(
desc_dma
>>
32
,
gp
->
regs
+
RXDMA_DBHI
);
writel
(
desc_dma
&
0xffffffff
,
gp
->
regs
+
RXDMA_DBLOW
);
writel
(
RX_RING_SIZE
-
4
,
gp
->
regs
+
RXDMA_KICK
);
val
=
(
RXDMA_CFG_BASE
|
(
RX_OFFSET
<<
10
)
|
((
14
/
2
)
<<
13
)
|
RXDMA_CFG_FTHRESH_128
);
writel
(
val
,
gp
->
regs
+
RXDMA_CFG
);
if
(
readl
(
gp
->
regs
+
GREG_BIFCFG
)
&
GREG_BIFCFG_M66EN
)
writel
(((
5
&
RXDMA_BLANK_IPKTS
)
|
((
8
<<
12
)
&
RXDMA_BLANK_ITIME
)),
gp
->
regs
+
RXDMA_BLANK
);
else
writel
(((
5
&
RXDMA_BLANK_IPKTS
)
|
((
4
<<
12
)
&
RXDMA_BLANK_ITIME
)),
gp
->
regs
+
RXDMA_BLANK
);
val
=
(((
gp
->
rx_pause_off
/
64
)
<<
0
)
&
RXDMA_PTHRESH_OFF
);
val
|=
(((
gp
->
rx_pause_on
/
64
)
<<
12
)
&
RXDMA_PTHRESH_ON
);
writel
(
val
,
gp
->
regs
+
RXDMA_PTHRESH
);
val
=
readl
(
gp
->
regs
+
RXDMA_CFG
);
writel
(
val
|
RXDMA_CFG_ENABLE
,
gp
->
regs
+
RXDMA_CFG
);
writel
(
MAC_RXSTAT_RCV
,
gp
->
regs
+
MAC_RXMASK
);
val
=
readl
(
gp
->
regs
+
MAC_RXCFG
);
writel
(
val
|
MAC_RXCFG_ENAB
,
gp
->
regs
+
MAC_RXCFG
);
return
0
;
}
static
int
gem_rxmac_interrupt
(
struct
net_device
*
dev
,
struct
gem
*
gp
,
u32
gem_status
)
static
int
gem_rxmac_interrupt
(
struct
net_device
*
dev
,
struct
gem
*
gp
,
u32
gem_status
)
{
{
u32
rxmac_stat
=
readl
(
gp
->
regs
+
MAC_RXSTAT
);
u32
rxmac_stat
=
readl
(
gp
->
regs
+
MAC_RXSTAT
);
int
ret
=
0
;
if
(
netif_msg_intr
(
gp
))
if
(
netif_msg_intr
(
gp
))
printk
(
KERN_DEBUG
"%s: rxmac interrupt, rxmac_stat: 0x%x
\n
"
,
printk
(
KERN_DEBUG
"%s: rxmac interrupt, rxmac_stat: 0x%x
\n
"
,
gp
->
dev
->
name
,
rxmac_stat
);
gp
->
dev
->
name
,
rxmac_stat
);
if
(
rxmac_stat
&
MAC_RXSTAT_OFLW
)
{
if
(
rxmac_stat
&
MAC_RXSTAT_OFLW
)
{
printk
(
KERN_ERR
"%s: RX MAC fifo overflow.
\n
"
,
dev
->
name
);
gp
->
net_stats
.
rx_over_errors
++
;
gp
->
net_stats
.
rx_over_errors
++
;
gp
->
net_stats
.
rx_fifo_errors
++
;
gp
->
net_stats
.
rx_fifo_errors
++
;
ret
=
gem_rxmac_reset
(
gp
);
}
}
if
(
rxmac_stat
&
MAC_RXSTAT_ACE
)
if
(
rxmac_stat
&
MAC_RXSTAT_ACE
)
...
@@ -320,7 +423,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
...
@@ -320,7 +423,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
/* We do not track MAC_RXSTAT_FCE and MAC_RXSTAT_VCE
/* We do not track MAC_RXSTAT_FCE and MAC_RXSTAT_VCE
* events.
* events.
*/
*/
return
0
;
return
ret
;
}
}
static
int
gem_mac_interrupt
(
struct
net_device
*
dev
,
struct
gem
*
gp
,
u32
gem_status
)
static
int
gem_mac_interrupt
(
struct
net_device
*
dev
,
struct
gem
*
gp
,
u32
gem_status
)
...
@@ -480,7 +583,7 @@ static int gem_abnormal_irq(struct net_device *dev, struct gem *gp, u32 gem_stat
...
@@ -480,7 +583,7 @@ static int gem_abnormal_irq(struct net_device *dev, struct gem *gp, u32 gem_stat
return
0
;
return
0
;
do_reset:
do_reset:
gp
->
reset_task_pending
=
1
;
gp
->
reset_task_pending
=
2
;
schedule_task
(
&
gp
->
reset_task
);
schedule_task
(
&
gp
->
reset_task
);
return
1
;
return
1
;
...
@@ -542,7 +645,7 @@ static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_st
...
@@ -542,7 +645,7 @@ static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_st
gp
->
tx_old
=
entry
;
gp
->
tx_old
=
entry
;
if
(
netif_queue_stopped
(
dev
)
&&
if
(
netif_queue_stopped
(
dev
)
&&
TX_BUFFS_AVAIL
(
gp
)
>
0
)
TX_BUFFS_AVAIL
(
gp
)
>
(
MAX_SKB_FRAGS
+
1
)
)
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
...
@@ -717,7 +820,7 @@ static void gem_tx_timeout(struct net_device *dev)
...
@@ -717,7 +820,7 @@ static void gem_tx_timeout(struct net_device *dev)
spin_lock_irq
(
&
gp
->
lock
);
spin_lock_irq
(
&
gp
->
lock
);
gp
->
reset_task_pending
=
1
;
gp
->
reset_task_pending
=
2
;
schedule_task
(
&
gp
->
reset_task
);
schedule_task
(
&
gp
->
reset_task
);
spin_unlock_irq
(
&
gp
->
lock
);
spin_unlock_irq
(
&
gp
->
lock
);
...
@@ -752,9 +855,12 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -752,9 +855,12 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irq
(
&
gp
->
lock
);
spin_lock_irq
(
&
gp
->
lock
);
/* This is a hard error, log it. */
if
(
TX_BUFFS_AVAIL
(
gp
)
<=
(
skb_shinfo
(
skb
)
->
nr_frags
+
1
))
{
if
(
TX_BUFFS_AVAIL
(
gp
)
<=
(
skb_shinfo
(
skb
)
->
nr_frags
+
1
))
{
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
spin_unlock_irq
(
&
gp
->
lock
);
spin_unlock_irq
(
&
gp
->
lock
);
printk
(
KERN_ERR
PFX
"%s: BUG! Tx Ring full when queue awake!
\n
"
,
dev
->
name
);
return
1
;
return
1
;
}
}
...
@@ -829,7 +935,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -829,7 +935,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
gp
->
tx_new
=
entry
;
gp
->
tx_new
=
entry
;
if
(
TX_BUFFS_AVAIL
(
gp
)
<=
0
)
if
(
TX_BUFFS_AVAIL
(
gp
)
<=
(
MAX_SKB_FRAGS
+
1
)
)
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
if
(
netif_msg_tx_queued
(
gp
))
if
(
netif_msg_tx_queued
(
gp
))
...
@@ -844,19 +950,28 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -844,19 +950,28 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
/* Jumbo-grams don't seem to work :-( */
/* Jumbo-grams don't seem to work :-( */
#define GEM_MIN_MTU 68
#if 1
#if 1
#define
MAX_MTU
1500
#define
GEM_MAX_MTU
1500
#else
#else
#define
MAX_MTU
9000
#define
GEM_MAX_MTU
9000
#endif
#endif
static
int
gem_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
static
int
gem_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
{
struct
gem
*
gp
=
dev
->
priv
;
struct
gem
*
gp
=
dev
->
priv
;
if
(
new_mtu
<
0
||
new_mtu
>
MAX_MTU
)
if
(
new_mtu
<
GEM_MIN_MTU
||
new_mtu
>
GEM_
MAX_MTU
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
netif_running
(
dev
)
||
!
netif_device_present
(
dev
))
{
/* We'll just catch it later when the
* device is up'd or resumed.
*/
dev
->
mtu
=
new_mtu
;
return
0
;
}
spin_lock_irq
(
&
gp
->
lock
);
spin_lock_irq
(
&
gp
->
lock
);
dev
->
mtu
=
new_mtu
;
dev
->
mtu
=
new_mtu
;
gp
->
reset_task_pending
=
1
;
gp
->
reset_task_pending
=
1
;
...
@@ -870,6 +985,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
...
@@ -870,6 +985,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
#define STOP_TRIES 32
#define STOP_TRIES 32
/* Must be invoked under gp->lock. */
static
void
gem_stop
(
struct
gem
*
gp
)
static
void
gem_stop
(
struct
gem
*
gp
)
{
{
int
limit
;
int
limit
;
...
@@ -879,7 +995,8 @@ static void gem_stop(struct gem *gp)
...
@@ -879,7 +995,8 @@ static void gem_stop(struct gem *gp)
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
/* Reset the chip */
/* Reset the chip */
writel
(
GREG_SWRST_TXRST
|
GREG_SWRST_RXRST
,
gp
->
regs
+
GREG_SWRST
);
writel
(
gp
->
swrst_base
|
GREG_SWRST_TXRST
|
GREG_SWRST_RXRST
,
gp
->
regs
+
GREG_SWRST
);
limit
=
STOP_TRIES
;
limit
=
STOP_TRIES
;
...
@@ -894,6 +1011,7 @@ static void gem_stop(struct gem *gp)
...
@@ -894,6 +1011,7 @@ static void gem_stop(struct gem *gp)
printk
(
KERN_ERR
"gem: SW reset is ghetto.
\n
"
);
printk
(
KERN_ERR
"gem: SW reset is ghetto.
\n
"
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_start_dma
(
struct
gem
*
gp
)
static
void
gem_start_dma
(
struct
gem
*
gp
)
{
{
unsigned
long
val
;
unsigned
long
val
;
...
@@ -929,6 +1047,7 @@ static int phy_BCM5400_link_table[8][3] = {
...
@@ -929,6 +1047,7 @@ static int phy_BCM5400_link_table[8][3] = {
{
1
,
0
,
1
},
/* 1000BT */
{
1
,
0
,
1
},
/* 1000BT */
};
};
/* Must be invoked under gp->lock. */
static
void
gem_begin_auto_negotiation
(
struct
gem
*
gp
,
struct
ethtool_cmd
*
ep
)
static
void
gem_begin_auto_negotiation
(
struct
gem
*
gp
,
struct
ethtool_cmd
*
ep
)
{
{
u16
ctl
;
u16
ctl
;
...
@@ -954,11 +1073,8 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
...
@@ -954,11 +1073,8 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
}
}
start_aneg:
start_aneg:
spin_lock_irq
(
&
gp
->
lock
);
if
(
!
gp
->
hw_running
)
if
(
!
gp
->
hw_running
)
{
spin_unlock_irq
(
&
gp
->
lock
);
return
;
return
;
}
/* Configure PHY & start aneg */
/* Configure PHY & start aneg */
ctl
=
phy_read
(
gp
,
MII_BMCR
);
ctl
=
phy_read
(
gp
,
MII_BMCR
);
...
@@ -973,11 +1089,10 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
...
@@ -973,11 +1089,10 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
phy_write
(
gp
,
MII_BMCR
,
ctl
);
phy_write
(
gp
,
MII_BMCR
,
ctl
);
gp
->
timer_ticks
=
0
;
gp
->
timer_ticks
=
0
;
gp
->
link_timer
.
expires
=
jiffies
+
((
12
*
HZ
)
/
10
);
mod_timer
(
&
gp
->
link_timer
,
jiffies
+
((
12
*
HZ
)
/
10
));
add_timer
(
&
gp
->
link_timer
);
spin_unlock_irq
(
&
gp
->
lock
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_read_mii_link_mode
(
struct
gem
*
gp
,
int
*
fd
,
int
*
spd
,
int
*
pause
)
static
void
gem_read_mii_link_mode
(
struct
gem
*
gp
,
int
*
fd
,
int
*
spd
,
int
*
pause
)
{
{
u32
val
;
u32
val
;
...
@@ -1021,6 +1136,8 @@ static void gem_read_mii_link_mode(struct gem *gp, int *fd, int *spd, int *pause
...
@@ -1021,6 +1136,8 @@ static void gem_read_mii_link_mode(struct gem *gp, int *fd, int *spd, int *pause
/* A link-up condition has occurred, initialize and enable the
/* A link-up condition has occurred, initialize and enable the
* rest of the chip.
* rest of the chip.
*
* Must be invoked under gp->lock.
*/
*/
static
void
gem_set_link_modes
(
struct
gem
*
gp
)
static
void
gem_set_link_modes
(
struct
gem
*
gp
)
{
{
...
@@ -1101,6 +1218,20 @@ static void gem_set_link_modes(struct gem *gp)
...
@@ -1101,6 +1218,20 @@ static void gem_set_link_modes(struct gem *gp)
pause
=
1
;
pause
=
1
;
}
}
if
(
netif_msg_link
(
gp
))
{
if
(
pause
)
{
printk
(
KERN_INFO
"%s: Pause is enabled "
"(rxfifo: %d off: %d on: %d)
\n
"
,
gp
->
dev
->
name
,
gp
->
rx_fifo_sz
,
gp
->
rx_pause_off
,
gp
->
rx_pause_on
);
}
else
{
printk
(
KERN_INFO
"%s: Pause is disabled
\n
"
,
gp
->
dev
->
name
);
}
}
if
(
!
full_duplex
)
if
(
!
full_duplex
)
writel
(
512
,
gp
->
regs
+
MAC_STIME
);
writel
(
512
,
gp
->
regs
+
MAC_STIME
);
else
else
...
@@ -1115,6 +1246,7 @@ static void gem_set_link_modes(struct gem *gp)
...
@@ -1115,6 +1246,7 @@ static void gem_set_link_modes(struct gem *gp)
gem_start_dma
(
gp
);
gem_start_dma
(
gp
);
}
}
/* Must be invoked under gp->lock. */
static
int
gem_mdio_link_not_up
(
struct
gem
*
gp
)
static
int
gem_mdio_link_not_up
(
struct
gem
*
gp
)
{
{
u16
val
;
u16
val
;
...
@@ -1158,7 +1290,7 @@ static int gem_mdio_link_not_up(struct gem *gp)
...
@@ -1158,7 +1290,7 @@ static int gem_mdio_link_not_up(struct gem *gp)
return
0
;
return
0
;
}
}
static
void
gem_init_rings
(
struct
gem
*
,
int
);
static
void
gem_init_rings
(
struct
gem
*
);
static
void
gem_init_hw
(
struct
gem
*
,
int
);
static
void
gem_init_hw
(
struct
gem
*
,
int
);
static
void
gem_reset_task
(
void
*
data
)
static
void
gem_reset_task
(
void
*
data
)
...
@@ -1169,24 +1301,27 @@ static void gem_reset_task(void *data)
...
@@ -1169,24 +1301,27 @@ static void gem_reset_task(void *data)
* DMA stopped. Todo: Use this function for reset
* DMA stopped. Todo: Use this function for reset
* on error as well.
* on error as well.
*/
*/
spin_lock_irq
(
&
gp
->
lock
);
if
(
gp
->
hw_running
&&
gp
->
opened
)
{
if
(
gp
->
hw_running
&&
gp
->
opened
)
{
/* Make sure we don't get interrupts or tx packets */
/* Make sure we don't get interrupts or tx packets */
spin_lock_irq
(
&
gp
->
lock
);
netif_stop_queue
(
gp
->
dev
);
netif_stop_queue
(
gp
->
dev
);
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
spin_unlock_irq
(
&
gp
->
lock
);
/* Reset the chip & rings */
/* Reset the chip & rings */
gem_stop
(
gp
);
gem_stop
(
gp
);
gem_init_rings
(
gp
,
0
);
gem_init_rings
(
gp
);
gem_init_hw
(
gp
,
0
);
gem_init_hw
(
gp
,
(
gp
->
reset_task_pending
==
2
));
netif_wake_queue
(
gp
->
dev
);
netif_wake_queue
(
gp
->
dev
);
}
}
gp
->
reset_task_pending
=
0
;
gp
->
reset_task_pending
=
0
;
spin_unlock_irq
(
&
gp
->
lock
);
}
}
static
void
gem_link_timer
(
unsigned
long
data
)
static
void
gem_link_timer
(
unsigned
long
data
)
...
@@ -1196,13 +1331,14 @@ static void gem_link_timer(unsigned long data)
...
@@ -1196,13 +1331,14 @@ static void gem_link_timer(unsigned long data)
if
(
!
gp
->
hw_running
)
if
(
!
gp
->
hw_running
)
return
;
return
;
spin_lock_irq
(
&
gp
->
lock
);
/* If the link of task is still pending, we just
/* If the link of task is still pending, we just
* reschedule the link timer
* reschedule the link timer
*/
*/
if
(
gp
->
reset_task_pending
)
if
(
gp
->
reset_task_pending
)
goto
restart
;
goto
restart
;
spin_lock_irq
(
&
gp
->
lock
);
if
(
gp
->
phy_type
==
phy_mii_mdio0
||
if
(
gp
->
phy_type
==
phy_mii_mdio0
||
gp
->
phy_type
==
phy_mii_mdio1
)
{
gp
->
phy_type
==
phy_mii_mdio1
)
{
u16
val
=
phy_read
(
gp
,
MII_BMSR
);
u16
val
=
phy_read
(
gp
,
MII_BMSR
);
...
@@ -1247,16 +1383,15 @@ static void gem_link_timer(unsigned long data)
...
@@ -1247,16 +1383,15 @@ static void gem_link_timer(unsigned long data)
if
(
netif_msg_link
(
gp
))
if
(
netif_msg_link
(
gp
))
printk
(
KERN_INFO
"%s: Link down
\n
"
,
printk
(
KERN_INFO
"%s: Link down
\n
"
,
gp
->
dev
->
name
);
gp
->
dev
->
name
);
gp
->
reset_task_pending
=
1
;
gp
->
reset_task_pending
=
2
;
schedule_task
(
&
gp
->
reset_task
);
schedule_task
(
&
gp
->
reset_task
);
restart
=
1
;
restart
=
1
;
}
else
if
(
++
gp
->
timer_ticks
>
10
)
}
else
if
(
++
gp
->
timer_ticks
>
10
)
restart
=
gem_mdio_link_not_up
(
gp
);
restart
=
gem_mdio_link_not_up
(
gp
);
if
(
restart
)
{
if
(
restart
)
{
spin_unlock_irq
(
&
gp
->
lock
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
return
;
goto
out_unlock
;
}
}
}
}
}
else
{
}
else
{
...
@@ -1273,11 +1408,12 @@ static void gem_link_timer(unsigned long data)
...
@@ -1273,11 +1408,12 @@ static void gem_link_timer(unsigned long data)
}
}
restart:
restart:
gp
->
link_timer
.
expires
=
jiffies
+
((
12
*
HZ
)
/
10
);
mod_timer
(
&
gp
->
link_timer
,
jiffies
+
((
12
*
HZ
)
/
10
)
);
add_timer
(
&
gp
->
link_timer
);
out_unlock:
spin_unlock_irq
(
&
gp
->
lock
);
spin_unlock_irq
(
&
gp
->
lock
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_clean_rings
(
struct
gem
*
gp
)
static
void
gem_clean_rings
(
struct
gem
*
gp
)
{
{
struct
gem_init_block
*
gb
=
gp
->
init_block
;
struct
gem_init_block
*
gb
=
gp
->
init_block
;
...
@@ -1311,7 +1447,9 @@ static void gem_clean_rings(struct gem *gp)
...
@@ -1311,7 +1447,9 @@ static void gem_clean_rings(struct gem *gp)
gp
->
tx_skbs
[
i
]
=
NULL
;
gp
->
tx_skbs
[
i
]
=
NULL
;
for
(
frag
=
0
;
frag
<=
skb_shinfo
(
skb
)
->
nr_frags
;
frag
++
)
{
for
(
frag
=
0
;
frag
<=
skb_shinfo
(
skb
)
->
nr_frags
;
frag
++
)
{
txd
=
&
gb
->
txd
[
i
];
int
ent
=
i
&
(
TX_RING_SIZE
-
1
);
txd
=
&
gb
->
txd
[
ent
];
dma_addr
=
le64_to_cpu
(
txd
->
buffer
);
dma_addr
=
le64_to_cpu
(
txd
->
buffer
);
pci_unmap_page
(
gp
->
pdev
,
dma_addr
,
pci_unmap_page
(
gp
->
pdev
,
dma_addr
,
le64_to_cpu
(
txd
->
control_word
)
&
le64_to_cpu
(
txd
->
control_word
)
&
...
@@ -1325,16 +1463,14 @@ static void gem_clean_rings(struct gem *gp)
...
@@ -1325,16 +1463,14 @@ static void gem_clean_rings(struct gem *gp)
}
}
}
}
static
void
gem_init_rings
(
struct
gem
*
gp
,
int
from_irq
)
/* Must be invoked under gp->lock. */
static
void
gem_init_rings
(
struct
gem
*
gp
)
{
{
struct
gem_init_block
*
gb
=
gp
->
init_block
;
struct
gem_init_block
*
gb
=
gp
->
init_block
;
struct
net_device
*
dev
=
gp
->
dev
;
struct
net_device
*
dev
=
gp
->
dev
;
int
i
,
gfp_flags
=
GFP_KERNEL
;
int
i
;
dma_addr_t
dma_addr
;
dma_addr_t
dma_addr
;
if
(
from_irq
)
gfp_flags
=
GFP_ATOMIC
;
gp
->
rx_new
=
gp
->
rx_old
=
gp
->
tx_new
=
gp
->
tx_old
=
0
;
gp
->
rx_new
=
gp
->
rx_old
=
gp
->
tx_new
=
gp
->
tx_old
=
0
;
gem_clean_rings
(
gp
);
gem_clean_rings
(
gp
);
...
@@ -1343,7 +1479,7 @@ static void gem_init_rings(struct gem *gp, int from_irq)
...
@@ -1343,7 +1479,7 @@ static void gem_init_rings(struct gem *gp, int from_irq)
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
struct
gem_rxd
*
rxd
=
&
gb
->
rxd
[
i
];
struct
gem_rxd
*
rxd
=
&
gb
->
rxd
[
i
];
skb
=
gem_alloc_skb
(
RX_BUF_ALLOC_SIZE
(
gp
),
gfp_flags
);
skb
=
gem_alloc_skb
(
RX_BUF_ALLOC_SIZE
(
gp
),
GFP_ATOMIC
);
if
(
!
skb
)
{
if
(
!
skb
)
{
rxd
->
buffer
=
0
;
rxd
->
buffer
=
0
;
rxd
->
status_word
=
0
;
rxd
->
status_word
=
0
;
...
@@ -1372,6 +1508,7 @@ static void gem_init_rings(struct gem *gp, int from_irq)
...
@@ -1372,6 +1508,7 @@ static void gem_init_rings(struct gem *gp, int from_irq)
}
}
}
}
/* Must be invoked under gp->lock. */
static
int
gem_reset_one_mii_phy
(
struct
gem
*
gp
,
int
phy_addr
)
static
int
gem_reset_one_mii_phy
(
struct
gem
*
gp
,
int
phy_addr
)
{
{
u16
val
;
u16
val
;
...
@@ -1396,6 +1533,7 @@ static int gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
...
@@ -1396,6 +1533,7 @@ static int gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
return
(
limit
<=
0
);
return
(
limit
<=
0
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_bcm5201_phy
(
struct
gem
*
gp
)
static
void
gem_init_bcm5201_phy
(
struct
gem
*
gp
)
{
{
u16
data
;
u16
data
;
...
@@ -1405,6 +1543,7 @@ static void gem_init_bcm5201_phy(struct gem *gp)
...
@@ -1405,6 +1543,7 @@ static void gem_init_bcm5201_phy(struct gem *gp)
phy_write
(
gp
,
MII_BCM5201_MULTIPHY
,
data
);
phy_write
(
gp
,
MII_BCM5201_MULTIPHY
,
data
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_bcm5400_phy
(
struct
gem
*
gp
)
static
void
gem_init_bcm5400_phy
(
struct
gem
*
gp
)
{
{
u16
data
;
u16
data
;
...
@@ -1432,6 +1571,7 @@ static void gem_init_bcm5400_phy(struct gem *gp)
...
@@ -1432,6 +1571,7 @@ static void gem_init_bcm5400_phy(struct gem *gp)
phy_write
(
gp
,
MII_BCM5400_AUXCONTROL
,
data
);
phy_write
(
gp
,
MII_BCM5400_AUXCONTROL
,
data
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_bcm5401_phy
(
struct
gem
*
gp
)
static
void
gem_init_bcm5401_phy
(
struct
gem
*
gp
)
{
{
u16
data
;
u16
data
;
...
@@ -1446,6 +1586,9 @@ static void gem_init_bcm5401_phy(struct gem *gp)
...
@@ -1446,6 +1586,9 @@ static void gem_init_bcm5401_phy(struct gem *gp)
* WARNING ! OF and Darwin don't agree on the
* WARNING ! OF and Darwin don't agree on the
* register addresses. OF seem to interpret the
* register addresses. OF seem to interpret the
* register numbers below as decimal
* register numbers below as decimal
*
* Note: This should (and does) match tg3_init_5401phy_dsp
* in the tg3.c driver. -DaveM
*/
*/
phy_write
(
gp
,
0x18
,
0x0c20
);
phy_write
(
gp
,
0x18
,
0x0c20
);
phy_write
(
gp
,
0x17
,
0x0012
);
phy_write
(
gp
,
0x17
,
0x0012
);
...
@@ -1475,6 +1618,7 @@ static void gem_init_bcm5401_phy(struct gem *gp)
...
@@ -1475,6 +1618,7 @@ static void gem_init_bcm5401_phy(struct gem *gp)
__phy_write
(
gp
,
MII_BCM5201_MULTIPHY
,
data
,
0x1f
);
__phy_write
(
gp
,
MII_BCM5201_MULTIPHY
,
data
,
0x1f
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_bcm5411_phy
(
struct
gem
*
gp
)
static
void
gem_init_bcm5411_phy
(
struct
gem
*
gp
)
{
{
u16
data
;
u16
data
;
...
@@ -1501,6 +1645,7 @@ static void gem_init_bcm5411_phy(struct gem *gp)
...
@@ -1501,6 +1645,7 @@ static void gem_init_bcm5411_phy(struct gem *gp)
phy_write
(
gp
,
MII_BCM5400_GB_CONTROL
,
data
);
phy_write
(
gp
,
MII_BCM5400_GB_CONTROL
,
data
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_phy
(
struct
gem
*
gp
)
static
void
gem_init_phy
(
struct
gem
*
gp
)
{
{
u32
mifcfg
;
u32
mifcfg
;
...
@@ -1649,7 +1794,9 @@ static void gem_init_phy(struct gem *gp)
...
@@ -1649,7 +1794,9 @@ static void gem_init_phy(struct gem *gp)
val
&=
~
(
PCS_CFG_ENABLE
|
PCS_CFG_TO
);
val
&=
~
(
PCS_CFG_ENABLE
|
PCS_CFG_TO
);
writel
(
val
,
gp
->
regs
+
PCS_CFG
);
writel
(
val
,
gp
->
regs
+
PCS_CFG
);
/* Advertise all capabilities. */
/* Advertise all capabilities except assymetric
* pause.
*/
val
=
readl
(
gp
->
regs
+
PCS_MIIADV
);
val
=
readl
(
gp
->
regs
+
PCS_MIIADV
);
val
|=
(
PCS_MIIADV_FD
|
PCS_MIIADV_HD
|
val
|=
(
PCS_MIIADV_FD
|
PCS_MIIADV_HD
|
PCS_MIIADV_SP
|
PCS_MIIADV_AP
);
PCS_MIIADV_SP
|
PCS_MIIADV_AP
);
...
@@ -1684,9 +1831,9 @@ static void gem_init_phy(struct gem *gp)
...
@@ -1684,9 +1831,9 @@ static void gem_init_phy(struct gem *gp)
if
(
gp
->
phy_mod
!=
phymod_bcm5400
&&
gp
->
phy_mod
!=
phymod_bcm5401
&&
if
(
gp
->
phy_mod
!=
phymod_bcm5400
&&
gp
->
phy_mod
!=
phymod_bcm5401
&&
gp
->
phy_mod
!=
phymod_bcm5411
)
gp
->
phy_mod
!=
phymod_bcm5411
)
gp
->
link_cntl
&=
~
BMCR_SPD2
;
gp
->
link_cntl
&=
~
BMCR_SPD2
;
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_dma
(
struct
gem
*
gp
)
static
void
gem_init_dma
(
struct
gem
*
gp
)
{
{
u64
desc_dma
=
(
u64
)
gp
->
gblock_dvma
;
u64
desc_dma
=
(
u64
)
gp
->
gblock_dvma
;
...
@@ -1702,7 +1849,7 @@ static void gem_init_dma(struct gem *gp)
...
@@ -1702,7 +1849,7 @@ static void gem_init_dma(struct gem *gp)
writel
(
0
,
gp
->
regs
+
TXDMA_KICK
);
writel
(
0
,
gp
->
regs
+
TXDMA_KICK
);
val
=
(
RXDMA_CFG_BASE
|
(
RX_OFFSET
<<
10
)
|
val
=
(
RXDMA_CFG_BASE
|
(
RX_OFFSET
<<
10
)
|
((
14
/
2
)
<<
13
)
|
RXDMA_CFG_FTHRESH_
512
);
((
14
/
2
)
<<
13
)
|
RXDMA_CFG_FTHRESH_
128
);
writel
(
val
,
gp
->
regs
+
RXDMA_CFG
);
writel
(
val
,
gp
->
regs
+
RXDMA_CFG
);
writel
(
desc_dma
>>
32
,
gp
->
regs
+
RXDMA_DBHI
);
writel
(
desc_dma
>>
32
,
gp
->
regs
+
RXDMA_DBHI
);
...
@@ -1724,6 +1871,7 @@ static void gem_init_dma(struct gem *gp)
...
@@ -1724,6 +1871,7 @@ static void gem_init_dma(struct gem *gp)
gp
->
regs
+
RXDMA_BLANK
);
gp
->
regs
+
RXDMA_BLANK
);
}
}
/* Must be invoked under gp->lock. */
static
u32
static
u32
gem_setup_multicast
(
struct
gem
*
gp
)
gem_setup_multicast
(
struct
gem
*
gp
)
{
{
...
@@ -1766,10 +1914,10 @@ gem_setup_multicast(struct gem *gp)
...
@@ -1766,10 +1914,10 @@ gem_setup_multicast(struct gem *gp)
return
rxcfg
;
return
rxcfg
;
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_mac
(
struct
gem
*
gp
)
static
void
gem_init_mac
(
struct
gem
*
gp
)
{
{
unsigned
char
*
e
=
&
gp
->
dev
->
dev_addr
[
0
];
unsigned
char
*
e
=
&
gp
->
dev
->
dev_addr
[
0
];
u32
rxcfg
;
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_SUN
&&
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_SUN
&&
gp
->
pdev
->
device
==
PCI_DEVICE_ID_SUN_GEM
)
gp
->
pdev
->
device
==
PCI_DEVICE_ID_SUN_GEM
)
...
@@ -1780,7 +1928,10 @@ static void gem_init_mac(struct gem *gp)
...
@@ -1780,7 +1928,10 @@ static void gem_init_mac(struct gem *gp)
writel
(
0x04
,
gp
->
regs
+
MAC_IPG2
);
writel
(
0x04
,
gp
->
regs
+
MAC_IPG2
);
writel
(
0x40
,
gp
->
regs
+
MAC_STIME
);
writel
(
0x40
,
gp
->
regs
+
MAC_STIME
);
writel
(
0x40
,
gp
->
regs
+
MAC_MINFSZ
);
writel
(
0x40
,
gp
->
regs
+
MAC_MINFSZ
);
writel
(
0x20000000
|
(
gp
->
dev
->
mtu
+
18
),
gp
->
regs
+
MAC_MAXFSZ
);
/* Ethernet payload + header + FCS + optional VLAN tag. */
writel
(
0x20000000
|
(
gp
->
dev
->
mtu
+
ETH_HLEN
+
4
+
4
),
gp
->
regs
+
MAC_MAXFSZ
);
writel
(
0x07
,
gp
->
regs
+
MAC_PASIZE
);
writel
(
0x07
,
gp
->
regs
+
MAC_PASIZE
);
writel
(
0x04
,
gp
->
regs
+
MAC_JAMSIZE
);
writel
(
0x04
,
gp
->
regs
+
MAC_JAMSIZE
);
writel
(
0x10
,
gp
->
regs
+
MAC_ATTLIM
);
writel
(
0x10
,
gp
->
regs
+
MAC_ATTLIM
);
...
@@ -1806,7 +1957,7 @@ static void gem_init_mac(struct gem *gp)
...
@@ -1806,7 +1957,7 @@ static void gem_init_mac(struct gem *gp)
writel
(
0
,
gp
->
regs
+
MAC_AF21MSK
);
writel
(
0
,
gp
->
regs
+
MAC_AF21MSK
);
writel
(
0
,
gp
->
regs
+
MAC_AF0MSK
);
writel
(
0
,
gp
->
regs
+
MAC_AF0MSK
);
rx
cfg
=
gem_setup_multicast
(
gp
);
gp
->
mac_rx_
cfg
=
gem_setup_multicast
(
gp
);
writel
(
0
,
gp
->
regs
+
MAC_NCOLL
);
writel
(
0
,
gp
->
regs
+
MAC_NCOLL
);
writel
(
0
,
gp
->
regs
+
MAC_FASUCC
);
writel
(
0
,
gp
->
regs
+
MAC_FASUCC
);
...
@@ -1824,7 +1975,7 @@ static void gem_init_mac(struct gem *gp)
...
@@ -1824,7 +1975,7 @@ static void gem_init_mac(struct gem *gp)
* them once a link is established.
* them once a link is established.
*/
*/
writel
(
0
,
gp
->
regs
+
MAC_TXCFG
);
writel
(
0
,
gp
->
regs
+
MAC_TXCFG
);
writel
(
rx
cfg
,
gp
->
regs
+
MAC_RXCFG
);
writel
(
gp
->
mac_rx_
cfg
,
gp
->
regs
+
MAC_RXCFG
);
writel
(
0
,
gp
->
regs
+
MAC_MCCFG
);
writel
(
0
,
gp
->
regs
+
MAC_MCCFG
);
writel
(
0
,
gp
->
regs
+
MAC_XIFCFG
);
writel
(
0
,
gp
->
regs
+
MAC_XIFCFG
);
...
@@ -1841,6 +1992,7 @@ static void gem_init_mac(struct gem *gp)
...
@@ -1841,6 +1992,7 @@ static void gem_init_mac(struct gem *gp)
writel
(
0xffffffff
,
gp
->
regs
+
MAC_MCMASK
);
writel
(
0xffffffff
,
gp
->
regs
+
MAC_MCMASK
);
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_pause_thresholds
(
struct
gem
*
gp
)
static
void
gem_init_pause_thresholds
(
struct
gem
*
gp
)
{
{
/* Calculate pause thresholds. Setting the OFF threshold to the
/* Calculate pause thresholds. Setting the OFF threshold to the
...
@@ -1851,8 +2003,9 @@ static void gem_init_pause_thresholds(struct gem *gp)
...
@@ -1851,8 +2003,9 @@ static void gem_init_pause_thresholds(struct gem *gp)
if
(
gp
->
rx_fifo_sz
<=
(
2
*
1024
))
{
if
(
gp
->
rx_fifo_sz
<=
(
2
*
1024
))
{
gp
->
rx_pause_off
=
gp
->
rx_pause_on
=
gp
->
rx_fifo_sz
;
gp
->
rx_pause_off
=
gp
->
rx_pause_on
=
gp
->
rx_fifo_sz
;
}
else
{
}
else
{
int
off
=
(
gp
->
rx_fifo_sz
-
(
5
*
1024
));
int
max_frame
=
(
gp
->
dev
->
mtu
+
ETH_HLEN
+
4
+
4
+
64
)
&
~
63
;
int
on
=
off
-
1024
;
int
off
=
(
gp
->
rx_fifo_sz
-
(
max_frame
*
2
));
int
on
=
off
-
max_frame
;
gp
->
rx_pause_off
=
off
;
gp
->
rx_pause_off
=
off
;
gp
->
rx_pause_on
=
on
;
gp
->
rx_pause_on
=
on
;
...
@@ -1861,7 +2014,10 @@ static void gem_init_pause_thresholds(struct gem *gp)
...
@@ -1861,7 +2014,10 @@ static void gem_init_pause_thresholds(struct gem *gp)
{
{
u32
cfg
;
u32
cfg
;
cfg
=
GREG_CFG_IBURST
;
cfg
=
0
;
#if !defined(CONFIG_SPARC64) && !defined(CONFIG_ALPHA)
cfg
|=
GREG_CFG_IBURST
;
#endif
cfg
|=
((
31
<<
1
)
&
GREG_CFG_TXDMALIM
);
cfg
|=
((
31
<<
1
)
&
GREG_CFG_TXDMALIM
);
cfg
|=
((
31
<<
6
)
&
GREG_CFG_RXDMALIM
);
cfg
|=
((
31
<<
6
)
&
GREG_CFG_RXDMALIM
);
writel
(
cfg
,
gp
->
regs
+
GREG_CFG
);
writel
(
cfg
,
gp
->
regs
+
GREG_CFG
);
...
@@ -1881,6 +2037,7 @@ static int gem_check_invariants(struct gem *gp)
...
@@ -1881,6 +2037,7 @@ static int gem_check_invariants(struct gem *gp)
gp
->
phy_type
=
phy_mii_mdio0
;
gp
->
phy_type
=
phy_mii_mdio0
;
gp
->
tx_fifo_sz
=
readl
(
gp
->
regs
+
TXDMA_FSZ
)
*
64
;
gp
->
tx_fifo_sz
=
readl
(
gp
->
regs
+
TXDMA_FSZ
)
*
64
;
gp
->
rx_fifo_sz
=
readl
(
gp
->
regs
+
RXDMA_FSZ
)
*
64
;
gp
->
rx_fifo_sz
=
readl
(
gp
->
regs
+
RXDMA_FSZ
)
*
64
;
gp
->
swrst_base
=
0
;
return
0
;
return
0
;
}
}
...
@@ -1943,6 +2100,7 @@ static int gem_check_invariants(struct gem *gp)
...
@@ -1943,6 +2100,7 @@ static int gem_check_invariants(struct gem *gp)
gp
->
tx_fifo_sz
,
gp
->
rx_fifo_sz
);
gp
->
tx_fifo_sz
,
gp
->
rx_fifo_sz
);
return
-
1
;
return
-
1
;
}
}
gp
->
swrst_base
=
0
;
}
else
{
}
else
{
if
(
gp
->
tx_fifo_sz
!=
(
2
*
1024
)
||
if
(
gp
->
tx_fifo_sz
!=
(
2
*
1024
)
||
gp
->
rx_fifo_sz
!=
(
2
*
1024
))
{
gp
->
rx_fifo_sz
!=
(
2
*
1024
))
{
...
@@ -1950,12 +2108,14 @@ static int gem_check_invariants(struct gem *gp)
...
@@ -1950,12 +2108,14 @@ static int gem_check_invariants(struct gem *gp)
gp
->
tx_fifo_sz
,
gp
->
rx_fifo_sz
);
gp
->
tx_fifo_sz
,
gp
->
rx_fifo_sz
);
return
-
1
;
return
-
1
;
}
}
gp
->
swrst_base
=
(
64
/
4
)
<<
GREG_SWRST_CACHE_SHIFT
;
}
}
}
}
return
0
;
return
0
;
}
}
/* Must be invoked under gp->lock. */
static
void
gem_init_hw
(
struct
gem
*
gp
,
int
restart_link
)
static
void
gem_init_hw
(
struct
gem
*
gp
,
int
restart_link
)
{
{
/* On Apple's gmac, I initialize the PHY only after
/* On Apple's gmac, I initialize the PHY only after
...
@@ -1970,21 +2130,16 @@ static void gem_init_hw(struct gem *gp, int restart_link)
...
@@ -1970,21 +2130,16 @@ static void gem_init_hw(struct gem *gp, int restart_link)
gem_init_mac
(
gp
);
gem_init_mac
(
gp
);
gem_init_pause_thresholds
(
gp
);
gem_init_pause_thresholds
(
gp
);
spin_lock_irq
(
&
gp
->
lock
);
if
(
restart_link
)
{
if
(
restart_link
)
{
/* Default aneg parameters */
/* Default aneg parameters */
gp
->
timer_ticks
=
0
;
gp
->
timer_ticks
=
0
;
gp
->
lstate
=
link_down
;
gp
->
lstate
=
link_down
;
spin_unlock_irq
(
&
gp
->
lock
);
/* Can I advertise gigabit here ? I'd need BCM PHY docs... */
/* Can I advertise gigabit here ? I'd need BCM PHY docs... */
gem_begin_auto_negotiation
(
gp
,
NULL
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
}
else
{
}
else
{
if
(
gp
->
lstate
==
link_up
)
if
(
gp
->
lstate
==
link_up
)
gem_set_link_modes
(
gp
);
gem_set_link_modes
(
gp
);
spin_unlock_irq
(
&
gp
->
lock
);
}
}
}
}
...
@@ -2029,6 +2184,7 @@ static void gem_apple_powerdown(struct gem *gp)
...
@@ -2029,6 +2184,7 @@ static void gem_apple_powerdown(struct gem *gp)
#endif
/* CONFIG_ALL_PPC */
#endif
/* CONFIG_ALL_PPC */
/* Must be invoked under gp->lock. */
static
void
gem_stop_phy
(
struct
gem
*
gp
)
static
void
gem_stop_phy
(
struct
gem
*
gp
)
{
{
u32
mifcfg
;
u32
mifcfg
;
...
@@ -2100,14 +2256,21 @@ static void gem_shutdown(struct gem *gp)
...
@@ -2100,14 +2256,21 @@ static void gem_shutdown(struct gem *gp)
schedule
();
schedule
();
/* Actually stop the chip */
/* Actually stop the chip */
spin_lock_irq
(
&
gp
->
lock
);
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
{
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
{
gem_stop_phy
(
gp
);
gem_stop_phy
(
gp
);
spin_unlock_irq
(
&
gp
->
lock
);
#ifdef CONFIG_ALL_PPC
#ifdef CONFIG_ALL_PPC
/* Power down the chip */
/* Power down the chip */
gem_apple_powerdown
(
gp
);
gem_apple_powerdown
(
gp
);
#endif
/* CONFIG_ALL_PPC */
#endif
/* CONFIG_ALL_PPC */
}
else
}
else
{
gem_stop
(
gp
);
gem_stop
(
gp
);
spin_unlock_irq
(
&
gp
->
lock
);
}
}
}
static
void
gem_pm_task
(
void
*
data
)
static
void
gem_pm_task
(
void
*
data
)
...
@@ -2142,14 +2305,19 @@ static void gem_pm_timer(unsigned long data)
...
@@ -2142,14 +2305,19 @@ static void gem_pm_timer(unsigned long data)
static
int
gem_open
(
struct
net_device
*
dev
)
static
int
gem_open
(
struct
net_device
*
dev
)
{
{
struct
gem
*
gp
=
dev
->
priv
;
struct
gem
*
gp
=
dev
->
priv
;
int
hw_was_up
=
gp
->
hw_running
;
int
hw_was_up
;
down
(
&
gp
->
pm_sem
);
down
(
&
gp
->
pm_sem
);
hw_was_up
=
gp
->
hw_running
;
/* Stop the PM timer/task */
/* Stop the PM timer/task */
del_timer
(
&
gp
->
pm_timer
);
del_timer
(
&
gp
->
pm_timer
);
flush_scheduled_tasks
();
flush_scheduled_tasks
();
/* The power-management semaphore protects the hw_running
* etc. state so it is safe to do this bit without gp->lock
*/
if
(
!
gp
->
hw_running
)
{
if
(
!
gp
->
hw_running
)
{
#ifdef CONFIG_ALL_PPC
#ifdef CONFIG_ALL_PPC
/* First, we need to bring up the chip */
/* First, we need to bring up the chip */
...
@@ -2158,18 +2326,26 @@ static int gem_open(struct net_device *dev)
...
@@ -2158,18 +2326,26 @@ static int gem_open(struct net_device *dev)
gem_check_invariants
(
gp
);
gem_check_invariants
(
gp
);
}
}
#endif
/* CONFIG_ALL_PPC */
#endif
/* CONFIG_ALL_PPC */
/* Reset the chip */
/* Reset the chip */
spin_lock_irq
(
&
gp
->
lock
);
gem_stop
(
gp
);
gem_stop
(
gp
);
spin_unlock_irq
(
&
gp
->
lock
);
gp
->
hw_running
=
1
;
gp
->
hw_running
=
1
;
}
}
spin_lock_irq
(
&
gp
->
lock
);
/* We can now request the interrupt as we know it's masked
/* We can now request the interrupt as we know it's masked
* on the controller
* on the controller
*/
*/
if
(
request_irq
(
gp
->
pdev
->
irq
,
gem_interrupt
,
if
(
request_irq
(
gp
->
pdev
->
irq
,
gem_interrupt
,
SA_SHIRQ
,
dev
->
name
,
(
void
*
)
dev
))
{
SA_SHIRQ
,
dev
->
name
,
(
void
*
)
dev
))
{
spin_unlock_irq
(
&
gp
->
lock
);
printk
(
KERN_ERR
"%s: failed to request irq !
\n
"
,
gp
->
dev
->
name
);
printk
(
KERN_ERR
"%s: failed to request irq !
\n
"
,
gp
->
dev
->
name
);
#ifdef CONFIG_ALL_PPC
#ifdef CONFIG_ALL_PPC
if
(
!
hw_was_up
&&
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
if
(
!
hw_was_up
&&
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
gem_apple_powerdown
(
gp
);
gem_apple_powerdown
(
gp
);
...
@@ -2183,13 +2359,15 @@ static int gem_open(struct net_device *dev)
...
@@ -2183,13 +2359,15 @@ static int gem_open(struct net_device *dev)
}
}
/* Allocate & setup ring buffers */
/* Allocate & setup ring buffers */
gem_init_rings
(
gp
,
0
);
gem_init_rings
(
gp
);
/* Init & setup chip hardware */
/* Init & setup chip hardware */
gem_init_hw
(
gp
,
!
hw_was_up
);
gem_init_hw
(
gp
,
!
hw_was_up
);
gp
->
opened
=
1
;
gp
->
opened
=
1
;
spin_unlock_irq
(
&
gp
->
lock
);
up
(
&
gp
->
pm_sem
);
up
(
&
gp
->
pm_sem
);
return
0
;
return
0
;
...
@@ -2209,8 +2387,6 @@ static int gem_close(struct net_device *dev)
...
@@ -2209,8 +2387,6 @@ static int gem_close(struct net_device *dev)
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
spin_unlock_irq
(
&
gp
->
lock
);
/* Stop chip */
/* Stop chip */
gem_stop
(
gp
);
gem_stop
(
gp
);
...
@@ -2220,6 +2396,8 @@ static int gem_close(struct net_device *dev)
...
@@ -2220,6 +2396,8 @@ static int gem_close(struct net_device *dev)
/* Bye, the pm timer will finish the job */
/* Bye, the pm timer will finish the job */
free_irq
(
gp
->
pdev
->
irq
,
(
void
*
)
dev
);
free_irq
(
gp
->
pdev
->
irq
,
(
void
*
)
dev
);
spin_unlock_irq
(
&
gp
->
lock
);
/* Fire the PM timer that will shut us down in about 10 seconds */
/* Fire the PM timer that will shut us down in about 10 seconds */
gp
->
pm_timer
.
expires
=
jiffies
+
10
*
HZ
;
gp
->
pm_timer
.
expires
=
jiffies
+
10
*
HZ
;
add_timer
(
&
gp
->
pm_timer
);
add_timer
(
&
gp
->
pm_timer
);
...
@@ -2245,21 +2423,21 @@ static int gem_suspend(struct pci_dev *pdev, u32 state)
...
@@ -2245,21 +2423,21 @@ static int gem_suspend(struct pci_dev *pdev, u32 state)
/* If the driver is opened, we stop the DMA */
/* If the driver is opened, we stop the DMA */
if
(
gp
->
opened
)
{
if
(
gp
->
opened
)
{
spin_lock_irq
(
&
gp
->
lock
);
/* Stop traffic, mark us closed */
/* Stop traffic, mark us closed */
netif_device_detach
(
dev
);
netif_device_detach
(
dev
);
spin_lock_irq
(
&
gp
->
lock
);
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
writel
(
0xffffffff
,
gp
->
regs
+
GREG_IMASK
);
spin_unlock_irq
(
&
gp
->
lock
);
/* Stop chip */
/* Stop chip */
gem_stop
(
gp
);
gem_stop
(
gp
);
/* Get rid of ring buffers */
/* Get rid of ring buffers */
gem_clean_rings
(
gp
);
gem_clean_rings
(
gp
);
spin_unlock_irq
(
&
gp
->
lock
);
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
disable_irq
(
gp
->
pdev
->
irq
);
disable_irq
(
gp
->
pdev
->
irq
);
}
}
...
@@ -2290,10 +2468,15 @@ static int gem_resume(struct pci_dev *pdev)
...
@@ -2290,10 +2468,15 @@ static int gem_resume(struct pci_dev *pdev)
gem_check_invariants
(
gp
);
gem_check_invariants
(
gp
);
}
}
#endif
/* CONFIG_ALL_PPC */
#endif
/* CONFIG_ALL_PPC */
spin_lock_irq
(
&
gp
->
lock
);
gem_stop
(
gp
);
gem_stop
(
gp
);
gp
->
hw_running
=
1
;
gp
->
hw_running
=
1
;
gem_init_rings
(
gp
,
0
);
gem_init_rings
(
gp
);
gem_init_hw
(
gp
,
1
);
gem_init_hw
(
gp
,
1
);
spin_unlock_irq
(
&
gp
->
lock
);
netif_device_attach
(
dev
);
netif_device_attach
(
dev
);
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
if
(
gp
->
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
enable_irq
(
gp
->
pdev
->
irq
);
enable_irq
(
gp
->
pdev
->
irq
);
...
@@ -2309,6 +2492,8 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
...
@@ -2309,6 +2492,8 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
struct
gem
*
gp
=
dev
->
priv
;
struct
gem
*
gp
=
dev
->
priv
;
struct
net_device_stats
*
stats
=
&
gp
->
net_stats
;
struct
net_device_stats
*
stats
=
&
gp
->
net_stats
;
spin_lock_irq
(
&
gp
->
lock
);
if
(
gp
->
hw_running
)
{
if
(
gp
->
hw_running
)
{
stats
->
rx_crc_errors
+=
readl
(
gp
->
regs
+
MAC_FCSERR
);
stats
->
rx_crc_errors
+=
readl
(
gp
->
regs
+
MAC_FCSERR
);
writel
(
0
,
gp
->
regs
+
MAC_FCSERR
);
writel
(
0
,
gp
->
regs
+
MAC_FCSERR
);
...
@@ -2326,6 +2511,9 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
...
@@ -2326,6 +2511,9 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
writel
(
0
,
gp
->
regs
+
MAC_ECOLL
);
writel
(
0
,
gp
->
regs
+
MAC_ECOLL
);
writel
(
0
,
gp
->
regs
+
MAC_LCOLL
);
writel
(
0
,
gp
->
regs
+
MAC_LCOLL
);
}
}
spin_unlock_irq
(
&
gp
->
lock
);
return
&
gp
->
net_stats
;
return
&
gp
->
net_stats
;
}
}
...
@@ -2338,10 +2526,12 @@ static void gem_set_multicast(struct net_device *dev)
...
@@ -2338,10 +2526,12 @@ static void gem_set_multicast(struct net_device *dev)
if
(
!
gp
->
hw_running
)
if
(
!
gp
->
hw_running
)
return
;
return
;
spin_lock_irq
(
&
gp
->
lock
);
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
rxcfg
=
readl
(
gp
->
regs
+
MAC_RXCFG
);
rxcfg
=
readl
(
gp
->
regs
+
MAC_RXCFG
);
rxcfg_new
=
gem_setup_multicast
(
gp
);
gp
->
mac_rx_cfg
=
rxcfg_new
=
gem_setup_multicast
(
gp
);
writel
(
rxcfg
&
~
MAC_RXCFG_ENAB
,
gp
->
regs
+
MAC_RXCFG
);
writel
(
rxcfg
&
~
MAC_RXCFG_ENAB
,
gp
->
regs
+
MAC_RXCFG
);
while
(
readl
(
gp
->
regs
+
MAC_RXCFG
)
&
MAC_RXCFG_ENAB
)
{
while
(
readl
(
gp
->
regs
+
MAC_RXCFG
)
&
MAC_RXCFG_ENAB
)
{
...
@@ -2355,8 +2545,9 @@ static void gem_set_multicast(struct net_device *dev)
...
@@ -2355,8 +2545,9 @@ static void gem_set_multicast(struct net_device *dev)
writel
(
rxcfg
,
gp
->
regs
+
MAC_RXCFG
);
writel
(
rxcfg
,
gp
->
regs
+
MAC_RXCFG
);
/* Hrm... we may walk on the reset task here... */
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
spin_unlock_irq
(
&
gp
->
lock
);
}
}
/* Eventually add support for changing the advertisement
/* Eventually add support for changing the advertisement
...
@@ -2405,11 +2596,13 @@ static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
...
@@ -2405,11 +2596,13 @@ static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
ecmd
.
phy_address
=
0
;
/* XXX fixed PHYAD */
ecmd
.
phy_address
=
0
;
/* XXX fixed PHYAD */
/* Record PHY settings if HW is on. */
/* Record PHY settings if HW is on. */
spin_lock_irq
(
&
gp
->
lock
);
if
(
gp
->
hw_running
)
{
if
(
gp
->
hw_running
)
{
bmcr
=
phy_read
(
gp
,
MII_BMCR
);
bmcr
=
phy_read
(
gp
,
MII_BMCR
);
gem_read_mii_link_mode
(
gp
,
&
full_duplex
,
&
speed
,
&
pause
);
gem_read_mii_link_mode
(
gp
,
&
full_duplex
,
&
speed
,
&
pause
);
}
else
}
else
bmcr
=
0
;
bmcr
=
0
;
spin_unlock_irq
(
&
gp
->
lock
);
if
(
bmcr
&
BMCR_ANENABLE
)
{
if
(
bmcr
&
BMCR_ANENABLE
)
{
ecmd
.
autoneg
=
AUTONEG_ENABLE
;
ecmd
.
autoneg
=
AUTONEG_ENABLE
;
ecmd
.
speed
=
speed
==
10
?
SPEED_10
:
(
speed
==
1000
?
SPEED_1000
:
SPEED_100
);
ecmd
.
speed
=
speed
==
10
?
SPEED_10
:
(
speed
==
1000
?
SPEED_1000
:
SPEED_100
);
...
@@ -2443,18 +2636,22 @@ static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
...
@@ -2443,18 +2636,22 @@ static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
ecmd
.
duplex
!=
DUPLEX_FULL
)))
ecmd
.
duplex
!=
DUPLEX_FULL
)))
return
-
EINVAL
;
return
-
EINVAL
;
/* Apply settings and restart link process */
/* Apply settings and restart link process. */
if
(
gp
->
hw_running
)
spin_lock_irq
(
&
gp
->
lock
);
del_timer
(
&
gp
->
link_timer
);
gem_begin_auto_negotiation
(
gp
,
&
ecmd
);
gem_begin_auto_negotiation
(
gp
,
&
ecmd
);
spin_unlock_irq
(
&
gp
->
lock
);
return
0
;
return
0
;
case
ETHTOOL_NWAY_RST
:
case
ETHTOOL_NWAY_RST
:
if
((
gp
->
link_cntl
&
BMCR_ANENABLE
)
==
0
)
if
((
gp
->
link_cntl
&
BMCR_ANENABLE
)
==
0
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
gp
->
hw_running
)
del_timer
(
&
gp
->
link_timer
);
/* Restart link process. */
spin_lock_irq
(
&
gp
->
lock
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
spin_unlock_irq
(
&
gp
->
lock
);
return
0
;
return
0
;
case
ETHTOOL_GWOL
:
case
ETHTOOL_GWOL
:
...
@@ -2602,8 +2799,10 @@ static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
...
@@ -2602,8 +2799,10 @@ static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
u32
rom_reg_orig
;
u32
rom_reg_orig
;
void
*
p
;
void
*
p
;
if
(
pdev
->
resource
[
PCI_ROM_RESOURCE
].
parent
==
NULL
)
if
(
pdev
->
resource
[
PCI_ROM_RESOURCE
].
parent
==
NULL
)
{
pci_assign_resource
(
pdev
,
PCI_ROM_RESOURCE
);
if
(
pci_assign_resource
(
pdev
,
PCI_ROM_RESOURCE
)
<
0
)
goto
use_random
;
}
pci_read_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
&
rom_reg_orig
);
pci_read_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
&
rom_reg_orig
);
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
...
@@ -2617,6 +2816,15 @@ static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
...
@@ -2617,6 +2816,15 @@ static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
iounmap
(
p
);
iounmap
(
p
);
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
rom_reg_orig
);
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
rom_reg_orig
);
return
;
use_random:
/* Sun MAC prefix then 3 random bytes. */
dev_addr
[
0
]
=
0x08
;
dev_addr
[
1
]
=
0x00
;
dev_addr
[
2
]
=
0x20
;
get_random_bytes
(
dev_addr
,
3
);
return
;
}
}
#endif
/* not Sparc and not PPC */
#endif
/* not Sparc and not PPC */
...
@@ -2773,12 +2981,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
...
@@ -2773,12 +2981,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if
(
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
if
(
pdev
->
vendor
==
PCI_VENDOR_ID_APPLE
)
gem_apple_powerup
(
gp
);
gem_apple_powerup
(
gp
);
#endif
#endif
spin_lock_irq
(
&
gp
->
lock
);
gem_stop
(
gp
);
gem_stop
(
gp
);
spin_unlock_irq
(
&
gp
->
lock
);
if
(
gem_check_invariants
(
gp
))
if
(
gem_check_invariants
(
gp
))
goto
err_out_iounmap
;
goto
err_out_iounmap
;
spin_lock_irq
(
&
gp
->
lock
);
gp
->
hw_running
=
1
;
gp
->
hw_running
=
1
;
gem_init_phy
(
gp
);
gem_init_phy
(
gp
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
gem_begin_auto_negotiation
(
gp
,
NULL
);
spin_unlock_irq
(
&
gp
->
lock
);
/* It is guarenteed that the returned buffer will be at least
/* It is guarenteed that the returned buffer will be at least
* PAGE_SIZE aligned.
* PAGE_SIZE aligned.
...
...
drivers/net/sungem.h
View file @
a19d03a3
...
@@ -94,6 +94,8 @@
...
@@ -94,6 +94,8 @@
#define GREG_SWRST_TXRST 0x00000001
/* TX Software Reset */
#define GREG_SWRST_TXRST 0x00000001
/* TX Software Reset */
#define GREG_SWRST_RXRST 0x00000002
/* RX Software Reset */
#define GREG_SWRST_RXRST 0x00000002
/* RX Software Reset */
#define GREG_SWRST_RSTOUT 0x00000004
/* Force RST# pin active */
#define GREG_SWRST_RSTOUT 0x00000004
/* Force RST# pin active */
#define GREG_SWRST_CACHESIZE 0x00ff0000
/* RIO only: cache line size */
#define GREG_SWRST_CACHE_SHIFT 16
/* TX DMA Registers */
/* TX DMA Registers */
#define TXDMA_KICK 0x2000UL
/* TX Kick Register */
#define TXDMA_KICK 0x2000UL
/* TX Kick Register */
...
@@ -986,6 +988,9 @@ struct gem {
...
@@ -986,6 +988,9 @@ struct gem {
int
mii_phy_addr
;
int
mii_phy_addr
;
int
gigabit_capable
;
int
gigabit_capable
;
u32
mac_rx_cfg
;
u32
swrst_base
;
/* Autoneg & PHY control */
/* Autoneg & PHY control */
int
link_cntl
;
int
link_cntl
;
int
link_advertise
;
int
link_advertise
;
...
...
drivers/net/sunhme.c
View file @
a19d03a3
...
@@ -34,6 +34,7 @@ static char version[] =
...
@@ -34,6 +34,7 @@ static char version[] =
#include <linux/ethtool.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include <linux/crc32.h>
#include <linux/random.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/io.h>
...
@@ -2929,8 +2930,10 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
...
@@ -2929,8 +2930,10 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
if
(
is_quattro_p
(
pdev
))
if
(
is_quattro_p
(
pdev
))
index
=
PCI_SLOT
(
pdev
->
devfn
);
index
=
PCI_SLOT
(
pdev
->
devfn
);
if
(
pdev
->
resource
[
PCI_ROM_RESOURCE
].
parent
==
NULL
)
if
(
pdev
->
resource
[
PCI_ROM_RESOURCE
].
parent
==
NULL
)
{
pci_assign_resource
(
pdev
,
PCI_ROM_RESOURCE
);
if
(
pci_assign_resource
(
pdev
,
PCI_ROM_RESOURCE
)
<
0
)
goto
use_random
;
}
pci_read_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
&
rom_reg_orig
);
pci_read_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
&
rom_reg_orig
);
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
...
@@ -2944,6 +2947,15 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
...
@@ -2944,6 +2947,15 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
iounmap
(
p
);
iounmap
(
p
);
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
rom_reg_orig
);
pci_write_config_dword
(
pdev
,
pdev
->
rom_base_reg
,
rom_reg_orig
);
return
;
use_random:
/* Sun MAC prefix then 3 random bytes. */
dev_addr
[
0
]
=
0x08
;
dev_addr
[
1
]
=
0x00
;
dev_addr
[
2
]
=
0x20
;
get_random_bytes
(
dev_addr
,
3
);
return
;
}
}
#endif
/* !(__sparc__) */
#endif
/* !(__sparc__) */
...
...
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