Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6720b96a
Commit
6720b96a
authored
Jul 02, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge pobox.com:/spare/repo/linux-2.6
into pobox.com:/spare/repo/netdev-2.6/velocity
parents
db376e4c
c55d03f9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
281 additions
and
291 deletions
+281
-291
drivers/net/Kconfig
drivers/net/Kconfig
+1
-0
drivers/net/via-velocity.c
drivers/net/via-velocity.c
+277
-289
drivers/net/via-velocity.h
drivers/net/via-velocity.h
+2
-2
include/linux/pci_ids.h
include/linux/pci_ids.h
+1
-0
No files found.
drivers/net/Kconfig
View file @
6720b96a
...
...
@@ -1746,6 +1746,7 @@ config VIA_VELOCITY
tristate "VIA Velocity support"
depends on NET_PCI && PCI
select CRC32
select CRC16
select MII
help
If you have a VIA "Velocity" based network card say Y here.
...
...
drivers/net/via-velocity.c
View file @
6720b96a
...
...
@@ -78,6 +78,8 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/crc16.h>
#include <linux/crc32.h>
#include "via-velocity.h"
...
...
@@ -226,7 +228,10 @@ VELOCITY_PARAM(wol_opts, "Wake On Lan options");
VELOCITY_PARAM
(
int_works
,
"Number of packets per interrupt services"
);
static
int
velocity_found1
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
int
rx_copybreak
=
200
;
MODULE_PARM
(
rx_copybreak
,
"i"
);
MODULE_PARM_DESC
(
rx_copybreak
,
"Copy breakpoint for copy-only-tiny-frames"
);
static
void
velocity_init_info
(
struct
pci_dev
*
pdev
,
struct
velocity_info
*
vptr
,
struct
velocity_info_tbl
*
info
);
static
int
velocity_get_pci_info
(
struct
velocity_info
*
,
struct
pci_dev
*
pdev
);
static
void
velocity_print_info
(
struct
velocity_info
*
vptr
);
...
...
@@ -238,10 +243,8 @@ static void velocity_set_multi(struct net_device *dev);
static
struct
net_device_stats
*
velocity_get_stats
(
struct
net_device
*
dev
);
static
int
velocity_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
);
static
int
velocity_close
(
struct
net_device
*
dev
);
static
int
velocity_rx_srv
(
struct
velocity_info
*
vptr
,
int
status
);
static
int
velocity_receive_frame
(
struct
velocity_info
*
,
int
idx
);
static
int
velocity_alloc_rx_buf
(
struct
velocity_info
*
,
int
idx
);
static
void
velocity_init_registers
(
struct
velocity_info
*
vptr
,
enum
velocity_init_type
type
);
static
void
velocity_free_rd_ring
(
struct
velocity_info
*
vptr
);
static
void
velocity_free_tx_buf
(
struct
velocity_info
*
vptr
,
struct
velocity_td_info
*
);
static
int
velocity_soft_reset
(
struct
velocity_info
*
vptr
);
...
...
@@ -254,12 +257,8 @@ static void enable_flow_control_ability(struct velocity_info *vptr);
static
void
enable_mii_autopoll
(
struct
mac_regs
*
regs
);
static
int
velocity_mii_read
(
struct
mac_regs
*
,
u8
byIdx
,
u16
*
pdata
);
static
int
velocity_mii_write
(
struct
mac_regs
*
,
u8
byMiiAddr
,
u16
data
);
static
int
velocity_set_wol
(
struct
velocity_info
*
vptr
);
static
void
velocity_save_context
(
struct
velocity_info
*
vptr
,
struct
velocity_context
*
context
);
static
void
velocity_restore_context
(
struct
velocity_info
*
vptr
,
struct
velocity_context
*
context
);
static
u32
mii_check_media_mode
(
struct
mac_regs
*
regs
);
static
u32
check_connection_type
(
struct
mac_regs
*
regs
);
static
void
velocity_init_cam_filter
(
struct
velocity_info
*
vptr
);
static
int
velocity_set_media_mode
(
struct
velocity_info
*
vptr
,
u32
mii_status
);
#ifdef CONFIG_PM
...
...
@@ -269,8 +268,9 @@ static int velocity_resume(struct pci_dev *pdev);
static
int
velocity_netdev_event
(
struct
notifier_block
*
nb
,
unsigned
long
notification
,
void
*
ptr
);
static
struct
notifier_block
velocity_inetaddr_notifier
=
{
notifier_call:
velocity_netdev_event
,
.
notifier_call
=
velocity_netdev_event
,
};
static
int
velocity_notifier_registered
;
#endif
/* CONFIG_PM */
...
...
@@ -289,8 +289,9 @@ static struct velocity_info_tbl chip_info_table[] = {
*/
static
struct
pci_device_id
velocity_id_table
[]
__devinitdata
=
{
{
0x1106
,
0x3119
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
(
unsigned
long
)
&
chip_info_table
[
0
]},
{
0
,}
{
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_612X
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
(
unsigned
long
)
chip_info_table
},
{
0
,
}
};
MODULE_DEVICE_TABLE
(
pci
,
velocity_id_table
);
...
...
@@ -463,6 +464,12 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
}
}
static
inline
void
velocity_give_rx_desc
(
struct
rx_desc
*
rd
)
{
*
(
u32
*
)
&
rd
->
rdesc0
=
0
;
rd
->
rdesc0
.
owner
=
cpu_to_le32
(
OWNED_BY_NIC
);
}
/**
* velocity_rx_reset - handle a receive reset
* @vptr: velocity we are resetting
...
...
@@ -477,13 +484,13 @@ static void velocity_rx_reset(struct velocity_info *vptr)
struct
mac_regs
*
regs
=
vptr
->
mac_regs
;
int
i
;
vptr
->
rd_
us
ed
=
vptr
->
rd_curr
=
0
;
vptr
->
rd_
dirty
=
vptr
->
rd_fill
ed
=
vptr
->
rd_curr
=
0
;
/*
* Init state, all RD entries belong to the NIC
*/
for
(
i
=
0
;
i
<
vptr
->
options
.
numrx
;
++
i
)
v
ptr
->
rd_ring
[
i
].
rdesc0
.
owner
=
cpu_to_le32
(
OWNED_BY_NIC
);
v
elocity_give_rx_desc
(
vptr
->
rd_ring
+
i
);
writew
(
vptr
->
options
.
numrx
,
&
regs
->
RBRDU
);
writel
(
vptr
->
rd_pool_dma
,
&
regs
->
RDBaseLo
);
...
...
@@ -776,6 +783,12 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
pci_set_power_state
(
pdev
,
3
);
out:
#ifdef CONFIG_PM
if
(
ret
==
0
&&
!
velocity_notifier_registered
)
{
velocity_notifier_registered
=
1
;
register_inetaddr_notifier
(
&
velocity_inetaddr_notifier
);
}
#endif
return
ret
;
err_iounmap:
...
...
@@ -966,6 +979,60 @@ static void velocity_free_rings(struct velocity_info *vptr)
pci_free_consistent
(
vptr
->
pdev
,
size
,
vptr
->
tx_bufs
,
vptr
->
tx_bufs_dma
);
}
static
inline
void
velocity_give_many_rx_descs
(
struct
velocity_info
*
vptr
)
{
struct
mac_regs
*
regs
=
vptr
->
mac_regs
;
int
avail
,
dirty
,
unusable
;
/*
* RD number must be equal to 4X per hardware spec
* (programming guide rev 1.20, p.13)
*/
if
(
vptr
->
rd_filled
<
4
)
return
;
wmb
();
unusable
=
vptr
->
rd_filled
|
0x0003
;
dirty
=
vptr
->
rd_dirty
-
unusable
+
1
;
for
(
avail
=
vptr
->
rd_filled
&
0xfffc
;
avail
;
avail
--
)
{
dirty
=
(
dirty
>
0
)
?
dirty
-
1
:
vptr
->
options
.
numrx
-
1
;
velocity_give_rx_desc
(
vptr
->
rd_ring
+
dirty
);
}
writew
(
vptr
->
rd_filled
&
0xfffc
,
&
regs
->
RBRDU
);
vptr
->
rd_filled
=
unusable
;
}
static
int
velocity_rx_refill
(
struct
velocity_info
*
vptr
)
{
int
dirty
=
vptr
->
rd_dirty
,
done
=
0
,
ret
=
0
;
do
{
struct
rx_desc
*
rd
=
vptr
->
rd_ring
+
dirty
;
/* Fine for an all zero Rx desc at init time as well */
if
(
rd
->
rdesc0
.
owner
==
cpu_to_le32
(
OWNED_BY_NIC
))
break
;
if
(
!
vptr
->
rd_info
[
dirty
].
skb
)
{
ret
=
velocity_alloc_rx_buf
(
vptr
,
dirty
);
if
(
ret
<
0
)
break
;
}
done
++
;
dirty
=
(
dirty
<
vptr
->
options
.
numrx
-
1
)
?
dirty
+
1
:
0
;
}
while
(
dirty
!=
vptr
->
rd_curr
);
if
(
done
)
{
vptr
->
rd_dirty
=
dirty
;
vptr
->
rd_filled
+=
done
;
velocity_give_many_rx_descs
(
vptr
);
}
return
ret
;
}
/**
* velocity_init_rd_ring - set up receive ring
* @vptr: velocity to configure
...
...
@@ -976,9 +1043,7 @@ static void velocity_free_rings(struct velocity_info *vptr)
static
int
velocity_init_rd_ring
(
struct
velocity_info
*
vptr
)
{
int
i
,
ret
=
-
ENOMEM
;
struct
rx_desc
*
rd
;
struct
velocity_rd_info
*
rd_info
;
int
ret
=
-
ENOMEM
;
unsigned
int
rsize
=
sizeof
(
struct
velocity_rd_info
)
*
vptr
->
options
.
numrx
;
...
...
@@ -987,22 +1052,14 @@ static int velocity_init_rd_ring(struct velocity_info *vptr)
goto
out
;
memset
(
vptr
->
rd_info
,
0
,
rsize
);
/* Init the RD ring entries */
for
(
i
=
0
;
i
<
vptr
->
options
.
numrx
;
i
++
)
{
rd
=
&
(
vptr
->
rd_ring
[
i
]);
rd_info
=
&
(
vptr
->
rd_info
[
i
]);
vptr
->
rd_filled
=
vptr
->
rd_dirty
=
vptr
->
rd_curr
=
0
;
ret
=
velocity_alloc_rx_buf
(
vptr
,
i
);
if
(
ret
<
0
)
{
VELOCITY_PRT
(
MSG_LEVEL_ERR
,
KERN_ERR
"%s: failed to allocate RX buffer.
\n
"
,
vptr
->
dev
->
name
);
velocity_free_rd_ring
(
vptr
);
goto
out
;
}
rd
->
rdesc0
.
owner
=
OWNED_BY_NIC
;
ret
=
velocity_rx_refill
(
vptr
);
if
(
ret
<
0
)
{
VELOCITY_PRT
(
MSG_LEVEL_ERR
,
KERN_ERR
"%s: failed to allocate RX buffer.
\n
"
,
vptr
->
dev
->
name
);
velocity_free_rd_ring
(
vptr
);
}
vptr
->
rd_used
=
vptr
->
rd_curr
=
0
;
out:
return
ret
;
}
...
...
@@ -1025,7 +1082,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
for
(
i
=
0
;
i
<
vptr
->
options
.
numrx
;
i
++
)
{
struct
velocity_rd_info
*
rd_info
=
&
(
vptr
->
rd_info
[
i
]);
if
(
!
rd_info
->
skb
_dma
)
if
(
!
rd_info
->
skb
)
continue
;
pci_unmap_single
(
vptr
->
pdev
,
rd_info
->
skb_dma
,
vptr
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
...
...
@@ -1146,22 +1203,14 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
static
int
velocity_rx_srv
(
struct
velocity_info
*
vptr
,
int
status
)
{
struct
rx_desc
*
rd
;
struct
net_device_stats
*
stats
=
&
vptr
->
stats
;
struct
mac_regs
*
regs
=
vptr
->
mac_regs
;
int
rd_curr
=
vptr
->
rd_curr
;
int
works
=
0
;
while
(
1
)
{
struct
rx_desc
*
rd
=
vptr
->
rd_ring
+
rd_curr
;
rd
=
&
(
vptr
->
rd_ring
[
rd_curr
]);
if
((
vptr
->
rd_info
[
rd_curr
]).
skb
==
NULL
)
{
if
(
velocity_alloc_rx_buf
(
vptr
,
rd_curr
)
<
0
)
break
;
}
if
(
works
++
>
15
)
if
(
!
vptr
->
rd_info
[
rd_curr
].
skb
||
(
works
++
>
15
))
break
;
if
(
rd
->
rdesc0
.
owner
==
OWNED_BY_NIC
)
...
...
@@ -1169,17 +1218,10 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
/*
* Don't drop CE or RL error frame although RXOK is off
* FIXME: need to handle copybreak
*/
if
((
rd
->
rdesc0
.
RSR
&
RSR_RXOK
)
||
(
!
(
rd
->
rdesc0
.
RSR
&
RSR_RXOK
)
&&
(
rd
->
rdesc0
.
RSR
&
(
RSR_CE
|
RSR_RL
))))
{
if
(
velocity_receive_frame
(
vptr
,
rd_curr
)
==
0
)
{
if
(
velocity_alloc_rx_buf
(
vptr
,
rd_curr
)
<
0
)
{
VELOCITY_PRT
(
MSG_LEVEL_ERR
,
KERN_ERR
"%s: can not allocate rx buf
\n
"
,
vptr
->
dev
->
name
);
break
;
}
}
else
{
if
(
velocity_receive_frame
(
vptr
,
rd_curr
)
<
0
)
stats
->
rx_dropped
++
;
}
}
else
{
if
(
rd
->
rdesc0
.
RSR
&
RSR_CRC
)
stats
->
rx_crc_errors
++
;
...
...
@@ -1191,25 +1233,18 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
rd
->
inten
=
1
;
if
(
++
vptr
->
rd_used
>=
4
)
{
int
i
,
rd_prev
=
rd_curr
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
--
rd_prev
<
0
)
rd_prev
=
vptr
->
options
.
numrx
-
1
;
rd
=
&
(
vptr
->
rd_ring
[
rd_prev
]);
rd
->
rdesc0
.
owner
=
OWNED_BY_NIC
;
}
writew
(
4
,
&
(
regs
->
RBRDU
));
vptr
->
rd_used
-=
4
;
}
vptr
->
dev
->
last_rx
=
jiffies
;
rd_curr
++
;
if
(
rd_curr
>=
vptr
->
options
.
numrx
)
rd_curr
=
0
;
}
if
(
velocity_rx_refill
(
vptr
)
<
0
)
{
VELOCITY_PRT
(
MSG_LEVEL_ERR
,
KERN_ERR
"%s: rx buf allocation failure
\n
"
,
vptr
->
dev
->
name
);
}
vptr
->
rd_curr
=
rd_curr
;
VAR_USED
(
stats
);
return
works
;
...
...
@@ -1241,6 +1276,65 @@ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
}
}
/**
* velocity_rx_copy - in place Rx copy for small packets
* @rx_skb: network layer packet buffer candidate
* @pkt_size: received data size
* @rd: receive packet descriptor
* @dev: network device
*
* Replace the current skb that is scheduled for Rx processing by a
* shorter, immediatly allocated skb, if the received packet is small
* enough. This function returns a negative value if the received
* packet is too big or if memory is exhausted.
*/
static
inline
int
velocity_rx_copy
(
struct
sk_buff
**
rx_skb
,
int
pkt_size
,
struct
velocity_info
*
vptr
)
{
int
ret
=
-
1
;
if
(
pkt_size
<
rx_copybreak
)
{
struct
sk_buff
*
new_skb
;
new_skb
=
dev_alloc_skb
(
pkt_size
+
2
);
if
(
new_skb
)
{
new_skb
->
dev
=
vptr
->
dev
;
new_skb
->
ip_summed
=
rx_skb
[
0
]
->
ip_summed
;
if
(
vptr
->
flags
&
VELOCITY_FLAGS_IP_ALIGN
)
skb_reserve
(
new_skb
,
2
);
memcpy
(
new_skb
->
data
,
rx_skb
[
0
]
->
tail
,
pkt_size
);
*
rx_skb
=
new_skb
;
ret
=
0
;
}
}
return
ret
;
}
/**
* velocity_iph_realign - IP header alignment
* @vptr: velocity we are handling
* @skb: network layer packet buffer
* @pkt_size: received data size
*
* Align IP header on a 2 bytes boundary. This behavior can be
* configured by the user.
*/
static
inline
void
velocity_iph_realign
(
struct
velocity_info
*
vptr
,
struct
sk_buff
*
skb
,
int
pkt_size
)
{
/* FIXME - memmove ? */
if
(
vptr
->
flags
&
VELOCITY_FLAGS_IP_ALIGN
)
{
int
i
;
for
(
i
=
pkt_size
;
i
>=
0
;
i
--
)
*
(
skb
->
data
+
i
+
2
)
=
*
(
skb
->
data
+
i
);
skb_reserve
(
skb
,
2
);
}
}
/**
* velocity_receive_frame - received packet processor
* @vptr: velocity we are handling
...
...
@@ -1252,9 +1346,11 @@ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
static
int
velocity_receive_frame
(
struct
velocity_info
*
vptr
,
int
idx
)
{
void
(
*
pci_action
)(
struct
pci_dev
*
,
dma_addr_t
,
size_t
,
int
);
struct
net_device_stats
*
stats
=
&
vptr
->
stats
;
struct
velocity_rd_info
*
rd_info
=
&
(
vptr
->
rd_info
[
idx
]);
struct
rx_desc
*
rd
=
&
(
vptr
->
rd_ring
[
idx
]);
int
pkt_len
=
rd
->
rdesc0
.
len
;
struct
sk_buff
*
skb
;
if
(
rd
->
rdesc0
.
RSR
&
(
RSR_STP
|
RSR_EDP
))
{
...
...
@@ -1269,22 +1365,8 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
skb
=
rd_info
->
skb
;
skb
->
dev
=
vptr
->
dev
;
pci_unmap_single
(
vptr
->
pdev
,
rd_info
->
skb_dma
,
vptr
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
rd_info
->
skb_dma
=
(
dma_addr_t
)
NULL
;
rd_info
->
skb
=
NULL
;
/* FIXME - memmove ? */
if
(
vptr
->
flags
&
VELOCITY_FLAGS_IP_ALIGN
)
{
int
i
;
for
(
i
=
rd
->
rdesc0
.
len
+
4
;
i
>=
0
;
i
--
)
*
(
skb
->
data
+
i
+
2
)
=
*
(
skb
->
data
+
i
);
skb
->
data
+=
2
;
skb
->
tail
+=
2
;
}
skb_put
(
skb
,
(
rd
->
rdesc0
.
len
-
4
));
skb
->
protocol
=
eth_type_trans
(
skb
,
skb
->
dev
);
pci_dma_sync_single_for_cpu
(
vptr
->
pdev
,
rd_info
->
skb_dma
,
vptr
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
/*
* Drop frame not meeting IEEE 802.3
...
...
@@ -1297,13 +1379,23 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
}
}
pci_action
=
pci_dma_sync_single_for_device
;
velocity_rx_csum
(
rd
,
skb
);
/*
* FIXME: need rx_copybreak handling
*/
stats
->
rx_bytes
+=
skb
->
len
;
if
(
velocity_rx_copy
(
&
skb
,
pkt_len
,
vptr
)
<
0
)
{
velocity_iph_realign
(
vptr
,
skb
,
pkt_len
);
pci_action
=
pci_unmap_single
;
rd_info
->
skb
=
NULL
;
}
pci_action
(
vptr
->
pdev
,
rd_info
->
skb_dma
,
vptr
->
rx_buf_sz
,
PCI_DMA_FROMDEVICE
);
skb_put
(
skb
,
pkt_len
-
4
);
skb
->
protocol
=
eth_type_trans
(
skb
,
skb
->
dev
);
stats
->
rx_bytes
+=
pkt_len
;
netif_rx
(
skb
);
return
0
;
...
...
@@ -1962,32 +2054,6 @@ static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs)
}
/**
* ether_crc - ethernet CRC function
*
* Compute an ethernet CRC hash of the data block provided. This
* is not performance optimised but is not needed in performance
* critical code paths.
*
* FIXME: could we use shared code here ?
*/
static
inline
u32
ether_crc
(
int
length
,
unsigned
char
*
data
)
{
static
unsigned
const
ethernet_polynomial
=
0x04c11db7U
;
int
crc
=
-
1
;
while
(
--
length
>=
0
)
{
unsigned
char
current_octet
=
*
data
++
;
int
bit
;
for
(
bit
=
0
;
bit
<
8
;
bit
++
,
current_octet
>>=
1
)
{
crc
=
(
crc
<<
1
)
^
((
crc
<
0
)
^
(
current_octet
&
1
)
?
ethernet_polynomial
:
0
);
}
}
return
crc
;
}
/**
* velocity_set_multi - filter list change callback
* @dev: network device
...
...
@@ -2123,13 +2189,13 @@ static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
*/
static
struct
pci_driver
velocity_driver
=
{
name:
VELOCITY_NAME
,
id_table:
velocity_id_table
,
probe:
velocity_found1
,
remove:
velocity_remove1
,
.
name
=
VELOCITY_NAME
,
.
id_table
=
velocity_id_table
,
.
probe
=
velocity_found1
,
.
remove
=
__devexit_p
(
velocity_remove1
)
,
#ifdef CONFIG_PM
suspend:
velocity_suspend
,
resume:
velocity_resume
,
.
suspend
=
velocity_suspend
,
.
resume
=
velocity_resume
,
#endif
};
...
...
@@ -2147,9 +2213,6 @@ static int __init velocity_init_module(void)
int
ret
;
ret
=
pci_module_init
(
&
velocity_driver
);
#ifdef CONFIG_PM
register_inetaddr_notifier
(
&
velocity_inetaddr_notifier
);
#endif
return
ret
;
}
...
...
@@ -2165,7 +2228,10 @@ static int __init velocity_init_module(void)
static
void
__exit
velocity_cleanup_module
(
void
)
{
#ifdef CONFIG_PM
unregister_inetaddr_notifier
(
&
velocity_inetaddr_notifier
);
if
(
velocity_notifier_registered
)
{
unregister_inetaddr_notifier
(
&
velocity_inetaddr_notifier
);
velocity_notifier_registered
=
0
;
}
#endif
pci_unregister_driver
(
&
velocity_driver
);
}
...
...
@@ -2992,172 +3058,6 @@ static void velocity_restore_context(struct velocity_info *vptr, struct velocity
}
static
int
velocity_suspend
(
struct
pci_dev
*
pdev
,
u32
state
)
{
struct
velocity_info
*
vptr
=
pci_get_drvdata
(
pdev
);
unsigned
long
flags
;
if
(
!
netif_running
(
vptr
->
dev
))
return
0
;
netif_device_detach
(
vptr
->
dev
);
spin_lock_irqsave
(
&
vptr
->
lock
,
flags
);
pci_save_state
(
pdev
,
vptr
->
pci_state
);
#ifdef ETHTOOL_GWOL
if
(
vptr
->
flags
&
VELOCITY_FLAGS_WOL_ENABLED
)
{
velocity_get_ip
(
vptr
);
velocity_save_context
(
vptr
,
&
vptr
->
context
);
velocity_shutdown
(
vptr
);
velocity_set_wol
(
vptr
);
pci_enable_wake
(
pdev
,
3
,
1
);
pci_set_power_state
(
pdev
,
3
);
}
else
{
velocity_save_context
(
vptr
,
&
vptr
->
context
);
velocity_shutdown
(
vptr
);
pci_disable_device
(
pdev
);
pci_set_power_state
(
pdev
,
state
);
}
#else
pci_set_power_state
(
pdev
,
state
);
#endif
spin_unlock_irqrestore
(
&
vptr
->
lock
,
flags
);
return
0
;
}
static
int
velocity_resume
(
struct
pci_dev
*
pdev
)
{
struct
velocity_info
*
vptr
=
pci_get_drvdata
(
pdev
);
unsigned
long
flags
;
int
i
;
if
(
!
netif_running
(
vptr
->
dev
))
return
0
;
pci_set_power_state
(
pdev
,
0
);
pci_enable_wake
(
pdev
,
0
,
0
);
pci_restore_state
(
pdev
,
vptr
->
pci_state
);
mac_wol_reset
(
vptr
->
mac_regs
);
spin_lock_irqsave
(
&
vptr
->
lock
,
flags
);
velocity_restore_context
(
vptr
,
&
vptr
->
context
);
velocity_init_registers
(
vptr
,
VELOCITY_INIT_WOL
);
mac_disable_int
(
vptr
->
mac_regs
);
velocity_tx_srv
(
vptr
,
0
);
for
(
i
=
0
;
i
<
vptr
->
num_txq
;
i
++
)
{
if
(
vptr
->
td_used
[
i
])
{
mac_tx_queue_wake
(
vptr
->
mac_regs
,
i
);
}
}
mac_enable_int
(
vptr
->
mac_regs
);
spin_unlock_irqrestore
(
&
vptr
->
lock
,
flags
);
netif_device_attach
(
vptr
->
dev
);
return
0
;
}
static
int
velocity_netdev_event
(
struct
notifier_block
*
nb
,
unsigned
long
notification
,
void
*
ptr
)
{
struct
in_ifaddr
*
ifa
=
(
struct
in_ifaddr
*
)
ptr
;
struct
net_device
*
dev
;
struct
velocity_info
*
vptr
;
if
(
ifa
)
{
dev
=
ifa
->
ifa_dev
->
dev
;
vptr
=
dev
->
priv
;
velocity_get_ip
(
vptr
);
}
return
NOTIFY_DONE
;
}
#endif
/*
* Purpose: Functions to set WOL.
*/
const
static
unsigned
short
crc16_tab
[
256
]
=
{
0x0000
,
0x1189
,
0x2312
,
0x329b
,
0x4624
,
0x57ad
,
0x6536
,
0x74bf
,
0x8c48
,
0x9dc1
,
0xaf5a
,
0xbed3
,
0xca6c
,
0xdbe5
,
0xe97e
,
0xf8f7
,
0x1081
,
0x0108
,
0x3393
,
0x221a
,
0x56a5
,
0x472c
,
0x75b7
,
0x643e
,
0x9cc9
,
0x8d40
,
0xbfdb
,
0xae52
,
0xdaed
,
0xcb64
,
0xf9ff
,
0xe876
,
0x2102
,
0x308b
,
0x0210
,
0x1399
,
0x6726
,
0x76af
,
0x4434
,
0x55bd
,
0xad4a
,
0xbcc3
,
0x8e58
,
0x9fd1
,
0xeb6e
,
0xfae7
,
0xc87c
,
0xd9f5
,
0x3183
,
0x200a
,
0x1291
,
0x0318
,
0x77a7
,
0x662e
,
0x54b5
,
0x453c
,
0xbdcb
,
0xac42
,
0x9ed9
,
0x8f50
,
0xfbef
,
0xea66
,
0xd8fd
,
0xc974
,
0x4204
,
0x538d
,
0x6116
,
0x709f
,
0x0420
,
0x15a9
,
0x2732
,
0x36bb
,
0xce4c
,
0xdfc5
,
0xed5e
,
0xfcd7
,
0x8868
,
0x99e1
,
0xab7a
,
0xbaf3
,
0x5285
,
0x430c
,
0x7197
,
0x601e
,
0x14a1
,
0x0528
,
0x37b3
,
0x263a
,
0xdecd
,
0xcf44
,
0xfddf
,
0xec56
,
0x98e9
,
0x8960
,
0xbbfb
,
0xaa72
,
0x6306
,
0x728f
,
0x4014
,
0x519d
,
0x2522
,
0x34ab
,
0x0630
,
0x17b9
,
0xef4e
,
0xfec7
,
0xcc5c
,
0xddd5
,
0xa96a
,
0xb8e3
,
0x8a78
,
0x9bf1
,
0x7387
,
0x620e
,
0x5095
,
0x411c
,
0x35a3
,
0x242a
,
0x16b1
,
0x0738
,
0xffcf
,
0xee46
,
0xdcdd
,
0xcd54
,
0xb9eb
,
0xa862
,
0x9af9
,
0x8b70
,
0x8408
,
0x9581
,
0xa71a
,
0xb693
,
0xc22c
,
0xd3a5
,
0xe13e
,
0xf0b7
,
0x0840
,
0x19c9
,
0x2b52
,
0x3adb
,
0x4e64
,
0x5fed
,
0x6d76
,
0x7cff
,
0x9489
,
0x8500
,
0xb79b
,
0xa612
,
0xd2ad
,
0xc324
,
0xf1bf
,
0xe036
,
0x18c1
,
0x0948
,
0x3bd3
,
0x2a5a
,
0x5ee5
,
0x4f6c
,
0x7df7
,
0x6c7e
,
0xa50a
,
0xb483
,
0x8618
,
0x9791
,
0xe32e
,
0xf2a7
,
0xc03c
,
0xd1b5
,
0x2942
,
0x38cb
,
0x0a50
,
0x1bd9
,
0x6f66
,
0x7eef
,
0x4c74
,
0x5dfd
,
0xb58b
,
0xa402
,
0x9699
,
0x8710
,
0xf3af
,
0xe226
,
0xd0bd
,
0xc134
,
0x39c3
,
0x284a
,
0x1ad1
,
0x0b58
,
0x7fe7
,
0x6e6e
,
0x5cf5
,
0x4d7c
,
0xc60c
,
0xd785
,
0xe51e
,
0xf497
,
0x8028
,
0x91a1
,
0xa33a
,
0xb2b3
,
0x4a44
,
0x5bcd
,
0x6956
,
0x78df
,
0x0c60
,
0x1de9
,
0x2f72
,
0x3efb
,
0xd68d
,
0xc704
,
0xf59f
,
0xe416
,
0x90a9
,
0x8120
,
0xb3bb
,
0xa232
,
0x5ac5
,
0x4b4c
,
0x79d7
,
0x685e
,
0x1ce1
,
0x0d68
,
0x3ff3
,
0x2e7a
,
0xe70e
,
0xf687
,
0xc41c
,
0xd595
,
0xa12a
,
0xb0a3
,
0x8238
,
0x93b1
,
0x6b46
,
0x7acf
,
0x4854
,
0x59dd
,
0x2d62
,
0x3ceb
,
0x0e70
,
0x1ff9
,
0xf78f
,
0xe606
,
0xd49d
,
0xc514
,
0xb1ab
,
0xa022
,
0x92b9
,
0x8330
,
0x7bc7
,
0x6a4e
,
0x58d5
,
0x495c
,
0x3de3
,
0x2c6a
,
0x1ef1
,
0x0f78
};
static
u32
mask_pattern
[
2
][
4
]
=
{
{
0x00203000
,
0x000003C0
,
0x00000000
,
0x0000000
},
/* ARP */
{
0xfffff000
,
0xffffffff
,
0xffffffff
,
0x000ffff
}
/* Magic Packet */
};
/**
* ether_crc16 - compute ethernet CRC
* @len: buffer length
* @cp: buffer
* @crc16: initial CRC
*
* Compute a CRC value for a block of data.
* FIXME: can we use generic functions ?
*/
static
u16
ether_crc16
(
int
len
,
u8
*
cp
,
u16
crc16
)
{
while
(
len
--
)
crc16
=
(
crc16
>>
8
)
^
crc16_tab
[(
crc16
^
*
cp
++
)
&
0xff
];
return
(
crc16
);
}
/**
* bit_reverse - 16bit reverse
* @data: 16bit data t reverse
*
* Reverse the order of a 16bit value and return the reversed bits
*/
static
u16
bit_reverse
(
u16
data
)
{
u32
new
=
0x00000000
;
int
ii
;
for
(
ii
=
0
;
ii
<
16
;
ii
++
)
{
new
|=
((
u32
)
(
data
&
1
)
<<
(
31
-
ii
));
data
>>=
1
;
}
return
(
u16
)
(
new
>>
16
);
}
/**
* wol_calc_crc - WOL CRC
* @pattern: data pattern
...
...
@@ -3166,7 +3066,7 @@ static u16 bit_reverse(u16 data)
* Compute the wake on lan crc hashes for the packet header
* we are interested in.
*/
u16
wol_calc_crc
(
int
size
,
u8
*
pattern
,
u8
*
mask_pattern
)
{
u16
crc
=
0xFFFF
;
...
...
@@ -3186,12 +3086,12 @@ u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
continue
;
}
mask
>>=
1
;
crc
=
ether_crc16
(
1
,
&
(
pattern
[
i
*
8
+
j
]),
crc
);
crc
=
crc16
(
crc
,
&
(
pattern
[
i
*
8
+
j
]),
1
);
}
}
/* Finally, invert the result once to get the correct data */
crc
=
~
crc
;
return
bit
_reverse
(
crc
)
;
return
bit
reverse
(
crc
)
>>
16
;
}
/**
...
...
@@ -3203,13 +3103,18 @@ u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
*
* FIXME: check static buffer is safe here
*/
static
int
velocity_set_wol
(
struct
velocity_info
*
vptr
)
{
struct
mac_regs
*
regs
=
vptr
->
mac_regs
;
static
u8
buf
[
256
];
int
i
;
static
u32
mask_pattern
[
2
][
4
]
=
{
{
0x00203000
,
0x000003C0
,
0x00000000
,
0x0000000
},
/* ARP */
{
0xfffff000
,
0xffffffff
,
0xffffffff
,
0x000ffff
}
/* Magic Packet */
};
writew
(
0xFFFF
,
&
regs
->
WOLCRClr
);
writeb
(
WOLCFG_SAB
|
WOLCFG_SAM
,
&
regs
->
WOLCFGSet
);
writew
(
WOLCR_MAGIC_EN
,
&
regs
->
WOLCRSet
);
...
...
@@ -3236,7 +3141,8 @@ static int velocity_set_wol(struct velocity_info *vptr)
memcpy
(
arp
->
ar_tip
,
vptr
->
ip_addr
,
4
);
crc
=
wol_calc_crc
((
sizeof
(
struct
arp_packet
)
+
7
)
/
8
,
buf
,
(
u8
*
)
&
mask_pattern
[
0
][
0
]);
crc
=
wol_calc_crc
((
sizeof
(
struct
arp_packet
)
+
7
)
/
8
,
buf
,
(
u8
*
)
&
mask_pattern
[
0
][
0
]);
writew
(
crc
,
&
regs
->
PatternCRC
[
0
]);
writew
(
WOLCR_ARP_EN
,
&
regs
->
WOLCRSet
);
...
...
@@ -3275,3 +3181,85 @@ static int velocity_set_wol(struct velocity_info *vptr)
return
0
;
}
static
int
velocity_suspend
(
struct
pci_dev
*
pdev
,
u32
state
)
{
struct
velocity_info
*
vptr
=
pci_get_drvdata
(
pdev
);
unsigned
long
flags
;
if
(
!
netif_running
(
vptr
->
dev
))
return
0
;
netif_device_detach
(
vptr
->
dev
);
spin_lock_irqsave
(
&
vptr
->
lock
,
flags
);
pci_save_state
(
pdev
,
vptr
->
pci_state
);
#ifdef ETHTOOL_GWOL
if
(
vptr
->
flags
&
VELOCITY_FLAGS_WOL_ENABLED
)
{
velocity_get_ip
(
vptr
);
velocity_save_context
(
vptr
,
&
vptr
->
context
);
velocity_shutdown
(
vptr
);
velocity_set_wol
(
vptr
);
pci_enable_wake
(
pdev
,
3
,
1
);
pci_set_power_state
(
pdev
,
3
);
}
else
{
velocity_save_context
(
vptr
,
&
vptr
->
context
);
velocity_shutdown
(
vptr
);
pci_disable_device
(
pdev
);
pci_set_power_state
(
pdev
,
state
);
}
#else
pci_set_power_state
(
pdev
,
state
);
#endif
spin_unlock_irqrestore
(
&
vptr
->
lock
,
flags
);
return
0
;
}
static
int
velocity_resume
(
struct
pci_dev
*
pdev
)
{
struct
velocity_info
*
vptr
=
pci_get_drvdata
(
pdev
);
unsigned
long
flags
;
int
i
;
if
(
!
netif_running
(
vptr
->
dev
))
return
0
;
pci_set_power_state
(
pdev
,
0
);
pci_enable_wake
(
pdev
,
0
,
0
);
pci_restore_state
(
pdev
,
vptr
->
pci_state
);
mac_wol_reset
(
vptr
->
mac_regs
);
spin_lock_irqsave
(
&
vptr
->
lock
,
flags
);
velocity_restore_context
(
vptr
,
&
vptr
->
context
);
velocity_init_registers
(
vptr
,
VELOCITY_INIT_WOL
);
mac_disable_int
(
vptr
->
mac_regs
);
velocity_tx_srv
(
vptr
,
0
);
for
(
i
=
0
;
i
<
vptr
->
num_txq
;
i
++
)
{
if
(
vptr
->
td_used
[
i
])
{
mac_tx_queue_wake
(
vptr
->
mac_regs
,
i
);
}
}
mac_enable_int
(
vptr
->
mac_regs
);
spin_unlock_irqrestore
(
&
vptr
->
lock
,
flags
);
netif_device_attach
(
vptr
->
dev
);
return
0
;
}
static
int
velocity_netdev_event
(
struct
notifier_block
*
nb
,
unsigned
long
notification
,
void
*
ptr
)
{
struct
in_ifaddr
*
ifa
=
(
struct
in_ifaddr
*
)
ptr
;
struct
net_device
*
dev
;
struct
velocity_info
*
vptr
;
if
(
ifa
)
{
dev
=
ifa
->
ifa_dev
->
dev
;
vptr
=
dev
->
priv
;
velocity_get_ip
(
vptr
);
}
return
NOTIFY_DONE
;
}
#endif
drivers/net/via-velocity.h
View file @
6720b96a
...
...
@@ -37,7 +37,6 @@
#define OPTION_DEFAULT { [0 ... MAX_UNITS-1] = -1}
#define REV_ID_VT6110 (0)
#define DEVICE_ID (0x3119)
#define BYTE_REG_BITS_ON(x,p) do { writeb(readb((p))|(x),(p));} while (0)
#define WORD_REG_BITS_ON(x,p) do { writew(readw((p))|(x),(p));} while (0)
...
...
@@ -1772,7 +1771,8 @@ struct velocity_info {
struct
velocity_td_info
*
td_infos
[
TX_QUEUE_NO
];
int
rd_curr
;
int
rd_used
;
int
rd_dirty
;
u32
rd_filled
;
struct
rx_desc
*
rd_ring
;
struct
velocity_rd_info
*
rd_info
;
/* It's an array */
...
...
include/linux/pci_ids.h
View file @
6720b96a
...
...
@@ -1218,6 +1218,7 @@
#define PCI_DEVICE_ID_VIA_8233C_0 0x3109
#define PCI_DEVICE_ID_VIA_8361 0x3112
#define PCI_DEVICE_ID_VIA_XM266 0x3116
#define PCI_DEVICE_ID_VIA_612X 0x3119
#define PCI_DEVICE_ID_VIA_862X_0 0x3123
#define PCI_DEVICE_ID_VIA_8753_0 0x3128
#define PCI_DEVICE_ID_VIA_8233A 0x3147
...
...
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