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
nexedi
linux
Commits
245ac873
Commit
245ac873
authored
Jun 27, 2005
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge upstream net/ieee80211.h changes into 'ieee80211' branch.
parents
716b4330
a5fe736e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
934 additions
and
1375 deletions
+934
-1375
drivers/net/skge.c
drivers/net/skge.c
+829
-881
drivers/net/skge.h
drivers/net/skge.h
+104
-482
include/linux/etherdevice.h
include/linux/etherdevice.h
+1
-1
include/net/ieee80211.h
include/net/ieee80211.h
+0
-11
No files found.
drivers/net/skge.c
View file @
245ac873
...
...
@@ -7,7 +7,7 @@
* of the original driver such as link fail-over and link management because
* those should be done at higher levels.
*
* Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
* Copyright (C) 2004,
2005
Stephen Hemminger <shemminger@osdl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -42,19 +42,20 @@
#include "skge.h"
#define DRV_NAME "skge"
#define DRV_VERSION "0.
6
"
#define DRV_VERSION "0.
7
"
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
#define DEFAULT_RX_RING_SIZE 512
#define MAX_TX_RING_SIZE 1024
#define MAX_RX_RING_SIZE 4096
#define RX_COPY_THRESHOLD 128
#define RX_BUF_SIZE 1536
#define PHY_RETRIES 1000
#define ETH_JUMBO_MTU 9000
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define BLINK_HZ (HZ/4)
#define LINK_POLL_HZ (HZ/10)
MODULE_DESCRIPTION
(
"SysKonnect Gigabit Ethernet driver"
);
MODULE_AUTHOR
(
"Stephen Hemminger <shemminger@osdl.org>"
);
...
...
@@ -70,28 +71,17 @@ module_param(debug, int, 0);
MODULE_PARM_DESC
(
debug
,
"Debug level (0=none,...,16=all)"
);
static
const
struct
pci_device_id
skge_id_table
[]
=
{
{
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940B
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_GE
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_YU
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_SYSKONNECT
,
0x9E00
,
/* SK-9Exx */
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_DLINK
,
PCI_DEVICE_ID_DLINK_DGE510T
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_MARVELL
,
0x4320
,
/* Gigabit Ethernet Controller */
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_MARVELL
,
0x5005
,
/* Marvell (11ab), Belkin */
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_CNET
,
PCI_DEVICE_ID_CNET_GIGACARD
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1032
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1064
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940B
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_GE
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_YU
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_SYSKONNECT
,
0x9E00
)
},
/* SK-9Exx */
{
PCI_DEVICE
(
PCI_VENDOR_ID_DLINK
,
PCI_DEVICE_ID_DLINK_DGE510T
),
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x4320
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5005
)
},
/* Belkin */
{
PCI_DEVICE
(
PCI_VENDOR_ID_CNET
,
PCI_DEVICE_ID_CNET_GIGACARD
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1032
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1064
)
},
{
0
}
};
MODULE_DEVICE_TABLE
(
pci
,
skge_id_table
);
...
...
@@ -99,19 +89,22 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
static
int
skge_up
(
struct
net_device
*
dev
);
static
int
skge_down
(
struct
net_device
*
dev
);
static
void
skge_tx_clean
(
struct
skge_port
*
skge
);
static
void
skge_
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
skge_
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
genesis_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
);
static
void
yukon_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
);
static
void
yukon_init
(
struct
skge_hw
*
hw
,
int
port
);
static
void
yukon_reset
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_reset
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_link_up
(
struct
skge_port
*
skge
);
/* Avoid conditionals by using array */
static
const
int
txqaddr
[]
=
{
Q_XA1
,
Q_XA2
};
static
const
int
rxqaddr
[]
=
{
Q_R1
,
Q_R2
};
static
const
u32
rxirqmask
[]
=
{
IS_R1_F
,
IS_R2_F
};
static
const
u32
txirqmask
[]
=
{
IS_XA1_F
,
IS_XA2_F
};
static
const
u32
portirqmask
[]
=
{
IS_PORT_1
,
IS_PORT_2
};
/* Don't need to look at whole 16K.
* last interesting register is descriptor poll timer.
...
...
@@ -154,7 +147,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
static
int
wol_supported
(
const
struct
skge_hw
*
hw
)
{
return
!
((
hw
->
chip_id
==
CHIP_ID_GENESIS
||
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
chip_rev
(
hw
)
==
0
)));
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
hw
->
chip_rev
==
0
)));
}
static
void
skge_get_wol
(
struct
net_device
*
dev
,
struct
ethtool_wolinfo
*
wol
)
...
...
@@ -170,7 +163,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_hw
*
hw
=
skge
->
hw
;
if
(
wol
->
wolopts
!=
WAKE_MAGIC
&&
wol
->
wolopts
!=
0
)
if
(
wol
->
wolopts
!=
WAKE_MAGIC
&&
wol
->
wolopts
!=
0
)
return
-
EOPNOTSUPP
;
if
(
wol
->
wolopts
==
WAKE_MAGIC
&&
!
wol_supported
(
hw
))
...
...
@@ -190,22 +183,15 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return
0
;
}
static
int
skge_get_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
ecmd
)
/* Determine supported/adverised modes based on hardware.
* Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
*/
static
u32
skge_supported_modes
(
const
struct
skge_hw
*
hw
)
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_hw
*
hw
=
skge
->
hw
;
ecmd
->
transceiver
=
XCVR_INTERNAL
;
u32
supported
;
if
(
iscopper
(
hw
))
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
ecmd
->
supported
=
SUPPORTED_1000baseT_Full
|
SUPPORTED_1000baseT_Half
|
SUPPORTED_Autoneg
|
SUPPORTED_TP
;
else
{
ecmd
->
supported
=
SUPPORTED_10baseT_Half
supported
=
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
...
...
@@ -213,23 +199,35 @@ static int skge_get_settings(struct net_device *dev,
|
SUPPORTED_1000baseT_Full
|
SUPPORTED_Autoneg
|
SUPPORTED_TP
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON
)
ecmd
->
supported
&=
~
SUPPORTED_1000baseT_Half
;
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
supported
&=
~
(
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
);
else
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
ecmd
->
supported
&=
~
(
SUPPORTED_1000baseT_Half
|
SUPPORTED_1000baseT_Full
);
}
else
if
(
hw
->
chip_id
==
CHIP_ID_YUKON
)
supported
&=
~
SUPPORTED_1000baseT_Half
;
}
else
supported
=
SUPPORTED_1000baseT_Full
|
SUPPORTED_FIBRE
|
SUPPORTED_Autoneg
;
return
supported
;
}
static
int
skge_get_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
ecmd
)
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_hw
*
hw
=
skge
->
hw
;
ecmd
->
transceiver
=
XCVR_INTERNAL
;
ecmd
->
supported
=
skge_supported_modes
(
hw
);
if
(
iscopper
(
hw
))
{
ecmd
->
port
=
PORT_TP
;
ecmd
->
phy_address
=
hw
->
phy_addr
;
}
else
{
ecmd
->
supported
=
SUPPORTED_1000baseT_Full
|
SUPPORTED_FIBRE
|
SUPPORTED_Autoneg
;
}
else
ecmd
->
port
=
PORT_FIBRE
;
}
ecmd
->
advertising
=
skge
->
advertising
;
ecmd
->
autoneg
=
skge
->
autoneg
;
...
...
@@ -238,65 +236,57 @@ static int skge_get_settings(struct net_device *dev,
return
0
;
}
static
u32
skge_modes
(
const
struct
skge_hw
*
hw
)
{
u32
modes
=
ADVERTISED_Autoneg
|
ADVERTISED_1000baseT_Full
|
ADVERTISED_1000baseT_Half
|
ADVERTISED_100baseT_Full
|
ADVERTISED_100baseT_Half
|
ADVERTISED_10baseT_Full
|
ADVERTISED_10baseT_Half
;
if
(
iscopper
(
hw
))
{
modes
|=
ADVERTISED_TP
;
switch
(
hw
->
chip_id
)
{
case
CHIP_ID_GENESIS
:
modes
&=
~
(
ADVERTISED_100baseT_Full
|
ADVERTISED_100baseT_Half
|
ADVERTISED_10baseT_Full
|
ADVERTISED_10baseT_Half
);
break
;
case
CHIP_ID_YUKON
:
modes
&=
~
ADVERTISED_1000baseT_Half
;
break
;
case
CHIP_ID_YUKON_FE
:
modes
&=
~
(
ADVERTISED_1000baseT_Half
|
ADVERTISED_1000baseT_Full
);
break
;
}
}
else
{
modes
|=
ADVERTISED_FIBRE
;
modes
&=
~
ADVERTISED_1000baseT_Half
;
}
return
modes
;
}
static
int
skge_set_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
ecmd
)
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
const
struct
skge_hw
*
hw
=
skge
->
hw
;
u32
supported
=
skge_supported_modes
(
hw
);
if
(
ecmd
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
ecmd
->
advertising
&
skge_modes
(
hw
))
return
-
EINVAL
;
ecmd
->
advertising
=
supported
;
skge
->
duplex
=
-
1
;
skge
->
speed
=
-
1
;
}
else
{
u32
setting
;
switch
(
ecmd
->
speed
)
{
case
SPEED_1000
:
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
setting
=
SUPPORTED_1000baseT_Full
;
else
if
(
ecmd
->
duplex
==
DUPLEX_HALF
)
setting
=
SUPPORTED_1000baseT_Half
;
else
return
-
EINVAL
;
break
;
case
SPEED_100
:
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
setting
=
SUPPORTED_100baseT_Full
;
else
if
(
ecmd
->
duplex
==
DUPLEX_HALF
)
setting
=
SUPPORTED_100baseT_Half
;
else
return
-
EINVAL
;
break
;
case
SPEED_10
:
if
(
iscopper
(
hw
)
||
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
setting
=
SUPPORTED_10baseT_Full
;
else
if
(
ecmd
->
duplex
==
DUPLEX_HALF
)
setting
=
SUPPORTED_10baseT_Half
;
else
return
-
EINVAL
;
break
;
default:
return
-
EINVAL
;
}
}
skge
->
autoneg
=
ecmd
->
autoneg
;
if
((
setting
&
supported
)
==
0
)
return
-
EINVAL
;
skge
->
speed
=
ecmd
->
speed
;
skge
->
duplex
=
ecmd
->
duplex
;
}
skge
->
autoneg
=
ecmd
->
autoneg
;
skge
->
advertising
=
ecmd
->
advertising
;
if
(
netif_running
(
dev
))
{
...
...
@@ -393,7 +383,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
int
i
;
switch
(
stringset
)
{
switch
(
stringset
)
{
case
ETH_SS_STATS
:
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
memcpy
(
data
+
i
*
ETH_GSTRING_LEN
,
...
...
@@ -511,14 +501,6 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data)
return
0
;
}
/* Only Yukon II supports TSO (not implemented yet) */
static
int
skge_set_tso
(
struct
net_device
*
dev
,
u32
data
)
{
if
(
data
)
return
-
EOPNOTSUPP
;
return
0
;
}
static
void
skge_get_pauseparam
(
struct
net_device
*
dev
,
struct
ethtool_pauseparam
*
ecmd
)
{
...
...
@@ -540,9 +522,9 @@ static int skge_set_pauseparam(struct net_device *dev,
skge
->
autoneg
=
ecmd
->
autoneg
;
if
(
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
else
if
(
ecmd
->
rx_pause
&&
!
ecmd
->
tx_pause
)
else
if
(
ecmd
->
rx_pause
&&
!
ecmd
->
tx_pause
)
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
else
if
(
!
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
else
if
(
!
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
else
skge
->
flow_control
=
FLOW_MODE_NONE
;
...
...
@@ -559,8 +541,6 @@ static inline u32 hwkhz(const struct skge_hw *hw)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
return
53215
;
/* or: 53.125 MHz */
else
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_EC
)
return
125000
;
/* or: 125.000 MHz */
else
return
78215
;
/* or: 78.125 MHz */
}
...
...
@@ -643,30 +623,18 @@ static int skge_set_coalesce(struct net_device *dev,
static
void
skge_led_on
(
struct
skge_hw
*
hw
,
int
port
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_ON
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_TST
),
LED_T_ON
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_VAL
),
100
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_TST
),
LED_T_ON
);
skge_write32
(
hw
,
SK_REG
(
port
,
RX_LED_VAL
),
100
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
switch
(
hw
->
phy_type
)
{
case
SK_PHY_BCOM
:
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_ON
);
break
;
case
SK_PHY_LONE
:
skge_xm_phy_write
(
hw
,
port
,
PHY_LONE_LED_CFG
,
0x0800
);
break
;
default:
skge_write8
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_TST
),
LED_T_ON
);
skge_write32
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_VAL
),
100
);
skge_write8
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_CTRL
),
LED_START
);
}
/* For Broadcom Phy only */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_ON
);
}
else
{
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
PHY_M_LED_MO_DUP
(
MO_LED_ON
)
|
PHY_M_LED_MO_10
(
MO_LED_ON
)
|
PHY_M_LED_MO_100
(
MO_LED_ON
)
|
...
...
@@ -678,28 +646,17 @@ static void skge_led_on(struct skge_hw *hw, int port)
static
void
skge_led_off
(
struct
skge_hw
*
hw
,
int
port
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_OFF
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_OFF
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_OFF
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_VAL
),
0
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_T_OFF
);
skge_write32
(
hw
,
SK_REG
(
port
,
RX_LED_VAL
),
0
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_T_OFF
);
switch
(
hw
->
phy_type
)
{
case
SK_PHY_BCOM
:
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_OFF
);
break
;
case
SK_PHY_LONE
:
skge_xm_phy_write
(
hw
,
port
,
PHY_LONE_LED_CFG
,
PHY_L_LC_LEDT
);
break
;
default:
skge_write32
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_VAL
),
0
);
skge_write8
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_CTRL
),
LED_T_OFF
);
}
/* Broadcom only */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_OFF
);
}
else
{
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
PHY_M_LED_MO_DUP
(
MO_LED_OFF
)
|
PHY_M_LED_MO_10
(
MO_LED_OFF
)
|
PHY_M_LED_MO_100
(
MO_LED_OFF
)
|
...
...
@@ -730,7 +687,7 @@ static int skge_phys_id(struct net_device *dev, u32 data)
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
if
(
!
data
||
data
>
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
))
if
(
!
data
||
data
>
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
))
data
=
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
);
/* start blinking */
...
...
@@ -763,8 +720,6 @@ static struct ethtool_ops skge_ethtool_ops = {
.
set_pauseparam
=
skge_set_pauseparam
,
.
get_coalesce
=
skge_get_coalesce
,
.
set_coalesce
=
skge_set_coalesce
,
.
get_tso
=
ethtool_op_get_tso
,
.
set_tso
=
skge_set_tso
,
.
get_sg
=
ethtool_op_get_sg
,
.
set_sg
=
skge_set_sg
,
.
get_tx_csum
=
ethtool_op_get_tx_csum
,
...
...
@@ -793,6 +748,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
for
(
i
=
0
,
e
=
ring
->
start
,
d
=
vaddr
;
i
<
ring
->
count
;
i
++
,
e
++
,
d
++
)
{
e
->
desc
=
d
;
e
->
skb
=
NULL
;
if
(
i
==
ring
->
count
-
1
)
{
e
->
next
=
ring
->
start
;
d
->
next_offset
=
base
;
...
...
@@ -806,24 +762,23 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
return
0
;
}
/* Setup buffer for receiving */
static
inline
int
skge_rx_alloc
(
struct
skge_port
*
skge
,
struct
skge_element
*
e
)
static
struct
sk_buff
*
skge_rx_alloc
(
struct
net_device
*
dev
,
unsigned
int
size
)
{
unsigned
long
bufsize
=
skge
->
netdev
->
mtu
+
ETH_HLEN
;
/* VLAN? */
struct
skge_rx_desc
*
rd
=
e
->
desc
;
struct
sk_buff
*
skb
;
u64
map
;
struct
sk_buff
*
skb
=
dev_alloc_skb
(
size
);
skb
=
dev_alloc_skb
(
bufsize
+
NET_IP_ALIGN
);
if
(
unlikely
(
!
skb
))
{
printk
(
KERN_DEBUG
PFX
"%s: out of memory for receive
\n
"
,
skge
->
netdev
->
name
);
return
-
ENOMEM
;
if
(
likely
(
skb
))
{
skb
->
dev
=
dev
;
skb_reserve
(
skb
,
NET_IP_ALIGN
);
}
return
skb
;
}
skb
->
dev
=
skge
->
netdev
;
skb_reserve
(
skb
,
NET_IP_ALIGN
);
/* Allocate and setup a new buffer for receiving */
static
void
skge_rx_setup
(
struct
skge_port
*
skge
,
struct
skge_element
*
e
,
struct
sk_buff
*
skb
,
unsigned
int
bufsize
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
u64
map
;
map
=
pci_map_single
(
skge
->
hw
->
pdev
,
skb
->
data
,
bufsize
,
PCI_DMA_FROMDEVICE
);
...
...
@@ -841,20 +796,37 @@ static inline int skge_rx_alloc(struct skge_port *skge,
rd
->
control
=
BMU_OWN
|
BMU_STF
|
BMU_IRQ_EOF
|
BMU_TCP_CHECK
|
bufsize
;
pci_unmap_addr_set
(
e
,
mapaddr
,
map
);
pci_unmap_len_set
(
e
,
maplen
,
bufsize
);
return
0
;
}
/* Free all unused buffers in receive ring, assumes receiver stopped */
/* Resume receiving using existing skb,
* Note: DMA address is not changed by chip.
* MTU not changed while receiver active.
*/
static
void
skge_rx_reuse
(
struct
skge_element
*
e
,
unsigned
int
size
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
rd
->
csum2
=
0
;
rd
->
csum2_start
=
ETH_HLEN
;
wmb
();
rd
->
control
=
BMU_OWN
|
BMU_STF
|
BMU_IRQ_EOF
|
BMU_TCP_CHECK
|
size
;
}
/* Free all buffers in receive ring, assumes receiver stopped */
static
void
skge_rx_clean
(
struct
skge_port
*
skge
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_ring
*
ring
=
&
skge
->
rx_ring
;
struct
skge_element
*
e
;
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
;
e
=
e
->
next
)
{
e
=
ring
->
start
;
do
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
rd
->
control
=
0
;
if
(
e
->
skb
)
{
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_len
(
e
,
maplen
),
...
...
@@ -862,34 +834,31 @@ static void skge_rx_clean(struct skge_port *skge)
dev_kfree_skb
(
e
->
skb
);
e
->
skb
=
NULL
;
}
ring
->
to_clean
=
e
;
}
while
((
e
=
e
->
next
)
!=
ring
->
start
)
;
}
/* Allocate buffers for receive ring
* For receive: to_use is refill location
* to_clean is next received frame.
*
* if (to_use == to_clean)
* then ring all frames in ring need buffers
* if (to_use->next == to_clean)
* then ring all frames in ring have buffers
* For receive: to_clean is next received frame.
*/
static
int
skge_rx_fill
(
struct
skge_port
*
skge
)
{
struct
skge_ring
*
ring
=
&
skge
->
rx_ring
;
struct
skge_element
*
e
;
int
ret
=
0
;
unsigned
int
bufsize
=
skge
->
rx_buf_size
;
for
(
e
=
ring
->
to_use
;
e
->
next
!=
ring
->
to_clean
;
e
=
e
->
next
)
{
if
(
skge_rx_alloc
(
skge
,
e
))
{
ret
=
1
;
break
;
}
e
=
ring
->
start
;
do
{
struct
sk_buff
*
skb
=
skge_rx_alloc
(
skge
->
netdev
,
bufsize
);
}
ring
->
to_use
=
e
;
if
(
!
skb
)
return
-
ENOMEM
;
skge_rx_setup
(
skge
,
e
,
skb
,
bufsize
);
}
while
(
(
e
=
e
->
next
)
!=
ring
->
start
);
return
ret
;
ring
->
to_clean
=
ring
->
start
;
return
0
;
}
static
void
skge_link_up
(
struct
skge_port
*
skge
)
...
...
@@ -919,17 +888,18 @@ static void skge_link_down(struct skge_port *skge)
printk
(
KERN_INFO
PFX
"%s: Link is down.
\n
"
,
skge
->
netdev
->
name
);
}
static
u16
skge_xm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
static
u16
xm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
{
int
i
;
u16
v
;
skge_xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
v
=
skge_xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
{
xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
v
=
xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
/* Need to wait for external PHY */
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
if
(
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
if
(
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_RDY
)
goto
ready
;
}
...
...
@@ -938,31 +908,30 @@ static u16 skge_xm_phy_read(struct skge_hw *hw, int port, u16 reg)
hw
->
dev
[
port
]
->
name
);
return
0
;
ready:
v
=
skge_xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
}
v
=
xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
return
v
;
}
static
void
skge_
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
static
void
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
{
int
i
;
skge_
xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
if
(
!
(
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
if
(
!
(
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
goto
ready
;
cpu_relax
(
);
udelay
(
1
);
}
printk
(
KERN_WARNING
PFX
"%s: phy write failed to come ready
\n
"
,
hw
->
dev
[
port
]
->
name
);
ready:
skge_
xm_write16
(
hw
,
port
,
XM_PHY_DATA
,
val
);
xm_write16
(
hw
,
port
,
XM_PHY_DATA
,
val
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
if
(
!
(
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
if
(
!
(
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
return
;
}
printk
(
KERN_WARNING
PFX
"%s: phy write timed out
\n
"
,
...
...
@@ -999,34 +968,112 @@ static void genesis_init(struct skge_hw *hw)
static
void
genesis_reset
(
struct
skge_hw
*
hw
,
int
port
)
{
int
i
;
u64
zero
=
0
;
const
u8
zero
[
8
]
=
{
0
};
/* reset the statistics module */
skge_
xm_write32
(
hw
,
port
,
XM_GP_PORT
,
XM_GP_RES_STAT
);
skge_
xm_write16
(
hw
,
port
,
XM_IMSK
,
0xffff
);
/* disable XMAC IRQs */
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
0
);
/* clear Mode Reg */
skge_
xm_write16
(
hw
,
port
,
XM_TX_CMD
,
0
);
/* reset TX CMD Reg */
skge_
xm_write16
(
hw
,
port
,
XM_RX_CMD
,
0
);
/* reset RX CMD Reg */
xm_write32
(
hw
,
port
,
XM_GP_PORT
,
XM_GP_RES_STAT
);
xm_write16
(
hw
,
port
,
XM_IMSK
,
0xffff
);
/* disable XMAC IRQs */
xm_write32
(
hw
,
port
,
XM_MODE
,
0
);
/* clear Mode Reg */
xm_write16
(
hw
,
port
,
XM_TX_CMD
,
0
);
/* reset TX CMD Reg */
xm_write16
(
hw
,
port
,
XM_RX_CMD
,
0
);
/* reset RX CMD Reg */
/* disable all PHY IRQs */
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
skge_xm_write16
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
0xffff
);
/* disable Broadcom PHY IRQ */
xm_write16
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
0xffff
);
skge_xm_outhash
(
hw
,
port
,
XM_HSM
,
(
u8
*
)
&
zero
);
for
(
i
=
0
;
i
<
15
;
i
++
)
skge_xm_outaddr
(
hw
,
port
,
XM_EXM
(
i
),
(
u8
*
)
&
zero
);
skge_xm_outhash
(
hw
,
port
,
XM_SRC_CHK
,
(
u8
*
)
&
zero
);
xm_outhash
(
hw
,
port
,
XM_HSM
,
zero
);
}
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
)
/* Convert mode to MII values */
static
const
u16
phy_pause_map
[]
=
{
[
FLOW_MODE_NONE
]
=
0
,
[
FLOW_MODE_LOC_SEND
]
=
PHY_AN_PAUSE_ASYM
,
[
FLOW_MODE_SYMMETRIC
]
=
PHY_AN_PAUSE_CAP
,
[
FLOW_MODE_REM_SEND
]
=
PHY_AN_PAUSE_CAP
|
PHY_AN_PAUSE_ASYM
,
};
/* Check status of Broadcom phy link */
static
void
bcom_check_link
(
struct
skge_hw
*
hw
,
int
port
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
struct
net_device
*
dev
=
hw
->
dev
[
port
];
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
u16
status
;
/* read twice because of latch */
(
void
)
xm_phy_read
(
hw
,
port
,
PHY_BCOM_STAT
);
status
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_STAT
);
pr_debug
(
"bcom_check_link status=0x%x
\n
"
,
status
);
if
((
status
&
PHY_ST_LSYNC
)
==
0
)
{
u16
cmd
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
cmd
&=
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
);
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
);
/* dummy read to ensure writing */
(
void
)
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
if
(
netif_carrier_ok
(
dev
))
skge_link_down
(
skge
);
}
else
{
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
&&
(
status
&
PHY_ST_AN_OVER
))
{
u16
lpa
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUNE_LP
);
u16
aux
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_STAT
);
if
(
lpa
&
PHY_B_AN_RF
)
{
printk
(
KERN_NOTICE
PFX
"%s: remote fault
\n
"
,
dev
->
name
);
return
;
}
/* Check Duplex mismatch */
switch
(
aux
&
PHY_B_AS_AN_RES_MSK
)
{
case
PHY_B_RES_1000FD
:
skge
->
duplex
=
DUPLEX_FULL
;
break
;
case
PHY_B_RES_1000HD
:
skge
->
duplex
=
DUPLEX_HALF
;
break
;
default:
printk
(
KERN_NOTICE
PFX
"%s: duplex mismatch
\n
"
,
dev
->
name
);
return
;
}
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
switch
(
aux
&
PHY_B_AS_PAUSE_MSK
)
{
case
PHY_B_AS_PAUSE_MSK
:
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
break
;
case
PHY_B_AS_PRR
:
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
break
;
case
PHY_B_AS_PRT
:
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
break
;
default:
skge
->
flow_control
=
FLOW_MODE_NONE
;
}
skge
->
speed
=
SPEED_1000
;
}
if
(
!
netif_carrier_ok
(
dev
))
genesis_link_up
(
skge
);
}
}
/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
* Phy on for 100 or 10Mbit operation
*/
static
void
bcom_phy_init
(
struct
skge_port
*
skge
,
int
jumbo
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
int
i
;
u32
r
;
u16
id1
;
u16
ctrl1
,
ctrl2
,
ctrl3
,
ctrl4
,
ctrl5
;
u16
id1
,
r
,
ext
,
ctl
;
/* magic workaround patterns for Broadcom */
static
const
struct
{
...
...
@@ -1042,16 +1089,120 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
{
0x17
,
0x0013
},
{
0x15
,
0x0A04
},
{
0x18
,
0x0420
},
};
pr_debug
(
"bcom_phy_init
\n
"
);
/* read Id from external PHY (all have the same address) */
id1
=
xm_phy_read
(
hw
,
port
,
PHY_XMAC_ID1
);
/* Optimize MDIO transfer by suppressing preamble. */
r
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
r
|=
XM_MMU_NO_PRE
;
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
r
);
switch
(
id1
)
{
case
PHY_BCOM_ID1_C0
:
/*
* Workaround BCOM Errata for the C0 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
C0hack
);
i
++
)
xm_phy_write
(
hw
,
port
,
C0hack
[
i
].
reg
,
C0hack
[
i
].
val
);
break
;
case
PHY_BCOM_ID1_A1
:
/*
* Workaround BCOM Errata for the A1 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
A1hack
);
i
++
)
xm_phy_write
(
hw
,
port
,
A1hack
[
i
].
reg
,
A1hack
[
i
].
val
);
break
;
}
/*
* Workaround BCOM Errata (#10523) for all BCom PHYs.
* Disable Power Management after reset.
*/
r
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
);
r
|=
PHY_B_AC_DIS_PM
;
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
r
);
/* Dummy read */
xm_read16
(
hw
,
port
,
XM_ISRC
);
ext
=
PHY_B_PEC_EN_LTR
;
/* enable tx led */
ctl
=
PHY_CT_SP1000
;
/* always 1000mbit */
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
/*
* Workaround BCOM Errata #1 for the C5 type.
* 1000Base-T Link Acquisition Failure in Slave Mode
* Set Repeater/DTE bit 10 of the 1000Base-T Control Register
*/
u16
adv
=
PHY_B_1000C_RD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Half
)
adv
|=
PHY_B_1000C_AHD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Full
)
adv
|=
PHY_B_1000C_AFD
;
xm_phy_write
(
hw
,
port
,
PHY_BCOM_1000T_CTRL
,
adv
);
ctl
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
if
(
skge
->
duplex
==
DUPLEX_FULL
)
ctl
|=
PHY_CT_DUP_MD
;
/* Force to slave */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_1000T_CTRL
,
PHY_B_1000C_MSE
);
}
/* Set autonegotiation pause parameters */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUNE_ADV
,
phy_pause_map
[
skge
->
flow_control
]
|
PHY_AN_CSMA
);
/* Handle Jumbo frames */
if
(
jumbo
)
{
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
PHY_B_AC_TX_TST
|
PHY_B_AC_LONG_PACK
);
ext
|=
PHY_B_PEC_HIGH_LA
;
}
xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
ext
);
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctl
);
/* Use link status change interrrupt */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
PHY_B_DEF_MSK
);
bcom_check_link
(
hw
,
port
);
}
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
)
{
struct
net_device
*
dev
=
hw
->
dev
[
port
];
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
int
jumbo
=
hw
->
dev
[
port
]
->
mtu
>
ETH_DATA_LEN
;
int
i
;
u32
r
;
const
u8
zero
[
6
]
=
{
0
};
/* Clear MIB counters */
xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* Clear two times according to Errata #3 */
xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* initialize Rx, Tx and Link LED */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_LINKSYNC_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_LINKSYNC_ON
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_LED_CTRL
),
LED_START
);
/* Unreset the XMAC. */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
MFF_CLR_MAC_RST
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_CLR_MAC_RST
);
/*
* Perform additional initialization for external PHYs,
...
...
@@ -1059,8 +1210,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* GMII mode.
*/
spin_lock_bh
(
&
hw
->
phy_lock
);
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
{
/* Take PHY out of reset. */
/* Take external Phy out of reset */
r
=
skge_read32
(
hw
,
B2_GP_IO
);
if
(
port
==
0
)
r
|=
GP_DIR_0
|
GP_IO_0
;
...
...
@@ -1069,57 +1219,47 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write32
(
hw
,
B2_GP_IO
,
r
);
skge_read32
(
hw
,
B2_GP_IO
);
spin_unlock_bh
(
&
hw
->
phy_lock
);
/* Enable GMII mode on the XMAC.
*/
skge_
xm_write16
(
hw
,
port
,
XM_HW_CFG
,
XM_HW_GMII_MD
);
/* Enable GMII interfac
*/
xm_write16
(
hw
,
port
,
XM_HW_CFG
,
XM_HW_GMII_MD
);
id1
=
skge_xm_phy_read
(
hw
,
port
,
PHY_XMAC_ID1
);
bcom_phy_init
(
skge
,
jumbo
);
/* Optimize MDIO transfer by suppressing preamble. */
skge_xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
|
XM_MMU_NO_PRE
);
/* Set Station Address */
xm_outaddr
(
hw
,
port
,
XM_SA
,
dev
->
dev_addr
);
if
(
id1
==
PHY_BCOM_ID1_C0
)
{
/*
* Workaround BCOM Errata for the C0 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
C0hack
);
i
++
)
skge_xm_phy_write
(
hw
,
port
,
C0hack
[
i
].
reg
,
C0hack
[
i
].
val
);
/* We don't use match addresses so clear */
for
(
i
=
1
;
i
<
16
;
i
++
)
xm_outaddr
(
hw
,
port
,
XM_EXM
(
i
),
zero
);
}
else
if
(
id1
==
PHY_BCOM_ID1_A1
)
{
/*
* Workaround BCOM Errata for the A1 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
A1hack
);
i
++
)
skge_xm_phy_write
(
hw
,
port
,
A1hack
[
i
].
reg
,
A1hack
[
i
].
val
);
}
/* configure Rx High Water Mark (XM_RX_HI_WM) */
xm_write16
(
hw
,
port
,
XM_RX_HI_WM
,
1450
);
/* We don't need the FCS appended to the packet. */
r
=
XM_RX_LENERR_OK
|
XM_RX_STRIP_FCS
;
if
(
jumbo
)
r
|=
XM_RX_BIG_PK_OK
;
if
(
skge
->
duplex
==
DUPLEX_HALF
)
{
/*
* Workaround BCOM Errata (#10523) for all BCom PHYs.
* Disable Power Management after reset.
* If in manual half duplex mode the other side might be in
* full duplex mode, so ignore if a carrier extension is not seen
* on frames received
*/
r
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
r
|
PHY_B_AC_DIS_PM
);
r
|=
XM_RX_DIS_CEXT
;
}
xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
);
/* Dummy read */
skge_xm_read16
(
hw
,
port
,
XM_ISRC
);
r
=
skge_xm_read32
(
hw
,
port
,
XM_MODE
);
skge_xm_write32
(
hw
,
port
,
XM_MODE
,
r
|
XM_MD_CSA
);
/* We don't need the FCS appended to the packet. */
r
=
skge_xm_read16
(
hw
,
port
,
XM_RX_CMD
);
skge_xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
|
XM_RX_STRIP_FCS
);
/* We want short frames padded to 60 bytes. */
r
=
skge_xm_read16
(
hw
,
port
,
XM_TX_CMD
);
skge_xm_write16
(
hw
,
port
,
XM_TX_CMD
,
r
|
XM_TX_AUTO_PAD
);
xm_write16
(
hw
,
port
,
XM_TX_CMD
,
XM_TX_AUTO_PAD
);
/*
* Bump up the transmit threshold. This helps hold off transmit
* underruns when we're blasting traffic from both ports at once.
*/
xm_write16
(
hw
,
port
,
XM_TX_THR
,
512
);
/*
* Enable the reception of all error frames. This is is
...
...
@@ -1135,19 +1275,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* case the XMAC will start transfering frames out of the
* RX FIFO as soon as the FIFO threshold is reached.
*/
r
=
skge_xm_read32
(
hw
,
port
,
XM_MODE
);
skge_xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_RX_CRCE
|
XM_MD_RX_LONG
|
XM_MD_RX_RUNT
|
XM_MD_RX_ERR
|
XM_MD_RX_IRLE
);
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_DEF_MODE
);
skge_xm_outaddr
(
hw
,
port
,
XM_SA
,
hw
->
dev
[
port
]
->
dev_addr
);
skge_xm_outaddr
(
hw
,
port
,
XM_EXM
(
0
),
hw
->
dev
[
port
]
->
dev_addr
);
/*
* Bump up the transmit threshold. This helps hold off transmit
* underruns when we're blasting traffic from both ports at once.
* Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
* - Enable all bits excepting 'Octets Rx OK Low CntOv'
* and 'Octets Rx OK Hi Cnt Ov'.
*/
xm_write32
(
hw
,
port
,
XM_RX_EV_MSK
,
XMR_DEF_MSK
);
/*
* Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
* - Enable all bits excepting 'Octets Tx OK Low CntOv'
* and 'Octets Tx OK Hi Cnt Ov'.
*/
skge_xm_write16
(
hw
,
port
,
XM_TX_THR
,
512
);
xm_write32
(
hw
,
port
,
XM_TX_EV_MSK
,
XMT_DEF_MSK
);
/* Configure MAC arbiter */
skge_write16
(
hw
,
B3_MA_TO_CTRL
,
MA_RST_CLR
);
...
...
@@ -1164,137 +1307,30 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write8
(
hw
,
B3_MA_RCINI_TX2
,
0
);
/* Configure Rx MAC FIFO */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_TIM_PAT
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_TIM_PAT
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
/* Configure Tx MAC FIFO */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
MFF_TX_CTRL_DEF
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_TX_CTRL_DEF
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
if
(
hw
->
dev
[
port
]
->
mtu
>
ETH_DATA_LEN
)
{
if
(
jumbo
)
{
/* Enable frame flushing if jumbo frames used */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_FLUSH
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_FLUSH
);
}
else
{
/* enable timeout timers if normal frames */
skge_write16
(
hw
,
B3_PA_CTRL
,
port
==
0
?
PA_ENA_TO_TX1
:
PA_ENA_TO_TX2
);
}
r
=
skge_xm_read16
(
hw
,
port
,
XM_RX_CMD
);
if
(
hw
->
dev
[
port
]
->
mtu
>
ETH_DATA_LEN
)
skge_xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
|
XM_RX_BIG_PK_OK
);
else
skge_xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
&
~
(
XM_RX_BIG_PK_OK
));
switch
(
hw
->
phy_type
)
{
case
SK_PHY_XMAC
:
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
ctrl1
=
PHY_X_AN_FD
|
PHY_X_AN_HD
;
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
ctrl1
|=
PHY_X_P_NO_PAUSE
;
break
;
case
FLOW_MODE_LOC_SEND
:
ctrl1
|=
PHY_X_P_ASYM_MD
;
break
;
case
FLOW_MODE_SYMMETRIC
:
ctrl1
|=
PHY_X_P_SYM_MD
;
break
;
case
FLOW_MODE_REM_SEND
:
ctrl1
|=
PHY_X_P_BOTH_MD
;
break
;
}
skge_xm_phy_write
(
hw
,
port
,
PHY_XMAC_AUNE_ADV
,
ctrl1
);
ctrl2
=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
ctrl2
=
0
;
if
(
skge
->
duplex
==
DUPLEX_FULL
)
ctrl2
|=
PHY_CT_DUP_MD
;
}
skge_xm_phy_write
(
hw
,
port
,
PHY_XMAC_CTRL
,
ctrl2
);
break
;
case
SK_PHY_BCOM
:
ctrl1
=
PHY_CT_SP1000
;
ctrl2
=
0
;
ctrl3
=
PHY_SEL_TYPE
;
ctrl4
=
PHY_B_PEC_EN_LTR
;
ctrl5
=
PHY_B_AC_TX_TST
;
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
/*
* Workaround BCOM Errata #1 for the C5 type.
* 1000Base-T Link Acquisition Failure in Slave Mode
* Set Repeater/DTE bit 10 of the 1000Base-T Control Register
*/
ctrl2
|=
PHY_B_1000C_RD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Half
)
ctrl2
|=
PHY_B_1000C_AHD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Full
)
ctrl2
|=
PHY_B_1000C_AFD
;
/* Set Flow-control capabilities */
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
ctrl3
|=
PHY_B_P_NO_PAUSE
;
break
;
case
FLOW_MODE_LOC_SEND
:
ctrl3
|=
PHY_B_P_ASYM_MD
;
break
;
case
FLOW_MODE_SYMMETRIC
:
ctrl3
|=
PHY_B_P_SYM_MD
;
break
;
case
FLOW_MODE_REM_SEND
:
ctrl3
|=
PHY_B_P_BOTH_MD
;
break
;
}
/* Restart Auto-negotiation */
ctrl1
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
if
(
skge
->
duplex
==
DUPLEX_FULL
)
ctrl1
|=
PHY_CT_DUP_MD
;
ctrl2
|=
PHY_B_1000C_MSE
;
/* set it to Slave */
}
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_1000T_CTRL
,
ctrl2
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUNE_ADV
,
ctrl3
);
if
(
skge
->
netdev
->
mtu
>
ETH_DATA_LEN
)
{
ctrl4
|=
PHY_B_PEC_HIGH_LA
;
ctrl5
|=
PHY_B_AC_LONG_PACK
;
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
ctrl5
);
}
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
ctrl4
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctrl1
);
break
;
(
port
==
0
)
?
PA_ENA_TO_TX1
:
PA_ENA_TO_TX2
);
}
spin_unlock_bh
(
&
hw
->
phy_lock
);
/* Clear MIB counters */
skge_xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* Clear two times according to Errata #3 */
skge_xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* Start polling for link status */
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
static
void
genesis_stop
(
struct
skge_port
*
skge
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
u32
reg
;
/* Clear Tx packet arbiter timeout IRQ */
skge_write16
(
hw
,
B3_PA_CTRL
,
...
...
@@ -1304,17 +1340,15 @@ static void genesis_stop(struct skge_port *skge)
* If the transfer stucks at the MAC the STOP command will not
* terminate if we don't flush the XMAC's transmit FIFO !
*/
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
skge_
xm_read32
(
hw
,
port
,
XM_MODE
)
|
XM_MD_FTF
);
xm_write32
(
hw
,
port
,
XM_MODE
,
xm_read32
(
hw
,
port
,
XM_MODE
)
|
XM_MD_FTF
);
/* Reset the MAC */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
MFF_SET_MAC_RST
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_SET_MAC_RST
);
/* For external PHYs there must be special handling */
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
{
u32
reg
=
skge_read32
(
hw
,
B2_GP_IO
);
reg
=
skge_read32
(
hw
,
B2_GP_IO
);
if
(
port
==
0
)
{
reg
|=
GP_DIR_0
;
reg
&=
~
GP_IO_0
;
...
...
@@ -1324,13 +1358,12 @@ static void genesis_stop(struct skge_port *skge)
}
skge_write32
(
hw
,
B2_GP_IO
,
reg
);
skge_read32
(
hw
,
B2_GP_IO
);
}
skge_
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
));
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
}
...
...
@@ -1341,11 +1374,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
int
i
;
unsigned
long
timeout
=
jiffies
+
HZ
;
skge_
xm_write16
(
hw
,
port
,
xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_SNP_TXC
|
XM_SC_SNP_RXC
);
/* wait for update to complete */
while
(
skge_
xm_read16
(
hw
,
port
,
XM_STAT_CMD
)
while
(
xm_read16
(
hw
,
port
,
XM_STAT_CMD
)
&
(
XM_SC_SNP_TXC
|
XM_SC_SNP_RXC
))
{
if
(
time_after
(
jiffies
,
timeout
))
break
;
...
...
@@ -1353,68 +1386,60 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
}
/* special case for 64 bit octet counter */
data
[
0
]
=
(
u64
)
skge_
xm_read32
(
hw
,
port
,
XM_TXO_OK_HI
)
<<
32
|
skge_
xm_read32
(
hw
,
port
,
XM_TXO_OK_LO
);
data
[
1
]
=
(
u64
)
skge_
xm_read32
(
hw
,
port
,
XM_RXO_OK_HI
)
<<
32
|
skge_
xm_read32
(
hw
,
port
,
XM_RXO_OK_LO
);
data
[
0
]
=
(
u64
)
xm_read32
(
hw
,
port
,
XM_TXO_OK_HI
)
<<
32
|
xm_read32
(
hw
,
port
,
XM_TXO_OK_LO
);
data
[
1
]
=
(
u64
)
xm_read32
(
hw
,
port
,
XM_RXO_OK_HI
)
<<
32
|
xm_read32
(
hw
,
port
,
XM_RXO_OK_LO
);
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
data
[
i
]
=
skge_
xm_read32
(
hw
,
port
,
skge_stats
[
i
].
xmac_offset
);
data
[
i
]
=
xm_read32
(
hw
,
port
,
skge_stats
[
i
].
xmac_offset
);
}
static
void
genesis_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
u16
status
=
skge_
xm_read16
(
hw
,
port
,
XM_ISRC
);
u16
status
=
xm_read16
(
hw
,
port
,
XM_ISRC
);
pr_debug
(
"genesis_intr status %x
\n
"
,
status
);
if
(
hw
->
phy_type
==
SK_PHY_XMAC
)
{
/* LInk down, start polling for state change */
if
(
status
&
XM_IS_INP_ASS
)
{
skge_xm_write16
(
hw
,
port
,
XM_IMSK
,
skge_xm_read16
(
hw
,
port
,
XM_IMSK
)
|
XM_IS_INP_ASS
);
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
else
if
(
status
&
XM_IS_AND
)
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: mac interrupt status 0x%x
\n
"
,
skge
->
netdev
->
name
,
status
);
if
(
status
&
XM_IS_TXF_UR
)
{
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FTF
);
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FTF
);
++
skge
->
net_stats
.
tx_fifo_errors
;
}
if
(
status
&
XM_IS_RXF_OV
)
{
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FRF
);
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FRF
);
++
skge
->
net_stats
.
rx_fifo_errors
;
}
}
static
void
skge_
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
static
void
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
{
int
i
;
skge_
gma_write16
(
hw
,
port
,
GM_SMI_DATA
,
val
);
skge_
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
gma_write16
(
hw
,
port
,
GM_SMI_DATA
,
val
);
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
GM_SMI_CT_PHY_AD
(
hw
->
phy_addr
)
|
GM_SMI_CT_REG_AD
(
reg
));
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
if
(
!
(
skge_
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_BUSY
))
if
(
!
(
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_BUSY
))
break
;
}
}
static
u16
skge_
gm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
static
u16
gm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
{
int
i
;
skge_
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
GM_SMI_CT_PHY_AD
(
hw
->
phy_addr
)
|
GM_SMI_CT_REG_AD
(
reg
)
|
GM_SMI_CT_OP_RD
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
if
(
skge_
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_RD_VAL
)
if
(
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_RD_VAL
)
goto
ready
;
}
...
...
@@ -1422,24 +1447,7 @@ static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg)
hw
->
dev
[
port
]
->
name
);
return
0
;
ready:
return
skge_gma_read16
(
hw
,
port
,
GM_SMI_DATA
);
}
static
void
genesis_link_down
(
struct
skge_port
*
skge
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
pr_debug
(
"genesis_link_down
\n
"
);
skge_xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
));
/* dummy read to ensure writing */
(
void
)
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
skge_link_down
(
skge
);
return
gma_read16
(
hw
,
port
,
GM_SMI_DATA
);
}
static
void
genesis_link_up
(
struct
skge_port
*
skge
)
...
...
@@ -1450,7 +1458,7 @@ static void genesis_link_up(struct skge_port *skge)
u32
mode
,
msk
;
pr_debug
(
"genesis_link_up
\n
"
);
cmd
=
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
cmd
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
/*
* enabling pause frame reception is required for 1000BT
...
...
@@ -1458,14 +1466,15 @@ static void genesis_link_up(struct skge_port *skge)
*/
if
(
skge
->
flow_control
==
FLOW_MODE_NONE
||
skge
->
flow_control
==
FLOW_MODE_LOC_SEND
)
/* Disable Pause Frame Reception */
cmd
|=
XM_MMU_IGN_PF
;
else
/* Enable Pause Frame Reception */
cmd
&=
~
XM_MMU_IGN_PF
;
skge_
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
);
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
);
mode
=
skge_
xm_read32
(
hw
,
port
,
XM_MODE
);
mode
=
xm_read32
(
hw
,
port
,
XM_MODE
);
if
(
skge
->
flow_control
==
FLOW_MODE_SYMMETRIC
||
skge
->
flow_control
==
FLOW_MODE_LOC_SEND
)
{
/*
...
...
@@ -1479,10 +1488,10 @@ static void genesis_link_up(struct skge_port *skge)
/* XM_PAUSE_DA = '010000C28001' (default) */
/* XM_MAC_PTIME = 0xffff (maximum) */
/* remember this value is defined in big endian (!) */
skge_
xm_write16
(
hw
,
port
,
XM_MAC_PTIME
,
0xffff
);
xm_write16
(
hw
,
port
,
XM_MAC_PTIME
,
0xffff
);
mode
|=
XM_PAUSE_MODE
;
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_PAUSE
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_PAUSE
);
}
else
{
/*
* disable pause frame generation is required for 1000BT
...
...
@@ -1491,125 +1500,68 @@ static void genesis_link_up(struct skge_port *skge)
/* Disable Pause Mode in Mode Register */
mode
&=
~
XM_PAUSE_MODE
;
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_DIS_PAUSE
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_DIS_PAUSE
);
}
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
msk
=
XM_DEF_MSK
;
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
msk
|=
XM_IS_INP_ASS
;
/* disable GP0 interrupt bit */
/* disable GP0 interrupt bit for external Phy */
msk
|=
XM_IS_INP_ASS
;
skge_
xm_write16
(
hw
,
port
,
XM_IMSK
,
msk
);
skge_
xm_read16
(
hw
,
port
,
XM_ISRC
);
xm_write16
(
hw
,
port
,
XM_IMSK
,
msk
);
xm_read16
(
hw
,
port
,
XM_ISRC
);
/* get MMU Command Reg. */
cmd
=
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
&&
skge
->
duplex
==
DUPLEX_FULL
)
cmd
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
if
(
skge
->
duplex
==
DUPLEX_FULL
)
cmd
|=
XM_MMU_GMII_FD
;
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
{
/*
* Workaround BCOM Errata (#10523) for all BCom Phys
* Enable Power Management after link up
*/
skge_
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
skge_
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
)
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
)
&
~
PHY_B_AC_DIS_PM
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
PHY_B_DEF_MSK
);
}
xm_phy_write
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
PHY_B_DEF_MSK
);
/* enable Rx/Tx */
skge_
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
|
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
);
skge_link_up
(
skge
);
}
static
void
genesis_bcom
_intr
(
struct
skge_port
*
skge
)
static
inline
void
bcom_phy
_intr
(
struct
skge_port
*
skge
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
u16
stat
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_INT_STAT
);
u16
isrc
;
isrc
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_INT_STAT
);
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: phy interrupt status 0x%x
\n
"
,
skge
->
netdev
->
name
,
isrc
);
pr_debug
(
"genesis_bcom intr stat=%x
\n
"
,
stat
);
if
(
isrc
&
PHY_B_IS_PSE
)
printk
(
KERN_ERR
PFX
"%s: uncorrectable pair swap error
\n
"
,
hw
->
dev
[
port
]
->
name
);
/* Workaround BCom Errata:
* enable and disable loopback mode if "NO HCD" occurs.
*/
if
(
stat
&
PHY_B_IS_NO_HDCL
)
{
u16
ctrl
=
skge_
xm_phy_read
(
hw
,
port
,
PHY_BCOM_CTRL
);
skge_
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
if
(
isrc
&
PHY_B_IS_NO_HDCL
)
{
u16
ctrl
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_CTRL
);
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctrl
|
PHY_CT_LOOP
);
skge_
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctrl
&
~
PHY_CT_LOOP
);
}
stat
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_STAT
);
if
(
stat
&
(
PHY_B_IS_AN_PR
|
PHY_B_IS_LST_CHANGE
))
{
u16
aux
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_STAT
);
if
(
!
(
aux
&
PHY_B_AS_LS
)
&&
netif_carrier_ok
(
skge
->
netdev
))
genesis_link_down
(
skge
);
else
if
(
stat
&
PHY_B_IS_LST_CHANGE
)
{
if
(
aux
&
PHY_B_AS_AN_C
)
{
switch
(
aux
&
PHY_B_AS_AN_RES_MSK
)
{
case
PHY_B_RES_1000FD
:
skge
->
duplex
=
DUPLEX_FULL
;
break
;
case
PHY_B_RES_1000HD
:
skge
->
duplex
=
DUPLEX_HALF
;
break
;
}
switch
(
aux
&
PHY_B_AS_PAUSE_MSK
)
{
case
PHY_B_AS_PAUSE_MSK
:
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
break
;
case
PHY_B_AS_PRR
:
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
break
;
case
PHY_B_AS_PRT
:
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
break
;
default:
skge
->
flow_control
=
FLOW_MODE_NONE
;
}
skge
->
speed
=
SPEED_1000
;
}
genesis_link_up
(
skge
);
}
else
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
}
/* Perodic poll of phy status to check for link transistion */
static
void
skge_link_timer
(
unsigned
long
__arg
)
{
struct
skge_port
*
skge
=
(
struct
skge_port
*
)
__arg
;
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
||
!
netif_running
(
skge
->
netdev
))
return
;
spin_lock_bh
(
&
hw
->
phy_lock
);
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
genesis_bcom_intr
(
skge
);
else
{
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
skge_xm_read16
(
hw
,
port
,
XM_ISRC
)
&
XM_IS_INP_ASS
)
break
;
if
(
isrc
&
(
PHY_B_IS_AN_PR
|
PHY_B_IS_LST_CHANGE
))
bcom_check_link
(
hw
,
port
);
if
(
i
==
3
)
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
else
genesis_link_up
(
skge
);
}
spin_unlock_bh
(
&
hw
->
phy_lock
);
}
/* Marvell Phy Initailization */
...
...
@@ -1621,31 +1573,27 @@ static void yukon_init(struct skge_hw *hw, int port)
pr_debug
(
"yukon_init
\n
"
);
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
u16
ectrl
=
skge_
gm_phy_read
(
hw
,
port
,
PHY_MARV_EXT_CTRL
);
u16
ectrl
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_EXT_CTRL
);
ectrl
&=
~
(
PHY_M_EC_M_DSC_MSK
|
PHY_M_EC_S_DSC_MSK
|
PHY_M_EC_MAC_S_MSK
);
ectrl
|=
PHY_M_EC_MAC_S
(
MAC_TX_CLK_25_MHZ
);
/* on PHY 88E1111 there is a change for downshift control */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_EC
)
ectrl
|=
PHY_M_EC_M_DSC_2
(
0
)
|
PHY_M_EC_DOWN_S_ENA
;
else
ectrl
|=
PHY_M_EC_M_DSC
(
0
)
|
PHY_M_EC_S_DSC
(
1
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_EXT_CTRL
,
ectrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_EXT_CTRL
,
ectrl
);
}
ctrl
=
skge_
gm_phy_read
(
hw
,
port
,
PHY_MARV_CTRL
);
ctrl
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_CTRL
);
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
)
ctrl
&=
~
PHY_CT_ANE
;
ctrl
|=
PHY_CT_RESET
;
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
ctrl
=
0
;
ct1000
=
0
;
adv
=
PHY_
SEL_TYPE
;
adv
=
PHY_
AN_CSMA
;
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
iscopper
(
hw
))
{
...
...
@@ -1661,41 +1609,12 @@ static void yukon_init(struct skge_hw *hw, int port)
adv
|=
PHY_M_AN_10_FD
;
if
(
skge
->
advertising
&
ADVERTISED_10baseT_Half
)
adv
|=
PHY_M_AN_10_HD
;
/* Set Flow-control capabilities */
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
adv
|=
PHY_B_P_NO_PAUSE
;
break
;
case
FLOW_MODE_LOC_SEND
:
adv
|=
PHY_B_P_ASYM_MD
;
break
;
case
FLOW_MODE_SYMMETRIC
:
adv
|=
PHY_B_P_SYM_MD
;
break
;
case
FLOW_MODE_REM_SEND
:
adv
|=
PHY_B_P_BOTH_MD
;
break
;
}
}
else
{
/* special defines for FIBER (88E1011S only) */
}
else
/* special defines for FIBER (88E1011S only) */
adv
|=
PHY_M_AN_1000X_AHD
|
PHY_M_AN_1000X_AFD
;
/* Set Flow-control capabilities */
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
adv
|=
PHY_M_P_NO_PAUSE_X
;
break
;
case
FLOW_MODE_LOC_SEND
:
adv
|=
PHY_M_P_ASYM_MD_X
;
break
;
case
FLOW_MODE_SYMMETRIC
:
adv
|=
PHY_M_P_SYM_MD_X
;
break
;
case
FLOW_MODE_REM_SEND
:
adv
|=
PHY_M_P_BOTH_MD_X
;
break
;
}
}
adv
|=
phy_pause_map
[
skge
->
flow_control
];
/* Restart Auto-negotiation */
ctrl
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
...
...
@@ -1717,36 +1636,23 @@ static void yukon_init(struct skge_hw *hw, int port)
ctrl
|=
PHY_CT_RESET
;
}
if
(
hw
->
chip_id
!=
CHIP_ID_YUKON_FE
)
skge_gm_phy_write
(
hw
,
port
,
PHY_MARV_1000T_CTRL
,
ct1000
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_1000T_CTRL
,
ct1000
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
adv
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
adv
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
/* Setup Phy LED's */
ledctrl
=
PHY_M_LED_PULS_DUR
(
PULS_170MS
);
ledover
=
0
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
{
/* on 88E3082 these bits are at 11..9 (shifted left) */
ledctrl
|=
PHY_M_LED_BLINK_RT
(
BLINK_84MS
)
<<
1
;
skge_gm_phy_write
(
hw
,
port
,
PHY_MARV_FE_LED_PAR
,
((
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_FE_LED_PAR
)
&
~
PHY_M_FELP_LED1_MSK
)
|
PHY_M_FELP_LED1_CTRL
(
LED_PAR_CTRL_ACT_BL
)));
}
else
{
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
ledctrl
|=
PHY_M_LED_BLINK_RT
(
BLINK_84MS
)
|
PHY_M_LEDC_TX_CTRL
;
/* turn off the Rx LED (LED_RX) */
ledover
|=
PHY_M_LED_MO_RX
(
MO_LED_OFF
);
}
/* disable blink mode (LED_DUPLEX) on collisions */
ctrl
|=
PHY_M_LEDC_DP_CTRL
;
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
ledctrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
ledctrl
);
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
||
skge
->
speed
==
SPEED_100
)
{
/* turn on 100 Mbps LED (LED_LINK100) */
...
...
@@ -1754,25 +1660,25 @@ static void yukon_init(struct skge_hw *hw, int port)
}
if
(
ledover
)
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
ledover
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
ledover
);
/* Enable phy interrupt on autonegotiation complete (or link up) */
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_IS_AN_COMPL
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_IS_AN_COMPL
);
else
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
}
static
void
yukon_reset
(
struct
skge_hw
*
hw
,
int
port
)
{
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
/* disable PHY IRQs */
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
0
);
/* clear MC hash */
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
0
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
/* disable PHY IRQs */
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
0
);
/* clear MC hash */
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
0
);
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
0
);
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
skge_
gma_read16
(
hw
,
port
,
GM_RX_CTRL
)
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
gma_read16
(
hw
,
port
,
GM_RX_CTRL
)
|
GM_RXCR_UCF_ENA
|
GM_RXCR_MCF_ENA
);
}
...
...
@@ -1785,17 +1691,17 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
/* WA code for COMA mode -- set PHY reset */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
skge_write32
(
hw
,
B2_GP_IO
,
(
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
|
GP_IO_9
));
/* hard reset */
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GPHY_CTRL
),
GPC_RST_SET
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_RST_SET
);
skge_write32
(
hw
,
SK_REG
(
port
,
GPHY_CTRL
),
GPC_RST_SET
);
skge_write32
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_RST_SET
);
/* WA code for COMA mode -- clear PHY reset */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
skge_write32
(
hw
,
B2_GP_IO
,
(
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
)
&
~
GP_IO_9
);
...
...
@@ -1806,13 +1712,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg
|=
iscopper
(
hw
)
?
GPC_HWCFG_GMII_COP
:
GPC_HWCFG_GMII_FIB
;
/* Clear GMC reset */
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_SET
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_CLR
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
|
GMC_RST_CLR
);
skge_write32
(
hw
,
SK_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_SET
);
skge_write32
(
hw
,
SK_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_CLR
);
skge_write32
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
|
GMC_RST_CLR
);
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
)
{
reg
=
GM_GPCR_AU_ALL_DIS
;
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
|
reg
);
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
|
reg
);
switch
(
skge
->
speed
)
{
case
SPEED_1000
:
...
...
@@ -1828,7 +1734,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg
=
GM_GPCR_SPEED_1000
|
GM_GPCR_SPEED_100
|
GM_GPCR_DUP_FULL
;
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
skge_write32
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
reg
|=
GM_GPCR_FC_TX_DIS
|
GM_GPCR_FC_RX_DIS
|
GM_GPCR_AU_FCT_DIS
;
break
;
case
FLOW_MODE_LOC_SEND
:
...
...
@@ -1836,7 +1742,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg
|=
GM_GPCR_FC_RX_DIS
|
GM_GPCR_AU_FCT_DIS
;
}
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
skge_read16
(
hw
,
GMAC_IRQ_SRC
);
spin_lock_bh
(
&
hw
->
phy_lock
);
...
...
@@ -1844,25 +1750,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
spin_unlock_bh
(
&
hw
->
phy_lock
);
/* MIB clear */
reg
=
skge_
gma_read16
(
hw
,
port
,
GM_PHY_ADDR
);
skge_
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
|
GM_PAR_MIB_CLR
);
reg
=
gma_read16
(
hw
,
port
,
GM_PHY_ADDR
);
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
|
GM_PAR_MIB_CLR
);
for
(
i
=
0
;
i
<
GM_MIB_CNT_SIZE
;
i
++
)
skge_
gma_read16
(
hw
,
port
,
GM_MIB_CNT_BASE
+
8
*
i
);
skge_
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
);
gma_read16
(
hw
,
port
,
GM_MIB_CNT_BASE
+
8
*
i
);
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
);
/* transmit control */
skge_
gma_write16
(
hw
,
port
,
GM_TX_CTRL
,
TX_COL_THR
(
TX_COL_DEF
));
gma_write16
(
hw
,
port
,
GM_TX_CTRL
,
TX_COL_THR
(
TX_COL_DEF
));
/* receive control reg: unicast + multicast + no FCS */
skge_
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
GM_RXCR_UCF_ENA
|
GM_RXCR_CRC_DIS
|
GM_RXCR_MCF_ENA
);
/* transmit flow control */
skge_
gma_write16
(
hw
,
port
,
GM_TX_FLOW_CTRL
,
0xffff
);
gma_write16
(
hw
,
port
,
GM_TX_FLOW_CTRL
,
0xffff
);
/* transmit parameter */
skge_
gma_write16
(
hw
,
port
,
GM_TX_PARAM
,
gma_write16
(
hw
,
port
,
GM_TX_PARAM
,
TX_JAM_LEN_VAL
(
TX_JAM_LEN_DEF
)
|
TX_JAM_IPG_VAL
(
TX_JAM_IPG_DEF
)
|
TX_IPG_JAM_DATA
(
TX_IPG_JAM_DEF
));
...
...
@@ -1872,33 +1778,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
if
(
hw
->
dev
[
port
]
->
mtu
>
1500
)
reg
|=
GM_SMOD_JUMBO_ENA
;
skge_
gma_write16
(
hw
,
port
,
GM_SERIAL_MODE
,
reg
);
gma_write16
(
hw
,
port
,
GM_SERIAL_MODE
,
reg
);
/* physical address: used for pause frames */
skge_gm
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_1L
,
addr
);
gma
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_1L
,
addr
);
/* virtual address for data */
skge_gm
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_2L
,
addr
);
gma
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_2L
,
addr
);
/* enable interrupt mask for counter overflows */
skge_
gma_write16
(
hw
,
port
,
GM_TX_IRQ_MSK
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_RX_IRQ_MSK
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_TR_IRQ_MSK
,
0
);
gma_write16
(
hw
,
port
,
GM_TX_IRQ_MSK
,
0
);
gma_write16
(
hw
,
port
,
GM_RX_IRQ_MSK
,
0
);
gma_write16
(
hw
,
port
,
GM_TR_IRQ_MSK
,
0
);
/* Initialize Mac Fifo */
/* Configure Rx MAC FIFO */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_FL_MSK
),
RX_FF_FL_DEF_MSK
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_GMF_FL_MSK
),
RX_FF_FL_DEF_MSK
);
reg
=
GMF_OPER_ON
|
GMF_RX_F_FL_ON
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
reg
&=
~
GMF_RX_F_FL_ON
;
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_CTRL_T
),
reg
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_FL_THR
),
RX_GMF_FL_THR_DEF
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_GMF_CTRL_T
),
reg
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_GMF_FL_THR
),
RX_GMF_FL_THR_DEF
);
/* Configure Tx MAC FIFO */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_OPER_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_OPER_ON
);
}
static
void
yukon_stop
(
struct
skge_port
*
skge
)
...
...
@@ -1907,19 +1813,19 @@ static void yukon_stop(struct skge_port *skge)
int
port
=
skge
->
port
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
{
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
{
skge_write32
(
hw
,
B2_GP_IO
,
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
|
GP_IO_9
);
}
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
&
~
(
GM_GPCR_RX_ENA
|
GM_GPCR_RX_ENA
));
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
/* set GPHY Control reset */
skge_
gma_write32
(
hw
,
port
,
GPHY_CTRL
,
GPC_RST_SET
);
skge_
gma_write32
(
hw
,
port
,
GMAC_CTRL
,
GMC_RST_SET
);
gma_write32
(
hw
,
port
,
GPHY_CTRL
,
GPC_RST_SET
);
gma_write32
(
hw
,
port
,
GMAC_CTRL
,
GMC_RST_SET
);
}
static
void
yukon_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
)
...
...
@@ -1928,39 +1834,40 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data)
int
port
=
skge
->
port
;
int
i
;
data
[
0
]
=
(
u64
)
skge_
gma_read32
(
hw
,
port
,
GM_TXO_OK_HI
)
<<
32
|
skge_
gma_read32
(
hw
,
port
,
GM_TXO_OK_LO
);
data
[
1
]
=
(
u64
)
skge_
gma_read32
(
hw
,
port
,
GM_RXO_OK_HI
)
<<
32
|
skge_
gma_read32
(
hw
,
port
,
GM_RXO_OK_LO
);
data
[
0
]
=
(
u64
)
gma_read32
(
hw
,
port
,
GM_TXO_OK_HI
)
<<
32
|
gma_read32
(
hw
,
port
,
GM_TXO_OK_LO
);
data
[
1
]
=
(
u64
)
gma_read32
(
hw
,
port
,
GM_RXO_OK_HI
)
<<
32
|
gma_read32
(
hw
,
port
,
GM_RXO_OK_LO
);
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
data
[
i
]
=
skge_
gma_read32
(
hw
,
port
,
data
[
i
]
=
gma_read32
(
hw
,
port
,
skge_stats
[
i
].
gma_offset
);
}
static
void
yukon_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
u8
status
=
skge_read8
(
hw
,
SKGEMAC_REG
(
port
,
GMAC_IRQ_SRC
));
struct
net_device
*
dev
=
hw
->
dev
[
port
];
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
u8
status
=
skge_read8
(
hw
,
SK_REG
(
port
,
GMAC_IRQ_SRC
));
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: mac interrupt status 0x%x
\n
"
,
dev
->
name
,
status
);
pr_debug
(
"yukon_intr status %x
\n
"
,
status
);
if
(
status
&
GM_IS_RX_FF_OR
)
{
++
skge
->
net_stats
.
rx_fifo_errors
;
skge_
gma_write8
(
hw
,
port
,
RX_GMF_CTRL_T
,
GMF_CLI_RX_FO
);
gma_write8
(
hw
,
port
,
RX_GMF_CTRL_T
,
GMF_CLI_RX_FO
);
}
if
(
status
&
GM_IS_TX_FF_UR
)
{
++
skge
->
net_stats
.
tx_fifo_errors
;
skge_
gma_write8
(
hw
,
port
,
TX_GMF_CTRL_T
,
GMF_CLI_TX_FU
);
gma_write8
(
hw
,
port
,
TX_GMF_CTRL_T
,
GMF_CLI_TX_FU
);
}
}
static
u16
yukon_speed
(
const
struct
skge_hw
*
hw
,
u16
aux
)
{
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
return
(
aux
&
PHY_M_PS_SPEED_100
)
?
SPEED_100
:
SPEED_10
;
switch
(
aux
&
PHY_M_PS_SPEED_MSK
)
{
switch
(
aux
&
PHY_M_PS_SPEED_MSK
)
{
case
PHY_M_PS_SPEED_1000
:
return
SPEED_1000
;
case
PHY_M_PS_SPEED_100
:
...
...
@@ -1981,15 +1888,15 @@ static void yukon_link_up(struct skge_port *skge)
/* Enable Transmit FIFO Underrun */
skge_write8
(
hw
,
GMAC_IRQ_MSK
,
GMAC_DEF_MSK
);
reg
=
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
reg
=
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
if
(
skge
->
duplex
==
DUPLEX_FULL
||
skge
->
autoneg
==
AUTONEG_ENABLE
)
reg
|=
GM_GPCR_DUP_FULL
;
/* enable Rx/Tx */
reg
|=
GM_GPCR_RX_ENA
|
GM_GPCR_TX_ENA
;
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
skge_link_up
(
skge
);
}
...
...
@@ -1999,16 +1906,15 @@ static void yukon_link_down(struct skge_port *skge)
int
port
=
skge
->
port
;
pr_debug
(
"yukon_link_down
\n
"
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
skge_
gm_phy_write
(
hw
,
port
,
GM_GP_CTRL
,
skge_
gm_phy_read
(
hw
,
port
,
GM_GP_CTRL
)
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
gm_phy_write
(
hw
,
port
,
GM_GP_CTRL
,
gm_phy_read
(
hw
,
port
,
GM_GP_CTRL
)
&
~
(
GM_GPCR_RX_ENA
|
GM_GPCR_TX_ENA
));
if
(
hw
->
chip_id
!=
CHIP_ID_YUKON_FE
&&
skge
->
flow_control
==
FLOW_MODE_REM_SEND
)
{
if
(
skge
->
flow_control
==
FLOW_MODE_REM_SEND
)
{
/* restore Asymmetric Pause bit */
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
skge_
gm_phy_read
(
hw
,
port
,
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
gm_phy_read
(
hw
,
port
,
PHY_MARV_AUNE_ADV
)
|
PHY_M_AN_ASP
);
...
...
@@ -2027,20 +1933,21 @@ static void yukon_phy_intr(struct skge_port *skge)
const
char
*
reason
=
NULL
;
u16
istatus
,
phystat
;
istatus
=
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_INT_STAT
);
phystat
=
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_PHY_STAT
);
pr_debug
(
"yukon phy intr istat=%x phy_stat=%x
\n
"
,
istatus
,
phystat
);
istatus
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_INT_STAT
);
phystat
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_PHY_STAT
);
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: phy interrupt status 0x%x 0x%x
\n
"
,
skge
->
netdev
->
name
,
istatus
,
phystat
);
if
(
istatus
&
PHY_M_IS_AN_COMPL
)
{
if
(
skge_
gm_phy_read
(
hw
,
port
,
PHY_MARV_AUNE_LP
)
if
(
gm_phy_read
(
hw
,
port
,
PHY_MARV_AUNE_LP
)
&
PHY_M_AN_RF
)
{
reason
=
"remote fault"
;
goto
failed
;
}
if
(
!
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
||
hw
->
chip_id
==
CHIP_ID_YUKON_EC
)
&&
(
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_1000T_STAT
)
&
PHY_B_1000S_MSF
))
{
if
(
gm_phy_read
(
hw
,
port
,
PHY_MARV_1000T_STAT
)
&
PHY_B_1000S_MSF
)
{
reason
=
"master/slave fault"
;
goto
failed
;
}
...
...
@@ -2054,10 +1961,6 @@ static void yukon_phy_intr(struct skge_port *skge)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
skge
->
speed
=
yukon_speed
(
hw
,
phystat
);
/* Tx & Rx Pause Enabled bits are at 9..8 */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_XL
)
phystat
>>=
6
;
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
switch
(
phystat
&
PHY_M_PS_PAUSE_MSK
)
{
case
PHY_M_PS_PAUSE_MSK
:
...
...
@@ -2075,9 +1978,9 @@ static void yukon_phy_intr(struct skge_port *skge)
if
(
skge
->
flow_control
==
FLOW_MODE_NONE
||
(
skge
->
speed
<
SPEED_1000
&&
skge
->
duplex
==
DUPLEX_HALF
))
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
skge_write8
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
else
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
);
yukon_link_up
(
skge
);
return
;
}
...
...
@@ -2161,6 +2064,12 @@ static int skge_up(struct net_device *dev)
if
(
netif_msg_ifup
(
skge
))
printk
(
KERN_INFO
PFX
"%s: enabling interface
\n
"
,
dev
->
name
);
if
(
dev
->
mtu
>
RX_BUF_SIZE
)
skge
->
rx_buf_size
=
dev
->
mtu
+
ETH_HLEN
+
NET_IP_ALIGN
;
else
skge
->
rx_buf_size
=
RX_BUF_SIZE
;
rx_size
=
skge
->
rx_ring
.
count
*
sizeof
(
struct
skge_rx_desc
);
tx_size
=
skge
->
tx_ring
.
count
*
sizeof
(
struct
skge_tx_desc
);
skge
->
mem_size
=
tx_size
+
rx_size
;
...
...
@@ -2173,7 +2082,8 @@ static int skge_up(struct net_device *dev)
if
((
err
=
skge_ring_alloc
(
&
skge
->
rx_ring
,
skge
->
mem
,
skge
->
dma
)))
goto
free_pci_mem
;
if
(
skge_rx_fill
(
skge
))
err
=
skge_rx_fill
(
skge
);
if
(
err
)
goto
free_rx_ring
;
if
((
err
=
skge_ring_alloc
(
&
skge
->
tx_ring
,
skge
->
mem
+
rx_size
,
...
...
@@ -2182,6 +2092,10 @@ static int skge_up(struct net_device *dev)
skge
->
tx_avail
=
skge
->
tx_ring
.
count
-
1
;
/* Enable IRQ from port */
hw
->
intr_mask
|=
portirqmask
[
port
];
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
/* Initialze MAC */
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
genesis_mac_init
(
hw
,
port
);
...
...
@@ -2189,7 +2103,7 @@ static int skge_up(struct net_device *dev)
yukon_mac_init
(
hw
,
port
);
/* Configure RAMbuffers */
chunk
=
hw
->
ram_size
/
(
isdualport
(
hw
)
?
4
:
2
);
chunk
=
hw
->
ram_size
/
(
(
hw
->
ports
+
1
)
*
2
);
ram_addr
=
hw
->
ram_offset
+
2
*
chunk
*
port
;
skge_ramset
(
hw
,
rxqaddr
[
port
],
ram_addr
,
chunk
);
...
...
@@ -2227,7 +2141,6 @@ static int skge_down(struct net_device *dev)
netif_stop_queue
(
dev
);
del_timer_sync
(
&
skge
->
led_blink
);
del_timer_sync
(
&
skge
->
link_check
);
/* Stop transmitter */
skge_write8
(
hw
,
Q_ADDR
(
txqaddr
[
port
],
Q_CSR
),
CSR_STOP
);
...
...
@@ -2240,12 +2153,12 @@ static int skge_down(struct net_device *dev)
yukon_stop
(
skge
);
/* Disable Force Sync bit and Enable Alloc bit */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TXA_CTRL
),
skge_write8
(
hw
,
SK_REG
(
port
,
TXA_CTRL
),
TXA_DIS_FSYNC
|
TXA_DIS_ALLOC
|
TXA_STOP_RC
);
/* Stop Interval Timer and Limit Counter of Tx Arbiter */
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
TXA_ITI_INI
),
0L
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
TXA_LIM_INI
),
0L
);
skge_write32
(
hw
,
SK_REG
(
port
,
TXA_ITI_INI
),
0L
);
skge_write32
(
hw
,
SK_REG
(
port
,
TXA_LIM_INI
),
0L
);
/* Reset PCI FIFO */
skge_write32
(
hw
,
Q_ADDR
(
txqaddr
[
port
],
Q_CSR
),
CSR_SET_RESET
);
...
...
@@ -2260,13 +2173,13 @@ static int skge_down(struct net_device *dev)
skge_write32
(
hw
,
Q_ADDR
(
rxqaddr
[
port
],
Q_CSR
),
CSR_SET_RESET
);
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_LED_CTRL
),
LED_STOP
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_STOP
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_LED_CTRL
),
LED_STOP
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_STOP
);
}
else
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_SET
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_SET
);
}
/* turn off led's */
...
...
@@ -2333,7 +2246,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
* does. Looks like hardware is wrong?
*/
if
(
ip
->
protocol
==
IPPROTO_UDP
&&
chip_rev
(
hw
)
==
0
&&
hw
->
chip_id
==
CHIP_ID_YUKON
)
&&
hw
->
chip_rev
==
0
&&
hw
->
chip_id
==
CHIP_ID_YUKON
)
control
=
BMU_TCP_CHECK
;
else
control
=
BMU_UDP_CHECK
;
...
...
@@ -2394,6 +2307,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
static
inline
void
skge_tx_free
(
struct
skge_hw
*
hw
,
struct
skge_element
*
e
)
{
/* This ring element can be skb or fragment */
if
(
e
->
skb
)
{
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
...
...
@@ -2438,16 +2352,17 @@ static void skge_tx_timeout(struct net_device *dev)
static
int
skge_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
int
err
=
0
;
int
running
=
netif_running
(
dev
);
if
(
new_mtu
<
ETH_ZLEN
||
new_mtu
>
ETH_JUMBO_MTU
)
if
(
new_mtu
<
ETH_ZLEN
||
new_mtu
>
ETH_JUMBO_MTU
)
return
-
EINVAL
;
dev
->
mtu
=
new_mtu
;
if
(
netif_running
(
dev
))
{
if
(
running
)
skge_down
(
dev
);
dev
->
mtu
=
new_mtu
;
if
(
running
)
skge_up
(
dev
);
}
return
err
;
}
...
...
@@ -2462,7 +2377,9 @@ static void genesis_set_multicast(struct net_device *dev)
u32
mode
;
u8
filter
[
8
];
mode
=
skge_xm_read32
(
hw
,
port
,
XM_MODE
);
pr_debug
(
"genesis_set_multicast flags=%x count=%d
\n
"
,
dev
->
flags
,
dev
->
mc_count
);
mode
=
xm_read32
(
hw
,
port
,
XM_MODE
);
mode
|=
XM_MD_ENA_HASH
;
if
(
dev
->
flags
&
IFF_PROMISC
)
mode
|=
XM_MD_ENA_PROM
;
...
...
@@ -2473,17 +2390,16 @@ static void genesis_set_multicast(struct net_device *dev)
memset
(
filter
,
0xff
,
sizeof
(
filter
));
else
{
memset
(
filter
,
0
,
sizeof
(
filter
));
for
(
i
=
0
;
list
&&
i
<
count
;
i
++
,
list
=
list
->
next
)
{
u32
crc
=
crc32_le
(
~
0
,
list
->
dmi_addr
,
ETH_ALEN
)
;
u8
bit
=
63
-
(
crc
&
63
);
for
(
i
=
0
;
list
&&
i
<
count
;
i
++
,
list
=
list
->
next
)
{
u32
crc
,
bit
;
crc
=
ether_crc_le
(
ETH_ALEN
,
list
->
dmi_addr
);
bit
=
~
crc
&
0x3f
;
filter
[
bit
/
8
]
|=
1
<<
(
bit
%
8
);
}
}
skge_xm_outhash
(
hw
,
port
,
XM_HSM
,
filter
);
skge_xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
xm_outhash
(
hw
,
port
,
XM_HSM
,
filter
);
}
static
void
yukon_set_multicast
(
struct
net_device
*
dev
)
...
...
@@ -2497,7 +2413,7 @@ static void yukon_set_multicast(struct net_device *dev)
memset
(
filter
,
0
,
sizeof
(
filter
));
reg
=
skge_
gma_read16
(
hw
,
port
,
GM_RX_CTRL
);
reg
=
gma_read16
(
hw
,
port
,
GM_RX_CTRL
);
reg
|=
GM_RXCR_UCF_ENA
;
if
(
dev
->
flags
&
IFF_PROMISC
)
/* promiscious */
...
...
@@ -2510,23 +2426,23 @@ static void yukon_set_multicast(struct net_device *dev)
int
i
;
reg
|=
GM_RXCR_MCF_ENA
;
for
(
i
=
0
;
list
&&
i
<
dev
->
mc_count
;
i
++
,
list
=
list
->
next
)
{
for
(
i
=
0
;
list
&&
i
<
dev
->
mc_count
;
i
++
,
list
=
list
->
next
)
{
u32
bit
=
ether_crc
(
ETH_ALEN
,
list
->
dmi_addr
)
&
0x3f
;
filter
[
bit
/
8
]
|=
1
<<
(
bit
%
8
);
}
}
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
(
u16
)
filter
[
0
]
|
((
u16
)
filter
[
1
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
(
u16
)
filter
[
2
]
|
((
u16
)
filter
[
3
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
(
u16
)
filter
[
4
]
|
((
u16
)
filter
[
5
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
(
u16
)
filter
[
6
]
|
((
u16
)
filter
[
7
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
reg
);
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
reg
);
}
static
inline
int
bad_phy_status
(
const
struct
skge_hw
*
hw
,
u32
status
)
...
...
@@ -2545,11 +2461,9 @@ static void skge_rx_error(struct skge_port *skge, int slot,
printk
(
KERN_DEBUG
PFX
"%s: rx err, slot %d control 0x%x status 0x%x
\n
"
,
skge
->
netdev
->
name
,
slot
,
control
,
status
);
if
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
)
||
(
control
&
BMU_BBC
)
>
skge
->
netdev
->
mtu
+
VLAN_ETH_HLEN
)
if
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
))
skge
->
net_stats
.
rx_length_errors
++
;
else
{
if
(
skge
->
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
else
if
(
skge
->
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
status
&
(
XMR_FS_RUNT
|
XMR_FS_LNG_ERR
))
skge
->
net_stats
.
rx_length_errors
++
;
if
(
status
&
XMR_FS_FRA_ERR
)
...
...
@@ -2564,9 +2478,59 @@ static void skge_rx_error(struct skge_port *skge, int slot,
if
(
status
&
GMR_FS_CRC_ERR
)
skge
->
net_stats
.
rx_crc_errors
++
;
}
}
/* Get receive buffer from descriptor.
* Handles copy of small buffers and reallocation failures
*/
static
inline
struct
sk_buff
*
skge_rx_get
(
struct
skge_port
*
skge
,
struct
skge_element
*
e
,
unsigned
int
len
)
{
struct
sk_buff
*
nskb
,
*
skb
;
if
(
len
<
RX_COPY_THRESHOLD
)
{
nskb
=
skge_rx_alloc
(
skge
->
netdev
,
len
+
NET_IP_ALIGN
);
if
(
unlikely
(
!
nskb
))
return
NULL
;
pci_dma_sync_single_for_cpu
(
skge
->
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
len
,
PCI_DMA_FROMDEVICE
);
memcpy
(
nskb
->
data
,
e
->
skb
->
data
,
len
);
pci_dma_sync_single_for_device
(
skge
->
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
len
,
PCI_DMA_FROMDEVICE
);
if
(
skge
->
rx_csum
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
nskb
->
csum
=
le16_to_cpu
(
rd
->
csum2
);
nskb
->
ip_summed
=
CHECKSUM_HW
;
}
skge_rx_reuse
(
e
,
skge
->
rx_buf_size
);
return
nskb
;
}
else
{
nskb
=
skge_rx_alloc
(
skge
->
netdev
,
skge
->
rx_buf_size
);
if
(
unlikely
(
!
nskb
))
return
NULL
;
pci_unmap_single
(
skge
->
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_len
(
e
,
maplen
),
PCI_DMA_FROMDEVICE
);
skb
=
e
->
skb
;
if
(
skge
->
rx_csum
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
skb
->
csum
=
le16_to_cpu
(
rd
->
csum2
);
skb
->
ip_summed
=
CHECKSUM_HW
;
}
skge_rx_setup
(
skge
,
e
,
nskb
,
skge
->
rx_buf_size
);
return
skb
;
}
}
static
int
skge_poll
(
struct
net_device
*
dev
,
int
*
budget
)
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
...
...
@@ -2575,13 +2539,12 @@ static int skge_poll(struct net_device *dev, int *budget)
struct
skge_element
*
e
;
unsigned
int
to_do
=
min
(
dev
->
quota
,
*
budget
);
unsigned
int
work_done
=
0
;
int
done
;
static
const
u32
irqmask
[]
=
{
IS_PORT_1
,
IS_PORT_2
};
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
&&
work_done
<
to_do
;
e
=
e
->
next
)
{
pr_debug
(
"skge_poll
\n
"
);
for
(
e
=
ring
->
to_clean
;
work_done
<
to_do
;
e
=
e
->
next
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
struct
sk_buff
*
skb
=
e
->
skb
;
struct
sk_buff
*
skb
;
u32
control
,
len
,
status
;
rmb
();
...
...
@@ -2590,19 +2553,12 @@ static int skge_poll(struct net_device *dev, int *budget)
break
;
len
=
control
&
BMU_BBC
;
e
->
skb
=
NULL
;
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_len
(
e
,
maplen
),
PCI_DMA_FROMDEVICE
);
status
=
rd
->
status
;
if
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
)
||
len
>
dev
->
mtu
+
VLAN_ETH_HLEN
||
bad_phy_status
(
hw
,
status
))
{
if
(
unlikely
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
)
||
bad_phy_status
(
hw
,
status
)
))
{
skge_rx_error
(
skge
,
e
-
ring
->
start
,
control
,
status
);
dev_kfree_skb
(
skb
);
skge_rx_reuse
(
e
,
skge
->
rx_buf_size
);
continue
;
}
...
...
@@ -2610,43 +2566,37 @@ static int skge_poll(struct net_device *dev, int *budget)
printk
(
KERN_DEBUG
PFX
"%s: rx slot %td status 0x%x len %d
\n
"
,
dev
->
name
,
e
-
ring
->
start
,
rd
->
status
,
len
);
skb
=
skge_rx_get
(
skge
,
e
,
len
);
if
(
likely
(
skb
))
{
skb_put
(
skb
,
len
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
if
(
skge
->
rx_csum
)
{
skb
->
csum
=
le16_to_cpu
(
rd
->
csum2
);
skb
->
ip_summed
=
CHECKSUM_HW
;
}
dev
->
last_rx
=
jiffies
;
netif_receive_skb
(
skb
);
++
work_done
;
}
else
skge_rx_reuse
(
e
,
skge
->
rx_buf_size
);
}
ring
->
to_clean
=
e
;
*
budget
-=
work_done
;
dev
->
quota
-=
work_done
;
done
=
work_done
<
to_do
;
if
(
skge_rx_fill
(
skge
))
done
=
0
;
/* restart receiver */
wmb
();
skge_write8
(
hw
,
Q_ADDR
(
rxqaddr
[
skge
->
port
],
Q_CSR
),
CSR_START
|
CSR_IRQ_CL_F
);
if
(
done
)
{
*
budget
-=
work_done
;
dev
->
quota
-=
work_done
;
if
(
work_done
>=
to_do
)
return
1
;
/* not done */
local_irq_disable
();
hw
->
intr_mask
|=
irqmask
[
skge
->
port
];
/* Order is important since data can get interrupted */
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
__netif_rx_complete
(
dev
);
hw
->
intr_mask
|=
portirqmask
[
skge
->
port
];
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
local_irq_enable
();
}
return
!
done
;
return
0
;
}
static
inline
void
skge_tx_intr
(
struct
net_device
*
dev
)
...
...
@@ -2657,7 +2607,7 @@ static inline void skge_tx_intr(struct net_device *dev)
struct
skge_element
*
e
;
spin_lock
(
&
skge
->
tx_lock
);
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
;
e
=
e
->
next
)
{
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
;
e
=
e
->
next
)
{
struct
skge_tx_desc
*
td
=
e
->
desc
;
u32
control
;
...
...
@@ -2690,12 +2640,12 @@ static void skge_mac_parity(struct skge_hw *hw, int port)
:
(
port
==
0
?
"(port A)"
:
"(port B"
));
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_CLR_PERR
);
else
/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
chip_rev
(
hw
)
==
0
)
skge_write8
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
hw
->
chip_rev
==
0
)
?
GMF_CLI_TX_FC
:
GMF_CLI_TX_PE
);
}
...
...
@@ -2703,9 +2653,9 @@ static void skge_pci_clear(struct skge_hw *hw)
{
u16
status
;
status
=
skge_read16
(
hw
,
SKGEPCI_REG
(
PCI_STATUS
)
);
pci_read_config_word
(
hw
->
pdev
,
PCI_STATUS
,
&
status
);
skge_write8
(
hw
,
B2_TST_CTRL1
,
TST_CFG_WRITE_ON
);
skge_write16
(
hw
,
SKGEPCI_REG
(
PCI_STATUS
)
,
pci_write_config_word
(
hw
->
pdev
,
PCI_STATUS
,
status
|
PCI_STATUS_ERROR_BITS
);
skge_write8
(
hw
,
B2_TST_CTRL1
,
TST_CFG_WRITE_OFF
);
}
...
...
@@ -2726,9 +2676,9 @@ static void skge_error_irq(struct skge_hw *hw)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
/* clear xmac errors */
if
(
hwstatus
&
(
IS_NO_STAT_M1
|
IS_NO_TIST_M1
))
skge_write16
(
hw
,
SK
GEMAC
_REG
(
0
,
RX_MFF_CTRL1
),
MFF_CLR_INSTAT
);
skge_write16
(
hw
,
SK_REG
(
0
,
RX_MFF_CTRL1
),
MFF_CLR_INSTAT
);
if
(
hwstatus
&
(
IS_NO_STAT_M2
|
IS_NO_TIST_M2
))
skge_write16
(
hw
,
SK
GEMAC
_REG
(
0
,
RX_MFF_CTRL2
),
MFF_CLR_INSTAT
);
skge_write16
(
hw
,
SK_REG
(
0
,
RX_MFF_CTRL2
),
MFF_CLR_INSTAT
);
}
else
{
/* Timestamp (unused) overflow */
if
(
hwstatus
&
IS_IRQ_TIST_OV
)
...
...
@@ -2803,8 +2753,8 @@ static void skge_extirq(unsigned long data)
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
)
yukon_phy_intr
(
skge
);
else
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
genesis_bcom
_intr
(
skge
);
else
bcom_phy
_intr
(
skge
);
}
}
spin_unlock
(
&
hw
->
phy_lock
);
...
...
@@ -2824,19 +2774,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
return
IRQ_NONE
;
status
&=
hw
->
intr_mask
;
if
((
status
&
IS_R1_F
)
&&
netif_rx_schedule_prep
(
hw
->
dev
[
0
]))
{
status
&=
~
IS_R1_F
;
if
(
status
&
IS_R1_F
)
{
hw
->
intr_mask
&=
~
IS_R1_F
;
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
__netif_rx_schedule
(
hw
->
dev
[
0
]);
netif_rx_schedule
(
hw
->
dev
[
0
]);
}
if
((
status
&
IS_R2_F
)
&&
netif_rx_schedule_prep
(
hw
->
dev
[
1
]))
{
status
&=
~
IS_R2_F
;
if
(
status
&
IS_R2_F
)
{
hw
->
intr_mask
&=
~
IS_R2_F
;
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
__netif_rx_schedule
(
hw
->
dev
[
1
]);
netif_rx_schedule
(
hw
->
dev
[
1
]);
}
if
(
status
&
IS_XA1_F
)
...
...
@@ -2845,6 +2790,24 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
if
(
status
&
IS_XA2_F
)
skge_tx_intr
(
hw
->
dev
[
1
]);
if
(
status
&
IS_PA_TO_RX1
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
0
]);
++
skge
->
net_stats
.
rx_over_errors
;
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_RX1
);
}
if
(
status
&
IS_PA_TO_RX2
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
1
]);
++
skge
->
net_stats
.
rx_over_errors
;
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_RX2
);
}
if
(
status
&
IS_PA_TO_TX1
)
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_TX1
);
if
(
status
&
IS_PA_TO_TX2
)
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_TX2
);
if
(
status
&
IS_MAC1
)
skge_mac_intr
(
hw
,
0
);
...
...
@@ -2859,7 +2822,6 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
tasklet_schedule
(
&
hw
->
ext_tasklet
);
}
if
(
status
)
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
return
IRQ_HANDLED
;
...
...
@@ -2904,9 +2866,6 @@ static const struct {
{
CHIP_ID_YUKON
,
"Yukon"
},
{
CHIP_ID_YUKON_LITE
,
"Yukon-Lite"
},
{
CHIP_ID_YUKON_LP
,
"Yukon-LP"
},
{
CHIP_ID_YUKON_XL
,
"Yukon-2 XL"
},
{
CHIP_ID_YUKON_EC
,
"YUKON-2 EC"
},
{
CHIP_ID_YUKON_FE
,
"YUKON-2 FE"
},
};
static
const
char
*
skge_board_name
(
const
struct
skge_hw
*
hw
)
...
...
@@ -2930,8 +2889,8 @@ static const char *skge_board_name(const struct skge_hw *hw)
static
int
skge_reset
(
struct
skge_hw
*
hw
)
{
u16
ctst
;
u8
t8
;
int
i
,
ports
;
u8
t8
,
mac_cfg
;
int
i
;
ctst
=
skge_read16
(
hw
,
B0_CTST
);
...
...
@@ -2952,12 +2911,9 @@ static int skge_reset(struct skge_hw *hw)
hw
->
phy_type
=
skge_read8
(
hw
,
B2_E_1
)
&
0xf
;
hw
->
pmd_type
=
skge_read8
(
hw
,
B2_PMD_TYP
);
switch
(
hw
->
chip_id
)
{
switch
(
hw
->
chip_id
)
{
case
CHIP_ID_GENESIS
:
switch
(
hw
->
phy_type
)
{
case
SK_PHY_XMAC
:
hw
->
phy_addr
=
PHY_ADDR_XMAC
;
break
;
case
SK_PHY_BCOM
:
hw
->
phy_addr
=
PHY_ADDR_BCOM
;
break
;
...
...
@@ -2986,8 +2942,9 @@ static int skge_reset(struct skge_hw *hw)
return
-
EOPNOTSUPP
;
}
hw
->
mac_cfg
=
skge_read8
(
hw
,
B2_MAC_CFG
);
ports
=
isdualport
(
hw
)
?
2
:
1
;
mac_cfg
=
skge_read8
(
hw
,
B2_MAC_CFG
);
hw
->
ports
=
(
mac_cfg
&
CFG_SNG_MAC
)
?
1
:
2
;
hw
->
chip_rev
=
(
mac_cfg
&
CFG_CHIP_R_MSK
)
>>
4
;
/* read the adapters RAM size */
t8
=
skge_read8
(
hw
,
B2_E_0
);
...
...
@@ -3010,9 +2967,9 @@ static int skge_reset(struct skge_hw *hw)
/* switch power to VCC (WA for VAUX problem) */
skge_write8
(
hw
,
B0_POWER_CTRL
,
PC_VAUX_ENA
|
PC_VCC_ENA
|
PC_VAUX_OFF
|
PC_VCC_ON
);
for
(
i
=
0
;
i
<
ports
;
i
++
)
{
skge_write16
(
hw
,
SK
GEMAC
_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_SET
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_CLR
);
for
(
i
=
0
;
i
<
hw
->
ports
;
i
++
)
{
skge_write16
(
hw
,
SK_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_SET
);
skge_write16
(
hw
,
SK_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_CLR
);
}
}
...
...
@@ -3022,8 +2979,8 @@ static int skge_reset(struct skge_hw *hw)
skge_write8
(
hw
,
B0_LED
,
LED_STAT_ON
);
/* enable the Tx Arbiters */
for
(
i
=
0
;
i
<
ports
;
i
++
)
skge_write8
(
hw
,
SK
GEMAC
_REG
(
i
,
TXA_CTRL
),
TXA_ENA_ARB
);
for
(
i
=
0
;
i
<
hw
->
ports
;
i
++
)
skge_write8
(
hw
,
SK_REG
(
i
,
TXA_CTRL
),
TXA_ENA_ARB
);
/* Initialize ram interface */
skge_write16
(
hw
,
B3_RI_CTRL
,
RI_RST_CLR
);
...
...
@@ -3050,16 +3007,14 @@ static int skge_reset(struct skge_hw *hw)
skge_write32
(
hw
,
B2_IRQM_INI
,
skge_usecs2clk
(
hw
,
100
));
skge_write32
(
hw
,
B2_IRQM_CTRL
,
TIM_START
);
hw
->
intr_mask
=
IS_HW_ERR
|
IS_EXT_REG
|
IS_PORT_1
;
if
(
isdualport
(
hw
))
hw
->
intr_mask
|=
IS_PORT_2
;
hw
->
intr_mask
=
IS_HW_ERR
|
IS_EXT_REG
;
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
)
skge_write8
(
hw
,
GMAC_IRQ_MSK
,
0
);
spin_lock_bh
(
&
hw
->
phy_lock
);
for
(
i
=
0
;
i
<
ports
;
i
++
)
{
for
(
i
=
0
;
i
<
hw
->
ports
;
i
++
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
genesis_reset
(
hw
,
i
);
else
...
...
@@ -3071,7 +3026,8 @@ static int skge_reset(struct skge_hw *hw)
}
/* Initialize network device */
static
struct
net_device
*
skge_devinit
(
struct
skge_hw
*
hw
,
int
port
)
static
struct
net_device
*
skge_devinit
(
struct
skge_hw
*
hw
,
int
port
,
int
highmem
)
{
struct
skge_port
*
skge
;
struct
net_device
*
dev
=
alloc_etherdev
(
sizeof
(
*
skge
));
...
...
@@ -3104,6 +3060,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
#endif
dev
->
irq
=
hw
->
pdev
->
irq
;
dev
->
features
=
NETIF_F_LLTX
;
if
(
highmem
)
dev
->
features
|=
NETIF_F_HIGHDMA
;
skge
=
netdev_priv
(
dev
);
skge
->
netdev
=
dev
;
...
...
@@ -3117,7 +3075,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
skge
->
duplex
=
-
1
;
skge
->
speed
=
-
1
;
skge
->
advertising
=
skge_modes
(
hw
);
skge
->
advertising
=
skge_
supported_
modes
(
hw
);
hw
->
dev
[
port
]
=
dev
;
...
...
@@ -3125,10 +3083,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
spin_lock_init
(
&
skge
->
tx_lock
);
init_timer
(
&
skge
->
link_check
);
skge
->
link_check
.
function
=
skge_link_timer
;
skge
->
link_check
.
data
=
(
unsigned
long
)
skge
;
init_timer
(
&
skge
->
led_blink
);
skge
->
led_blink
.
function
=
skge_blink_timer
;
skge
->
led_blink
.
data
=
(
unsigned
long
)
skge
;
...
...
@@ -3232,14 +3186,11 @@ static int __devinit skge_probe(struct pci_dev *pdev,
printk
(
KERN_INFO
PFX
"addr 0x%lx irq %d chip %s rev %d
\n
"
,
pci_resource_start
(
pdev
,
0
),
pdev
->
irq
,
skge_board_name
(
hw
),
chip_rev
(
hw
)
);
skge_board_name
(
hw
),
hw
->
chip_rev
);
if
((
dev
=
skge_devinit
(
hw
,
0
))
==
NULL
)
if
((
dev
=
skge_devinit
(
hw
,
0
,
using_dac
))
==
NULL
)
goto
err_out_led_off
;
if
(
using_dac
)
dev
->
features
|=
NETIF_F_HIGHDMA
;
if
((
err
=
register_netdev
(
dev
)))
{
printk
(
KERN_ERR
PFX
"%s: cannot register net device
\n
"
,
pci_name
(
pdev
));
...
...
@@ -3248,10 +3199,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
skge_show_addr
(
dev
);
if
(
isdualport
(
hw
)
&&
(
dev1
=
skge_devinit
(
hw
,
1
)))
{
if
(
using_dac
)
dev1
->
features
|=
NETIF_F_HIGHDMA
;
if
(
hw
->
ports
>
1
&&
(
dev1
=
skge_devinit
(
hw
,
1
,
using_dac
)))
{
if
(
register_netdev
(
dev1
)
==
0
)
skge_show_addr
(
dev1
);
else
{
...
...
@@ -3288,7 +3236,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
struct
skge_hw
*
hw
=
pci_get_drvdata
(
pdev
);
struct
net_device
*
dev0
,
*
dev1
;
if
(
!
hw
)
if
(
!
hw
)
return
;
if
((
dev1
=
hw
->
dev
[
1
]))
...
...
@@ -3316,7 +3264,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state)
struct
skge_hw
*
hw
=
pci_get_drvdata
(
pdev
);
int
i
,
wol
=
0
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
struct
net_device
*
dev
=
hw
->
dev
[
i
];
if
(
dev
)
{
...
...
@@ -3349,11 +3297,11 @@ static int skge_resume(struct pci_dev *pdev)
skge_reset
(
hw
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
struct
net_device
*
dev
=
hw
->
dev
[
i
];
if
(
dev
)
{
netif_device_attach
(
dev
);
if
(
netif_running
(
dev
))
if
(
netif_running
(
dev
))
skge_up
(
dev
);
}
}
...
...
drivers/net/skge.h
View file @
245ac873
...
...
@@ -7,31 +7,6 @@
/* PCI config registers */
#define PCI_DEV_REG1 0x40
#define PCI_DEV_REG2 0x44
#ifndef PCI_VPD
#define PCI_VPD 0x50
#endif
/* PCI_OUR_REG_2 32 bit Our Register 2 */
enum
{
PCI_VPD_WR_THR
=
0xff
<<
24
,
/* Bit 31..24: VPD Write Threshold */
PCI_DEV_SEL
=
0x7f
<<
17
,
/* Bit 23..17: EEPROM Device Select */
PCI_VPD_ROM_SZ
=
7
<<
14
,
/* Bit 16..14: VPD ROM Size */
/* Bit 13..12: reserved */
PCI_EN_DUMMY_RD
=
1
<<
3
,
/* Enable Dummy Read */
PCI_REV_DESC
=
1
<<
2
,
/* Reverse Desc. Bytes */
PCI_USEDATA64
=
1
<<
0
,
/* Use 64Bit Data bus ext */
};
/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
enum
{
PCI_VPD_FLAG
=
1
<<
15
,
/* starts VPD rd/wr cycle */
PCI_VPD_ADR_MSK
=
0x7fffL
,
/* Bit 14.. 0: VPD Address Mask */
VPD_RES_ID
=
0x82
,
VPD_RES_READ
=
0x90
,
VPD_RES_WRITE
=
0x81
,
VPD_RES_END
=
0x78
,
};
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
...
...
@@ -39,7 +14,6 @@ enum {
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
enum
csr_regs
{
B0_RAP
=
0x0000
,
B0_CTST
=
0x0004
,
...
...
@@ -229,8 +203,11 @@ enum {
IS_XA2_F
=
1
<<
1
,
/* Q_XA2 End of Frame */
IS_XA2_C
=
1
<<
0
,
/* Q_XA2 Encoding Error */
IS_PORT_1
=
IS_XA1_F
|
IS_R1_F
|
IS_MAC1
,
IS_PORT_2
=
IS_XA2_F
|
IS_R2_F
|
IS_MAC2
,
IS_TO_PORT1
=
IS_PA_TO_RX1
|
IS_PA_TO_TX1
,
IS_TO_PORT2
=
IS_PA_TO_RX2
|
IS_PA_TO_TX2
,
IS_PORT_1
=
IS_XA1_F
|
IS_R1_F
|
IS_TO_PORT1
|
IS_MAC1
,
IS_PORT_2
=
IS_XA2_F
|
IS_R2_F
|
IS_TO_PORT2
|
IS_MAC2
,
};
...
...
@@ -288,14 +265,6 @@ enum {
CHIP_REV_YU_LITE_A3
=
7
,
/* Chip Rev. for YUKON-Lite A3 */
};
/* B2_LD_TEST 8 bit EPROM loader test register */
enum
{
LD_T_ON
=
1
<<
3
,
/* Loader Test mode on */
LD_T_OFF
=
1
<<
2
,
/* Loader Test mode off */
LD_T_STEP
=
1
<<
1
,
/* Decrement FPROM addr. Counter */
LD_START
=
1
<<
0
,
/* Start loading FPROM */
};
/* B2_TI_CTRL 8 bit Timer control */
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
enum
{
...
...
@@ -313,16 +282,6 @@ enum {
TIM_T_STEP
=
1
<<
0
,
/* Test step */
};
/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
enum
{
DPT_MSK
=
0x00ffffffL
,
/* Bit 23.. 0: Desc Poll Timer Bits */
DPT_START
=
1
<<
1
,
/* Start Descriptor Poll Timer */
DPT_STOP
=
1
<<
0
,
/* Stop Descriptor Poll Timer */
};
/* B2_GP_IO 32 bit General Purpose I/O Register */
enum
{
GP_DIR_9
=
1
<<
25
,
/* IO_9 direct, 0=In/1=Out */
...
...
@@ -348,30 +307,6 @@ enum {
GP_IO_0
=
1
<<
0
,
/* IO_0 pin */
};
/* Rx/Tx Path related Arbiter Test Registers */
/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
enum
{
TX2_T_EV
=
1
<<
15
,
/* TX2 Timeout/Recv Event occured */
TX2_T_ON
=
1
<<
14
,
/* TX2 Timeout/Recv Timer Test On */
TX2_T_OFF
=
1
<<
13
,
/* TX2 Timeout/Recv Timer Tst Off */
TX2_T_STEP
=
1
<<
12
,
/* TX2 Timeout/Recv Timer Step */
TX1_T_EV
=
1
<<
11
,
/* TX1 Timeout/Recv Event occured */
TX1_T_ON
=
1
<<
10
,
/* TX1 Timeout/Recv Timer Test On */
TX1_T_OFF
=
1
<<
9
,
/* TX1 Timeout/Recv Timer Tst Off */
TX1_T_STEP
=
1
<<
8
,
/* TX1 Timeout/Recv Timer Step */
RX2_T_EV
=
1
<<
7
,
/* RX2 Timeout/Recv Event occured */
RX2_T_ON
=
1
<<
6
,
/* RX2 Timeout/Recv Timer Test On */
RX2_T_OFF
=
1
<<
5
,
/* RX2 Timeout/Recv Timer Tst Off */
RX2_T_STEP
=
1
<<
4
,
/* RX2 Timeout/Recv Timer Step */
RX1_T_EV
=
1
<<
3
,
/* RX1 Timeout/Recv Event occured */
RX1_T_ON
=
1
<<
2
,
/* RX1 Timeout/Recv Timer Test On */
RX1_T_OFF
=
1
<<
1
,
/* RX1 Timeout/Recv Timer Tst Off */
RX1_T_STEP
=
1
<<
0
,
/* RX1 Timeout/Recv Timer Step */
};
/* Descriptor Bit Definition */
/* TxCtrl Transmit Buffer Control Field */
/* RxCtrl Receive Buffer Control Field */
...
...
@@ -428,14 +363,6 @@ enum {
RI_RST_SET
=
1
<<
0
,
/* Set RAM Interface Reset */
};
/* B3_RI_TEST 8 bit RAM Iface Test Register */
enum
{
RI_T_EV
=
1
<<
3
,
/* Timeout Event occured */
RI_T_ON
=
1
<<
2
,
/* Timeout Timer Test On */
RI_T_OFF
=
1
<<
1
,
/* Timeout Timer Test Off */
RI_T_STEP
=
1
<<
0
,
/* Timeout Timer Step */
};
/* MAC Arbiter Registers */
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
enum
{
...
...
@@ -452,19 +379,6 @@ enum {
#define SK_PKT_TO_MAX 0xffff
/* Maximum value */
#define SK_RI_TO_53 36
/* RAM interface timeout */
/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
enum
{
MA_ENA_REC_TX2
=
1
<<
7
,
/* Enable Recovery Timer TX2 */
MA_DIS_REC_TX2
=
1
<<
6
,
/* Disable Recovery Timer TX2 */
MA_ENA_REC_TX1
=
1
<<
5
,
/* Enable Recovery Timer TX1 */
MA_DIS_REC_TX1
=
1
<<
4
,
/* Disable Recovery Timer TX1 */
MA_ENA_REC_RX2
=
1
<<
3
,
/* Enable Recovery Timer RX2 */
MA_DIS_REC_RX2
=
1
<<
2
,
/* Disable Recovery Timer RX2 */
MA_ENA_REC_RX1
=
1
<<
1
,
/* Enable Recovery Timer RX1 */
MA_DIS_REC_RX1
=
1
<<
0
,
/* Disable Recovery Timer RX1 */
};
/* Packet Arbiter Registers */
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
enum
{
...
...
@@ -488,7 +402,7 @@ enum {
PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
/* Transmit Arbiter Registers MAC 1 and 2, use
MR_ADDR
() to access */
/* Transmit Arbiter Registers MAC 1 and 2, use
SK_REG
() to access */
/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
...
...
@@ -511,7 +425,7 @@ enum {
/*
* Bank 4 - 5
*/
/* Transmit Arbiter Registers MAC 1 and 2, use
MR_ADDR
() to access */
/* Transmit Arbiter Registers MAC 1 and 2, use
SK_REG
() to access */
enum
{
TXA_ITI_INI
=
0x0200
,
/* 32 bit Tx Arb Interval Timer Init Val*/
TXA_ITI_VAL
=
0x0204
,
/* 32 bit Tx Arb Interval Timer Value */
...
...
@@ -618,8 +532,7 @@ enum {
enum
{
PHY_ADDR_XMAC
=
0
<<
8
,
PHY_ADDR_BCOM
=
1
<<
8
,
PHY_ADDR_LONE
=
3
<<
8
,
PHY_ADDR_NAT
=
0
<<
8
,
/* GPHY address (bits 15..11 of SMI control reg) */
PHY_ADDR_MARV
=
0
,
};
...
...
@@ -1151,54 +1064,6 @@ enum {
PHY_MARV_FE_SPEC_2
=
0x1c
,
/* 16 bit r/w Specific Control Reg. 2 */
};
/* Level One-PHY Registers, indirect addressed over XMAC */
enum
{
PHY_LONE_CTRL
=
0x00
,
/* 16 bit r/w PHY Control Register */
PHY_LONE_STAT
=
0x01
,
/* 16 bit r/o PHY Status Register */
PHY_LONE_ID0
=
0x02
,
/* 16 bit r/o PHY ID0 Register */
PHY_LONE_ID1
=
0x03
,
/* 16 bit r/o PHY ID1 Register */
PHY_LONE_AUNE_ADV
=
0x04
,
/* 16 bit r/w Auto-Neg. Advertisement */
PHY_LONE_AUNE_LP
=
0x05
,
/* 16 bit r/o Link Part Ability Reg */
PHY_LONE_AUNE_EXP
=
0x06
,
/* 16 bit r/o Auto-Neg. Expansion Reg */
PHY_LONE_NEPG
=
0x07
,
/* 16 bit r/w Next Page Register */
PHY_LONE_NEPG_LP
=
0x08
,
/* 16 bit r/o Next Page Link Partner */
/* Level One-specific registers */
PHY_LONE_1000T_CTRL
=
0x09
,
/* 16 bit r/w 1000Base-T Control Reg */
PHY_LONE_1000T_STAT
=
0x0a
,
/* 16 bit r/o 1000Base-T Status Reg */
PHY_LONE_EXT_STAT
=
0x0f
,
/* 16 bit r/o Extended Status Reg */
PHY_LONE_PORT_CFG
=
0x10
,
/* 16 bit r/w Port Configuration Reg*/
PHY_LONE_Q_STAT
=
0x11
,
/* 16 bit r/o Quick Status Reg */
PHY_LONE_INT_ENAB
=
0x12
,
/* 16 bit r/w Interrupt Enable Reg */
PHY_LONE_INT_STAT
=
0x13
,
/* 16 bit r/o Interrupt Status Reg */
PHY_LONE_LED_CFG
=
0x14
,
/* 16 bit r/w LED Configuration Reg */
PHY_LONE_PORT_CTRL
=
0x15
,
/* 16 bit r/w Port Control Reg */
PHY_LONE_CIM
=
0x16
,
/* 16 bit r/o CIM Reg */
};
/* National-PHY Registers, indirect addressed over XMAC */
enum
{
PHY_NAT_CTRL
=
0x00
,
/* 16 bit r/w PHY Control Register */
PHY_NAT_STAT
=
0x01
,
/* 16 bit r/w PHY Status Register */
PHY_NAT_ID0
=
0x02
,
/* 16 bit r/o PHY ID0 Register */
PHY_NAT_ID1
=
0x03
,
/* 16 bit r/o PHY ID1 Register */
PHY_NAT_AUNE_ADV
=
0x04
,
/* 16 bit r/w Auto-Neg. Advertisement */
PHY_NAT_AUNE_LP
=
0x05
,
/* 16 bit r/o Link Partner Ability Reg */
PHY_NAT_AUNE_EXP
=
0x06
,
/* 16 bit r/o Auto-Neg. Expansion Reg */
PHY_NAT_NEPG
=
0x07
,
/* 16 bit r/w Next Page Register */
PHY_NAT_NEPG_LP
=
0x08
,
/* 16 bit r/o Next Page Link Partner Reg */
/* National-specific registers */
PHY_NAT_1000T_CTRL
=
0x09
,
/* 16 bit r/w 1000Base-T Control Reg */
PHY_NAT_1000T_STAT
=
0x0a
,
/* 16 bit r/o 1000Base-T Status Reg */
PHY_NAT_EXT_STAT
=
0x0f
,
/* 16 bit r/o Extended Status Register */
PHY_NAT_EXT_CTRL1
=
0x10
,
/* 16 bit r/o Extended Control Reg1 */
PHY_NAT_Q_STAT1
=
0x11
,
/* 16 bit r/o Quick Status Reg1 */
PHY_NAT_10B_OP
=
0x12
,
/* 16 bit r/o 10Base-T Operations Reg */
PHY_NAT_EXT_CTRL2
=
0x13
,
/* 16 bit r/o Extended Control Reg1 */
PHY_NAT_Q_STAT2
=
0x14
,
/* 16 bit r/o Quick Status Reg2 */
PHY_NAT_PHY_ADDR
=
0x19
,
/* 16 bit r/o PHY Address Register */
};
enum
{
PHY_CT_RESET
=
1
<<
15
,
/* Bit 15: (sc) clear all PHY related regs */
PHY_CT_LOOP
=
1
<<
14
,
/* Bit 14: enable Loopback over PHY */
...
...
@@ -1253,8 +1118,29 @@ enum {
PHY_MARV_ID1_Y2
=
0x0C91
,
/* Yukon-2 (PHY 88E1112) */
};
/* Advertisement register bits */
enum
{
PHY_AN_NXT_PG
=
1
<<
15
,
/* Bit 15: Request Next Page */
PHY_AN_ACK
=
1
<<
14
,
/* Bit 14: (ro) Acknowledge Received */
PHY_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault Bits */
PHY_AN_PAUSE_ASYM
=
1
<<
11
,
/* Bit 11: Try for asymmetric */
PHY_AN_PAUSE_CAP
=
1
<<
10
,
/* Bit 10: Try for pause */
PHY_AN_100BASE4
=
1
<<
9
,
/* Bit 9: Try for 100mbps 4k packets */
PHY_AN_100FULL
=
1
<<
8
,
/* Bit 8: Try for 100mbps full-duplex */
PHY_AN_100HALF
=
1
<<
7
,
/* Bit 7: Try for 100mbps half-duplex */
PHY_AN_10FULL
=
1
<<
6
,
/* Bit 6: Try for 10mbps full-duplex */
PHY_AN_10HALF
=
1
<<
5
,
/* Bit 5: Try for 10mbps half-duplex */
PHY_AN_CSMA
=
1
<<
0
,
/* Bit 0: Only selector supported */
PHY_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
PHY_AN_FULL
=
PHY_AN_100FULL
|
PHY_AN_10FULL
|
PHY_AN_CSMA
,
PHY_AN_ALL
=
PHY_AN_10HALF
|
PHY_AN_10FULL
|
PHY_AN_100HALF
|
PHY_AN_100FULL
,
};
/* Xmac Specific */
enum
{
PHY_X_AN_NXT_PG
=
1
<<
15
,
/* Bit 15: Request Next Page */
PHY_X_AN_ACK
=
1
<<
14
,
/* Bit 14: (ro) Acknowledge Received */
PHY_X_AN_RFB
=
3
<<
12
,
/* Bit 13..12: Remote Fault Bits */
...
...
@@ -1263,82 +1149,6 @@ enum {
PHY_X_AN_FD
=
1
<<
5
,
/* Bit 5: Full Duplex */
};
enum
{
PHY_B_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
PHY_B_AN_ASP
=
1
<<
11
,
/* Bit 11: Asymmetric Pause */
PHY_B_AN_PC
=
1
<<
10
,
/* Bit 10: Pause Capable */
PHY_B_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
};
enum
{
PHY_L_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
/* Bit 12: reserved */
PHY_L_AN_ASP
=
1
<<
11
,
/* Bit 11: Asymmetric Pause */
PHY_L_AN_PC
=
1
<<
10
,
/* Bit 10: Pause Capable */
PHY_L_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
};
/* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */
/* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
enum
{
PHY_N_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
PHY_N_AN_100F
=
1
<<
11
,
/* Bit 11: 100Base-T2 FD Support */
PHY_N_AN_100H
=
1
<<
10
,
/* Bit 10: 100Base-T2 HD Support */
PHY_N_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
};
/* field type definition for PHY_x_AN_SEL */
enum
{
PHY_SEL_TYPE
=
1
,
/* 00001 = Ethernet */
};
enum
{
PHY_ANE_LP_NP
=
1
<<
3
,
/* Bit 3: Link Partner can Next Page */
PHY_ANE_LOC_NP
=
1
<<
2
,
/* Bit 2: Local PHY can Next Page */
PHY_ANE_RX_PG
=
1
<<
1
,
/* Bit 1: Page Received */
};
enum
{
PHY_ANE_PAR_DF
=
1
<<
4
,
/* Bit 4: Parallel Detection Fault */
PHY_ANE_LP_CAP
=
1
<<
0
,
/* Bit 0: Link Partner Auto-Neg. Cap. */
};
enum
{
PHY_NP_MORE
=
1
<<
15
,
/* Bit 15: More, Next Pages to follow */
PHY_NP_ACK1
=
1
<<
14
,
/* Bit 14: (ro) Ack1, for receiving a message */
PHY_NP_MSG_VAL
=
1
<<
13
,
/* Bit 13: Message Page valid */
PHY_NP_ACK2
=
1
<<
12
,
/* Bit 12: Ack2, comply with msg content */
PHY_NP_TOG
=
1
<<
11
,
/* Bit 11: Toggle Bit, ensure sync */
PHY_NP_MSG
=
0x07ff
,
/* Bit 10..0: Message from/to Link Partner */
};
enum
{
PHY_X_EX_FD
=
1
<<
15
,
/* Bit 15: Device Supports Full Duplex */
PHY_X_EX_HD
=
1
<<
14
,
/* Bit 14: Device Supports Half Duplex */
};
enum
{
PHY_X_RS_PAUSE
=
3
<<
7
,
/* Bit 8..7: selected Pause Mode */
PHY_X_RS_HD
=
1
<<
6
,
/* Bit 6: Half Duplex Mode selected */
PHY_X_RS_FD
=
1
<<
5
,
/* Bit 5: Full Duplex Mode selected */
PHY_X_RS_ABLMIS
=
1
<<
4
,
/* Bit 4: duplex or pause cap mismatch */
PHY_X_RS_PAUMIS
=
1
<<
3
,
/* Bit 3: pause capability mismatch */
};
/** Remote Fault Bits (PHY_X_AN_RFB) encoding */
enum
{
X_RFB_OK
=
0
<<
12
,
/* Bit 13..12 No errors, Link OK */
X_RFB_LF
=
1
<<
12
,
/* Bit 13..12 Link Failure */
X_RFB_OFF
=
2
<<
12
,
/* Bit 13..12 Offline */
X_RFB_AN_ERR
=
3
<<
12
,
/* Bit 13..12 Auto-Negotiation Error */
};
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
enum
{
PHY_X_P_NO_PAUSE
=
0
<<
7
,
/* Bit 8..7: no Pause Mode */
...
...
@@ -1418,6 +1228,16 @@ enum {
PHY_B_PES_MLT3_ER
=
1
<<
0
,
/* Bit 0: MLT3 code Error */
};
/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
enum
{
PHY_B_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
PHY_B_AN_ASP
=
1
<<
11
,
/* Bit 11: Asymmetric Pause */
PHY_B_AN_PC
=
1
<<
10
,
/* Bit 10: Pause Capable */
};
/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
enum
{
PHY_B_FC_CTR
=
0xff
,
/* Bit 7..0: False Carrier Counter */
...
...
@@ -1478,7 +1298,9 @@ enum {
PHY_B_IS_LST_CHANGE
=
1
<<
1
,
/* Bit 1: Link Status Changed */
PHY_B_IS_CRC_ER
=
1
<<
0
,
/* Bit 0: CRC Error */
};
#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
#define PHY_B_DEF_MSK \
(~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
enum
{
...
...
@@ -1495,166 +1317,6 @@ enum {
PHY_B_RES_1000HD
=
6
<<
8
,
/* Bit 10..8: 1000Base-T Half Dup. */
};
/*
* Level One-Specific
*/
/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
enum
{
PHY_L_1000C_TEST
=
7
<<
13
,
/* Bit 15..13: Test Modes */
PHY_L_1000C_MSE
=
1
<<
12
,
/* Bit 12: Master/Slave Enable */
PHY_L_1000C_MSC
=
1
<<
11
,
/* Bit 11: M/S Configuration */
PHY_L_1000C_RD
=
1
<<
10
,
/* Bit 10: Repeater/DTE */
PHY_L_1000C_AFD
=
1
<<
9
,
/* Bit 9: Advertise Full Duplex */
PHY_L_1000C_AHD
=
1
<<
8
,
/* Bit 8: Advertise Half Duplex */
};
/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
enum
{
PHY_L_1000S_MSF
=
1
<<
15
,
/* Bit 15: Master/Slave Fault */
PHY_L_1000S_MSR
=
1
<<
14
,
/* Bit 14: Master/Slave Result */
PHY_L_1000S_LRS
=
1
<<
13
,
/* Bit 13: Local Receiver Status */
PHY_L_1000S_RRS
=
1
<<
12
,
/* Bit 12: Remote Receiver Status */
PHY_L_1000S_LP_FD
=
1
<<
11
,
/* Bit 11: Link Partner can FD */
PHY_L_1000S_LP_HD
=
1
<<
10
,
/* Bit 10: Link Partner can HD */
PHY_L_1000S_IEC
=
0xff
,
/* Bit 7..0: Idle Error Count */
/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
PHY_L_ES_X_FD_CAP
=
1
<<
15
,
/* Bit 15: 1000Base-X FD capable */
PHY_L_ES_X_HD_CAP
=
1
<<
14
,
/* Bit 14: 1000Base-X HD capable */
PHY_L_ES_T_FD_CAP
=
1
<<
13
,
/* Bit 13: 1000Base-T FD capable */
PHY_L_ES_T_HD_CAP
=
1
<<
12
,
/* Bit 12: 1000Base-T HD capable */
};
/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
enum
{
PHY_L_PC_REP_MODE
=
1
<<
15
,
/* Bit 15: Repeater Mode */
PHY_L_PC_TX_DIS
=
1
<<
13
,
/* Bit 13: Tx output Disabled */
PHY_L_PC_BY_SCR
=
1
<<
12
,
/* Bit 12: Bypass Scrambler */
PHY_L_PC_BY_45
=
1
<<
11
,
/* Bit 11: Bypass 4B5B-Decoder */
PHY_L_PC_JAB_DIS
=
1
<<
10
,
/* Bit 10: Jabber Disabled */
PHY_L_PC_SQE
=
1
<<
9
,
/* Bit 9: Enable Heartbeat */
PHY_L_PC_TP_LOOP
=
1
<<
8
,
/* Bit 8: TP Loopback */
PHY_L_PC_SSS
=
1
<<
7
,
/* Bit 7: Smart Speed Selection */
PHY_L_PC_FIFO_SIZE
=
1
<<
6
,
/* Bit 6: FIFO Size */
PHY_L_PC_PRE_EN
=
1
<<
5
,
/* Bit 5: Preamble Enable */
PHY_L_PC_CIM
=
1
<<
4
,
/* Bit 4: Carrier Integrity Mon */
PHY_L_PC_10_SER
=
1
<<
3
,
/* Bit 3: Use Serial Output */
PHY_L_PC_ANISOL
=
1
<<
2
,
/* Bit 2: Unisolate Port */
PHY_L_PC_TEN_BIT
=
1
<<
1
,
/* Bit 1: 10bit iface mode on */
PHY_L_PC_ALTCLOCK
=
1
<<
0
,
/* Bit 0: (ro) ALTCLOCK Mode on */
};
/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
enum
{
PHY_L_QS_D_RATE
=
3
<<
14
,
/* Bit 15..14: Data Rate */
PHY_L_QS_TX_STAT
=
1
<<
13
,
/* Bit 13: Transmitting */
PHY_L_QS_RX_STAT
=
1
<<
12
,
/* Bit 12: Receiving */
PHY_L_QS_COL_STAT
=
1
<<
11
,
/* Bit 11: Collision */
PHY_L_QS_L_STAT
=
1
<<
10
,
/* Bit 10: Link is up */
PHY_L_QS_DUP_MOD
=
1
<<
9
,
/* Bit 9: Full/Half Duplex */
PHY_L_QS_AN
=
1
<<
8
,
/* Bit 8: AutoNeg is On */
PHY_L_QS_AN_C
=
1
<<
7
,
/* Bit 7: AN is Complete */
PHY_L_QS_LLE
=
7
<<
4
,
/* Bit 6..4: Line Length Estim. */
PHY_L_QS_PAUSE
=
1
<<
3
,
/* Bit 3: LP advertised Pause */
PHY_L_QS_AS_PAUSE
=
1
<<
2
,
/* Bit 2: LP adv. asym. Pause */
PHY_L_QS_ISOLATE
=
1
<<
1
,
/* Bit 1: CIM Isolated */
PHY_L_QS_EVENT
=
1
<<
0
,
/* Bit 0: Event has occurred */
};
/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
enum
{
PHY_L_IS_AN_F
=
1
<<
13
,
/* Bit 13: Auto-Negotiation fault */
PHY_L_IS_CROSS
=
1
<<
11
,
/* Bit 11: Crossover used */
PHY_L_IS_POL
=
1
<<
10
,
/* Bit 10: Polarity correct. used */
PHY_L_IS_SS
=
1
<<
9
,
/* Bit 9: Smart Speed Downgrade */
PHY_L_IS_CFULL
=
1
<<
8
,
/* Bit 8: Counter Full */
PHY_L_IS_AN_C
=
1
<<
7
,
/* Bit 7: AutoNeg Complete */
PHY_L_IS_SPEED
=
1
<<
6
,
/* Bit 6: Speed Changed */
PHY_L_IS_DUP
=
1
<<
5
,
/* Bit 5: Duplex Changed */
PHY_L_IS_LS
=
1
<<
4
,
/* Bit 4: Link Status Changed */
PHY_L_IS_ISOL
=
1
<<
3
,
/* Bit 3: Isolate Occured */
PHY_L_IS_MDINT
=
1
<<
2
,
/* Bit 2: (ro) STAT: MII Int Pending */
PHY_L_IS_INTEN
=
1
<<
1
,
/* Bit 1: ENAB: Enable IRQs */
PHY_L_IS_FORCE
=
1
<<
0
,
/* Bit 0: ENAB: Force Interrupt */
};
/* int. mask */
#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
enum
{
PHY_L_LC_LEDC
=
3
<<
14
,
/* Bit 15..14: Col/Blink/On/Off */
PHY_L_LC_LEDR
=
3
<<
12
,
/* Bit 13..12: Rx/Blink/On/Off */
PHY_L_LC_LEDT
=
3
<<
10
,
/* Bit 11..10: Tx/Blink/On/Off */
PHY_L_LC_LEDG
=
3
<<
8
,
/* Bit 9..8: Giga/Blink/On/Off */
PHY_L_LC_LEDS
=
3
<<
6
,
/* Bit 7..6: 10-100/Blink/On/Off */
PHY_L_LC_LEDL
=
3
<<
4
,
/* Bit 5..4: Link/Blink/On/Off */
PHY_L_LC_LEDF
=
3
<<
2
,
/* Bit 3..2: Duplex/Blink/On/Off */
PHY_L_LC_PSTRECH
=
1
<<
1
,
/* Bit 1: Strech LED Pulses */
PHY_L_LC_FREQ
=
1
<<
0
,
/* Bit 0: 30/100 ms */
};
/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
enum
{
PHY_L_PC_TX_TCLK
=
1
<<
15
,
/* Bit 15: Enable TX_TCLK */
PHY_L_PC_ALT_NP
=
1
<<
13
,
/* Bit 14: Alternate Next Page */
PHY_L_PC_GMII_ALT
=
1
<<
12
,
/* Bit 13: Alternate GMII driver */
PHY_L_PC_TEN_CRS
=
1
<<
10
,
/* Bit 10: Extend CRS*/
};
/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
enum
{
PHY_L_CIM_ISOL
=
0xff
<<
8
,
/* Bit 15..8: Isolate Count */
PHY_L_CIM_FALSE_CAR
=
0xff
,
/* Bit 7..0: False Carrier Count */
};
/*
* Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
*/
enum
{
PHY_L_P_NO_PAUSE
=
0
<<
10
,
/* Bit 11..10: no Pause Mode */
PHY_L_P_SYM_MD
=
1
<<
10
,
/* Bit 11..10: symmetric Pause Mode */
PHY_L_P_ASYM_MD
=
2
<<
10
,
/* Bit 11..10: asymmetric Pause Mode */
PHY_L_P_BOTH_MD
=
3
<<
10
,
/* Bit 11..10: both Pause Mode */
};
/*
* National-Specific
*/
/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
enum
{
PHY_N_1000C_TEST
=
7
<<
13
,
/* Bit 15..13: Test Modes */
PHY_N_1000C_MSE
=
1
<<
12
,
/* Bit 12: Master/Slave Enable */
PHY_N_1000C_MSC
=
1
<<
11
,
/* Bit 11: M/S Configuration */
PHY_N_1000C_RD
=
1
<<
10
,
/* Bit 10: Repeater/DTE */
PHY_N_1000C_AFD
=
1
<<
9
,
/* Bit 9: Advertise Full Duplex */
PHY_N_1000C_AHD
=
1
<<
8
,
/* Bit 8: Advertise Half Duplex */
PHY_N_1000C_APC
=
1
<<
7
,
/* Bit 7: Asymmetric Pause Cap. */
};
/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
enum
{
PHY_N_1000S_MSF
=
1
<<
15
,
/* Bit 15: Master/Slave Fault */
PHY_N_1000S_MSR
=
1
<<
14
,
/* Bit 14: Master/Slave Result */
PHY_N_1000S_LRS
=
1
<<
13
,
/* Bit 13: Local Receiver Status */
PHY_N_1000S_RRS
=
1
<<
12
,
/* Bit 12: Remote Receiver Status*/
PHY_N_1000S_LP_FD
=
1
<<
11
,
/* Bit 11: Link Partner can FD */
PHY_N_1000S_LP_HD
=
1
<<
10
,
/* Bit 10: Link Partner can HD */
PHY_N_1000C_LP_APC
=
1
<<
9
,
/* Bit 9: LP Asym. Pause Cap. */
PHY_N_1000S_IEC
=
0xff
,
/* Bit 7..0: Idle Error Count */
};
/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
enum
{
PHY_N_ES_X_FD_CAP
=
1
<<
15
,
/* Bit 15: 1000Base-X FD capable */
PHY_N_ES_X_HD_CAP
=
1
<<
14
,
/* Bit 14: 1000Base-X HD capable */
PHY_N_ES_T_FD_CAP
=
1
<<
13
,
/* Bit 13: 1000Base-T FD capable */
PHY_N_ES_T_HD_CAP
=
1
<<
12
,
/* Bit 12: 1000Base-T HD capable */
};
/** Marvell-Specific */
enum
{
PHY_M_AN_NXT_PG
=
1
<<
15
,
/* Request Next Page */
...
...
@@ -2540,10 +2202,6 @@ enum {
};
/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
#define XM_PHY_ADDR_SZ 0x1f
/* Bit 4..0: PHY Address bits */
/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
enum
{
XM_GP_ANIP
=
1
<<
6
,
/* Bit 6: (ro) Auto-Neg. in progress */
...
...
@@ -2663,7 +2321,7 @@ enum {
#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CA
A)
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CS
A)
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
enum
{
...
...
@@ -2793,11 +2451,12 @@ struct skge_hw {
u32
intr_mask
;
struct
net_device
*
dev
[
2
];
u8
mac_cfg
;
u8
chip_id
;
u8
chip_rev
;
u8
phy_type
;
u8
pmd_type
;
u16
phy_addr
;
u8
ports
;
u32
ram_size
;
u32
ram_offset
;
...
...
@@ -2806,15 +2465,6 @@ struct skge_hw {
spinlock_t
phy_lock
;
};
static
inline
int
isdualport
(
const
struct
skge_hw
*
hw
)
{
return
!
(
hw
->
mac_cfg
&
CFG_SNG_MAC
);
}
static
inline
u8
chip_rev
(
const
struct
skge_hw
*
hw
)
{
return
(
hw
->
mac_cfg
&
CFG_CHIP_R_MSK
)
>>
4
;
}
static
inline
int
iscopper
(
const
struct
skge_hw
*
hw
)
{
...
...
@@ -2853,8 +2503,8 @@ struct skge_port {
void
*
mem
;
/* PCI memory for rings */
dma_addr_t
dma
;
unsigned
long
mem_size
;
unsigned
int
rx_buf_size
;
struct
timer_list
link_check
;
struct
timer_list
led_blink
;
};
...
...
@@ -2863,7 +2513,6 @@ struct skge_port {
static
inline
u32
skge_read32
(
const
struct
skge_hw
*
hw
,
int
reg
)
{
return
readl
(
hw
->
regs
+
reg
);
}
static
inline
u16
skge_read16
(
const
struct
skge_hw
*
hw
,
int
reg
)
...
...
@@ -2892,114 +2541,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
}
/* MAC Related Registers inside the device. */
#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg))
/* PCI config space can be accessed via memory mapped space */
#define SKGEPCI_REG(reg) ((reg)+ 0x380)
#define SKGEXM_REG(port, reg) \
#define SK_REG(port,reg) (((port)<<7)+(reg))
#define SK_XMAC_REG(port, reg) \
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
static
inline
u32
skge_
xm_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u32
xm_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
return
skge_read32
(
hw
,
SKGEXM_REG
(
port
,
reg
));
u32
v
;
v
=
skge_read16
(
hw
,
SK_XMAC_REG
(
port
,
reg
));
v
|=
(
u32
)
skge_read16
(
hw
,
SK_XMAC_REG
(
port
,
reg
+
2
))
<<
16
;
return
v
;
}
static
inline
u16
skge_
xm_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u16
xm_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
return
skge_read16
(
hw
,
SK
GEXM
_REG
(
port
,
reg
));
return
skge_read16
(
hw
,
SK
_XMAC
_REG
(
port
,
reg
));
}
static
inline
u8
skge_xm_read8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
void
xm_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
{
return
skge_read8
(
hw
,
SKGEXM_REG
(
port
,
reg
));
skge_write16
(
hw
,
SK_XMAC_REG
(
port
,
r
),
v
&
0xffff
);
skge_write16
(
hw
,
SK_XMAC_REG
(
port
,
r
+
2
),
v
>>
16
);
}
static
inline
void
skge_xm_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
static
inline
void
xm_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
{
skge_write
32
(
hw
,
SKGEXM
_REG
(
port
,
r
),
v
);
skge_write
16
(
hw
,
SK_XMAC
_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_xm_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
{
skge_write16
(
hw
,
SKGEXM_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_xm_write8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u8
v
)
{
skge_write8
(
hw
,
SKGEXM_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_xm_outhash
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
static
inline
void
xm_outhash
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
const
u8
*
hash
)
{
skge_xm_write16
(
hw
,
port
,
reg
,
(
u16
)
hash
[
0
]
|
((
u16
)
hash
[
1
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
+
2
,
(
u16
)
hash
[
2
]
|
((
u16
)
hash
[
3
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
hash
[
4
]
|
((
u16
)
hash
[
5
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
+
6
,
(
u16
)
hash
[
6
]
|
((
u16
)
hash
[
7
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
,
(
u16
)
hash
[
0
]
|
((
u16
)
hash
[
1
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
2
,
(
u16
)
hash
[
2
]
|
((
u16
)
hash
[
3
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
hash
[
4
]
|
((
u16
)
hash
[
5
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
6
,
(
u16
)
hash
[
6
]
|
((
u16
)
hash
[
7
]
<<
8
));
}
static
inline
void
skge_
xm_outaddr
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
static
inline
void
xm_outaddr
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
const
u8
*
addr
)
{
skge_xm_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
2
,
(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
}
#define SK_GMAC_REG(port,reg) \
(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
#define SKGEGMA_REG(port,reg) \
((reg) + BASE_GMAC_1 + \
(port) * (BASE_GMAC_2-BASE_GMAC_1))
static
inline
u16
skge_gma_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
return
skge_read16
(
hw
,
SKGEGMA_REG
(
port
,
reg
));
}
static
inline
u32
skge_gma_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u16
gma_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
return
(
u32
)
skge_read16
(
hw
,
SKGEGMA_REG
(
port
,
reg
))
|
((
u32
)
skge_read16
(
hw
,
SKGEGMA_REG
(
port
,
reg
+
4
))
<<
16
);
return
skge_read16
(
hw
,
SK_GMAC_REG
(
port
,
reg
));
}
static
inline
u
8
skge_gma_read8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u
32
gma_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
return
skge_read8
(
hw
,
SKGEGMA_REG
(
port
,
reg
));
return
(
u32
)
skge_read16
(
hw
,
SK_GMAC_REG
(
port
,
reg
))
|
((
u32
)
skge_read16
(
hw
,
SK_GMAC_REG
(
port
,
reg
+
4
))
<<
16
);
}
static
inline
void
skge_
gma_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
static
inline
void
gma_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
{
skge_write16
(
hw
,
SK
GEGMA
_REG
(
port
,
r
),
v
);
skge_write16
(
hw
,
SK
_GMAC
_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_
gma_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
static
inline
void
gma_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
{
skge_write16
(
hw
,
SK
GEGMA
_REG
(
port
,
r
),
(
u16
)
v
);
skge_write32
(
hw
,
SK
GEGMA
_REG
(
port
,
r
+
4
),
(
u16
)(
v
>>
16
));
skge_write16
(
hw
,
SK
_GMAC
_REG
(
port
,
r
),
(
u16
)
v
);
skge_write32
(
hw
,
SK
_GMAC
_REG
(
port
,
r
+
4
),
(
u16
)(
v
>>
16
));
}
static
inline
void
skge_
gma_write8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u8
v
)
static
inline
void
gma_write8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u8
v
)
{
skge_write8
(
hw
,
SK
GEGMA
_REG
(
port
,
r
),
v
);
skge_write8
(
hw
,
SK
_GMAC
_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_gm
_set_addr
(
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
static
inline
void
gma
_set_addr
(
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
const
u8
*
addr
)
{
skge_gma_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
skge_gma_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
skge_gma_write16
(
hw
,
port
,
reg
+
8
,
(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
gma_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
gma_write16
(
hw
,
port
,
reg
+
4
,(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
gma_write16
(
hw
,
port
,
reg
+
8
,(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
}
#endif
include/linux/etherdevice.h
View file @
245ac873
...
...
@@ -65,7 +65,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
*/
static
inline
int
is_multicast_ether_addr
(
const
u8
*
addr
)
{
return
addr
[
0
]
&
0x01
;
return
((
addr
[
0
]
!=
0xff
)
&&
(
0x01
&
addr
[
0
]))
;
}
/**
...
...
include/net/ieee80211.h
View file @
245ac873
...
...
@@ -625,17 +625,6 @@ enum ieee80211_state {
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
extern
inline
int
is_multicast_ether_addr
(
const
u8
*
addr
)
{
return
((
addr
[
0
]
!=
0xff
)
&&
(
0x01
&
addr
[
0
]));
}
extern
inline
int
is_broadcast_ether_addr
(
const
u8
*
addr
)
{
return
((
addr
[
0
]
==
0xff
)
&&
(
addr
[
1
]
==
0xff
)
&&
(
addr
[
2
]
==
0xff
)
&&
\
(
addr
[
3
]
==
0xff
)
&&
(
addr
[
4
]
==
0xff
)
&&
(
addr
[
5
]
==
0xff
));
}
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
...
...
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