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
74f54248
Commit
74f54248
authored
Oct 21, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/jgarzik/net-drivers-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
4c8aded7
d1b610e5
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1273 additions
and
657 deletions
+1273
-657
drivers/net/8139cp.c
drivers/net/8139cp.c
+1
-0
drivers/net/b44.c
drivers/net/b44.c
+83
-48
drivers/net/b44.h
drivers/net/b44.h
+5
-108
drivers/net/depca.c
drivers/net/depca.c
+4
-4
drivers/net/forcedeth.c
drivers/net/forcedeth.c
+28
-3
drivers/net/sis900.c
drivers/net/sis900.c
+142
-116
drivers/net/smc91x.c
drivers/net/smc91x.c
+258
-226
drivers/net/smc91x.h
drivers/net/smc91x.h
+18
-15
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/lanstreamer.c
+1
-1
drivers/net/tulip/dmfe.c
drivers/net/tulip/dmfe.c
+1
-0
drivers/net/via-rhine.c
drivers/net/via-rhine.c
+4
-0
drivers/net/wireless/prism54/isl_38xx.c
drivers/net/wireless/prism54/isl_38xx.c
+5
-10
drivers/net/wireless/prism54/isl_38xx.h
drivers/net/wireless/prism54/isl_38xx.h
+4
-0
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/prism54/isl_ioctl.c
+554
-85
drivers/net/wireless/prism54/isl_ioctl.h
drivers/net/wireless/prism54/isl_ioctl.h
+2
-0
drivers/net/wireless/prism54/isl_oid.h
drivers/net/wireless/prism54/isl_oid.h
+9
-0
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_dev.c
+32
-17
drivers/net/wireless/prism54/islpci_dev.h
drivers/net/wireless/prism54/islpci_dev.h
+4
-0
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/prism54/islpci_eth.c
+3
-2
drivers/net/wireless/prism54/islpci_hotplug.c
drivers/net/wireless/prism54/islpci_hotplug.c
+0
-3
drivers/net/wireless/prism54/islpci_mgt.c
drivers/net/wireless/prism54/islpci_mgt.c
+1
-0
drivers/net/wireless/prism54/islpci_mgt.h
drivers/net/wireless/prism54/islpci_mgt.h
+0
-2
drivers/net/wireless/prism54/oid_mgt.c
drivers/net/wireless/prism54/oid_mgt.c
+110
-16
drivers/net/wireless/prism54/oid_mgt.h
drivers/net/wireless/prism54/oid_mgt.h
+4
-1
No files found.
drivers/net/8139cp.c
View file @
74f54248
...
@@ -71,6 +71,7 @@
...
@@ -71,6 +71,7 @@
#include <linux/udp.h>
#include <linux/udp.h>
#include <linux/cache.h>
#include <linux/cache.h>
#include <asm/io.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
/* VLAN tagging feature enable/disable */
/* VLAN tagging feature enable/disable */
...
...
drivers/net/b44.c
View file @
74f54248
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>
...
@@ -27,8 +28,8 @@
...
@@ -27,8 +28,8 @@
#define DRV_MODULE_NAME "b44"
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.9
4
"
#define DRV_MODULE_VERSION "0.9
5
"
#define DRV_MODULE_RELDATE "
May 4
, 2004"
#define DRV_MODULE_RELDATE "
Aug 3
, 2004"
#define B44_DEF_MSG_ENABLE \
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
(NETIF_MSG_DRV | \
...
@@ -57,6 +58,7 @@
...
@@ -57,6 +58,7 @@
#define B44_DEF_TX_RING_PENDING (B44_TX_RING_SIZE - 1)
#define B44_DEF_TX_RING_PENDING (B44_TX_RING_SIZE - 1)
#define B44_TX_RING_BYTES (sizeof(struct dma_desc) * \
#define B44_TX_RING_BYTES (sizeof(struct dma_desc) * \
B44_TX_RING_SIZE)
B44_TX_RING_SIZE)
#define B44_DMA_MASK 0x3fffffff
#define TX_RING_GAP(BP) \
#define TX_RING_GAP(BP) \
(B44_TX_RING_SIZE - (BP)->tx_pending)
(B44_TX_RING_SIZE - (BP)->tx_pending)
...
@@ -67,6 +69,7 @@
...
@@ -67,6 +69,7 @@
#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64)
#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64)
#define TX_PKT_BUF_SZ (B44_MAX_MTU + ETH_HLEN + 8)
/* minimum number of free TX descriptors required to wake up TX process */
/* minimum number of free TX descriptors required to wake up TX process */
#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
...
@@ -74,13 +77,13 @@
...
@@ -74,13 +77,13 @@
static
char
version
[]
__devinitdata
=
static
char
version
[]
__devinitdata
=
DRV_MODULE_NAME
".c:v"
DRV_MODULE_VERSION
" ("
DRV_MODULE_RELDATE
")
\n
"
;
DRV_MODULE_NAME
".c:v"
DRV_MODULE_VERSION
" ("
DRV_MODULE_RELDATE
")
\n
"
;
MODULE_AUTHOR
(
"
David S. Miller (davem@redhat.com)
"
);
MODULE_AUTHOR
(
"
Florian Schirmer, Pekka Pietikainen, David S. Miller
"
);
MODULE_DESCRIPTION
(
"Broadcom 4400 10/100 PCI ethernet driver"
);
MODULE_DESCRIPTION
(
"Broadcom 4400 10/100 PCI ethernet driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
b44_debug
,
"i"
);
MODULE_PARM_DESC
(
b44_debug
,
"B44 bitmapped debugging message enable value"
);
static
int
b44_debug
=
-
1
;
/* -1 == use B44_DEF_MSG_ENABLE as value */
static
int
b44_debug
=
-
1
;
/* -1 == use B44_DEF_MSG_ENABLE as value */
module_param
(
b44_debug
,
int
,
0
);
MODULE_PARM_DESC
(
b44_debug
,
"B44 bitmapped debugging message enable value"
);
static
struct
pci_device_id
b44_pci_tbl
[]
=
{
static
struct
pci_device_id
b44_pci_tbl
[]
=
{
{
PCI_VENDOR_ID_BROADCOM
,
PCI_DEVICE_ID_BCM4401
,
{
PCI_VENDOR_ID_BROADCOM
,
PCI_DEVICE_ID_BCM4401
,
...
@@ -97,6 +100,10 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
...
@@ -97,6 +100,10 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static
void
b44_halt
(
struct
b44
*
);
static
void
b44_halt
(
struct
b44
*
);
static
void
b44_init_rings
(
struct
b44
*
);
static
void
b44_init_rings
(
struct
b44
*
);
static
void
b44_init_hw
(
struct
b44
*
);
static
void
b44_init_hw
(
struct
b44
*
);
static
int
b44_poll
(
struct
net_device
*
dev
,
int
*
budget
);
#ifdef CONFIG_NET_POLL_CONTROLLER
static
void
b44_poll_controller
(
struct
net_device
*
dev
);
#endif
static
inline
unsigned
long
br32
(
const
struct
b44
*
bp
,
unsigned
long
reg
)
static
inline
unsigned
long
br32
(
const
struct
b44
*
bp
,
unsigned
long
reg
)
{
{
...
@@ -141,41 +148,8 @@ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
...
@@ -141,41 +148,8 @@ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
* interrupts disabled.
* interrupts disabled.
*/
*/
#define SBID_SDRAM 0
#define SB_PCI_DMA 0x40000000
/* Client Mode PCI memory access space (1 GB) */
#define SBID_PCI_MEM 1
#define BCM4400_PCI_CORE_ADDR 0x18002000
/* Address of PCI core on BCM4400 cards */
#define SBID_PCI_CFG 2
#define SBID_PCI_DMA 3
#define SBID_SDRAM_SWAPPED 4
#define SBID_ENUM 5
#define SBID_REG_SDRAM 6
#define SBID_REG_ILINE20 7
#define SBID_REG_EMAC 8
#define SBID_REG_CODEC 9
#define SBID_REG_USB 10
#define SBID_REG_PCI 11
#define SBID_REG_MIPS 12
#define SBID_REG_EXTIF 13
#define SBID_EXTIF 14
#define SBID_EJTAG 15
#define SBID_MAX 16
static
u32
ssb_get_addr
(
struct
b44
*
bp
,
u32
id
,
u32
instance
)
{
switch
(
id
)
{
case
SBID_PCI_DMA
:
return
0x40000000
;
case
SBID_ENUM
:
return
0x18000000
;
case
SBID_REG_EMAC
:
return
0x18000000
;
case
SBID_REG_CODEC
:
return
0x18001000
;
case
SBID_REG_PCI
:
return
0x18002000
;
default:
return
0
;
};
}
static
u32
ssb_get_core_rev
(
struct
b44
*
bp
)
static
u32
ssb_get_core_rev
(
struct
b44
*
bp
)
{
{
...
@@ -187,8 +161,7 @@ static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
...
@@ -187,8 +161,7 @@ static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
u32
bar_orig
,
pci_rev
,
val
;
u32
bar_orig
,
pci_rev
,
val
;
pci_read_config_dword
(
bp
->
pdev
,
SSB_BAR0_WIN
,
&
bar_orig
);
pci_read_config_dword
(
bp
->
pdev
,
SSB_BAR0_WIN
,
&
bar_orig
);
pci_write_config_dword
(
bp
->
pdev
,
SSB_BAR0_WIN
,
pci_write_config_dword
(
bp
->
pdev
,
SSB_BAR0_WIN
,
BCM4400_PCI_CORE_ADDR
);
ssb_get_addr
(
bp
,
SBID_REG_PCI
,
0
));
pci_rev
=
ssb_get_core_rev
(
bp
);
pci_rev
=
ssb_get_core_rev
(
bp
);
val
=
br32
(
bp
,
B44_SBINTVEC
);
val
=
br32
(
bp
,
B44_SBINTVEC
);
...
@@ -649,10 +622,30 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
...
@@ -649,10 +622,30 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if
(
skb
==
NULL
)
if
(
skb
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
skb
->
dev
=
bp
->
dev
;
mapping
=
pci_map_single
(
bp
->
pdev
,
skb
->
data
,
mapping
=
pci_map_single
(
bp
->
pdev
,
skb
->
data
,
RX_PKT_BUF_SZ
,
RX_PKT_BUF_SZ
,
PCI_DMA_FROMDEVICE
);
PCI_DMA_FROMDEVICE
);
/* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */
if
(
mapping
+
RX_PKT_BUF_SZ
>
B44_DMA_MASK
)
{
/* Sigh... */
pci_unmap_single
(
bp
->
pdev
,
mapping
,
RX_PKT_BUF_SZ
,
PCI_DMA_FROMDEVICE
);
dev_kfree_skb_any
(
skb
);
skb
=
__dev_alloc_skb
(
RX_PKT_BUF_SZ
,
GFP_DMA
);
if
(
skb
==
NULL
)
return
-
ENOMEM
;
mapping
=
pci_map_single
(
bp
->
pdev
,
skb
->
data
,
RX_PKT_BUF_SZ
,
PCI_DMA_FROMDEVICE
);
if
(
mapping
+
RX_PKT_BUF_SZ
>
B44_DMA_MASK
)
{
pci_unmap_single
(
bp
->
pdev
,
mapping
,
RX_PKT_BUF_SZ
,
PCI_DMA_FROMDEVICE
);
dev_kfree_skb_any
(
skb
);
return
-
ENOMEM
;
}
}
skb
->
dev
=
bp
->
dev
;
skb_reserve
(
skb
,
bp
->
rx_offset
);
skb_reserve
(
skb
,
bp
->
rx_offset
);
rh
=
(
struct
rx_header
*
)
rh
=
(
struct
rx_header
*
)
...
@@ -930,6 +923,12 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -930,6 +923,12 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
entry
=
bp
->
tx_prod
;
entry
=
bp
->
tx_prod
;
mapping
=
pci_map_single
(
bp
->
pdev
,
skb
->
data
,
len
,
PCI_DMA_TODEVICE
);
mapping
=
pci_map_single
(
bp
->
pdev
,
skb
->
data
,
len
,
PCI_DMA_TODEVICE
);
if
(
mapping
+
len
>
B44_DMA_MASK
)
{
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
pci_unmap_single
(
bp
->
pdev
,
mapping
,
len
,
PCI_DMA_TODEVICE
);
memcpy
(
bp
->
tx_bufs
+
entry
*
TX_PKT_BUF_SZ
,
skb
->
data
,
skb
->
len
);
mapping
=
pci_map_single
(
bp
->
pdev
,
bp
->
tx_bufs
+
entry
*
TX_PKT_BUF_SZ
,
len
,
PCI_DMA_TODEVICE
);
}
bp
->
tx_buffers
[
entry
].
skb
=
skb
;
bp
->
tx_buffers
[
entry
].
skb
=
skb
;
pci_unmap_addr_set
(
&
bp
->
tx_buffers
[
entry
],
mapping
,
mapping
);
pci_unmap_addr_set
(
&
bp
->
tx_buffers
[
entry
],
mapping
,
mapping
);
...
@@ -1077,6 +1076,11 @@ static void b44_free_consistent(struct b44 *bp)
...
@@ -1077,6 +1076,11 @@ static void b44_free_consistent(struct b44 *bp)
bp
->
tx_ring
,
bp
->
tx_ring_dma
);
bp
->
tx_ring
,
bp
->
tx_ring_dma
);
bp
->
tx_ring
=
NULL
;
bp
->
tx_ring
=
NULL
;
}
}
if
(
bp
->
tx_bufs
)
{
pci_free_consistent
(
bp
->
pdev
,
B44_TX_RING_SIZE
*
TX_PKT_BUF_SZ
,
bp
->
tx_bufs
,
bp
->
tx_bufs_dma
);
bp
->
tx_bufs
=
NULL
;
}
}
}
/*
/*
...
@@ -1099,6 +1103,12 @@ static int b44_alloc_consistent(struct b44 *bp)
...
@@ -1099,6 +1103,12 @@ static int b44_alloc_consistent(struct b44 *bp)
goto
out_err
;
goto
out_err
;
memset
(
bp
->
tx_buffers
,
0
,
size
);
memset
(
bp
->
tx_buffers
,
0
,
size
);
size
=
B44_TX_RING_SIZE
*
TX_PKT_BUF_SZ
;
bp
->
tx_bufs
=
pci_alloc_consistent
(
bp
->
pdev
,
size
,
&
bp
->
tx_bufs_dma
);
if
(
!
bp
->
tx_bufs
)
goto
out_err
;
memset
(
bp
->
tx_bufs
,
0
,
size
);
size
=
DMA_TABLE_BYTES
;
size
=
DMA_TABLE_BYTES
;
bp
->
rx_ring
=
pci_alloc_consistent
(
bp
->
pdev
,
size
,
&
bp
->
rx_ring_dma
);
bp
->
rx_ring
=
pci_alloc_consistent
(
bp
->
pdev
,
size
,
&
bp
->
rx_ring_dma
);
if
(
!
bp
->
rx_ring
)
if
(
!
bp
->
rx_ring
)
...
@@ -1297,6 +1307,19 @@ static int b44_open(struct net_device *dev)
...
@@ -1297,6 +1307,19 @@ static int b44_open(struct net_device *dev)
}
}
#endif
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling receive - used by netconsole and other diagnostic tools
* to allow network i/o with interrupts disabled.
*/
static
void
b44_poll_controller
(
struct
net_device
*
dev
)
{
disable_irq
(
dev
->
irq
);
b44_interrupt
(
dev
->
irq
,
dev
,
NULL
);
enable_irq
(
dev
->
irq
);
}
#endif
static
int
b44_close
(
struct
net_device
*
dev
)
static
int
b44_close
(
struct
net_device
*
dev
)
{
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
struct
b44
*
bp
=
netdev_priv
(
dev
);
...
@@ -1358,7 +1381,10 @@ static struct net_device_stats *b44_get_stats(struct net_device *dev)
...
@@ -1358,7 +1381,10 @@ static struct net_device_stats *b44_get_stats(struct net_device *dev)
hwstat
->
rx_symbol_errs
);
hwstat
->
rx_symbol_errs
);
nstat
->
tx_aborted_errors
=
hwstat
->
tx_underruns
;
nstat
->
tx_aborted_errors
=
hwstat
->
tx_underruns
;
#if 0
/* Carrier lost counter seems to be broken for some devices */
nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
#endif
return
nstat
;
return
nstat
;
}
}
...
@@ -1684,7 +1710,6 @@ static int __devinit b44_get_invariants(struct b44 *bp)
...
@@ -1684,7 +1710,6 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp
->
dev
->
dev_addr
[
5
]
=
eeprom
[
82
];
bp
->
dev
->
dev_addr
[
5
]
=
eeprom
[
82
];
bp
->
phy_addr
=
eeprom
[
90
]
&
0x1f
;
bp
->
phy_addr
=
eeprom
[
90
]
&
0x1f
;
bp
->
mdc_port
=
(
eeprom
[
90
]
>>
14
)
&
0x1
;
/* With this, plus the rx_header prepended to the data by the
/* With this, plus the rx_header prepended to the data by the
* hardware, we'll land the ethernet header on a 2-byte boundary.
* hardware, we'll land the ethernet header on a 2-byte boundary.
...
@@ -1694,7 +1719,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
...
@@ -1694,7 +1719,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp
->
imask
=
IMASK_DEF
;
bp
->
imask
=
IMASK_DEF
;
bp
->
core_unit
=
ssb_core_unit
(
bp
);
bp
->
core_unit
=
ssb_core_unit
(
bp
);
bp
->
dma_offset
=
ssb_get_addr
(
bp
,
SBID_PCI_DMA
,
0
)
;
bp
->
dma_offset
=
SB_PCI_DMA
;
/* XXX - really required?
/* XXX - really required?
bp->flags |= B44_FLAG_BUGGY_TXPTR;
bp->flags |= B44_FLAG_BUGGY_TXPTR;
...
@@ -1738,12 +1763,19 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
...
@@ -1738,12 +1763,19 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
pci_set_master
(
pdev
);
pci_set_master
(
pdev
);
err
=
pci_set_dma_mask
(
pdev
,
(
u64
)
0xffffffff
);
err
=
pci_set_dma_mask
(
pdev
,
(
u64
)
B44_DMA_MASK
);
if
(
err
)
{
if
(
err
)
{
printk
(
KERN_ERR
PFX
"No usable DMA configuration, "
printk
(
KERN_ERR
PFX
"No usable DMA configuration, "
"aborting.
\n
"
);
"aborting.
\n
"
);
goto
err_out_free_res
;
goto
err_out_free_res
;
}
}
err
=
pci_set_consistent_dma_mask
(
pdev
,
(
u64
)
B44_DMA_MASK
);
if
(
err
)
{
printk
(
KERN_ERR
PFX
"No usable DMA configuration, "
"aborting.
\n
"
);
goto
err_out_free_res
;
}
b44reg_base
=
pci_resource_start
(
pdev
,
0
);
b44reg_base
=
pci_resource_start
(
pdev
,
0
);
b44reg_len
=
pci_resource_len
(
pdev
,
0
);
b44reg_len
=
pci_resource_len
(
pdev
,
0
);
...
@@ -1793,6 +1825,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
...
@@ -1793,6 +1825,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
dev
->
poll
=
b44_poll
;
dev
->
poll
=
b44_poll
;
dev
->
weight
=
64
;
dev
->
weight
=
64
;
dev
->
watchdog_timeo
=
B44_TX_TIMEOUT
;
dev
->
watchdog_timeo
=
B44_TX_TIMEOUT
;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev
->
poll_controller
=
b44_poll_controller
;
#endif
dev
->
change_mtu
=
b44_change_mtu
;
dev
->
change_mtu
=
b44_change_mtu
;
dev
->
irq
=
pdev
->
irq
;
dev
->
irq
=
pdev
->
irq
;
SET_ETHTOOL_OPS
(
dev
,
&
b44_ethtool_ops
);
SET_ETHTOOL_OPS
(
dev
,
&
b44_ethtool_ops
);
...
@@ -1870,7 +1905,7 @@ static void __devexit b44_remove_one(struct pci_dev *pdev)
...
@@ -1870,7 +1905,7 @@ static void __devexit b44_remove_one(struct pci_dev *pdev)
static
int
b44_suspend
(
struct
pci_dev
*
pdev
,
u32
state
)
static
int
b44_suspend
(
struct
pci_dev
*
pdev
,
u32
state
)
{
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
if
(
!
netif_running
(
dev
))
if
(
!
netif_running
(
dev
))
return
0
;
return
0
;
...
@@ -1891,7 +1926,7 @@ static int b44_suspend(struct pci_dev *pdev, u32 state)
...
@@ -1891,7 +1926,7 @@ static int b44_suspend(struct pci_dev *pdev, u32 state)
static
int
b44_resume
(
struct
pci_dev
*
pdev
)
static
int
b44_resume
(
struct
pci_dev
*
pdev
)
{
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
pci_restore_state
(
pdev
);
pci_restore_state
(
pdev
);
...
...
drivers/net/b44.h
View file @
74f54248
...
@@ -223,21 +223,8 @@
...
@@ -223,21 +223,8 @@
#define B44_RX_SYM 0x05D0UL
/* MIB RX Symbol Errors */
#define B44_RX_SYM 0x05D0UL
/* MIB RX Symbol Errors */
#define B44_RX_PAUSE 0x05D4UL
/* MIB RX Pause Packets */
#define B44_RX_PAUSE 0x05D4UL
/* MIB RX Pause Packets */
#define B44_RX_NPAUSE 0x05D8UL
/* MIB RX Non-Pause Packets */
#define B44_RX_NPAUSE 0x05D8UL
/* MIB RX Non-Pause Packets */
#define B44_SBIPSFLAG 0x0F08UL
/* SB Initiator Port OCP Slave Flag */
#define SBIPSFLAG_IMASK1 0x0000003f
/* Which sbflags --> mips interrupt 1 */
/* Silicon backplane register definitions */
#define SBIPSFLAG_ISHIFT1 0
#define SBIPSFLAG_IMASK2 0x00003f00
/* Which sbflags --> mips interrupt 2 */
#define SBIPSFLAG_ISHIFT2 8
#define SBIPSFLAG_IMASK3 0x003f0000
/* Which sbflags --> mips interrupt 3 */
#define SBIPSFLAG_ISHIFT3 16
#define SBIPSFLAG_IMASK4 0x3f000000
/* Which sbflags --> mips interrupt 4 */
#define SBIPSFLAG_ISHIFT4 24
#define B44_SBTPSFLAG 0x0F18UL
/* SB Target Port OCP Slave Flag */
#define SBTPS_NUM0_MASK 0x0000003f
#define SBTPS_F0EN0 0x00000040
#define B44_SBADMATCH3 0x0F60UL
/* SB Address Match 3 */
#define B44_SBADMATCH2 0x0F68UL
/* SB Address Match 2 */
#define B44_SBADMATCH1 0x0F70UL
/* SB Address Match 1 */
#define B44_SBIMSTATE 0x0F90UL
/* SB Initiator Agent State */
#define B44_SBIMSTATE 0x0F90UL
/* SB Initiator Agent State */
#define SBIMSTATE_PC 0x0000000f
/* Pipe Count */
#define SBIMSTATE_PC 0x0000000f
/* Pipe Count */
#define SBIMSTATE_AP_MASK 0x00000030
/* Arbitration Priority */
#define SBIMSTATE_AP_MASK 0x00000030
/* Arbitration Priority */
...
@@ -269,86 +256,6 @@
...
@@ -269,86 +256,6 @@
#define SBTMSHIGH_GCR 0x20000000
/* Gated Clock Request */
#define SBTMSHIGH_GCR 0x20000000
/* Gated Clock Request */
#define SBTMSHIGH_BISTF 0x40000000
/* BIST Failed */
#define SBTMSHIGH_BISTF 0x40000000
/* BIST Failed */
#define SBTMSHIGH_BISTD 0x80000000
/* BIST Done */
#define SBTMSHIGH_BISTD 0x80000000
/* BIST Done */
#define B44_SBBWA0 0x0FA0UL
/* SB Bandwidth Allocation Table 0 */
#define SBBWA0_TAB0_MASK 0x0000ffff
/* Lookup Table 0 */
#define SBBWA0_TAB0_SHIFT 0
#define SBBWA0_TAB1_MASK 0xffff0000
/* Lookup Table 0 */
#define SBBWA0_TAB1_SHIFT 16
#define B44_SBIMCFGLOW 0x0FA8UL
/* SB Initiator Configuration Low */
#define SBIMCFGLOW_STO_MASK 0x00000003
/* Service Timeout */
#define SBIMCFGLOW_RTO_MASK 0x00000030
/* Request Timeout */
#define SBIMCFGLOW_RTO_SHIFT 4
#define SBIMCFGLOW_CID_MASK 0x00ff0000
/* Connection ID */
#define SBIMCFGLOW_CID_SHIFT 16
#define B44_SBIMCFGHIGH 0x0FACUL
/* SB Initiator Configuration High */
#define SBIMCFGHIGH_IEM_MASK 0x0000000c
/* Inband Error Mode */
#define SBIMCFGHIGH_TEM_MASK 0x00000030
/* Timeout Error Mode */
#define SBIMCFGHIGH_TEM_SHIFT 4
#define SBIMCFGHIGH_BEM_MASK 0x000000c0
/* Bus Error Mode */
#define SBIMCFGHIGH_BEM_SHIFT 6
#define B44_SBADMATCH0 0x0FB0UL
/* SB Address Match 0 */
#define SBADMATCH0_TYPE_MASK 0x00000003
/* Address Type */
#define SBADMATCH0_AD64 0x00000004
/* Reserved */
#define SBADMATCH0_AI0_MASK 0x000000f8
/* Type0 Size */
#define SBADMATCH0_AI0_SHIFT 3
#define SBADMATCH0_AI1_MASK 0x000001f8
/* Type1 Size */
#define SBADMATCH0_AI1_SHIFT 3
#define SBADMATCH0_AI2_MASK 0x000001f8
/* Type2 Size */
#define SBADMATCH0_AI2_SHIFT 3
#define SBADMATCH0_ADEN 0x00000400
/* Enable */
#define SBADMATCH0_ADNEG 0x00000800
/* Negative Decode */
#define SBADMATCH0_BS0_MASK 0xffffff00
/* Type0 Base Address */
#define SBADMATCH0_BS0_SHIFT 8
#define SBADMATCH0_BS1_MASK 0xfffff000
/* Type1 Base Address */
#define SBADMATCH0_BS1_SHIFT 12
#define SBADMATCH0_BS2_MASK 0xffff0000
/* Type2 Base Address */
#define SBADMATCH0_BS2_SHIFT 16
#define B44_SBTMCFGLOW 0x0FB8UL
/* SB Target Configuration Low */
#define SBTMCFGLOW_CD_MASK 0x000000ff
/* Clock Divide Mask */
#define SBTMCFGLOW_CO_MASK 0x0000f800
/* Clock Offset Mask */
#define SBTMCFGLOW_CO_SHIFT 11
#define SBTMCFGLOW_IF_MASK 0x00fc0000
/* Interrupt Flags Mask */
#define SBTMCFGLOW_IF_SHIFT 18
#define SBTMCFGLOW_IM_MASK 0x03000000
/* Interrupt Mode Mask */
#define SBTMCFGLOW_IM_SHIFT 24
#define B44_SBTMCFGHIGH 0x0FBCUL
/* SB Target Configuration High */
#define SBTMCFGHIGH_BM_MASK 0x00000003
/* Busy Mode */
#define SBTMCFGHIGH_RM_MASK 0x0000000C
/* Retry Mode */
#define SBTMCFGHIGH_RM_SHIFT 2
#define SBTMCFGHIGH_SM_MASK 0x00000030
/* Stop Mode */
#define SBTMCFGHIGH_SM_SHIFT 4
#define SBTMCFGHIGH_EM_MASK 0x00000300
/* Error Mode */
#define SBTMCFGHIGH_EM_SHIFT 8
#define SBTMCFGHIGH_IM_MASK 0x00000c00
/* Interrupt Mode */
#define SBTMCFGHIGH_IM_SHIFT 10
#define B44_SBBCFG 0x0FC0UL
/* SB Broadcast Configuration */
#define SBBCFG_LAT_MASK 0x00000003
/* SB Latency */
#define SBBCFG_MAX0_MASK 0x000f0000
/* MAX Counter 0 */
#define SBBCFG_MAX0_SHIFT 16
#define SBBCFG_MAX1_MASK 0x00f00000
/* MAX Counter 1 */
#define SBBCFG_MAX1_SHIFT 20
#define B44_SBBSTATE 0x0FC8UL
/* SB Broadcast State */
#define SBBSTATE_SRD 0x00000001
/* ST Reg Disable */
#define SBBSTATE_HRD 0x00000002
/* Hold Reg Disable */
#define B44_SBACTCNFG 0x0FD8UL
/* SB Activate Configuration */
#define B44_SBFLAGST 0x0FE8UL
/* SB Current SBFLAGS */
#define B44_SBIDLOW 0x0FF8UL
/* SB Identification Low */
#define SBIDLOW_CS_MASK 0x00000003
/* Config Space Mask */
#define SBIDLOW_AR_MASK 0x00000038
/* Num Address Ranges Supported */
#define SBIDLOW_AR_SHIFT 3
#define SBIDLOW_SYNCH 0x00000040
/* Sync */
#define SBIDLOW_INIT 0x00000080
/* Initiator */
#define SBIDLOW_MINLAT_MASK 0x00000f00
/* Minimum Backplane Latency */
#define SBIDLOW_MINLAT_SHIFT 8
#define SBIDLOW_MAXLAT_MASK 0x0000f000
/* Maximum Backplane Latency */
#define SBIDLOW_MAXLAT_SHIFT 12
#define SBIDLOW_FIRST 0x00010000
/* This Initiator is First */
#define SBIDLOW_CW_MASK 0x000c0000
/* Cycle Counter Width */
#define SBIDLOW_CW_SHIFT 18
#define SBIDLOW_TP_MASK 0x00f00000
/* Target Ports */
#define SBIDLOW_TP_SHIFT 20
#define SBIDLOW_IP_MASK 0x0f000000
/* Initiator Ports */
#define SBIDLOW_IP_SHIFT 24
#define B44_SBIDHIGH 0x0FFCUL
/* SB Identification High */
#define B44_SBIDHIGH 0x0FFCUL
/* SB Identification High */
#define SBIDHIGH_RC_MASK 0x0000000f
/* Revision Code */
#define SBIDHIGH_RC_MASK 0x0000000f
/* Revision Code */
#define SBIDHIGH_CC_MASK 0x0000fff0
/* Core Code */
#define SBIDHIGH_CC_MASK 0x0000fff0
/* Core Code */
...
@@ -356,23 +263,13 @@
...
@@ -356,23 +263,13 @@
#define SBIDHIGH_VC_MASK 0xffff0000
/* Vendor Code */
#define SBIDHIGH_VC_MASK 0xffff0000
/* Vendor Code */
#define SBIDHIGH_VC_SHIFT 16
#define SBIDHIGH_VC_SHIFT 16
#define CORE_CODE_ILINE20 0x801
#define CORE_CODE_SDRAM 0x803
#define CORE_CODE_PCI 0x804
#define CORE_CODE_MIPS 0x805
#define CORE_CODE_ENET 0x806
#define CORE_CODE_CODEC 0x807
#define CORE_CODE_USB 0x808
#define CORE_CODE_ILINE100 0x80a
#define CORE_CODE_EXTIF 0x811
/* SSB PCI config space registers. */
/* SSB PCI config space registers. */
#define SSB_BAR0_WIN 0x80
#define SSB_BAR0_WIN 0x80
#define SSB_BAR1_WIN 0x84
#define SSB_BAR1_WIN 0x84
#define SSB_SPROM_CONTROL 0x88
#define SSB_SPROM_CONTROL 0x88
#define SSB_BAR1_CONTROL 0x8c
#define SSB_BAR1_CONTROL 0x8c
/* SSB core and h
so
t control registers. */
/* SSB core and h
os
t control registers. */
#define SSB_CONTROL 0x0000UL
#define SSB_CONTROL 0x0000UL
#define SSB_ARBCONTROL 0x0010UL
#define SSB_ARBCONTROL 0x0010UL
#define SSB_ISTAT 0x0020UL
#define SSB_ISTAT 0x0020UL
...
@@ -500,6 +397,7 @@ struct b44 {
...
@@ -500,6 +397,7 @@ struct b44 {
struct
ring_info
*
rx_buffers
;
struct
ring_info
*
rx_buffers
;
struct
ring_info
*
tx_buffers
;
struct
ring_info
*
tx_buffers
;
unsigned
char
*
tx_bufs
;
u32
dma_offset
;
u32
dma_offset
;
u32
flags
;
u32
flags
;
...
@@ -531,12 +429,11 @@ struct b44 {
...
@@ -531,12 +429,11 @@ struct b44 {
struct
pci_dev
*
pdev
;
struct
pci_dev
*
pdev
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
dma_addr_t
rx_ring_dma
,
tx_ring_dma
;
dma_addr_t
rx_ring_dma
,
tx_ring_dma
,
tx_bufs_dma
;
u32
rx_pending
;
u32
rx_pending
;
u32
tx_pending
;
u32
tx_pending
;
u8
phy_addr
;
u8
phy_addr
;
u8
mdc_port
;
u8
core_unit
;
u8
core_unit
;
struct
mii_if_info
mii_if
;
struct
mii_if_info
mii_if
;
...
...
drivers/net/depca.c
View file @
74f54248
...
@@ -1222,10 +1222,10 @@ static int InitRestartDepca(struct net_device *dev)
...
@@ -1222,10 +1222,10 @@ static int InitRestartDepca(struct net_device *dev)
/* clear IDON by writing a "1", enable interrupts and start lance */
/* clear IDON by writing a "1", enable interrupts and start lance */
outw
(
IDON
|
INEA
|
STRT
,
DEPCA_DATA
);
outw
(
IDON
|
INEA
|
STRT
,
DEPCA_DATA
);
if
(
depca_debug
>
2
)
{
if
(
depca_debug
>
2
)
{
printk
(
"%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.
\n
"
,
dev
->
name
,
i
,
virt_to_phys
(
lp
->
sh_mem
)
,
inw
(
DEPCA_DATA
));
printk
(
"%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.
\n
"
,
dev
->
name
,
i
,
lp
->
mem_start
,
inw
(
DEPCA_DATA
));
}
}
}
else
{
}
else
{
printk
(
"%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.
\n
"
,
dev
->
name
,
i
,
virt_to_phys
(
lp
->
sh_mem
)
,
inw
(
DEPCA_DATA
));
printk
(
"%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.
\n
"
,
dev
->
name
,
i
,
lp
->
mem_start
,
inw
(
DEPCA_DATA
));
status
=
-
1
;
status
=
-
1
;
}
}
...
@@ -1901,7 +1901,7 @@ static void depca_dbg_open(struct net_device *dev)
...
@@ -1901,7 +1901,7 @@ static void depca_dbg_open(struct net_device *dev)
}
}
}
}
printk
(
"...0x%8.8x
\n
"
,
readl
(
&
lp
->
tx_ring
[
i
].
base
));
printk
(
"...0x%8.8x
\n
"
,
readl
(
&
lp
->
tx_ring
[
i
].
base
));
printk
(
"Initialisation block at 0x%8.8lx(Phys)
\n
"
,
virt_to_phys
(
lp
->
sh_mem
)
);
printk
(
"Initialisation block at 0x%8.8lx(Phys)
\n
"
,
lp
->
mem_start
);
printk
(
" mode: 0x%4.4x
\n
"
,
p
->
mode
);
printk
(
" mode: 0x%4.4x
\n
"
,
p
->
mode
);
printk
(
" physical address: "
);
printk
(
" physical address: "
);
for
(
i
=
0
;
i
<
ETH_ALEN
-
1
;
i
++
)
{
for
(
i
=
0
;
i
<
ETH_ALEN
-
1
;
i
++
)
{
...
@@ -1915,7 +1915,7 @@ static void depca_dbg_open(struct net_device *dev)
...
@@ -1915,7 +1915,7 @@ static void depca_dbg_open(struct net_device *dev)
printk
(
"%2.2x
\n
"
,
p
->
mcast_table
[
i
]);
printk
(
"%2.2x
\n
"
,
p
->
mcast_table
[
i
]);
printk
(
" rx_ring at: 0x%8.8x
\n
"
,
p
->
rx_ring
);
printk
(
" rx_ring at: 0x%8.8x
\n
"
,
p
->
rx_ring
);
printk
(
" tx_ring at: 0x%8.8x
\n
"
,
p
->
tx_ring
);
printk
(
" tx_ring at: 0x%8.8x
\n
"
,
p
->
tx_ring
);
printk
(
"buffers (Phys): 0x%8.8lx
\n
"
,
virt_to_phys
(
lp
->
sh_mem
)
+
lp
->
buffs_offset
);
printk
(
"buffers (Phys): 0x%8.8lx
\n
"
,
lp
->
mem_start
+
lp
->
buffs_offset
);
printk
(
"Ring size:
\n
RX: %d Log2(rxRingMask): 0x%8.8x
\n
"
,
(
int
)
lp
->
rxRingMask
+
1
,
lp
->
rx_rlen
);
printk
(
"Ring size:
\n
RX: %d Log2(rxRingMask): 0x%8.8x
\n
"
,
(
int
)
lp
->
rxRingMask
+
1
,
lp
->
rx_rlen
);
printk
(
"TX: %d Log2(txRingMask): 0x%8.8x
\n
"
,
(
int
)
lp
->
txRingMask
+
1
,
lp
->
tx_rlen
);
printk
(
"TX: %d Log2(txRingMask): 0x%8.8x
\n
"
,
(
int
)
lp
->
txRingMask
+
1
,
lp
->
tx_rlen
);
outw
(
CSR2
,
DEPCA_ADDR
);
outw
(
CSR2
,
DEPCA_ADDR
);
...
...
drivers/net/forcedeth.c
View file @
74f54248
...
@@ -76,6 +76,9 @@
...
@@ -76,6 +76,9 @@
* for registers, link status and other minor fixes.
* for registers, link status and other minor fixes.
* 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe
* 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe
* 0.29: 31 Aug 2004: Add backup timer for link change notification.
* 0.29: 31 Aug 2004: Add backup timer for link change notification.
* 0.30: 25 Sep 2004: rx checksum support for nf 250 Gb. Add rx reset
* into nv_close, otherwise reenabling for wol can
* cause DMA to kfree'd memory.
*
*
* Known bugs:
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
* We suspect that on some hardware no TX done interrupts are generated.
...
@@ -87,7 +90,7 @@
...
@@ -87,7 +90,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
* superfluous timer interrupts from the nic.
*/
*/
#define FORCEDETH_VERSION "0.
29
"
#define FORCEDETH_VERSION "0.
30
"
#define DRV_NAME "forcedeth"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
#include <linux/module.h>
...
@@ -217,6 +220,7 @@ enum {
...
@@ -217,6 +220,7 @@ enum {
#define NVREG_TXRXCTL_BIT2 0x0004
#define NVREG_TXRXCTL_BIT2 0x0004
#define NVREG_TXRXCTL_IDLE 0x0008
#define NVREG_TXRXCTL_IDLE 0x0008
#define NVREG_TXRXCTL_RESET 0x0010
#define NVREG_TXRXCTL_RESET 0x0010
#define NVREG_TXRXCTL_RXCHECK 0x0400
NvRegMIIStatus
=
0x180
,
NvRegMIIStatus
=
0x180
,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
#define NVREG_MIISTAT_LINKCHANGE 0x0008
...
@@ -313,6 +317,10 @@ struct ring_desc {
...
@@ -313,6 +317,10 @@ struct ring_desc {
#define NV_RX_ERROR (1<<30)
#define NV_RX_ERROR (1<<30)
#define NV_RX_AVAIL (1<<31)
#define NV_RX_AVAIL (1<<31)
#define NV_RX2_CHECKSUMMASK (0x1C000000)
#define NV_RX2_CHECKSUMOK1 (0x10000000)
#define NV_RX2_CHECKSUMOK2 (0x14000000)
#define NV_RX2_CHECKSUMOK3 (0x18000000)
#define NV_RX2_DESCRIPTORVALID (1<<29)
#define NV_RX2_DESCRIPTORVALID (1<<29)
#define NV_RX2_SUBSTRACT1 (1<<25)
#define NV_RX2_SUBSTRACT1 (1<<25)
#define NV_RX2_ERROR1 (1<<18)
#define NV_RX2_ERROR1 (1<<18)
...
@@ -371,8 +379,15 @@ struct ring_desc {
...
@@ -371,8 +379,15 @@ struct ring_desc {
#define POLL_WAIT (1+HZ/100)
#define POLL_WAIT (1+HZ/100)
#define LINK_TIMEOUT (3*HZ)
#define LINK_TIMEOUT (3*HZ)
/*
* desc_ver values:
* This field has two purposes:
* - Newer nics uses a different ring layout. The layout is selected by
* comparing np->desc_ver with DESC_VER_xy.
* - It contains bits that are forced on when writing to NvRegTxRxControl.
*/
#define DESC_VER_1 0x0
#define DESC_VER_1 0x0
#define DESC_VER_2
0x02100
#define DESC_VER_2
(0x02100|NVREG_TXRXCTL_RXCHECK)
/* PHY defines */
/* PHY defines */
#define PHY_OUI_MARVELL 0x5043
#define PHY_OUI_MARVELL 0x5043
...
@@ -1142,6 +1157,15 @@ static void nv_rx_process(struct net_device *dev)
...
@@ -1142,6 +1157,15 @@ static void nv_rx_process(struct net_device *dev)
goto
next_pkt
;
goto
next_pkt
;
}
}
}
}
Flags
&=
NV_RX2_CHECKSUMMASK
;
if
(
Flags
==
NV_RX2_CHECKSUMOK1
||
Flags
==
NV_RX2_CHECKSUMOK2
||
Flags
==
NV_RX2_CHECKSUMOK3
)
{
dprintk
(
KERN_DEBUG
"%s: hw checksum hit!.
\n
"
,
dev
->
name
);
np
->
rx_skbuff
[
i
]
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
}
else
{
dprintk
(
KERN_DEBUG
"%s: hwchecksum miss!.
\n
"
,
dev
->
name
);
}
}
}
/* got a valid packet - forward it to the network core */
/* got a valid packet - forward it to the network core */
skb
=
np
->
rx_skbuff
[
i
];
skb
=
np
->
rx_skbuff
[
i
];
...
@@ -1634,9 +1658,10 @@ static int nv_close(struct net_device *dev)
...
@@ -1634,9 +1658,10 @@ static int nv_close(struct net_device *dev)
spin_lock_irq
(
&
np
->
lock
);
spin_lock_irq
(
&
np
->
lock
);
nv_stop_tx
(
dev
);
nv_stop_tx
(
dev
);
nv_stop_rx
(
dev
);
nv_stop_rx
(
dev
);
base
=
get_hwbase
(
dev
);
nv_txrx_reset
(
dev
);
/* disable interrupts on the nic or we will lock up */
/* disable interrupts on the nic or we will lock up */
base
=
get_hwbase
(
dev
);
writel
(
0
,
base
+
NvRegIrqMask
);
writel
(
0
,
base
+
NvRegIrqMask
);
pci_push
(
base
);
pci_push
(
base
);
dprintk
(
KERN_INFO
"%s: Irqmask is zero again
\n
"
,
dev
->
name
);
dprintk
(
KERN_INFO
"%s: Irqmask is zero again
\n
"
,
dev
->
name
);
...
...
drivers/net/sis900.c
View file @
74f54248
...
@@ -140,9 +140,9 @@ struct mii_phy {
...
@@ -140,9 +140,9 @@ struct mii_phy {
};
};
typedef
struct
_BufferDesc
{
typedef
struct
_BufferDesc
{
u32
link
;
u32
link
;
u32
cmdsts
;
u32
cmdsts
;
u32
bufptr
;
u32
bufptr
;
}
BufferDesc
;
}
BufferDesc
;
struct
sis900_private
{
struct
sis900_private
{
...
@@ -156,7 +156,7 @@ struct sis900_private {
...
@@ -156,7 +156,7 @@ struct sis900_private {
unsigned
int
cur_phy
;
unsigned
int
cur_phy
;
struct
timer_list
timer
;
/* Link status detection timer. */
struct
timer_list
timer
;
/* Link status detection timer. */
u8
autong_complete
;
/* 1: auto-negotiate complete */
u8
autong_complete
;
/* 1: auto-negotiate complete */
unsigned
int
cur_rx
,
dirty_rx
;
/* producer/comsumer pointers for Tx/Rx ring */
unsigned
int
cur_rx
,
dirty_rx
;
/* producer/comsumer pointers for Tx/Rx ring */
unsigned
int
cur_tx
,
dirty_tx
;
unsigned
int
cur_tx
,
dirty_tx
;
...
@@ -170,7 +170,7 @@ struct sis900_private {
...
@@ -170,7 +170,7 @@ struct sis900_private {
dma_addr_t
tx_ring_dma
;
dma_addr_t
tx_ring_dma
;
dma_addr_t
rx_ring_dma
;
dma_addr_t
rx_ring_dma
;
unsigned
int
tx_full
;
/* The Tx queue is full.
*/
unsigned
int
tx_full
;
/* The Tx queue is full.
*/
u8
host_bridge_rev
;
u8
host_bridge_rev
;
};
};
...
@@ -255,7 +255,8 @@ static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_de
...
@@ -255,7 +255,8 @@ static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_de
* MAC address is read into @net_dev->dev_addr.
* MAC address is read into @net_dev->dev_addr.
*/
*/
static
int
__devinit
sis630e_get_mac_addr
(
struct
pci_dev
*
pci_dev
,
struct
net_device
*
net_dev
)
static
int
__devinit
sis630e_get_mac_addr
(
struct
pci_dev
*
pci_dev
,
struct
net_device
*
net_dev
)
{
{
struct
pci_dev
*
isa_bridge
=
NULL
;
struct
pci_dev
*
isa_bridge
=
NULL
;
u8
reg
;
u8
reg
;
...
@@ -292,7 +293,8 @@ static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, struct net_d
...
@@ -292,7 +293,8 @@ static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, struct net_d
* @net_dev->dev_addr.
* @net_dev->dev_addr.
*/
*/
static
int
__devinit
sis635_get_mac_addr
(
struct
pci_dev
*
pci_dev
,
struct
net_device
*
net_dev
)
static
int
__devinit
sis635_get_mac_addr
(
struct
pci_dev
*
pci_dev
,
struct
net_device
*
net_dev
)
{
{
long
ioaddr
=
net_dev
->
base_addr
;
long
ioaddr
=
net_dev
->
base_addr
;
u32
rfcrSave
;
u32
rfcrSave
;
...
@@ -334,7 +336,8 @@ static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, struct net_de
...
@@ -334,7 +336,8 @@ static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, struct net_de
* MAC address is read into @net_dev->dev_addr.
* MAC address is read into @net_dev->dev_addr.
*/
*/
static
int
__devinit
sis96x_get_mac_addr
(
struct
pci_dev
*
pci_dev
,
struct
net_device
*
net_dev
)
static
int
__devinit
sis96x_get_mac_addr
(
struct
pci_dev
*
pci_dev
,
struct
net_device
*
net_dev
)
{
{
long
ioaddr
=
net_dev
->
base_addr
;
long
ioaddr
=
net_dev
->
base_addr
;
long
ee_addr
=
ioaddr
+
mear
;
long
ee_addr
=
ioaddr
+
mear
;
...
@@ -371,7 +374,8 @@ static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, struct net_de
...
@@ -371,7 +374,8 @@ static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, struct net_de
* ie: sis900_open(), sis900_start_xmit(), sis900_close(), etc.
* ie: sis900_open(), sis900_start_xmit(), sis900_close(), etc.
*/
*/
static
int
__devinit
sis900_probe
(
struct
pci_dev
*
pci_dev
,
const
struct
pci_device_id
*
pci_id
)
static
int
__devinit
sis900_probe
(
struct
pci_dev
*
pci_dev
,
const
struct
pci_device_id
*
pci_id
)
{
{
struct
sis900_private
*
sis_priv
;
struct
sis900_private
*
sis_priv
;
struct
net_device
*
net_dev
;
struct
net_device
*
net_dev
;
...
@@ -522,7 +526,7 @@ static int __devinit sis900_probe (struct pci_dev *pci_dev, const struct pci_dev
...
@@ -522,7 +526,7 @@ static int __devinit sis900_probe (struct pci_dev *pci_dev, const struct pci_dev
* return error if it failed to found.
* return error if it failed to found.
*/
*/
static
int
__init
sis900_mii_probe
(
struct
net_device
*
net_dev
)
static
int
__init
sis900_mii_probe
(
struct
net_device
*
net_dev
)
{
{
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
u16
poll_bit
=
MII_STAT_LINK
,
status
=
0
;
u16
poll_bit
=
MII_STAT_LINK
,
status
=
0
;
...
@@ -572,9 +576,10 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
...
@@ -572,9 +576,10 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
mii_phy
->
phy_types
=
mii_chip_table
[
i
].
phy_types
;
mii_phy
->
phy_types
=
mii_chip_table
[
i
].
phy_types
;
if
(
mii_chip_table
[
i
].
phy_types
==
MIX
)
if
(
mii_chip_table
[
i
].
phy_types
==
MIX
)
mii_phy
->
phy_types
=
mii_phy
->
phy_types
=
(
mii_status
&
(
MII_STAT_CAN_TX_FDX
|
MII_STAT_CAN_TX
))
?
LAN
:
HOME
;
(
mii_status
&
(
MII_STAT_CAN_TX_FDX
|
MII_STAT_CAN_TX
))
?
LAN
:
HOME
;
printk
(
KERN_INFO
"%s: %s transceiver found at address %d.
\n
"
,
printk
(
KERN_INFO
"%s: %s transceiver found at address %d.
\n
"
,
net_dev
->
name
,
mii_chip_table
[
i
].
name
,
phy_addr
);
net_dev
->
name
,
mii_chip_table
[
i
].
name
,
phy_addr
);
break
;
break
;
}
}
...
@@ -587,7 +592,7 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
...
@@ -587,7 +592,7 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
if
(
sis_priv
->
mii
==
NULL
)
{
if
(
sis_priv
->
mii
==
NULL
)
{
printk
(
KERN_INFO
"%s: No MII transceivers found!
\n
"
,
printk
(
KERN_INFO
"%s: No MII transceivers found!
\n
"
,
net_dev
->
name
);
net_dev
->
name
);
return
0
;
return
0
;
}
}
...
@@ -611,7 +616,8 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
...
@@ -611,7 +616,8 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
poll_bit
^=
(
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_STATUS
)
&
poll_bit
);
poll_bit
^=
(
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_STATUS
)
&
poll_bit
);
if
(
time_after_eq
(
jiffies
,
timeout
))
{
if
(
time_after_eq
(
jiffies
,
timeout
))
{
printk
(
KERN_WARNING
"%s: reset phy and link down now
\n
"
,
net_dev
->
name
);
printk
(
KERN_WARNING
"%s: reset phy and link down now
\n
"
,
net_dev
->
name
);
return
-
ETIME
;
return
-
ETIME
;
}
}
}
}
...
@@ -647,38 +653,41 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
...
@@ -647,38 +653,41 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
static
u16
sis900_default_phy
(
struct
net_device
*
net_dev
)
static
u16
sis900_default_phy
(
struct
net_device
*
net_dev
)
{
{
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
struct
mii_phy
*
phy
=
NULL
,
*
phy_home
=
NULL
,
*
default_phy
=
NULL
,
*
phy_lan
=
NULL
;
struct
mii_phy
*
phy
=
NULL
,
*
phy_home
=
NULL
,
*
default_phy
=
NULL
,
*
phy_lan
=
NULL
;
u16
status
;
u16
status
;
for
(
phy
=
sis_priv
->
first_mii
;
phy
;
phy
=
phy
->
next
)
{
for
(
phy
=
sis_priv
->
first_mii
;
phy
;
phy
=
phy
->
next
)
{
status
=
mdio_read
(
net_dev
,
phy
->
phy_addr
,
MII_STATUS
);
status
=
mdio_read
(
net_dev
,
phy
->
phy_addr
,
MII_STATUS
);
status
=
mdio_read
(
net_dev
,
phy
->
phy_addr
,
MII_STATUS
);
status
=
mdio_read
(
net_dev
,
phy
->
phy_addr
,
MII_STATUS
);
/* Link ON & Not select default PHY & not ghost PHY */
/* Link ON & Not select default PHY & not ghost PHY */
if
(
(
status
&
MII_STAT_LINK
)
&&
!
default_phy
&&
(
phy
->
phy_types
!=
UNKNOWN
)
)
if
((
status
&
MII_STAT_LINK
)
&&
!
default_phy
&&
(
phy
->
phy_types
!=
UNKNOWN
))
default_phy
=
phy
;
default_phy
=
phy
;
else
{
else
{
status
=
mdio_read
(
net_dev
,
phy
->
phy_addr
,
MII_CONTROL
);
status
=
mdio_read
(
net_dev
,
phy
->
phy_addr
,
MII_CONTROL
);
mdio_write
(
net_dev
,
phy
->
phy_addr
,
MII_CONTROL
,
mdio_write
(
net_dev
,
phy
->
phy_addr
,
MII_CONTROL
,
status
|
MII_CNTL_AUTO
|
MII_CNTL_ISOLATE
);
status
|
MII_CNTL_AUTO
|
MII_CNTL_ISOLATE
);
if
(
phy
->
phy_types
==
HOME
)
if
(
phy
->
phy_types
==
HOME
)
phy_home
=
phy
;
phy_home
=
phy
;
else
if
(
phy
->
phy_types
==
LAN
)
else
if
(
phy
->
phy_types
==
LAN
)
phy_lan
=
phy
;
phy_lan
=
phy
;
}
}
}
}
if
(
!
default_phy
&&
phy_home
)
if
(
!
default_phy
&&
phy_home
)
default_phy
=
phy_home
;
default_phy
=
phy_home
;
else
if
(
!
default_phy
&&
phy_lan
)
else
if
(
!
default_phy
&&
phy_lan
)
default_phy
=
phy_lan
;
default_phy
=
phy_lan
;
else
if
(
!
default_phy
)
else
if
(
!
default_phy
)
default_phy
=
sis_priv
->
first_mii
;
default_phy
=
sis_priv
->
first_mii
;
if
(
sis_priv
->
mii
!=
default_phy
)
{
if
(
sis_priv
->
mii
!=
default_phy
)
{
sis_priv
->
mii
=
default_phy
;
sis_priv
->
mii
=
default_phy
;
sis_priv
->
cur_phy
=
default_phy
->
phy_addr
;
sis_priv
->
cur_phy
=
default_phy
->
phy_addr
;
printk
(
KERN_INFO
"%s: Using transceiver found at address %d as default
\n
"
,
net_dev
->
name
,
sis_priv
->
cur_phy
);
printk
(
KERN_INFO
"%s: Using transceiver found at address %d as default
\n
"
,
net_dev
->
name
,
sis_priv
->
cur_phy
);
}
}
status
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_CONTROL
);
status
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_CONTROL
);
...
@@ -701,7 +710,7 @@ static u16 sis900_default_phy(struct net_device * net_dev)
...
@@ -701,7 +710,7 @@ static u16 sis900_default_phy(struct net_device * net_dev)
* mii status register. It's necessary before auto-negotiate.
* mii status register. It's necessary before auto-negotiate.
*/
*/
static
void
sis900_set_capability
(
struct
net_device
*
net_dev
,
struct
mii_phy
*
phy
)
static
void
sis900_set_capability
(
struct
net_device
*
net_dev
,
struct
mii_phy
*
phy
)
{
{
u16
cap
;
u16
cap
;
u16
status
;
u16
status
;
...
@@ -851,7 +860,8 @@ static u16 mdio_read(struct net_device *net_dev, int phy_id, int location)
...
@@ -851,7 +860,8 @@ static u16 mdio_read(struct net_device *net_dev, int phy_id, int location)
* please see SiS7014 or ICS spec
* please see SiS7014 or ICS spec
*/
*/
static
void
mdio_write
(
struct
net_device
*
net_dev
,
int
phy_id
,
int
location
,
int
value
)
static
void
mdio_write
(
struct
net_device
*
net_dev
,
int
phy_id
,
int
location
,
int
value
)
{
{
long
mdio_addr
=
net_dev
->
base_addr
+
mear
;
long
mdio_addr
=
net_dev
->
base_addr
+
mear
;
int
mii_cmd
=
MIIwrite
|
(
phy_id
<<
MIIpmdShift
)
|
(
location
<<
MIIregShift
);
int
mii_cmd
=
MIIwrite
|
(
phy_id
<<
MIIpmdShift
)
|
(
location
<<
MIIregShift
);
...
@@ -939,7 +949,8 @@ sis900_open(struct net_device *net_dev)
...
@@ -939,7 +949,8 @@ sis900_open(struct net_device *net_dev)
pci_read_config_byte
(
sis_priv
->
pci_dev
,
PCI_CLASS_REVISION
,
&
revision
);
pci_read_config_byte
(
sis_priv
->
pci_dev
,
PCI_CLASS_REVISION
,
&
revision
);
sis630_set_eq
(
net_dev
,
revision
);
sis630_set_eq
(
net_dev
,
revision
);
ret
=
request_irq
(
net_dev
->
irq
,
&
sis900_interrupt
,
SA_SHIRQ
,
net_dev
->
name
,
net_dev
);
ret
=
request_irq
(
net_dev
->
irq
,
&
sis900_interrupt
,
SA_SHIRQ
,
net_dev
->
name
,
net_dev
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
...
@@ -1136,48 +1147,55 @@ static void sis630_set_eq(struct net_device *net_dev, u8 revision)
...
@@ -1136,48 +1147,55 @@ static void sis630_set_eq(struct net_device *net_dev, u8 revision)
return
;
return
;
if
(
netif_carrier_ok
(
net_dev
))
{
if
(
netif_carrier_ok
(
net_dev
))
{
reg14h
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
);
reg14h
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
);
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
(
0x2200
|
reg14h
)
&
0xBFFF
);
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
(
0x2200
|
reg14h
)
&
0xBFFF
);
for
(
i
=
0
;
i
<
maxcount
;
i
++
)
{
for
(
i
=
0
;
i
<
maxcount
;
i
++
)
{
eq_value
=
(
0x00F8
&
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
))
>>
3
;
eq_value
=
(
0x00F8
&
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
))
>>
3
;
if
(
i
==
0
)
if
(
i
==
0
)
max_value
=
min_value
=
eq_value
;
max_value
=
min_value
=
eq_value
;
max_value
=
(
eq_value
>
max_value
)
?
eq_value
:
max_value
;
max_value
=
(
eq_value
>
max_value
)
?
min_value
=
(
eq_value
<
min_value
)
?
eq_value
:
min_value
;
eq_value
:
max_value
;
min_value
=
(
eq_value
<
min_value
)
?
eq_value
:
min_value
;
}
}
/* 630E rule to determine the equalizer value */
/* 630E rule to determine the equalizer value */
if
(
revision
==
SIS630E_900_REV
||
revision
==
SIS630EA1_900_REV
||
if
(
revision
==
SIS630E_900_REV
||
revision
==
SIS630EA1_900_REV
||
revision
==
SIS630ET_900_REV
)
{
revision
==
SIS630ET_900_REV
)
{
if
(
max_value
<
5
)
if
(
max_value
<
5
)
eq_value
=
max_value
;
eq_value
=
max_value
;
else
if
(
max_value
>=
5
&&
max_value
<
15
)
else
if
(
max_value
>=
5
&&
max_value
<
15
)
eq_value
=
(
max_value
==
min_value
)
?
max_value
+
2
:
max_value
+
1
;
eq_value
=
(
max_value
==
min_value
)
?
max_value
+
2
:
max_value
+
1
;
else
if
(
max_value
>=
15
)
else
if
(
max_value
>=
15
)
eq_value
=
(
max_value
==
min_value
)
?
max_value
+
6
:
max_value
+
5
;
eq_value
=
(
max_value
==
min_value
)
?
max_value
+
6
:
max_value
+
5
;
}
}
/* 630B0&B1 rule to determine the equalizer value */
/* 630B0&B1 rule to determine the equalizer value */
if
(
revision
==
SIS630A_900_REV
&&
if
(
revision
==
SIS630A_900_REV
&&
(
sis_priv
->
host_bridge_rev
==
SIS630B0
||
(
sis_priv
->
host_bridge_rev
==
SIS630B0
||
sis_priv
->
host_bridge_rev
==
SIS630B1
))
{
sis_priv
->
host_bridge_rev
==
SIS630B1
))
{
if
(
max_value
==
0
)
if
(
max_value
==
0
)
eq_value
=
3
;
eq_value
=
3
;
else
else
eq_value
=
(
max_value
+
min_value
+
1
)
/
2
;
eq_value
=
(
max_value
+
min_value
+
1
)
/
2
;
}
}
/* write equalizer value and setting */
/* write equalizer value and setting */
reg14h
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
);
reg14h
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
);
reg14h
=
(
reg14h
&
0xFF07
)
|
((
eq_value
<<
3
)
&
0x00F8
);
reg14h
=
(
reg14h
&
0xFF07
)
|
((
eq_value
<<
3
)
&
0x00F8
);
reg14h
=
(
reg14h
|
0x6000
)
&
0xFDFF
;
reg14h
=
(
reg14h
|
0x6000
)
&
0xFDFF
;
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
reg14h
);
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
reg14h
);
}
}
else
{
else
{
reg14h
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
);
reg14h
=
mdio_read
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
);
if
(
revision
==
SIS630A_900_REV
&&
if
(
revision
==
SIS630A_900_REV
&&
(
sis_priv
->
host_bridge_rev
==
SIS630B0
||
(
sis_priv
->
host_bridge_rev
==
SIS630B0
||
sis_priv
->
host_bridge_rev
==
SIS630B1
))
sis_priv
->
host_bridge_rev
==
SIS630B1
))
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
(
reg14h
|
0x2200
)
&
0xBFFF
);
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
(
reg14h
|
0x2200
)
&
0xBFFF
);
else
else
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
(
reg14h
|
0x2000
)
&
0xBFFF
);
mdio_write
(
net_dev
,
sis_priv
->
cur_phy
,
MII_RESV
,
(
reg14h
|
0x2000
)
&
0xBFFF
);
}
}
return
;
return
;
}
}
...
@@ -1205,7 +1223,8 @@ static void sis900_timer(unsigned long data)
...
@@ -1205,7 +1223,8 @@ static void sis900_timer(unsigned long data)
sis900_read_mode
(
net_dev
,
&
speed
,
&
duplex
);
sis900_read_mode
(
net_dev
,
&
speed
,
&
duplex
);
if
(
duplex
){
if
(
duplex
){
sis900_set_mode
(
net_dev
->
base_addr
,
speed
,
duplex
);
sis900_set_mode
(
net_dev
->
base_addr
,
speed
,
duplex
);
pci_read_config_byte
(
sis_priv
->
pci_dev
,
PCI_CLASS_REVISION
,
&
revision
);
pci_read_config_byte
(
sis_priv
->
pci_dev
,
PCI_CLASS_REVISION
,
&
revision
);
sis630_set_eq
(
net_dev
,
revision
);
sis630_set_eq
(
net_dev
,
revision
);
netif_start_queue
(
net_dev
);
netif_start_queue
(
net_dev
);
}
}
...
@@ -1229,9 +1248,8 @@ static void sis900_timer(unsigned long data)
...
@@ -1229,9 +1248,8 @@ static void sis900_timer(unsigned long data)
sis900_check_mode
(
net_dev
,
mii_phy
);
sis900_check_mode
(
net_dev
,
mii_phy
);
netif_carrier_on
(
net_dev
);
netif_carrier_on
(
net_dev
);
}
}
}
}
else
{
/* Link ON -> OFF */
/* Link ON -> OFF */
else
{
if
(
!
(
status
&
MII_STAT_LINK
)){
if
(
!
(
status
&
MII_STAT_LINK
)){
netif_carrier_off
(
net_dev
);
netif_carrier_off
(
net_dev
);
printk
(
KERN_INFO
"%s: Media Link Off
\n
"
,
net_dev
->
name
);
printk
(
KERN_INFO
"%s: Media Link Off
\n
"
,
net_dev
->
name
);
...
@@ -1241,7 +1259,8 @@ static void sis900_timer(unsigned long data)
...
@@ -1241,7 +1259,8 @@ static void sis900_timer(unsigned long data)
((
mii_phy
->
phy_id1
&
0xFFF0
)
==
0x8000
))
((
mii_phy
->
phy_id1
&
0xFFF0
)
==
0x8000
))
sis900_reset_phy
(
net_dev
,
sis_priv
->
cur_phy
);
sis900_reset_phy
(
net_dev
,
sis_priv
->
cur_phy
);
pci_read_config_byte
(
sis_priv
->
pci_dev
,
PCI_CLASS_REVISION
,
&
revision
);
pci_read_config_byte
(
sis_priv
->
pci_dev
,
PCI_CLASS_REVISION
,
&
revision
);
sis630_set_eq
(
net_dev
,
revision
);
sis630_set_eq
(
net_dev
,
revision
);
goto
LookForLink
;
goto
LookForLink
;
...
@@ -1264,18 +1283,18 @@ static void sis900_timer(unsigned long data)
...
@@ -1264,18 +1283,18 @@ static void sis900_timer(unsigned long data)
* and autong_complete should be set to 1.
* and autong_complete should be set to 1.
*/
*/
static
void
sis900_check_mode
(
struct
net_device
*
net_dev
,
struct
mii_phy
*
mii_phy
)
static
void
sis900_check_mode
(
struct
net_device
*
net_dev
,
struct
mii_phy
*
mii_phy
)
{
{
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
long
ioaddr
=
net_dev
->
base_addr
;
long
ioaddr
=
net_dev
->
base_addr
;
int
speed
,
duplex
;
int
speed
,
duplex
;
if
(
mii_phy
->
phy_types
==
LAN
)
{
if
(
mii_phy
->
phy_types
==
LAN
)
{
outl
(
~
EXD
&
inl
(
ioaddr
+
cfg
),
ioaddr
+
cfg
);
outl
(
~
EXD
&
inl
(
ioaddr
+
cfg
),
ioaddr
+
cfg
);
sis900_set_capability
(
net_dev
,
mii_phy
);
sis900_set_capability
(
net_dev
,
mii_phy
);
sis900_auto_negotiate
(
net_dev
,
sis_priv
->
cur_phy
);
sis900_auto_negotiate
(
net_dev
,
sis_priv
->
cur_phy
);
}
else
{
}
else
{
outl
(
EXD
|
inl
(
ioaddr
+
cfg
),
ioaddr
+
cfg
);
outl
(
EXD
|
inl
(
ioaddr
+
cfg
),
ioaddr
+
cfg
);
speed
=
HW_SPEED_HOME
;
speed
=
HW_SPEED_HOME
;
duplex
=
FDX_CAPABLE_HALF_SELECTED
;
duplex
=
FDX_CAPABLE_HALF_SELECTED
;
sis900_set_mode
(
ioaddr
,
speed
,
duplex
);
sis900_set_mode
(
ioaddr
,
speed
,
duplex
);
...
@@ -1300,20 +1319,20 @@ static void sis900_set_mode (long ioaddr, int speed, int duplex)
...
@@ -1300,20 +1319,20 @@ static void sis900_set_mode (long ioaddr, int speed, int duplex)
{
{
u32
tx_flags
=
0
,
rx_flags
=
0
;
u32
tx_flags
=
0
,
rx_flags
=
0
;
if
(
inl
(
ioaddr
+
cfg
)
&
EDB_MASTER_EN
){
if
(
inl
(
ioaddr
+
cfg
)
&
EDB_MASTER_EN
)
{
tx_flags
=
TxATP
|
(
DMA_BURST_64
<<
TxMXDMA_shift
)
|
(
TX_FILL_THRESH
<<
TxFILLT_shift
);
tx_flags
=
TxATP
|
(
DMA_BURST_64
<<
TxMXDMA_shift
)
|
(
TX_FILL_THRESH
<<
TxFILLT_shift
);
rx_flags
=
DMA_BURST_64
<<
RxMXDMA_shift
;
rx_flags
=
DMA_BURST_64
<<
RxMXDMA_shift
;
}
}
else
{
else
{
tx_flags
=
TxATP
|
(
DMA_BURST_512
<<
TxMXDMA_shift
)
|
tx_flags
=
TxATP
|
(
DMA_BURST_512
<<
TxMXDMA_shift
)
|
(
TX_FILL_THRESH
<<
TxFILLT_shift
);
(
TX_FILL_THRESH
<<
TxFILLT_shift
);
rx_flags
=
DMA_BURST_512
<<
RxMXDMA_shift
;
rx_flags
=
DMA_BURST_512
<<
RxMXDMA_shift
;
}
}
if
(
speed
==
HW_SPEED_HOME
||
speed
==
HW_SPEED_10_MBPS
)
{
if
(
speed
==
HW_SPEED_HOME
||
speed
==
HW_SPEED_10_MBPS
)
{
rx_flags
|=
(
RxDRNT_10
<<
RxDRNT_shift
);
rx_flags
|=
(
RxDRNT_10
<<
RxDRNT_shift
);
tx_flags
|=
(
TxDRNT_10
<<
TxDRNT_shift
);
tx_flags
|=
(
TxDRNT_10
<<
TxDRNT_shift
);
}
}
else
{
else
{
rx_flags
|=
(
RxDRNT_100
<<
RxDRNT_shift
);
rx_flags
|=
(
RxDRNT_100
<<
RxDRNT_shift
);
tx_flags
|=
(
TxDRNT_100
<<
TxDRNT_shift
);
tx_flags
|=
(
TxDRNT_100
<<
TxDRNT_shift
);
}
}
...
@@ -1403,19 +1422,19 @@ static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex
...
@@ -1403,19 +1422,19 @@ static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex
sis_priv
->
autong_complete
=
1
;
sis_priv
->
autong_complete
=
1
;
/* Workaround for Realtek RTL8201 PHY issue */
/* Workaround for Realtek RTL8201 PHY issue */
if
((
phy
->
phy_id0
==
0x0000
)
&&
((
phy
->
phy_id1
&
0xFFF0
)
==
0x8200
))
{
if
((
phy
->
phy_id0
==
0x0000
)
&&
((
phy
->
phy_id1
&
0xFFF0
)
==
0x8200
))
{
if
(
mdio_read
(
net_dev
,
phy_addr
,
MII_CONTROL
)
&
MII_CNTL_FDX
)
if
(
mdio_read
(
net_dev
,
phy_addr
,
MII_CONTROL
)
&
MII_CNTL_FDX
)
*
duplex
=
FDX_CAPABLE_FULL_SELECTED
;
*
duplex
=
FDX_CAPABLE_FULL_SELECTED
;
if
(
mdio_read
(
net_dev
,
phy_addr
,
0x0019
)
&
0x01
)
if
(
mdio_read
(
net_dev
,
phy_addr
,
0x0019
)
&
0x01
)
*
speed
=
HW_SPEED_100_MBPS
;
*
speed
=
HW_SPEED_100_MBPS
;
}
}
printk
(
KERN_INFO
"%s: Media Link On %s %s-duplex
\n
"
,
printk
(
KERN_INFO
"%s: Media Link On %s %s-duplex
\n
"
,
net_dev
->
name
,
net_dev
->
name
,
*
speed
==
HW_SPEED_100_MBPS
?
*
speed
==
HW_SPEED_100_MBPS
?
"100mbps"
:
"10mbps"
,
"100mbps"
:
"10mbps"
,
*
duplex
==
FDX_CAPABLE_FULL_SELECTED
?
*
duplex
==
FDX_CAPABLE_FULL_SELECTED
?
"full"
:
"half"
);
"full"
:
"half"
);
}
}
/**
/**
...
@@ -1677,13 +1696,13 @@ static int sis900_rx(struct net_device *net_dev)
...
@@ -1677,13 +1696,13 @@ static int sis900_rx(struct net_device *net_dev)
sis_priv
->
stats
.
rx_bytes
+=
rx_size
;
sis_priv
->
stats
.
rx_bytes
+=
rx_size
;
sis_priv
->
stats
.
rx_packets
++
;
sis_priv
->
stats
.
rx_packets
++
;
/* refill the Rx buffer, what if there is not enought
memory for
/* refill the Rx buffer, what if there is not enought
new socket buffer ?? */
* memory for
new socket buffer ?? */
if
((
skb
=
dev_alloc_skb
(
RX_BUF_SIZE
))
==
NULL
)
{
if
((
skb
=
dev_alloc_skb
(
RX_BUF_SIZE
))
==
NULL
)
{
/* not enough memory for skbuff, this makes a
"hole"
/* not enough memory for skbuff, this makes a
on the buffer ring, it is not clear how the
* "hole" on the buffer ring, it is not clear
hardware will react to this kind of degenerate
d
* how the hardware will react to this kin
d
buffer */
* of degenerated
buffer */
printk
(
KERN_INFO
"%s: Memory squeeze,"
printk
(
KERN_INFO
"%s: Memory squeeze,"
"deferring packet.
\n
"
,
"deferring packet.
\n
"
,
net_dev
->
name
);
net_dev
->
name
);
...
@@ -1707,8 +1726,8 @@ static int sis900_rx(struct net_device *net_dev)
...
@@ -1707,8 +1726,8 @@ static int sis900_rx(struct net_device *net_dev)
rx_status
=
sis_priv
->
rx_ring
[
entry
].
cmdsts
;
rx_status
=
sis_priv
->
rx_ring
[
entry
].
cmdsts
;
}
// while
}
// while
/* refill the Rx buffer, what if the rate of refilling is slower
than
/* refill the Rx buffer, what if the rate of refilling is slower
consuming ?? */
* than
consuming ?? */
for
(;
sis_priv
->
cur_rx
-
sis_priv
->
dirty_rx
>
0
;
sis_priv
->
dirty_rx
++
)
{
for
(;
sis_priv
->
cur_rx
-
sis_priv
->
dirty_rx
>
0
;
sis_priv
->
dirty_rx
++
)
{
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
...
@@ -1716,10 +1735,10 @@ static int sis900_rx(struct net_device *net_dev)
...
@@ -1716,10 +1735,10 @@ static int sis900_rx(struct net_device *net_dev)
if
(
sis_priv
->
rx_skbuff
[
entry
]
==
NULL
)
{
if
(
sis_priv
->
rx_skbuff
[
entry
]
==
NULL
)
{
if
((
skb
=
dev_alloc_skb
(
RX_BUF_SIZE
))
==
NULL
)
{
if
((
skb
=
dev_alloc_skb
(
RX_BUF_SIZE
))
==
NULL
)
{
/* not enough memory for skbuff, this makes a
"hole"
/* not enough memory for skbuff, this makes a
on the buffer ring, it is not clear how the
* "hole" on the buffer ring, it is not clear
hardware will react to this kind of degenerated
* how the hardware will react to this kind
buffer */
* of degenerated
buffer */
printk
(
KERN_INFO
"%s: Memory squeeze,"
printk
(
KERN_INFO
"%s: Memory squeeze,"
"deferring packet.
\n
"
,
"deferring packet.
\n
"
,
net_dev
->
name
);
net_dev
->
name
);
...
@@ -1764,8 +1783,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
...
@@ -1764,8 +1783,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
if
(
tx_status
&
OWN
)
{
if
(
tx_status
&
OWN
)
{
/* The packet is not transmitted yet (owned by hardware) !
/* The packet is not transmitted yet (owned by hardware) !
Note: the interrupt is generated only when Tx Machine
*
Note: the interrupt is generated only when Tx Machine
is idle, so this is an almost impossible case */
*
is idle, so this is an almost impossible case */
break
;
break
;
}
}
...
@@ -1803,8 +1822,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
...
@@ -1803,8 +1822,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
if
(
sis_priv
->
tx_full
&&
netif_queue_stopped
(
net_dev
)
&&
if
(
sis_priv
->
tx_full
&&
netif_queue_stopped
(
net_dev
)
&&
sis_priv
->
cur_tx
-
sis_priv
->
dirty_tx
<
NUM_TX_DESC
-
4
)
{
sis_priv
->
cur_tx
-
sis_priv
->
dirty_tx
<
NUM_TX_DESC
-
4
)
{
/* The ring is no longer full, clear tx_full and schedule
more transmission
/* The ring is no longer full, clear tx_full and schedule
by netif_wake_queue(net_dev) */
* more transmission
by netif_wake_queue(net_dev) */
sis_priv
->
tx_full
=
0
;
sis_priv
->
tx_full
=
0
;
netif_wake_queue
(
net_dev
);
netif_wake_queue
(
net_dev
);
}
}
...
@@ -1818,8 +1837,7 @@ static void sis900_finish_xmit (struct net_device *net_dev)
...
@@ -1818,8 +1837,7 @@ static void sis900_finish_xmit (struct net_device *net_dev)
* free Tx and RX socket buffer
* free Tx and RX socket buffer
*/
*/
static
int
static
int
sis900_close
(
struct
net_device
*
net_dev
)
sis900_close
(
struct
net_device
*
net_dev
)
{
{
long
ioaddr
=
net_dev
->
base_addr
;
long
ioaddr
=
net_dev
->
base_addr
;
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
...
@@ -1955,27 +1973,28 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
...
@@ -1955,27 +1973,28 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
if
((
map
->
port
!=
(
u_char
)(
-
1
))
&&
(
map
->
port
!=
dev
->
if_port
))
{
if
((
map
->
port
!=
(
u_char
)(
-
1
))
&&
(
map
->
port
!=
dev
->
if_port
))
{
/* we switch on the ifmap->port field. I couldn't find anything
/* we switch on the ifmap->port field. I couldn't find anything
like a definition or standard for the values of that field.
* like a definition or standard for the values of that field.
I think the meaning of those values is device specific. But
* I think the meaning of those values is device specific. But
since I would like to change the media type via the ifconfig
* since I would like to change the media type via the ifconfig
command I use the definition from linux/netdevice.h
* command I use the definition from linux/netdevice.h
(which seems to be different from the ifport(pcmcia) definition)
* (which seems to be different from the ifport(pcmcia) definition) */
*/
switch
(
map
->
port
){
switch
(
map
->
port
){
case
IF_PORT_UNKNOWN
:
/* use auto here */
case
IF_PORT_UNKNOWN
:
/* use auto here */
dev
->
if_port
=
map
->
port
;
dev
->
if_port
=
map
->
port
;
/* we are going to change the media type, so the Link will
/* we are going to change the media type, so the Link
be temporary down and we need to reflect that here. When
* will be temporary down and we need to reflect that
the Link comes up again, it will be sensed by the sis_timer
* here. When the Link comes up again, it will be
procedure, which also does all the rest for us */
* sensed by the sis_timer procedure, which also does
* all the rest for us */
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
/* read current state */
/* read current state */
status
=
mdio_read
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
);
status
=
mdio_read
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
);
/* enable auto negotiation and reset the negotioation
/* enable auto negotiation and reset the negotioation
(I don't really know what the auto negatiotiation reset
* (I don't really know what the auto negatiotiation
really means, but it sounds for me right to do one here)*/
* reset really means, but it sounds for me right to
* do one here) */
mdio_write
(
dev
,
mii_phy
->
phy_addr
,
mdio_write
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
,
status
|
MII_CNTL_AUTO
|
MII_CNTL_RST_AUTO
);
MII_CONTROL
,
status
|
MII_CNTL_AUTO
|
MII_CNTL_RST_AUTO
);
...
@@ -1984,10 +2003,11 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
...
@@ -1984,10 +2003,11 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
case
IF_PORT_10BASET
:
/* 10BaseT */
case
IF_PORT_10BASET
:
/* 10BaseT */
dev
->
if_port
=
map
->
port
;
dev
->
if_port
=
map
->
port
;
/* we are going to change the media type, so the Link will
/* we are going to change the media type, so the Link
be temporary down and we need to reflect that here. When
* will be temporary down and we need to reflect that
the Link comes up again, it will be sensed by the sis_timer
* here. When the Link comes up again, it will be
procedure, which also does all the rest for us */
* sensed by the sis_timer procedure, which also does
* all the rest for us */
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
/* set Speed to 10Mbps */
/* set Speed to 10Mbps */
...
@@ -1996,24 +2016,27 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
...
@@ -1996,24 +2016,27 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
/* disable auto negotiation and force 10MBit mode*/
/* disable auto negotiation and force 10MBit mode*/
mdio_write
(
dev
,
mii_phy
->
phy_addr
,
mdio_write
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
,
status
&
~
(
MII_CNTL_SPEED
|
MII_CNTL_AUTO
));
MII_CONTROL
,
status
&
~
(
MII_CNTL_SPEED
|
MII_CNTL_AUTO
));
break
;
break
;
case
IF_PORT_100BASET
:
/* 100BaseT */
case
IF_PORT_100BASET
:
/* 100BaseT */
case
IF_PORT_100BASETX
:
/* 100BaseTx */
case
IF_PORT_100BASETX
:
/* 100BaseTx */
dev
->
if_port
=
map
->
port
;
dev
->
if_port
=
map
->
port
;
/* we are going to change the media type, so the Link will
/* we are going to change the media type, so the Link
be temporary down and we need to reflect that here. When
* will be temporary down and we need to reflect that
the Link comes up again, it will be sensed by the sis_timer
* here. When the Link comes up again, it will be
procedure, which also does all the rest for us */
* sensed by the sis_timer procedure, which also does
* all the rest for us */
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
/* set Speed to 100Mbps */
/* set Speed to 100Mbps */
/* disable auto negotiation and enable 100MBit Mode */
/* disable auto negotiation and enable 100MBit Mode */
status
=
mdio_read
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
);
status
=
mdio_read
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
);
mdio_write
(
dev
,
mii_phy
->
phy_addr
,
mdio_write
(
dev
,
mii_phy
->
phy_addr
,
MII_CONTROL
,
(
status
&
~
MII_CNTL_SPEED
)
|
MII_CNTL_SPEED
);
MII_CONTROL
,
(
status
&
~
MII_CNTL_SPEED
)
|
MII_CNTL_SPEED
);
break
;
break
;
...
@@ -2093,12 +2116,14 @@ static void set_rx_mode(struct net_device *net_dev)
...
@@ -2093,12 +2116,14 @@ static void set_rx_mode(struct net_device *net_dev)
for
(
i
=
0
;
i
<
table_entries
;
i
++
)
for
(
i
=
0
;
i
<
table_entries
;
i
++
)
mc_filter
[
i
]
=
0xffff
;
mc_filter
[
i
]
=
0xffff
;
}
else
{
}
else
{
/* Accept Broadcast packet, destination address matchs our MAC address,
/* Accept Broadcast packet, destination address matchs our
use Receive Filter to reject unwanted MCAST packet */
* MAC address, use Receive Filter to reject unwanted MCAST
* packets */
struct
dev_mc_list
*
mclist
;
struct
dev_mc_list
*
mclist
;
rx_mode
=
RFAAB
;
rx_mode
=
RFAAB
;
for
(
i
=
0
,
mclist
=
net_dev
->
mc_list
;
mclist
&&
i
<
net_dev
->
mc_count
;
for
(
i
=
0
,
mclist
=
net_dev
->
mc_list
;
i
++
,
mclist
=
mclist
->
next
)
{
mclist
&&
i
<
net_dev
->
mc_count
;
i
++
,
mclist
=
mclist
->
next
)
{
unsigned
int
bit_nr
=
unsigned
int
bit_nr
=
sis900_mcast_bitnr
(
mclist
->
dmi_addr
,
revision
);
sis900_mcast_bitnr
(
mclist
->
dmi_addr
,
revision
);
mc_filter
[
bit_nr
>>
4
]
|=
(
1
<<
(
bit_nr
&
0xf
));
mc_filter
[
bit_nr
>>
4
]
|=
(
1
<<
(
bit_nr
&
0xf
));
...
@@ -2114,7 +2139,8 @@ static void set_rx_mode(struct net_device *net_dev)
...
@@ -2114,7 +2139,8 @@ static void set_rx_mode(struct net_device *net_dev)
outl
(
RFEN
|
rx_mode
,
ioaddr
+
rfcr
);
outl
(
RFEN
|
rx_mode
,
ioaddr
+
rfcr
);
/* sis900 is capatable of looping back packet at MAC level for debugging purpose */
/* sis900 is capable of looping back packets at MAC level for
* debugging purpose */
if
(
net_dev
->
flags
&
IFF_LOOPBACK
)
{
if
(
net_dev
->
flags
&
IFF_LOOPBACK
)
{
u32
cr_saved
;
u32
cr_saved
;
/* We must disable Tx/Rx before setting loopback mode */
/* We must disable Tx/Rx before setting loopback mode */
...
...
drivers/net/smc91x.c
View file @
74f54248
...
@@ -55,12 +55,10 @@
...
@@ -55,12 +55,10 @@
* smc_phy_configure
* smc_phy_configure
* - clean up (and fix stack overrun) in PHY
* - clean up (and fix stack overrun) in PHY
* MII read/write functions
* MII read/write functions
* 09/15/04 Hayato Fujiwara - Add m32r support.
* 22/09/04 Nicolas Pitre big update (see commit log for details)
* - Modify for SMP kernel; Change spin-locked
* regions.
*/
*/
static
const
char
version
[]
=
static
const
char
version
[]
=
"smc91x.c: v1.
0, mar 07 2003
by Nicolas Pitre <nico@cam.org>
\n
"
;
"smc91x.c: v1.
1, sep 22 2004
by Nicolas Pitre <nico@cam.org>
\n
"
;
/* Debugging level */
/* Debugging level */
#ifndef SMC_DEBUG
#ifndef SMC_DEBUG
...
@@ -75,7 +73,7 @@ static const char version[] =
...
@@ -75,7 +73,7 @@ static const char version[] =
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/
timer
.h>
#include <linux/
interrupt
.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/crc32.h>
#include <linux/crc32.h>
...
@@ -83,6 +81,7 @@ static const char version[] =
...
@@ -83,6 +81,7 @@ static const char version[] =
#include <linux/spinlock.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/mii.h>
#include <linux/workqueue.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
...
@@ -177,7 +176,8 @@ struct smc_local {
...
@@ -177,7 +176,8 @@ struct smc_local {
* packet, I will store the skbuff here, until I get the
* packet, I will store the skbuff here, until I get the
* desired memory. Then, I'll send it out and free it.
* desired memory. Then, I'll send it out and free it.
*/
*/
struct
sk_buff
*
saved_skb
;
struct
sk_buff
*
pending_tx_skb
;
struct
tasklet_struct
tx_task
;
/*
/*
* these are things that the kernel wants me to keep, so users
* these are things that the kernel wants me to keep, so users
...
@@ -203,6 +203,8 @@ struct smc_local {
...
@@ -203,6 +203,8 @@ struct smc_local {
u32
msg_enable
;
u32
msg_enable
;
u32
phy_type
;
u32
phy_type
;
struct
mii_if_info
mii
;
struct
mii_if_info
mii
;
struct
work_struct
phy_configure
;
spinlock_t
lock
;
spinlock_t
lock
;
#ifdef SMC_USE_PXA_DMA
#ifdef SMC_USE_PXA_DMA
...
@@ -215,7 +217,7 @@ struct smc_local {
...
@@ -215,7 +217,7 @@ struct smc_local {
#define DBG(n, args...) \
#define DBG(n, args...) \
do { \
do { \
if (SMC_DEBUG >= (n)) \
if (SMC_DEBUG >= (n)) \
printk(
KERN_DEBUG
args); \
printk(args); \
} while (0)
} while (0)
#define PRINTK(args...) printk(args)
#define PRINTK(args...) printk(args)
...
@@ -260,17 +262,21 @@ static void PRINT_PKT(u_char *buf, int length)
...
@@ -260,17 +262,21 @@ static void PRINT_PKT(u_char *buf, int length)
/* this enables an interrupt in the interrupt mask register */
/* this enables an interrupt in the interrupt mask register */
#define SMC_ENABLE_INT(x) do { \
#define SMC_ENABLE_INT(x) do { \
unsigned char mask; \
unsigned char mask; \
spin_lock_irq(&lp->lock); \
mask = SMC_GET_INT_MASK(); \
mask = SMC_GET_INT_MASK(); \
mask |= (x); \
mask |= (x); \
SMC_SET_INT_MASK(mask); \
SMC_SET_INT_MASK(mask); \
spin_unlock_irq(&lp->lock); \
} while (0)
} while (0)
/* this disables an interrupt from the interrupt mask register */
/* this disables an interrupt from the interrupt mask register */
#define SMC_DISABLE_INT(x) do { \
#define SMC_DISABLE_INT(x) do { \
unsigned char mask; \
unsigned char mask; \
spin_lock_irq(&lp->lock); \
mask = SMC_GET_INT_MASK(); \
mask = SMC_GET_INT_MASK(); \
mask &= ~(x); \
mask &= ~(x); \
SMC_SET_INT_MASK(mask); \
SMC_SET_INT_MASK(mask); \
spin_unlock_irq(&lp->lock); \
} while (0)
} while (0)
/*
/*
...
@@ -299,10 +305,17 @@ static void PRINT_PKT(u_char *buf, int length)
...
@@ -299,10 +305,17 @@ static void PRINT_PKT(u_char *buf, int length)
static
void
smc_reset
(
struct
net_device
*
dev
)
static
void
smc_reset
(
struct
net_device
*
dev
)
{
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
int
ctl
,
cfg
;
unsigned
int
ctl
,
cfg
;
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
/* Disable all interrupts */
spin_lock
(
&
lp
->
lock
);
SMC_SELECT_BANK
(
2
);
SMC_SET_INT_MASK
(
0
);
spin_unlock
(
&
lp
->
lock
);
/*
/*
* This resets the registers mostly to defaults, but doesn't
* This resets the registers mostly to defaults, but doesn't
* affect EEPROM. That seems unnecessary
* affect EEPROM. That seems unnecessary
...
@@ -358,20 +371,24 @@ static void smc_reset(struct net_device *dev)
...
@@ -358,20 +371,24 @@ static void smc_reset(struct net_device *dev)
* transmitted packets, to make the best use out of our limited
* transmitted packets, to make the best use out of our limited
* memory
* memory
*/
*/
#if ! THROTTLE_TX_PKTS
if
(
!
THROTTLE_TX_PKTS
)
ctl
|=
CTL_AUTO_RELEASE
;
ctl
|=
CTL_AUTO_RELEASE
;
#else
else
ctl
&=
~
CTL_AUTO_RELEASE
;
ctl
&=
~
CTL_AUTO_RELEASE
;
#endif
SMC_SET_CTL
(
ctl
);
SMC_SET_CTL
(
ctl
);
/* Disable all interrupts */
SMC_SELECT_BANK
(
2
);
SMC_SET_INT_MASK
(
0
);
/* Reset the MMU */
/* Reset the MMU */
SMC_SELECT_BANK
(
2
);
SMC_SET_MMU_CMD
(
MC_RESET
);
SMC_SET_MMU_CMD
(
MC_RESET
);
SMC_WAIT_MMU_BUSY
();
SMC_WAIT_MMU_BUSY
();
/* clear anything saved */
if
(
lp
->
pending_tx_skb
!=
NULL
)
{
dev_kfree_skb
(
lp
->
pending_tx_skb
);
lp
->
pending_tx_skb
=
NULL
;
lp
->
stats
.
tx_errors
++
;
lp
->
stats
.
tx_aborted_errors
++
;
}
}
}
/*
/*
...
@@ -390,24 +407,39 @@ static void smc_enable(struct net_device *dev)
...
@@ -390,24 +407,39 @@ static void smc_enable(struct net_device *dev)
SMC_SET_TCR
(
lp
->
tcr_cur_mode
);
SMC_SET_TCR
(
lp
->
tcr_cur_mode
);
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
SMC_SELECT_BANK
(
1
);
SMC_SET_MAC_ADDR
(
dev
->
dev_addr
);
/* now, enable interrupts */
/* now, enable interrupts */
mask
=
IM_EPH_INT
|
IM_RX_OVRN_INT
|
IM_RCV_INT
;
mask
=
IM_EPH_INT
|
IM_RX_OVRN_INT
|
IM_RCV_INT
;
if
(
lp
->
version
>=
(
CHIP_91100
<<
4
))
if
(
lp
->
version
>=
(
CHIP_91100
<<
4
))
mask
|=
IM_MDINT
;
mask
|=
IM_MDINT
;
SMC_SELECT_BANK
(
2
);
SMC_SELECT_BANK
(
2
);
SMC_SET_INT_MASK
(
mask
);
SMC_SET_INT_MASK
(
mask
);
/*
* From this point the register bank must _NOT_ be switched away
* to something else than bank 2 without proper locking against
* races with any tasklet or interrupt handlers until smc_shutdown()
* or smc_reset() is called.
*/
}
}
/*
/*
* this puts the device in an inactive state
* this puts the device in an inactive state
*/
*/
static
void
smc_shutdown
(
unsigned
long
ioaddr
)
static
void
smc_shutdown
(
struct
net_device
*
dev
)
{
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
DBG
(
2
,
"%s: %s
\n
"
,
CARDNAME
,
__FUNCTION__
);
DBG
(
2
,
"%s: %s
\n
"
,
CARDNAME
,
__FUNCTION__
);
/* no more interrupts for me */
/* no more interrupts for me */
spin_lock
(
&
lp
->
lock
);
SMC_SELECT_BANK
(
2
);
SMC_SELECT_BANK
(
2
);
SMC_SET_INT_MASK
(
0
);
SMC_SET_INT_MASK
(
0
);
spin_unlock
(
&
lp
->
lock
);
/* and tell the card to stay away from that nasty outside world */
/* and tell the card to stay away from that nasty outside world */
SMC_SELECT_BANK
(
0
);
SMC_SELECT_BANK
(
0
);
...
@@ -449,6 +481,8 @@ static inline void smc_rcv(struct net_device *dev)
...
@@ -449,6 +481,8 @@ static inline void smc_rcv(struct net_device *dev)
packet_len
,
packet_len
);
packet_len
,
packet_len
);
if
(
unlikely
(
status
&
RS_ERRORS
))
{
if
(
unlikely
(
status
&
RS_ERRORS
))
{
SMC_WAIT_MMU_BUSY
();
SMC_SET_MMU_CMD
(
MC_RELEASE
);
lp
->
stats
.
rx_errors
++
;
lp
->
stats
.
rx_errors
++
;
if
(
status
&
RS_ALGNERR
)
if
(
status
&
RS_ALGNERR
)
lp
->
stats
.
rx_frame_errors
++
;
lp
->
stats
.
rx_frame_errors
++
;
...
@@ -466,17 +500,21 @@ static inline void smc_rcv(struct net_device *dev)
...
@@ -466,17 +500,21 @@ static inline void smc_rcv(struct net_device *dev)
lp
->
stats
.
multicast
++
;
lp
->
stats
.
multicast
++
;
/*
/*
* Actual payload is packet_len -
4 (or 3
if odd byte).
* Actual payload is packet_len -
6 (or 5
if odd byte).
* We want skb_reserve(2) and the final ctrl word
* We want skb_reserve(2) and the final ctrl word
* (2 bytes, possibly containing the payload odd byte).
* (2 bytes, possibly containing the payload odd byte).
* Ence packet_len - 4 + 2 + 2.
* Furthermore, we add 2 bytes to allow rounding up to
* multiple of 4 bytes on 32 bit buses.
* Ence packet_len - 6 + 2 + 2 + 2.
*/
*/
skb
=
dev_alloc_skb
(
packet_len
);
skb
=
dev_alloc_skb
(
packet_len
);
if
(
unlikely
(
skb
==
NULL
))
{
if
(
unlikely
(
skb
==
NULL
))
{
printk
(
KERN_NOTICE
"%s: Low memory, packet dropped.
\n
"
,
printk
(
KERN_NOTICE
"%s: Low memory, packet dropped.
\n
"
,
dev
->
name
);
dev
->
name
);
SMC_WAIT_MMU_BUSY
();
SMC_SET_MMU_CMD
(
MC_RELEASE
);
lp
->
stats
.
rx_dropped
++
;
lp
->
stats
.
rx_dropped
++
;
goto
done
;
return
;
}
}
/* Align IP header to 32 bits */
/* Align IP header to 32 bits */
...
@@ -487,14 +525,18 @@ static inline void smc_rcv(struct net_device *dev)
...
@@ -487,14 +525,18 @@ static inline void smc_rcv(struct net_device *dev)
status
|=
RS_ODDFRAME
;
status
|=
RS_ODDFRAME
;
/*
/*
* If odd length: packet_len - 3,
* If odd length: packet_len - 5,
* otherwise packet_len - 4.
* otherwise packet_len - 6.
* With the trailing ctrl byte it's packet_len - 4.
*/
*/
data_len
=
packet_len
-
((
status
&
RS_ODDFRAME
)
?
3
:
4
);
data_len
=
packet_len
-
((
status
&
RS_ODDFRAME
)
?
5
:
6
);
data
=
skb_put
(
skb
,
data_len
);
data
=
skb_put
(
skb
,
data_len
);
SMC_PULL_DATA
(
data
,
packet_len
-
2
);
SMC_PULL_DATA
(
data
,
packet_len
-
4
);
SMC_WAIT_MMU_BUSY
();
SMC_SET_MMU_CMD
(
MC_RELEASE
);
PRINT_PKT
(
data
,
packet_len
-
2
);
PRINT_PKT
(
data
,
packet_len
-
4
);
dev
->
last_rx
=
jiffies
;
dev
->
last_rx
=
jiffies
;
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
...
@@ -503,34 +545,76 @@ static inline void smc_rcv(struct net_device *dev)
...
@@ -503,34 +545,76 @@ static inline void smc_rcv(struct net_device *dev)
lp
->
stats
.
rx_packets
++
;
lp
->
stats
.
rx_packets
++
;
lp
->
stats
.
rx_bytes
+=
data_len
;
lp
->
stats
.
rx_bytes
+=
data_len
;
}
}
done:
SMC_WAIT_MMU_BUSY
();
SMC_SET_MMU_CMD
(
MC_RELEASE
);
}
}
#ifdef CONFIG_SMP
/*
* On SMP we have the following problem:
*
* A = smc_hardware_send_pkt()
* B = smc_hard_start_xmit()
* C = smc_interrupt()
*
* A and B can never be executed simultaneously. However, at least on UP,
* it is possible (and even desirable) for C to interrupt execution of
* A or B in order to have better RX reliability and avoid overruns.
* C, just like A and B, must have exclusive access to the chip and
* each of them must lock against any other concurrent access.
* Unfortunately this is not possible to have C suspend execution of A or
* B taking place on another CPU. On UP this is no an issue since A and B
* are run from softirq context and C from hard IRQ context, and there is
* no other CPU where concurrent access can happen.
* If ever there is a way to force at least B and C to always be executed
* on the same CPU then we could use read/write locks to protect against
* any other concurrent access and C would always interrupt B. But life
* isn't that easy in a SMP world...
*/
#define smc_special_trylock(lock) \
({ \
int __ret; \
local_irq_disable(); \
__ret = spin_trylock(lock); \
if (!__ret) \
local_irq_enable(); \
__ret; \
})
#define smc_special_lock(lock) spin_lock_irq(lock)
#define smc_special_unlock(lock) spin_unlock_irq(lock)
#else
#define smc_special_trylock(lock) (1)
#define smc_special_lock(lock) do { } while (0)
#define smc_special_unlock(lock) do { } while (0)
#endif
/*
/*
* This is called to actually send a packet to the chip.
* This is called to actually send a packet to the chip.
* Returns non-zero when successful.
*/
*/
static
void
smc_hardware_send_p
acket
(
struct
net_device
*
dev
)
static
void
smc_hardware_send_p
kt
(
unsigned
long
data
)
{
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
data
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
sk_buff
*
skb
=
lp
->
saved_skb
;
struct
sk_buff
*
skb
;
unsigned
int
packet_no
,
len
;
unsigned
int
packet_no
,
len
;
unsigned
char
*
buf
;
unsigned
char
*
buf
;
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
if
(
!
smc_special_trylock
(
&
lp
->
lock
))
{
netif_stop_queue
(
dev
);
tasklet_schedule
(
&
lp
->
tx_task
);
return
;
}
skb
=
lp
->
pending_tx_skb
;
lp
->
pending_tx_skb
=
NULL
;
packet_no
=
SMC_GET_AR
();
packet_no
=
SMC_GET_AR
();
if
(
unlikely
(
packet_no
&
AR_FAILED
))
{
if
(
unlikely
(
packet_no
&
AR_FAILED
))
{
printk
(
"%s: Memory allocation failed.
\n
"
,
dev
->
name
);
printk
(
"%s: Memory allocation failed.
\n
"
,
dev
->
name
);
lp
->
saved_skb
=
NULL
;
lp
->
stats
.
tx_errors
++
;
lp
->
stats
.
tx_errors
++
;
lp
->
stats
.
tx_fifo_errors
++
;
lp
->
stats
.
tx_fifo_errors
++
;
dev_kfree_skb_any
(
skb
);
smc_special_unlock
(
&
lp
->
lock
);
return
;
goto
done
;
}
}
/* point to the beginning of the packet */
/* point to the beginning of the packet */
...
@@ -555,15 +639,33 @@ static void smc_hardware_send_packet(struct net_device *dev)
...
@@ -555,15 +639,33 @@ static void smc_hardware_send_packet(struct net_device *dev)
/* Send final ctl word with the last byte if there is one */
/* Send final ctl word with the last byte if there is one */
SMC_outw
(((
len
&
1
)
?
(
0x2000
|
buf
[
len
-
1
])
:
0
),
ioaddr
,
DATA_REG
);
SMC_outw
(((
len
&
1
)
?
(
0x2000
|
buf
[
len
-
1
])
:
0
),
ioaddr
,
DATA_REG
);
/* and let the chipset deal with it */
/*
* If THROTTLE_TX_PKTS is set, we look at the TX_EMPTY flag
* before queueing this packet for TX, and if it's clear then
* we stop the queue here. This will have the effect of
* having at most 2 packets queued for TX in the chip's memory
* at all time. If THROTTLE_TX_PKTS is not set then the queue
* is stopped only when memory allocation (MC_ALLOC) does not
* succeed right away.
*/
if
(
THROTTLE_TX_PKTS
&&
!
(
SMC_GET_INT
()
&
IM_TX_EMPTY_INT
))
netif_stop_queue
(
dev
);
/* queue the packet for TX */
SMC_SET_MMU_CMD
(
MC_ENQUEUE
);
SMC_SET_MMU_CMD
(
MC_ENQUEUE
);
SMC_ACK_INT
(
IM_TX_EMPTY_INT
);
SMC_ACK_INT
(
IM_TX_EMPTY_INT
);
smc_special_unlock
(
&
lp
->
lock
);
dev
->
trans_start
=
jiffies
;
dev
->
trans_start
=
jiffies
;
dev_kfree_skb_any
(
skb
);
lp
->
saved_skb
=
NULL
;
lp
->
stats
.
tx_packets
++
;
lp
->
stats
.
tx_packets
++
;
lp
->
stats
.
tx_bytes
+=
len
;
lp
->
stats
.
tx_bytes
+=
len
;
SMC_ENABLE_INT
(
IM_TX_INT
|
IM_TX_EMPTY_INT
);
done:
if
(
!
THROTTLE_TX_PKTS
)
netif_wake_queue
(
dev
);
dev_kfree_skb
(
skb
);
}
}
/*
/*
...
@@ -576,15 +678,12 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -576,15 +678,12 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
int
numPages
,
poll_count
,
status
,
saved_bank
;
unsigned
int
numPages
,
poll_count
,
status
;
unsigned
long
flags
;
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
BUG_ON
(
lp
->
pending_tx_skb
!=
NULL
);
lp
->
pending_tx_skb
=
skb
;
BUG_ON
(
lp
->
saved_skb
!=
NULL
);
lp
->
saved_skb
=
skb
;
/*
/*
* The MMU wants the number of pages to be the number of 256 bytes
* The MMU wants the number of pages to be the number of 256 bytes
...
@@ -600,17 +699,16 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -600,17 +699,16 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
numPages
=
((
skb
->
len
&
~
1
)
+
(
6
-
1
))
>>
8
;
numPages
=
((
skb
->
len
&
~
1
)
+
(
6
-
1
))
>>
8
;
if
(
unlikely
(
numPages
>
7
))
{
if
(
unlikely
(
numPages
>
7
))
{
printk
(
"%s: Far too big packet error.
\n
"
,
dev
->
name
);
printk
(
"%s: Far too big packet error.
\n
"
,
dev
->
name
);
lp
->
saved
_skb
=
NULL
;
lp
->
pending_tx
_skb
=
NULL
;
lp
->
stats
.
tx_errors
++
;
lp
->
stats
.
tx_errors
++
;
lp
->
stats
.
tx_dropped
++
;
lp
->
stats
.
tx_dropped
++
;
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
return
0
;
return
0
;
}
}
smc_special_lock
(
&
lp
->
lock
);
/* now, try to allocate the memory */
/* now, try to allocate the memory */
saved_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
2
);
SMC_SET_MMU_CMD
(
MC_ALLOC
|
numPages
);
SMC_SET_MMU_CMD
(
MC_ALLOC
|
numPages
);
/*
/*
...
@@ -626,6 +724,8 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -626,6 +724,8 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
}
while
(
--
poll_count
);
}
while
(
--
poll_count
);
smc_special_unlock
(
&
lp
->
lock
);
if
(
!
poll_count
)
{
if
(
!
poll_count
)
{
/* oh well, wait until the chip finds memory later */
/* oh well, wait until the chip finds memory later */
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
...
@@ -635,25 +735,10 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -635,25 +735,10 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
/*
/*
* Allocation succeeded: push packet to the chip's own memory
* Allocation succeeded: push packet to the chip's own memory
* immediately.
* immediately.
*
* If THROTTLE_TX_PKTS is selected that means we don't want
* more than a single TX packet taking up space in the chip's
* internal memory at all time, in which case we stop the
* queue right here until we're notified of TX completion.
*
* Otherwise we're quite happy to feed more TX packets right
* away for better TX throughput, in which case the queue is
* left active.
*/
*/
#if THROTTLE_TX_PKTS
smc_hardware_send_pkt
((
unsigned
long
)
dev
);
netif_stop_queue
(
dev
);
#endif
smc_hardware_send_packet
(
dev
);
SMC_ENABLE_INT
(
IM_TX_INT
|
IM_TX_EMPTY_INT
);
}
}
SMC_SELECT_BANK
(
saved_bank
);
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
return
0
;
return
0
;
}
}
...
@@ -767,10 +852,8 @@ static unsigned int smc_mii_in(struct net_device *dev, int bits)
...
@@ -767,10 +852,8 @@ static unsigned int smc_mii_in(struct net_device *dev, int bits)
static
int
smc_phy_read
(
struct
net_device
*
dev
,
int
phyaddr
,
int
phyreg
)
static
int
smc_phy_read
(
struct
net_device
*
dev
,
int
phyaddr
,
int
phyreg
)
{
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
int
phydata
,
old_bank
;
unsigned
int
phydata
;
/* Save the current bank, and select bank 3 */
old_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
3
);
SMC_SELECT_BANK
(
3
);
/* Idle - 32 ones */
/* Idle - 32 ones */
...
@@ -785,12 +868,10 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
...
@@ -785,12 +868,10 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
/* Return to idle state */
/* Return to idle state */
SMC_SET_MII
(
SMC_GET_MII
()
&
~
(
MII_MCLK
|
MII_MDOE
|
MII_MDO
));
SMC_SET_MII
(
SMC_GET_MII
()
&
~
(
MII_MCLK
|
MII_MDOE
|
MII_MDO
));
/* And select original bank */
SMC_SELECT_BANK
(
old_bank
);
DBG
(
3
,
"%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x
\n
"
,
DBG
(
3
,
"%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x
\n
"
,
__FUNCTION__
,
phyaddr
,
phyreg
,
phydata
);
__FUNCTION__
,
phyaddr
,
phyreg
,
phydata
);
SMC_SELECT_BANK
(
2
);
return
phydata
;
return
phydata
;
}
}
...
@@ -801,10 +882,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
...
@@ -801,10 +882,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
int
phydata
)
int
phydata
)
{
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
int
old_bank
;
/* Save the current bank, and select bank 3 */
old_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
3
);
SMC_SELECT_BANK
(
3
);
/* Idle - 32 ones */
/* Idle - 32 ones */
...
@@ -816,11 +894,10 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
...
@@ -816,11 +894,10 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
/* Return to idle state */
/* Return to idle state */
SMC_SET_MII
(
SMC_GET_MII
()
&
~
(
MII_MCLK
|
MII_MDOE
|
MII_MDO
));
SMC_SET_MII
(
SMC_GET_MII
()
&
~
(
MII_MCLK
|
MII_MDOE
|
MII_MDO
));
/* And select original bank */
SMC_SELECT_BANK
(
old_bank
);
DBG
(
3
,
"%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x
\n
"
,
DBG
(
3
,
"%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x
\n
"
,
__FUNCTION__
,
phyaddr
,
phyreg
,
phydata
);
__FUNCTION__
,
phyaddr
,
phyreg
,
phydata
);
SMC_SELECT_BANK
(
2
);
}
}
/*
/*
...
@@ -893,7 +970,9 @@ static int smc_phy_fixed(struct net_device *dev)
...
@@ -893,7 +970,9 @@ static int smc_phy_fixed(struct net_device *dev)
smc_phy_write
(
dev
,
phyaddr
,
MII_BMCR
,
bmcr
);
smc_phy_write
(
dev
,
phyaddr
,
MII_BMCR
,
bmcr
);
/* Re-Configure the Receive/Phy Control register */
/* Re-Configure the Receive/Phy Control register */
SMC_SELECT_BANK
(
0
);
SMC_SET_RPC
(
lp
->
rpc_cur_mode
);
SMC_SET_RPC
(
lp
->
rpc_cur_mode
);
SMC_SELECT_BANK
(
2
);
return
1
;
return
1
;
}
}
...
@@ -941,13 +1020,10 @@ static int smc_phy_reset(struct net_device *dev, int phy)
...
@@ -941,13 +1020,10 @@ static int smc_phy_reset(struct net_device *dev, int phy)
*/
*/
static
void
smc_phy_powerdown
(
struct
net_device
*
dev
,
int
phy
)
static
void
smc_phy_powerdown
(
struct
net_device
*
dev
,
int
phy
)
{
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
int
bmcr
;
unsigned
int
bmcr
;
spin_lock_irq
(
&
lp
->
lock
);
bmcr
=
smc_phy_read
(
dev
,
phy
,
MII_BMCR
);
bmcr
=
smc_phy_read
(
dev
,
phy
,
MII_BMCR
);
smc_phy_write
(
dev
,
phy
,
MII_BMCR
,
bmcr
|
BMCR_PDOWN
);
smc_phy_write
(
dev
,
phy
,
MII_BMCR
,
bmcr
|
BMCR_PDOWN
);
spin_unlock_irq
(
&
lp
->
lock
);
}
}
/*
/*
...
@@ -964,8 +1040,6 @@ static void smc_phy_check_media(struct net_device *dev, int init)
...
@@ -964,8 +1040,6 @@ static void smc_phy_check_media(struct net_device *dev, int init)
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
if
(
mii_check_media
(
&
lp
->
mii
,
netif_msg_link
(
lp
),
init
))
{
if
(
mii_check_media
(
&
lp
->
mii
,
netif_msg_link
(
lp
),
init
))
{
unsigned
int
old_bank
;
/* duplex state has changed */
/* duplex state has changed */
if
(
lp
->
mii
.
full_duplex
)
{
if
(
lp
->
mii
.
full_duplex
)
{
lp
->
tcr_cur_mode
|=
TCR_SWFDUP
;
lp
->
tcr_cur_mode
|=
TCR_SWFDUP
;
...
@@ -973,10 +1047,8 @@ static void smc_phy_check_media(struct net_device *dev, int init)
...
@@ -973,10 +1047,8 @@ static void smc_phy_check_media(struct net_device *dev, int init)
lp
->
tcr_cur_mode
&=
~
TCR_SWFDUP
;
lp
->
tcr_cur_mode
&=
~
TCR_SWFDUP
;
}
}
old_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
0
);
SMC_SELECT_BANK
(
0
);
SMC_SET_TCR
(
lp
->
tcr_cur_mode
);
SMC_SET_TCR
(
lp
->
tcr_cur_mode
);
SMC_SELECT_BANK
(
old_bank
);
}
}
}
}
...
@@ -989,8 +1061,9 @@ static void smc_phy_check_media(struct net_device *dev, int init)
...
@@ -989,8 +1061,9 @@ static void smc_phy_check_media(struct net_device *dev, int init)
* of autonegotiation.) If the RPC ANEG bit is cleared, the selection
* of autonegotiation.) If the RPC ANEG bit is cleared, the selection
* is controlled by the RPC SPEED and RPC DPLX bits.
* is controlled by the RPC SPEED and RPC DPLX bits.
*/
*/
static
void
smc_phy_configure
(
struct
net_device
*
dev
)
static
void
smc_phy_configure
(
void
*
data
)
{
{
struct
net_device
*
dev
=
data
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
int
phyaddr
=
lp
->
mii
.
phy_id
;
int
phyaddr
=
lp
->
mii
.
phy_id
;
...
@@ -1117,12 +1190,13 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
...
@@ -1117,12 +1190,13 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
{
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
int
old_carrier
,
new_carrier
,
old_bank
;
unsigned
int
old_carrier
,
new_carrier
;
old_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
0
);
old_carrier
=
netif_carrier_ok
(
dev
)
?
1
:
0
;
old_carrier
=
netif_carrier_ok
(
dev
)
?
1
:
0
;
SMC_SELECT_BANK
(
0
);
new_carrier
=
SMC_inw
(
ioaddr
,
EPH_STATUS_REG
)
&
ES_LINK_OK
?
1
:
0
;
new_carrier
=
SMC_inw
(
ioaddr
,
EPH_STATUS_REG
)
&
ES_LINK_OK
?
1
:
0
;
SMC_SELECT_BANK
(
2
);
if
(
init
||
(
old_carrier
!=
new_carrier
))
{
if
(
init
||
(
old_carrier
!=
new_carrier
))
{
if
(
!
new_carrier
)
{
if
(
!
new_carrier
)
{
...
@@ -1134,24 +1208,20 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
...
@@ -1134,24 +1208,20 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
printk
(
KERN_INFO
"%s: link %s
\n
"
,
dev
->
name
,
printk
(
KERN_INFO
"%s: link %s
\n
"
,
dev
->
name
,
new_carrier
?
"up"
:
"down"
);
new_carrier
?
"up"
:
"down"
);
}
}
SMC_SELECT_BANK
(
old_bank
);
}
}
static
void
smc_eph_interrupt
(
struct
net_device
*
dev
)
static
void
smc_eph_interrupt
(
struct
net_device
*
dev
)
{
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
int
old_bank
,
ctl
;
unsigned
int
ctl
;
smc_10bt_check_media
(
dev
,
0
);
smc_10bt_check_media
(
dev
,
0
);
old_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
1
);
SMC_SELECT_BANK
(
1
);
ctl
=
SMC_GET_CTL
();
ctl
=
SMC_GET_CTL
();
SMC_SET_CTL
(
ctl
&
~
CTL_LE_ENABLE
);
SMC_SET_CTL
(
ctl
&
~
CTL_LE_ENABLE
);
SMC_SET_CTL
(
ctl
);
SMC_SET_CTL
(
ctl
);
SMC_SELECT_BANK
(
2
);
SMC_SELECT_BANK
(
old_bank
);
}
}
/*
/*
...
@@ -1164,14 +1234,12 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1164,14 +1234,12 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
int
status
,
mask
,
timeout
,
card_stats
;
int
status
,
mask
,
timeout
,
card_stats
;
int
saved_
bank
,
saved_
pointer
;
int
saved_pointer
;
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
spin_lock
(
&
lp
->
lock
);
spin_lock
(
&
lp
->
lock
);
saved_bank
=
SMC_CURRENT_BANK
();
SMC_SELECT_BANK
(
2
);
saved_pointer
=
SMC_GET_PTR
();
saved_pointer
=
SMC_GET_PTR
();
mask
=
SMC_GET_INT_MASK
();
mask
=
SMC_GET_INT_MASK
();
SMC_SET_INT_MASK
(
0
);
SMC_SET_INT_MASK
(
0
);
...
@@ -1182,7 +1250,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1182,7 +1250,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
do
{
do
{
status
=
SMC_GET_INT
();
status
=
SMC_GET_INT
();
DBG
(
2
,
"%s: I
RQ
0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x
\n
"
,
DBG
(
2
,
"%s: I
NT
0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x
\n
"
,
dev
->
name
,
status
,
mask
,
dev
->
name
,
status
,
mask
,
({
int
meminfo
;
SMC_SELECT_BANK
(
0
);
({
int
meminfo
;
SMC_SELECT_BANK
(
0
);
meminfo
=
SMC_GET_MIR
();
meminfo
=
SMC_GET_MIR
();
...
@@ -1200,17 +1268,12 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1200,17 +1268,12 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
DBG
(
3
,
"%s: TX int
\n
"
,
dev
->
name
);
DBG
(
3
,
"%s: TX int
\n
"
,
dev
->
name
);
smc_tx
(
dev
);
smc_tx
(
dev
);
SMC_ACK_INT
(
IM_TX_INT
);
SMC_ACK_INT
(
IM_TX_INT
);
#if THROTTLE_TX_PKTS
if
(
THROTTLE_TX_PKTS
)
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
#endif
}
else
if
(
status
&
IM_ALLOC_INT
)
{
}
else
if
(
status
&
IM_ALLOC_INT
)
{
DBG
(
3
,
"%s: Allocation irq
\n
"
,
dev
->
name
);
DBG
(
3
,
"%s: Allocation irq
\n
"
,
dev
->
name
);
smc_hardware_send_packet
(
dev
);
tasklet_hi_schedule
(
&
lp
->
tx_task
);
mask
|=
(
IM_TX_INT
|
IM_TX_EMPTY_INT
);
mask
&=
~
IM_ALLOC_INT
;
mask
&=
~
IM_ALLOC_INT
;
#if ! THROTTLE_TX_PKTS
netif_wake_queue
(
dev
);
#endif
}
else
if
(
status
&
IM_TX_EMPTY_INT
)
{
}
else
if
(
status
&
IM_TX_EMPTY_INT
)
{
DBG
(
3
,
"%s: TX empty
\n
"
,
dev
->
name
);
DBG
(
3
,
"%s: TX empty
\n
"
,
dev
->
name
);
mask
&=
~
IM_TX_EMPTY_INT
;
mask
&=
~
IM_TX_EMPTY_INT
;
...
@@ -1240,17 +1303,16 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1240,17 +1303,16 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
SMC_ACK_INT
(
IM_ERCV_INT
);
SMC_ACK_INT
(
IM_ERCV_INT
);
PRINTK
(
"%s: UNSUPPORTED: ERCV INTERRUPT
\n
"
,
dev
->
name
);
PRINTK
(
"%s: UNSUPPORTED: ERCV INTERRUPT
\n
"
,
dev
->
name
);
}
}
}
while
(
--
timeout
);
}
while
(
--
timeout
);
/* restore register states */
/* restore register states */
SMC_SET_INT_MASK
(
mask
);
SMC_SET_PTR
(
saved_pointer
);
SMC_SET_PTR
(
saved_pointer
);
SMC_SELECT_BANK
(
saved_bank
);
SMC_SET_INT_MASK
(
mask
);
spin_unlock
(
&
lp
->
lock
);
DBG
(
3
,
"%s: Interrupt done (%d loops)
\n
"
,
dev
->
name
,
8
-
timeout
);
DBG
(
3
,
"%s: Interrupt done (%d loops)
\n
"
,
dev
->
name
,
8
-
timeout
);
spin_unlock
(
&
lp
->
lock
);
/*
/*
* We return IRQ_HANDLED unconditionally here even if there was
* We return IRQ_HANDLED unconditionally here even if there was
* nothing to do. There is a possibility that a packet might
* nothing to do. There is a possibility that a packet might
...
@@ -1266,100 +1328,38 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1266,100 +1328,38 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static
void
smc_timeout
(
struct
net_device
*
dev
)
static
void
smc_timeout
(
struct
net_device
*
dev
)
{
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
flags
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
int
status
,
mask
,
meminfo
,
fifo
;
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
spin_lock_irq
(
&
lp
->
lock
);
status
=
SMC_GET_INT
();
mask
=
SMC_GET_INT_MASK
();
fifo
=
SMC_GET_FIFO
();
SMC_SELECT_BANK
(
0
);
meminfo
=
SMC_GET_MIR
();
SMC_SELECT_BANK
(
2
);
spin_unlock_irq
(
&
lp
->
lock
);
PRINTK
(
"%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x
\n
"
,
dev
->
name
,
status
,
mask
,
meminfo
,
fifo
);
smc_reset
(
dev
);
smc_reset
(
dev
);
smc_enable
(
dev
);
smc_enable
(
dev
);
#if 0
/*
/*
* Reconfiguring the PHY doesn't seem like a bad idea here, but
* Reconfiguring the PHY doesn't seem like a bad idea here, but
* it introduced a problem. Now that this is a timeout routine,
* smc_phy_configure() calls msleep() which calls schedule_timeout()
* we are getting called from within an interrupt context.
* which calls schedule(). Ence we use a work queue.
* smc_phy_configure() calls msleep() which calls
* schedule_timeout() which calls schedule(). When schedule()
* is called from an interrupt context, it prints out
* "Scheduling in interrupt" and then calls BUG(). This is
* obviously not desirable. This was worked around by removing
* the call to smc_phy_configure() here because it didn't seem
* absolutely necessary. Ultimately, if msleep() is
* supposed to be usable from an interrupt context (which it
* looks like it thinks it should handle), it should be fixed.
*/
*/
if
(
lp
->
phy_type
!=
0
)
if
(
lp
->
phy_type
!=
0
)
smc_phy_configure(dev);
schedule_work
(
&
lp
->
phy_configure
);
#endif
/* clear anything saved */
if
(
lp
->
saved_skb
!=
NULL
)
{
dev_kfree_skb
(
lp
->
saved_skb
);
lp
->
saved_skb
=
NULL
;
lp
->
stats
.
tx_errors
++
;
lp
->
stats
.
tx_aborted_errors
++
;
}
/* We can accept TX packets again */
/* We can accept TX packets again */
dev
->
trans_start
=
jiffies
;
dev
->
trans_start
=
jiffies
;
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
/*
* This sets the internal hardware table to filter out unwanted multicast
* packets before they take up memory.
*
* The SMC chip uses a hash table where the high 6 bits of the CRC of
* address are the offset into the table. If that bit is 1, then the
* multicast packet is accepted. Otherwise, it's dropped silently.
*
* To use the 6 bits as an offset into the table, the high 3 bits are the
* number of the 8 bit register, while the low 3 bits are the bit within
* that register.
*
* This routine is based very heavily on the one provided by Peter Cammaert.
*/
static
void
smc_setmulticast
(
unsigned
long
ioaddr
,
int
count
,
struct
dev_mc_list
*
addrs
)
{
int
i
;
unsigned
char
multicast_table
[
8
];
struct
dev_mc_list
*
cur_addr
;
/* table for flipping the order of 3 bits */
static
unsigned
char
invert3
[]
=
{
0
,
4
,
2
,
6
,
1
,
5
,
3
,
7
};
/* start with a table of all zeros: reject all */
memset
(
multicast_table
,
0
,
sizeof
(
multicast_table
));
cur_addr
=
addrs
;
for
(
i
=
0
;
i
<
count
;
i
++
,
cur_addr
=
cur_addr
->
next
)
{
int
position
;
/* do we have a pointer here? */
if
(
!
cur_addr
)
break
;
/* make sure this is a multicast address - shouldn't this
be a given if we have it here ? */
if
(
!
(
*
cur_addr
->
dmi_addr
&
1
))
continue
;
/* only use the low order bits */
position
=
crc32_le
(
~
0
,
cur_addr
->
dmi_addr
,
6
)
&
0x3f
;
/* do some messy swapping to put the bit in the right spot */
multicast_table
[
invert3
[
position
&
7
]]
|=
(
1
<<
invert3
[(
position
>>
3
)
&
7
]);
}
/* now, the table can be loaded into the chipset */
SMC_SELECT_BANK
(
3
);
SMC_SET_MCAST
(
multicast_table
);
}
/*
/*
* This routine will, depending on the values passed to it,
* This routine will, depending on the values passed to it,
* either make it accept multicast packets, go into
* either make it accept multicast packets, go into
...
@@ -1370,14 +1370,14 @@ static void smc_set_multicast_list(struct net_device *dev)
...
@@ -1370,14 +1370,14 @@ static void smc_set_multicast_list(struct net_device *dev)
{
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
unsigned
char
multicast_table
[
8
];
int
update_multicast
=
0
;
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
SMC_SELECT_BANK
(
0
);
if
(
dev
->
flags
&
IFF_PROMISC
)
{
if
(
dev
->
flags
&
IFF_PROMISC
)
{
DBG
(
2
,
"%s: RCR_PRMS
\n
"
,
dev
->
name
);
DBG
(
2
,
"%s: RCR_PRMS
\n
"
,
dev
->
name
);
lp
->
rcr_cur_mode
|=
RCR_PRMS
;
lp
->
rcr_cur_mode
|=
RCR_PRMS
;
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
}
}
/* BUG? I never disable promiscuous mode if multicasting was turned on.
/* BUG? I never disable promiscuous mode if multicasting was turned on.
...
@@ -1391,38 +1391,78 @@ static void smc_set_multicast_list(struct net_device *dev)
...
@@ -1391,38 +1391,78 @@ static void smc_set_multicast_list(struct net_device *dev)
* checked before the table is
* checked before the table is
*/
*/
else
if
(
dev
->
flags
&
IFF_ALLMULTI
||
dev
->
mc_count
>
16
)
{
else
if
(
dev
->
flags
&
IFF_ALLMULTI
||
dev
->
mc_count
>
16
)
{
lp
->
rcr_cur_mode
|=
RCR_ALMUL
;
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
DBG
(
2
,
"%s: RCR_ALMUL
\n
"
,
dev
->
name
);
DBG
(
2
,
"%s: RCR_ALMUL
\n
"
,
dev
->
name
);
lp
->
rcr_cur_mode
|=
RCR_ALMUL
;
}
}
/*
/*
* We just get all multicast packets even if we only want them
* This sets the internal hardware table to filter out unwanted
* from one source. This will be changed at some future point.
* multicast packets before they take up memory.
*
* The SMC chip uses a hash table where the high 6 bits of the CRC of
* address are the offset into the table. If that bit is 1, then the
* multicast packet is accepted. Otherwise, it's dropped silently.
*
* To use the 6 bits as an offset into the table, the high 3 bits are
* the number of the 8 bit register, while the low 3 bits are the bit
* within that register.
*/
*/
else
if
(
dev
->
mc_count
)
{
else
if
(
dev
->
mc_count
)
{
/* support hardware multicasting */
int
i
;
struct
dev_mc_list
*
cur_addr
;
/* table for flipping the order of 3 bits */
static
const
unsigned
char
invert3
[]
=
{
0
,
4
,
2
,
6
,
1
,
5
,
3
,
7
};
/* start with a table of all zeros: reject all */
memset
(
multicast_table
,
0
,
sizeof
(
multicast_table
));
cur_addr
=
dev
->
mc_list
;
for
(
i
=
0
;
i
<
dev
->
mc_count
;
i
++
,
cur_addr
=
cur_addr
->
next
)
{
int
position
;
/* do we have a pointer here? */
if
(
!
cur_addr
)
break
;
/* make sure this is a multicast address -
shouldn't this be a given if we have it here ? */
if
(
!
(
*
cur_addr
->
dmi_addr
&
1
))
continue
;
/* only use the low order bits */
position
=
crc32_le
(
~
0
,
cur_addr
->
dmi_addr
,
6
)
&
0x3f
;
/* do some messy swapping to put the bit in the right spot */
multicast_table
[
invert3
[
position
&
7
]]
|=
(
1
<<
invert3
[(
position
>>
3
)
&
7
]);
}
/* be sure I get rid of flags I might have set */
/* be sure I get rid of flags I might have set */
lp
->
rcr_cur_mode
&=
~
(
RCR_PRMS
|
RCR_ALMUL
);
lp
->
rcr_cur_mode
&=
~
(
RCR_PRMS
|
RCR_ALMUL
);
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
/*
/* now, the table can be loaded into the chipset */
* NOTE: this has to set the bank, so make sure it is the
update_multicast
=
1
;
* last thing called. The bank is set to zero at the top
*/
smc_setmulticast
(
ioaddr
,
dev
->
mc_count
,
dev
->
mc_list
);
}
else
{
}
else
{
DBG
(
2
,
"%s: ~(RCR_PRMS|RCR_ALMUL)
\n
"
,
dev
->
name
);
DBG
(
2
,
"%s: ~(RCR_PRMS|RCR_ALMUL)
\n
"
,
dev
->
name
);
lp
->
rcr_cur_mode
&=
~
(
RCR_PRMS
|
RCR_ALMUL
);
lp
->
rcr_cur_mode
&=
~
(
RCR_PRMS
|
RCR_ALMUL
);
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
/*
/*
* since I'm disabling all multicast entirely, I need to
* since I'm disabling all multicast entirely, I need to
* clear the multicast list
* clear the multicast list
*/
*/
memset
(
multicast_table
,
0
,
sizeof
(
multicast_table
));
update_multicast
=
1
;
}
spin_lock_irq
(
&
lp
->
lock
);
SMC_SELECT_BANK
(
0
);
SMC_SET_RCR
(
lp
->
rcr_cur_mode
);
if
(
update_multicast
)
{
SMC_SELECT_BANK
(
3
);
SMC_SELECT_BANK
(
3
);
SMC_
CLEAR_MCAST
(
);
SMC_
SET_MCAST
(
multicast_table
);
}
}
SMC_SELECT_BANK
(
2
);
spin_unlock_irq
(
&
lp
->
lock
);
}
}
...
@@ -1435,7 +1475,6 @@ static int
...
@@ -1435,7 +1475,6 @@ static int
smc_open
(
struct
net_device
*
dev
)
smc_open
(
struct
net_device
*
dev
)
{
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
@@ -1445,13 +1484,10 @@ smc_open(struct net_device *dev)
...
@@ -1445,13 +1484,10 @@ smc_open(struct net_device *dev)
* address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
* address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
*/
*/
if
(
!
is_valid_ether_addr
(
dev
->
dev_addr
))
{
if
(
!
is_valid_ether_addr
(
dev
->
dev_addr
))
{
DBG
(
2
,
"smc_open: no valid ethernet hw addr
\n
"
);
PRINTK
(
"%s: no valid ethernet hw addr
\n
"
,
__FUNCTION__
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
/* clear out all the junk that was put here before... */
lp
->
saved_skb
=
NULL
;
/* Setup the default Register Modes */
/* Setup the default Register Modes */
lp
->
tcr_cur_mode
=
TCR_DEFAULT
;
lp
->
tcr_cur_mode
=
TCR_DEFAULT
;
lp
->
rcr_cur_mode
=
RCR_DEFAULT
;
lp
->
rcr_cur_mode
=
RCR_DEFAULT
;
...
@@ -1468,10 +1504,7 @@ smc_open(struct net_device *dev)
...
@@ -1468,10 +1504,7 @@ smc_open(struct net_device *dev)
smc_reset
(
dev
);
smc_reset
(
dev
);
smc_enable
(
dev
);
smc_enable
(
dev
);
SMC_SELECT_BANK
(
1
);
/* Configure the PHY, initialize the link state */
SMC_SET_MAC_ADDR
(
dev
->
dev_addr
);
/* Configure the PHY */
if
(
lp
->
phy_type
!=
0
)
if
(
lp
->
phy_type
!=
0
)
smc_phy_configure
(
dev
);
smc_phy_configure
(
dev
);
else
{
else
{
...
@@ -1480,12 +1513,6 @@ smc_open(struct net_device *dev)
...
@@ -1480,12 +1513,6 @@ smc_open(struct net_device *dev)
spin_unlock_irq
(
&
lp
->
lock
);
spin_unlock_irq
(
&
lp
->
lock
);
}
}
/*
* make sure to initialize the link state with netif_carrier_off()
* somewhere, too --jgarzik
*
* smc_phy_configure() and smc_10bt_check_media() does that. --rmk
*/
netif_start_queue
(
dev
);
netif_start_queue
(
dev
);
return
0
;
return
0
;
}
}
...
@@ -1507,10 +1534,17 @@ static int smc_close(struct net_device *dev)
...
@@ -1507,10 +1534,17 @@ static int smc_close(struct net_device *dev)
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
/* clear everything */
/* clear everything */
smc_shutdown
(
dev
->
base_addr
);
smc_shutdown
(
dev
);
if
(
lp
->
phy_type
!=
0
)
if
(
lp
->
phy_type
!=
0
)
{
flush_scheduled_work
();
smc_phy_powerdown
(
dev
,
lp
->
mii
.
phy_id
);
smc_phy_powerdown
(
dev
,
lp
->
mii
.
phy_id
);
}
if
(
lp
->
pending_tx_skb
)
{
dev_kfree_skb
(
lp
->
pending_tx_skb
);
lp
->
pending_tx_skb
=
NULL
;
}
return
0
;
return
0
;
}
}
...
@@ -1800,6 +1834,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
...
@@ -1800,6 +1834,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
/* fill in some of the fields */
/* fill in some of the fields */
dev
->
base_addr
=
ioaddr
;
dev
->
base_addr
=
ioaddr
;
lp
->
version
=
revision_register
&
0xff
;
lp
->
version
=
revision_register
&
0xff
;
spin_lock_init
(
&
lp
->
lock
);
/* Get the MAC address */
/* Get the MAC address */
SMC_SELECT_BANK
(
1
);
SMC_SELECT_BANK
(
1
);
...
@@ -1855,7 +1890,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
...
@@ -1855,7 +1890,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
dev
->
set_multicast_list
=
smc_set_multicast_list
;
dev
->
set_multicast_list
=
smc_set_multicast_list
;
dev
->
ethtool_ops
=
&
smc_ethtool_ops
;
dev
->
ethtool_ops
=
&
smc_ethtool_ops
;
spin_lock_init
(
&
lp
->
lock
);
tasklet_init
(
&
lp
->
tx_task
,
smc_hardware_send_pkt
,
(
unsigned
long
)
dev
);
INIT_WORK
(
&
lp
->
phy_configure
,
smc_phy_configure
,
dev
);
lp
->
mii
.
phy_id_mask
=
0x1f
;
lp
->
mii
.
phy_id_mask
=
0x1f
;
lp
->
mii
.
reg_num_mask
=
0x1f
;
lp
->
mii
.
reg_num_mask
=
0x1f
;
lp
->
mii
.
force_media
=
0
;
lp
->
mii
.
force_media
=
0
;
...
@@ -1885,9 +1921,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
...
@@ -1885,9 +1921,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
if
(
retval
)
if
(
retval
)
goto
err_out
;
goto
err_out
;
#if !defined(__m32r__)
set_irq_type
(
dev
->
irq
,
IRQT_RISING
);
set_irq_type
(
dev
->
irq
,
IRQT_RISING
);
#endif
#ifdef SMC_USE_PXA_DMA
#ifdef SMC_USE_PXA_DMA
{
{
int
dma
=
pxa_request_dma
(
dev
->
name
,
DMA_PRIO_LOW
,
int
dma
=
pxa_request_dma
(
dev
->
name
,
DMA_PRIO_LOW
,
...
@@ -2121,7 +2156,7 @@ static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
...
@@ -2121,7 +2156,7 @@ static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
if
(
ndev
&&
level
==
SUSPEND_DISABLE
)
{
if
(
ndev
&&
level
==
SUSPEND_DISABLE
)
{
if
(
netif_running
(
ndev
))
{
if
(
netif_running
(
ndev
))
{
netif_device_detach
(
ndev
);
netif_device_detach
(
ndev
);
smc_shutdown
(
ndev
->
base_addr
);
smc_shutdown
(
ndev
);
}
}
}
}
return
0
;
return
0
;
...
@@ -2134,15 +2169,12 @@ static int smc_drv_resume(struct device *dev, u32 level)
...
@@ -2134,15 +2169,12 @@ static int smc_drv_resume(struct device *dev, u32 level)
if
(
ndev
&&
level
==
RESUME_ENABLE
)
{
if
(
ndev
&&
level
==
RESUME_ENABLE
)
{
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
unsigned
long
ioaddr
=
ndev
->
base_addr
;
if
(
pdev
->
num_resources
==
3
)
if
(
pdev
->
num_resources
==
3
)
smc_enable_device
(
pdev
->
resource
[
2
].
start
);
smc_enable_device
(
pdev
->
resource
[
2
].
start
);
if
(
netif_running
(
ndev
))
{
if
(
netif_running
(
ndev
))
{
smc_reset
(
ndev
);
smc_reset
(
ndev
);
smc_enable
(
ndev
);
smc_enable
(
ndev
);
SMC_SELECT_BANK
(
1
);
SMC_SET_MAC_ADDR
(
ndev
->
dev_addr
);
if
(
lp
->
phy_type
!=
0
)
if
(
lp
->
phy_type
!=
0
)
smc_phy_configure
(
ndev
);
smc_phy_configure
(
ndev
);
netif_device_attach
(
ndev
);
netif_device_attach
(
ndev
);
...
...
drivers/net/smc91x.h
View file @
74f54248
...
@@ -173,6 +173,11 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
...
@@ -173,6 +173,11 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
#define set_irq_type(irq, type) do {} while(0)
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
#else
#else
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_8BIT 1
...
@@ -202,8 +207,9 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
...
@@ -202,8 +207,9 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
* different and probably not worth it for that reason, and not as critical
* different and probably not worth it for that reason, and not as critical
* as RX which can overrun memory and lose packets.
* as RX which can overrun memory and lose packets.
*/
*/
#include <linux/
pci
.h>
#include <linux/
dma-mapping
.h>
#include <asm/dma.h>
#include <asm/dma.h>
#include <asm/arch/pxa-regs.h>
#ifdef SMC_insl
#ifdef SMC_insl
#undef SMC_insl
#undef SMC_insl
...
@@ -223,19 +229,21 @@ smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
...
@@ -223,19 +229,21 @@ smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
/* 64 bit alignment is required for memory to memory DMA */
/* 64 bit alignment is required for memory to memory DMA */
if
((
long
)
buf
&
4
)
{
if
((
long
)
buf
&
4
)
{
*
((
u32
*
)
buf
)
++
=
SMC_inl
(
ioaddr
,
reg
);
*
((
u32
*
)
buf
)
=
SMC_inl
(
ioaddr
,
reg
);
buf
+=
4
;
len
--
;
len
--
;
}
}
len
*=
4
;
len
*=
4
;
dmabuf
=
dma_map_single
(
NULL
,
buf
,
len
,
PCI_DMA_FROM
DEVICE
);
dmabuf
=
dma_map_single
(
NULL
,
buf
,
len
,
DMA_FROM_
DEVICE
);
DCSR
(
dma
)
=
DCSR_NODESC
;
DCSR
(
dma
)
=
DCSR_NODESC
;
DTADR
(
dma
)
=
dmabuf
;
DTADR
(
dma
)
=
dmabuf
;
DSADR
(
dma
)
=
physaddr
+
reg
;
DSADR
(
dma
)
=
physaddr
+
reg
;
DCMD
(
dma
)
=
(
DCMD_INCTRGADDR
|
DCMD_BURST32
|
DCMD
(
dma
)
=
(
DCMD_INCTRGADDR
|
DCMD_BURST32
|
DCMD_WIDTH4
|
(
DCMD_LENGTH
&
len
));
DCMD_WIDTH4
|
(
DCMD_LENGTH
&
len
));
DCSR
(
dma
)
=
DCSR_NODESC
|
DCSR_RUN
;
DCSR
(
dma
)
=
DCSR_NODESC
|
DCSR_RUN
;
while
(
!
(
DCSR
(
dma
)
&
DCSR_STOPSTATE
));
while
(
!
(
DCSR
(
dma
)
&
DCSR_STOPSTATE
))
cpu_relax
();
DCSR
(
dma
)
=
0
;
DCSR
(
dma
)
=
0
;
dma_unmap_single
(
NULL
,
dmabuf
,
len
,
PCI_DMA_FROMDEVICE
);
dma_unmap_single
(
NULL
,
dmabuf
,
len
,
PCI_DMA_FROMDEVICE
);
}
}
...
@@ -259,7 +267,8 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
...
@@ -259,7 +267,8 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
/* 64 bit alignment is required for memory to memory DMA */
/* 64 bit alignment is required for memory to memory DMA */
while
((
long
)
buf
&
6
)
{
while
((
long
)
buf
&
6
)
{
*
((
u16
*
)
buf
)
++
=
SMC_inw
(
ioaddr
,
reg
);
*
((
u16
*
)
buf
)
=
SMC_inw
(
ioaddr
,
reg
);
buf
+=
2
;
len
--
;
len
--
;
}
}
...
@@ -271,9 +280,10 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
...
@@ -271,9 +280,10 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
DCMD
(
dma
)
=
(
DCMD_INCTRGADDR
|
DCMD_BURST32
|
DCMD
(
dma
)
=
(
DCMD_INCTRGADDR
|
DCMD_BURST32
|
DCMD_WIDTH2
|
(
DCMD_LENGTH
&
len
));
DCMD_WIDTH2
|
(
DCMD_LENGTH
&
len
));
DCSR
(
dma
)
=
DCSR_NODESC
|
DCSR_RUN
;
DCSR
(
dma
)
=
DCSR_NODESC
|
DCSR_RUN
;
while
(
!
(
DCSR
(
dma
)
&
DCSR_STOPSTATE
));
while
(
!
(
DCSR
(
dma
)
&
DCSR_STOPSTATE
))
cpu_relax
();
DCSR
(
dma
)
=
0
;
DCSR
(
dma
)
=
0
;
dma_unmap_single
(
NULL
,
dmabuf
,
len
,
PCI_DMA_FROM
DEVICE
);
dma_unmap_single
(
NULL
,
dmabuf
,
len
,
DMA_FROM_
DEVICE
);
}
}
#endif
#endif
...
@@ -762,16 +772,9 @@ static const char * chip_ids[ 16 ] = {
...
@@ -762,16 +772,9 @@ static const char * chip_ids[ 16 ] = {
SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \
SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \
} while (0)
} while (0)
#define SMC_CLEAR_MCAST() \
do { \
SMC_outw( 0, ioaddr, MCAST_REG1 ); \
SMC_outw( 0, ioaddr, MCAST_REG2 ); \
SMC_outw( 0, ioaddr, MCAST_REG3 ); \
SMC_outw( 0, ioaddr, MCAST_REG4 ); \
} while (0)
#define SMC_SET_MCAST(x) \
#define SMC_SET_MCAST(x) \
do { \
do { \
unsigned char *mt = (x); \
const
unsigned char *mt = (x); \
SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \
SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \
SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \
SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \
SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \
SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \
...
...
drivers/net/tokenring/lanstreamer.c
View file @
74f54248
...
@@ -1606,7 +1606,7 @@ static void streamer_arb_cmd(struct net_device *dev)
...
@@ -1606,7 +1606,7 @@ static void streamer_arb_cmd(struct net_device *dev)
i
+=
2
;
i
+=
2
;
}
}
memcpy
_fromio
(
skb_put
(
mac_frame
,
buffer_len
),
memcpy
(
skb_put
(
mac_frame
,
buffer_len
),
frame_data
,
buffer_len
);
frame_data
,
buffer_len
);
}
while
(
next_ptr
&&
(
buff_off
=
next_ptr
));
}
while
(
next_ptr
&&
(
buff_off
=
next_ptr
));
...
...
drivers/net/tulip/dmfe.c
View file @
74f54248
...
@@ -92,6 +92,7 @@
...
@@ -92,6 +92,7 @@
#include <asm/io.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
/* Board/System/Debug information/definition ---------------- */
/* Board/System/Debug information/definition ---------------- */
...
...
drivers/net/via-rhine.c
View file @
74f54248
...
@@ -1957,6 +1957,7 @@ static int rhine_suspend(struct pci_dev *pdev, u32 state)
...
@@ -1957,6 +1957,7 @@ static int rhine_suspend(struct pci_dev *pdev, u32 state)
rhine_shutdown
(
&
pdev
->
dev
);
rhine_shutdown
(
&
pdev
->
dev
);
spin_unlock_irqrestore
(
&
rp
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
rp
->
lock
,
flags
);
free_irq
(
dev
->
irq
,
dev
);
return
0
;
return
0
;
}
}
...
@@ -1970,6 +1971,9 @@ static int rhine_resume(struct pci_dev *pdev)
...
@@ -1970,6 +1971,9 @@ static int rhine_resume(struct pci_dev *pdev)
if
(
!
netif_running
(
dev
))
if
(
!
netif_running
(
dev
))
return
0
;
return
0
;
if
(
request_irq
(
dev
->
irq
,
rhine_interrupt
,
SA_SHIRQ
,
dev
->
name
,
dev
))
printk
(
KERN_ERR
"via-rhine %s: request_irq failed
\n
"
,
dev
->
name
);
ret
=
pci_set_power_state
(
pdev
,
0
);
ret
=
pci_set_power_state
(
pdev
,
0
);
if
(
debug
>
1
)
if
(
debug
>
1
)
printk
(
KERN_INFO
"%s: Entering power state D0 %s (%d).
\n
"
,
printk
(
KERN_INFO
"%s: Entering power state D0 %s (%d).
\n
"
,
...
...
drivers/net/wireless/prism54/isl_38xx.c
View file @
74f54248
...
@@ -133,8 +133,8 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
...
@@ -133,8 +133,8 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
readl
(
device_base
+
ISL38XX_CTRL_STAT_REG
));
readl
(
device_base
+
ISL38XX_CTRL_STAT_REG
));
udelay
(
ISL38XX_WRITEIO_DELAY
);
udelay
(
ISL38XX_WRITEIO_DELAY
);
if
(
reg
=
readl
(
device_base
+
ISL38XX_INT_IDENT_REG
),
reg
=
readl
(
device_base
+
ISL38XX_INT_IDENT_REG
);
reg
==
0xabadface
)
{
if
(
reg
==
0xabadface
)
{
#if VERBOSE > SHOW_ERROR_MESSAGES
#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday
(
&
current_time
);
do_gettimeofday
(
&
current_time
);
DEBUG
(
SHOW_TRACING
,
DEBUG
(
SHOW_TRACING
,
...
@@ -192,10 +192,8 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
...
@@ -192,10 +192,8 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
void
void
isl38xx_interface_reset
(
void
__iomem
*
device_base
,
dma_addr_t
host_address
)
isl38xx_interface_reset
(
void
__iomem
*
device_base
,
dma_addr_t
host_address
)
{
{
u32
reg
;
#if VERBOSE > SHOW_ERROR_MESSAGES
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG
(
SHOW_FUNCTION_CALLS
,
"isl38xx_interface_reset
\n
"
);
DEBUG
(
SHOW_FUNCTION_CALLS
,
"isl38xx_interface_reset
\n
"
);
#endif
#endif
/* load the address of the control block in the device */
/* load the address of the control block in the device */
...
@@ -203,8 +201,7 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
...
@@ -203,8 +201,7 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
udelay
(
ISL38XX_WRITEIO_DELAY
);
udelay
(
ISL38XX_WRITEIO_DELAY
);
/* set the reset bit in the Device Interrupt Register */
/* set the reset bit in the Device Interrupt Register */
isl38xx_w32_flush
(
device_base
,
ISL38XX_DEV_INT_RESET
,
isl38xx_w32_flush
(
device_base
,
ISL38XX_DEV_INT_RESET
,
ISL38XX_DEV_INT_REG
);
ISL38XX_DEV_INT_REG
);
udelay
(
ISL38XX_WRITEIO_DELAY
);
udelay
(
ISL38XX_WRITEIO_DELAY
);
/* enable the interrupt for detecting initialization */
/* enable the interrupt for detecting initialization */
...
@@ -212,9 +209,7 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
...
@@ -212,9 +209,7 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
/* Note: Do not enable other interrupts here. We want the
/* Note: Do not enable other interrupts here. We want the
* device to have come up first 100% before allowing any other
* device to have come up first 100% before allowing any other
* interrupts. */
* interrupts. */
reg
=
ISL38XX_INT_IDENT_INIT
;
isl38xx_w32_flush
(
device_base
,
ISL38XX_INT_IDENT_INIT
,
ISL38XX_INT_EN_REG
);
isl38xx_w32_flush
(
device_base
,
reg
,
ISL38XX_INT_EN_REG
);
udelay
(
ISL38XX_WRITEIO_DELAY
);
/* allow complete full reset */
udelay
(
ISL38XX_WRITEIO_DELAY
);
/* allow complete full reset */
}
}
...
...
drivers/net/wireless/prism54/isl_38xx.h
View file @
74f54248
...
@@ -95,6 +95,10 @@ isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
...
@@ -95,6 +95,10 @@ isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
#define ISL38XX_INT_SOURCES 0x001E
#define ISL38XX_INT_SOURCES 0x001E
/* Control/Status register bits */
/* Control/Status register bits */
/* Looks like there are other meaningful bits
0x20004400 seen in normal operation,
0x200044db at 'timeout waiting for mgmt response'
*/
#define ISL38XX_CTRL_STAT_SLEEPMODE 0x00000200
#define ISL38XX_CTRL_STAT_SLEEPMODE 0x00000200
#define ISL38XX_CTRL_STAT_CLKRUN 0x00800000
#define ISL38XX_CTRL_STAT_CLKRUN 0x00800000
#define ISL38XX_CTRL_STAT_RESET 0x10000000
#define ISL38XX_CTRL_STAT_RESET 0x10000000
...
...
drivers/net/wireless/prism54/isl_ioctl.c
View file @
74f54248
...
@@ -36,38 +36,6 @@
...
@@ -36,38 +36,6 @@
#include <net/iw_handler.h>
/* New driver API */
#include <net/iw_handler.h>
/* New driver API */
static
int
init_mode
=
CARD_DEFAULT_IW_MODE
;
static
int
init_channel
=
CARD_DEFAULT_CHANNEL
;
static
int
init_wep
=
CARD_DEFAULT_WEP
;
static
int
init_filter
=
CARD_DEFAULT_FILTER
;
static
int
init_authen
=
CARD_DEFAULT_AUTHEN
;
static
int
init_dot1x
=
CARD_DEFAULT_DOT1X
;
static
int
init_conformance
=
CARD_DEFAULT_CONFORMANCE
;
static
int
init_mlme
=
CARD_DEFAULT_MLME_MODE
;
module_param
(
init_mode
,
int
,
0
);
MODULE_PARM_DESC
(
init_mode
,
"Set card mode:
\n
0: Auto
\n
1: Ad-Hoc
\n
2: Managed Client (Default)
\n
3: Master / Access Point
\n
4: Repeater (Not supported yet)
\n
5: Secondary (Not supported yet)
\n
6: Monitor"
);
module_param
(
init_channel
,
int
,
0
);
MODULE_PARM_DESC
(
init_channel
,
"Check `iwpriv ethx channel` for available channels"
);
module_param
(
init_wep
,
int
,
0
);
module_param
(
init_filter
,
int
,
0
);
module_param
(
init_authen
,
int
,
0
);
MODULE_PARM_DESC
(
init_authen
,
"Authentication method. Can be of seven types:
\n
0 0x0000: None
\n
1 0x0001: DOT11_AUTH_OS (Default)
\n
2 0x0002: DOT11_AUTH_SK
\n
3 0x0003: DOT11_AUTH_BOTH"
);
module_param
(
init_dot1x
,
int
,
0
);
MODULE_PARM_DESC
(
init_dot1x
,
"
\n
0: None/not set (Default)
\n
1: DOT11_DOT1X_AUTHENABLED
\n
2: DOT11_DOT1X_KEYTXENABLED"
);
module_param
(
init_mlme
,
int
,
0
);
MODULE_PARM_DESC
(
init_mlme
,
"Sets the MAC layer management entity (MLME) mode of operation,
\n
0: DOT11_MLME_AUTO (Default)
\n
1: DOT11_MLME_INTERMEDIATE
\n
2: DOT11_MLME_EXTENDED"
);
/**
/**
* prism54_mib_mode_helper - MIB change mode helper function
* prism54_mib_mode_helper - MIB change mode helper function
* @mib: the &struct islpci_mib object to modify
* @mib: the &struct islpci_mib object to modify
...
@@ -141,36 +109,34 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
...
@@ -141,36 +109,34 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
void
void
prism54_mib_init
(
islpci_private
*
priv
)
prism54_mib_init
(
islpci_private
*
priv
)
{
{
u32
t
;
u32
channel
,
authen
,
wep
,
filter
,
dot1x
,
mlme
,
conformance
,
power
,
mode
;
struct
obj_buffer
psm_buffer
=
{
struct
obj_buffer
psm_buffer
=
{
.
size
=
PSM_BUFFER_SIZE
,
.
size
=
PSM_BUFFER_SIZE
,
.
addr
=
priv
->
device_psm_buffer
.
addr
=
priv
->
device_psm_buffer
};
};
mgt_set
(
priv
,
DOT11_OID_CHANNEL
,
&
init_channel
);
channel
=
CARD_DEFAULT_CHANNEL
;
mgt_set
(
priv
,
DOT11_OID_AUTHENABLE
,
&
init_authen
);
authen
=
CARD_DEFAULT_AUTHEN
;
mgt_set
(
priv
,
DOT11_OID_PRIVACYINVOKED
,
&
init_wep
);
wep
=
CARD_DEFAULT_WEP
;
filter
=
CARD_DEFAULT_FILTER
;
/* (0) Do not filter un-encrypted data */
dot1x
=
CARD_DEFAULT_DOT1X
;
mlme
=
CARD_DEFAULT_MLME_MODE
;
conformance
=
CARD_DEFAULT_CONFORMANCE
;
power
=
127
;
mode
=
CARD_DEFAULT_IW_MODE
;
mgt_set
(
priv
,
DOT11_OID_CHANNEL
,
&
channel
);
mgt_set
(
priv
,
DOT11_OID_AUTHENABLE
,
&
authen
);
mgt_set
(
priv
,
DOT11_OID_PRIVACYINVOKED
,
&
wep
);
mgt_set
(
priv
,
DOT11_OID_PSMBUFFER
,
&
psm_buffer
);
mgt_set
(
priv
,
DOT11_OID_PSMBUFFER
,
&
psm_buffer
);
mgt_set
(
priv
,
DOT11_OID_EXUNENCRYPTED
,
&
init_filter
);
mgt_set
(
priv
,
DOT11_OID_EXUNENCRYPTED
,
&
filter
);
mgt_set
(
priv
,
DOT11_OID_DOT1XENABLE
,
&
init_dot1x
);
mgt_set
(
priv
,
DOT11_OID_DOT1XENABLE
,
&
dot1x
);
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
init_mlme
);
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
mlme
);
mgt_set
(
priv
,
OID_INL_DOT11D_CONFORMANCE
,
&
init_conformance
);
mgt_set
(
priv
,
OID_INL_DOT11D_CONFORMANCE
,
&
conformance
);
mgt_set
(
priv
,
OID_INL_OUTPUTPOWER
,
&
power
);
t
=
127
;
mgt_set
(
priv
,
OID_INL_OUTPUTPOWER
,
&
t
);
/* Important: we are setting a default wireless mode and we are
* forcing a valid one, so prism54_mib_mode_helper should just set
* mib values depending on what the wireless mode given is. No need
* for it save old values */
if
(
init_mode
>
IW_MODE_MONITOR
||
init_mode
<
IW_MODE_AUTO
)
{
printk
(
KERN_DEBUG
"%s(): You passed a non-valid init_mode. "
"Using default mode
\n
"
,
__FUNCTION__
);
init_mode
=
CARD_DEFAULT_IW_MODE
;
}
/* This sets all of the mode-dependent values */
/* This sets all of the mode-dependent values */
prism54_mib_mode_helper
(
priv
,
init_
mode
);
prism54_mib_mode_helper
(
priv
,
mode
);
}
}
/* this will be executed outside of atomic context thanks to
/* this will be executed outside of atomic context thanks to
...
@@ -374,7 +340,10 @@ prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
...
@@ -374,7 +340,10 @@ prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
mlmeautolevel
);
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
mlmeautolevel
);
mgt_commit
(
priv
);
if
(
mgt_commit
(
priv
))
{
up_write
(
&
priv
->
mib_sem
);
return
-
EIO
;
}
priv
->
ndev
->
type
=
(
priv
->
iw_mode
==
IW_MODE_MONITOR
)
priv
->
ndev
->
type
=
(
priv
->
iw_mode
==
IW_MODE_MONITOR
)
?
priv
->
monitor_type
:
ARPHRD_ETHER
;
?
priv
->
monitor_type
:
ARPHRD_ETHER
;
up_write
(
&
priv
->
mib_sem
);
up_write
(
&
priv
->
mib_sem
);
...
@@ -485,6 +454,15 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
...
@@ -485,6 +454,15 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
/* txpower is supported in dBm's */
/* txpower is supported in dBm's */
range
->
txpower_capa
=
IW_TXPOW_DBM
;
range
->
txpower_capa
=
IW_TXPOW_DBM
;
#if WIRELESS_EXT > 16
/* Event capability (kernel + driver) */
range
->
event_capa
[
0
]
=
(
IW_EVENT_CAPA_K_0
|
IW_EVENT_CAPA_MASK
(
SIOCGIWTHRSPY
)
|
IW_EVENT_CAPA_MASK
(
SIOCGIWAP
));
range
->
event_capa
[
1
]
=
IW_EVENT_CAPA_K_1
;
range
->
event_capa
[
4
]
=
IW_EVENT_CAPA_MASK
(
IWEVCUSTOM
);
#endif
/* WIRELESS_EXT > 16 */
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
return
0
;
return
0
;
...
@@ -629,8 +607,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
...
@@ -629,8 +607,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
current_ev
=
iwe_stream_add_point
(
current_ev
,
end_buf
,
&
iwe
,
NULL
);
current_ev
=
iwe_stream_add_point
(
current_ev
,
end_buf
,
&
iwe
,
NULL
);
/* Add frequency. (short) bss->channel is the frequency in MHz */
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe
.
u
.
freq
.
m
=
channel_of_freq
(
bss
->
channel
)
;
iwe
.
u
.
freq
.
m
=
bss
->
channel
;
iwe
.
u
.
freq
.
e
=
0
;
iwe
.
u
.
freq
.
e
=
6
;
iwe
.
cmd
=
SIOCGIWFREQ
;
iwe
.
cmd
=
SIOCGIWFREQ
;
current_ev
=
current_ev
=
iwe_stream_add_event
(
current_ev
,
end_buf
,
&
iwe
,
IW_EV_FREQ_LEN
);
iwe_stream_add_event
(
current_ev
,
end_buf
,
&
iwe
,
IW_EV_FREQ_LEN
);
...
@@ -690,19 +668,33 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
...
@@ -690,19 +668,33 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
rvalue
=
mgt_get_request
(
priv
,
DOT11_OID_NOISEFLOOR
,
0
,
NULL
,
&
r
);
rvalue
=
mgt_get_request
(
priv
,
DOT11_OID_NOISEFLOOR
,
0
,
NULL
,
&
r
);
noise
=
r
.
u
;
noise
=
r
.
u
;
/* Ask the device for a list of known bss. We can report at most
/* Ask the device for a list of known bss.
* IW_MAX_AP=64 to the range struct. But the device won't repport anything
* The old API, using SIOCGIWAPLIST, had a hard limit of IW_MAX_AP=64.
* if you change the value of IWMAX_BSS=24.
* The new API, using SIOCGIWSCAN, is only limited by the buffer size.
*/
* WE-14->WE-16, the buffer is limited to IW_SCAN_MAX_DATA bytes.
* Starting with WE-17, the buffer can be as big as needed.
* But the device won't repport anything if you change the value
* of IWMAX_BSS=24. */
rvalue
|=
mgt_get_request
(
priv
,
DOT11_OID_BSSLIST
,
0
,
NULL
,
&
r
);
rvalue
|=
mgt_get_request
(
priv
,
DOT11_OID_BSSLIST
,
0
,
NULL
,
&
r
);
bsslist
=
r
.
ptr
;
bsslist
=
r
.
ptr
;
/* ok now, scan the list and translate its info */
/* ok now, scan the list and translate its info */
for
(
i
=
0
;
i
<
min
(
IW_MAX_AP
,
(
int
)
bsslist
->
nr
);
i
++
)
for
(
i
=
0
;
i
<
(
int
)
bsslist
->
nr
;
i
++
)
{
current_ev
=
prism54_translate_bss
(
ndev
,
current_ev
,
current_ev
=
prism54_translate_bss
(
ndev
,
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
extra
+
dwrq
->
length
,
&
(
bsslist
->
bsslist
[
i
]),
&
(
bsslist
->
bsslist
[
i
]),
noise
);
noise
);
#if WIRELESS_EXT > 16
/* Check if there is space for one more entry */
if
((
extra
+
dwrq
->
length
-
current_ev
)
<=
IW_EV_ADDR_LEN
)
{
/* Ask user space to try again with a bigger buffer */
rvalue
=
-
E2BIG
;
break
;
}
#endif
/* WIRELESS_EXT > 16 */
}
kfree
(
bsslist
);
kfree
(
bsslist
);
dwrq
->
length
=
(
current_ev
-
extra
);
dwrq
->
length
=
(
current_ev
-
extra
);
dwrq
->
flags
=
0
;
/* todo */
dwrq
->
flags
=
0
;
/* todo */
...
@@ -1412,7 +1404,10 @@ prism54_set_policy(struct net_device *ndev, struct iw_request_info *info,
...
@@ -1412,7 +1404,10 @@ prism54_set_policy(struct net_device *ndev, struct iw_request_info *info,
mlmeautolevel
=
DOT11_MLME_EXTENDED
;
mlmeautolevel
=
DOT11_MLME_EXTENDED
;
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
mlmeautolevel
);
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
mlmeautolevel
);
/* restart the card with our new policy */
/* restart the card with our new policy */
mgt_commit
(
priv
);
if
(
mgt_commit
(
priv
))
{
up_write
(
&
priv
->
mib_sem
);
return
-
EIO
;
}
up_write
(
&
priv
->
mib_sem
);
up_write
(
&
priv
->
mib_sem
);
return
0
;
return
0
;
...
@@ -1746,11 +1741,13 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
...
@@ -1746,11 +1741,13 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char
*
data
)
char
*
data
)
{
{
struct
obj_mlme
*
mlme
=
(
struct
obj_mlme
*
)
data
;
struct
obj_mlme
*
mlme
=
(
struct
obj_mlme
*
)
data
;
size_t
len
;
struct
obj_mlmeex
*
mlmeex
=
(
struct
obj_mlmeex
*
)
data
;
u8
*
payload
,
*
pos
=
(
u8
*
)
(
mlme
+
1
);
struct
obj_mlmeex
*
confirm
;
u8
wpa_ie
[
MAX_WPA_IE_LEN
];
len
=
pos
[
0
]
|
(
pos
[
1
]
<<
8
);
/* little endian data length */
int
wpa_ie_len
;
payload
=
pos
+
2
;
size_t
len
=
0
;
/* u16, better? */
u8
*
payload
=
0
,
*
pos
=
0
;
int
ret
;
/* I think all trapable objects are listed here.
/* I think all trapable objects are listed here.
* Some oids have a EX version. The difference is that they are emitted
* Some oids have a EX version. The difference is that they are emitted
...
@@ -1760,9 +1757,14 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
...
@@ -1760,9 +1757,14 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
* suited. We use the more flexible custom event facility.
* suited. We use the more flexible custom event facility.
*/
*/
if
(
oid
>=
DOT11_OID_BEACON
)
{
len
=
mlmeex
->
size
;
payload
=
pos
=
mlmeex
->
data
;
}
/* I fear prism54_process_bss_data won't work with big endian data */
/* I fear prism54_process_bss_data won't work with big endian data */
if
((
oid
==
DOT11_OID_BEACON
)
||
(
oid
==
DOT11_OID_PROBE
))
if
((
oid
==
DOT11_OID_BEACON
)
||
(
oid
==
DOT11_OID_PROBE
))
prism54_process_bss_data
(
priv
,
oid
,
mlme
->
address
,
prism54_process_bss_data
(
priv
,
oid
,
mlme
ex
->
address
,
payload
,
len
);
payload
,
len
);
mgt_le_to_cpu
(
isl_oid
[
oid
].
flags
&
OID_FLAG_TYPE
,
(
void
*
)
mlme
);
mgt_le_to_cpu
(
isl_oid
[
oid
].
flags
&
OID_FLAG_TYPE
,
(
void
*
)
mlme
);
...
@@ -1822,21 +1824,134 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
...
@@ -1822,21 +1824,134 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
case
DOT11_OID_AUTHENTICATEEX
:
case
DOT11_OID_AUTHENTICATEEX
:
handle_request
(
priv
,
mlme
,
oid
);
handle_request
(
priv
,
mlme
,
oid
);
send_formatted_event
(
priv
,
"Authenticate request"
,
mlme
,
1
);
send_formatted_event
(
priv
,
"Authenticate request (ex)"
,
mlme
,
1
);
if
(
priv
->
iw_mode
!=
IW_MODE_MASTER
&&
mlmeex
->
state
!=
DOT11_STATE_AUTHING
)
break
;
confirm
=
kmalloc
(
sizeof
(
struct
obj_mlmeex
)
+
6
,
GFP_ATOMIC
);
if
(
!
confirm
)
break
;
memcpy
(
&
confirm
->
address
,
mlmeex
->
address
,
ETH_ALEN
);
printk
(
KERN_DEBUG
"Authenticate from: address:
\t
%02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
mlmeex
->
address
[
0
],
mlmeex
->
address
[
1
],
mlmeex
->
address
[
2
],
mlmeex
->
address
[
3
],
mlmeex
->
address
[
4
],
mlmeex
->
address
[
5
]
);
confirm
->
id
=
-
1
;
/* or mlmeex->id ? */
confirm
->
state
=
0
;
/* not used */
confirm
->
code
=
0
;
confirm
->
size
=
6
;
confirm
->
data
[
0
]
=
0x00
;
confirm
->
data
[
1
]
=
0x00
;
confirm
->
data
[
2
]
=
0x02
;
confirm
->
data
[
3
]
=
0x00
;
confirm
->
data
[
4
]
=
0x00
;
confirm
->
data
[
5
]
=
0x00
;
ret
=
mgt_set_varlen
(
priv
,
DOT11_OID_ASSOCIATEEX
,
confirm
,
6
);
kfree
(
confirm
);
if
(
ret
)
return
ret
;
break
;
break
;
case
DOT11_OID_DISASSOCIATEEX
:
case
DOT11_OID_DISASSOCIATEEX
:
send_formatted_event
(
priv
,
"Disassociate request"
,
mlme
,
0
);
send_formatted_event
(
priv
,
"Disassociate request
(ex)
"
,
mlme
,
0
);
break
;
break
;
case
DOT11_OID_ASSOCIATEEX
:
case
DOT11_OID_ASSOCIATEEX
:
handle_request
(
priv
,
mlme
,
oid
);
handle_request
(
priv
,
mlme
,
oid
);
send_formatted_event
(
priv
,
"Associate request"
,
mlme
,
1
);
send_formatted_event
(
priv
,
"Associate request (ex)"
,
mlme
,
1
);
if
(
priv
->
iw_mode
!=
IW_MODE_MASTER
&&
mlmeex
->
state
!=
DOT11_STATE_AUTHING
)
break
;
confirm
=
kmalloc
(
sizeof
(
struct
obj_mlmeex
),
GFP_ATOMIC
);
if
(
!
confirm
)
break
;
memcpy
(
&
confirm
->
address
,
mlmeex
->
address
,
ETH_ALEN
);
confirm
->
id
=
((
struct
obj_mlmeex
*
)
mlme
)
->
id
;
confirm
->
state
=
0
;
/* not used */
confirm
->
code
=
0
;
wpa_ie_len
=
prism54_wpa_ie_get
(
priv
,
mlmeex
->
address
,
wpa_ie
);
if
(
!
wpa_ie_len
)
{
printk
(
KERN_DEBUG
"No WPA IE found from "
"address:
\t
%02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
mlmeex
->
address
[
0
],
mlmeex
->
address
[
1
],
mlmeex
->
address
[
2
],
mlmeex
->
address
[
3
],
mlmeex
->
address
[
4
],
mlmeex
->
address
[
5
]
);
kfree
(
confirm
);
break
;
}
confirm
->
size
=
wpa_ie_len
;
memcpy
(
&
confirm
->
data
,
wpa_ie
,
wpa_ie_len
);
mgt_set_varlen
(
priv
,
oid
,
confirm
,
wpa_ie_len
);
kfree
(
confirm
);
break
;
break
;
case
DOT11_OID_REASSOCIATEEX
:
case
DOT11_OID_REASSOCIATEEX
:
handle_request
(
priv
,
mlme
,
oid
);
handle_request
(
priv
,
mlme
,
oid
);
send_formatted_event
(
priv
,
"Reassociate request"
,
mlme
,
1
);
send_formatted_event
(
priv
,
"Reassociate request (ex)"
,
mlme
,
1
);
if
(
priv
->
iw_mode
!=
IW_MODE_MASTER
&&
mlmeex
->
state
!=
DOT11_STATE_ASSOCING
)
break
;
confirm
=
kmalloc
(
sizeof
(
struct
obj_mlmeex
),
GFP_ATOMIC
);
if
(
!
confirm
)
break
;
memcpy
(
&
confirm
->
address
,
mlmeex
->
address
,
ETH_ALEN
);
confirm
->
id
=
mlmeex
->
id
;
confirm
->
state
=
0
;
/* not used */
confirm
->
code
=
0
;
wpa_ie_len
=
prism54_wpa_ie_get
(
priv
,
mlmeex
->
address
,
wpa_ie
);
if
(
!
wpa_ie_len
)
{
printk
(
KERN_DEBUG
"No WPA IE found from "
"address:
\t
%02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
mlmeex
->
address
[
0
],
mlmeex
->
address
[
1
],
mlmeex
->
address
[
2
],
mlmeex
->
address
[
3
],
mlmeex
->
address
[
4
],
mlmeex
->
address
[
5
]
);
kfree
(
confirm
);
break
;
}
confirm
->
size
=
wpa_ie_len
;
memcpy
(
&
confirm
->
data
,
wpa_ie
,
wpa_ie_len
);
mgt_set_varlen
(
priv
,
oid
,
confirm
,
wpa_ie_len
);
kfree
(
confirm
);
break
;
break
;
default:
default:
...
@@ -1879,23 +1994,367 @@ prism54_set_mac_address(struct net_device *ndev, void *addr)
...
@@ -1879,23 +1994,367 @@ prism54_set_mac_address(struct net_device *ndev, void *addr)
return
ret
;
return
ret
;
}
}
/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
* support. This is to be replaced with Linux wireless extensions once they
* get WPA support. */
/* Note II: please leave all this together as it will be easier to remove later,
* once wireless extensions add WPA support -mcgrof */
/* PRISM54_HOSTAPD ioctl() cmd: */
enum
{
PRISM2_SET_ENCRYPTION
=
6
,
PRISM2_HOSTAPD_SET_GENERIC_ELEMENT
=
12
,
PRISM2_HOSTAPD_MLME
=
13
,
PRISM2_HOSTAPD_SCAN_REQ
=
14
,
};
#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
/* Maximum length for algorithm names (-1 for nul termination)
* used in ioctl() */
#define HOSTAP_CRYPT_ALG_NAME_LEN 16
struct
prism2_hostapd_param
{
u32
cmd
;
u8
sta_addr
[
ETH_ALEN
];
union
{
struct
{
u8
alg
[
HOSTAP_CRYPT_ALG_NAME_LEN
];
u32
flags
;
u32
err
;
u8
idx
;
u8
seq
[
8
];
/* sequence counter (set: RX, get: TX) */
u16
key_len
;
u8
key
[
0
];
}
crypt
;
struct
{
u8
len
;
u8
data
[
0
];
}
generic_elem
;
struct
{
#define MLME_STA_DEAUTH 0
#define MLME_STA_DISASSOC 1
u16
cmd
;
u16
reason_code
;
}
mlme
;
struct
{
u8
ssid_len
;
u8
ssid
[
32
];
}
scan_req
;
}
u
;
};
static
int
prism2_ioctl_set_encryption
(
struct
net_device
*
dev
,
struct
prism2_hostapd_param
*
param
,
int
param_len
)
{
islpci_private
*
priv
=
netdev_priv
(
dev
);
int
rvalue
=
0
,
force
=
0
;
int
authen
=
DOT11_AUTH_OS
,
invoke
=
0
,
exunencrypt
=
0
;
union
oid_res_t
r
;
/* with the new API, it's impossible to get a NULL pointer.
* New version of iwconfig set the IW_ENCODE_NOKEY flag
* when no key is given, but older versions don't. */
if
(
param
->
u
.
crypt
.
key_len
>
0
)
{
/* we have a key to set */
int
index
=
param
->
u
.
crypt
.
idx
;
int
current_index
;
struct
obj_key
key
=
{
DOT11_PRIV_TKIP
,
0
,
""
};
/* get the current key index */
rvalue
=
mgt_get_request
(
priv
,
DOT11_OID_DEFKEYID
,
0
,
NULL
,
&
r
);
current_index
=
r
.
u
;
/* Verify that the key is not marked as invalid */
if
(
!
(
param
->
u
.
crypt
.
flags
&
IW_ENCODE_NOKEY
))
{
key
.
length
=
param
->
u
.
crypt
.
key_len
>
sizeof
(
param
->
u
.
crypt
.
key
)
?
sizeof
(
param
->
u
.
crypt
.
key
)
:
param
->
u
.
crypt
.
key_len
;
memcpy
(
key
.
key
,
param
->
u
.
crypt
.
key
,
key
.
length
);
if
(
key
.
length
==
32
)
/* we want WPA-PSK */
key
.
type
=
DOT11_PRIV_TKIP
;
if
((
index
<
0
)
||
(
index
>
3
))
/* no index provided use the current one */
index
=
current_index
;
/* now send the key to the card */
rvalue
|=
mgt_set_request
(
priv
,
DOT11_OID_DEFKEYX
,
index
,
&
key
);
}
/*
* If a valid key is set, encryption should be enabled
* (user may turn it off later).
* This is also how "iwconfig ethX key on" works
*/
if
((
index
==
current_index
)
&&
(
key
.
length
>
0
))
force
=
1
;
}
else
{
int
index
=
(
param
->
u
.
crypt
.
flags
&
IW_ENCODE_INDEX
)
-
1
;
if
((
index
>=
0
)
&&
(
index
<=
3
))
{
/* we want to set the key index */
rvalue
|=
mgt_set_request
(
priv
,
DOT11_OID_DEFKEYID
,
0
,
&
index
);
}
else
{
if
(
!
param
->
u
.
crypt
.
flags
&
IW_ENCODE_MODE
)
{
/* we cannot do anything. Complain. */
return
-
EINVAL
;
}
}
}
/* now read the flags */
if
(
param
->
u
.
crypt
.
flags
&
IW_ENCODE_DISABLED
)
{
/* Encoding disabled,
* authen = DOT11_AUTH_OS;
* invoke = 0;
* exunencrypt = 0; */
}
if
(
param
->
u
.
crypt
.
flags
&
IW_ENCODE_OPEN
)
/* Encode but accept non-encoded packets. No auth */
invoke
=
1
;
if
((
param
->
u
.
crypt
.
flags
&
IW_ENCODE_RESTRICTED
)
||
force
)
{
/* Refuse non-encoded packets. Auth */
authen
=
DOT11_AUTH_BOTH
;
invoke
=
1
;
exunencrypt
=
1
;
}
/* do the change if requested */
if
((
param
->
u
.
crypt
.
flags
&
IW_ENCODE_MODE
)
||
force
)
{
rvalue
|=
mgt_set_request
(
priv
,
DOT11_OID_AUTHENABLE
,
0
,
&
authen
);
rvalue
|=
mgt_set_request
(
priv
,
DOT11_OID_PRIVACYINVOKED
,
0
,
&
invoke
);
rvalue
|=
mgt_set_request
(
priv
,
DOT11_OID_EXUNENCRYPTED
,
0
,
&
exunencrypt
);
}
return
rvalue
;
}
static
int
prism2_ioctl_set_generic_element
(
struct
net_device
*
ndev
,
struct
prism2_hostapd_param
*
param
,
int
param_len
)
{
islpci_private
*
priv
=
netdev_priv
(
ndev
);
int
max_len
,
len
,
alen
,
ret
=
0
;
struct
obj_attachment
*
attach
;
len
=
param
->
u
.
generic_elem
.
len
;
max_len
=
param_len
-
PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN
;
if
(
max_len
<
0
||
max_len
<
len
)
return
-
EINVAL
;
alen
=
sizeof
(
*
attach
)
+
len
;
attach
=
kmalloc
(
alen
,
GFP_KERNEL
);
if
(
attach
==
NULL
)
return
-
ENOMEM
;
memset
(
attach
,
0
,
alen
);
#define WLAN_FC_TYPE_MGMT 0
#define WLAN_FC_STYPE_ASSOC_REQ 0
#define WLAN_FC_STYPE_REASSOC_REQ 2
/* Note: endianness is covered by mgt_set_varlen */
attach
->
type
=
(
WLAN_FC_TYPE_MGMT
<<
2
)
|
(
WLAN_FC_STYPE_ASSOC_REQ
<<
4
);
attach
->
id
=
-
1
;
attach
->
size
=
len
;
memcpy
(
attach
->
data
,
param
->
u
.
generic_elem
.
data
,
len
);
ret
=
mgt_set_varlen
(
priv
,
DOT11_OID_ATTACHMENT
,
attach
,
len
);
if
(
ret
==
0
)
{
attach
->
type
=
(
WLAN_FC_TYPE_MGMT
<<
2
)
|
(
WLAN_FC_STYPE_REASSOC_REQ
<<
4
);
ret
=
mgt_set_varlen
(
priv
,
DOT11_OID_ATTACHMENT
,
attach
,
len
);
if
(
ret
==
0
)
printk
(
KERN_DEBUG
"%s: WPA IE Attachment was set
\n
"
,
ndev
->
name
);
}
kfree
(
attach
);
return
ret
;
}
static
int
prism2_ioctl_mlme
(
struct
net_device
*
dev
,
struct
prism2_hostapd_param
*
param
)
{
return
-
EOPNOTSUPP
;
}
static
int
prism2_ioctl_scan_req
(
struct
net_device
*
ndev
,
struct
prism2_hostapd_param
*
param
)
{
islpci_private
*
priv
=
netdev_priv
(
ndev
);
int
i
,
rvalue
;
struct
obj_bsslist
*
bsslist
;
u32
noise
=
0
;
char
*
extra
=
""
;
char
*
current_ev
=
"foo"
;
union
oid_res_t
r
;
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
{
/* device is not ready, fail gently */
return
0
;
}
/* first get the noise value. We will use it to report the link quality */
rvalue
=
mgt_get_request
(
priv
,
DOT11_OID_NOISEFLOOR
,
0
,
NULL
,
&
r
);
noise
=
r
.
u
;
/* Ask the device for a list of known bss. We can report at most
* IW_MAX_AP=64 to the range struct. But the device won't repport anything
* if you change the value of IWMAX_BSS=24.
*/
rvalue
|=
mgt_get_request
(
priv
,
DOT11_OID_BSSLIST
,
0
,
NULL
,
&
r
);
bsslist
=
r
.
ptr
;
/* ok now, scan the list and translate its info */
for
(
i
=
0
;
i
<
min
(
IW_MAX_AP
,
(
int
)
bsslist
->
nr
);
i
++
)
current_ev
=
prism54_translate_bss
(
ndev
,
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
&
(
bsslist
->
bsslist
[
i
]),
noise
);
kfree
(
bsslist
);
return
rvalue
;
}
static
int
prism54_hostapd
(
struct
net_device
*
ndev
,
struct
iw_point
*
p
)
{
struct
prism2_hostapd_param
*
param
;
int
ret
=
0
;
u32
uwrq
;
printk
(
KERN_DEBUG
"prism54_hostapd - len=%d
\n
"
,
p
->
length
);
if
(
p
->
length
<
sizeof
(
struct
prism2_hostapd_param
)
||
p
->
length
>
PRISM2_HOSTAPD_MAX_BUF_SIZE
||
!
p
->
pointer
)
return
-
EINVAL
;
param
=
(
struct
prism2_hostapd_param
*
)
kmalloc
(
p
->
length
,
GFP_KERNEL
);
if
(
param
==
NULL
)
return
-
ENOMEM
;
if
(
copy_from_user
(
param
,
p
->
pointer
,
p
->
length
))
{
kfree
(
param
);
return
-
EFAULT
;
}
switch
(
param
->
cmd
)
{
case
PRISM2_SET_ENCRYPTION
:
printk
(
KERN_DEBUG
"%s: Caught WPA supplicant set encryption request
\n
"
,
ndev
->
name
);
ret
=
prism2_ioctl_set_encryption
(
ndev
,
param
,
p
->
length
);
break
;
case
PRISM2_HOSTAPD_SET_GENERIC_ELEMENT
:
printk
(
KERN_DEBUG
"%s: Caught WPA supplicant set WPA IE request
\n
"
,
ndev
->
name
);
ret
=
prism2_ioctl_set_generic_element
(
ndev
,
param
,
p
->
length
);
break
;
case
PRISM2_HOSTAPD_MLME
:
printk
(
KERN_DEBUG
"%s: Caught WPA supplicant MLME request
\n
"
,
ndev
->
name
);
ret
=
prism2_ioctl_mlme
(
ndev
,
param
);
break
;
case
PRISM2_HOSTAPD_SCAN_REQ
:
printk
(
KERN_DEBUG
"%s: Caught WPA supplicant scan request
\n
"
,
ndev
->
name
);
ret
=
prism2_ioctl_scan_req
(
ndev
,
param
);
break
;
case
PRISM54_SET_WPA
:
printk
(
KERN_DEBUG
"%s: Caught WPA supplicant wpa init request
\n
"
,
ndev
->
name
);
uwrq
=
1
;
ret
=
prism54_set_wpa
(
ndev
,
NULL
,
&
uwrq
,
NULL
);
break
;
case
PRISM54_DROP_UNENCRYPTED
:
printk
(
KERN_DEBUG
"%s: Caught WPA drop unencrypted request
\n
"
,
ndev
->
name
);
#if 0
uwrq = 0x01;
mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
down_write(&priv->mib_sem);
mgt_commit(priv);
up_write(&priv->mib_sem);
#endif
/* Not necessary, as set_wpa does it, should we just do it here though? */
ret
=
0
;
break
;
default:
printk
(
KERN_DEBUG
"%s: Caught a WPA supplicant request that is not supported
\n
"
,
ndev
->
name
);
ret
=
-
EOPNOTSUPP
;
break
;
}
if
(
ret
==
0
&&
copy_to_user
(
p
->
pointer
,
param
,
p
->
length
))
ret
=
-
EFAULT
;
kfree
(
param
);
return
ret
;
}
int
int
prism54_set_wpa
(
struct
net_device
*
ndev
,
struct
iw_request_info
*
info
,
prism54_set_wpa
(
struct
net_device
*
ndev
,
struct
iw_request_info
*
info
,
__u32
*
uwrq
,
char
*
extra
)
__u32
*
uwrq
,
char
*
extra
)
{
{
islpci_private
*
priv
=
netdev_priv
(
ndev
);
islpci_private
*
priv
=
netdev_priv
(
ndev
);
u32
mlme
,
authen
,
dot1x
,
filter
,
wep
;
down_write
(
&
priv
->
mib_sem
);
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
return
0
;
wep
=
1
;
/* For privacy invoked */
filter
=
1
;
/* Filter out all unencrypted frames */
dot1x
=
0x01
;
/* To enable eap filter */
mlme
=
DOT11_MLME_EXTENDED
;
authen
=
DOT11_AUTH_OS
;
/* Only WEP uses _SK and _BOTH */
down_write
(
&
priv
->
mib_sem
);
priv
->
wpa
=
*
uwrq
;
priv
->
wpa
=
*
uwrq
;
if
(
priv
->
wpa
)
{
u32
l
=
DOT11_MLME_EXTENDED
;
switch
(
priv
->
wpa
)
{
mgt_set
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
&
l
);
default:
case
0
:
/* Clears/disables WPA and friends */
wep
=
0
;
filter
=
0
;
/* Do not filter un-encrypted data */
dot1x
=
0
;
mlme
=
DOT11_MLME_AUTO
;
printk
(
"%s: Disabling WPA
\n
"
,
ndev
->
name
);
break
;
case
2
:
case
1
:
/* WPA */
printk
(
"%s: Enabling WPA
\n
"
,
ndev
->
name
);
break
;
}
}
/* restart the card with new level. Needed ? */
mgt_commit
(
priv
);
up_write
(
&
priv
->
mib_sem
);
up_write
(
&
priv
->
mib_sem
);
mgt_set_request
(
priv
,
DOT11_OID_AUTHENABLE
,
0
,
&
authen
);
mgt_set_request
(
priv
,
DOT11_OID_PRIVACYINVOKED
,
0
,
&
wep
);
mgt_set_request
(
priv
,
DOT11_OID_EXUNENCRYPTED
,
0
,
&
filter
);
mgt_set_request
(
priv
,
DOT11_OID_DOT1XENABLE
,
0
,
&
dot1x
);
mgt_set_request
(
priv
,
DOT11_OID_MLMEAUTOLEVEL
,
0
,
&
mlme
);
return
0
;
return
0
;
}
}
...
@@ -1947,7 +2406,7 @@ prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
...
@@ -1947,7 +2406,7 @@ prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
struct
iw_point
*
data
,
char
*
extra
)
struct
iw_point
*
data
,
char
*
extra
)
{
{
islpci_private
*
priv
=
netdev_priv
(
ndev
);
islpci_private
*
priv
=
netdev_priv
(
ndev
);
struct
islpci_mgmtframe
*
response
=
NULL
;
struct
islpci_mgmtframe
*
response
;
int
ret
=
-
EIO
;
int
ret
=
-
EIO
;
printk
(
"%s: get_oid 0x%08X
\n
"
,
ndev
->
name
,
priv
->
priv_oid
);
printk
(
"%s: get_oid 0x%08X
\n
"
,
ndev
->
name
,
priv
->
priv_oid
);
...
@@ -1983,7 +2442,7 @@ prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
...
@@ -1983,7 +2442,7 @@ prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
struct
iw_point
*
data
,
char
*
extra
)
struct
iw_point
*
data
,
char
*
extra
)
{
{
islpci_private
*
priv
=
netdev_priv
(
ndev
);
islpci_private
*
priv
=
netdev_priv
(
ndev
);
struct
islpci_mgmtframe
*
response
=
NULL
;
struct
islpci_mgmtframe
*
response
;
int
ret
=
0
,
response_op
=
PIMFOR_OP_ERROR
;
int
ret
=
0
,
response_op
=
PIMFOR_OP_ERROR
;
printk
(
"%s: set_oid 0x%08X
\t
len: %d
\n
"
,
ndev
->
name
,
priv
->
priv_oid
,
printk
(
"%s: set_oid 0x%08X
\t
len: %d
\n
"
,
ndev
->
name
,
priv
->
priv_oid
,
...
@@ -2256,14 +2715,24 @@ const struct iw_handler_def prism54_handler_def = {
...
@@ -2256,14 +2715,24 @@ const struct iw_handler_def prism54_handler_def = {
.
standard
=
(
iw_handler
*
)
prism54_handler
,
.
standard
=
(
iw_handler
*
)
prism54_handler
,
.
private
=
(
iw_handler
*
)
prism54_private_handler
,
.
private
=
(
iw_handler
*
)
prism54_private_handler
,
.
private_args
=
(
struct
iw_priv_args
*
)
prism54_private_args
,
.
private_args
=
(
struct
iw_priv_args
*
)
prism54_private_args
,
#if WIRELESS_EXT == 16
.
spy_offset
=
offsetof
(
islpci_private
,
spy_data
),
.
spy_offset
=
offsetof
(
islpci_private
,
spy_data
),
#endif
/* WIRELESS_EXT == 16 */
};
};
/* For
ioctls that don't work with the new API
*/
/* For
wpa_supplicant
*/
int
int
prism54_ioctl
(
struct
net_device
*
ndev
,
struct
ifreq
*
rq
,
int
cmd
)
prism54_ioctl
(
struct
net_device
*
ndev
,
struct
ifreq
*
rq
,
int
cmd
)
{
{
struct
iwreq
*
wrq
=
(
struct
iwreq
*
)
rq
;
int
ret
=
-
1
;
switch
(
cmd
)
{
case
PRISM54_HOSTAPD
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
ret
=
prism54_hostapd
(
ndev
,
&
wrq
->
u
.
data
);
return
ret
;
}
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
drivers/net/wireless/prism54/isl_ioctl.h
View file @
74f54248
...
@@ -48,6 +48,8 @@ size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
...
@@ -48,6 +48,8 @@ size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
int
prism54_set_mac_address
(
struct
net_device
*
,
void
*
);
int
prism54_set_mac_address
(
struct
net_device
*
,
void
*
);
int
prism54_ioctl
(
struct
net_device
*
,
struct
ifreq
*
,
int
);
int
prism54_ioctl
(
struct
net_device
*
,
struct
ifreq
*
,
int
);
int
prism54_set_wpa
(
struct
net_device
*
,
struct
iw_request_info
*
,
__u32
*
,
char
*
);
extern
const
struct
iw_handler_def
prism54_handler_def
;
extern
const
struct
iw_handler_def
prism54_handler_def
;
...
...
drivers/net/wireless/prism54/isl_oid.h
View file @
74f54248
...
@@ -91,6 +91,14 @@ struct obj_frequencies {
...
@@ -91,6 +91,14 @@ struct obj_frequencies {
u16
mhz
[
0
];
u16
mhz
[
0
];
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
struct
obj_attachment
{
char
type
;
char
reserved
;
short
id
;
short
size
;
char
data
[
0
];
}
__attribute__
((
packed
));
/*
/*
* in case everything's ok, the inlined function below will be
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
* optimized away by the compiler...
...
@@ -472,6 +480,7 @@ enum oid_num_t {
...
@@ -472,6 +480,7 @@ enum oid_num_t {
#define OID_TYPE_MLMEEX 0x09
#define OID_TYPE_MLMEEX 0x09
#define OID_TYPE_ADDR 0x0A
#define OID_TYPE_ADDR 0x0A
#define OID_TYPE_RAW 0x0B
#define OID_TYPE_RAW 0x0B
#define OID_TYPE_ATTACH 0x0C
/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
* Not yet implemented (not used in driver anyway).
* Not yet implemented (not used in driver anyway).
...
...
drivers/net/wireless/prism54/islpci_dev.c
View file @
74f54248
...
@@ -105,7 +105,7 @@ isl_upload_firmware(islpci_private *priv)
...
@@ -105,7 +105,7 @@ isl_upload_firmware(islpci_private *priv)
"%s: firmware '%s' size is not multiple of 32bit, aborting!
\n
"
,
"%s: firmware '%s' size is not multiple of 32bit, aborting!
\n
"
,
"prism54"
,
priv
->
firmware
);
"prism54"
,
priv
->
firmware
);
release_firmware
(
fw_entry
);
release_firmware
(
fw_entry
);
return
EILSEQ
;
/* Illegal byte sequence */
;
return
-
EILSEQ
;
/* Illegal byte sequence */
;
}
}
while
(
fw_len
>
0
)
{
while
(
fw_len
>
0
)
{
...
@@ -142,6 +142,10 @@ isl_upload_firmware(islpci_private *priv)
...
@@ -142,6 +142,10 @@ isl_upload_firmware(islpci_private *priv)
BUG_ON
(
fw_len
!=
0
);
BUG_ON
(
fw_len
!=
0
);
/* Firmware version is at offset 40 (also for "newmac") */
printk
(
KERN_DEBUG
"%s: firmware version: %.8s
\n
"
,
priv
->
ndev
->
name
,
fw_entry
->
data
+
40
);
release_firmware
(
fw_entry
);
release_firmware
(
fw_entry
);
}
}
...
@@ -375,8 +379,6 @@ islpci_open(struct net_device *ndev)
...
@@ -375,8 +379,6 @@ islpci_open(struct net_device *ndev)
u32
rc
;
u32
rc
;
islpci_private
*
priv
=
netdev_priv
(
ndev
);
islpci_private
*
priv
=
netdev_priv
(
ndev
);
printk
(
KERN_DEBUG
"%s: islpci_open()
\n
"
,
ndev
->
name
);
/* reset data structures, upload firmware and reset device */
/* reset data structures, upload firmware and reset device */
rc
=
islpci_reset
(
priv
,
1
);
rc
=
islpci_reset
(
priv
,
1
);
if
(
rc
)
{
if
(
rc
)
{
...
@@ -462,8 +464,7 @@ islpci_upload_fw(islpci_private *priv)
...
@@ -462,8 +464,7 @@ islpci_upload_fw(islpci_private *priv)
return
rc
;
return
rc
;
}
}
printk
(
KERN_DEBUG
printk
(
KERN_DEBUG
"%s: firmware upload complete
\n
"
,
"%s: firmware uploaded done, now triggering reset...
\n
"
,
priv
->
ndev
->
name
);
priv
->
ndev
->
name
);
islpci_set_state
(
priv
,
PRV_STATE_POSTBOOT
);
islpci_set_state
(
priv
,
PRV_STATE_POSTBOOT
);
...
@@ -489,6 +490,7 @@ islpci_reset_if(islpci_private *priv)
...
@@ -489,6 +490,7 @@ islpci_reset_if(islpci_private *priv)
/* The software reset acknowledge needs about 220 msec here.
/* The software reset acknowledge needs about 220 msec here.
* Be conservative and wait for up to one second. */
* Be conservative and wait for up to one second. */
set_current_state
(
TASK_UNINTERRUPTIBLE
);
remaining
=
schedule_timeout
(
HZ
);
remaining
=
schedule_timeout
(
HZ
);
if
(
remaining
>
0
)
{
if
(
remaining
>
0
)
{
...
@@ -499,15 +501,16 @@ islpci_reset_if(islpci_private *priv)
...
@@ -499,15 +501,16 @@ islpci_reset_if(islpci_private *priv)
/* If we're here it's because our IRQ hasn't yet gone through.
/* If we're here it's because our IRQ hasn't yet gone through.
* Retry a bit more...
* Retry a bit more...
*/
*/
printk
(
KERN_ERR
"%s: device soft reset timed out
\n
"
,
printk
(
KERN_ERR
"%s: no 'reset complete' IRQ seen - retrying
\n
"
,
priv
->
ndev
->
name
);
priv
->
ndev
->
name
);
}
}
finish_wait
(
&
priv
->
reset_done
,
&
wait
);
finish_wait
(
&
priv
->
reset_done
,
&
wait
);
if
(
result
)
if
(
result
)
{
printk
(
KERN_ERR
"%s: interface reset failure
\n
"
,
priv
->
ndev
->
name
);
return
result
;
return
result
;
}
islpci_set_state
(
priv
,
PRV_STATE_INIT
);
islpci_set_state
(
priv
,
PRV_STATE_INIT
);
...
@@ -519,11 +522,17 @@ islpci_reset_if(islpci_private *priv)
...
@@ -519,11 +522,17 @@ islpci_reset_if(islpci_private *priv)
isl38xx_enable_common_interrupts
(
priv
->
device_base
);
isl38xx_enable_common_interrupts
(
priv
->
device_base
);
down_write
(
&
priv
->
mib_sem
);
down_write
(
&
priv
->
mib_sem
);
mgt_commit
(
priv
);
result
=
mgt_commit
(
priv
);
if
(
result
)
{
printk
(
KERN_ERR
"%s: interface reset failure
\n
"
,
priv
->
ndev
->
name
);
up_write
(
&
priv
->
mib_sem
);
return
result
;
}
up_write
(
&
priv
->
mib_sem
);
up_write
(
&
priv
->
mib_sem
);
islpci_set_state
(
priv
,
PRV_STATE_READY
);
islpci_set_state
(
priv
,
PRV_STATE_READY
);
printk
(
KERN_DEBUG
"%s: interface reset complete
\n
"
,
priv
->
ndev
->
name
);
return
0
;
return
0
;
}
}
...
@@ -584,18 +593,18 @@ islpci_reset(islpci_private *priv, int reload_firmware)
...
@@ -584,18 +593,18 @@ islpci_reset(islpci_private *priv, int reload_firmware)
/* now that the data structures are cleaned up, upload
/* now that the data structures are cleaned up, upload
* firmware and reset interface */
* firmware and reset interface */
rc
=
islpci_upload_fw
(
priv
);
rc
=
islpci_upload_fw
(
priv
);
if
(
rc
)
if
(
rc
)
{
printk
(
KERN_ERR
"%s: islpci_reset: failure
\n
"
,
priv
->
ndev
->
name
);
return
rc
;
return
rc
;
}
}
}
/* finally reset interface */
/* finally reset interface */
rc
=
islpci_reset_if
(
priv
);
rc
=
islpci_reset_if
(
priv
);
if
(
!
rc
)
/* If successful */
if
(
rc
)
return
rc
;
printk
(
KERN_ERR
"prism54: Your card/socket may be faulty, or IRQ line too busy :(
\n
"
);
printk
(
KERN_DEBUG
"prism54: Your card/socket may be faulty, or IRQ line too busy :(
\n
"
);
return
rc
;
return
rc
;
}
}
struct
net_device_stats
*
struct
net_device_stats
*
...
@@ -604,7 +613,7 @@ islpci_statistics(struct net_device *ndev)
...
@@ -604,7 +613,7 @@ islpci_statistics(struct net_device *ndev)
islpci_private
*
priv
=
netdev_priv
(
ndev
);
islpci_private
*
priv
=
netdev_priv
(
ndev
);
#if VERBOSE > SHOW_ERROR_MESSAGES
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG
(
SHOW_FUNCTION_CALLS
,
"islpci_statistics
\n
"
);
DEBUG
(
SHOW_FUNCTION_CALLS
,
"islpci_statistics
\n
"
);
#endif
#endif
return
&
priv
->
statistics
;
return
&
priv
->
statistics
;
...
@@ -830,6 +839,12 @@ islpci_setup(struct pci_dev *pdev)
...
@@ -830,6 +839,12 @@ islpci_setup(struct pci_dev *pdev)
priv
->
ndev
->
type
=
(
priv
->
iw_mode
==
IW_MODE_MONITOR
)
?
priv
->
ndev
->
type
=
(
priv
->
iw_mode
==
IW_MODE_MONITOR
)
?
priv
->
monitor_type
:
ARPHRD_ETHER
;
priv
->
monitor_type
:
ARPHRD_ETHER
;
#if WIRELESS_EXT > 16
/* Add pointers to enable iwspy support. */
priv
->
wireless_data
.
spy_data
=
&
priv
->
spy_data
;
ndev
->
wireless_data
=
&
priv
->
wireless_data
;
#endif
/* WIRELESS_EXT > 16 */
/* save the start and end address of the PCI memory area */
/* save the start and end address of the PCI memory area */
ndev
->
mem_start
=
(
unsigned
long
)
priv
->
device_base
;
ndev
->
mem_start
=
(
unsigned
long
)
priv
->
device_base
;
ndev
->
mem_end
=
ndev
->
mem_start
+
ISL38XX_PCI_MEM_SIZE
;
ndev
->
mem_end
=
ndev
->
mem_start
+
ISL38XX_PCI_MEM_SIZE
;
...
...
drivers/net/wireless/prism54/islpci_dev.h
View file @
74f54248
...
@@ -100,6 +100,10 @@ typedef struct {
...
@@ -100,6 +100,10 @@ typedef struct {
struct
iw_spy_data
spy_data
;
/* iwspy support */
struct
iw_spy_data
spy_data
;
/* iwspy support */
#if WIRELESS_EXT > 16
struct
iw_public_data
wireless_data
;
#endif
/* WIRELESS_EXT > 16 */
int
monitor_type
;
/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
int
monitor_type
;
/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
struct
islpci_acl
acl
;
struct
islpci_acl
acl
;
...
...
drivers/net/wireless/prism54/islpci_eth.c
View file @
74f54248
...
@@ -508,11 +508,12 @@ islpci_eth_tx_timeout(struct net_device *ndev)
...
@@ -508,11 +508,12 @@ islpci_eth_tx_timeout(struct net_device *ndev)
/* increment the transmit error counter */
/* increment the transmit error counter */
statistics
->
tx_errors
++
;
statistics
->
tx_errors
++
;
printk
(
KERN_WARNING
"%s: tx_timeout"
,
ndev
->
name
);
if
(
!
priv
->
reset_task_pending
)
{
if
(
!
priv
->
reset_task_pending
)
{
priv
->
reset_task_pending
=
1
;
priv
->
reset_task_pending
=
1
;
printk
(
", scheduling a reset"
);
netif_stop_queue
(
ndev
);
netif_stop_queue
(
ndev
);
schedule_work
(
&
priv
->
reset_task
);
schedule_work
(
&
priv
->
reset_task
);
}
}
printk
(
"
\n
"
);
return
;
}
}
drivers/net/wireless/prism54/islpci_hotplug.c
View file @
74f54248
...
@@ -107,9 +107,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
...
@@ -107,9 +107,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
islpci_private
*
priv
;
islpci_private
*
priv
;
int
rvalue
;
int
rvalue
;
/* TRACE(DRV_NAME); */
/* Enable the pci device */
/* Enable the pci device */
if
(
pci_enable_device
(
pdev
))
{
if
(
pci_enable_device
(
pdev
))
{
printk
(
KERN_ERR
"%s: pci_enable_device() failed.
\n
"
,
DRV_NAME
);
printk
(
KERN_ERR
"%s: pci_enable_device() failed.
\n
"
,
DRV_NAME
);
...
...
drivers/net/wireless/prism54/islpci_mgt.c
View file @
74f54248
...
@@ -473,6 +473,7 @@ islpci_mgt_transaction(struct net_device *ndev,
...
@@ -473,6 +473,7 @@ islpci_mgt_transaction(struct net_device *ndev,
int
timeleft
;
int
timeleft
;
struct
islpci_mgmtframe
*
frame
;
struct
islpci_mgmtframe
*
frame
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
timeleft
=
schedule_timeout
(
wait_cycle_jiffies
);
timeleft
=
schedule_timeout
(
wait_cycle_jiffies
);
frame
=
xchg
(
&
priv
->
mgmt_received
,
NULL
);
frame
=
xchg
(
&
priv
->
mgmt_received
,
NULL
);
if
(
frame
)
{
if
(
frame
)
{
...
...
drivers/net/wireless/prism54/islpci_mgt.h
View file @
74f54248
...
@@ -31,8 +31,6 @@
...
@@ -31,8 +31,6 @@
#define K_DEBUG(f, m, args...) do { if(f & m) printk(KERN_DEBUG args); } while(0)
#define K_DEBUG(f, m, args...) do { if(f & m) printk(KERN_DEBUG args); } while(0)
#define DEBUG(f, args...) K_DEBUG(f, pc_debug, args)
#define DEBUG(f, args...) K_DEBUG(f, pc_debug, args)
#define TRACE(devname) K_DEBUG(SHOW_TRACING, VERBOSE, "%s: -> " __FUNCTION__ "()\n", devname)
extern
int
pc_debug
;
extern
int
pc_debug
;
#define init_wds 0
/* help compiler optimize away dead code */
#define init_wds 0
/* help compiler optimize away dead code */
...
...
drivers/net/wireless/prism54/oid_mgt.c
View file @
74f54248
...
@@ -201,7 +201,8 @@ struct oid_t isl_oid[] = {
...
@@ -201,7 +201,8 @@ struct oid_t isl_oid[] = {
OID_U32
(
DOT11_OID_STATIMEOUT
,
0x19000000
),
OID_U32
(
DOT11_OID_STATIMEOUT
,
0x19000000
),
OID_U32_C
(
DOT11_OID_MLMEAUTOLEVEL
,
0x19000001
),
OID_U32_C
(
DOT11_OID_MLMEAUTOLEVEL
,
0x19000001
),
OID_U32
(
DOT11_OID_BSSTIMEOUT
,
0x19000002
),
OID_U32
(
DOT11_OID_BSSTIMEOUT
,
0x19000002
),
OID_UNKNOWN
(
DOT11_OID_ATTACHMENT
,
0x19000003
),
[
DOT11_OID_ATTACHMENT
]
=
{
0x19000003
,
0
,
sizeof
(
struct
obj_attachment
),
OID_TYPE_ATTACH
},
OID_STRUCT_C
(
DOT11_OID_PSMBUFFER
,
0x19000004
,
struct
obj_buffer
,
OID_STRUCT_C
(
DOT11_OID_PSMBUFFER
,
0x19000004
,
struct
obj_buffer
,
OID_TYPE_BUFFER
),
OID_TYPE_BUFFER
),
...
@@ -329,6 +330,12 @@ mgt_le_to_cpu(int type, void *data)
...
@@ -329,6 +330,12 @@ mgt_le_to_cpu(int type, void *data)
mlme
->
size
=
le16_to_cpu
(
mlme
->
size
);
mlme
->
size
=
le16_to_cpu
(
mlme
->
size
);
break
;
break
;
}
}
case
OID_TYPE_ATTACH
:{
struct
obj_attachment
*
attach
=
data
;
attach
->
id
=
le16_to_cpu
(
attach
->
id
);
attach
->
size
=
le16_to_cpu
(
attach
->
size
);;
break
;
}
case
OID_TYPE_SSID
:
case
OID_TYPE_SSID
:
case
OID_TYPE_KEY
:
case
OID_TYPE_KEY
:
case
OID_TYPE_ADDR
:
case
OID_TYPE_ADDR
:
...
@@ -392,6 +399,12 @@ mgt_cpu_to_le(int type, void *data)
...
@@ -392,6 +399,12 @@ mgt_cpu_to_le(int type, void *data)
mlme
->
size
=
cpu_to_le16
(
mlme
->
size
);
mlme
->
size
=
cpu_to_le16
(
mlme
->
size
);
break
;
break
;
}
}
case
OID_TYPE_ATTACH
:{
struct
obj_attachment
*
attach
=
data
;
attach
->
id
=
cpu_to_le16
(
attach
->
id
);
attach
->
size
=
cpu_to_le16
(
attach
->
size
);;
break
;
}
case
OID_TYPE_SSID
:
case
OID_TYPE_SSID
:
case
OID_TYPE_KEY
:
case
OID_TYPE_KEY
:
case
OID_TYPE_ADDR
:
case
OID_TYPE_ADDR
:
...
@@ -465,6 +478,42 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
...
@@ -465,6 +478,42 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
return
ret
;
return
ret
;
}
}
/* None of these are cached */
int
mgt_set_varlen
(
islpci_private
*
priv
,
enum
oid_num_t
n
,
void
*
data
,
int
extra_len
)
{
int
ret
=
0
;
struct
islpci_mgmtframe
*
response
;
int
response_op
=
PIMFOR_OP_ERROR
;
int
dlen
;
u32
oid
;
BUG_ON
(
OID_NUM_LAST
<=
n
);
dlen
=
isl_oid
[
n
].
size
;
oid
=
isl_oid
[
n
].
oid
;
mgt_cpu_to_le
(
isl_oid
[
n
].
flags
&
OID_FLAG_TYPE
,
data
);
if
(
islpci_get_state
(
priv
)
>=
PRV_STATE_READY
)
{
ret
=
islpci_mgt_transaction
(
priv
->
ndev
,
PIMFOR_OP_SET
,
oid
,
data
,
dlen
+
extra_len
,
&
response
);
if
(
!
ret
)
{
response_op
=
response
->
header
->
operation
;
islpci_mgt_release
(
response
);
}
if
(
ret
||
response_op
==
PIMFOR_OP_ERROR
)
ret
=
-
EIO
;
}
else
ret
=
-
EIO
;
/* re-set given data to what it was */
if
(
data
)
mgt_le_to_cpu
(
isl_oid
[
n
].
flags
&
OID_FLAG_TYPE
,
data
);
return
ret
;
}
int
int
mgt_get_request
(
islpci_private
*
priv
,
enum
oid_num_t
n
,
int
extra
,
void
*
data
,
mgt_get_request
(
islpci_private
*
priv
,
enum
oid_num_t
n
,
int
extra
,
void
*
data
,
union
oid_res_t
*
res
)
union
oid_res_t
*
res
)
...
@@ -555,15 +604,18 @@ mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n)
...
@@ -555,15 +604,18 @@ mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n)
u32
oid
=
t
->
oid
;
u32
oid
=
t
->
oid
;
BUG_ON
(
data
==
NULL
);
BUG_ON
(
data
==
NULL
);
while
(
j
<=
t
->
range
)
{
while
(
j
<=
t
->
range
)
{
response
=
NULL
;
int
r
=
islpci_mgt_transaction
(
priv
->
ndev
,
PIMFOR_OP_SET
,
ret
|=
islpci_mgt_transaction
(
priv
->
ndev
,
PIMFOR_OP_SET
,
oid
,
data
,
t
->
size
,
oid
,
data
,
t
->
size
,
&
response
);
&
response
);
if
(
response
)
{
if
(
response
)
{
ret
|=
(
response
->
header
->
operation
==
r
|=
(
response
->
header
->
operation
==
PIMFOR_OP_ERROR
);
PIMFOR_OP_ERROR
);
islpci_mgt_release
(
response
);
islpci_mgt_release
(
response
);
}
}
if
(
r
)
printk
(
KERN_ERR
"%s: mgt_commit_list: failure. "
"oid=%08x err=%d
\n
"
,
priv
->
ndev
->
name
,
oid
,
r
);
ret
|=
r
;
j
++
;
j
++
;
oid
++
;
oid
++
;
data
+=
t
->
size
;
data
+=
t
->
size
;
...
@@ -624,7 +676,7 @@ static enum oid_num_t commit_part2[] = {
...
@@ -624,7 +676,7 @@ static enum oid_num_t commit_part2[] = {
static
int
static
int
mgt_update_addr
(
islpci_private
*
priv
)
mgt_update_addr
(
islpci_private
*
priv
)
{
{
struct
islpci_mgmtframe
*
res
=
NULL
;
struct
islpci_mgmtframe
*
res
;
int
ret
;
int
ret
;
ret
=
islpci_mgt_transaction
(
priv
->
ndev
,
PIMFOR_OP_GET
,
ret
=
islpci_mgt_transaction
(
priv
->
ndev
,
PIMFOR_OP_GET
,
...
@@ -638,26 +690,26 @@ mgt_update_addr(islpci_private *priv)
...
@@ -638,26 +690,26 @@ mgt_update_addr(islpci_private *priv)
if
(
res
)
if
(
res
)
islpci_mgt_release
(
res
);
islpci_mgt_release
(
res
);
if
(
ret
)
printk
(
KERN_ERR
"%s: mgt_update_addr: failure
\n
"
,
priv
->
ndev
->
name
);
return
ret
;
return
ret
;
}
}
void
#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
int
mgt_commit
(
islpci_private
*
priv
)
mgt_commit
(
islpci_private
*
priv
)
{
{
int
rvalue
;
int
rvalue
;
u32
u
;
u32
u
;
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
return
;
return
0
;
rvalue
=
mgt_commit_list
(
priv
,
commit_part1
,
rvalue
=
mgt_commit_list
(
priv
,
commit_part1
,
VEC_SIZE
(
commit_part1
));
sizeof
(
commit_part1
)
/
sizeof
(
commit_part1
[
0
]));
if
(
priv
->
iw_mode
!=
IW_MODE_MONITOR
)
if
(
priv
->
iw_mode
!=
IW_MODE_MONITOR
)
rvalue
|=
mgt_commit_list
(
priv
,
commit_part2
,
rvalue
|=
mgt_commit_list
(
priv
,
commit_part2
,
VEC_SIZE
(
commit_part2
));
sizeof
(
commit_part2
)
/
sizeof
(
commit_part2
[
0
]));
u
=
OID_INL_MODE
;
u
=
OID_INL_MODE
;
rvalue
|=
mgt_commit_list
(
priv
,
&
u
,
1
);
rvalue
|=
mgt_commit_list
(
priv
,
&
u
,
1
);
...
@@ -666,9 +718,43 @@ mgt_commit(islpci_private *priv)
...
@@ -666,9 +718,43 @@ mgt_commit(islpci_private *priv)
if
(
rvalue
)
{
if
(
rvalue
)
{
/* some request have failed. The device might be in an
/* some request have failed. The device might be in an
incoherent state. We should reset it ! */
incoherent state. We should reset it ! */
printk
(
KERN_DEBUG
"%s: mgt_commit has failed. Restart the "
printk
(
KERN_DEBUG
"%s: mgt_commit: failure
\n
"
,
priv
->
ndev
->
name
);
"device
\n
"
,
priv
->
ndev
->
name
);
}
}
return
rvalue
;
}
/* The following OIDs need to be "unlatched":
*
* MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
* FREQUENCY,EXTENDEDRATES.
*
* The way to do this is to set ESSID. Note though that they may get
* unlatch before though by setting another OID. */
void
mgt_unlatch_all
(
islpci_private
*
priv
)
{
u32
u
;
int
rvalue
=
0
;
if
(
islpci_get_state
(
priv
)
<
PRV_STATE_INIT
)
return
;
u
=
DOT11_OID_SSID
;
rvalue
=
mgt_commit_list
(
priv
,
&
u
,
1
);
/* Necessary if in MANUAL RUN mode? */
#if 0
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
u = DOT11_OID_MLMEAUTOLEVEL;
rvalue |= mgt_commit_list(priv, &u, 1);
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
#endif
if
(
rvalue
)
printk
(
KERN_DEBUG
"%s: Unlatching OIDs failed
\n
"
,
priv
->
ndev
->
name
);
}
}
/* This will tell you if you are allowed to answer a mlme(ex) request .*/
/* This will tell you if you are allowed to answer a mlme(ex) request .*/
...
@@ -771,6 +857,14 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
...
@@ -771,6 +857,14 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
mlme
->
state
,
mlme
->
code
,
mlme
->
size
);
mlme
->
state
,
mlme
->
code
,
mlme
->
size
);
}
}
break
;
break
;
case
OID_TYPE_ATTACH
:{
struct
obj_attachment
*
attach
=
r
->
ptr
;
return
snprintf
(
str
,
PRIV_STR_SIZE
,
"id=%d
\n
size=%d
\n
"
,
attach
->
id
,
attach
->
size
);
}
break
;
case
OID_TYPE_SSID
:{
case
OID_TYPE_SSID
:{
struct
obj_ssid
*
ssid
=
r
->
ptr
;
struct
obj_ssid
*
ssid
=
r
->
ptr
;
return
snprintf
(
str
,
PRIV_STR_SIZE
,
return
snprintf
(
str
,
PRIV_STR_SIZE
,
...
...
drivers/net/wireless/prism54/oid_mgt.h
View file @
74f54248
...
@@ -36,6 +36,8 @@ int channel_of_freq(int);
...
@@ -36,6 +36,8 @@ int channel_of_freq(int);
void
mgt_le_to_cpu
(
int
,
void
*
);
void
mgt_le_to_cpu
(
int
,
void
*
);
int
mgt_set_request
(
islpci_private
*
,
enum
oid_num_t
,
int
,
void
*
);
int
mgt_set_request
(
islpci_private
*
,
enum
oid_num_t
,
int
,
void
*
);
int
mgt_set_varlen
(
islpci_private
*
,
enum
oid_num_t
,
void
*
,
int
);
int
mgt_get_request
(
islpci_private
*
,
enum
oid_num_t
,
int
,
void
*
,
int
mgt_get_request
(
islpci_private
*
,
enum
oid_num_t
,
int
,
void
*
,
union
oid_res_t
*
);
union
oid_res_t
*
);
...
@@ -46,7 +48,8 @@ void mgt_set(islpci_private *, enum oid_num_t, void *);
...
@@ -46,7 +48,8 @@ void mgt_set(islpci_private *, enum oid_num_t, void *);
void
mgt_get
(
islpci_private
*
,
enum
oid_num_t
,
void
*
);
void
mgt_get
(
islpci_private
*
,
enum
oid_num_t
,
void
*
);
void
mgt_commit
(
islpci_private
*
);
int
mgt_commit
(
islpci_private
*
);
void
mgt_unlatch_all
(
islpci_private
*
);
int
mgt_mlme_answer
(
islpci_private
*
);
int
mgt_mlme_answer
(
islpci_private
*
);
...
...
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