Skip to content

Commit

Permalink
MN10300: ASB2364: Add support for SMSC911X and SMC911X
Browse files Browse the repository at this point in the history
Add support for SMSC911X and SMC911X for the ASB2364 unit.

Signed-off-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com>
Signed-off-by: Kiyoshi Owada <owada.kiyoshi@jp.panasonic.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: steve.glendinning@smsc.com
cc: netdev@vger.kernel.org
  • Loading branch information
Akira Takeuchi authored and David Howells committed Oct 27, 2010
1 parent 6044cf1 commit 62747cd
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 3 deletions.
1 change: 1 addition & 0 deletions arch/mn10300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ config MN10300_UNIT_ASB2305

config MN10300_UNIT_ASB2364
bool "ASB2364"
select SMSC911X_ARCH_HOOKS if SMSC911X

endchoice

Expand Down
1 change: 1 addition & 0 deletions arch/mn10300/include/asm/smsc911x.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <unit/smsc911x.h>
2 changes: 2 additions & 0 deletions arch/mn10300/unit-asb2364/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
# Note 2! The CFLAGS definitions are now in the main makefile...

obj-y := unit-init.o leds.o irq-fpga.o

obj-$(CONFIG_SMSC911X) += smsc911x.o
171 changes: 171 additions & 0 deletions arch/mn10300/unit-asb2364/include/unit/smsc911x.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/* Support for the SMSC911x NIC
*
* Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_UNIT_SMSC911X_H
#define _ASM_UNIT_SMSC911X_H

#include <linux/netdevice.h>
#include <proc/irq.h>
#include <unit/fpga-regs.h>

#define MN10300_USE_EXT_EEPROM


#define SMSC911X_BASE 0xA8000000UL
#define SMSC911X_BASE_END 0xA8000100UL
#define SMSC911X_IRQ FPGA_LAN_IRQ

/*
* Allow the FPGA to be initialised by the SMSC911x driver
*/
#undef SMSC_INITIALIZE
#define SMSC_INITIALIZE() \
do { \
/* release reset */ \
ASB2364_FPGA_REG_RESET_LAN = 0x0001; \
SyncExBus(); \
} while (0)

#ifdef MN10300_USE_EXT_EEPROM
#include <linux/delay.h>
#include <unit/clock.h>

#define EEPROM_ADDRESS 0xA0
#define MAC_OFFSET 0x0008
#define USE_IIC_CH 0 /* 0 or 1 */
#define IIC_OFFSET (0x80000 * USE_IIC_CH)
#define IIC_DTRM __SYSREG(0xd8400000 + IIC_OFFSET, u32)
#define IIC_DREC __SYSREG(0xd8400004 + IIC_OFFSET, u32)
#define IIC_MYADD __SYSREG(0xd8400008 + IIC_OFFSET, u32)
#define IIC_CLK __SYSREG(0xd840000c + IIC_OFFSET, u32)
#define IIC_BRST __SYSREG(0xd8400010 + IIC_OFFSET, u32)
#define IIC_HOLD __SYSREG(0xd8400014 + IIC_OFFSET, u32)
#define IIC_BSTS __SYSREG(0xd8400018 + IIC_OFFSET, u32)
#define IIC_ICR __SYSREG(0xd4000080 + 4 * USE_IIC_CH, u16)

#define IIC_CLK_PLS ((unsigned short)(MN10300_IOCLK / 100000 - 1))
#define IIC_CLK_LOW ((unsigned short)(IIC_CLK_PLS / 2))

#define SYS_IIC_DTRM_Bit_STA ((unsigned short)0x0400)
#define SYS_IIC_DTRM_Bit_STO ((unsigned short)0x0200)
#define SYS_IIC_DTRM_Bit_ACK ((unsigned short)0x0100)
#define SYS_IIC_DTRM_Bit_DATA ((unsigned short)0x00FF)

static inline void POLL_INT_REQ(volatile u16 *icr)
{
unsigned long flags;
u16 tmp;

while (!(*icr & GxICR_REQUEST))
;
flags = arch_local_cli_save();
tmp = *icr;
*icr = (tmp & GxICR_LEVEL) | GxICR_DETECT;
tmp = *icr;
arch_local_irq_restore(flags);
}

/*
* Implement the SMSC911x hook for MAC address retrieval
*/
#undef smsc_get_mac
static inline int smsc_get_mac(struct net_device *dev)
{
unsigned char *mac_buf = dev->dev_addr;
int i;
unsigned short value;
unsigned int data;
int mac_length = 6;
int check;
u16 orig_gicr, tmp;
unsigned long flags;

/* save original GnICR and clear GnICR.IE */
flags = arch_local_cli_save();
orig_gicr = IIC_ICR;
IIC_ICR = orig_gicr & GxICR_LEVEL;
tmp = IIC_ICR;
arch_local_irq_restore(flags);

IIC_MYADD = 0x00000008;
IIC_CLK = (IIC_CLK_LOW << 16) + (IIC_CLK_PLS);
/* bus hung recovery */

while (1) {
check = 0;
for (i = 0; i < 3; i++) {
if ((IIC_BSTS & 0x00000003) == 0x00000003)
check++;
udelay(3);
}

if (check == 3) {
IIC_BRST = 0x00000003;
break;
} else {
for (i = 0; i < 3; i++) {
IIC_BRST = 0x00000002;
udelay(8);
IIC_BRST = 0x00000003;
udelay(8);
}
}
}

IIC_BRST = 0x00000002;
IIC_BRST = 0x00000003;

value = SYS_IIC_DTRM_Bit_STA | SYS_IIC_DTRM_Bit_ACK;
value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
(unsigned short)0x0000);
IIC_DTRM = value;
POLL_INT_REQ(&IIC_ICR);

