|
From: SourceForge.net <no...@so...> - 2003-08-20 07:59:31
|
Bugs item #775368, was opened at 2003-07-21 19:31 Message generated for change (Settings changed) made by smiley73 You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=410643&aid=775368&group_id=34096 >Category: Base System Group: None >Status: Closed >Resolution: Fixed Priority: 5 Submitted By: Heiko Zuerker (smiley73) >Assigned to: Heiko Zuerker (smiley73) Summary: Add support for the ROL-F card. Initial Comment: request from Thomas Eder. http://www.peppercon.com/products/rolf.html He wrote that it works fine on his system --- scripts/config/config_linux 2003-07-12 11:17:03.000000000 +0200 +++ scripts/config/config_linux-patch 2003-07-12 11:12:30.000000000 +0200 @@ -631,7 +631,7 @@ # CONFIG_ES3210 is not set CONFIG_8139CP=m CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_PIO=y # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set diff -Nur linux-2.4.21/drivers/net/8139too.c linux-2.4.21-patch/drivers/net/8139too.c --- linux-2.4.21/drivers/net/8139too.c 2003-06-13 16:51:34.000000000 +0200 +++ linux-2.4.21-patch/drivers/net/8139too.c 2003-06-25 13:27:09.000000000 +0200 @@ -5,6 +5,8 @@ Maintained by Jeff Garzik <jg...@po...> Copyright 2000-2002 Jeff Garzik + ROL/F Support added by Peppercon AG, 2001, 2002, 2003 + Much code comes from Donald Becker's rtl8139.c driver, versions 1.13 and older. This driver was originally based on rtl8139.c version 1.07. Header of rtl8139.c version 1.13: @@ -93,6 +95,7 @@ #define DRV_NAME "8139too" #define DRV_VERSION "0.9.26" +#define ROLF_VERSION "$Revision: 1.2 $" #include <linux/config.h> @@ -113,9 +116,12 @@ #include <asm/io.h> #include <asm/uaccess.h> -#define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION +#define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION " / ROL/F version: " ROLF_VERSION #define PFX DRV_NAME ": " +#ifndef CONFIG_8139TOO_PIO +#error "Please activate "Use PIO instead of MMIO" in the kernel config (e.g. make menuconfig). Useing MMIO doesn't work on some mainbaords." +#endif /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */ #ifdef CONFIG_8139TOO_PIO @@ -128,6 +134,8 @@ /* define to 1 to disable lightweight runtime debugging checks */ #undef RTL8139_NDEBUG +/* undef to disable ROL when interface is down or module is unloaded */ +#define ROLF_ENABLE_ROL_IFDOWN 1 #ifdef RTL8139_DEBUG /* note: prints function name for you */ @@ -199,6 +207,7 @@ HAS_MII_XCVR = 0x010000, HAS_CHIP_XCVR = 0x020000, HAS_LNK_CHNG = 0x040000, + IS_ROLF =0x80000, }; #define RTL_NUM_STATS 4 /* number of ETHTOOL_GSTATS u64's */ @@ -208,12 +217,14 @@ #define RTL8129_CAPS HAS_MII_XCVR #define RTL8139_CAPS HAS_CHIP_XCVR|HAS_LNK_CHNG +#define ROLF_CAPS IS_ROLF|RTL8139_CAPS typedef enum { RTL8139 = 0, RTL8139_CB, SMC1211TX, /*MPX5030,*/ + RTL8139ROLF, DELTA8139, ADDTRON8139, DFE538TX, @@ -235,6 +246,7 @@ { "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS }, { "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS }, /* { MPX5030, "Accton MPX5030 (RealTek RTL8139)", RTL8139_CAPS }, */ + { "Peppercon AG ROL/F (RealTek RTL8139)", ROLF_CAPS }, { "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS }, { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS }, { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS }, @@ -252,6 +264,7 @@ {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139_CB }, {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX }, /* {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/ + {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139ROLF }, {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 }, {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 }, {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX }, @@ -326,6 +339,10 @@ PARA78 = 0x78, PARA7c = 0x7c, /* Magic transceiver parameter register. */ Config5 = 0xD8, /* absent on RTL-8139A */ + PowerManCRC0=0x84, + WakeupMask0=0x8C, + LSBCR0=0xCC, + FlashAccess=0xD4, }; enum ClearBitMasks { @@ -460,6 +477,212 @@ RxNoWrap = (1 << 7), }; +/* begin ROL/F specific */ +#include <linux/delay.h> +static void lat_write(void *ioaddr, long offset, unsigned char data); +static unsigned char lat_read (void *ioaddr, long offset); +void rolf_init(struct net_device *dev); +void rolf_stop(struct net_device *dev); +#define LAT_REG_WDCOUNT 0x00 +#define LAT_REG_CONFIG 0x01 +#define LAT_REG_FLASHADR 0x02 + +/* Register Config Bit Masks */ +#define LAT_CFG_WDGENB 0x01 +#define LAT_CFG_ROLENB 0x02 +#define LAT_CFG_FLASHENB 0x04 +#define LAT_CFG_EMERENB 0x08 + +#define FLASH_DATA_MASK 0xFF000000 +#define FLASH_CSB 0x00100000 +#define FLASH_OEB 0x00080000 +#define FLASH_WEB 0x00040000 +#define FLASH_ENABLE 0x00020000 +#define FLASH_ADDR_MASK 0x0001FFFF +#define LAT_BASE_ADDR 0x0001E000 + +/* defines the offsets of the ROL/F Data in EEPROM */ +#define EEPROM_ROLBASE 0x30 +#define ROLF_CRC8_AND_LASTBYTE 0xA +#define ROLF_DISABLE_ROL 0x9 +#include <linux/miscdevice.h> +#include <linux/fcntl.h> +#include <asm/uaccess.h> +#include <linux/watchdog.h> + +#define RWDIOF_GETSUPPORT 0x1 +#define RWDIOF_GETTIMEOUT 0x2 +#define RWDIOF_SETTIMEOUT 0x4 +#define RWDIOF_KEEPALIVE 0x8 +#define RWDIOF_GETTIMER 0x10 + +static int rolf_wdog_is_open = 0; +static int rolf_wdog_registered = 0; +enum RTL8139_Config_Register +{ + CFG_UNLOCK = 0xC0, + CFG_LOCK = 0x3F, + + CFG1_PMEN = 0x01, + CFG3_MAGIC = 0x20, + CFG4_LWPME = 0x10, + CFG5_LANWAKE = 0x02 +}; +static void *rolf_ioaddr; +static int start = 0xe1; +spinlock_t lattice_lock = SPIN_LOCK_UNLOCKED; + +static void rolf_wdog_ctr_load(unsigned char val) +{ + spin_lock(&lattice_lock); + lat_write(rolf_ioaddr,LAT_REG_WDCOUNT, val); + spin_unlock(&lattice_lock); +} + +static long long rolf_wdog_llseek(struct file *file, long long offset, int origin) +{ + return -ESPIPE; +} + +static void rolf_wdog_ping(void) +{ + /* Write a watchdog value */ + rolf_wdog_ctr_load(start); +#ifdef RTL8139_DEBUG + printk(KERN_INFO "rtl8139: ROL/F Watchdog: Reset Watchdog\n"); +#endif +} + +static ssize_t rolf_wdog_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + if(count) { + rolf_wdog_ping(); + return 1; + } + return 0; +} + +static ssize_t rolf_wdog_read(struct file *file, char *buf, size_t count, loff_t *ptr) +{ + unsigned char cp; + + /* Can't seek (pread) on this device */ + if (ptr != &file->f_pos) + return -ESPIPE; + switch(MINOR(file->f_dentry->d_inode->i_rdev)) { + case WATCHDOG_MINOR: + spin_lock(&lattice_lock); + cp = lat_read(rolf_ioaddr,LAT_REG_WDCOUNT); + spin_unlock(&lattice_lock); + if(copy_to_user(buf,&cp,1)) + return -EFAULT; + return 1; + default: + return -EINVAL; + } +} +static int rolf_wdog_ioctl( struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned char newtimeout; + unsigned char count; + static struct watchdog_info ident= + { + RWDIOF_SETTIMEOUT|RWDIOF_GETTIMEOUT|RWDIOF_KEEPALIVE|RWDIOF_GETSUPPORT|RWDIOF_GETTIMER, + 1, + "ROL/F" + }; + + switch(cmd) + { + default: + return -ENOIOCTLCMD; + case RWDIOF_GETSUPPORT: + return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + case RWDIOF_GETTIMER: + spin_lock(&lattice_lock); + count = lat_read(rolf_ioaddr,LAT_REG_WDCOUNT); + spin_unlock(&lattice_lock); + return put_user( count, (unsigned char *)arg); + case RWDIOF_GETTIMEOUT: + return put_user(0xff-start, (unsigned char *)arg); + case RWDIOF_SETTIMEOUT: + get_user(newtimeout,(unsigned char*) arg); + if (newtimeout > 0) { + printk (KERN_INFO "rtl8139: ROL/F Watchdog: set new Timeout: %u\n",newtimeout); + start = 0xff-newtimeout; + } else { + printk (KERN_INFO "rtl8139: ROL/F Watchdog: reject Timeout: %u\n",newtimeout); + } + case RWDIOF_KEEPALIVE: + rolf_wdog_ping(); + return 0; + } +} + +static int rolf_wdog_open(struct inode *inode, struct file *file) +{ + unsigned char uchControl; + switch(MINOR(inode->i_rdev)) + { + case WATCHDOG_MINOR: + if(rolf_wdog_is_open) + return -EBUSY; + MOD_INC_USE_COUNT; + rolf_wdog_is_open=1; + spin_lock(&lattice_lock); + uchControl = lat_read(rolf_ioaddr,LAT_REG_CONFIG); + uchControl |= LAT_CFG_WDGENB; + lat_write(rolf_ioaddr, LAT_REG_CONFIG, uchControl); + spin_unlock(&lattice_lock); + printk (KERN_INFO "rtl8139: ROL/F Watchdog: activate watchdog\n"); + return 0; + default: + return -ENODEV; + } +} + +static int rolf_wdog_release(struct inode *inode, struct file *file) +{ + unsigned char uchControl; + if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) + { +#ifndef CONFIG_WATCHDOG_NOWAYOUT + spin_lock(&lattice_lock); + uchControl = lat_read(rolf_ioaddr,LAT_REG_CONFIG); + uchControl &= ~LAT_CFG_WDGENB; + lat_write(rolf_ioaddr, LAT_REG_CONFIG, uchControl); + spin_unlock(&lattice_lock); + rolf_wdog_ctr_load(0); /* 0 length reset pulses now */ + printk (KERN_INFO "rtl8139: ROL/F Watchdog: release watchdog\n"); +#endif + rolf_wdog_is_open=0; + } + MOD_DEC_USE_COUNT; + return 0; +} + + +static struct file_operations rolf_wdog_fops = { + owner: THIS_MODULE, + llseek: rolf_wdog_llseek, + read: rolf_wdog_read, + write: rolf_wdog_write, + ioctl: rolf_wdog_ioctl, + open: rolf_wdog_open, + release: rolf_wdog_release, +}; + +static struct miscdevice rolf_wdog_miscdev= +{ + WATCHDOG_MINOR, + "watchdog", + &rolf_wdog_fops +}; +/* end ROL/F specific */ /* Twister tuning parameters from RealTek. Completely undocumented, but required to tune bad links on some boards. */ @@ -789,6 +1012,7 @@ /* set this immediately, we need to know before * we talk to the chip directly */ DPRINTK("PIO region size == 0x%02X\n", pio_len); + DPRINTK("PIO region start == 0x%08X\n", pio_start); DPRINTK("MMIO region size == 0x%02lX\n", mmio_len); #ifdef USE_IO_OPS @@ -830,6 +1054,7 @@ dev->base_addr = pio_start; tp->mmio_addr = ioaddr; tp->regs_len = pio_len; + DPRINTK("Use IO-mapped-IO\n"); #else /* ioremap MMIO region */ ioaddr = ioremap (mmio_start, mmio_len); @@ -841,6 +1066,7 @@ dev->base_addr = (long) ioaddr; tp->mmio_addr = ioaddr; tp->regs_len = mmio_len; + DPRINTK("Use MEM-mapped-IO\n"); #endif /* USE_IO_OPS */ /* Bring old chips out of low-power mode. */ @@ -1070,6 +1296,14 @@ if (rtl_chip_info[tp->chipset].flags & HasHltClk) RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */ + /* init ROL/F watchdog */ + if (tp->drv_flags & IS_ROLF) { + rolf_ioaddr = ioaddr; + printk(KERN_INFO "ROL/F Watchdog at %08lx, Timeout: %u s\n",(long)rolf_ioaddr,0xff-start); + rolf_wdog_registered = 1; + misc_register(&rolf_wdog_miscdev); + } + return 0; err_out: @@ -1115,7 +1349,7 @@ #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) -static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) +static int read_eeprom (void *ioaddr, int location, int addr_len) { int i; unsigned retval = 0; @@ -1290,6 +1524,9 @@ void *ioaddr = tp->mmio_addr; #endif +#ifdef ROLF_ENABLE_ROL_IFDOWN + pci_set_master (tp->pci_dev); +#endif retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); if (retval) return retval; @@ -1422,6 +1659,11 @@ /* Enable all known interrupts by setting the interrupt mask. */ RTL_W16 (IntrMask, rtl8139_intr_mask); + /* ROL/F specific */ + if (tp->drv_flags & IS_ROLF) { + rolf_init(dev); + } + netif_start_queue (dev); } @@ -2115,9 +2357,16 @@ void *ioaddr = tp->mmio_addr; int ret = 0; unsigned long flags; + u16 cmd; + unsigned short disable_rol; netif_stop_queue (dev); + /* ROL/F specific */ + if (tp->drv_flags & IS_ROLF) { + rolf_stop(dev); + } + if (tp->thr_pid >= 0) { tp->time_to_die = 1; wmb(); @@ -2158,11 +2407,28 @@ tp->rx_ring = NULL; tp->tx_bufs = NULL; - /* Green! Put the chip in low-power mode. */ - RTL_W8 (Cfg9346, Cfg9346_Unlock); +#ifdef ROLF_ENABLE_ROL_IFDOWN + disable_rol = read_eeprom(rolf_ioaddr, EEPROM_ROLBASE+ROLF_DISABLE_ROL, 6); + if (!(disable_rol & 0x2)) { + /* re-enable ROL after shutdown */ + DPRINTK ("ROL enabled in EEPROM\n"); + RTL_W8 (Cfg9346, Cfg9346_Unlock); + + /* enable reset on LAN after shutdown */ + pci_read_config_word(tp->pci_dev, PCI_COMMAND, &cmd); + cmd &= ~PCI_COMMAND_MASTER; + pci_write_config_word(tp->pci_dev, PCI_COMMAND, cmd); + /* enable Rx */ + RTL_W8_F (ChipCmd, 0x8); + /* accept phys, mult, unicast */ + RTL_W32 (RxConfig, 0xe); + RTL_W8 (Cfg9346, Cfg9346_Lock); - if (rtl_chip_info[tp->chipset].flags & HasHltClk) - RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */ + rolf_init(dev); + } else { + DPRINTK ("ROL disabled in EEPROM\n"); + } +#endif return 0; } @@ -2500,6 +2766,7 @@ /* Note: do not reorder, GCC is clever about common statements. */ if (dev->flags & IFF_PROMISC) { + rolf_stop(dev); /* Unconditionally log net taps. */ printk (KERN_NOTICE "%s: Promiscuous mode enabled. \n", dev->name); @@ -2533,6 +2800,10 @@ } RTL_W32_F (MAR0 + 0, mc_filter[0]); RTL_W32_F (MAR0 + 4, mc_filter[1]); + + if (!(dev->flags & IFF_PROMISC)) { + rolf_init(dev); + } } static void rtl8139_set_rx_mode (struct net_device *dev) @@ -2615,9 +2886,266 @@ static void __exit rtl8139_cleanup_module (void) { + if (rolf_wdog_registered) + misc_deregister(&rolf_wdog_miscdev); pci_unregister_driver (&rtl8139_pci_driver); } +/* begin ROL/F specific */ +void rolf_init(struct net_device *dev) +{ + unsigned char uchControl; + unsigned char wakeup_crc8[8] = + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned long wakeup_mask[8][2] = { + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + {0x00000000,0x00000000}, + }; + unsigned char wakeup_lsb[8] = + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + unsigned char reg_cfg9346, reg_config; + int i; + unsigned short crc8_and_lastbyte, disable_rol; + unsigned char lwake_state; + struct rtl8139_private *tp = dev->priv; + void *ioaddr; + + DPRINTK("ROL/F IO Addr: %08lx\n",rolf_ioaddr); + ioaddr = rolf_ioaddr; + + disable_rol = read_eeprom(ioaddr, EEPROM_ROLBASE+ROLF_DISABLE_ROL, 6); + if (disable_rol & 0x2) { + DPRINTK ("ROL disabled in EEPROM\n"); + rolf_stop(dev); + return; + } + DPRINTK ("ROL enabled in EEPROM\n"); + + + printk(KERN_INFO "Setting up ROL/F\n"); + /* reset LWAKE */ + pci_read_config_byte(tp->pci_dev, 0x55, &lwake_state); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "LWake State: %02x\n",lwake_state); +#endif + if (lwake_state & 0x80) { +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "Clear LWAKE\n"); +#endif + pci_write_config_byte(tp->pci_dev, 0x55, 0x80); + } + /* Unlock register access */ + reg_cfg9346 = RTL_R8(Cfg9346); + reg_cfg9346 |= CFG_UNLOCK; + RTL_W8(Cfg9346, reg_cfg9346); + + /* Disable LAN Wake signal */ + reg_config = RTL_R8(Config5); + reg_config &= ~CFG5_LANWAKE; + RTL_W8(Config5, reg_config); + + /* Disable Magic Paket support */ + reg_config = RTL_R8(Config3); + reg_config &= ~CFG3_MAGIC; + RTL_W8(Config3, reg_config); + + /* Disable PME support */ + reg_config = RTL_R8(Config1); + reg_config &= ~CFG1_PMEN; + RTL_W8(Config1, reg_config); + + /* Write ROL values from EEPROM in RTL8139C registers */ + crc8_and_lastbyte = read_eeprom(ioaddr, EEPROM_ROLBASE+ROLF_CRC8_AND_LASTBYTE, 6); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "CRC8+Lastbyte (%x): %X\n",EEPROM_ROLBASE+ROLF_CRC8_AND_LASTBYTE,crc8_and_lastbyte); +#endif + wakeup_crc8[7] = (unsigned char)(crc8_and_lastbyte >> 8); + wakeup_mask[7][0] = 0x00000003; + wakeup_mask[7][1] = 0x00000000; + wakeup_lsb[7] = (unsigned char)(crc8_and_lastbyte); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "CRC8: %02x, LSB: %02x\n",wakeup_crc8[7],wakeup_lsb[7]); +#endif + for (i=0;i<8;i++){ + RTL_W8(PowerManCRC0 + i, wakeup_crc8[i]); + RTL_W32(WakeupMask0 + (i * 8), wakeup_mask[i][0]); + RTL_W32(WakeupMask0 + 4 + (i * 8), wakeup_mask[i][1]); + RTL_W8(LSBCR0 + i, wakeup_lsb[i]); + } + + /* Enable PME support */ + reg_config = RTL_R8(Config1); + reg_config |= CFG1_PMEN; + RTL_W8(Config1, reg_config); + + /* Enable LAN Wake signal */ + reg_config = RTL_R8(Config5); + reg_config |= CFG5_LANWAKE; + RTL_W8(Config5, reg_config); + + /* LWAKE and PMEB pins asserted at same time */ + reg_config = RTL_R8(Config4); + reg_config &= ~CFG4_LWPME; + RTL_W8(Config4, reg_config); + + /* Lock register access */ + reg_cfg9346 &= ~CFG_UNLOCK; + RTL_W8(Cfg9346, reg_cfg9346); + + /* reset LWAKE */ + pci_read_config_byte(tp->pci_dev, 0x55, &lwake_state); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "LWake State: %02x\n",lwake_state); +#endif + if (lwake_state & 0x80) { +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "Clear LWAKE\n"); +#endif + pci_write_config_byte(tp->pci_dev, 0x55, 0x80); + } + + /* Enable Reset on LAN */ + spin_lock(&lattice_lock); + uchControl = lat_read(ioaddr,LAT_REG_CONFIG); + uchControl |= LAT_CFG_ROLENB; + lat_write(ioaddr, LAT_REG_CONFIG, uchControl); + spin_unlock(&lattice_lock); +} + +void rolf_stop(struct net_device *dev) +{ + unsigned char uchControl; + unsigned char lwake_state; + struct rtl8139_private *tp = dev->priv; + void *ioaddr; + + DPRINTK(KERN_DEBUG "ROL/F IO Addr: %08lx\n",rolf_ioaddr); + ioaddr = rolf_ioaddr; + + /* reset LWAKE */ + pci_read_config_byte(tp->pci_dev, 0x55, &lwake_state); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "LWake State: %02x\n",lwake_state); +#endif + if (lwake_state & 0x80) { +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG "Clear LWAKE\n"); +#endif + pci_write_config_byte(tp->pci_dev, 0x55, 0x80); + } + + /* Disable Reset on LAN */ + spin_lock(&lattice_lock); + uchControl = lat_read(ioaddr,LAT_REG_CONFIG); + uchControl &= ~LAT_CFG_ROLENB; + lat_write(ioaddr, LAT_REG_CONFIG, uchControl); + spin_unlock(&lattice_lock); +} + +static unsigned char lat_read(void *ioaddr, long offset) +{ + unsigned long value = 0; + volatile unsigned long value_in = 0; + + long flash_addr = FlashAccess; + + /* deactivate control lines */ + value = FLASH_CSB | FLASH_OEB | FLASH_WEB; + + /* Enable Flash Access, drive Address lines */ + value |= FLASH_ENABLE | ((offset | LAT_BASE_ADDR) & FLASH_ADDR_MASK); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Enable Flash Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); + + /* Start Read Access */ + value &= ~(FLASH_OEB | FLASH_CSB); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Start Read Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); + + /* Read the Flash Register content */ + value_in = RTL_R32(flash_addr); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Return Value from FlashReg: %08lx\n", value_in); +#endif + value_in &= FLASH_DATA_MASK; + value_in >>=24; +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Return Value from Flash : %02lx\n", value_in); +#endif + /* Stop Read Access */ + value |= FLASH_OEB | FLASH_CSB; +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Stop Read Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); + + /* Disable Flash Access */ + value = FLASH_CSB | FLASH_OEB | FLASH_WEB; +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Disable Flash Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Return Value from FlashReg: %08lx\n", RTL_R32(flash_addr)); +#endif + + return (unsigned char) value_in; +} + +static void lat_write(void *ioaddr, long offset, unsigned char data) +{ + unsigned long value = 0; + long flash_addr = FlashAccess; + + /* set data and deactivate control lines */ + value = ((data << 24) & FLASH_DATA_MASK) | FLASH_CSB | FLASH_OEB | FLASH_WEB; + + /* Enable Flash Access, drive Address lines */ + value |= FLASH_ENABLE | ((offset | LAT_BASE_ADDR) & FLASH_ADDR_MASK); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG " Enable Flash Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); + + /* Start Write Access */ + value &= ~(FLASH_WEB | FLASH_CSB); +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG " Start Write Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); + /* lattice design needs a delay of one clock period to receive data, + f=32768 kHz -> clock period 30 usec + */ + + udelay(100); /* its save to increase delay to 100 micro seconds */ + + /* Stop Write Access */ + value |= FLASH_WEB | FLASH_CSB; +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Stop Write Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); + + /* Disable Flash Access */ + value = FLASH_CSB | FLASH_OEB | FLASH_WEB; +#ifdef RTL8139_DEBUG + printk(KERN_DEBUG" Disable Flash Access: %04lx: %08lx\n", flash_addr, value); +#endif + RTL_W32(flash_addr, value); +} + +/* end ROL/F specific */ module_init(rtl8139_init_module); module_exit(rtl8139_cleanup_module); ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=410643&aid=775368&group_id=34096 |