Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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
Hide 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
(
pdev
,
IORESOURCE_MEM
,
0
);
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
;
NCR_0
|=
NCR_ENET_OSC_EN
;
#endif
ret
=
smc_enable_device
(
ext
->
start
);
if
(
ret
)
goto
release_both
;
}
ret
=
smc_enable_device
(
pdev
);
if
(
ret
)
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