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
30be2b69
Commit
30be2b69
authored
Mar 05, 2005
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge pobox.com:/garz/repo/netdev-2.6/smc91x
into pobox.com:/garz/repo/net-drivers-2.6
parents
56ca2948
955bd9bb
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
258 additions
and
100 deletions
+258
-100
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/lubbock.c
+2
-0
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/neponset.c
+2
-0
drivers/net/smc91x.c
drivers/net/smc91x.c
+182
-93
drivers/net/smc91x.h
drivers/net/smc91x.h
+72
-7
No files found.
arch/arm/mach-pxa/lubbock.c
View file @
30be2b69
...
...
@@ -138,6 +138,7 @@ static struct platform_device sa1111_device = {
static
struct
resource
smc91x_resources
[]
=
{
[
0
]
=
{
.
name
=
"smc91x-regs"
,
.
start
=
0x0c000000
,
.
end
=
0x0c0fffff
,
.
flags
=
IORESOURCE_MEM
,
...
...
@@ -148,6 +149,7 @@ static struct resource smc91x_resources[] = {
.
flags
=
IORESOURCE_IRQ
,
},
[
2
]
=
{
.
name
=
"smc91x-attrib"
,
.
start
=
0x0e000000
,
.
end
=
0x0e0fffff
,
.
flags
=
IORESOURCE_MEM
,
...
...
arch/arm/mach-sa1100/neponset.c
View file @
30be2b69
...
...
@@ -266,6 +266,7 @@ static struct platform_device sa1111_device = {
static
struct
resource
smc91x_resources
[]
=
{
[
0
]
=
{
.
name
=
"smc91x-regs"
,
.
start
=
SA1100_CS3_PHYS
,
.
end
=
SA1100_CS3_PHYS
+
0x01ffffff
,
.
flags
=
IORESOURCE_MEM
,
...
...
@@ -276,6 +277,7 @@ static struct resource smc91x_resources[] = {
.
flags
=
IORESOURCE_IRQ
,
},
[
2
]
=
{
.
name
=
"smc91x-attrib"
,
.
start
=
SA1100_CS3_PHYS
+
0x02000000
,
.
end
=
SA1100_CS3_PHYS
+
0x03ffffff
,
.
flags
=
IORESOURCE_MEM
,
...
...
drivers/net/smc91x.c
View file @
30be2b69
...
...
@@ -210,10 +210,15 @@ struct smc_local {
spinlock_t
lock
;
#ifdef SMC_CAN_USE_DATACS
u32
__iomem
*
datacs
;
#endif
#ifdef SMC_USE_PXA_DMA
/* DMA needs the physical address of the chip */
u_long
physaddr
;
#endif
void
__iomem
*
base
;
};
#if SMC_DEBUG > 0
...
...
@@ -307,8 +312,8 @@ static void PRINT_PKT(u_char *buf, int length)
*/
static
void
smc_reset
(
struct
net_device
*
dev
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
ctl
,
cfg
;
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
...
@@ -399,8 +404,8 @@ static void smc_reset(struct net_device *dev)
*/
static
void
smc_enable
(
struct
net_device
*
dev
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
int
mask
;
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
...
@@ -433,8 +438,8 @@ static void smc_enable(struct net_device *dev)
*/
static
void
smc_shutdown
(
struct
net_device
*
dev
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
DBG
(
2
,
"%s: %s
\n
"
,
CARDNAME
,
__FUNCTION__
);
...
...
@@ -462,7 +467,7 @@ static void smc_shutdown(struct net_device *dev)
static
inline
void
smc_rcv
(
struct
net_device
*
dev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
packet_number
,
status
,
packet_len
;
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
...
@@ -483,7 +488,19 @@ static inline void smc_rcv(struct net_device *dev)
dev
->
name
,
packet_number
,
status
,
packet_len
,
packet_len
);
if
(
unlikely
(
status
&
RS_ERRORS
))
{
back:
if
(
unlikely
(
packet_len
<
6
||
status
&
RS_ERRORS
))
{
if
(
status
&
RS_TOOLONG
&&
packet_len
<=
(
1514
+
4
+
6
))
{
/* accept VLAN packets */
status
&=
~
RS_TOOLONG
;
goto
back
;
}
if
(
packet_len
<
6
)
{
/* bloody hardware */
printk
(
KERN_ERR
"%s: fubar (rxlen %u status %x
\n
"
,
dev
->
name
,
packet_len
,
status
);
status
|=
RS_TOOSHORT
;
}
SMC_WAIT_MMU_BUSY
();
SMC_SET_MMU_CMD
(
MC_RELEASE
);
lp
->
stats
.
rx_errors
++
;
...
...
@@ -508,7 +525,7 @@ static inline void smc_rcv(struct net_device *dev)
* (2 bytes, possibly containing the payload odd byte).
* Furthermore, we add 2 bytes to allow rounding up to
* multiple of 4 bytes on 32 bit buses.
*
E
nce packet_len - 6 + 2 + 2 + 2.
*
He
nce packet_len - 6 + 2 + 2 + 2.
*/
skb
=
dev_alloc_skb
(
packet_len
);
if
(
unlikely
(
skb
==
NULL
))
{
...
...
@@ -596,7 +613,7 @@ static void smc_hardware_send_pkt(unsigned long data)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
data
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
struct
sk_buff
*
skb
;
unsigned
int
packet_no
,
len
;
unsigned
char
*
buf
;
...
...
@@ -680,7 +697,7 @@ done: if (!THROTTLE_TX_PKTS)
static
int
smc_hard_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
numPages
,
poll_count
,
status
;
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
...
@@ -752,8 +769,8 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static
void
smc_tx
(
struct
net_device
*
dev
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
saved_packet
,
packet_no
,
tx_status
,
pkt_len
;
DBG
(
3
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
...
@@ -809,7 +826,8 @@ static void smc_tx(struct net_device *dev)
static
void
smc_mii_out
(
struct
net_device
*
dev
,
unsigned
int
val
,
int
bits
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
mii_reg
,
mask
;
mii_reg
=
SMC_GET_MII
()
&
~
(
MII_MCLK
|
MII_MDOE
|
MII_MDO
);
...
...
@@ -830,7 +848,8 @@ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
static
unsigned
int
smc_mii_in
(
struct
net_device
*
dev
,
int
bits
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
mii_reg
,
mask
,
val
;
mii_reg
=
SMC_GET_MII
()
&
~
(
MII_MCLK
|
MII_MDOE
|
MII_MDO
);
...
...
@@ -854,7 +873,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
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
phydata
;
SMC_SELECT_BANK
(
3
);
...
...
@@ -884,7 +904,8 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
static
void
smc_phy_write
(
struct
net_device
*
dev
,
int
phyaddr
,
int
phyreg
,
int
phydata
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
SMC_SELECT_BANK
(
3
);
...
...
@@ -946,7 +967,7 @@ static void smc_phy_detect(struct net_device *dev)
static
int
smc_phy_fixed
(
struct
net_device
*
dev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
int
phyaddr
=
lp
->
mii
.
phy_id
;
int
bmcr
,
cfg1
;
...
...
@@ -1017,13 +1038,29 @@ static int smc_phy_reset(struct net_device *dev, int phy)
/*
* smc_phy_powerdown - powerdown phy
* @dev: net device
* @phy: phy address
*
* Power down the specified PHY
*/
static
void
smc_phy_powerdown
(
struct
net_device
*
dev
,
int
phy
)
static
void
smc_phy_powerdown
(
struct
net_device
*
dev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
int
bmcr
;
int
phy
=
lp
->
mii
.
phy_id
;
if
(
lp
->
phy_type
==
0
)
return
;
/* We need to ensure that no calls to smc_phy_configure are
pending.
flush_scheduled_work() cannot be called because we are
running with the netlink semaphore held (from
devinet_ioctl()) and the pending work queue contains
linkwatch_event() (scheduled by netif_carrier_off()
above). linkwatch_event() also wants the netlink semaphore.
*/
while
(
lp
->
work_pending
)
schedule
();
bmcr
=
smc_phy_read
(
dev
,
phy
,
MII_BMCR
);
smc_phy_write
(
dev
,
phy
,
MII_BMCR
,
bmcr
|
BMCR_PDOWN
);
...
...
@@ -1040,7 +1077,7 @@ static void smc_phy_powerdown(struct net_device *dev, int phy)
static
void
smc_phy_check_media
(
struct
net_device
*
dev
,
int
init
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
if
(
mii_check_media
(
&
lp
->
mii
,
netif_msg_link
(
lp
),
init
))
{
/* duplex state has changed */
...
...
@@ -1068,7 +1105,7 @@ static void smc_phy_configure(void *data)
{
struct
net_device
*
dev
=
data
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
int
phyaddr
=
lp
->
mii
.
phy_id
;
int
my_phy_caps
;
/* My PHY capabilities */
int
my_ad_caps
;
/* My Advertised capabilities */
...
...
@@ -1193,7 +1230,7 @@ static void smc_phy_interrupt(struct net_device *dev)
static
void
smc_10bt_check_media
(
struct
net_device
*
dev
,
int
init
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
old_carrier
,
new_carrier
;
old_carrier
=
netif_carrier_ok
(
dev
)
?
1
:
0
;
...
...
@@ -1216,7 +1253,8 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
static
void
smc_eph_interrupt
(
struct
net_device
*
dev
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
int
ctl
;
smc_10bt_check_media
(
dev
,
0
);
...
...
@@ -1235,8 +1273,8 @@ static void smc_eph_interrupt(struct net_device *dev)
static
irqreturn_t
smc_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
dev_id
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
lp
->
base
;
int
status
,
mask
,
timeout
,
card_stats
;
int
saved_pointer
;
...
...
@@ -1350,7 +1388,7 @@ static void smc_poll_controller(struct net_device *dev)
static
void
smc_timeout
(
struct
net_device
*
dev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
int
status
,
mask
,
meminfo
,
fifo
;
DBG
(
2
,
"%s: %s
\n
"
,
dev
->
name
,
__FUNCTION__
);
...
...
@@ -1394,7 +1432,7 @@ static void smc_timeout(struct net_device *dev)
static
void
smc_set_multicast_list
(
struct
net_device
*
dev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
unsigned
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
lp
->
base
;
unsigned
char
multicast_table
[
8
];
int
update_multicast
=
0
;
...
...
@@ -1561,21 +1599,7 @@ static int smc_close(struct net_device *dev)
/* clear everything */
smc_shutdown
(
dev
);
if
(
lp
->
phy_type
!=
0
)
{
/* We need to ensure that no calls to
smc_phy_configure are pending.
flush_scheduled_work() cannot be called because we
are running with the netlink semaphore held (from
devinet_ioctl()) and the pending work queue
contains linkwatch_event() (scheduled by
netif_carrier_off() above). linkwatch_event() also
wants the netlink semaphore.
*/
while
(
lp
->
work_pending
)
schedule
();
smc_phy_powerdown
(
dev
,
lp
->
mii
.
phy_id
);
}
smc_phy_powerdown
(
dev
);
if
(
lp
->
pending_tx_skb
)
{
dev_kfree_skb
(
lp
->
pending_tx_skb
);
...
...
@@ -1723,7 +1747,7 @@ static struct ethtool_ops smc_ethtool_ops = {
* I just deleted auto_irq.c, since it was never built...
* --jgarzik
*/
static
int
__init
smc_findirq
(
unsigned
long
ioaddr
)
static
int
__init
smc_findirq
(
void
__iomem
*
ioaddr
)
{
int
timeout
=
20
;
unsigned
long
cookie
;
...
...
@@ -1796,7 +1820,7 @@ static int __init smc_findirq(unsigned long ioaddr)
* o actually GRAB the irq.
* o GRAB the region
*/
static
int
__init
smc_probe
(
struct
net_device
*
dev
,
unsigned
long
ioaddr
)
static
int
__init
smc_probe
(
struct
net_device
*
dev
,
void
__iomem
*
ioaddr
)
{
struct
smc_local
*
lp
=
netdev_priv
(
dev
);
static
int
version_printed
=
0
;
...
...
@@ -1813,7 +1837,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
if
((
val
&
0xFF
)
==
0x33
)
{
printk
(
KERN_WARNING
"%s: Detected possible byte-swapped interface"
" at IOADDR
0x%lx
\n
"
,
CARDNAME
,
ioaddr
);
" at IOADDR
%p
\n
"
,
CARDNAME
,
ioaddr
);
}
retval
=
-
ENODEV
;
goto
err_out
;
...
...
@@ -1839,8 +1863,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
SMC_SELECT_BANK
(
1
);
val
=
SMC_GET_BASE
();
val
=
((
val
&
0x1F00
)
>>
3
)
<<
SMC_IO_SHIFT
;
if
((
ioaddr
&
((
PAGE_SIZE
-
1
)
<<
SMC_IO_SHIFT
))
!=
val
)
{
printk
(
"%s: IOADDR %
lx
doesn't match configuration (%x).
\n
"
,
if
((
(
unsigned
long
)
ioaddr
&
((
PAGE_SIZE
-
1
)
<<
SMC_IO_SHIFT
))
!=
val
)
{
/*XXX: WTF? */
printk
(
"%s: IOADDR %
p
doesn't match configuration (%x).
\n
"
,
CARDNAME
,
ioaddr
,
val
);
}
...
...
@@ -1855,7 +1879,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
version_string
=
chip_ids
[
(
revision_register
>>
4
)
&
0xF
];
if
(
!
version_string
||
(
revision_register
&
0xff00
)
!=
0x3300
)
{
/* I don't recognize this chip, so... */
printk
(
"%s: IO
0x%lx
: Unrecognized revision register 0x%04x"
printk
(
"%s: IO
%p
: Unrecognized revision register 0x%04x"
", Contact author.
\n
"
,
CARDNAME
,
ioaddr
,
revision_register
);
...
...
@@ -1868,7 +1892,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
printk
(
"%s"
,
version
);
/* fill in some of the fields */
dev
->
base_addr
=
ioaddr
;
dev
->
base_addr
=
(
unsigned
long
)
ioaddr
;
lp
->
base
=
ioaddr
;
lp
->
version
=
revision_register
&
0xff
;
spin_lock_init
(
&
lp
->
lock
);
...
...
@@ -1974,9 +1999,9 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
retval
=
register_netdev
(
dev
);
if
(
retval
==
0
)
{
/* now, print out the card info, in a short format.. */
printk
(
"%s: %s (rev %d) at %
#lx
IRQ %d"
,
printk
(
"%s: %s (rev %d) at %
p
IRQ %d"
,
dev
->
name
,
version_string
,
revision_register
&
0x0f
,
dev
->
base_addr
,
dev
->
irq
);
lp
->
base
,
dev
->
irq
);
if
(
dev
->
dma
!=
(
unsigned
char
)
-
1
)
printk
(
" DMA %d"
,
dev
->
dma
);
...
...
@@ -2012,16 +2037,21 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
return
retval
;
}
static
int
smc_enable_device
(
unsigned
long
attrib_phys
)
static
int
smc_enable_device
(
struct
platform_device
*
pdev
)
{
unsigned
long
flags
;
unsigned
char
ecor
,
ecsr
;
void
*
addr
;
void
__iomem
*
addr
;
struct
resource
*
res
;
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-attrib"
);
if
(
!
res
)
return
0
;
/*
* Map the attribute space. This is overkill, but clean.
*/
addr
=
ioremap
(
attrib_phys
,
ATTRIB_SIZE
);
addr
=
ioremap
(
res
->
start
,
ATTRIB_SIZE
);
if
(
!
addr
)
return
-
ENOMEM
;
...
...
@@ -2069,6 +2099,62 @@ static int smc_enable_device(unsigned long attrib_phys)
return
0
;
}
static
int
smc_request_attrib
(
struct
platform_device
*
pdev
)
{
struct
resource
*
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-attrib"
);
if
(
!
res
)
return
0
;
if
(
!
request_mem_region
(
res
->
start
,
ATTRIB_SIZE
,
CARDNAME
))
return
-
EBUSY
;
return
0
;
}
static
void
smc_release_attrib
(
struct
platform_device
*
pdev
)
{
struct
resource
*
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-attrib"
);
if
(
res
)
release_mem_region
(
res
->
start
,
ATTRIB_SIZE
);
}
#ifdef SMC_CAN_USE_DATACS
static
void
smc_request_datacs
(
struct
platform_device
*
pdev
,
struct
net_device
*
ndev
)
{
struct
resource
*
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-data32"
);
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
if
(
!
res
)
return
;
if
(
!
request_mem_region
(
res
->
start
,
SMC_DATA_EXTENT
,
CARDNAME
))
{
printk
(
KERN_INFO
"%s: failed to request datacs memory region.
\n
"
,
CARDNAME
);
return
;
}
lp
->
datacs
=
ioremap
(
res
->
start
,
SMC_DATA_EXTENT
);
}
static
void
smc_release_datacs
(
struct
platform_device
*
pdev
,
struct
net_device
*
ndev
)
{
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
struct
resource
*
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-data32"
);
if
(
lp
->
datacs
)
iounmap
(
lp
->
datacs
);
lp
->
datacs
=
NULL
;
if
(
res
)
release_mem_region
(
res
->
start
,
SMC_DATA_EXTENT
);
}
#else
static
void
smc_request_datacs
(
struct
platform_device
*
pdev
,
struct
net_device
*
ndev
)
{}
static
void
smc_release_datacs
(
struct
platform_device
*
pdev
,
struct
net_device
*
ndev
)
{}
#endif
/*
* smc_init(void)
* Input parameters:
...
...
@@ -2084,20 +2170,20 @@ static int smc_drv_probe(struct device *dev)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
net_device
*
ndev
;
struct
resource
*
res
,
*
ext
=
NULL
;
unsigned
int
*
addr
;
struct
resource
*
res
;
unsigned
int
__iomem
*
addr
;
int
ret
;
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-regs"
);
if
(
!
res
)
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res
)
{
ret
=
-
ENODEV
;
goto
out
;
}
/*
* Request the regions.
*/
if
(
!
request_mem_region
(
res
->
start
,
SMC_IO_EXTENT
,
"smc91x"
))
{
if
(
!
request_mem_region
(
res
->
start
,
SMC_IO_EXTENT
,
CARDNAME
))
{
ret
=
-
EBUSY
;
goto
out
;
}
...
...
@@ -2106,7 +2192,7 @@ static int smc_drv_probe(struct device *dev)
if
(
!
ndev
)
{
printk
(
"%s: could not allocate device.
\n
"
,
CARDNAME
);
ret
=
-
ENOMEM
;
goto
release_1
;
goto
out_release_io
;
}
SET_MODULE_OWNER
(
ndev
);
SET_NETDEV_DEV
(
ndev
,
dev
);
...
...
@@ -2114,42 +2200,26 @@ static int smc_drv_probe(struct device *dev)
ndev
->
dma
=
(
unsigned
char
)
-
1
;
ndev
->
irq
=
platform_get_irq
(
pdev
,
0
);
ext
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
1
);
if
(
ext
)
{
if
(
!
request_mem_region
(
ext
->
start
,
ATTRIB_SIZE
,
ndev
->
name
))
{
ret
=
-
EBUSY
;
goto
release_1
;
}
ret
=
smc_request_attrib
(
pdev
);
if
(
ret
)
goto
out_free_netdev
;
#if defined(CONFIG_SA1100_ASSABET)
NCR_0
|=
NCR_ENET_OSC_EN
;
#endif
ret
=
smc_enable_device
(
ext
->
start
);
ret
=
smc_enable_device
(
pdev
);
if
(
ret
)
goto
release_both
;
}
goto
out_release_attrib
;
addr
=
ioremap
(
res
->
start
,
SMC_IO_EXTENT
);
if
(
!
addr
)
{
ret
=
-
ENOMEM
;
goto
release_both
;
goto
out_release_attrib
;
}
dev_set_drvdata
(
dev
,
ndev
);
ret
=
smc_probe
(
ndev
,
(
unsigned
long
)
addr
);
if
(
ret
!=
0
)
{
dev_set_drvdata
(
dev
,
NULL
);
iounmap
(
addr
);
release_both:
if
(
ext
)
release_mem_region
(
ext
->
start
,
ATTRIB_SIZE
);
free_netdev
(
ndev
);
release_1:
release_mem_region
(
res
->
start
,
SMC_IO_EXTENT
);
out:
printk
(
"%s: not found (%d).
\n
"
,
CARDNAME
,
ret
);
}
ret
=
smc_probe
(
ndev
,
addr
);
if
(
ret
!=
0
)
goto
out_iounmap
;
#ifdef SMC_USE_PXA_DMA
else
{
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
...
...
@@ -2157,6 +2227,22 @@ static int smc_drv_probe(struct device *dev)
}
#endif
smc_request_datacs
(
pdev
,
ndev
);
return
0
;
out_iounmap:
dev_set_drvdata
(
dev
,
NULL
);
iounmap
(
addr
);
out_release_attrib:
smc_release_attrib
(
pdev
);
out_free_netdev:
free_netdev
(
ndev
);
out_release_io:
release_mem_region
(
res
->
start
,
SMC_IO_EXTENT
);
out:
printk
(
"%s: not found (%d).
\n
"
,
CARDNAME
,
ret
);
return
ret
;
}
...
...
@@ -2164,6 +2250,7 @@ static int smc_drv_remove(struct device *dev)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
net_device
*
ndev
=
dev_get_drvdata
(
dev
);
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
struct
resource
*
res
;
dev_set_drvdata
(
dev
,
NULL
);
...
...
@@ -2176,11 +2263,14 @@ static int smc_drv_remove(struct device *dev)
if
(
ndev
->
dma
!=
(
unsigned
char
)
-
1
)
pxa_free_dma
(
ndev
->
dma
);
#endif
iounmap
((
void
*
)
ndev
->
base_addr
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
1
);
if
(
res
)
release_mem_region
(
res
->
start
,
ATTRIB_SIZE
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
iounmap
(
lp
->
base
);
smc_release_datacs
(
pdev
,
ndev
);
smc_release_attrib
(
pdev
);
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"smc91x-regs"
);
if
(
!
res
)
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
release_mem_region
(
res
->
start
,
SMC_IO_EXTENT
);
free_netdev
(
ndev
);
...
...
@@ -2196,6 +2286,7 @@ static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
if
(
netif_running
(
ndev
))
{
netif_device_detach
(
ndev
);
smc_shutdown
(
ndev
);
smc_phy_powerdown
(
ndev
);
}
}
return
0
;
...
...
@@ -2208,9 +2299,7 @@ static int smc_drv_resume(struct device *dev, u32 level)
if
(
ndev
&&
level
==
RESUME_ENABLE
)
{
struct
smc_local
*
lp
=
netdev_priv
(
ndev
);
if
(
pdev
->
num_resources
==
3
)
smc_enable_device
(
pdev
->
resource
[
2
].
start
);
smc_enable_device
(
pdev
);
if
(
netif_running
(
ndev
))
{
smc_reset
(
ndev
);
smc_enable
(
ndev
);
...
...
drivers/net/smc91x.h
View file @
30be2b69
...
...
@@ -162,6 +162,26 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
}
}
#elif defined(CONFIG_ARCH_OMAP)
/* We can only do 16-bit reads and writes in the static memory space. */
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
#define SMC_inb(a, r) readb((a) + (r))
#define SMC_outb(v, a, r) writeb(v, (a) + (r))
#define SMC_inw(a, r) readw((a) + (r))
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
#define SMC_inl(a, r) readl((a) + (r))
#define SMC_outl(v, a, r) writel(v, (a) + (r))
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
#elif defined(CONFIG_ISA)
#define SMC_CAN_USE_8BIT 1
...
...
@@ -362,7 +382,7 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
#define SMC_IO_SHIFT 0
#endif
#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT)
#define SMC_DATA_EXTENT (4)
/*
. Bank Select Register:
...
...
@@ -883,7 +903,7 @@ static const char * chip_ids[ 16 ] = {
#endif
#if SMC_CAN_USE_32BIT
#define SMC_PUSH_DATA(p, l) \
#define
_
SMC_PUSH_DATA(p, l) \
do { \
char *__ptr = (p); \
int __len = (l); \
...
...
@@ -898,7 +918,7 @@ static const char * chip_ids[ 16 ] = {
SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
} \
} while (0)
#define SMC_PULL_DATA(p, l) \
#define
_
SMC_PULL_DATA(p, l) \
do { \
char *__ptr = (p); \
int __len = (l); \
...
...
@@ -918,11 +938,11 @@ static const char * chip_ids[ 16 ] = {
SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \
} while (0)
#elif SMC_CAN_USE_16BIT
#define SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
#define SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
#define
_
SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
#define
_
SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
#elif SMC_CAN_USE_8BIT
#define SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
#define SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
#define
_
SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
#define
_
SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
#endif
#if ! SMC_CAN_USE_16BIT
...
...
@@ -941,6 +961,51 @@ static const char * chip_ids[ 16 ] = {
})
#endif
#if SMC_CAN_USE_DATACS
#define SMC_PUSH_DATA(p, l) \
if ( lp->datacs ) { \
unsigned char *__ptr = (p); \
int __len = (l); \
if (__len >= 2 && (unsigned long)__ptr & 2) { \
__len -= 2; \
SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
__ptr += 2; \
} \
outsl(lp->datacs, __ptr, __len >> 2); \
if (__len & 2) { \
__ptr += (__len & ~3); \
SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
} \
} else { \
_SMC_PUSH_DATA(p, l); \
}
#define SMC_PULL_DATA(p, l) \
if ( lp->datacs ) { \
unsigned char *__ptr = (p); \
int __len = (l); \
if ((unsigned long)__ptr & 2) { \
/* \
* We want 32bit alignment here. \
* Since some buses perform a full 32bit \
* fetch even for 16bit data we can't use \
* SMC_inw() here. Back both source (on chip \
* and destination) pointers of 2 bytes. \
*/
\
__ptr -= 2; \
__len += 2; \
SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \
} \
__len += 2; \
insl( lp->datacs, __ptr, __len >> 2); \
} else { \
_SMC_PULL_DATA(p, l); \
}
#else
#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l)
#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l)
#endif
#if !defined (SMC_INTERRUPT_PREAMBLE)
# define SMC_INTERRUPT_PREAMBLE
#endif
...
...
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