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
5dde4af0
Commit
5dde4af0
authored
Jul 01, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[TG3]: Fibre PHY fixes from Sun.
- Support HW autoneg on 5704. - On serdes, no MII reg ioctl support.
parent
5f983ea0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
161 additions
and
47 deletions
+161
-47
drivers/net/tg3.c
drivers/net/tg3.c
+114
-45
drivers/net/tg3.h
drivers/net/tg3.h
+47
-2
No files found.
drivers/net/tg3.c
View file @
5dde4af0
/*
* tg3.c: Broadcom Tigon3 ethernet driver.
*
* Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003
, 2004
David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
*/
#include <linux/config.h>
...
...
@@ -1961,6 +1962,67 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,
return
ret
;
}
static
int
fiber_autoneg
(
struct
tg3
*
tp
,
u32
*
flags
)
{
int
res
=
0
;
if
(
tp
->
tg3_flags2
&
TG3_FLG2_HW_AUTONEG
)
{
u32
dig_status
;
dig_status
=
tr32
(
SG_DIG_STATUS
);
*
flags
=
0
;
if
(
dig_status
&
SG_DIG_PARTNER_ASYM_PAUSE
)
*
flags
|=
MR_LP_ADV_ASYM_PAUSE
;
if
(
dig_status
&
SG_DIG_PARTNER_PAUSE_CAPABLE
)
*
flags
|=
MR_LP_ADV_SYM_PAUSE
;
if
((
dig_status
&
SG_DIG_AUTONEG_COMPLETE
)
&&
!
(
dig_status
&
(
SG_DIG_AUTONEG_ERROR
|
SG_DIG_PARTNER_FAULT_MASK
)))
res
=
1
;
}
else
{
struct
tg3_fiber_aneginfo
aninfo
;
int
status
=
ANEG_FAILED
;
unsigned
int
tick
;
u32
tmp
;
tw32_f
(
MAC_TX_AUTO_NEG
,
0
);
tmp
=
tp
->
mac_mode
&
~
MAC_MODE_PORT_MODE_MASK
;
tw32_f
(
MAC_MODE
,
tmp
|
MAC_MODE_PORT_MODE_GMII
);
udelay
(
40
);
tw32_f
(
MAC_MODE
,
tp
->
mac_mode
|
MAC_MODE_SEND_CONFIGS
);
udelay
(
40
);
memset
(
&
aninfo
,
0
,
sizeof
(
aninfo
));
aninfo
.
flags
|=
MR_AN_ENABLE
;
aninfo
.
state
=
ANEG_STATE_UNKNOWN
;
aninfo
.
cur_time
=
0
;
tick
=
0
;
while
(
++
tick
<
195000
)
{
status
=
tg3_fiber_aneg_smachine
(
tp
,
&
aninfo
);
if
(
status
==
ANEG_DONE
||
status
==
ANEG_FAILED
)
break
;
udelay
(
1
);
}
tp
->
mac_mode
&=
~
MAC_MODE_SEND_CONFIGS
;
tw32_f
(
MAC_MODE
,
tp
->
mac_mode
);
udelay
(
40
);
*
flags
=
aninfo
.
flags
;
if
(
status
==
ANEG_DONE
&&
(
aninfo
.
flags
&
(
MR_AN_COMPLETE
|
MR_LINK_OK
|
MR_LP_ADV_FULL_DUPLEX
)))
res
=
1
;
}
return
res
;
}
static
int
tg3_setup_fiber_phy
(
struct
tg3
*
tp
,
int
force_reset
)
{
u32
orig_pause_cfg
;
...
...
@@ -1980,6 +2042,20 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
tw32_f
(
MAC_MODE
,
tp
->
mac_mode
);
udelay
(
40
);
if
(
tp
->
tg3_flags2
&
TG3_FLG2_HW_AUTONEG
)
{
/* Allow time for the hardware to auto-negotiate (195ms) */
unsigned
int
tick
=
0
;
while
(
++
tick
<
195000
)
{
if
(
tr32
(
SG_DIG_STATUS
)
&
SG_DIG_AUTONEG_COMPLETE
)
break
;
udelay
(
1
);
}
if
(
tick
>=
195000
)
printk
(
KERN_INFO
PFX
"%s: HW autoneg failed !
\n
"
,
tp
->
dev
->
name
);
}
/* Reset when initting first time or we have a link. */
if
(
!
(
tp
->
tg3_flags
&
TG3_FLAG_INIT_COMPLETE
)
||
(
tr32
(
MAC_STATUS
)
&
MAC_STATUS_PCS_SYNCED
))
{
...
...
@@ -2031,53 +2107,18 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
udelay
(
40
);
current_link_up
=
0
;
if
(
tr32
(
MAC_STATUS
)
&
MAC_STATUS_PCS_SYNCED
)
{
if
(
tp
->
link_config
.
autoneg
==
AUTONEG_ENABLE
&&
!
(
tp
->
tg3_flags
&
TG3_FLAG_GOT_SERDES_FLOWCTL
))
{
struct
tg3_fiber_aneginfo
aninfo
;
int
status
=
ANEG_FAILED
;
unsigned
int
tick
;
u32
tmp
;
memset
(
&
aninfo
,
0
,
sizeof
(
aninfo
));
aninfo
.
flags
|=
(
MR_AN_ENABLE
);
tw32
(
MAC_TX_AUTO_NEG
,
0
);
tmp
=
tp
->
mac_mode
&
~
MAC_MODE_PORT_MODE_MASK
;
tw32_f
(
MAC_MODE
,
tmp
|
MAC_MODE_PORT_MODE_GMII
);
udelay
(
40
);
tw32_f
(
MAC_MODE
,
tp
->
mac_mode
|
MAC_MODE_SEND_CONFIGS
);
udelay
(
40
);
aninfo
.
state
=
ANEG_STATE_UNKNOWN
;
aninfo
.
cur_time
=
0
;
tick
=
0
;
while
(
++
tick
<
195000
)
{
status
=
tg3_fiber_aneg_smachine
(
tp
,
&
aninfo
);
if
(
status
==
ANEG_DONE
||
status
==
ANEG_FAILED
)
break
;
udelay
(
1
);
}
tp
->
mac_mode
&=
~
MAC_MODE_SEND_CONFIGS
;
tw32_f
(
MAC_MODE
,
tp
->
mac_mode
);
udelay
(
40
);
if
(
status
==
ANEG_DONE
&&
(
aninfo
.
flags
&
(
MR_AN_COMPLETE
|
MR_LINK_OK
|
MR_LP_ADV_FULL_DUPLEX
)))
{
if
(
tr32
(
MAC_STATUS
)
&
MAC_STATUS_PCS_SYNCED
)
{
if
(
tp
->
link_config
.
autoneg
==
AUTONEG_ENABLE
)
{
u32
flags
;
if
(
fiber_autoneg
(
tp
,
&
flags
))
{
u32
local_adv
,
remote_adv
;
local_adv
=
ADVERTISE_PAUSE_CAP
;
remote_adv
=
0
;
if
(
aninfo
.
flags
&
MR_LP_ADV_SYM_PAUSE
)
remote_adv
|=
LPA_PAUSE_CAP
;
if
(
aninfo
.
flags
&
MR_LP_ADV_ASYM_PAUSE
)
if
(
flags
&
MR_LP_ADV_SYM_PAUSE
)
remote_adv
|=
LPA_PAUSE_CAP
;
if
(
flags
&
MR_LP_ADV_ASYM_PAUSE
)
remote_adv
|=
LPA_PAUSE_ASYM
;
tg3_setup_flow_control
(
tp
,
local_adv
,
remote_adv
);
...
...
@@ -2104,8 +2145,10 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
}
else
{
/* Forcing 1000FD link up. */
current_link_up
=
1
;
tp
->
tg3_flags
|=
TG3_FLAG_GOT_SERDES_FLOWCTL
;
}
}
}
else
tp
->
tg3_flags
&=
~
TG3_FLAG_GOT_SERDES_FLOWCTL
;
tp
->
mac_mode
&=
~
MAC_MODE_LINK_POLARITY
;
tw32_f
(
MAC_MODE
,
tp
->
mac_mode
);
...
...
@@ -5203,6 +5246,26 @@ static int tg3_reset_hw(struct tg3 *tp)
*/
tw32_f
(
MAC_LOW_WMARK_MAX_RX_FRAME
,
2
);
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
&&
tp
->
phy_id
==
PHY_ID_SERDES
)
{
/* Enable hardware link auto-negotiation */
u32
digctrl
,
txctrl
;
digctrl
=
SG_DIG_USING_HW_AUTONEG
|
SG_DIG_CRC16_CLEAR_N
|
SG_DIG_LOCAL_DUPLEX_STATUS
|
SG_DIG_LOCAL_LINK_STATUS
|
(
2
<<
SG_DIG_SPEED_STATUS_SHIFT
)
|
SG_DIG_FIBER_MODE
|
SG_DIG_GBIC_ENABLE
;
txctrl
=
tr32
(
MAC_SERDES_CFG
);
tw32_f
(
MAC_SERDES_CFG
,
txctrl
|
MAC_SERDES_CFG_EDGE_SELECT
);
tw32_f
(
SG_DIG_CTRL
,
digctrl
|
SG_DIG_SOFT_RESET
);
tr32
(
SG_DIG_CTRL
);
udelay
(
5
);
tw32_f
(
SG_DIG_CTRL
,
digctrl
);
tp
->
tg3_flags2
|=
TG3_FLG2_HW_AUTONEG
;
}
err
=
tg3_setup_phy
(
tp
,
1
);
if
(
err
)
return
err
;
...
...
@@ -6536,6 +6599,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case
SIOCGMIIREG
:
{
u32
mii_regval
;
if
(
tp
->
phy_id
==
PHY_ID_SERDES
)
break
;
/* We have no PHY */
spin_lock_irq
(
&
tp
->
lock
);
err
=
tg3_readphy
(
tp
,
data
->
reg_num
&
0x1f
,
&
mii_regval
);
spin_unlock_irq
(
&
tp
->
lock
);
...
...
@@ -6546,6 +6612,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
case
SIOCSMIIREG
:
if
(
tp
->
phy_id
==
PHY_ID_SERDES
)
break
;
/* We have no PHY */
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
...
...
drivers/net/tg3.h
View file @
5dde4af0
/* $Id: tg3.h,v 1.37.2.32 2002/03/11 12:18:18 davem Exp $
* tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
*
* Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002
, 2003, 2004
David S. Miller (davem@redhat.com)
* Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
*/
#ifndef _T3_H
...
...
@@ -116,6 +117,7 @@
#define CHIPREV_ID_5704_A0 0x2000
#define CHIPREV_ID_5704_A1 0x2001
#define CHIPREV_ID_5704_A2 0x2002
#define CHIPREV_ID_5704_A3 0x2003
#define CHIPREV_ID_5705_A0 0x3000
#define CHIPREV_ID_5705_A1 0x3001
#define CHIPREV_ID_5705_A2 0x3002
...
...
@@ -518,8 +520,50 @@
#define MAC_EXTADDR_11_HIGH 0x00000588
#define MAC_EXTADDR_11_LOW 0x0000058c
#define MAC_SERDES_CFG 0x00000590
#define MAC_SERDES_CFG_EDGE_SELECT 0x00001000
#define MAC_SERDES_STAT 0x00000594
/* 0x598 --> 0x600 unused */
/* 0x598 --> 0x5b0 unused */
#define SG_DIG_CTRL 0x000005b0
#define SG_DIG_USING_HW_AUTONEG 0x80000000
#define SG_DIG_SOFT_RESET 0x40000000
#define SG_DIG_DISABLE_LINKRDY 0x20000000
#define SG_DIG_CRC16_CLEAR_N 0x01000000
#define SG_DIG_EN10B 0x00800000
#define SG_DIG_CLEAR_STATUS 0x00400000
#define SG_DIG_LOCAL_DUPLEX_STATUS 0x00200000
#define SG_DIG_LOCAL_LINK_STATUS 0x00100000
#define SG_DIG_SPEED_STATUS_MASK 0x000c0000
#define SG_DIG_SPEED_STATUS_SHIFT 18
#define SG_DIG_JUMBO_PACKET_DISABLE 0x00020000
#define SG_DIG_RESTART_AUTONEG 0x00010000
#define SG_DIG_FIBER_MODE 0x00008000
#define SG_DIG_REMOTE_FAULT_MASK 0x00006000
#define SG_DIG_PAUSE_MASK 0x00001800
#define SG_DIG_GBIC_ENABLE 0x00000400
#define SG_DIG_CHECK_END_ENABLE 0x00000200
#define SG_DIG_SGMII_AUTONEG_TIMER 0x00000100
#define SG_DIG_CLOCK_PHASE_SELECT 0x00000080
#define SG_DIG_GMII_INPUT_SELECT 0x00000040
#define SG_DIG_MRADV_CRC16_SELECT 0x00000020
#define SG_DIG_COMMA_DETECT_ENABLE 0x00000010
#define SG_DIG_AUTONEG_TIMER_REDUCE 0x00000008
#define SG_DIG_AUTONEG_LOW_ENABLE 0x00000004
#define SG_DIG_REMOTE_LOOPBACK 0x00000002
#define SG_DIG_LOOPBACK 0x00000001
#define SG_DIG_STATUS 0x000005b4
#define SG_DIG_CRC16_BUS_MASK 0xffff0000
#define SG_DIG_PARTNER_FAULT_MASK 0x00600000
/* If !MRADV_CRC16_SELECT */
#define SG_DIG_PARTNER_ASYM_PAUSE 0x00100000
/* If !MRADV_CRC16_SELECT */
#define SG_DIG_PARTNER_PAUSE_CAPABLE 0x00080000
/* If !MRADV_CRC16_SELECT */
#define SG_DIG_PARTNER_HALF_DUPLEX 0x00040000
/* If !MRADV_CRC16_SELECT */
#define SG_DIG_PARTNER_FULL_DUPLEX 0x00020000
/* If !MRADV_CRC16_SELECT */
#define SG_DIG_PARTNER_NEXT_PAGE 0x00010000
/* If !MRADV_CRC16_SELECT */
#define SG_DIG_AUTONEG_STATE_MASK 0x00000ff0
#define SG_DIG_COMMA_DETECTOR 0x00000008
#define SG_DIG_MAC_ACK_STATUS 0x00000004
#define SG_DIG_AUTONEG_COMPLETE 0x00000002
#define SG_DIG_AUTONEG_ERROR 0x00000001
/* 0x5b8 --> 0x600 unused */
#define MAC_TX_MAC_STATE_BASE 0x00000600
/* 16 bytes */
#define MAC_RX_MAC_STATE_BASE 0x00000610
/* 20 bytes */
/* 0x624 --> 0x800 unused */
...
...
@@ -2044,6 +2088,7 @@ struct tg3 {
#define TG3_FLG2_PHY_BER_BUG 0x00000100
#define TG3_FLG2_PCI_EXPRESS 0x00000200
#define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400
#define TG3_FLG2_HW_AUTONEG 0x00000800
u32
split_mode_max_reqs
;
#define SPLIT_MODE_5704_MAX_REQ 3
...
...
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