Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
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