/** send offset of MAC address in EEPROM **/
IIC_DTRM = (unsigned char)((MAC_OFFSET & 0xFF00) >> 8);
POLL_INT_REQ(&IIC_ICR);

IIC_DTRM = (unsigned char)(MAC_OFFSET & 0x00FF);
POLL_INT_REQ(&IIC_ICR);

udelay(1000);

value = SYS_IIC_DTRM_Bit_STA;
value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
(unsigned short)0x0001);
IIC_DTRM = value;
POLL_INT_REQ(&IIC_ICR);

IIC_DTRM = 0x00000000;
while (mac_length > 0) {
POLL_INT_REQ(&IIC_ICR);

data = IIC_DREC;
mac_length--;
if (mac_length == 0)
value = 0x00000300; /* stop IIC bus */
else if (mac_length == 1)
value = 0x00000100; /* no ack */
else
value = 0x00000000; /* ack */
IIC_DTRM = value;
*mac_buf++ = (unsigned char)(data & 0xff);
}

/* restore GnICR.LV and GnICR.IE */
flags = arch_local_cli_save();
IIC_ICR = (orig_gicr & (GxICR_LEVEL | GxICR_ENABLE));
tmp = IIC_ICR;
arch_local_irq_restore(flags);

return 0;
}
#endif /* MN10300_USE_EXT_EEPROM */
#endif /* _ASM_UNIT_SMSC911X_H */
58 changes: 58 additions & 0 deletions arch/mn10300/unit-asb2364/smsc911x.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* Specification for the SMSC911x NIC
*
* Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/smsc911x.h>
#include <unit/smsc911x.h>

static struct smsc911x_platform_config smsc911x_config = {
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
.flags = SMSC911X_USE_32BIT,
};

static struct resource smsc911x_resources[] = {
[0] = {
.start = SMSC911X_BASE,
.end = SMSC911X_BASE_END,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = SMSC911X_IRQ,
.end = SMSC911X_IRQ,
.flags = IORESOURCE_IRQ,
},
};

static struct platform_device smsc911x_device = {
.name = "smsc911x",
.id = 0,
.num_resources = ARRAY_SIZE(smsc911x_resources),
.resource = smsc911x_resources,
.dev = {
.platform_data = &smsc911x_config,
}
};

/*
* add platform devices
*/
static int __init unit_device_init(void)
{
platform_device_register(&smsc911x_device);
return 0;
}

device_initcall(unit_device_init);
12 changes: 10 additions & 2 deletions drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,7 @@ config SMC911X
tristate "SMSC LAN911[5678] support"
select CRC32
select MII
depends on ARM || SUPERH
depends on ARM || SUPERH || MN10300
help
This is a driver for SMSC's LAN911x series of Ethernet chipsets
including the new LAN9115, LAN9116, LAN9117, and LAN9118.
Expand All @@ -1055,7 +1055,7 @@ config SMC911X

config SMSC911X
tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
depends on ARM || SUPERH || BLACKFIN || MIPS
depends on ARM || SUPERH || BLACKFIN || MIPS || MN10300
select CRC32
select MII
select PHYLIB
Expand All @@ -1067,6 +1067,14 @@ config SMSC911X
<file:Documentation/networking/net-modules.txt>. The module
will be called smsc911x.

config SMSC911X_ARCH_HOOKS
def_bool n
depends on SMSC911X
help
If the arch enables this, it allows the arch to implement various
hooks for more comprehensive interrupt control and also to override
the source of the MAC address.

config NET_VENDOR_RACAL
bool "Racal-Interlan (Micom) NI cards"
depends on ISA
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/smsc911x.c
Original file line number Diff line number Diff line change
Expand Up @@ -2075,7 +2075,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
} else {
/* Try reading mac address from device. if EEPROM is present
* it will already have been set */
smsc911x_read_mac_address(dev);
smsc_get_mac(dev);

if (is_valid_ether_addr(dev->dev_addr)) {
/* eeprom values are valid so use them */
Expand Down Expand Up @@ -2176,6 +2176,7 @@ static struct platform_driver smsc911x_driver = {
/* Entry point for loading the module */
static int __init smsc911x_init_module(void)
{
SMSC_INITIALIZE();
return platform_driver_register(&smsc911x_driver);
}

Expand Down
11 changes: 11 additions & 0 deletions drivers/net/smsc911x.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,15 @@
#define LPA_PAUSE_ALL (LPA_PAUSE_CAP | \
LPA_PAUSE_ASYM)

/*
* Provide hooks to let the arch add to the initialisation procedure
* and to override the source of the MAC address.
*/
#define SMSC_INITIALIZE() do {} while (0)
#define smsc_get_mac(dev) smsc911x_read_mac_address((dev))

#ifdef CONFIG_SMSC911X_ARCH_HOOKS
#include <asm/smsc911x.h>
#endif

#endif /* __SMSC911X_H__ */

0 comments on commit 62747cd

Please sign in to comment.