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
4dfd2c88
Commit
4dfd2c88
authored
Dec 26, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge pobox.com:/garz/repo/netdev-2.6/r8169
into pobox.com:/garz/repo/net-drivers-2.6
parents
f60fd965
966f4e9e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
645 additions
and
218 deletions
+645
-218
drivers/net/Kconfig
drivers/net/Kconfig
+9
-0
drivers/net/r8169.c
drivers/net/r8169.c
+636
-218
No files found.
drivers/net/Kconfig
View file @
4dfd2c88
...
...
@@ -1979,6 +1979,15 @@ config R8169_NAPI
If in doubt, say N.
config R8169_VLAN
bool "VLAN support"
depends on R8169 && VLAN_8021Q
---help---
Say Y here for the r8169 driver to support the functions required
by the kernel 802.1Q code.
If in doubt, say Y.
config SK98LIN
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
depends on PCI
...
...
drivers/net/r8169.c
View file @
4dfd2c88
...
...
@@ -6,6 +6,7 @@
History:
Feb 4 2002 - created initially by ShuChen <shuchen@realtek.com.tw>.
May 20 2002 - Add link status force-mode and TBI mode support.
2004 - Massive updates. See kernel SCM system for details.
=========================================================================
1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
Command: 'insmod r8169 media = SET_MEDIA'
...
...
@@ -33,22 +34,34 @@ VERSION 1.2 <2002/11/30>
- Copy mc_filter setup code from 8139cp
(includes an optimization, and avoids set_bit use)
VERSION 1.6LK <2004/04/14>
- Merge of Realtek's version 1.6
- Conversion to DMA API
- Suspend/resume
- Endianness
- Misc Rx/Tx bugs
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#define RTL8169_VERSION "1.
2
"
#define RTL8169_VERSION "1.
6LK
"
#define MODULENAME "r8169"
#define RTL8169_DRIVER_NAME MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION
#define PFX MODULENAME ": "
...
...
@@ -65,17 +78,23 @@ VERSION 1.2 <2002/11/30>
#define dprintk(fmt, args...) do {} while (0)
#endif
/* RTL8169_DEBUG */
#define TX_BUFFS_AVAIL(tp) \
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
#ifdef CONFIG_R8169_NAPI
#define rtl8169_rx_skb netif_receive_skb
#define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx
#define rtl8169_rx_quota(count, quota) min(count, quota)
#else
#define rtl8169_rx_skb netif_rx
#define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb
#define rtl8169_rx_quota(count, quota) count
#endif
/* media options */
#define MAX_UNITS 8
static
int
media
[
MAX_UNITS
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
};
static
int
num_media
=
0
;
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static
int
max_interrupt_work
=
20
;
...
...
@@ -87,9 +106,6 @@ static int multicast_filter_limit = 32;
/* MAC address length*/
#define MAC_ADDR_LEN 6
/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
#define MAX_ETH_FRAME_SIZE 1536
#define TX_FIFO_THRESH 256
/* In bytes */
#define RX_FIFO_THRESH 7
/* 7 means NO threshold, Rx buffer level before first PCI xfer. */
...
...
@@ -99,6 +115,7 @@ static int multicast_filter_limit = 32;
#define RxPacketMaxSize 0x0800
/* Maximum size supported is 16K-1 */
#define InterFrameGap 0x03
/* 3 means InterFrameGap = the shortest one */
#define R8169_REGS_SIZE 256
#define R8169_NAPI_WEIGHT 64
#define NUM_TX_DESC 64
/* Number of Tx descriptor registers */
#define NUM_RX_DESC 256
/* Number of Rx descriptor registers */
...
...
@@ -106,7 +123,6 @@ static int multicast_filter_limit = 32;
#define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
#define RTL_MIN_IO_SIZE 0x80
#define RTL8169_TX_TIMEOUT (6*HZ)
#define RTL8169_PHY_TIMEOUT (10*HZ)
...
...
@@ -122,7 +138,8 @@ enum mac_version {
RTL_GIGA_MAC_VER_B
=
0x00
,
/* RTL_GIGA_MAC_VER_C = 0x03, */
RTL_GIGA_MAC_VER_D
=
0x01
,
RTL_GIGA_MAC_VER_E
=
0x02
RTL_GIGA_MAC_VER_E
=
0x02
,
RTL_GIGA_MAC_VER_X
=
0x04
/* Greater than RTL_GIGA_MAC_VER_E */
};
enum
phy_version
{
...
...
@@ -305,28 +322,57 @@ enum RTL8169_register_content {
};
enum
_DescStatusBit
{
OWNbit
=
0x80000000
,
EORbit
=
0x40000000
,
FSbit
=
0x20000000
,
LSbit
=
0x10000000
,
DescOwn
=
(
1
<<
31
),
/* Descriptor is owned by NIC */
RingEnd
=
(
1
<<
30
),
/* End of descriptor ring */
FirstFrag
=
(
1
<<
29
),
/* First segment of a packet */
LastFrag
=
(
1
<<
28
),
/* Final segment of a packet */
/* Tx private */
LargeSend
=
(
1
<<
27
),
/* TCP Large Send Offload (TSO) */
MSSShift
=
16
,
/* MSS value position */
MSSMask
=
0xfff
,
/* MSS value + LargeSend bit: 12 bits */
IPCS
=
(
1
<<
18
),
/* Calculate IP checksum */
UDPCS
=
(
1
<<
17
),
/* Calculate UDP/IP checksum */
TCPCS
=
(
1
<<
16
),
/* Calculate TCP/IP checksum */
TxVlanTag
=
(
1
<<
17
),
/* Add VLAN tag */
/* Rx private */
PID1
=
(
1
<<
18
),
/* Protocol ID bit 1/2 */
PID0
=
(
1
<<
17
),
/* Protocol ID bit 2/2 */
#define RxProtoUDP (PID1)
#define RxProtoTCP (PID0)
#define RxProtoIP (PID1 | PID0)
#define RxProtoMask RxProtoIP
IPFail
=
(
1
<<
16
),
/* IP checksum failed */
UDPFail
=
(
1
<<
15
),
/* UDP/IP checksum failed */
TCPFail
=
(
1
<<
14
),
/* TCP/IP checksum failed */
RxVlanTag
=
(
1
<<
16
),
/* VLAN tag available */
};
#define RsvdMask 0x3fffc000
struct
TxDesc
{
u32
status
;
u32
vlan_tag
;
u32
opts1
;
u32
opts2
;
u64
addr
;
};
struct
RxDesc
{
u32
status
;
u32
vlan_tag
;
u32
opts1
;
u32
opts2
;
u64
addr
;
};
struct
ring_info
{
struct
sk_buff
*
skb
;
u32
len
;
u8
__pad
[
sizeof
(
void
*
)
-
sizeof
(
u32
)];
};
struct
rtl8169_private
{
void
*
mmio_addr
;
/* memory map physical address */
void
__iomem
*
mmio_addr
;
/* memory map physical address */
struct
pci_dev
*
pci_dev
;
/* Index of PCI device */
struct
net_device_stats
stats
;
/* statistics of net device */
spinlock_t
lock
;
/* spin lock flag */
...
...
@@ -342,25 +388,29 @@ struct rtl8169_private {
dma_addr_t
TxPhyAddr
;
dma_addr_t
RxPhyAddr
;
struct
sk_buff
*
Rx_skbuff
[
NUM_RX_DESC
];
/* Rx data buffers */
struct
sk_buff
*
Tx_skbuff
[
NUM_TX_DESC
];
/* Tx data buffers */
struct
ring_info
tx_skb
[
NUM_TX_DESC
];
/* Tx data buffers */
unsigned
rx_buf_sz
;
struct
timer_list
timer
;
u16
cp_cmd
;
u16
intr_mask
;
int
phy_auto_nego_reg
;
int
phy_1000_ctrl_reg
;
#ifdef CONFIG_R8169_VLAN
struct
vlan_group
*
vlgrp
;
#endif
int
(
*
set_speed
)(
struct
net_device
*
,
u8
autoneg
,
u16
speed
,
u8
duplex
);
void
(
*
get_settings
)(
struct
net_device
*
,
struct
ethtool_cmd
*
);
void
(
*
phy_reset_enable
)(
void
*
);
unsigned
int
(
*
phy_reset_pending
)(
void
*
);
unsigned
int
(
*
link_ok
)(
void
*
);
void
(
*
phy_reset_enable
)(
void
__iomem
*
);
unsigned
int
(
*
phy_reset_pending
)(
void
__iomem
*
);
unsigned
int
(
*
link_ok
)(
void
__iomem
*
);
struct
work_struct
task
;
};
MODULE_AUTHOR
(
"Realtek"
);
MODULE_DESCRIPTION
(
"RealTek RTL-8169 Gigabit Ethernet driver"
);
MODULE_PARM
(
media
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
MODULE_PARM
(
rx_copybreak
,
"i"
);
MODULE_PARM
(
use_dac
,
"i"
);
module_param_array
(
media
,
int
,
&
num_media
,
0
);
module_param
(
rx_copybreak
,
int
,
0
);
module_param
(
use_dac
,
int
,
0
);
MODULE_PARM_DESC
(
use_dac
,
"Enable PCI DAC. Unsafe on 32 bit PCI slot."
);
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -374,6 +424,8 @@ static int rtl8169_close(struct net_device *dev);
static
void
rtl8169_set_rx_mode
(
struct
net_device
*
dev
);
static
void
rtl8169_tx_timeout
(
struct
net_device
*
dev
);
static
struct
net_device_stats
*
rtl8169_get_stats
(
struct
net_device
*
netdev
);
static
int
rtl8169_rx_interrupt
(
struct
net_device
*
,
struct
rtl8169_private
*
,
void
__iomem
*
);
#ifdef CONFIG_R8169_NAPI
static
int
rtl8169_poll
(
struct
net_device
*
dev
,
int
*
budget
);
#endif
...
...
@@ -390,7 +442,7 @@ static const unsigned int rtl8169_rx_config =
#define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less
#define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less
static
void
mdio_write
(
void
*
ioaddr
,
int
RegAddr
,
int
value
)
static
void
mdio_write
(
void
__iomem
*
ioaddr
,
int
RegAddr
,
int
value
)
{
int
i
;
...
...
@@ -405,7 +457,7 @@ static void mdio_write(void *ioaddr, int RegAddr, int value)
}
}
static
int
mdio_read
(
void
*
ioaddr
,
int
RegAddr
)
static
int
mdio_read
(
void
__iomem
*
ioaddr
,
int
RegAddr
)
{
int
i
,
value
=
-
1
;
...
...
@@ -423,32 +475,32 @@ static int mdio_read(void *ioaddr, int RegAddr)
return
value
;
}
static
unsigned
int
rtl8169_tbi_reset_pending
(
void
*
ioaddr
)
static
unsigned
int
rtl8169_tbi_reset_pending
(
void
__iomem
*
ioaddr
)
{
return
RTL_R32
(
TBICSR
)
&
TBIReset
;
}
static
unsigned
int
rtl8169_xmii_reset_pending
(
void
*
ioaddr
)
static
unsigned
int
rtl8169_xmii_reset_pending
(
void
__iomem
*
ioaddr
)
{
return
mdio_read
(
ioaddr
,
0
)
&
0x8000
;
}
static
unsigned
int
rtl8169_tbi_link_ok
(
void
*
ioaddr
)
static
unsigned
int
rtl8169_tbi_link_ok
(
void
__iomem
*
ioaddr
)
{
return
RTL_R32
(
TBICSR
)
&
TBILinkOk
;
}
static
unsigned
int
rtl8169_xmii_link_ok
(
void
*
ioaddr
)
static
unsigned
int
rtl8169_xmii_link_ok
(
void
__iomem
*
ioaddr
)
{
return
RTL_R8
(
PHYstatus
)
&
LinkStatus
;
}
static
void
rtl8169_tbi_reset_enable
(
void
*
ioaddr
)
static
void
rtl8169_tbi_reset_enable
(
void
__iomem
*
ioaddr
)
{
RTL_W32
(
TBICSR
,
RTL_R32
(
TBICSR
)
|
TBIReset
);
}
static
void
rtl8169_xmii_reset_enable
(
void
*
ioaddr
)
static
void
rtl8169_xmii_reset_enable
(
void
__iomem
*
ioaddr
)
{
unsigned
int
val
;
...
...
@@ -457,7 +509,7 @@ static void rtl8169_xmii_reset_enable(void *ioaddr)
}
static
void
rtl8169_check_link_status
(
struct
net_device
*
dev
,
struct
rtl8169_private
*
tp
,
void
*
ioaddr
)
struct
rtl8169_private
*
tp
,
void
__iomem
*
ioaddr
)
{
unsigned
long
flags
;
...
...
@@ -512,11 +564,16 @@ static void rtl8169_get_drvinfo(struct net_device *dev,
strcpy
(
info
->
bus_info
,
pci_name
(
tp
->
pci_dev
));
}
static
int
rtl8169_get_regs_len
(
struct
net_device
*
dev
)
{
return
R8169_REGS_SIZE
;
}
static
int
rtl8169_set_speed_tbi
(
struct
net_device
*
dev
,
u8
autoneg
,
u16
speed
,
u8
duplex
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
int
ret
=
0
;
u32
reg
;
...
...
@@ -540,7 +597,7 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
u8
autoneg
,
u16
speed
,
u8
duplex
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
int
auto_nego
,
giga_ctrl
;
auto_nego
=
mdio_read
(
ioaddr
,
PHY_AUTO_NEGO_REG
);
...
...
@@ -602,10 +659,108 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return
ret
;
}
static
u32
rtl8169_get_rx_csum
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
return
tp
->
cp_cmd
&
RxChkSum
;
}
static
int
rtl8169_set_rx_csum
(
struct
net_device
*
dev
,
u32
data
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
tp
->
lock
,
flags
);
if
(
data
)
tp
->
cp_cmd
|=
RxChkSum
;
else
tp
->
cp_cmd
&=
~
RxChkSum
;
RTL_W16
(
CPlusCmd
,
tp
->
cp_cmd
);
RTL_R16
(
CPlusCmd
);
spin_unlock_irqrestore
(
&
tp
->
lock
,
flags
);
return
0
;
}
#ifdef CONFIG_R8169_VLAN
static
inline
u32
rtl8169_tx_vlan_tag
(
struct
rtl8169_private
*
tp
,
struct
sk_buff
*
skb
)
{
return
(
tp
->
vlgrp
&&
vlan_tx_tag_present
(
skb
))
?
TxVlanTag
|
cpu_to_be16
(
vlan_tx_tag_get
(
skb
))
:
0x00
;
}
static
void
rtl8169_vlan_rx_register
(
struct
net_device
*
dev
,
struct
vlan_group
*
grp
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
tp
->
lock
,
flags
);
tp
->
vlgrp
=
grp
;
if
(
tp
->
vlgrp
)
tp
->
cp_cmd
|=
RxVlan
;
else
tp
->
cp_cmd
&=
~
RxVlan
;
RTL_W16
(
CPlusCmd
,
tp
->
cp_cmd
);
RTL_R16
(
CPlusCmd
);
spin_unlock_irqrestore
(
&
tp
->
lock
,
flags
);
}
static
void
rtl8169_vlan_rx_kill_vid
(
struct
net_device
*
dev
,
unsigned
short
vid
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
tp
->
lock
,
flags
);
if
(
tp
->
vlgrp
)
tp
->
vlgrp
->
vlan_devices
[
vid
]
=
NULL
;
spin_unlock_irqrestore
(
&
tp
->
lock
,
flags
);
}
static
int
rtl8169_rx_vlan_skb
(
struct
rtl8169_private
*
tp
,
struct
RxDesc
*
desc
,
struct
sk_buff
*
skb
)
{
u32
opts2
=
desc
->
opts2
;
int
ret
;
if
(
tp
->
vlgrp
&&
(
opts2
&
RxVlanTag
))
{
rtl8169_rx_hwaccel_skb
(
skb
,
tp
->
vlgrp
,
be16_to_cpu
(
opts2
&
0xffff
));
ret
=
0
;
}
else
ret
=
-
1
;
desc
->
opts2
=
0
;
return
ret
;
}
#else
/* !CONFIG_R8169_VLAN */
static
inline
u32
rtl8169_tx_vlan_tag
(
struct
rtl8169_private
*
tp
,
struct
sk_buff
*
skb
)
{
return
0
;
}
static
int
rtl8169_rx_vlan_skb
(
struct
rtl8169_private
*
tp
,
struct
RxDesc
*
desc
,
struct
sk_buff
*
skb
)
{
return
-
1
;
}
#endif
static
void
rtl8169_gset_tbi
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
u32
status
;
cmd
->
supported
=
...
...
@@ -624,7 +779,7 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
static
void
rtl8169_gset_xmii
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
u8
status
;
cmd
->
supported
=
SUPPORTED_10baseT_Half
|
...
...
@@ -675,15 +830,38 @@ static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return
0
;
}
static
void
rtl8169_get_regs
(
struct
net_device
*
dev
,
struct
ethtool_regs
*
regs
,
void
*
p
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
unsigned
long
flags
;
if
(
regs
->
len
>
R8169_REGS_SIZE
)
regs
->
len
=
R8169_REGS_SIZE
;
spin_lock_irqsave
(
&
tp
->
lock
,
flags
);
memcpy_fromio
(
p
,
tp
->
mmio_addr
,
regs
->
len
);
spin_unlock_irqrestore
(
&
tp
->
lock
,
flags
);
}
static
struct
ethtool_ops
rtl8169_ethtool_ops
=
{
.
get_drvinfo
=
rtl8169_get_drvinfo
,
.
get_regs_len
=
rtl8169_get_regs_len
,
.
get_link
=
ethtool_op_get_link
,
.
get_settings
=
rtl8169_get_settings
,
.
set_settings
=
rtl8169_set_settings
,
.
get_rx_csum
=
rtl8169_get_rx_csum
,
.
set_rx_csum
=
rtl8169_set_rx_csum
,
.
get_tx_csum
=
ethtool_op_get_tx_csum
,
.
set_tx_csum
=
ethtool_op_set_tx_csum
,
.
get_sg
=
ethtool_op_get_sg
,
.
set_sg
=
ethtool_op_set_sg
,
.
get_tso
=
ethtool_op_get_tso
,
.
set_tso
=
ethtool_op_set_tso
,
.
get_regs
=
rtl8169_get_regs
,
};
static
void
rtl8169_write_gmii_reg_bit
(
void
*
ioaddr
,
int
reg
,
int
bitnum
,
static
void
rtl8169_write_gmii_reg_bit
(
void
__iomem
*
ioaddr
,
int
reg
,
int
bitnum
,
int
bitval
)
{
int
val
;
...
...
@@ -694,12 +872,13 @@ static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, int bitnum,
mdio_write
(
ioaddr
,
reg
,
val
&
0xffff
);
}
static
void
rtl8169_get_mac_version
(
struct
rtl8169_private
*
tp
,
void
*
ioaddr
)
static
void
rtl8169_get_mac_version
(
struct
rtl8169_private
*
tp
,
void
__iomem
*
ioaddr
)
{
const
struct
{
u32
mask
;
int
mac_version
;
}
mac_info
[]
=
{
{
0x1
<<
28
,
RTL_GIGA_MAC_VER_X
},
{
0x1
<<
26
,
RTL_GIGA_MAC_VER_E
},
{
0x1
<<
23
,
RTL_GIGA_MAC_VER_D
},
{
0x00000000
,
RTL_GIGA_MAC_VER_B
}
/* Catch-all */
...
...
@@ -734,7 +913,7 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp)
dprintk
(
"mac_version == Unknown
\n
"
);
}
static
void
rtl8169_get_phy_version
(
struct
rtl8169_private
*
tp
,
void
*
ioaddr
)
static
void
rtl8169_get_phy_version
(
struct
rtl8169_private
*
tp
,
void
__iomem
*
ioaddr
)
{
const
struct
{
u16
mask
;
...
...
@@ -780,7 +959,7 @@ static void rtl8169_print_phy_version(struct rtl8169_private *tp)
static
void
rtl8169_hw_phy_config
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
struct
{
u16
regs
[
5
];
/* Beware of bit-sign propagation */
}
phy_magic
[
5
]
=
{
{
...
...
@@ -850,7 +1029,7 @@ static void rtl8169_phy_timer(unsigned long __opaque)
struct
net_device
*
dev
=
(
struct
net_device
*
)
__opaque
;
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
struct
timer_list
*
timer
=
&
tp
->
timer
;
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
long
timeout
=
RTL8169_PHY_TIMEOUT
;
assert
(
tp
->
mac_version
>
RTL_GIGA_MAC_VER_B
);
...
...
@@ -911,41 +1090,65 @@ static inline void rtl8169_request_timer(struct net_device *dev)
add_timer
(
timer
);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
* without having to re-enable interrupts. It's not called while
* the interrupt routine is executing.
*/
static
void
rtl8169_netpoll
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
disable_irq
(
pdev
->
irq
);
rtl8169_interrupt
(
pdev
->
irq
,
dev
,
NULL
);
enable_irq
(
pdev
->
irq
);
}
#endif
static
void
rtl8169_release_board
(
struct
pci_dev
*
pdev
,
struct
net_device
*
dev
,
void
__iomem
*
ioaddr
)
{
iounmap
(
ioaddr
);
pci_release_regions
(
pdev
);
pci_disable_device
(
pdev
);
free_netdev
(
dev
);
}
static
int
__devinit
rtl8169_init_board
(
struct
pci_dev
*
pdev
,
struct
net_device
**
dev_out
,
void
**
ioaddr_out
)
void
__iomem
**
ioaddr_out
)
{
void
*
ioaddr
=
NULL
;
void
__iomem
*
ioaddr
;
struct
net_device
*
dev
;
struct
rtl8169_private
*
tp
;
unsigned
long
mmio_start
,
mmio_end
,
mmio_flags
,
mmio_len
;
int
rc
,
i
,
acpi_idle_state
=
0
,
pm_cap
;
int
rc
=
-
ENOMEM
,
i
,
acpi_idle_state
=
0
,
pm_cap
;
assert
(
pdev
!=
NULL
);
assert
(
ioaddr_out
!=
NULL
);
*
ioaddr_out
=
NULL
;
*
dev_out
=
NULL
;
// dev zeroed in alloc_etherdev
dev
=
alloc_etherdev
(
sizeof
(
*
tp
));
if
(
dev
==
NULL
)
{
printk
(
KERN_ERR
PFX
"unable to alloc new ethernet
\n
"
);
return
-
ENOMEM
;
goto
err_out
;
}
SET_MODULE_OWNER
(
dev
);
SET_NETDEV_DEV
(
dev
,
&
pdev
->
dev
);
tp
=
dev
->
priv
;
tp
=
netdev_priv
(
dev
)
;
// enable device (incl. PCI PM wakeup and hotplug setup)
rc
=
pci_enable_device
(
pdev
);
if
(
rc
)
{
printk
(
KERN_ERR
PFX
"%s: enable failure
\n
"
,
pdev
->
slot_name
);
goto
err_out
;
goto
err_out
_free_dev
;
}
rc
=
pci_set_mwi
(
pdev
);
if
(
rc
<
0
)
goto
err_out_disable
;
/* save power state before pci_enable_device overwrites it */
pm_cap
=
pci_find_capability
(
pdev
,
PCI_CAP_ID_PM
);
if
(
pm_cap
)
{
...
...
@@ -956,41 +1159,37 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
}
else
{
printk
(
KERN_ERR
PFX
"Cannot find PowerManagement capability, aborting.
\n
"
);
goto
err_out_
free_res
;
goto
err_out_
mwi
;
}
mmio_start
=
pci_resource_start
(
pdev
,
1
);
mmio_end
=
pci_resource_end
(
pdev
,
1
);
mmio_flags
=
pci_resource_flags
(
pdev
,
1
);
mmio_len
=
pci_resource_len
(
pdev
,
1
);
// make sure PCI base addr 1 is MMIO
if
(
!
(
mmio_flags
&
IORESOURCE_MEM
))
{
if
(
!
(
pci_resource_flags
(
pdev
,
1
)
&
IORESOURCE_MEM
))
{
printk
(
KERN_ERR
PFX
"region #1 not an MMIO resource, aborting
\n
"
);
rc
=
-
ENODEV
;
goto
err_out_
disable
;
goto
err_out_
mwi
;
}
// check for weird/broken PCI region reporting
if
(
mmio_len
<
RTL_MIN_IO
_SIZE
)
{
if
(
pci_resource_len
(
pdev
,
1
)
<
R8169_REGS
_SIZE
)
{
printk
(
KERN_ERR
PFX
"Invalid PCI region size(s), aborting
\n
"
);
rc
=
-
ENODEV
;
goto
err_out_
disable
;
goto
err_out_
mwi
;
}
rc
=
pci_request_regions
(
pdev
,
MODULENAME
);
if
(
rc
)
{
printk
(
KERN_ERR
PFX
"%s: could not request regions.
\n
"
,
pdev
->
slot_name
);
goto
err_out_
disable
;
goto
err_out_
mwi
;
}
tp
->
cp_cmd
=
PCIMulRW
|
RxChkSum
;
if
((
sizeof
(
dma_addr_t
)
>
4
)
&&
!
pci_set_dma_mask
(
pdev
,
DMA_64BIT_MASK
)
&&
use_dac
)
!
pci_set_dma_mask
(
pdev
,
DMA_64BIT_MASK
)
&&
use_dac
)
{
tp
->
cp_cmd
|=
PCIDAC
;
else
{
dev
->
features
|=
NETIF_F_HIGHDMA
;
}
else
{
rc
=
pci_set_dma_mask
(
pdev
,
DMA_32BIT_MASK
);
if
(
rc
<
0
)
{
printk
(
KERN_ERR
PFX
"DMA configuration failed.
\n
"
);
...
...
@@ -998,12 +1197,10 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
}
}
// enable PCI bus-mastering
pci_set_master
(
pdev
);
// ioremap MMIO region
ioaddr
=
ioremap
(
mmio_start
,
mmio_len
);
ioaddr
=
ioremap
(
pci_resource_start
(
pdev
,
1
),
R8169_REGS_SIZE
);
if
(
ioaddr
==
NULL
)
{
printk
(
KERN_ERR
PFX
"cannot remap MMIO, aborting
\n
"
);
rc
=
-
EIO
;
...
...
@@ -1040,27 +1237,36 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
}
tp
->
chipset
=
i
;
tp
->
rx_buf_sz
=
RX_BUF_SIZE
;
*
ioaddr_out
=
ioaddr
;
*
dev_out
=
dev
;
return
0
;
out:
return
rc
;
err_out_free_res:
pci_release_regions
(
pdev
);
err_out_mwi:
pci_clear_mwi
(
pdev
);
err_out_disable:
pci_disable_device
(
pdev
);
err_out:
err_out
_free_dev
:
free_netdev
(
dev
);
return
rc
;
err_out:
*
ioaddr_out
=
NULL
;
*
dev_out
=
NULL
;
goto
out
;
}
static
int
__devinit
rtl8169_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
struct
net_device
*
dev
=
NULL
;
struct
rtl8169_private
*
tp
=
NULL
;
void
*
ioaddr
=
NULL
;
struct
rtl8169_private
*
tp
;
void
__iomem
*
ioaddr
=
NULL
;
static
int
board_idx
=
-
1
;
static
int
printed_version
=
0
;
u8
autoneg
,
duplex
;
...
...
@@ -1081,10 +1287,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if
(
rc
)
return
rc
;
tp
=
dev
->
priv
;
tp
=
netdev_priv
(
dev
)
;
assert
(
ioaddr
!=
NULL
);
assert
(
dev
!=
NULL
);
assert
(
tp
!=
NULL
);
if
(
RTL_R8
(
PHYstatus
)
&
TBI_Enable
)
{
tp
->
set_speed
=
rtl8169_set_speed_tbi
;
...
...
@@ -1109,18 +1313,30 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev
->
open
=
rtl8169_open
;
dev
->
hard_start_xmit
=
rtl8169_start_xmit
;
dev
->
get_stats
=
rtl8169_get_stats
;
dev
->
ethtool_ops
=
&
rtl8169_ethtool_ops
;
SET_ETHTOOL_OPS
(
dev
,
&
rtl8169_ethtool_ops
)
;
dev
->
stop
=
rtl8169_close
;
dev
->
tx_timeout
=
rtl8169_tx_timeout
;
dev
->
set_multicast_list
=
rtl8169_set_rx_mode
;
dev
->
watchdog_timeo
=
RTL8169_TX_TIMEOUT
;
dev
->
irq
=
pdev
->
irq
;
dev
->
base_addr
=
(
unsigned
long
)
ioaddr
;
#ifdef CONFIG_R8169_NAPI
dev
->
poll
=
rtl8169_poll
;
dev
->
weight
=
R8169_NAPI_WEIGHT
;
printk
(
KERN_INFO
PFX
"NAPI enabled
\n
"
);
#endif
#ifdef CONFIG_R8169_VLAN
dev
->
features
|=
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
;
dev
->
vlan_rx_register
=
rtl8169_vlan_rx_register
;
dev
->
vlan_rx_kill_vid
=
rtl8169_vlan_rx_kill_vid
;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev
->
poll_controller
=
rtl8169_netpoll
;
#endif
tp
->
intr_mask
=
0xffff
;
tp
->
pci_dev
=
pdev
;
tp
->
mmio_addr
=
ioaddr
;
...
...
@@ -1129,10 +1345,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc
=
register_netdev
(
dev
);
if
(
rc
)
{
iounmap
(
ioaddr
);
pci_release_regions
(
pdev
);
pci_disable_device
(
pdev
);
free_netdev
(
dev
);
rtl8169_release_board
(
pdev
,
dev
,
ioaddr
);
return
rc
;
}
...
...
@@ -1188,11 +1401,7 @@ rtl8169_remove_one(struct pci_dev *pdev)
assert
(
tp
!=
NULL
);
unregister_netdev
(
dev
);
iounmap
(
tp
->
mmio_addr
);
pci_release_regions
(
pdev
);
pci_disable_device
(
pdev
);
free_netdev
(
dev
);
rtl8169_release_board
(
pdev
,
dev
,
tp
->
mmio_addr
);
pci_set_drvdata
(
pdev
,
NULL
);
}
...
...
@@ -1202,7 +1411,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, u32 state)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
long
flags
;
if
(
!
netif_running
(
dev
))
...
...
@@ -1271,6 +1480,8 @@ rtl8169_open(struct net_device *dev)
if
(
retval
<
0
)
goto
err_free_rx
;
INIT_WORK
(
&
tp
->
task
,
NULL
,
dev
);
rtl8169_hw_start
(
dev
);
rtl8169_request_timer
(
dev
);
...
...
@@ -1290,11 +1501,23 @@ rtl8169_open(struct net_device *dev)
goto
out
;
}
static
void
rtl8169_hw_reset
(
void
__iomem
*
ioaddr
)
{
/* Disable interrupts */
RTL_W16
(
IntrMask
,
0x0000
);
/* Reset the chipset */
RTL_W8
(
ChipCmd
,
CmdReset
);
/* PCI commit */
RTL_R8
(
ChipCmd
);
}
static
void
rtl8169_hw_start
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
u32
i
;
/* Soft reset the chip. */
...
...
@@ -1333,8 +1556,6 @@ rtl8169_hw_start(struct net_device *dev)
RTL_W16
(
CPlusCmd
,
tp
->
cp_cmd
);
}
tp
->
cur_rx
=
0
;
RTL_W32
(
TxDescStartAddrLow
,
((
u64
)
tp
->
TxPhyAddr
&
DMA_32BIT_MASK
));
RTL_W32
(
TxDescStartAddrHigh
,
((
u64
)
tp
->
TxPhyAddr
>>
32
));
RTL_W32
(
RxDescAddrLow
,
((
u64
)
tp
->
RxPhyAddr
&
DMA_32BIT_MASK
));
...
...
@@ -1358,49 +1579,51 @@ rtl8169_hw_start(struct net_device *dev)
static
inline
void
rtl8169_make_unusable_by_asic
(
struct
RxDesc
*
desc
)
{
desc
->
addr
=
0x0badbadbadbadbadull
;
desc
->
status
&=
~
cpu_to_le32
(
OWNbit
|
RsvdMask
);
desc
->
opts1
&=
~
cpu_to_le32
(
DescOwn
|
RsvdMask
);
}
static
void
rtl8169_free_rx_skb
(
struct
pci_dev
*
pdev
,
struct
sk_buff
**
sk_buff
,
struct
RxDesc
*
desc
)
static
void
rtl8169_free_rx_skb
(
struct
rtl8169_private
*
tp
,
struct
sk_buff
**
sk_buff
,
struct
RxDesc
*
desc
)
{
pci_unmap_single
(
pdev
,
le64_to_cpu
(
desc
->
addr
),
RX_BUF_SIZE
,
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
pci_unmap_single
(
pdev
,
le64_to_cpu
(
desc
->
addr
),
tp
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
dev_kfree_skb
(
*
sk_buff
);
*
sk_buff
=
NULL
;
rtl8169_make_unusable_by_asic
(
desc
);
}
static
inline
void
rtl8169_return_to_asic
(
struct
RxDesc
*
desc
)
static
inline
void
rtl8169_return_to_asic
(
struct
RxDesc
*
desc
,
int
rx_buf_sz
)
{
desc
->
status
|=
cpu_to_le32
(
OWNbit
+
RX_BUF_SIZE
);
desc
->
opts1
|=
cpu_to_le32
(
DescOwn
+
rx_buf_sz
);
}
static
inline
void
rtl8169_give_to_asic
(
struct
RxDesc
*
desc
,
dma_addr_t
mapping
)
static
inline
void
rtl8169_give_to_asic
(
struct
RxDesc
*
desc
,
dma_addr_t
mapping
,
int
rx_buf_sz
)
{
desc
->
addr
=
cpu_to_le64
(
mapping
);
desc
->
status
|=
cpu_to_le32
(
OWNbit
+
RX_BUF_SIZE
);
desc
->
opts1
|=
cpu_to_le32
(
DescOwn
+
rx_buf_sz
);
}
static
int
rtl8169_alloc_rx_skb
(
struct
pci_dev
*
pdev
,
struct
net_device
*
dev
,
struct
sk_buff
**
sk_buff
,
struct
RxDesc
*
desc
)
static
int
rtl8169_alloc_rx_skb
(
struct
pci_dev
*
pdev
,
struct
sk_buff
**
sk_buff
,
struct
RxDesc
*
desc
,
int
rx_buf_sz
)
{
struct
sk_buff
*
skb
;
dma_addr_t
mapping
;
int
ret
=
0
;
skb
=
dev_alloc_skb
(
RX_BUF_SIZE
);
skb
=
dev_alloc_skb
(
rx_buf_sz
);
if
(
!
skb
)
goto
err_out
;
skb
->
dev
=
dev
;
skb_reserve
(
skb
,
2
);
*
sk_buff
=
skb
;
mapping
=
pci_map_single
(
pdev
,
skb
->
tail
,
RX_BUF_SIZE
,
mapping
=
pci_map_single
(
pdev
,
skb
->
tail
,
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
rtl8169_give_to_asic
(
desc
,
mapping
);
rtl8169_give_to_asic
(
desc
,
mapping
,
rx_buf_sz
);
out:
return
ret
;
...
...
@@ -1417,7 +1640,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp)
for
(
i
=
0
;
i
<
NUM_RX_DESC
;
i
++
)
{
if
(
tp
->
Rx_skbuff
[
i
])
{
rtl8169_free_rx_skb
(
tp
->
pci_dev
,
tp
->
Rx_skbuff
+
i
,
rtl8169_free_rx_skb
(
tp
,
tp
->
Rx_skbuff
+
i
,
tp
->
RxDescArray
+
i
);
}
}
...
...
@@ -1434,8 +1657,8 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
if
(
tp
->
Rx_skbuff
[
i
])
continue
;
ret
=
rtl8169_alloc_rx_skb
(
tp
->
pci_dev
,
dev
,
tp
->
Rx_skbuff
+
i
,
tp
->
RxDescArray
+
i
);
ret
=
rtl8169_alloc_rx_skb
(
tp
->
pci_dev
,
tp
->
Rx_skbuff
+
i
,
tp
->
RxDescArray
+
i
,
tp
->
rx_buf_sz
);
if
(
ret
<
0
)
break
;
}
...
...
@@ -1444,19 +1667,21 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
static
inline
void
rtl8169_mark_as_last_descriptor
(
struct
RxDesc
*
desc
)
{
desc
->
status
|=
cpu_to_le32
(
EORbit
);
desc
->
opts1
|=
cpu_to_le32
(
RingEnd
);
}
static
void
rtl8169_init_ring_indexes
(
struct
rtl8169_private
*
tp
)
{
tp
->
dirty_tx
=
tp
->
dirty_rx
=
tp
->
cur_tx
=
tp
->
cur_rx
=
0
;
}
static
int
rtl8169_init_ring
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
tp
->
cur_rx
=
tp
->
dirty_rx
=
0
;
tp
->
cur_tx
=
tp
->
dirty_tx
=
0
;
memset
(
tp
->
TxDescArray
,
0x0
,
NUM_TX_DESC
*
sizeof
(
struct
TxDesc
));
memset
(
tp
->
RxDescArray
,
0x0
,
NUM_RX_DESC
*
sizeof
(
struct
RxDesc
));
rtl8169_init_ring_indexes
(
tp
);
memset
(
tp
->
Tx_skbuff
,
0x0
,
NUM_TX_DESC
*
sizeof
(
struct
sk_buff
*
));
memset
(
tp
->
tx_skb
,
0x0
,
NUM_TX_DESC
*
sizeof
(
struct
ring_info
));
memset
(
tp
->
Rx_skbuff
,
0x0
,
NUM_RX_DESC
*
sizeof
(
struct
sk_buff
*
));
if
(
rtl8169_rx_fill
(
tp
,
dev
,
0
,
NUM_RX_DESC
)
!=
NUM_RX_DESC
)
...
...
@@ -1471,123 +1696,293 @@ static int rtl8169_init_ring(struct net_device *dev)
return
-
ENOMEM
;
}
static
void
rtl8169_unmap_tx_skb
(
struct
pci_dev
*
pdev
,
struct
sk_buff
**
sk_buff
,
static
void
rtl8169_unmap_tx_skb
(
struct
pci_dev
*
pdev
,
struct
ring_info
*
tx_skb
,
struct
TxDesc
*
desc
)
{
u
32
len
=
sk_buff
[
0
]
->
len
;
u
nsigned
int
len
=
tx_skb
->
len
;
pci_unmap_single
(
pdev
,
le64_to_cpu
(
desc
->
addr
),
len
<
ETH_ZLEN
?
ETH_ZLEN
:
len
,
PCI_DMA_TODEVICE
);
pci_unmap_single
(
pdev
,
le64_to_cpu
(
desc
->
addr
),
len
,
PCI_DMA_TODEVICE
);
desc
->
opts1
=
0x00
;
desc
->
opts2
=
0x00
;
desc
->
addr
=
0x00
;
*
sk_buff
=
NULL
;
tx_skb
->
len
=
0
;
}
static
void
rtl8169_tx_clear
(
struct
rtl8169_private
*
tp
)
static
void
rtl8169_tx_clear
(
struct
rtl8169_private
*
tp
)
{
int
i
;
unsigned
int
i
;
tp
->
cur_tx
=
0
;
for
(
i
=
0
;
i
<
NUM_TX_DESC
;
i
++
)
{
struct
sk_buff
*
skb
=
tp
->
Tx_skbuff
[
i
];
for
(
i
=
tp
->
dirty_tx
;
i
<
tp
->
dirty_tx
+
NUM_TX_DESC
;
i
++
)
{
unsigned
int
entry
=
i
%
NUM_TX_DESC
;
struct
ring_info
*
tx_skb
=
tp
->
tx_skb
+
entry
;
unsigned
int
len
=
tx_skb
->
len
;
if
(
skb
)
{
rtl8169_unmap_tx_skb
(
tp
->
pci_dev
,
tp
->
Tx_skbuff
+
i
,
tp
->
TxDescArray
+
i
);
dev_kfree_skb
(
skb
);
if
(
len
)
{
struct
sk_buff
*
skb
=
tx_skb
->
skb
;
rtl8169_unmap_tx_skb
(
tp
->
pci_dev
,
tx_skb
,
tp
->
TxDescArray
+
entry
);
if
(
skb
)
{
dev_kfree_skb
(
skb
);
tx_skb
->
skb
=
NULL
;
}
tp
->
stats
.
tx_dropped
++
;
}
}
tp
->
cur_tx
=
tp
->
dirty_tx
=
0
;
}
static
void
rtl8169_tx_timeout
(
struct
net_device
*
dev
)
static
void
rtl8169_schedule_work
(
struct
net_device
*
dev
,
void
(
*
task
)(
void
*
))
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
u8
tmp8
;
printk
(
KERN_INFO
"%s: TX Timeout
\n
"
,
dev
->
name
);
/* disable Tx, if not already */
tmp8
=
RTL_R8
(
ChipCmd
);
if
(
tmp8
&
CmdTxEnb
)
RTL_W8
(
ChipCmd
,
tmp8
&
~
CmdTxEnb
);
PREPARE_WORK
(
&
tp
->
task
,
task
,
dev
);
schedule_delayed_work
(
&
tp
->
task
,
4
);
}
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16
(
IntrMask
,
0x0000
);
static
void
rtl8169_wait_for_quiescence
(
struct
net_device
*
dev
)
{
synchronize_irq
(
dev
->
irq
);
/* Stop a shared interrupt from scavenging while we are. */
spin_lock_irq
(
&
tp
->
lock
);
rtl8169_tx_clear
(
tp
);
spin_unlock_irq
(
&
tp
->
lock
);
/* Wait for any pending NAPI task to complete */
netif_poll_disable
(
dev
);
}
/* ...and finally, reset everything */
rtl8169_hw_start
(
dev
);
static
void
rtl8169_reinit_task
(
void
*
_data
)
{
struct
net_device
*
dev
=
_data
;
int
ret
;
netif_wake_queue
(
dev
);
if
(
netif_running
(
dev
))
{
rtl8169_wait_for_quiescence
(
dev
);
rtl8169_close
(
dev
);
}
ret
=
rtl8169_open
(
dev
);
if
(
unlikely
(
ret
<
0
))
{
if
(
net_ratelimit
())
{
printk
(
PFX
KERN_ERR
"%s: reinit failure (status = %d)."
" Rescheduling.
\n
"
,
dev
->
name
,
ret
);
}
rtl8169_schedule_work
(
dev
,
rtl8169_reinit_task
);
}
}
static
int
rtl8169_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
static
void
rtl8169_reset_task
(
void
*
_data
)
{
struct
net_device
*
dev
=
_data
;
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
int
entry
=
tp
->
cur_tx
%
NUM_TX_DESC
;
u32
len
=
skb
->
len
;
if
(
unlikely
(
skb
->
len
<
ETH_ZLEN
))
{
skb
=
skb_padto
(
skb
,
ETH_ZLEN
);
if
(
!
skb
)
goto
err_update_stats
;
len
=
ETH_ZLEN
;
if
(
!
netif_running
(
dev
))
return
;
rtl8169_wait_for_quiescence
(
dev
);
rtl8169_rx_interrupt
(
dev
,
tp
,
tp
->
mmio_addr
);
rtl8169_tx_clear
(
tp
);
if
(
tp
->
dirty_rx
==
tp
->
cur_rx
)
{
rtl8169_init_ring_indexes
(
tp
);
rtl8169_hw_start
(
dev
);
netif_wake_queue
(
dev
);
}
else
{
if
(
net_ratelimit
())
{
printk
(
PFX
KERN_EMERG
"%s: Rx buffers shortage
\n
"
,
dev
->
name
);
}
rtl8169_schedule_work
(
dev
,
rtl8169_reset_task
);
}
if
(
!
(
le32_to_cpu
(
tp
->
TxDescArray
[
entry
].
status
)
&
OWNbit
))
{
}
static
void
rtl8169_tx_timeout
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
rtl8169_hw_reset
(
tp
->
mmio_addr
);
/* Let's wait a bit while any (async) irq lands on */
rtl8169_schedule_work
(
dev
,
rtl8169_reset_task
);
}
static
int
rtl8169_xmit_frags
(
struct
rtl8169_private
*
tp
,
struct
sk_buff
*
skb
,
u32
opts1
)
{
struct
skb_shared_info
*
info
=
skb_shinfo
(
skb
);
unsigned
int
cur_frag
,
entry
;
struct
TxDesc
*
txd
;
entry
=
tp
->
cur_tx
;
for
(
cur_frag
=
0
;
cur_frag
<
info
->
nr_frags
;
cur_frag
++
)
{
skb_frag_t
*
frag
=
info
->
frags
+
cur_frag
;
dma_addr_t
mapping
;
u32
status
;
u32
status
,
len
;
void
*
addr
;
mapping
=
pci_map_single
(
tp
->
pci_dev
,
skb
->
data
,
len
,
PCI_DMA_TODEVICE
);
entry
=
(
entry
+
1
)
%
NUM_TX_DESC
;
tp
->
Tx_skbuff
[
entry
]
=
skb
;
tp
->
TxDescArray
[
entry
].
addr
=
cpu_to_le64
(
mapping
);
txd
=
tp
->
TxDescArray
+
entry
;
len
=
frag
->
size
;
addr
=
((
void
*
)
page_address
(
frag
->
page
))
+
frag
->
page_offset
;
mapping
=
pci_map_single
(
tp
->
pci_dev
,
addr
,
len
,
PCI_DMA_TODEVICE
);
/* anti gcc 2.95.3 bugware */
status
=
OWNbit
|
FSbit
|
LSbit
|
len
|
(
EORbit
*
!
((
entry
+
1
)
%
NUM_TX_DESC
));
tp
->
TxDescArray
[
entry
].
status
=
cpu_to_le32
(
status
);
RTL_W8
(
TxPoll
,
0x40
);
//set polling bit
/* anti gcc 2.95.3 bugware (sic) */
status
=
opts1
|
len
|
(
RingEnd
*
!
((
entry
+
1
)
%
NUM_TX_DESC
));
dev
->
trans_start
=
jiffies
;
txd
->
opts1
=
cpu_to_le32
(
status
);
txd
->
addr
=
cpu_to_le64
(
mapping
);
tp
->
cur_tx
++
;
smp_wmb
();
}
else
goto
err_drop
;
tp
->
tx_skb
[
entry
].
len
=
len
;
}
if
(
cur_frag
)
{
tp
->
tx_skb
[
entry
].
skb
=
skb
;
txd
->
opts1
|=
cpu_to_le32
(
LastFrag
);
}
if
((
tp
->
cur_tx
-
NUM_TX_DESC
)
==
tp
->
dirty_tx
)
{
u32
dirty
=
tp
->
dirty_tx
;
return
cur_frag
;
}
static
inline
u32
rtl8169_tso_csum
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
if
(
dev
->
features
&
NETIF_F_TSO
)
{
u32
mss
=
skb_shinfo
(
skb
)
->
tso_size
;
if
(
mss
)
return
LargeSend
|
((
mss
&
MSSMask
)
<<
MSSShift
);
}
if
(
skb
->
ip_summed
==
CHECKSUM_HW
)
{
const
struct
iphdr
*
ip
=
skb
->
nh
.
iph
;
if
(
ip
->
protocol
==
IPPROTO_TCP
)
return
IPCS
|
TCPCS
;
else
if
(
ip
->
protocol
==
IPPROTO_UDP
)
return
IPCS
|
UDPCS
;
WARN_ON
(
1
);
/* we need a WARN() */
}
return
0
;
}
static
int
rtl8169_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
unsigned
int
frags
,
entry
=
tp
->
cur_tx
%
NUM_TX_DESC
;
struct
TxDesc
*
txd
=
tp
->
TxDescArray
+
entry
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
dma_addr_t
mapping
;
u32
status
,
len
;
u32
opts1
;
int
ret
=
0
;
if
(
unlikely
(
TX_BUFFS_AVAIL
(
tp
)
<
skb_shinfo
(
skb
)
->
nr_frags
))
{
printk
(
KERN_ERR
PFX
"%s: BUG! Tx Ring full when queue awake!
\n
"
,
dev
->
name
);
goto
err_stop
;
}
if
(
unlikely
(
le32_to_cpu
(
txd
->
opts1
)
&
DescOwn
))
goto
err_stop
;
opts1
=
DescOwn
|
rtl8169_tso_csum
(
skb
,
dev
);
frags
=
rtl8169_xmit_frags
(
tp
,
skb
,
opts1
);
if
(
frags
)
{
len
=
skb_headlen
(
skb
);
opts1
|=
FirstFrag
;
}
else
{
len
=
skb
->
len
;
if
(
unlikely
(
len
<
ETH_ZLEN
))
{
skb
=
skb_padto
(
skb
,
ETH_ZLEN
);
if
(
!
skb
)
goto
err_update_stats
;
len
=
ETH_ZLEN
;
}
opts1
|=
FirstFrag
|
LastFrag
;
tp
->
tx_skb
[
entry
].
skb
=
skb
;
}
mapping
=
pci_map_single
(
tp
->
pci_dev
,
skb
->
data
,
len
,
PCI_DMA_TODEVICE
);
tp
->
tx_skb
[
entry
].
len
=
len
;
txd
->
addr
=
cpu_to_le64
(
mapping
);
txd
->
opts2
=
cpu_to_le32
(
rtl8169_tx_vlan_tag
(
tp
,
skb
));
wmb
();
/* anti gcc 2.95.3 bugware (sic) */
status
=
opts1
|
len
|
(
RingEnd
*
!
((
entry
+
1
)
%
NUM_TX_DESC
));
txd
->
opts1
=
cpu_to_le32
(
status
);
dev
->
trans_start
=
jiffies
;
tp
->
cur_tx
+=
frags
+
1
;
smp_wmb
();
RTL_W8
(
TxPoll
,
0x40
);
//set polling bit
if
(
TX_BUFFS_AVAIL
(
tp
)
<
MAX_SKB_FRAGS
)
{
netif_stop_queue
(
dev
);
smp_rmb
();
if
(
dirty
!=
tp
->
dirty_tx
)
if
(
TX_BUFFS_AVAIL
(
tp
)
>=
MAX_SKB_FRAGS
)
netif_wake_queue
(
dev
);
}
out:
return
0
;
return
ret
;
err_drop:
dev_kfree_skb
(
skb
);
err_stop:
netif_stop_queue
(
dev
);
ret
=
1
;
err_update_stats:
tp
->
stats
.
tx_dropped
++
;
goto
out
;
}
static
void
rtl8169_pcierr_interrupt
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
u16
pci_status
,
pci_cmd
;
pci_read_config_word
(
pdev
,
PCI_COMMAND
,
&
pci_cmd
);
pci_read_config_word
(
pdev
,
PCI_STATUS
,
&
pci_status
);
printk
(
KERN_ERR
PFX
"%s: PCI error (cmd = 0x%04x, status = 0x%04x).
\n
"
,
dev
->
name
,
pci_cmd
,
pci_status
);
/*
* The recovery sequence below admits a very elaborated explanation:
* - it seems to work;
* - I did not see what else could be done.
*
* Feel free to adjust to your needs.
*/
pci_write_config_word
(
pdev
,
PCI_COMMAND
,
pci_cmd
|
PCI_COMMAND_SERR
|
PCI_COMMAND_PARITY
);
pci_write_config_word
(
pdev
,
PCI_STATUS
,
pci_status
&
(
PCI_STATUS_DETECTED_PARITY
|
PCI_STATUS_SIG_SYSTEM_ERROR
|
PCI_STATUS_REC_MASTER_ABORT
|
PCI_STATUS_REC_TARGET_ABORT
|
PCI_STATUS_SIG_TARGET_ABORT
));
/* The infamous DAC f*ckup only happens at boot time */
if
((
tp
->
cp_cmd
&
PCIDAC
)
&&
(
tp
->
dirty_rx
==
tp
->
cur_rx
==
0
))
{
printk
(
KERN_INFO
PFX
"%s: disabling PCI DAC.
\n
"
,
dev
->
name
);
tp
->
cp_cmd
&=
~
PCIDAC
;
RTL_W16
(
CPlusCmd
,
tp
->
cp_cmd
);
dev
->
features
&=
~
NETIF_F_HIGHDMA
;
rtl8169_schedule_work
(
dev
,
rtl8169_reinit_task
);
}
rtl8169_hw_reset
(
ioaddr
);
}
static
void
rtl8169_tx_interrupt
(
struct
net_device
*
dev
,
struct
rtl8169_private
*
tp
,
void
*
ioaddr
)
void
__iomem
*
ioaddr
)
{
unsigned
int
dirty_tx
,
tx_left
;
...
...
@@ -1601,22 +1996,24 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
while
(
tx_left
>
0
)
{
unsigned
int
entry
=
dirty_tx
%
NUM_TX_DESC
;
struct
sk_buff
*
skb
=
tp
->
Tx_skbuff
[
entry
];
struct
ring_info
*
tx_skb
=
tp
->
tx_skb
+
entry
;
u32
len
=
tx_skb
->
len
;
u32
status
;
rmb
();
status
=
le32_to_cpu
(
tp
->
TxDescArray
[
entry
].
status
);
if
(
status
&
OWNbit
)
status
=
le32_to_cpu
(
tp
->
TxDescArray
[
entry
].
opts1
);
if
(
status
&
DescOwn
)
break
;
/* FIXME: is it really accurate for TxErr ? */
tp
->
stats
.
tx_bytes
+=
skb
->
len
>=
ETH_ZLEN
?
skb
->
len
:
ETH_ZLEN
;
tp
->
stats
.
tx_bytes
+=
len
;
tp
->
stats
.
tx_packets
++
;
rtl8169_unmap_tx_skb
(
tp
->
pci_dev
,
tp
->
Tx_skbuff
+
entry
,
tp
->
TxDescArray
+
entry
);
dev_kfree_skb_irq
(
skb
);
tp
->
Tx_skbuff
[
entry
]
=
NULL
;
rtl8169_unmap_tx_skb
(
tp
->
pci_dev
,
tx_skb
,
tp
->
TxDescArray
+
entry
);
if
(
status
&
LastFrag
)
{
dev_kfree_skb_irq
(
tx_skb
->
skb
);
tx_skb
->
skb
=
NULL
;
}
dirty_tx
++
;
tx_left
--
;
}
...
...
@@ -1624,14 +2021,28 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
if
(
tp
->
dirty_tx
!=
dirty_tx
)
{
tp
->
dirty_tx
=
dirty_tx
;
smp_wmb
();
if
(
netif_queue_stopped
(
dev
))
if
(
netif_queue_stopped
(
dev
)
&&
(
TX_BUFFS_AVAIL
(
tp
)
>=
MAX_SKB_FRAGS
))
{
netif_wake_queue
(
dev
);
}
}
}
static
inline
void
rtl8169_rx_csum
(
struct
sk_buff
*
skb
,
struct
RxDesc
*
desc
)
{
u32
opts1
=
desc
->
opts1
;
u32
status
=
opts1
&
RxProtoMask
;
if
(((
status
==
RxProtoTCP
)
&&
!
(
opts1
&
TCPFail
))
||
((
status
==
RxProtoUDP
)
&&
!
(
opts1
&
UDPFail
))
||
((
status
==
RxProtoIP
)
&&
!
(
opts1
&
IPFail
)))
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
else
skb
->
ip_summed
=
CHECKSUM_NONE
;
}
static
inline
int
rtl8169_try_rx_copy
(
struct
sk_buff
**
sk_buff
,
int
pkt_size
,
struct
RxDesc
*
desc
,
struct
net_device
*
dev
)
struct
RxDesc
*
desc
,
int
rx_buf_sz
)
{
int
ret
=
-
1
;
...
...
@@ -1640,11 +2051,10 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
skb
=
dev_alloc_skb
(
pkt_size
+
2
);
if
(
skb
)
{
skb
->
dev
=
dev
;
skb_reserve
(
skb
,
2
);
eth_copy_and_sum
(
skb
,
sk_buff
[
0
]
->
tail
,
pkt_size
,
0
);
*
sk_buff
=
skb
;
rtl8169_return_to_asic
(
desc
);
rtl8169_return_to_asic
(
desc
,
rx_buf_sz
);
ret
=
0
;
}
}
...
...
@@ -1653,7 +2063,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
static
int
rtl8169_rx_interrupt
(
struct
net_device
*
dev
,
struct
rtl8169_private
*
tp
,
void
*
ioaddr
)
void
__iomem
*
ioaddr
)
{
unsigned
int
cur_rx
,
rx_left
,
count
;
int
delta
;
...
...
@@ -1671,9 +2081,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
u32
status
;
rmb
();
status
=
le32_to_cpu
(
tp
->
RxDescArray
[
entry
].
status
);
status
=
le32_to_cpu
(
tp
->
RxDescArray
[
entry
].
opts1
);
if
(
status
&
OWNbit
)
if
(
status
&
DescOwn
)
break
;
if
(
status
&
RxRES
)
{
printk
(
KERN_INFO
"%s: Rx ERROR!!!
\n
"
,
dev
->
name
);
...
...
@@ -1689,22 +2099,27 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
void
(
*
pci_action
)(
struct
pci_dev
*
,
dma_addr_t
,
size_t
,
int
)
=
pci_dma_sync_single_for_device
;
rtl8169_rx_csum
(
skb
,
desc
);
pci_dma_sync_single_for_cpu
(
tp
->
pci_dev
,
le64_to_cpu
(
desc
->
addr
),
RX_BUF_SIZE
,
le64_to_cpu
(
desc
->
addr
),
tp
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
if
(
rtl8169_try_rx_copy
(
&
skb
,
pkt_size
,
desc
,
dev
))
{
if
(
rtl8169_try_rx_copy
(
&
skb
,
pkt_size
,
desc
,
tp
->
rx_buf_sz
))
{
pci_action
=
pci_unmap_single
;
tp
->
Rx_skbuff
[
entry
]
=
NULL
;
}
pci_action
(
tp
->
pci_dev
,
le64_to_cpu
(
desc
->
addr
),
RX_BUF_SIZE
,
PCI_DMA_FROMDEVICE
);
tp
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
skb
->
dev
=
dev
;
skb_put
(
skb
,
pkt_size
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
rtl8169_rx_skb
(
skb
);
if
(
rtl8169_rx_vlan_skb
(
tp
,
desc
,
skb
)
<
0
)
rtl8169_rx_skb
(
skb
);
dev
->
last_rx
=
jiffies
;
tp
->
stats
.
rx_bytes
+=
pkt_size
;
...
...
@@ -1745,10 +2160,13 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_instance
;
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
int
boguscnt
=
max_interrupt_work
;
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
int
status
=
0
;
int
handled
=
0
;
if
(
unlikely
(
!
netif_running
(
dev
)))
goto
out
;
do
{
status
=
RTL_R16
(
IntrStatus
);
...
...
@@ -1766,11 +2184,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
break
;
if
(
unlikely
(
status
&
SYSErr
))
{
printk
(
KERN_ERR
PFX
"%s: PCI error (status: 0x%04x)."
" Device disabled.
\n
"
,
dev
->
name
,
status
);
RTL_W8
(
ChipCmd
,
0x00
);
RTL_W16
(
IntrMask
,
0x0000
);
RTL_R16
(
IntrMask
);
rtl8169_pcierr_interrupt
(
dev
);
break
;
}
...
...
@@ -1784,7 +2198,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
if
(
likely
(
netif_rx_schedule_prep
(
dev
)))
__netif_rx_schedule
(
dev
);
else
{
printk
(
KERN_INFO
"%s: interrupt %x taken in poll
\n
"
,
printk
(
KERN_INFO
"%s: interrupt %
04
x taken in poll
\n
"
,
dev
->
name
,
status
);
}
break
;
...
...
@@ -1807,6 +2221,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
/* Clear all interrupt sources. */
RTL_W16
(
IntrStatus
,
0xffff
);
}
out:
return
IRQ_RETVAL
(
handled
);
}
...
...
@@ -1815,7 +2230,7 @@ static int rtl8169_poll(struct net_device *dev, int *budget)
{
unsigned
int
work_done
,
work_to_do
=
min
(
*
budget
,
dev
->
quota
);
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
work_done
=
rtl8169_rx_interrupt
(
dev
,
tp
,
ioaddr
);
rtl8169_tx_interrupt
(
dev
,
tp
,
ioaddr
);
...
...
@@ -1845,10 +2260,12 @@ rtl8169_close(struct net_device *dev)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
struct
pci_dev
*
pdev
=
tp
->
pci_dev
;
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
netif_stop_queue
(
dev
);
flush_scheduled_work
();
rtl8169_delete_timer
(
dev
);
spin_lock_irq
(
&
tp
->
lock
);
...
...
@@ -1865,9 +2282,10 @@ rtl8169_close(struct net_device *dev)
spin_unlock_irq
(
&
tp
->
lock
);
synchronize_irq
(
dev
->
irq
);
free_irq
(
dev
->
irq
,
dev
);
netif_poll_disable
(
dev
);
rtl8169_tx_clear
(
tp
);
rtl8169_rx_clear
(
tp
);
...
...
@@ -1886,7 +2304,7 @@ static void
rtl8169_set_rx_mode
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
long
flags
;
u32
mc_filter
[
2
];
/* Multicast hash filter */
int
i
,
rx_mode
;
...
...
@@ -1938,7 +2356,7 @@ rtl8169_set_rx_mode(struct net_device *dev)
static
struct
net_device_stats
*
rtl8169_get_stats
(
struct
net_device
*
dev
)
{
struct
rtl8169_private
*
tp
=
netdev_priv
(
dev
);
void
*
ioaddr
=
tp
->
mmio_addr
;
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
unsigned
long
flags
;
if
(
netif_running
(
dev
))
{
...
...
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