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
bb092c0d
Commit
bb092c0d
authored
Mar 11, 2012
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'davem-next.r8169' of
git://violet.fr.zoreil.com/romieu/linux
parents
a320757a
92a7c4e7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
971 additions
and
995 deletions
+971
-995
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/realtek/r8169.c
+971
-995
No files found.
drivers/net/ethernet/realtek/r8169.c
View file @
bb092c0d
...
...
@@ -255,10 +255,6 @@ enum cfg_version {
RTL_CFG_2
};
static
void
rtl_hw_start_8169
(
struct
net_device
*
);
static
void
rtl_hw_start_8168
(
struct
net_device
*
);
static
void
rtl_hw_start_8101
(
struct
net_device
*
);
static
DEFINE_PCI_DEVICE_TABLE
(
rtl8169_pci_tbl
)
=
{
{
PCI_DEVICE
(
PCI_VENDOR_ID_REALTEK
,
0x8129
),
0
,
0
,
RTL_CFG_0
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_REALTEK
,
0x8136
),
0
,
0
,
RTL_CFG_2
},
...
...
@@ -774,22 +770,6 @@ MODULE_FIRMWARE(FIRMWARE_8105E_1);
MODULE_FIRMWARE
(
FIRMWARE_8168F_1
);
MODULE_FIRMWARE
(
FIRMWARE_8168F_2
);
static
int
rtl8169_open
(
struct
net_device
*
dev
);
static
netdev_tx_t
rtl8169_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
irqreturn_t
rtl8169_interrupt
(
int
irq
,
void
*
dev_instance
);
static
int
rtl8169_init_ring
(
struct
net_device
*
dev
);
static
void
rtl_hw_start
(
struct
net_device
*
dev
);
static
int
rtl8169_close
(
struct
net_device
*
dev
);
static
void
rtl_set_rx_mode
(
struct
net_device
*
dev
);
static
void
rtl8169_tx_timeout
(
struct
net_device
*
dev
);
static
struct
rtnl_link_stats64
*
rtl8169_get_stats64
(
struct
net_device
*
dev
,
struct
rtnl_link_stats64
*
stats
);
static
int
rtl8169_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
);
static
void
rtl8169_rx_clear
(
struct
rtl8169_private
*
tp
);
static
int
rtl8169_poll
(
struct
napi_struct
*
napi
,
int
budget
);
static
void
rtl_lock_work
(
struct
rtl8169_private
*
tp
)
{
mutex_lock
(
&
tp
->
wk
.
mutex
);
...
...
@@ -3303,15 +3283,6 @@ static void rtl8169_phy_timer(unsigned long __opaque)
rtl_schedule_task
(
tp
,
RTL_FLAG_TASK_PHY_PENDING
);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
static
void
rtl8169_netpoll
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rtl8169_interrupt
(
tp
->
pci_dev
->
irq
,
dev
);
}
#endif
static
void
rtl8169_release_board
(
struct
pci_dev
*
pdev
,
struct
net_device
*
dev
,
void
__iomem
*
ioaddr
)
{
...
...
@@ -3463,63 +3434,6 @@ static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data
return
-
EOPNOTSUPP
;
}
static
const
struct
rtl_cfg_info
{
void
(
*
hw_start
)(
struct
net_device
*
);
unsigned
int
region
;
unsigned
int
align
;
u16
event_slow
;
unsigned
features
;
u8
default_ver
;
}
rtl_cfg_infos
[]
=
{
[
RTL_CFG_0
]
=
{
.
hw_start
=
rtl_hw_start_8169
,
.
region
=
1
,
.
align
=
0
,
.
event_slow
=
SYSErr
|
LinkChg
|
RxOverflow
|
RxFIFOOver
,
.
features
=
RTL_FEATURE_GMII
,
.
default_ver
=
RTL_GIGA_MAC_VER_01
,
},
[
RTL_CFG_1
]
=
{
.
hw_start
=
rtl_hw_start_8168
,
.
region
=
2
,
.
align
=
8
,
.
event_slow
=
SYSErr
|
LinkChg
|
RxOverflow
,
.
features
=
RTL_FEATURE_GMII
|
RTL_FEATURE_MSI
,
.
default_ver
=
RTL_GIGA_MAC_VER_11
,
},
[
RTL_CFG_2
]
=
{
.
hw_start
=
rtl_hw_start_8101
,
.
region
=
2
,
.
align
=
8
,
.
event_slow
=
SYSErr
|
LinkChg
|
RxOverflow
|
RxFIFOOver
|
PCSTimeout
,
.
features
=
RTL_FEATURE_MSI
,
.
default_ver
=
RTL_GIGA_MAC_VER_13
,
}
};
/* Cfg9346_Unlock assumed. */
static
unsigned
rtl_try_msi
(
struct
rtl8169_private
*
tp
,
const
struct
rtl_cfg_info
*
cfg
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
msi
=
0
;
u8
cfg2
;
cfg2
=
RTL_R8
(
Config2
)
&
~
MSIEnable
;
if
(
cfg
->
features
&
RTL_FEATURE_MSI
)
{
if
(
pci_enable_msi
(
tp
->
pci_dev
))
{
netif_info
(
tp
,
hw
,
tp
->
dev
,
"no MSI. Back to INTx.
\n
"
);
}
else
{
cfg2
|=
MSIEnable
;
msi
=
RTL_FEATURE_MSI
;
}
}
if
(
tp
->
mac_version
<=
RTL_GIGA_MAC_VER_06
)
RTL_W8
(
Config2
,
cfg2
);
return
msi
;
}
static
void
rtl_disable_msi
(
struct
pci_dev
*
pdev
,
struct
rtl8169_private
*
tp
)
{
if
(
tp
->
features
&
RTL_FEATURE_MSI
)
{
...
...
@@ -3528,25 +3442,6 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
}
}
static
const
struct
net_device_ops
rtl8169_netdev_ops
=
{
.
ndo_open
=
rtl8169_open
,
.
ndo_stop
=
rtl8169_close
,
.
ndo_get_stats64
=
rtl8169_get_stats64
,
.
ndo_start_xmit
=
rtl8169_start_xmit
,
.
ndo_tx_timeout
=
rtl8169_tx_timeout
,
.
ndo_validate_addr
=
eth_validate_addr
,
.
ndo_change_mtu
=
rtl8169_change_mtu
,
.
ndo_fix_features
=
rtl8169_fix_features
,
.
ndo_set_features
=
rtl8169_set_features
,
.
ndo_set_mac_address
=
rtl_set_mac_address
,
.
ndo_do_ioctl
=
rtl8169_ioctl
,
.
ndo_set_rx_mode
=
rtl_set_rx_mode
,
#ifdef CONFIG_NET_POLL_CONTROLLER
.
ndo_poll_controller
=
rtl8169_netpoll
,
#endif
};
static
void
__devinit
rtl_init_mdio_ops
(
struct
rtl8169_private
*
tp
)
{
struct
mdio_ops
*
ops
=
&
tp
->
mdio_ops
;
...
...
@@ -4018,912 +3913,607 @@ static void rtl_hw_reset(struct rtl8169_private *tp)
}
}
static
int
__devinit
rtl8169_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
static
void
rtl_request_uncached_firmware
(
struct
rtl8169_private
*
tp
)
{
const
struct
rtl_cfg_info
*
cfg
=
rtl_cfg_infos
+
ent
->
driver_data
;
const
unsigned
int
region
=
cfg
->
region
;
struct
rtl8169_private
*
tp
;
struct
mii_if_info
*
mii
;
struct
net_device
*
dev
;
void
__iomem
*
ioaddr
;
int
chipset
,
i
;
int
rc
;
struct
rtl_fw
*
rtl_fw
;
const
char
*
name
;
int
rc
=
-
ENOMEM
;
if
(
netif_msg_drv
(
&
debug
))
{
printk
(
KERN_INFO
"%s Gigabit Ethernet driver %s loaded
\n
"
,
MODULENAME
,
RTL8169_VERSION
);
}
name
=
rtl_lookup_firmware_name
(
tp
);
if
(
!
name
)
goto
out_no_firmware
;
dev
=
alloc_etherdev
(
sizeof
(
*
tp
));
if
(
!
dev
)
{
rc
=
-
ENOMEM
;
goto
out
;
}
rtl_fw
=
kzalloc
(
sizeof
(
*
rtl_fw
),
GFP_KERNEL
);
if
(
!
rtl_fw
)
goto
err_warn
;
SET_NETDEV_DEV
(
dev
,
&
pdev
->
dev
);
dev
->
netdev_ops
=
&
rtl8169_netdev_ops
;
tp
=
netdev_priv
(
dev
);
tp
->
dev
=
dev
;
tp
->
pci_dev
=
pdev
;
tp
->
msg_enable
=
netif_msg_init
(
debug
.
msg_enable
,
R8169_MSG_DEFAULT
);
rc
=
request_firmware
(
&
rtl_fw
->
fw
,
name
,
&
tp
->
pci_dev
->
dev
);
if
(
rc
<
0
)
goto
err_free
;
mii
=
&
tp
->
mii
;
mii
->
dev
=
dev
;
mii
->
mdio_read
=
rtl_mdio_read
;
mii
->
mdio_write
=
rtl_mdio_write
;
mii
->
phy_id_mask
=
0x1f
;
mii
->
reg_num_mask
=
0x1f
;
mii
->
supports_gmii
=
!!
(
cfg
->
features
&
RTL_FEATURE_GMII
);
rc
=
rtl_check_firmware
(
tp
,
rtl_fw
);
if
(
rc
<
0
)
goto
err_release_firmware
;
/* disable ASPM completely as that cause random device stop working
* problems as well as full system hangs for some PCIe devices users */
pci_disable_link_state
(
pdev
,
PCIE_LINK_STATE_L0S
|
PCIE_LINK_STATE_L1
|
PCIE_LINK_STATE_CLKPM
);
tp
->
rtl_fw
=
rtl_fw
;
out:
return
;
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc
=
pci_enable_device
(
pdev
);
if
(
rc
<
0
)
{
netif_err
(
tp
,
probe
,
dev
,
"enable failure
\n
"
);
goto
err_out_free_dev_1
;
}
err_release_firmware:
release_firmware
(
rtl_fw
->
fw
);
err_free:
kfree
(
rtl_fw
);
err_warn:
netif_warn
(
tp
,
ifup
,
tp
->
dev
,
"unable to load firmware patch %s (%d)
\n
"
,
name
,
rc
);
out_no_firmware:
tp
->
rtl_fw
=
NULL
;
goto
out
;
}
if
(
pci_set_mwi
(
pdev
)
<
0
)
netif_info
(
tp
,
probe
,
dev
,
"Mem-Wr-Inval unavailable
\n
"
);
static
void
rtl_request_firmware
(
struct
rtl8169_private
*
tp
)
{
if
(
IS_ERR
(
tp
->
rtl_fw
))
rtl_request_uncached_firmware
(
tp
);
}
/* make sure PCI base addr 1 is MMIO */
if
(
!
(
pci_resource_flags
(
pdev
,
region
)
&
IORESOURCE_MEM
))
{
netif_err
(
tp
,
probe
,
dev
,
"region #%d not an MMIO resource, aborting
\n
"
,
region
);
rc
=
-
ENODEV
;
goto
err_out_mwi_2
;
}
static
void
rtl_rx_close
(
struct
rtl8169_private
*
tp
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
/* check for weird/broken PCI region reporting */
if
(
pci_resource_len
(
pdev
,
region
)
<
R8169_REGS_SIZE
)
{
netif_err
(
tp
,
probe
,
dev
,
"Invalid PCI region size(s), aborting
\n
"
);
rc
=
-
ENODEV
;
goto
err_out_mwi_2
;
}
RTL_W32
(
RxConfig
,
RTL_R32
(
RxConfig
)
&
~
RX_CONFIG_ACCEPT_MASK
);
}
rc
=
pci_request_regions
(
pdev
,
MODULENAME
);
if
(
rc
<
0
)
{
netif_err
(
tp
,
probe
,
dev
,
"could not request regions
\n
"
);
goto
err_out_mwi_2
;
}
static
void
rtl8169_hw_reset
(
struct
rtl8169_private
*
tp
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
tp
->
cp_cmd
=
RxChkSum
;
/* Disable interrupts */
rtl8169_irq_mask_and_ack
(
tp
);
if
((
sizeof
(
dma_addr_t
)
>
4
)
&&
!
pci_set_dma_mask
(
pdev
,
DMA_BIT_MASK
(
64
))
&&
use_dac
)
{
tp
->
cp_cmd
|=
PCIDAC
;
dev
->
features
|=
NETIF_F_HIGHDMA
;
}
else
{
rc
=
pci_set_dma_mask
(
pdev
,
DMA_BIT_MASK
(
32
));
if
(
rc
<
0
)
{
netif_err
(
tp
,
probe
,
dev
,
"DMA configuration failed
\n
"
);
goto
err_out_free_res_3
;
}
}
rtl_rx_close
(
tp
);
/* ioremap MMIO region */
ioaddr
=
ioremap
(
pci_resource_start
(
pdev
,
region
),
R8169_REGS_SIZE
);
if
(
!
ioaddr
)
{
netif_err
(
tp
,
probe
,
dev
,
"cannot remap MMIO, aborting
\n
"
);
rc
=
-
EIO
;
goto
err_out_free_res_3
;
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_27
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_28
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_31
)
{
while
(
RTL_R8
(
TxPoll
)
&
NPQ
)
udelay
(
20
);
}
else
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_34
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_35
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_36
)
{
RTL_W8
(
ChipCmd
,
RTL_R8
(
ChipCmd
)
|
StopReq
);
while
(
!
(
RTL_R32
(
TxConfig
)
&
TXCFG_EMPTY
))
udelay
(
100
);
}
else
{
RTL_W8
(
ChipCmd
,
RTL_R8
(
ChipCmd
)
|
StopReq
);
udelay
(
100
);
}
tp
->
mmio_addr
=
ioaddr
;
if
(
!
pci_is_pcie
(
pdev
))
netif_info
(
tp
,
probe
,
dev
,
"not PCI Express
\n
"
);
/* Identify chip attached to board */
rtl8169_get_mac_version
(
tp
,
dev
,
cfg
->
default_ver
);
rtl_hw_reset
(
tp
);
}
rtl_init_rxcfg
(
tp
);
static
void
rtl_set_rx_tx_config_registers
(
struct
rtl8169_private
*
tp
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
rtl_irq_disable
(
tp
);
/* Set DMA burst size and Interframe Gap Time */
RTL_W32
(
TxConfig
,
(
TX_DMA_BURST
<<
TxDMAShift
)
|
(
InterFrameGap
<<
TxInterFrameGapShift
));
}
rtl_hw_reset
(
tp
);
static
void
rtl_hw_start
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rtl_ack_events
(
tp
,
0xffff
);
tp
->
hw_start
(
dev
);
pci_set_master
(
pdev
);
rtl_irq_enable_all
(
tp
);
}
static
void
rtl_set_rx_tx_desc_registers
(
struct
rtl8169_private
*
tp
,
void
__iomem
*
ioaddr
)
{
/*
* Pretend we are using VLANs; This bypasses a nasty bug where
* Interrupts stop flowing on high load on 8110SCd controllers.
* Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
* register to be written before TxDescAddrLow to work.
* Switching from MMIO to I/O access fixes the issue as well.
*/
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_05
)
tp
->
cp_cmd
|=
RxVlan
;
RTL_W32
(
TxDescStartAddrHigh
,
((
u64
)
tp
->
TxPhyAddr
)
>>
32
);
RTL_W32
(
TxDescStartAddrLow
,
((
u64
)
tp
->
TxPhyAddr
)
&
DMA_BIT_MASK
(
32
));
RTL_W32
(
RxDescAddrHigh
,
((
u64
)
tp
->
RxPhyAddr
)
>>
32
);
RTL_W32
(
RxDescAddrLow
,
((
u64
)
tp
->
RxPhyAddr
)
&
DMA_BIT_MASK
(
32
));
}
rtl_init_mdio_ops
(
tp
);
rtl_init_pll_power_ops
(
tp
);
rtl_init_jumbo_ops
(
tp
)
;
static
u16
rtl_rw_cpluscmd
(
void
__iomem
*
ioaddr
)
{
u16
cmd
;
rtl8169_print_mac_version
(
tp
);
cmd
=
RTL_R16
(
CPlusCmd
);
RTL_W16
(
CPlusCmd
,
cmd
);
return
cmd
;
}
chipset
=
tp
->
mac_version
;
tp
->
txd_version
=
rtl_chip_infos
[
chipset
].
txd_version
;
static
void
rtl_set_rx_max_size
(
void
__iomem
*
ioaddr
,
unsigned
int
rx_buf_sz
)
{
/* Low hurts. Let's disable the filtering. */
RTL_W16
(
RxMaxSize
,
rx_buf_sz
+
1
);
}
RTL_W8
(
Cfg9346
,
Cfg9346_Unlock
);
RTL_W8
(
Config1
,
RTL_R8
(
Config1
)
|
PMEnable
);
RTL_W8
(
Config5
,
RTL_R8
(
Config5
)
&
PMEStatus
);
if
((
RTL_R8
(
Config3
)
&
(
LinkUp
|
MagicPacket
))
!=
0
)
tp
->
features
|=
RTL_FEATURE_WOL
;
if
((
RTL_R8
(
Config5
)
&
(
UWF
|
BWF
|
MWF
))
!=
0
)
tp
->
features
|=
RTL_FEATURE_WOL
;
tp
->
features
|=
rtl_try_msi
(
tp
,
cfg
);
RTL_W8
(
Cfg9346
,
Cfg9346_Lock
);
static
void
rtl8169_set_magic_reg
(
void
__iomem
*
ioaddr
,
unsigned
mac_version
)
{
static
const
struct
rtl_cfg2_info
{
u32
mac_version
;
u32
clk
;
u32
val
;
}
cfg2_info
[]
=
{
{
RTL_GIGA_MAC_VER_05
,
PCI_Clock_33MHz
,
0x000fff00
},
// 8110SCd
{
RTL_GIGA_MAC_VER_05
,
PCI_Clock_66MHz
,
0x000fffff
},
{
RTL_GIGA_MAC_VER_06
,
PCI_Clock_33MHz
,
0x00ffff00
},
// 8110SCe
{
RTL_GIGA_MAC_VER_06
,
PCI_Clock_66MHz
,
0x00ffffff
}
};
const
struct
rtl_cfg2_info
*
p
=
cfg2_info
;
unsigned
int
i
;
u32
clk
;
if
(
rtl_tbi_enabled
(
tp
))
{
tp
->
set_speed
=
rtl8169_set_speed_tbi
;
tp
->
get_settings
=
rtl8169_gset_tbi
;
tp
->
phy_reset_enable
=
rtl8169_tbi_reset_enable
;
tp
->
phy_reset_pending
=
rtl8169_tbi_reset_pending
;
tp
->
link_ok
=
rtl8169_tbi_link_ok
;
tp
->
do_ioctl
=
rtl_tbi_ioctl
;
}
else
{
tp
->
set_speed
=
rtl8169_set_speed_xmii
;
tp
->
get_settings
=
rtl8169_gset_xmii
;
tp
->
phy_reset_enable
=
rtl8169_xmii_reset_enable
;
tp
->
phy_reset_pending
=
rtl8169_xmii_reset_pending
;
tp
->
link_ok
=
rtl8169_xmii_link_ok
;
tp
->
do_ioctl
=
rtl_xmii_ioctl
;
clk
=
RTL_R8
(
Config2
)
&
PCI_Clock_66MHz
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cfg2_info
);
i
++
,
p
++
)
{
if
((
p
->
mac_version
==
mac_version
)
&&
(
p
->
clk
==
clk
))
{
RTL_W32
(
0x7c
,
p
->
val
);
break
;
}
}
}
mutex_init
(
&
tp
->
wk
.
mutex
);
static
void
rtl_set_rx_mode
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
u32
mc_filter
[
2
];
/* Multicast hash filter */
int
rx_mode
;
u32
tmp
=
0
;
/* Get MAC address */
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
dev
->
dev_addr
[
i
]
=
RTL_R8
(
MAC0
+
i
);
memcpy
(
dev
->
perm_addr
,
dev
->
dev_addr
,
dev
->
addr_len
);
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* Unconditionally log net taps. */
netif_notice
(
tp
,
link
,
dev
,
"Promiscuous mode enabled
\n
"
);
rx_mode
=
AcceptBroadcast
|
AcceptMulticast
|
AcceptMyPhys
|
AcceptAllPhys
;
mc_filter
[
1
]
=
mc_filter
[
0
]
=
0xffffffff
;
}
else
if
((
netdev_mc_count
(
dev
)
>
multicast_filter_limit
)
||
(
dev
->
flags
&
IFF_ALLMULTI
))
{
/* Too many to filter perfectly -- accept all multicasts. */
rx_mode
=
AcceptBroadcast
|
AcceptMulticast
|
AcceptMyPhys
;
mc_filter
[
1
]
=
mc_filter
[
0
]
=
0xffffffff
;
}
else
{
struct
netdev_hw_addr
*
ha
;
SET_ETHTOOL_OPS
(
dev
,
&
rtl8169_ethtool_ops
);
dev
->
watchdog_timeo
=
RTL8169_TX_TIMEOUT
;
dev
->
irq
=
pdev
->
irq
;
dev
->
base_addr
=
(
unsigned
long
)
ioaddr
;
rx_mode
=
AcceptBroadcast
|
AcceptMyPhys
;
mc_filter
[
1
]
=
mc_filter
[
0
]
=
0
;
netdev_for_each_mc_addr
(
ha
,
dev
)
{
int
bit_nr
=
ether_crc
(
ETH_ALEN
,
ha
->
addr
)
>>
26
;
mc_filter
[
bit_nr
>>
5
]
|=
1
<<
(
bit_nr
&
31
);
rx_mode
|=
AcceptMulticast
;
}
}
netif_napi_add
(
dev
,
&
tp
->
napi
,
rtl8169_poll
,
R8169_NAPI_WEIGHT
);
if
(
dev
->
features
&
NETIF_F_RXALL
)
rx_mode
|=
(
AcceptErr
|
AcceptRunt
);
/* don't enable SG, IP_CSUM and TSO by default - it might not work
* properly for all devices */
dev
->
features
|=
NETIF_F_RXCSUM
|
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
;
tmp
=
(
RTL_R32
(
RxConfig
)
&
~
RX_CONFIG_ACCEPT_MASK
)
|
rx_mode
;
dev
->
hw_features
=
NETIF_F_SG
|
NETIF_F_IP_CSUM
|
NETIF_F_TSO
|
NETIF_F_RXCSUM
|
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
;
dev
->
vlan_features
=
NETIF_F_SG
|
NETIF_F_IP_CSUM
|
NETIF_F_TSO
|
NETIF_F_HIGHDMA
;
if
(
tp
->
mac_version
>
RTL_GIGA_MAC_VER_06
)
{
u32
data
=
mc_filter
[
0
];
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_05
)
/* 8110SCd requires hardware Rx VLAN - disallow toggling */
dev
->
hw_features
&=
~
NETIF_F_HW_VLAN_RX
;
mc_filter
[
0
]
=
swab32
(
mc_filter
[
1
]);
mc_filter
[
1
]
=
swab32
(
data
);
}
dev
->
hw_features
|=
NETIF_F_RXALL
;
dev
->
hw_features
|=
NETIF_F_RXFCS
;
RTL_W32
(
MAR0
+
4
,
mc_filter
[
1
])
;
RTL_W32
(
MAR0
+
0
,
mc_filter
[
0
])
;
tp
->
hw_start
=
cfg
->
hw_start
;
tp
->
event_slow
=
cfg
->
event_slow
;
RTL_W32
(
RxConfig
,
tmp
)
;
}
tp
->
opts1_mask
=
(
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_01
)
?
~
(
RxBOVF
|
RxFOVF
)
:
~
0
;
static
void
rtl_hw_start_8169
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
init_timer
(
&
tp
->
timer
);
tp
->
timer
.
data
=
(
unsigned
long
)
dev
;
tp
->
timer
.
function
=
rtl8169_phy_timer
;
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_05
)
{
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
|
PCIMulRW
);
pci_write_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
0x08
);
}
tp
->
rtl_fw
=
RTL_FIRMWARE_UNKNOWN
;
RTL_W8
(
Cfg9346
,
Cfg9346_Unlock
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_01
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_02
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_03
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_04
)
RTL_W8
(
ChipCmd
,
CmdTxEnb
|
CmdRxEnb
);
rc
=
register_netdev
(
dev
);
if
(
rc
<
0
)
goto
err_out_msi_4
;
rtl_init_rxcfg
(
tp
);
pci_set_drvdata
(
pdev
,
dev
);
RTL_W8
(
EarlyTxThres
,
NoEarlyTx
);
netif_info
(
tp
,
probe
,
dev
,
"%s at 0x%lx, %pM, XID %08x IRQ %d
\n
"
,
rtl_chip_infos
[
chipset
].
name
,
dev
->
base_addr
,
dev
->
dev_addr
,
(
u32
)(
RTL_R32
(
TxConfig
)
&
0x9cf0f8ff
),
dev
->
irq
);
if
(
rtl_chip_infos
[
chipset
].
jumbo_max
!=
JUMBO_1K
)
{
netif_info
(
tp
,
probe
,
dev
,
"jumbo features [frames: %d bytes, "
"tx checksumming: %s]
\n
"
,
rtl_chip_infos
[
chipset
].
jumbo_max
,
rtl_chip_infos
[
chipset
].
jumbo_tx_csum
?
"ok"
:
"ko"
);
}
rtl_set_rx_max_size
(
ioaddr
,
rx_buf_sz
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_
27
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_
28
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_
31
)
{
rtl8168_driver_start
(
tp
);
}
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_
01
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_
02
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_
03
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_04
)
rtl_set_rx_tx_config_registers
(
tp
);
device_set_wakeup_enable
(
&
pdev
->
dev
,
tp
->
features
&
RTL_FEATURE_WOL
)
;
tp
->
cp_cmd
|=
rtl_rw_cpluscmd
(
ioaddr
)
|
PCIMulRW
;
if
(
pci_dev_run_wake
(
pdev
))
pm_runtime_put_noidle
(
&
pdev
->
dev
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_02
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_03
)
{
dprintk
(
"Set MAC Reg C+CR Offset 0xE0. "
"Bit-3 and bit-14 MUST be 1
\n
"
);
tp
->
cp_cmd
|=
(
1
<<
14
);
}
netif_carrier_off
(
dev
);
RTL_W16
(
CPlusCmd
,
tp
->
cp_cmd
);
out:
return
rc
;
rtl8169_set_magic_reg
(
ioaddr
,
tp
->
mac_version
);
err_out_msi_4:
rtl_disable_msi
(
pdev
,
tp
);
iounmap
(
ioaddr
);
err_out_free_res_3:
pci_release_regions
(
pdev
);
err_out_mwi_2:
pci_clear_mwi
(
pdev
);
pci_disable_device
(
pdev
);
err_out_free_dev_1:
free_netdev
(
dev
);
goto
out
;
}
/*
* Undocumented corner. Supposedly:
* (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
*/
RTL_W16
(
IntrMitigate
,
0x0000
);
static
void
__devexit
rtl8169_remove_one
(
struct
pci_dev
*
pdev
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rtl_set_rx_tx_desc_registers
(
tp
,
ioaddr
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_27
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_28
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_31
)
{
rtl8168_driver_stop
(
tp
);
if
(
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_01
&&
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_02
&&
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_03
&&
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_04
)
{
RTL_W8
(
ChipCmd
,
CmdTxEnb
|
CmdRxEnb
);
rtl_set_rx_tx_config_registers
(
tp
);
}
cancel_work_sync
(
&
tp
->
wk
.
work
);
unregister_netdev
(
dev
);
RTL_W8
(
Cfg9346
,
Cfg9346_Lock
);
rtl_release_firmware
(
tp
);
/* Initially a 10 us delay. Turned it into a PCI commit. - FR */
RTL_R8
(
IntrMask
);
if
(
pci_dev_run_wake
(
pdev
))
pm_runtime_get_noresume
(
&
pdev
->
dev
);
RTL_W32
(
RxMissed
,
0
);
/* restore original MAC address */
rtl_rar_set
(
tp
,
dev
->
perm_addr
);
rtl_set_rx_mode
(
dev
);
rtl_disable_msi
(
pdev
,
tp
);
rtl8169_release_board
(
pdev
,
dev
,
tp
->
mmio_addr
);
pci_set_drvdata
(
pdev
,
NULL
);
/* no early-rx interrupts */
RTL_W16
(
MultiIntr
,
RTL_R16
(
MultiIntr
)
&
0xF000
);
}
static
void
rtl_
request_uncached_firmware
(
struct
rtl8169_private
*
tp
)
static
void
rtl_
csi_access_enable
(
void
__iomem
*
ioaddr
,
u32
bits
)
{
struct
rtl_fw
*
rtl_fw
;
const
char
*
name
;
int
rc
=
-
ENOMEM
;
name
=
rtl_lookup_firmware_name
(
tp
);
if
(
!
name
)
goto
out_no_firmware
;
u32
csi
;
rtl_fw
=
kzalloc
(
sizeof
(
*
rtl_fw
),
GFP_KERNEL
);
if
(
!
rtl_fw
)
goto
err_warn
;
rc
=
request_firmware
(
&
rtl_fw
->
fw
,
name
,
&
tp
->
pci_dev
->
dev
);
if
(
rc
<
0
)
goto
err_free
;
rc
=
rtl_check_firmware
(
tp
,
rtl_fw
);
if
(
rc
<
0
)
goto
err_release_firmware
;
tp
->
rtl_fw
=
rtl_fw
;
out:
return
;
csi
=
rtl_csi_read
(
ioaddr
,
0x070c
)
&
0x00ffffff
;
rtl_csi_write
(
ioaddr
,
0x070c
,
csi
|
bits
);
}
err_release_firmware:
release_firmware
(
rtl_fw
->
fw
);
err_free:
kfree
(
rtl_fw
);
err_warn:
netif_warn
(
tp
,
ifup
,
tp
->
dev
,
"unable to load firmware patch %s (%d)
\n
"
,
name
,
rc
);
out_no_firmware:
tp
->
rtl_fw
=
NULL
;
goto
out
;
static
void
rtl_csi_access_enable_1
(
void
__iomem
*
ioaddr
)
{
rtl_csi_access_enable
(
ioaddr
,
0x17000000
);
}
static
void
rtl_
request_firmware
(
struct
rtl8169_private
*
tp
)
static
void
rtl_
csi_access_enable_2
(
void
__iomem
*
ioaddr
)
{
if
(
IS_ERR
(
tp
->
rtl_fw
))
rtl_request_uncached_firmware
(
tp
);
rtl_csi_access_enable
(
ioaddr
,
0x27000000
);
}
static
void
rtl_task
(
struct
work_struct
*
);
struct
ephy_info
{
unsigned
int
offset
;
u16
mask
;
u16
bits
;
};
static
int
rtl8169_open
(
struct
net_device
*
dev
)
static
void
rtl_ephy_init
(
void
__iomem
*
ioaddr
,
const
struct
ephy_info
*
e
,
int
len
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
int
retval
=
-
ENOMEM
;
u16
w
;
pm_runtime_get_sync
(
&
pdev
->
dev
);
while
(
len
--
>
0
)
{
w
=
(
rtl_ephy_read
(
ioaddr
,
e
->
offset
)
&
~
e
->
mask
)
|
e
->
bits
;
rtl_ephy_write
(
ioaddr
,
e
->
offset
,
w
);
e
++
;
}
}
/*
* Rx and Tx desscriptors needs 256 bytes alignment.
* dma_alloc_coherent provides more.
*/
tp
->
TxDescArray
=
dma_alloc_coherent
(
&
pdev
->
dev
,
R8169_TX_RING_BYTES
,
&
tp
->
TxPhyAddr
,
GFP_KERNEL
);
if
(
!
tp
->
TxDescArray
)
goto
err_pm_runtime_put
;
static
void
rtl_disable_clock_request
(
struct
pci_dev
*
pdev
)
{
int
cap
=
pci_pcie_cap
(
pdev
);
tp
->
RxDescArray
=
dma_alloc_coherent
(
&
pdev
->
dev
,
R8169_RX_RING_BYTES
,
&
tp
->
RxPhyAddr
,
GFP_KERNEL
);
if
(
!
tp
->
RxDescArray
)
goto
err_free_tx_0
;
if
(
cap
)
{
u16
ctl
;
retval
=
rtl8169_init_ring
(
dev
);
if
(
retval
<
0
)
goto
err_free_rx_1
;
pci_read_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
&
ctl
);
ctl
&=
~
PCI_EXP_LNKCTL_CLKREQ_EN
;
pci_write_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
ctl
);
}
}
INIT_WORK
(
&
tp
->
wk
.
work
,
rtl_task
);
static
void
rtl_enable_clock_request
(
struct
pci_dev
*
pdev
)
{
int
cap
=
pci_pcie_cap
(
pdev
);
smp_mb
();
if
(
cap
)
{
u16
ctl
;
rtl_request_firmware
(
tp
);
pci_read_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
&
ctl
);
ctl
|=
PCI_EXP_LNKCTL_CLKREQ_EN
;
pci_write_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
ctl
);
}
}
retval
=
request_irq
(
dev
->
irq
,
rtl8169_interrupt
,
(
tp
->
features
&
RTL_FEATURE_MSI
)
?
0
:
IRQF_SHARED
,
dev
->
name
,
dev
);
if
(
retval
<
0
)
goto
err_release_fw_2
;
#define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
Force_half_dup | \
Force_rxflow_en | \
Force_txflow_en | \
Cxpl_dbg_sel | \
ASF | \
PktCntrDisable | \
Mac_dbgo_sel)
rtl_lock_work
(
tp
);
static
void
rtl_hw_start_8168bb
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
set_bit
(
RTL_FLAG_TASK_ENABLED
,
tp
->
wk
.
flags
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
napi_enable
(
&
tp
->
napi
);
rtl_tx_performance_tweak
(
pdev
,
(
0x5
<<
MAX_READ_REQUEST_SHIFT
)
|
PCI_EXP_DEVCTL_NOSNOOP_EN
);
}
rtl8169_init_phy
(
dev
,
tp
);
static
void
rtl_hw_start_8168bef
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_hw_start_8168bb
(
ioaddr
,
pdev
);
__rtl8169_set_features
(
dev
,
dev
->
features
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_pll_power_up
(
tp
);
RTL_W8
(
Config4
,
RTL_R8
(
Config4
)
&
~
(
1
<<
0
));
}
rtl_hw_start
(
dev
);
static
void
__rtl_hw_start_8168cp
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
RTL_W8
(
Config1
,
RTL_R8
(
Config1
)
|
Speed_down
);
netif_start_queue
(
dev
);
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
rtl_
unlock_work
(
tp
);
rtl_
tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
tp
->
saved_wolopts
=
0
;
pm_runtime_put_noidle
(
&
pdev
->
dev
);
rtl_disable_clock_request
(
pdev
);
rtl8169_check_link_status
(
dev
,
tp
,
ioaddr
);
out:
return
retval
;
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
err_release_fw_2:
rtl_release_firmware
(
tp
);
rtl8169_rx_clear
(
tp
);
err_free_rx_1:
dma_free_coherent
(
&
pdev
->
dev
,
R8169_RX_RING_BYTES
,
tp
->
RxDescArray
,
tp
->
RxPhyAddr
);
tp
->
RxDescArray
=
NULL
;
err_free_tx_0:
dma_free_coherent
(
&
pdev
->
dev
,
R8169_TX_RING_BYTES
,
tp
->
TxDescArray
,
tp
->
TxPhyAddr
);
tp
->
TxDescArray
=
NULL
;
err_pm_runtime_put:
pm_runtime_put_noidle
(
&
pdev
->
dev
);
goto
out
;
static
void
rtl_hw_start_8168cp_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168cp
[]
=
{
{
0x01
,
0
,
0x0001
},
{
0x02
,
0x0800
,
0x1000
},
{
0x03
,
0
,
0x0042
},
{
0x06
,
0x0080
,
0x0000
},
{
0x07
,
0
,
0x2000
}
};
rtl_csi_access_enable_2
(
ioaddr
);
rtl_ephy_init
(
ioaddr
,
e_info_8168cp
,
ARRAY_SIZE
(
e_info_8168cp
));
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_
rx_close
(
struct
rtl8169_private
*
tp
)
static
void
rtl_
hw_start_8168cp_2
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
rtl_csi_access_enable_2
(
ioaddr
)
;
RTL_W32
(
RxConfig
,
RTL_R32
(
RxConfig
)
&
~
RX_CONFIG_ACCEPT_MASK
);
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
static
void
rtl
8169_hw_reset
(
struct
rtl8169_private
*
tp
)
static
void
rtl
_hw_start_8168cp_3
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
rtl_csi_access_enable_2
(
ioaddr
)
;
/* Disable interrupts */
rtl8169_irq_mask_and_ack
(
tp
);
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
rtl_rx_close
(
tp
);
/* Magic. */
RTL_W8
(
DBG_REG
,
0x20
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_27
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_28
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_31
)
{
while
(
RTL_R8
(
TxPoll
)
&
NPQ
)
udelay
(
20
);
}
else
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_34
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_35
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_36
)
{
RTL_W8
(
ChipCmd
,
RTL_R8
(
ChipCmd
)
|
StopReq
);
while
(
!
(
RTL_R32
(
TxConfig
)
&
TXCFG_EMPTY
))
udelay
(
100
);
}
else
{
RTL_W8
(
ChipCmd
,
RTL_R8
(
ChipCmd
)
|
StopReq
);
udelay
(
100
);
}
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_hw_reset
(
tp
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
static
void
rtl_
set_rx_tx_config_registers
(
struct
rtl8169_private
*
tp
)
static
void
rtl_
hw_start_8168c_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
static
const
struct
ephy_info
e_info_8168c_1
[]
=
{
{
0x02
,
0x0800
,
0x1000
},
{
0x03
,
0
,
0x0002
},
{
0x06
,
0x0080
,
0x0000
}
};
/* Set DMA burst size and Interframe Gap Time */
RTL_W32
(
TxConfig
,
(
TX_DMA_BURST
<<
TxDMAShift
)
|
(
InterFrameGap
<<
TxInterFrameGapShift
));
rtl_csi_access_enable_2
(
ioaddr
);
RTL_W8
(
DBG_REG
,
0x06
|
FIX_NAK_1
|
FIX_NAK_2
);
rtl_ephy_init
(
ioaddr
,
e_info_8168c_1
,
ARRAY_SIZE
(
e_info_8168c_1
));
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_hw_start
(
struct
net_device
*
dev
)
static
void
rtl_hw_start
_8168c_2
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
p
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
static
const
struct
ephy_info
e_info_8168c_2
[]
=
{
{
0x01
,
0
,
0x0001
},
{
0x03
,
0x0400
,
0x0220
}
};
tp
->
hw_start
(
dev
);
rtl_csi_access_enable_2
(
ioaddr
);
rtl_irq_enable_all
(
tp
);
rtl_ephy_init
(
ioaddr
,
e_info_8168c_2
,
ARRAY_SIZE
(
e_info_8168c_2
));
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_set_rx_tx_desc_registers
(
struct
rtl8169_private
*
tp
,
void
__iomem
*
ioaddr
)
static
void
rtl_hw_start_8168c_3
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
/*
* Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
* register to be written before TxDescAddrLow to work.
* Switching from MMIO to I/O access fixes the issue as well.
*/
RTL_W32
(
TxDescStartAddrHigh
,
((
u64
)
tp
->
TxPhyAddr
)
>>
32
);
RTL_W32
(
TxDescStartAddrLow
,
((
u64
)
tp
->
TxPhyAddr
)
&
DMA_BIT_MASK
(
32
));
RTL_W32
(
RxDescAddrHigh
,
((
u64
)
tp
->
RxPhyAddr
)
>>
32
);
RTL_W32
(
RxDescAddrLow
,
((
u64
)
tp
->
RxPhyAddr
)
&
DMA_BIT_MASK
(
32
));
rtl_hw_start_8168c_2
(
ioaddr
,
pdev
);
}
static
u16
rtl_rw_cpluscmd
(
void
__iomem
*
ioaddr
)
static
void
rtl_hw_start_8168c_4
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
u16
cmd
;
cmd
=
RTL_R16
(
CPlusCmd
);
RTL_W16
(
CPlusCmd
,
cmd
);
return
cmd
;
}
rtl_csi_access_enable_2
(
ioaddr
);
static
void
rtl_set_rx_max_size
(
void
__iomem
*
ioaddr
,
unsigned
int
rx_buf_sz
)
{
/* Low hurts. Let's disable the filtering. */
RTL_W16
(
RxMaxSize
,
rx_buf_sz
+
1
);
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl
8169_set_magic_reg
(
void
__iomem
*
ioaddr
,
unsigned
mac_version
)
static
void
rtl
_hw_start_8168d
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
rtl_cfg2_info
{
u32
mac_version
;
u32
clk
;
u32
val
;
}
cfg2_info
[]
=
{
{
RTL_GIGA_MAC_VER_05
,
PCI_Clock_33MHz
,
0x000fff00
},
// 8110SCd
{
RTL_GIGA_MAC_VER_05
,
PCI_Clock_66MHz
,
0x000fffff
},
{
RTL_GIGA_MAC_VER_06
,
PCI_Clock_33MHz
,
0x00ffff00
},
// 8110SCe
{
RTL_GIGA_MAC_VER_06
,
PCI_Clock_66MHz
,
0x00ffffff
}
};
const
struct
rtl_cfg2_info
*
p
=
cfg2_info
;
unsigned
int
i
;
u32
clk
;
clk
=
RTL_R8
(
Config2
)
&
PCI_Clock_66MHz
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cfg2_info
);
i
++
,
p
++
)
{
if
((
p
->
mac_version
==
mac_version
)
&&
(
p
->
clk
==
clk
))
{
RTL_W32
(
0x7c
,
p
->
val
);
break
;
}
}
}
rtl_csi_access_enable_2
(
ioaddr
);
static
void
rtl_hw_start_8169
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
rtl_disable_clock_request
(
pdev
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_05
)
{
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
|
PCIMulRW
);
pci_write_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
0x08
);
}
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
RTL_W8
(
Cfg9346
,
Cfg9346_Unlock
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_01
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_02
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_03
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_04
)
RTL_W8
(
ChipCmd
,
CmdTxEnb
|
CmdRxEnb
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
rtl_init_rxcfg
(
tp
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
RTL_W8
(
EarlyTxThres
,
NoEarlyTx
);
static
void
rtl_hw_start_8168dp
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable_1
(
ioaddr
);
rtl_
set_rx_max_size
(
ioaddr
,
rx_buf_sz
);
rtl_
tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_01
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_02
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_03
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_04
)
rtl_set_rx_tx_config_registers
(
tp
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
tp
->
cp_cmd
|=
rtl_rw_cpluscmd
(
ioaddr
)
|
PCIMulRW
;
rtl_disable_clock_request
(
pdev
);
}
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_02
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_03
)
{
dprintk
(
"Set MAC Reg C+CR Offset 0xE0. "
"Bit-3 and bit-14 MUST be 1
\n
"
);
tp
->
cp_cmd
|=
(
1
<<
14
);
}
static
void
rtl_hw_start_8168d_4
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168d_4
[]
=
{
{
0x0b
,
~
0
,
0x48
},
{
0x19
,
0x20
,
0x50
},
{
0x0c
,
~
0
,
0x20
}
};
int
i
;
RTL_W16
(
CPlusCmd
,
tp
->
cp_cmd
);
rtl_csi_access_enable_1
(
ioaddr
);
rtl
8169_set_magic_reg
(
ioaddr
,
tp
->
mac_version
);
rtl
_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
/*
* Undocumented corner. Supposedly:
* (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
*/
RTL_W16
(
IntrMitigate
,
0x0000
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_set_rx_tx_desc_registers
(
tp
,
ioaddr
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
e_info_8168d_4
);
i
++
)
{
const
struct
ephy_info
*
e
=
e_info_8168d_4
+
i
;
u16
w
;
if
(
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_01
&&
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_02
&&
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_03
&&
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_04
)
{
RTL_W8
(
ChipCmd
,
CmdTxEnb
|
CmdRxEnb
);
rtl_set_rx_tx_config_registers
(
tp
);
w
=
rtl_ephy_read
(
ioaddr
,
e
->
offset
);
rtl_ephy_write
(
ioaddr
,
0x03
,
(
w
&
e
->
mask
)
|
e
->
bits
);
}
RTL_W8
(
Cfg9346
,
Cfg9346_Lock
);
/* Initially a 10 us delay. Turned it into a PCI commit. - FR */
RTL_R8
(
IntrMask
);
RTL_W32
(
RxMissed
,
0
);
rtl_set_rx_mode
(
dev
);
/* no early-rx interrupts */
RTL_W16
(
MultiIntr
,
RTL_R16
(
MultiIntr
)
&
0xF000
);
}
static
void
rtl_csi_access_enable
(
void
__iomem
*
ioaddr
,
u32
bits
)
{
u32
csi
;
csi
=
rtl_csi_read
(
ioaddr
,
0x070c
)
&
0x00ffffff
;
rtl_csi_write
(
ioaddr
,
0x070c
,
csi
|
bits
);
rtl_enable_clock_request
(
pdev
);
}
static
void
rtl_
csi_access_enable_1
(
void
__iomem
*
ioaddr
)
static
void
rtl_
hw_start_8168e_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable
(
ioaddr
,
0x17000000
);
}
static
const
struct
ephy_info
e_info_8168e_1
[]
=
{
{
0x00
,
0x0200
,
0x0100
},
{
0x00
,
0x0000
,
0x0004
},
{
0x06
,
0x0002
,
0x0001
},
{
0x06
,
0x0000
,
0x0030
},
{
0x07
,
0x0000
,
0x2000
},
{
0x00
,
0x0000
,
0x0020
},
{
0x03
,
0x5800
,
0x2000
},
{
0x03
,
0x0000
,
0x0001
},
{
0x01
,
0x0800
,
0x1000
},
{
0x07
,
0x0000
,
0x4000
},
{
0x1e
,
0x0000
,
0x2000
},
{
0x19
,
0xffff
,
0xfe6c
},
{
0x0a
,
0x0000
,
0x0040
}
};
static
void
rtl_csi_access_enable_2
(
void
__iomem
*
ioaddr
)
{
rtl_csi_access_enable
(
ioaddr
,
0x27000000
);
}
rtl_csi_access_enable_2
(
ioaddr
);
struct
ephy_info
{
unsigned
int
offset
;
u16
mask
;
u16
bits
;
};
rtl_ephy_init
(
ioaddr
,
e_info_8168e_1
,
ARRAY_SIZE
(
e_info_8168e_1
));
static
void
rtl_ephy_init
(
void
__iomem
*
ioaddr
,
const
struct
ephy_info
*
e
,
int
len
)
{
u16
w
;
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
while
(
len
--
>
0
)
{
w
=
(
rtl_ephy_read
(
ioaddr
,
e
->
offset
)
&
~
e
->
mask
)
|
e
->
bits
;
rtl_ephy_write
(
ioaddr
,
e
->
offset
,
w
);
e
++
;
}
}
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
static
void
rtl_disable_clock_request
(
struct
pci_dev
*
pdev
)
{
int
cap
=
pci_pcie_cap
(
pdev
);
rtl_disable_clock_request
(
pdev
);
if
(
cap
)
{
u16
ctl
;
/* Reset tx FIFO pointer */
RTL_W32
(
MISC
,
RTL_R32
(
MISC
)
|
TXPLA_RST
);
RTL_W32
(
MISC
,
RTL_R32
(
MISC
)
&
~
TXPLA_RST
);
pci_read_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
&
ctl
);
ctl
&=
~
PCI_EXP_LNKCTL_CLKREQ_EN
;
pci_write_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
ctl
);
}
RTL_W8
(
Config5
,
RTL_R8
(
Config5
)
&
~
Spi_en
);
}
static
void
rtl_
enable_clock_request
(
struct
pci_dev
*
pdev
)
static
void
rtl_
hw_start_8168e_2
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
int
cap
=
pci_pcie_cap
(
pdev
);
static
const
struct
ephy_info
e_info_8168e_2
[]
=
{
{
0x09
,
0x0000
,
0x0080
},
{
0x19
,
0x0000
,
0x0224
}
};
if
(
cap
)
{
u16
ctl
;
rtl_csi_access_enable_1
(
ioaddr
);
pci_read_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
&
ctl
);
ctl
|=
PCI_EXP_LNKCTL_CLKREQ_EN
;
pci_write_config_word
(
pdev
,
cap
+
PCI_EXP_LNKCTL
,
ctl
);
}
}
rtl_ephy_init
(
ioaddr
,
e_info_8168e_2
,
ARRAY_SIZE
(
e_info_8168e_2
));
#define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
Force_half_dup | \
Force_rxflow_en | \
Force_txflow_en | \
Cxpl_dbg_sel | \
ASF | \
PktCntrDisable | \
Mac_dbgo_sel)
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
static
void
rtl_hw_start_8168bb
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
rtl_eri_write
(
ioaddr
,
0xc0
,
ERIAR_MASK_0011
,
0x0000
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xb8
,
ERIAR_MASK_0011
,
0x0000
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xc8
,
ERIAR_MASK_1111
,
0x00100002
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xe8
,
ERIAR_MASK_1111
,
0x00100006
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xcc
,
ERIAR_MASK_1111
,
0x00000050
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xd0
,
ERIAR_MASK_1111
,
0x07ff0060
,
ERIAR_EXGMAC
);
rtl_w1w0_eri
(
ioaddr
,
0x1b0
,
ERIAR_MASK_0001
,
0x10
,
0x00
,
ERIAR_EXGMAC
);
rtl_w1w0_eri
(
ioaddr
,
0x0d4
,
ERIAR_MASK_0011
,
0x0c00
,
0xff00
,
ERIAR_EXGMAC
);
RTL_W
16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
RTL_W
8
(
MaxTxPacketSize
,
EarlySize
);
rtl_tx_performance_tweak
(
pdev
,
(
0x5
<<
MAX_READ_REQUEST_SHIFT
)
|
PCI_EXP_DEVCTL_NOSNOOP_EN
);
}
rtl_disable_clock_request
(
pdev
);
static
void
rtl_hw_start_8168bef
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_hw_start_8168bb
(
ioaddr
,
pdev
);
RTL_W32
(
TxConfig
,
RTL_R32
(
TxConfig
)
|
TXCFG_AUTO_FIFO
);
RTL_W8
(
MCU
,
RTL_R8
(
MCU
)
&
~
NOW_IS_OOB
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
/* Adjust EEE LED frequency */
RTL_W8
(
EEE_LED
,
RTL_R8
(
EEE_LED
)
&
~
0x07
);
RTL_W8
(
Config4
,
RTL_R8
(
Config4
)
&
~
(
1
<<
0
));
RTL_W8
(
DLLPR
,
RTL_R8
(
DLLPR
)
|
PFM_EN
);
RTL_W32
(
MISC
,
RTL_R32
(
MISC
)
|
PWM_EN
);
RTL_W8
(
Config5
,
RTL_R8
(
Config5
)
&
~
Spi_en
);
}
static
void
__rtl_hw_start_8168cp
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
static
void
rtl_hw_start_8168f_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
RTL_W8
(
Config1
,
RTL_R8
(
Config1
)
|
Speed_down
);
static
const
struct
ephy_info
e_info_8168f_1
[]
=
{
{
0x06
,
0x00c0
,
0x0020
},
{
0x08
,
0x0001
,
0x0002
},
{
0x09
,
0x0000
,
0x0080
},
{
0x19
,
0x0000
,
0x0224
}
};
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
rtl_csi_access_enable_1
(
ioaddr
);
rtl_
tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
rtl_
ephy_init
(
ioaddr
,
e_info_8168f_1
,
ARRAY_SIZE
(
e_info_8168f_1
)
);
rtl_disable_clock_request
(
pdev
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
static
void
rtl_hw_start_8168cp_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168cp
[]
=
{
{
0x01
,
0
,
0x0001
},
{
0x02
,
0x0800
,
0x1000
},
{
0x03
,
0
,
0x0042
},
{
0x06
,
0x0080
,
0x0000
},
{
0x07
,
0
,
0x2000
}
};
rtl_csi_access_enable_2
(
ioaddr
);
rtl_ephy_init
(
ioaddr
,
e_info_8168cp
,
ARRAY_SIZE
(
e_info_8168cp
));
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_hw_start_8168cp_2
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable_2
(
ioaddr
);
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
static
void
rtl_hw_start_8168cp_3
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable_2
(
ioaddr
);
RTL_W8
(
Config3
,
RTL_R8
(
Config3
)
&
~
Beacon_en
);
/* Magic. */
RTL_W8
(
DBG_REG
,
0x20
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
static
void
rtl_hw_start_8168c_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168c_1
[]
=
{
{
0x02
,
0x0800
,
0x1000
},
{
0x03
,
0
,
0x0002
},
{
0x06
,
0x0080
,
0x0000
}
};
rtl_csi_access_enable_2
(
ioaddr
);
RTL_W8
(
DBG_REG
,
0x06
|
FIX_NAK_1
|
FIX_NAK_2
);
rtl_ephy_init
(
ioaddr
,
e_info_8168c_1
,
ARRAY_SIZE
(
e_info_8168c_1
));
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_hw_start_8168c_2
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168c_2
[]
=
{
{
0x01
,
0
,
0x0001
},
{
0x03
,
0x0400
,
0x0220
}
};
rtl_csi_access_enable_2
(
ioaddr
);
rtl_ephy_init
(
ioaddr
,
e_info_8168c_2
,
ARRAY_SIZE
(
e_info_8168c_2
));
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_hw_start_8168c_3
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_hw_start_8168c_2
(
ioaddr
,
pdev
);
}
static
void
rtl_hw_start_8168c_4
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable_2
(
ioaddr
);
__rtl_hw_start_8168cp
(
ioaddr
,
pdev
);
}
static
void
rtl_hw_start_8168d
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable_2
(
ioaddr
);
rtl_disable_clock_request
(
pdev
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W16
(
CPlusCmd
,
RTL_R16
(
CPlusCmd
)
&
~
R8168_CPCMD_QUIRK_MASK
);
}
static
void
rtl_hw_start_8168dp
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
rtl_csi_access_enable_1
(
ioaddr
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_disable_clock_request
(
pdev
);
}
static
void
rtl_hw_start_8168d_4
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168d_4
[]
=
{
{
0x0b
,
~
0
,
0x48
},
{
0x19
,
0x20
,
0x50
},
{
0x0c
,
~
0
,
0x20
}
};
int
i
;
rtl_csi_access_enable_1
(
ioaddr
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
e_info_8168d_4
);
i
++
)
{
const
struct
ephy_info
*
e
=
e_info_8168d_4
+
i
;
u16
w
;
w
=
rtl_ephy_read
(
ioaddr
,
e
->
offset
);
rtl_ephy_write
(
ioaddr
,
0x03
,
(
w
&
e
->
mask
)
|
e
->
bits
);
}
rtl_enable_clock_request
(
pdev
);
}
static
void
rtl_hw_start_8168e_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168e_1
[]
=
{
{
0x00
,
0x0200
,
0x0100
},
{
0x00
,
0x0000
,
0x0004
},
{
0x06
,
0x0002
,
0x0001
},
{
0x06
,
0x0000
,
0x0030
},
{
0x07
,
0x0000
,
0x2000
},
{
0x00
,
0x0000
,
0x0020
},
{
0x03
,
0x5800
,
0x2000
},
{
0x03
,
0x0000
,
0x0001
},
{
0x01
,
0x0800
,
0x1000
},
{
0x07
,
0x0000
,
0x4000
},
{
0x1e
,
0x0000
,
0x2000
},
{
0x19
,
0xffff
,
0xfe6c
},
{
0x0a
,
0x0000
,
0x0040
}
};
rtl_csi_access_enable_2
(
ioaddr
);
rtl_ephy_init
(
ioaddr
,
e_info_8168e_1
,
ARRAY_SIZE
(
e_info_8168e_1
));
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
RTL_W8
(
MaxTxPacketSize
,
TxPacketMax
);
rtl_disable_clock_request
(
pdev
);
/* Reset tx FIFO pointer */
RTL_W32
(
MISC
,
RTL_R32
(
MISC
)
|
TXPLA_RST
);
RTL_W32
(
MISC
,
RTL_R32
(
MISC
)
&
~
TXPLA_RST
);
RTL_W8
(
Config5
,
RTL_R8
(
Config5
)
&
~
Spi_en
);
}
static
void
rtl_hw_start_8168e_2
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168e_2
[]
=
{
{
0x09
,
0x0000
,
0x0080
},
{
0x19
,
0x0000
,
0x0224
}
};
rtl_csi_access_enable_1
(
ioaddr
);
rtl_ephy_init
(
ioaddr
,
e_info_8168e_2
,
ARRAY_SIZE
(
e_info_8168e_2
));
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
rtl_eri_write
(
ioaddr
,
0xc0
,
ERIAR_MASK_0011
,
0x0000
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xb8
,
ERIAR_MASK_0011
,
0x0000
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xc8
,
ERIAR_MASK_1111
,
0x00100002
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xe8
,
ERIAR_MASK_1111
,
0x00100006
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xcc
,
ERIAR_MASK_1111
,
0x00000050
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xd0
,
ERIAR_MASK_1111
,
0x07ff0060
,
ERIAR_EXGMAC
);
rtl_w1w0_eri
(
ioaddr
,
0x1b0
,
ERIAR_MASK_0001
,
0x10
,
0x00
,
ERIAR_EXGMAC
);
rtl_w1w0_eri
(
ioaddr
,
0x0d4
,
ERIAR_MASK_0011
,
0x0c00
,
0xff00
,
ERIAR_EXGMAC
);
RTL_W8
(
MaxTxPacketSize
,
EarlySize
);
rtl_disable_clock_request
(
pdev
);
RTL_W32
(
TxConfig
,
RTL_R32
(
TxConfig
)
|
TXCFG_AUTO_FIFO
);
RTL_W8
(
MCU
,
RTL_R8
(
MCU
)
&
~
NOW_IS_OOB
);
/* Adjust EEE LED frequency */
RTL_W8
(
EEE_LED
,
RTL_R8
(
EEE_LED
)
&
~
0x07
);
RTL_W8
(
DLLPR
,
RTL_R8
(
DLLPR
)
|
PFM_EN
);
RTL_W32
(
MISC
,
RTL_R32
(
MISC
)
|
PWM_EN
);
RTL_W8
(
Config5
,
RTL_R8
(
Config5
)
&
~
Spi_en
);
}
static
void
rtl_hw_start_8168f_1
(
void
__iomem
*
ioaddr
,
struct
pci_dev
*
pdev
)
{
static
const
struct
ephy_info
e_info_8168f_1
[]
=
{
{
0x06
,
0x00c0
,
0x0020
},
{
0x08
,
0x0001
,
0x0002
},
{
0x09
,
0x0000
,
0x0080
},
{
0x19
,
0x0000
,
0x0224
}
};
rtl_csi_access_enable_1
(
ioaddr
);
rtl_ephy_init
(
ioaddr
,
e_info_8168f_1
,
ARRAY_SIZE
(
e_info_8168f_1
));
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
rtl_tx_performance_tweak
(
pdev
,
0x5
<<
MAX_READ_REQUEST_SHIFT
);
rtl_eri_write
(
ioaddr
,
0xc0
,
ERIAR_MASK_0011
,
0x0000
,
ERIAR_EXGMAC
);
rtl_eri_write
(
ioaddr
,
0xb8
,
ERIAR_MASK_0011
,
0x0000
,
ERIAR_EXGMAC
);
...
...
@@ -6044,7 +5634,7 @@ static int rtl8169_close(struct net_device *dev)
rtl8169_down
(
dev
);
rtl_unlock_work
(
tp
);
free_irq
(
dev
->
irq
,
dev
);
free_irq
(
p
dev
->
irq
,
dev
);
dma_free_coherent
(
&
pdev
->
dev
,
R8169_RX_RING_BYTES
,
tp
->
RxDescArray
,
tp
->
RxPhyAddr
);
...
...
@@ -6058,54 +5648,93 @@ static int rtl8169_close(struct net_device *dev)
return
0
;
}
static
void
rtl_set_rx_mode
(
struct
net_device
*
dev
)
#ifdef CONFIG_NET_POLL_CONTROLLER
static
void
rtl8169_netpoll
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
u32
mc_filter
[
2
];
/* Multicast hash filter */
int
rx_mode
;
u32
tmp
=
0
;
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* Unconditionally log net taps. */
netif_notice
(
tp
,
link
,
dev
,
"Promiscuous mode enabled
\n
"
);
rx_mode
=
AcceptBroadcast
|
AcceptMulticast
|
AcceptMyPhys
|
AcceptAllPhys
;
mc_filter
[
1
]
=
mc_filter
[
0
]
=
0xffffffff
;
}
else
if
((
netdev_mc_count
(
dev
)
>
multicast_filter_limit
)
||
(
dev
->
flags
&
IFF_ALLMULTI
))
{
/* Too many to filter perfectly -- accept all multicasts. */
rx_mode
=
AcceptBroadcast
|
AcceptMulticast
|
AcceptMyPhys
;
mc_filter
[
1
]
=
mc_filter
[
0
]
=
0xffffffff
;
}
else
{
struct
netdev_hw_addr
*
ha
;
rtl8169_interrupt
(
tp
->
pci_dev
->
irq
,
dev
);
}
#endif
rx_mode
=
AcceptBroadcast
|
AcceptMyPhys
;
mc_filter
[
1
]
=
mc_filter
[
0
]
=
0
;
netdev_for_each_mc_addr
(
ha
,
dev
)
{
int
bit_nr
=
ether_crc
(
ETH_ALEN
,
ha
->
addr
)
>>
26
;
mc_filter
[
bit_nr
>>
5
]
|=
1
<<
(
bit_nr
&
31
);
rx_mode
|=
AcceptMulticast
;
}
}
static
int
rtl_open
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
int
retval
=
-
ENOMEM
;
if
(
dev
->
features
&
NETIF_F_RXALL
)
rx_mode
|=
(
AcceptErr
|
AcceptRunt
);
pm_runtime_get_sync
(
&
pdev
->
dev
);
tmp
=
(
RTL_R32
(
RxConfig
)
&
~
RX_CONFIG_ACCEPT_MASK
)
|
rx_mode
;
/*
* Rx and Tx desscriptors needs 256 bytes alignment.
* dma_alloc_coherent provides more.
*/
tp
->
TxDescArray
=
dma_alloc_coherent
(
&
pdev
->
dev
,
R8169_TX_RING_BYTES
,
&
tp
->
TxPhyAddr
,
GFP_KERNEL
);
if
(
!
tp
->
TxDescArray
)
goto
err_pm_runtime_put
;
if
(
tp
->
mac_version
>
RTL_GIGA_MAC_VER_06
)
{
u32
data
=
mc_filter
[
0
];
tp
->
RxDescArray
=
dma_alloc_coherent
(
&
pdev
->
dev
,
R8169_RX_RING_BYTES
,
&
tp
->
RxPhyAddr
,
GFP_KERNEL
);
if
(
!
tp
->
RxDescArray
)
goto
err_free_tx_0
;
mc_filter
[
0
]
=
swab32
(
mc_filter
[
1
]
);
mc_filter
[
1
]
=
swab32
(
data
);
}
retval
=
rtl8169_init_ring
(
dev
);
if
(
retval
<
0
)
goto
err_free_rx_1
;
RTL_W32
(
MAR0
+
4
,
mc_filter
[
1
]);
RTL_W32
(
MAR0
+
0
,
mc_filter
[
0
]);
INIT_WORK
(
&
tp
->
wk
.
work
,
rtl_task
);
RTL_W32
(
RxConfig
,
tmp
);
smp_mb
();
rtl_request_firmware
(
tp
);
retval
=
request_irq
(
pdev
->
irq
,
rtl8169_interrupt
,
(
tp
->
features
&
RTL_FEATURE_MSI
)
?
0
:
IRQF_SHARED
,
dev
->
name
,
dev
);
if
(
retval
<
0
)
goto
err_release_fw_2
;
rtl_lock_work
(
tp
);
set_bit
(
RTL_FLAG_TASK_ENABLED
,
tp
->
wk
.
flags
);
napi_enable
(
&
tp
->
napi
);
rtl8169_init_phy
(
dev
,
tp
);
__rtl8169_set_features
(
dev
,
dev
->
features
);
rtl_pll_power_up
(
tp
);
rtl_hw_start
(
dev
);
netif_start_queue
(
dev
);
rtl_unlock_work
(
tp
);
tp
->
saved_wolopts
=
0
;
pm_runtime_put_noidle
(
&
pdev
->
dev
);
rtl8169_check_link_status
(
dev
,
tp
,
ioaddr
);
out:
return
retval
;
err_release_fw_2:
rtl_release_firmware
(
tp
);
rtl8169_rx_clear
(
tp
);
err_free_rx_1:
dma_free_coherent
(
&
pdev
->
dev
,
R8169_RX_RING_BYTES
,
tp
->
RxDescArray
,
tp
->
RxPhyAddr
);
tp
->
RxDescArray
=
NULL
;
err_free_tx_0:
dma_free_coherent
(
&
pdev
->
dev
,
R8169_TX_RING_BYTES
,
tp
->
TxDescArray
,
tp
->
TxPhyAddr
);
tp
->
TxDescArray
=
NULL
;
err_pm_runtime_put:
pm_runtime_put_noidle
(
&
pdev
->
dev
);
goto
out
;
}
static
struct
rtnl_link_stats64
*
...
...
@@ -6167,160 +5796,507 @@ static int rtl8169_suspend(struct device *device)
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
rtl8169_net_suspend
(
dev
);
rtl8169_net_suspend
(
dev
);
return
0
;
}
static
void
__rtl8169_resume
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
netif_device_attach
(
dev
);
rtl_pll_power_up
(
tp
);
set_bit
(
RTL_FLAG_TASK_ENABLED
,
tp
->
wk
.
flags
);
rtl_schedule_task
(
tp
,
RTL_FLAG_TASK_RESET_PENDING
);
}
static
int
rtl8169_resume
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rtl8169_init_phy
(
dev
,
tp
);
if
(
netif_running
(
dev
))
__rtl8169_resume
(
dev
);
return
0
;
}
static
int
rtl8169_runtime_suspend
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
if
(
!
tp
->
TxDescArray
)
return
0
;
rtl_lock_work
(
tp
);
tp
->
saved_wolopts
=
__rtl8169_get_wol
(
tp
);
__rtl8169_set_wol
(
tp
,
WAKE_ANY
);
rtl_unlock_work
(
tp
);
rtl8169_net_suspend
(
dev
);
return
0
;
}
static
int
rtl8169_runtime_resume
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
if
(
!
tp
->
TxDescArray
)
return
0
;
rtl_lock_work
(
tp
);
__rtl8169_set_wol
(
tp
,
tp
->
saved_wolopts
);
tp
->
saved_wolopts
=
0
;
rtl_unlock_work
(
tp
);
rtl8169_init_phy
(
dev
,
tp
);
__rtl8169_resume
(
dev
);
return
0
;
}
static
int
rtl8169_runtime_idle
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
return
tp
->
TxDescArray
?
-
EBUSY
:
0
;
}
static
const
struct
dev_pm_ops
rtl8169_pm_ops
=
{
.
suspend
=
rtl8169_suspend
,
.
resume
=
rtl8169_resume
,
.
freeze
=
rtl8169_suspend
,
.
thaw
=
rtl8169_resume
,
.
poweroff
=
rtl8169_suspend
,
.
restore
=
rtl8169_resume
,
.
runtime_suspend
=
rtl8169_runtime_suspend
,
.
runtime_resume
=
rtl8169_runtime_resume
,
.
runtime_idle
=
rtl8169_runtime_idle
,
};
#define RTL8169_PM_OPS (&rtl8169_pm_ops)
#else
/* !CONFIG_PM */
#define RTL8169_PM_OPS NULL
#endif
/* !CONFIG_PM */
static
void
rtl_wol_shutdown_quirk
(
struct
rtl8169_private
*
tp
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
/* WoL fails with 8168b when the receiver is disabled. */
switch
(
tp
->
mac_version
)
{
case
RTL_GIGA_MAC_VER_11
:
case
RTL_GIGA_MAC_VER_12
:
case
RTL_GIGA_MAC_VER_17
:
pci_clear_master
(
tp
->
pci_dev
);
RTL_W8
(
ChipCmd
,
CmdRxEnb
);
/* PCI commit */
RTL_R8
(
ChipCmd
);
break
;
default:
break
;
}
}
static
void
rtl_shutdown
(
struct
pci_dev
*
pdev
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
struct
device
*
d
=
&
pdev
->
dev
;
pm_runtime_get_sync
(
d
);
rtl8169_net_suspend
(
dev
);
/* Restore original MAC address */
rtl_rar_set
(
tp
,
dev
->
perm_addr
);
rtl8169_hw_reset
(
tp
);
if
(
system_state
==
SYSTEM_POWER_OFF
)
{
if
(
__rtl8169_get_wol
(
tp
)
&
WAKE_ANY
)
{
rtl_wol_suspend_quirk
(
tp
);
rtl_wol_shutdown_quirk
(
tp
);
}
pci_wake_from_d3
(
pdev
,
true
);
pci_set_power_state
(
pdev
,
PCI_D3hot
);
}
pm_runtime_put_noidle
(
d
);
}
static
void
__devexit
rtl_remove_one
(
struct
pci_dev
*
pdev
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_27
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_28
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_31
)
{
rtl8168_driver_stop
(
tp
);
}
cancel_work_sync
(
&
tp
->
wk
.
work
);
unregister_netdev
(
dev
);
rtl_release_firmware
(
tp
);
if
(
pci_dev_run_wake
(
pdev
))
pm_runtime_get_noresume
(
&
pdev
->
dev
);
/* restore original MAC address */
rtl_rar_set
(
tp
,
dev
->
perm_addr
);
rtl_disable_msi
(
pdev
,
tp
);
rtl8169_release_board
(
pdev
,
dev
,
tp
->
mmio_addr
);
pci_set_drvdata
(
pdev
,
NULL
);
}
static
const
struct
net_device_ops
rtl_netdev_ops
=
{
.
ndo_open
=
rtl_open
,
.
ndo_stop
=
rtl8169_close
,
.
ndo_get_stats64
=
rtl8169_get_stats64
,
.
ndo_start_xmit
=
rtl8169_start_xmit
,
.
ndo_tx_timeout
=
rtl8169_tx_timeout
,
.
ndo_validate_addr
=
eth_validate_addr
,
.
ndo_change_mtu
=
rtl8169_change_mtu
,
.
ndo_fix_features
=
rtl8169_fix_features
,
.
ndo_set_features
=
rtl8169_set_features
,
.
ndo_set_mac_address
=
rtl_set_mac_address
,
.
ndo_do_ioctl
=
rtl8169_ioctl
,
.
ndo_set_rx_mode
=
rtl_set_rx_mode
,
#ifdef CONFIG_NET_POLL_CONTROLLER
.
ndo_poll_controller
=
rtl8169_netpoll
,
#endif
};
static
const
struct
rtl_cfg_info
{
void
(
*
hw_start
)(
struct
net_device
*
);
unsigned
int
region
;
unsigned
int
align
;
u16
event_slow
;
unsigned
features
;
u8
default_ver
;
}
rtl_cfg_infos
[]
=
{
[
RTL_CFG_0
]
=
{
.
hw_start
=
rtl_hw_start_8169
,
.
region
=
1
,
.
align
=
0
,
.
event_slow
=
SYSErr
|
LinkChg
|
RxOverflow
|
RxFIFOOver
,
.
features
=
RTL_FEATURE_GMII
,
.
default_ver
=
RTL_GIGA_MAC_VER_01
,
},
[
RTL_CFG_1
]
=
{
.
hw_start
=
rtl_hw_start_8168
,
.
region
=
2
,
.
align
=
8
,
.
event_slow
=
SYSErr
|
LinkChg
|
RxOverflow
,
.
features
=
RTL_FEATURE_GMII
|
RTL_FEATURE_MSI
,
.
default_ver
=
RTL_GIGA_MAC_VER_11
,
},
[
RTL_CFG_2
]
=
{
.
hw_start
=
rtl_hw_start_8101
,
.
region
=
2
,
.
align
=
8
,
.
event_slow
=
SYSErr
|
LinkChg
|
RxOverflow
|
RxFIFOOver
|
PCSTimeout
,
.
features
=
RTL_FEATURE_MSI
,
.
default_ver
=
RTL_GIGA_MAC_VER_13
,
}
};
/* Cfg9346_Unlock assumed. */
static
unsigned
rtl_try_msi
(
struct
rtl8169_private
*
tp
,
const
struct
rtl_cfg_info
*
cfg
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
msi
=
0
;
u8
cfg2
;
cfg2
=
RTL_R8
(
Config2
)
&
~
MSIEnable
;
if
(
cfg
->
features
&
RTL_FEATURE_MSI
)
{
if
(
pci_enable_msi
(
tp
->
pci_dev
))
{
netif_info
(
tp
,
hw
,
tp
->
dev
,
"no MSI. Back to INTx.
\n
"
);
}
else
{
cfg2
|=
MSIEnable
;
msi
=
RTL_FEATURE_MSI
;
}
}
if
(
tp
->
mac_version
<=
RTL_GIGA_MAC_VER_06
)
RTL_W8
(
Config2
,
cfg2
);
return
msi
;
}
static
int
__devinit
rtl_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
const
struct
rtl_cfg_info
*
cfg
=
rtl_cfg_infos
+
ent
->
driver_data
;
const
unsigned
int
region
=
cfg
->
region
;
struct
rtl8169_private
*
tp
;
struct
mii_if_info
*
mii
;
struct
net_device
*
dev
;
void
__iomem
*
ioaddr
;
int
chipset
,
i
;
int
rc
;
if
(
netif_msg_drv
(
&
debug
))
{
printk
(
KERN_INFO
"%s Gigabit Ethernet driver %s loaded
\n
"
,
MODULENAME
,
RTL8169_VERSION
);
}
dev
=
alloc_etherdev
(
sizeof
(
*
tp
));
if
(
!
dev
)
{
rc
=
-
ENOMEM
;
goto
out
;
}
SET_NETDEV_DEV
(
dev
,
&
pdev
->
dev
);
dev
->
netdev_ops
=
&
rtl_netdev_ops
;
tp
=
netdev_priv
(
dev
);
tp
->
dev
=
dev
;
tp
->
pci_dev
=
pdev
;
tp
->
msg_enable
=
netif_msg_init
(
debug
.
msg_enable
,
R8169_MSG_DEFAULT
);
mii
=
&
tp
->
mii
;
mii
->
dev
=
dev
;
mii
->
mdio_read
=
rtl_mdio_read
;
mii
->
mdio_write
=
rtl_mdio_write
;
mii
->
phy_id_mask
=
0x1f
;
mii
->
reg_num_mask
=
0x1f
;
mii
->
supports_gmii
=
!!
(
cfg
->
features
&
RTL_FEATURE_GMII
);
/* disable ASPM completely as that cause random device stop working
* problems as well as full system hangs for some PCIe devices users */
pci_disable_link_state
(
pdev
,
PCIE_LINK_STATE_L0S
|
PCIE_LINK_STATE_L1
|
PCIE_LINK_STATE_CLKPM
);
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc
=
pci_enable_device
(
pdev
);
if
(
rc
<
0
)
{
netif_err
(
tp
,
probe
,
dev
,
"enable failure
\n
"
);
goto
err_out_free_dev_1
;
}
if
(
pci_set_mwi
(
pdev
)
<
0
)
netif_info
(
tp
,
probe
,
dev
,
"Mem-Wr-Inval unavailable
\n
"
);
/* make sure PCI base addr 1 is MMIO */
if
(
!
(
pci_resource_flags
(
pdev
,
region
)
&
IORESOURCE_MEM
))
{
netif_err
(
tp
,
probe
,
dev
,
"region #%d not an MMIO resource, aborting
\n
"
,
region
);
rc
=
-
ENODEV
;
goto
err_out_mwi_2
;
}
return
0
;
}
/* check for weird/broken PCI region reporting */
if
(
pci_resource_len
(
pdev
,
region
)
<
R8169_REGS_SIZE
)
{
netif_err
(
tp
,
probe
,
dev
,
"Invalid PCI region size(s), aborting
\n
"
);
rc
=
-
ENODEV
;
goto
err_out_mwi_2
;
}
static
void
__rtl8169_resume
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rc
=
pci_request_regions
(
pdev
,
MODULENAME
);
if
(
rc
<
0
)
{
netif_err
(
tp
,
probe
,
dev
,
"could not request regions
\n
"
);
goto
err_out_mwi_2
;
}
netif_device_attach
(
dev
)
;
tp
->
cp_cmd
=
RxChkSum
;
rtl_pll_power_up
(
tp
);
if
((
sizeof
(
dma_addr_t
)
>
4
)
&&
!
pci_set_dma_mask
(
pdev
,
DMA_BIT_MASK
(
64
))
&&
use_dac
)
{
tp
->
cp_cmd
|=
PCIDAC
;
dev
->
features
|=
NETIF_F_HIGHDMA
;
}
else
{
rc
=
pci_set_dma_mask
(
pdev
,
DMA_BIT_MASK
(
32
));
if
(
rc
<
0
)
{
netif_err
(
tp
,
probe
,
dev
,
"DMA configuration failed
\n
"
);
goto
err_out_free_res_3
;
}
}
set_bit
(
RTL_FLAG_TASK_ENABLED
,
tp
->
wk
.
flags
);
/* ioremap MMIO region */
ioaddr
=
ioremap
(
pci_resource_start
(
pdev
,
region
),
R8169_REGS_SIZE
);
if
(
!
ioaddr
)
{
netif_err
(
tp
,
probe
,
dev
,
"cannot remap MMIO, aborting
\n
"
);
rc
=
-
EIO
;
goto
err_out_free_res_3
;
}
tp
->
mmio_addr
=
ioaddr
;
rtl_schedule_task
(
tp
,
RTL_FLAG_TASK_RESET_PENDING
);
}
if
(
!
pci_is_pcie
(
pdev
))
netif_info
(
tp
,
probe
,
dev
,
"not PCI Express
\n
"
);
static
int
rtl8169_resume
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
/* Identify chip attached to board */
rtl8169_get_mac_version
(
tp
,
dev
,
cfg
->
default_ver
);
rtl
8169_init_phy
(
dev
,
tp
);
rtl
_init_rxcfg
(
tp
);
if
(
netif_running
(
dev
))
__rtl8169_resume
(
dev
);
rtl_irq_disable
(
tp
);
return
0
;
}
rtl_hw_reset
(
tp
);
static
int
rtl8169_runtime_suspend
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rtl_ack_events
(
tp
,
0xffff
);
if
(
!
tp
->
TxDescArray
)
return
0
;
pci_set_master
(
pdev
);
rtl_lock_work
(
tp
);
tp
->
saved_wolopts
=
__rtl8169_get_wol
(
tp
);
__rtl8169_set_wol
(
tp
,
WAKE_ANY
);
rtl_unlock_work
(
tp
);
/*
* Pretend we are using VLANs; This bypasses a nasty bug where
* Interrupts stop flowing on high load on 8110SCd controllers.
*/
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_05
)
tp
->
cp_cmd
|=
RxVlan
;
rtl8169_net_suspend
(
dev
);
rtl_init_mdio_ops
(
tp
);
rtl_init_pll_power_ops
(
tp
);
rtl_init_jumbo_ops
(
tp
);
return
0
;
}
rtl8169_print_mac_version
(
tp
);
static
int
rtl8169_runtime_resume
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
chipset
=
tp
->
mac_version
;
tp
->
txd_version
=
rtl_chip_infos
[
chipset
].
txd_version
;
if
(
!
tp
->
TxDescArray
)
return
0
;
RTL_W8
(
Cfg9346
,
Cfg9346_Unlock
);
RTL_W8
(
Config1
,
RTL_R8
(
Config1
)
|
PMEnable
);
RTL_W8
(
Config5
,
RTL_R8
(
Config5
)
&
PMEStatus
);
if
((
RTL_R8
(
Config3
)
&
(
LinkUp
|
MagicPacket
))
!=
0
)
tp
->
features
|=
RTL_FEATURE_WOL
;
if
((
RTL_R8
(
Config5
)
&
(
UWF
|
BWF
|
MWF
))
!=
0
)
tp
->
features
|=
RTL_FEATURE_WOL
;
tp
->
features
|=
rtl_try_msi
(
tp
,
cfg
);
RTL_W8
(
Cfg9346
,
Cfg9346_Lock
);
rtl_lock_work
(
tp
);
__rtl8169_set_wol
(
tp
,
tp
->
saved_wolopts
);
tp
->
saved_wolopts
=
0
;
rtl_unlock_work
(
tp
);
if
(
rtl_tbi_enabled
(
tp
))
{
tp
->
set_speed
=
rtl8169_set_speed_tbi
;
tp
->
get_settings
=
rtl8169_gset_tbi
;
tp
->
phy_reset_enable
=
rtl8169_tbi_reset_enable
;
tp
->
phy_reset_pending
=
rtl8169_tbi_reset_pending
;
tp
->
link_ok
=
rtl8169_tbi_link_ok
;
tp
->
do_ioctl
=
rtl_tbi_ioctl
;
}
else
{
tp
->
set_speed
=
rtl8169_set_speed_xmii
;
tp
->
get_settings
=
rtl8169_gset_xmii
;
tp
->
phy_reset_enable
=
rtl8169_xmii_reset_enable
;
tp
->
phy_reset_pending
=
rtl8169_xmii_reset_pending
;
tp
->
link_ok
=
rtl8169_xmii_link_ok
;
tp
->
do_ioctl
=
rtl_xmii_ioctl
;
}
rtl8169_init_phy
(
dev
,
tp
);
mutex_init
(
&
tp
->
wk
.
mutex
);
__rtl8169_resume
(
dev
);
/* Get MAC address */
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
dev
->
dev_addr
[
i
]
=
RTL_R8
(
MAC0
+
i
);
memcpy
(
dev
->
perm_addr
,
dev
->
dev_addr
,
dev
->
addr_len
);
return
0
;
}
SET_ETHTOOL_OPS
(
dev
,
&
rtl8169_ethtool_ops
)
;
dev
->
watchdog_timeo
=
RTL8169_TX_TIMEOUT
;
static
int
rtl8169_runtime_idle
(
struct
device
*
device
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
device
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
netif_napi_add
(
dev
,
&
tp
->
napi
,
rtl8169_poll
,
R8169_NAPI_WEIGHT
);
return
tp
->
TxDescArray
?
-
EBUSY
:
0
;
}
/* don't enable SG, IP_CSUM and TSO by default - it might not work
* properly for all devices */
dev
->
features
|=
NETIF_F_RXCSUM
|
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
;
static
const
struct
dev_pm_ops
rtl8169_pm_ops
=
{
.
suspend
=
rtl8169_suspend
,
.
resume
=
rtl8169_resume
,
.
freeze
=
rtl8169_suspend
,
.
thaw
=
rtl8169_resume
,
.
poweroff
=
rtl8169_suspend
,
.
restore
=
rtl8169_resume
,
.
runtime_suspend
=
rtl8169_runtime_suspend
,
.
runtime_resume
=
rtl8169_runtime_resume
,
.
runtime_idle
=
rtl8169_runtime_idle
,
};
dev
->
hw_features
=
NETIF_F_SG
|
NETIF_F_IP_CSUM
|
NETIF_F_TSO
|
NETIF_F_RXCSUM
|
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
;
dev
->
vlan_features
=
NETIF_F_SG
|
NETIF_F_IP_CSUM
|
NETIF_F_TSO
|
NETIF_F_HIGHDMA
;
#define RTL8169_PM_OPS (&rtl8169_pm_ops)
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_05
)
/* 8110SCd requires hardware Rx VLAN - disallow toggling */
dev
->
hw_features
&=
~
NETIF_F_HW_VLAN_RX
;
#else
/* !CONFIG_PM */
dev
->
hw_features
|=
NETIF_F_RXALL
;
dev
->
hw_features
|=
NETIF_F_RXFCS
;
#define RTL8169_PM_OPS NULL
tp
->
hw_start
=
cfg
->
hw_start
;
tp
->
event_slow
=
cfg
->
event_slow
;
#endif
/* !CONFIG_PM */
tp
->
opts1_mask
=
(
tp
->
mac_version
!=
RTL_GIGA_MAC_VER_01
)
?
~
(
RxBOVF
|
RxFOVF
)
:
~
0
;
static
void
rtl_wol_shutdown_quirk
(
struct
rtl8169_private
*
tp
)
{
void
__iomem
*
ioaddr
=
tp
->
mmio_add
r
;
init_timer
(
&
tp
->
timer
);
tp
->
timer
.
data
=
(
unsigned
long
)
dev
;
tp
->
timer
.
function
=
rtl8169_phy_time
r
;
/* WoL fails with 8168b when the receiver is disabled. */
switch
(
tp
->
mac_version
)
{
case
RTL_GIGA_MAC_VER_11
:
case
RTL_GIGA_MAC_VER_12
:
case
RTL_GIGA_MAC_VER_17
:
pci_clear_master
(
tp
->
pci_dev
);
tp
->
rtl_fw
=
RTL_FIRMWARE_UNKNOWN
;
RTL_W8
(
ChipCmd
,
CmdRxEnb
);
/* PCI commit */
RTL_R8
(
ChipCmd
);
break
;
default:
break
;
}
}
rc
=
register_netdev
(
dev
);
if
(
rc
<
0
)
goto
err_out_msi_4
;
static
void
rtl_shutdown
(
struct
pci_dev
*
pdev
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
struct
device
*
d
=
&
pdev
->
dev
;
pci_set_drvdata
(
pdev
,
dev
);
pm_runtime_get_sync
(
d
);
netif_info
(
tp
,
probe
,
dev
,
"%s at 0x%p, %pM, XID %08x IRQ %d
\n
"
,
rtl_chip_infos
[
chipset
].
name
,
ioaddr
,
dev
->
dev_addr
,
(
u32
)(
RTL_R32
(
TxConfig
)
&
0x9cf0f8ff
),
pdev
->
irq
);
if
(
rtl_chip_infos
[
chipset
].
jumbo_max
!=
JUMBO_1K
)
{
netif_info
(
tp
,
probe
,
dev
,
"jumbo features [frames: %d bytes, "
"tx checksumming: %s]
\n
"
,
rtl_chip_infos
[
chipset
].
jumbo_max
,
rtl_chip_infos
[
chipset
].
jumbo_tx_csum
?
"ok"
:
"ko"
);
}
rtl8169_net_suspend
(
dev
);
if
(
tp
->
mac_version
==
RTL_GIGA_MAC_VER_27
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_28
||
tp
->
mac_version
==
RTL_GIGA_MAC_VER_31
)
{
rtl8168_driver_start
(
tp
);
}
/* Restore original MAC address */
rtl_rar_set
(
tp
,
dev
->
perm_addr
);
device_set_wakeup_enable
(
&
pdev
->
dev
,
tp
->
features
&
RTL_FEATURE_WOL
);
rtl8169_hw_reset
(
tp
);
if
(
pci_dev_run_wake
(
pdev
))
pm_runtime_put_noidle
(
&
pdev
->
dev
);
if
(
system_state
==
SYSTEM_POWER_OFF
)
{
if
(
__rtl8169_get_wol
(
tp
)
&
WAKE_ANY
)
{
rtl_wol_suspend_quirk
(
tp
);
rtl_wol_shutdown_quirk
(
tp
);
}
netif_carrier_off
(
dev
);
pci_wake_from_d3
(
pdev
,
true
);
pci_set_power_state
(
pdev
,
PCI_D3hot
);
}
out:
return
rc
;
pm_runtime_put_noidle
(
d
);
err_out_msi_4:
rtl_disable_msi
(
pdev
,
tp
);
iounmap
(
ioaddr
);
err_out_free_res_3:
pci_release_regions
(
pdev
);
err_out_mwi_2:
pci_clear_mwi
(
pdev
);
pci_disable_device
(
pdev
);
err_out_free_dev_1:
free_netdev
(
dev
);
goto
out
;
}
static
struct
pci_driver
rtl8169_pci_driver
=
{
.
name
=
MODULENAME
,
.
id_table
=
rtl8169_pci_tbl
,
.
probe
=
rtl
8169
_init_one
,
.
remove
=
__devexit_p
(
rtl
8169
_remove_one
),
.
probe
=
rtl_init_one
,
.
remove
=
__devexit_p
(
rtl_remove_one
),
.
shutdown
=
rtl_shutdown
,
.
driver
.
pm
=
RTL8169_PM_OPS
,
};
...
...
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