* [PATCH] Add new cs89x0 driver @ 2009-04-22 7:59 Sascha Hauer 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: Sascha Hauer @ 2009-04-22 7:59 UTC (permalink / raw) To: netdev; +Cc: Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix While this is a very old chip it is still in use on some embedded boards. I see myself unable to fix the in Kernel driver to bring it to driver model support, so this patch adds a new driver designed to replace the old one, at least for non-ISA hardware. Sascha ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 7:59 [PATCH] Add new cs89x0 driver Sascha Hauer @ 2009-04-22 7:59 ` Sascha Hauer 2009-04-22 7:59 ` [PATCH 2/2] mx1ads: Add cs89x0 network support Sascha Hauer ` (4 more replies) 2009-04-22 22:53 ` [PATCH] Add new " Lennert Buytenhek 2009-10-20 9:55 ` Ben Dooks 2 siblings, 5 replies; 17+ messages in thread From: Sascha Hauer @ 2009-04-22 7:59 UTC (permalink / raw) To: netdev Cc: Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix, Sascha Hauer The in Kernel driver is far beyond its age. it still does not use driver model and its mere presence in the Kernel image prevents booting my board. The CS8900 still is in use on some embedded boards, so this patch adds an alternative driver to the tree designed to replace the old one. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/net/Kconfig | 12 + drivers/net/Makefile | 1 + drivers/net/cirrus-cs89x0.c | 847 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 860 insertions(+), 0 deletions(-) create mode 100644 drivers/net/cirrus-cs89x0.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9e92154..1d358b1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1454,6 +1454,18 @@ config CS89x0_NONISA_IRQ depends on CS89x0 != n depends on MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X || MACH_MX31ADS +config CIRRUS_CS89X0 + tristate "CS89x0 support alternative" + ---help--- + This is an alternate version of the cs89x0 driver with platform_device + support. + Support for CS89x0 chipset based Ethernet cards. If you have a non-ISA + network card of this type, say Y here + + To compile this driver as a module, choose M here and read + <file:Documentation/networking/net-modules.txt>. The module will be + called cirrus-cs89x0. + config TC35815 tristate "TOSHIBA TC35815 Ethernet support" depends on NET_PCI && PCI && MIPS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1fc4602..41b524c 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -210,6 +210,7 @@ obj-$(CONFIG_A2065) += a2065.o obj-$(CONFIG_HYDRA) += hydra.o 8390.o obj-$(CONFIG_ARIADNE) += ariadne.o obj-$(CONFIG_CS89x0) += cs89x0.o +obj-$(CONFIG_CIRRUS_CS89X0) += cirrus-cs89x0.o obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MACMACE) += macmace.o obj-$(CONFIG_MAC89x0) += mac89x0.o diff --git a/drivers/net/cirrus-cs89x0.c b/drivers/net/cirrus-cs89x0.c new file mode 100644 index 0000000..1d98c18 --- /dev/null +++ b/drivers/net/cirrus-cs89x0.c @@ -0,0 +1,847 @@ +/* + * linux/drivers/net/cirrus.c + * + * Author: Abraham van der Merwe <abraham@2d3d.co.za> + * + * A Cirrus Logic CS8900A driver for Linux + * based on the cs89x0 driver written by Russell Nelson, + * Donald Becker, and others. + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include <linux/version.h> +#include <linux/module.h> + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/spinlock.h> +#include <linux/ioport.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/platform_device.h> + +#define CS89X0_ADDRESS 0x0a /* PacketPage Pointer Port (Section 4.10.10) */ +#define CS89X0_DATA 0x0c /* PacketPage Data Port (Section 4.10.10) */ + +/* + * Registers + */ +#define PRODUCTID 0x0000 /* Section 4.3.1 Identification Code */ +#define MEMBASE 0x002c /* Section 4.9.2 Base Address Register */ +#define INTNUM 0x0022 /* Section 3.2.3 Interrupt Number */ +#define EEPROMCMD 0x0040 /* Section 4.3.11 EEPROM Command */ +#define EEPROMDAT 0x0042 /* Section 4.3.12 EEPROM Data */ +#define RXCFG 0x0102 /* Section 4.4.6 Receiver Configuration */ +#define RXCTL 0x0104 /* Section 4.4.8 Receiver Control */ +#define TXCFG 0x0106 /* Section 4.4.9 Transmit Configuration */ +#define BUFCFG 0x010a /* Section 4.4.12 Buffer Configuration */ +#define LINECTL 0x0112 /* Section 4.4.16 Line Control */ +#define SELFCTL 0x0114 /* Section 4.4.18 Self Control */ +#define BUSCTL 0x0116 /* Section 4.4.20 Bus Control */ +#define TESTCTL 0x0118 /* Section 4.4.22 Test Control */ +#define ISQ 0x0120 /* Section 4.4.5 Interrupt Status Queue */ +#define TXEVENT 0x0128 /* Section 4.4.10 Transmitter Event */ +#define BUFEVENT 0x012c /* Section 4.4.13 Buffer Event */ +#define RXMISS 0x0130 /* Section 4.4.14 Receiver Miss Counter */ +#define TXCOL 0x0132 /* Section 4.4.15 Transmit Collision Counter */ +#define SELFST 0x0136 /* Section 4.4.19 Self Status */ +#define BUSST 0x0138 /* Section 4.4.21 Bus Status */ +#define TXCMD 0x0144 /* Section 4.4.11 Transmit Command */ +#define TXLENGTH 0x0146 /* Section 4.5.2 Transmit Length */ +#define IA 0x0158 /* Section 4.6.2 Individual Address */ +#define RXSTATUS 0x0400 /* Section 4.7.1 Receive Status */ +#define RXLENGTH 0x0402 /* Section 4.7.1 Receive Length (in bytes) */ +#define RXFRAME 0x0404 /* Section 4.7.2 Receive Frame Location */ +#define TXFRAME 0x0a00 /* Section 4.7.2 Transmit Frame Location */ + +/* + * Values + */ + +/* INTNUM */ +#define INTRQ0 0x0000 +#define INTRQ1 0x0001 +#define INTRQ2 0x0002 +#define INTRQ3 0x0003 + +/* ProductID */ +#define EISA_REG_CODE 0x630e +#define REVISION(x) (((x) & 0x1f00) >> 8) +#define VERSION(x) ((x) & ~0x1f00) + +#define CS8900A 0x0000 +#define REV_B 7 +#define REV_C 8 +#define REV_D 9 + +/* RXCFG */ +#define RXCFG_SKIP_1 0x0040 +#define RXCFG_STREAME 0x0080 +#define RXCFG_RXOKIE 0x0100 +#define RXCFG_RXDMAONLY 0x0200 +#define RXCFG_AUTORXDMAE 0x0400 +#define RXCFG_BUFFERCRC 0x0800 +#define RXCFG_CRCERRORIE 0x1000 +#define RXCFG_RUNTIE 0x2000 +#define RXCFG_EXTRADATAIE 0x4000 + +/* RxCTL */ +#define RXCTL_IAHASHA 0x0040 +#define RXCTL_PROMISCUOUSA 0x0080 +#define RXCTL_RXOKA 0x0100 +#define RXCTL_MULTICASTA 0x0200 +#define RXCTL_INDIVIDUALA 0x0400 +#define RXCTL_BROADCASTA 0x0800 +#define RXCTL_CRCERRORA 0x1000 +#define RXCTL_RUNTA 0x2000 +#define RXCTL_EXTRADATAA 0x4000 + +/* TXCFG */ +#define TXCFG_LOSS_OF_CRSIE 0x0040 +#define TXCFG_SQERRORIE 0x0080 +#define TXCFG_TXOKIE 0x0100 +#define TXCFG_OUT_OF_WINDOWIE 0x0200 +#define TXCFG_JABBERIE 0x0400 +#define TXCFG_ANYCOLLIE 0x0800 +#define TXCFG_T16COLLIE 0x8000 + +/* BUFCFG */ +#define BUFCFG_SWINT_X 0x0040 +#define BUFCFG_RXDMAIE 0x0080 +#define BUFCFG_RDY4TXIE 0x0100 +#define BUFCFG_TXUNDERRUNIE 0x0200 +#define BUFCFG_RXMISSIE 0x0400 +#define BUFCFG_RX128IE 0x0800 +#define BUFCFG_TXCOLOVFIE 0x1000 +#define BUFCFG_MISSOVFLOIE 0x2000 +#define BUFCFG_RXDESTIE 0x8000 + +/* LINECTL */ +#define LINECTL_SERRXON 0x0040 +#define LINECTL_SERTXON 0x0080 +#define LINECTL_AUIONLY 0x0100 +#define LINECTL_AUTOAUI_10BT 0x0200 +#define LINECTL_MODBACKOFFE 0x0800 +#define LINECTL_POLARITYDIS 0x1000 +#define LINECTL_L2_PARTDEFDIS 0x2000 +#define LINECTL_LORXSQUELCH 0x4000 + +/* SELFCTL */ +#define SELFCTL_RESET 0x0040 +#define SELFCTL_SWSUSPEND 0x0100 +#define SELFCTL_HWSLEEPE 0x0200 +#define SELFCTL_HWSTANDBYE 0x0400 +#define SELFCTL_HC0E 0x1000 +#define SELFCTL_HC1E 0x2000 +#define SELFCTL_HCB0 0x4000 +#define SELFCTL_HCB1 0x8000 + +/* BUSCTL */ +#define BUSCTL_RESETRXDMA 0x0040 +#define BUSCTL_DMAEXTEND 0x0100 +#define BUSCTL_USESA 0x0200 +#define BUSCTL_MEMORYE 0x0400 +#define BUSCTL_DMABURST 0x0800 +#define BUSCTL_IOCHRDYE 0x1000 +#define BUSCTL_RXDMASIZE 0x2000 +#define BUSCTL_ENABLERQ 0x8000 + +/* TESTCTL */ +#define TESTCTL_DISABLELT 0x0080 +#define TESTCTL_ENDECLOOP 0x0200 +#define TESTCTL_AUILOOP 0x0400 +#define TESTCTL_DISABLEBACKOFF 0x0800 +#define TESTCTL_FDX 0x4000 + +/* ISQ */ +#define ISQ_REGNUM(x) ((x) & 0x3f) +#define ISQ_REGCONTENT(x) ((x) & ~0x3d) + +#define ISQ_RXEVENT 0x0004 +#define ISQ_TXEVENT 0x0008 +#define ISQ_BUFEVENT 0x000c +#define ISQ_RXMISS 0x0010 +#define ISQ_TXCOL 0x0012 + +/* RXSTATUS */ +#define RXSTATUS_IAHASH 0x0040 +#define RXSTATUS_DRIBBLEBITS 0x0080 +#define RXSTATUS_RXOK 0x0100 +#define RXSTATUS_HASHED 0x0200 +#define RXSTATUS_INDIVIDUALADR 0x0400 +#define RXSTATUS_BROADCAST 0x0800 +#define RXSTATUS_CRCERROR 0x1000 +#define RXSTATUS_RUNT 0x2000 +#define RXSTATUS_EXTRADATA 0x4000 + +/* TXCMD */ +#define TXCMD_AFTER5 0 +#define TXCMD_AFTER381 1 +#define TXCMD_AFTER1021 2 +#define TXCMD_AFTERALL 3 +#define TXCMD_TXSTART(x) ((x) << 6) + +#define TXCMD_FORCE 0x0100 +#define TXCMD_ONECOLL 0x0200 +#define TXCMD_INHIBITCRC 0x1000 +#define TXCMD_TXPADDIS 0x2000 + +/* BUSST */ +#define BUSST_TXBIDERR 0x0080 +#define BUSST_RDY4TXNOW 0x0100 + +/* TXEVENT */ +#define TXEVENT_LOSS_OF_CRS 0x0040 +#define TXEVENT_SQEERROR 0x0080 +#define TXEVENT_TXOK 0x0100 +#define TXEVENT_OUT_OF_WINDOW 0x0200 +#define TXEVENT_JABBER 0x0400 +#define TXEVENT_T16COLL 0x8000 + +#define TXEVENT_TX_COLLISIONS(x) (((x) >> 0xb) & ~0x8000) + +/* BUFEVENT */ +#define BUFEVENT_SWINT 0x0040 +#define BUFEVENT_RXDMAFRAME 0x0080 +#define BUFEVENT_RDY4TX 0x0100 +#define BUFEVENT_TXUNDERRUN 0x0200 +#define BUFEVENT_RXMISS 0x0400 +#define BUFEVENT_RX128 0x0800 +#define BUFEVENT_RXDEST 0x8000 + +/* RXMISS */ +#define RXMISS_MISSCOUNT(x) ((x) >> 6) + +/* TXCOL */ +#define TXCOL_COLCOUNT(x) ((x) >> 6) + +/* SELFST */ +#define SELFST_T3VACTIVE 0x0040 +#define SELFST_INITD 0x0080 +#define SELFST_SIBUSY 0x0100 +#define SELFST_EEPROMPRESENT 0x0200 +#define SELFST_EEPROMOK 0x0400 +#define SELFST_ELPRESENT 0x0800 +#define SELFST_EESIZE 0x1000 + +/* EEPROMCOMMAND */ +#define EEPROMCOMMAND_EEWRITE 0x0100 +#define EEPROMCOMMAND_EEREAD 0x0200 +#define EEPROMCOMMAND_EEERASE 0x0300 +#define EEPROMCOMMAND_ELSEL 0x0400 + +struct cirrus_eeprom { + u16 io_base; /* I/O Base Address */ + u16 irq; /* Interrupt Number */ + u16 dma; /* DMA Channel Numbers */ + u32 mem_base; /* Memory Base Address */ + u32 rom_base; /* Boot PROM Base Address */ + u32 rom_mask; /* Boot PROM Address Mask */ + u8 mac[6]; /* Individual Address */ +}; + +struct cirrus_priv { + u16 txlen; + u16 txafter; /* Default is After5 (0) */ + spinlock_t lock; + void __iomem *base_addr; + struct cirrus_eeprom eeprom; +}; + +/* + * I/O routines + */ + +static inline u16 +cirrus_read(struct net_device *ndev, u16 reg) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + + writew(reg, priv->base_addr + CS89X0_ADDRESS); + return readw(priv->base_addr + CS89X0_DATA); +} + +static inline void +cirrus_write(struct net_device *ndev, u16 reg, u16 value) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + + writew(reg, priv->base_addr + CS89X0_ADDRESS); + writew(value, priv->base_addr + CS89X0_DATA); +} + +static inline void +cirrus_set(struct net_device *ndev, u16 reg, u16 value) +{ + cirrus_write(ndev, reg, cirrus_read(ndev, reg) | value); +} + +static inline void +cirrus_clear(struct net_device *ndev, u16 reg, u16 value) +{ + cirrus_write(ndev, reg, cirrus_read(ndev, reg) & ~value); +} + +static inline void +cirrus_frame_read(struct net_device *ndev, struct sk_buff *skb, u16 length) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + + readsw(priv->base_addr, skb_put(skb, length), (length + 1) / 2); +} + +static inline void +cirrus_frame_write(struct net_device *ndev, struct sk_buff *skb) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + + writesw(priv->base_addr, skb->data, (skb->len + 1) / 2); +} + +static void +cirrus_receive(struct net_device *ndev) +{ + struct sk_buff *skb; + u16 status, length; + + status = cirrus_read(ndev, RXSTATUS); + length = cirrus_read(ndev, RXLENGTH); + + if (!(status & RXSTATUS_RXOK)) { + ndev->stats.rx_errors++; + if ((status & (RXSTATUS_RUNT | RXSTATUS_EXTRADATA))) + ndev->stats.rx_length_errors++; + if ((status & RXSTATUS_CRCERROR)) + ndev->stats.rx_crc_errors++; + return; + } + + skb = dev_alloc_skb(length + 4); + if (!skb) { + ndev->stats.rx_dropped++; + return; + } + + skb->dev = ndev; + skb_reserve(skb, 2); + + cirrus_frame_read(ndev, skb, length); + + skb->protocol = eth_type_trans(skb, ndev); + + netif_rx(skb); + ndev->last_rx = jiffies; + + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += length; +} + +static int +cirrus_send_start(struct sk_buff *skb, struct net_device *ndev) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + u16 status; + + /* Tx start must be done with irq disabled + * else status can be wrong */ + spin_lock_irq(&priv->lock); + + netif_stop_queue(ndev); + + cirrus_write(ndev, TXCMD, TXCMD_TXSTART(priv->txafter)); + cirrus_write(ndev, TXLENGTH, skb->len); + + status = cirrus_read(ndev, BUSST); + if (!(status & BUSST_RDY4TXNOW)) { + ndev->stats.tx_errors++; + priv->txlen = 0; + spin_unlock_irq(&priv->lock); + return NETDEV_TX_BUSY; + } + + cirrus_frame_write(ndev, skb); + + ndev->trans_start = jiffies; + spin_unlock_irq(&priv->lock); + + dev_kfree_skb(skb); + + priv->txlen = skb->len; + + return NETDEV_TX_OK; +} + +static irqreturn_t cirrus_interrupt(int irq, void *id) +{ + struct net_device *ndev = (struct net_device *)id; + struct cirrus_priv *priv = netdev_priv(ndev); + u16 status; + + spin_lock(&priv->lock); + + while ((status = cirrus_read(ndev, ISQ))) { + switch (ISQ_REGNUM(status)) { + case ISQ_RXEVENT: + cirrus_receive(ndev); + break; + + case ISQ_TXEVENT: + ndev->stats.collisions += + TXCOL_COLCOUNT(cirrus_read(ndev, TXCOL)); + if (!(ISQ_REGCONTENT(status) & TXEVENT_TXOK)) { + ndev->stats.tx_errors++; + if (ISQ_REGCONTENT(status) & + TXEVENT_OUT_OF_WINDOW) + ndev->stats.tx_window_errors++; + if (ISQ_REGCONTENT(status) & TXEVENT_JABBER) + ndev->stats.tx_aborted_errors++; + break; + } else if (priv->txlen) { + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += priv->txlen; + } + priv->txlen = 0; + netif_wake_queue(ndev); + break; + + case ISQ_BUFEVENT: + if ((ISQ_REGCONTENT(status) & BUFEVENT_RXMISS)) { + u16 missed = + RXMISS_MISSCOUNT(cirrus_read(ndev, + RXMISS)); + ndev->stats.rx_errors += missed; + ndev->stats.rx_missed_errors += missed; + } + if (ISQ_REGCONTENT(status) & BUFEVENT_TXUNDERRUN) { + ndev->stats.tx_errors++; + /* Shift start tx if underruns + * come too often + */ + switch (ndev->stats.tx_fifo_errors++) { + case 3: + priv->txafter = TXCMD_AFTER381; + break; + case 6: + priv->txafter = TXCMD_AFTER1021; + break; + case 9: + priv->txafter = TXCMD_AFTERALL; + break; + } + } + /* Wakeup only for tx events ! */ + if (ISQ_REGCONTENT(status) & + (BUFEVENT_TXUNDERRUN | BUFEVENT_RDY4TX)) { + priv->txlen = 0; + netif_wake_queue(ndev); + } + break; + + case ISQ_TXCOL: + ndev->stats.collisions += + TXCOL_COLCOUNT(cirrus_read(ndev, TXCOL)); + break; + + case ISQ_RXMISS: + status = RXMISS_MISSCOUNT(cirrus_read(ndev, RXMISS)); + ndev->stats.rx_errors += status; + ndev->stats.rx_missed_errors += status; + break; + } + } + + spin_unlock(&priv->lock); + return IRQ_HANDLED; +} + +static void +cirrus_transmit_timeout(struct net_device *ndev) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + + ndev->stats.tx_errors++; + ndev->stats.tx_heartbeat_errors++; + priv->txlen = 0; + netif_wake_queue(ndev); +} + +static int +cirrus_start(struct net_device *ndev) +{ + int result; + + /* valid ethernet address? */ + if (!is_valid_ether_addr(ndev->dev_addr)) { + printk(KERN_ERR "%s: invalid ethernet MAC address\n", + ndev->name); + return -EINVAL; + } + + /* install interrupt handler */ + result = request_irq(ndev->irq, &cirrus_interrupt, 0, ndev->name, ndev); + if (result < 0) { + printk(KERN_ERR "%s: could not register interrupt %d\n", + ndev->name, ndev->irq); + return result; + } + + /* enable the ethernet controller */ + cirrus_set(ndev, RXCFG, + RXCFG_RXOKIE | RXCFG_BUFFERCRC | RXCFG_CRCERRORIE | + RXCFG_RUNTIE | RXCFG_EXTRADATAIE); + cirrus_set(ndev, RXCTL, RXCTL_RXOKA | RXCTL_INDIVIDUALA | + RXCTL_BROADCASTA); + cirrus_set(ndev, TXCFG, TXCFG_TXOKIE | TXCFG_OUT_OF_WINDOWIE | + TXCFG_JABBERIE); + cirrus_set(ndev, BUFCFG, + BUFCFG_RDY4TXIE | BUFCFG_RXMISSIE | + BUFCFG_TXUNDERRUNIE | BUFCFG_TXCOLOVFIE | + BUFCFG_MISSOVFLOIE); + cirrus_set(ndev, LINECTL, LINECTL_SERRXON | LINECTL_SERTXON); + cirrus_set(ndev, BUSCTL, BUSCTL_ENABLERQ); + + /* start the queue */ + netif_start_queue(ndev); + + return 0; +} + +static int +cirrus_stop(struct net_device *ndev) +{ + /* disable ethernet controller */ + cirrus_write(ndev, BUSCTL, 0); + cirrus_write(ndev, TESTCTL, 0); + cirrus_write(ndev, SELFCTL, 0); + cirrus_write(ndev, LINECTL, 0); + cirrus_write(ndev, BUFCFG, 0); + cirrus_write(ndev, TXCFG, 0); + cirrus_write(ndev, RXCTL, 0); + cirrus_write(ndev, RXCFG, 0); + + /* uninstall interrupt handler */ + free_irq(ndev->irq, ndev); + + /* stop the queue */ + netif_stop_queue(ndev); + + return 0; +} + +static int +cirrus_set_mac_address(struct net_device *ndev, void *p) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + struct sockaddr *addr = (struct sockaddr *) p; + int i; + + if (netif_running(ndev)) + return -EBUSY; + + spin_lock(&priv->lock); + + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); + + /* configure MAC address */ + for (i = 0; i < ETH_ALEN; i += 2) + cirrus_write(ndev, IA + i, + ndev->dev_addr[i] | (ndev->dev_addr[i + 1] << 8)); + + spin_unlock(&priv->lock); + + return 0; +} + +static struct net_device_stats * +cirrus_get_stats(struct net_device *ndev) +{ + return &ndev->stats; +} + +static void +cirrus_set_receive_mode(struct net_device *ndev) +{ + struct cirrus_priv *priv = netdev_priv(ndev); + + spin_lock(&priv->lock); + + if ((ndev->flags & IFF_PROMISC)) + cirrus_set(ndev, RXCTL, RXCTL_PROMISCUOUSA); + else + cirrus_clear(ndev, RXCTL, RXCTL_PROMISCUOUSA); + + if ((ndev->flags & IFF_ALLMULTI) || ndev->mc_list) + cirrus_set(ndev, RXCTL, RXCTL_MULTICASTA); + else + cirrus_clear(ndev, RXCTL, RXCTL_MULTICASTA); + + spin_unlock(&priv->lock); +} + +static int +cirrus_eeprom_wait(struct net_device *ndev) +{ + int i; + + for (i = 0; i < 200; i++) { + if (!(cirrus_read(ndev, SELFST) & SELFST_SIBUSY)) + return 0; + udelay(1); + } + + return -1; +} + +static int +cirrus_eeprom_read(struct net_device *ndev, u16 *value, u16 offset) +{ + if (cirrus_eeprom_wait(ndev) < 0) + return -1; + + cirrus_write(ndev, EEPROMCMD, offset | EEPROMCOMMAND_EEREAD); + + if (cirrus_eeprom_wait(ndev) < 0) + return -1; + + *value = cirrus_read(ndev, EEPROMDAT); + + return 0; +} + +static int +cirrus_eeprom(struct net_device *ndev, struct cirrus_eeprom *eeprom) +{ + u16 offset, buf[16], *word; + u8 checksum = 0, *byte; + + if (cirrus_eeprom_read(ndev, buf, 0) < 0) + return -ETIMEDOUT; + + + if ((buf[0] >> 8) != 0xa1) { + printk(KERN_DEBUG "%s: No EEPROM present\n", ndev->name); + return -ENODEV; + } + + if ((buf[0] & 0xff) < sizeof(buf)) { + printk(KERN_DEBUG "%s: EEPROM too small\n", ndev->name); + return -ENODEV; + } + + for (offset = 1; offset < ((buf[0] & 0xff) >> 1); offset++) { + if (cirrus_eeprom_read(ndev, buf + offset, offset) < 0) + return -ETIMEDOUT; + + if (buf[offset] == 0xffff) + return -ENODEV; + } + + if (buf[1] != 0x2020) { + printk(KERN_DEBUG "%s: Group Header #1 mismatch\n", ndev->name); + return -EIO; + } + + if (buf[5] != 0x502c) { + printk(KERN_DEBUG "%s: Group Header #2 mismatch\n", ndev->name); + return -EIO; + } + + if (buf[12] != 0x2158) { + printk(KERN_DEBUG "%s: Group Header #3 mismatch\n", ndev->name); + return -EIO; + } + + eeprom->io_base = buf[2]; + eeprom->irq = buf[3]; + eeprom->dma = buf[4]; + eeprom->mem_base = (buf[7] << 16) | buf[6]; + eeprom->rom_base = (buf[9] << 16) | buf[8]; + eeprom->rom_mask = (buf[11] << 16) | buf[10]; + + word = (u16 *) eeprom->mac; + for (offset = 0; offset < 3; offset++) + word[offset] = buf[13 + offset]; + + byte = (u8 *) buf; + for (offset = 0; offset < sizeof(buf); offset++) + checksum += byte[offset]; + + if (cirrus_eeprom_read(ndev, &offset, 0x10) < 0) + return -ETIMEDOUT; + + if ((offset >> 8) != (u8) (0x100 - checksum)) { + printk(KERN_DEBUG + "%s: Checksum mismatch (expected 0x%.2x, got 0x%.2x" + "instead\n", + ndev->name, (u8) (0x100 - checksum), offset >> 8); + return -EIO; + } + + return 0; +} + +/* + * Driver initialization routines + */ +static const struct net_device_ops cirrus_netdev_ops = { + .ndo_open = cirrus_start, + .ndo_stop = cirrus_stop, + .ndo_start_xmit = cirrus_send_start, + .ndo_get_stats = cirrus_get_stats, + .ndo_set_multicast_list = cirrus_set_receive_mode, + .ndo_set_mac_address = cirrus_set_mac_address, + .ndo_tx_timeout = cirrus_transmit_timeout, +}; + +static int __init +cirrus_probe(struct platform_device *pdev) +{ + struct net_device *ndev; + struct resource *res; + struct cirrus_priv *priv; + int ret, i; + u16 value; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + /* + * Request the regions. + */ + if (!request_mem_region(res->start, resource_size(res), "cs89x0")) + return -EBUSY; + + ndev = alloc_etherdev(sizeof(struct cirrus_priv)); + if (!ndev) { + ret = -ENOMEM; + goto failed_alloc; + } + + SET_NETDEV_DEV(ndev, &pdev->dev); + + priv = netdev_priv(ndev); + + ndev->irq = platform_get_irq(pdev, 0); + + priv->base_addr = ioremap(res->start, resource_size(res)); + if (!priv->base_addr) { + ret = -ENOMEM; + goto failed_ioremap; + } + ndev->base_addr = (unsigned long)priv->base_addr; + + platform_set_drvdata(pdev, ndev); + + ether_setup(ndev); + + ndev->netdev_ops = &cirrus_netdev_ops; + ndev->watchdog_timeo = HZ; + + ndev->if_port = IF_PORT_10BASET; + + spin_lock_init(&priv->lock); + + /* if an EEPROM is present, use it's MAC address */ + if (!cirrus_eeprom(ndev, &priv->eeprom)) + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = priv->eeprom.mac[i]; + else + random_ether_addr(ndev->dev_addr); + + /* verify EISA registration number for Cirrus Logic */ + value = cirrus_read(ndev, PRODUCTID); + if (value != EISA_REG_CODE) { + dev_err(&pdev->dev, "incorrect signature 0x%.4x\n", value); + ret = -ENXIO; + goto failed_probe; + } + + /* verify chip version */ + value = cirrus_read(ndev, PRODUCTID + 2); + if (VERSION(value) != CS8900A) { + dev_err(&pdev->dev, "unknown chip version 0x%.8x\n", + VERSION(value)); + ret = -ENXIO; + goto failed_probe; + } + dev_info(&pdev->dev, "CS8900A rev %c detected\n", + 'B' + REVISION(value) - REV_B); + + /* setup interrupt number */ + cirrus_write(ndev, INTNUM, 0); + + /* configure MAC address */ + for (i = 0; i < ETH_ALEN; i += 2) + cirrus_write(ndev, IA + i, + ndev->dev_addr[i] | (ndev->dev_addr[i + 1] << 8)); + + ret = register_netdev(ndev); + if (ret) + goto failed_probe; + + return 0; + +failed_probe: + platform_set_drvdata(pdev, NULL); + iounmap(priv->base_addr); +failed_ioremap: + free_netdev(ndev); +failed_alloc: + release_mem_region(res->start, resource_size(res)); + + return ret; +} + +static int +cirrus_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct cirrus_priv *priv = netdev_priv(ndev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + unregister_netdev(ndev); + iounmap(priv->base_addr); + free_netdev(ndev); + release_mem_region(res->start, resource_size(res)); + + return 0; +} + +static struct platform_driver cirrus_driver = { + .probe = cirrus_probe, + .remove = cirrus_remove, + .driver = { + .name = "cirrus-cs89x0", + }, +}; + +static int __init +cirrus_init(void) +{ + return platform_driver_register(&cirrus_driver); +} + +static void __exit +cirrus_cleanup(void) +{ + platform_driver_unregister(&cirrus_driver); +} + +MODULE_AUTHOR("Abraham van der Merwe <abraham@2d3d.co.za>"); +MODULE_DESCRIPTION("Cirrus Logic CS8900A driver for Linux"); +MODULE_LICENSE("GPL"); + +module_init(cirrus_init); +module_exit(cirrus_cleanup); -- 1.6.2.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/2] mx1ads: Add cs89x0 network support 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer @ 2009-04-22 7:59 ` Sascha Hauer 2009-04-22 9:28 ` [PATCH 1/2] Add an alternative cs89x0 driver Ivo Clarysse ` (3 subsequent siblings) 4 siblings, 0 replies; 17+ messages in thread From: Sascha Hauer @ 2009-04-22 7:59 UTC (permalink / raw) To: netdev Cc: Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix, Sascha Hauer Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/mach-mx1/mx1ads.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c index e54057f..6d23fcc 100644 --- a/arch/arm/mach-mx1/mx1ads.c +++ b/arch/arm/mach-mx1/mx1ads.c @@ -155,6 +155,24 @@ static struct i2c_board_info mx1ads_i2c_devices[] = { }, }; +static struct resource cs89x0_resources[] = { + { + .start = IMX_CS4_PHYS + 0x300, + .end = IMX_CS4_PHYS + 0x300 + 15, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_GPIOC(17), + .end = IRQ_GPIOC(17), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cs89x0_device = { + .name = "cirrus-cs89x0", + .num_resources = ARRAY_SIZE(cs89x0_resources), + .resource = cs89x0_resources, +}; + /* * Board init */ @@ -172,6 +190,8 @@ static void __init mx1ads_init(void) ARRAY_SIZE(mx1ads_i2c_devices)); mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data); + + platform_device_register(&cs89x0_device); } static void __init mx1ads_timer_init(void) -- 1.6.2.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer 2009-04-22 7:59 ` [PATCH 2/2] mx1ads: Add cs89x0 network support Sascha Hauer @ 2009-04-22 9:28 ` Ivo Clarysse 2009-04-22 12:18 ` Sascha Hauer 2009-04-22 9:42 ` Gilles Chanteperdrix ` (2 subsequent siblings) 4 siblings, 1 reply; 17+ messages in thread From: Ivo Clarysse @ 2009-04-22 9:28 UTC (permalink / raw) To: Sascha Hauer; +Cc: netdev, Lennert Buytenhek, Gilles Chanteperdrix On Wed, Apr 22, 2009 at 9:59 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote: > +#define CS8900A 0x0000 > +#define REV_B 7 > +#define REV_C 8 > +#define REV_D 9 These REV_B / REV_C / REV_D defines are not used, and in fact depend on the cs89x0x variant. > + dev_info(&pdev->dev, "CS8900A rev %c detected\n", > + 'B' + REVISION(value) - REV_B); This will report incorrectly for CS8900 (not CS8900A), and for CS8900A rev. F: According to the CS8900A and CS8920A datasheets, the product ID should be interpreted as: 0x0700 CS8900A rev. B 0x0800 CS8900A rev. C 0x0900 CS8900A rev. D 0x0A00 CS8900A rev. F 0x6100 CS8920 rev. B 0x6200 CS8920 rev. C 0x6300 CS8920 rev. D 0x6400 CS8920A rev. A/B 0x6500 CS8920A rev. C (I couldn't find the datasheet for the original CS8900; acoording to http://www.cirrus.com/en/products/eol/index.html, the CS8900A is the only CS89X0X variant which is not EOL) Ivo. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 9:28 ` [PATCH 1/2] Add an alternative cs89x0 driver Ivo Clarysse @ 2009-04-22 12:18 ` Sascha Hauer 0 siblings, 0 replies; 17+ messages in thread From: Sascha Hauer @ 2009-04-22 12:18 UTC (permalink / raw) To: Ivo Clarysse; +Cc: netdev, Lennert Buytenhek, Gilles Chanteperdrix On Wed, Apr 22, 2009 at 11:28:17AM +0200, Ivo Clarysse wrote: > On Wed, Apr 22, 2009 at 9:59 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote: > > > +#define CS8900A 0x0000 > > +#define REV_B 7 > > +#define REV_C 8 > > +#define REV_D 9 > > These REV_B / REV_C / REV_D defines are not used, and in fact depend > on the cs89x0x variant. > > > + dev_info(&pdev->dev, "CS8900A rev %c detected\n", > > + 'B' + REVISION(value) - REV_B); > > This will report incorrectly for CS8900 (not CS8900A), and for CS8900A rev. F: Ok, will fix. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer 2009-04-22 7:59 ` [PATCH 2/2] mx1ads: Add cs89x0 network support Sascha Hauer 2009-04-22 9:28 ` [PATCH 1/2] Add an alternative cs89x0 driver Ivo Clarysse @ 2009-04-22 9:42 ` Gilles Chanteperdrix 2009-04-22 12:20 ` Sascha Hauer 2009-08-26 10:46 ` Kurt Van Dijck 2009-10-16 9:37 ` Kurt Van Dijck 4 siblings, 1 reply; 17+ messages in thread From: Gilles Chanteperdrix @ 2009-04-22 9:42 UTC (permalink / raw) To: Sascha Hauer; +Cc: netdev, Lennert Buytenhek, Ivo Clarysse Sascha Hauer wrote: > +MODULE_AUTHOR("Abraham van der Merwe <abraham@2d3d.co.za>"); The 2d3d.co.za domain does not seem to exist. -- Gilles. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 9:42 ` Gilles Chanteperdrix @ 2009-04-22 12:20 ` Sascha Hauer 2009-04-22 12:25 ` Gilles Chanteperdrix 0 siblings, 1 reply; 17+ messages in thread From: Sascha Hauer @ 2009-04-22 12:20 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: netdev, Lennert Buytenhek, Ivo Clarysse On Wed, Apr 22, 2009 at 11:42:57AM +0200, Gilles Chanteperdrix wrote: > Sascha Hauer wrote: > > +MODULE_AUTHOR("Abraham van der Merwe <abraham@2d3d.co.za>"); > > The 2d3d.co.za domain does not seem to exist. Ok, I'll just put myself as the module author and leave the credits to Abraham in the header, just removing his email address. I can't find any newer pointers to Abraham besides a facebook profile. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 12:20 ` Sascha Hauer @ 2009-04-22 12:25 ` Gilles Chanteperdrix 2009-04-22 13:05 ` Sascha Hauer 0 siblings, 1 reply; 17+ messages in thread From: Gilles Chanteperdrix @ 2009-04-22 12:25 UTC (permalink / raw) To: Sascha Hauer; +Cc: netdev, Lennert Buytenhek, Ivo Clarysse Sascha Hauer wrote: > On Wed, Apr 22, 2009 at 11:42:57AM +0200, Gilles Chanteperdrix wrote: >> Sascha Hauer wrote: >>> +MODULE_AUTHOR("Abraham van der Merwe <abraham@2d3d.co.za>"); >> The 2d3d.co.za domain does not seem to exist. > > Ok, I'll just put myself as the module author and leave the credits to > Abraham in the header, just removing his email address. I can't find > any newer pointers to Abraham besides a facebook profile. 123people finds the following addresses: abz@clug.org.za abz@blio.net abz@debian.org -- Gilles. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 12:25 ` Gilles Chanteperdrix @ 2009-04-22 13:05 ` Sascha Hauer 0 siblings, 0 replies; 17+ messages in thread From: Sascha Hauer @ 2009-04-22 13:05 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: netdev, Lennert Buytenhek, Ivo Clarysse On Wed, Apr 22, 2009 at 02:25:29PM +0200, Gilles Chanteperdrix wrote: > Sascha Hauer wrote: > > On Wed, Apr 22, 2009 at 11:42:57AM +0200, Gilles Chanteperdrix wrote: > >> Sascha Hauer wrote: > >>> +MODULE_AUTHOR("Abraham van der Merwe <abraham@2d3d.co.za>"); > >> The 2d3d.co.za domain does not seem to exist. > > > > Ok, I'll just put myself as the module author and leave the credits to > > Abraham in the header, just removing his email address. I can't find > > any newer pointers to Abraham besides a facebook profile. > > 123people finds the following addresses: > abz@clug.org.za > abz@blio.net > abz@debian.org I'll set him on cc in the next round. I changed the module author nonetheless as it's better when mails regarding this driver go to me instead of Abraham (who wrote this driver in 2.4 days and probably has not much interest in it anymore) Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer ` (2 preceding siblings ...) 2009-04-22 9:42 ` Gilles Chanteperdrix @ 2009-08-26 10:46 ` Kurt Van Dijck 2009-09-07 10:24 ` Sascha Hauer 2009-10-16 9:37 ` Kurt Van Dijck 4 siblings, 1 reply; 17+ messages in thread From: Kurt Van Dijck @ 2009-08-26 10:46 UTC (permalink / raw) To: Sascha Hauer; +Cc: netdev Hi Sacha, I'm using a 2.6.25. Converting to your platform_device based driver, I needed to configure the irq (see patch, irq flags). Looking in the old cs89x0.c, it's done in the driver. Should I have configured the irq level elsewhere? Or is this patch valid to do? Kurt Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be> --- Index: drivers/net/cirrus-cs89x0.c =================================================================== --- drivers/net/cirrus-cs89x0.c (revision 7107) +++ drivers/net/cirrus-cs89x0.c (working copy) @@ -487,7 +487,8 @@ } /* install interrupt handler */ - result = request_irq(ndev->irq, &cirrus_interrupt, 0, ndev->name, ndev); + result = request_irq(ndev->irq, &cirrus_interrupt, + IRQF_TRIGGER_HIGH, ndev->name, ndev); if (result < 0) { printk(KERN_ERR "%s: could not register interrupt %d\n", ndev->name, ndev->irq); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-08-26 10:46 ` Kurt Van Dijck @ 2009-09-07 10:24 ` Sascha Hauer 2009-09-07 12:35 ` Kurt Van Dijck 0 siblings, 1 reply; 17+ messages in thread From: Sascha Hauer @ 2009-09-07 10:24 UTC (permalink / raw) To: Kurt Van Dijck; +Cc: netdev Hi Kurt, On Wed, Aug 26, 2009 at 12:46:34PM +0200, Kurt Van Dijck wrote: > Hi Sacha, > > I'm using a 2.6.25. > Converting to your platform_device based driver, > I needed to configure the irq (see patch, irq flags). > Looking in the old cs89x0.c, it's done in the driver. Should I have > configured the irq level elsewhere? Or is this patch valid to do? This is the way to go. I don't know if the cs89x0 has configurable interrupt levels though. Sascha > > Kurt > > Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be> > --- > Index: drivers/net/cirrus-cs89x0.c > =================================================================== > --- drivers/net/cirrus-cs89x0.c (revision 7107) > +++ drivers/net/cirrus-cs89x0.c (working copy) > @@ -487,7 +487,8 @@ > } > > /* install interrupt handler */ > - result = request_irq(ndev->irq, &cirrus_interrupt, 0, ndev->name, ndev); > + result = request_irq(ndev->irq, &cirrus_interrupt, > + IRQF_TRIGGER_HIGH, ndev->name, ndev); > if (result < 0) { > printk(KERN_ERR "%s: could not register interrupt %d\n", > ndev->name, ndev->irq); > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-09-07 10:24 ` Sascha Hauer @ 2009-09-07 12:35 ` Kurt Van Dijck 2009-09-07 13:21 ` Sascha Hauer 0 siblings, 1 reply; 17+ messages in thread From: Kurt Van Dijck @ 2009-09-07 12:35 UTC (permalink / raw) To: Sascha Hauer; +Cc: netdev On Mon, Sep 07, 2009 at 12:24:34PM +0200, Sascha Hauer wrote: > Date: Mon, 7 Sep 2009 12:24:34 +0200 > Subject: Re: [PATCH 1/2] Add an alternative cs89x0 driver > From: Sascha Hauer <s.hauer@pengutronix.de> > To: Kurt Van Dijck <kurt.van.dijck@eia.be> > Cc: netdev@vger.kernel.org > List-ID: <netdev.vger.kernel.org> > > Hi Kurt, > > On Wed, Aug 26, 2009 at 12:46:34PM +0200, Kurt Van Dijck wrote: > > Hi Sacha, > > > > I'm using a 2.6.25. > > Converting to your platform_device based driver, > > I needed to configure the irq (see patch, irq flags). > > Looking in the old cs89x0.c, it's done in the driver. Should I have > > configured the irq level elsewhere? Or is this patch valid to do? > > This is the way to go. I don't know if the cs89x0 has configurable > interrupt levels though. I haven't read any spec about cs89x0, but by looking in the existing code: 1) IRQF_TRIGGER_HIGH seems like the default 2) the old driver didn't do any irq config in the chip either. May I assume you were lucky testing the driver on a platform that had IRQF_TRIGGER_HIGH per default? I have it running (with patch) on a iMX31 (arm) Kurt > > Sascha > > > > > Kurt > > > > Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be> > > --- > > Index: drivers/net/cirrus-cs89x0.c > > =================================================================== > > --- drivers/net/cirrus-cs89x0.c (revision 7107) > > +++ drivers/net/cirrus-cs89x0.c (working copy) > > @@ -487,7 +487,8 @@ > > } > > > > /* install interrupt handler */ > > - result = request_irq(ndev->irq, &cirrus_interrupt, 0, ndev->name, ndev); > > + result = request_irq(ndev->irq, &cirrus_interrupt, > > + IRQF_TRIGGER_HIGH, ndev->name, ndev); > > if (result < 0) { > > printk(KERN_ERR "%s: could not register interrupt %d\n", > > ndev->name, ndev->irq); > > > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-09-07 12:35 ` Kurt Van Dijck @ 2009-09-07 13:21 ` Sascha Hauer 0 siblings, 0 replies; 17+ messages in thread From: Sascha Hauer @ 2009-09-07 13:21 UTC (permalink / raw) To: Kurt Van Dijck; +Cc: netdev On Mon, Sep 07, 2009 at 02:35:54PM +0200, Kurt Van Dijck wrote: > On Mon, Sep 07, 2009 at 12:24:34PM +0200, Sascha Hauer wrote: > > Date: Mon, 7 Sep 2009 12:24:34 +0200 > > Subject: Re: [PATCH 1/2] Add an alternative cs89x0 driver > > From: Sascha Hauer <s.hauer@pengutronix.de> > > To: Kurt Van Dijck <kurt.van.dijck@eia.be> > > Cc: netdev@vger.kernel.org > > List-ID: <netdev.vger.kernel.org> > > > > Hi Kurt, > > > > On Wed, Aug 26, 2009 at 12:46:34PM +0200, Kurt Van Dijck wrote: > > > Hi Sacha, > > > > > > I'm using a 2.6.25. > > > Converting to your platform_device based driver, > > > I needed to configure the irq (see patch, irq flags). > > > Looking in the old cs89x0.c, it's done in the driver. Should I have > > > configured the irq level elsewhere? Or is this patch valid to do? > > > > This is the way to go. I don't know if the cs89x0 has configurable > > interrupt levels though. > I haven't read any spec about cs89x0, but by looking in the existing > code: > 1) IRQF_TRIGGER_HIGH seems like the default > 2) the old driver didn't do any irq config in the chip either. > May I assume you were lucky testing the driver on a platform that had > IRQF_TRIGGER_HIGH per default? > I have it running (with patch) on a iMX31 (arm) I tested it with an i.MX1. Looking at the code it seems that __irq_set_trigger is only called if one of the trigger mask bits is set. So the interrupt control registers are never touched when 0 is passed as irq flags. The reset default for i.MX is rising edge. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] Add an alternative cs89x0 driver 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer ` (3 preceding siblings ...) 2009-08-26 10:46 ` Kurt Van Dijck @ 2009-10-16 9:37 ` Kurt Van Dijck 4 siblings, 0 replies; 17+ messages in thread From: Kurt Van Dijck @ 2009-10-16 9:37 UTC (permalink / raw) To: Sascha Hauer Cc: netdev, Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix On Wed, Apr 22, 2009 at 09:59:31AM +0200, Sascha Hauer wrote: > The in Kernel driver is far beyond its age. it still does not use > driver model and its mere presence in the Kernel image prevents > booting my board. The CS8900 still is in use on some embedded > boards, so this patch adds an alternative driver to the tree > designed to replace the old one. > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > --- > drivers/net/Kconfig | 12 + > drivers/net/Makefile | 1 + > drivers/net/cirrus-cs89x0.c | 847 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 860 insertions(+), 0 deletions(-) > create mode 100644 drivers/net/cirrus-cs89x0.c [...] > diff --git a/drivers/net/cirrus-cs89x0.c b/drivers/net/cirrus-cs89x0.c [...] > +static void > +cirrus_set_receive_mode(struct net_device *ndev) > +{ > + struct cirrus_priv *priv = netdev_priv(ndev); > + > + spin_lock(&priv->lock); > + I found this function causing locking problems. using spin_lock_irqsave/spin_lock_irqrestore solved them. Can xxx_set_receive_mode be called with interrupts enabled? I just want to make sure that I didn't break something elsewhere, and I don't know ethernet (devices) that well. Kurt ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add new cs89x0 driver 2009-04-22 7:59 [PATCH] Add new cs89x0 driver Sascha Hauer 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer @ 2009-04-22 22:53 ` Lennert Buytenhek 2009-04-23 7:03 ` Sascha Hauer 2009-10-20 9:55 ` Ben Dooks 2 siblings, 1 reply; 17+ messages in thread From: Lennert Buytenhek @ 2009-04-22 22:53 UTC (permalink / raw) To: Sascha Hauer Cc: netdev, Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix On Wed, Apr 22, 2009 at 09:59:30AM +0200, Sascha Hauer wrote: > While this is a very old chip it is still in use on some embedded > boards. I see myself unable to fix the in Kernel driver to bring > it to driver model support, so this patch adds a new driver designed > to replace the old one, at least for non-ISA hardware. I had the same thought initially when I started working on mv643xx_eth, but I decided to try and beat the existing driver into shape anyway. The mv643xx_eth driver now is not too different from how I would have written it had I rewritten it from scratch, and refactoring it took about a hundred commits and probably a bunch more effort than just rewriting it would have taken, but in the end I probably _saved_ myself time by being able to (have users) bisect problems instead of having to spend time trying to figure out why driver A works but B doesn't or vice versa, not having to chase people to switch their platforms over to the new driver, etc. (I'm not saying that there's absolutely no other way for you to go than to do the same thing -- it's just a thought.) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add new cs89x0 driver 2009-04-22 22:53 ` [PATCH] Add new " Lennert Buytenhek @ 2009-04-23 7:03 ` Sascha Hauer 0 siblings, 0 replies; 17+ messages in thread From: Sascha Hauer @ 2009-04-23 7:03 UTC (permalink / raw) To: Lennert Buytenhek Cc: netdev, Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix On Thu, Apr 23, 2009 at 12:53:28AM +0200, Lennert Buytenhek wrote: > On Wed, Apr 22, 2009 at 09:59:30AM +0200, Sascha Hauer wrote: > > > While this is a very old chip it is still in use on some embedded > > boards. I see myself unable to fix the in Kernel driver to bring > > it to driver model support, so this patch adds a new driver designed > > to replace the old one, at least for non-ISA hardware. > > I had the same thought initially when I started working on mv643xx_eth, > but I decided to try and beat the existing driver into shape anyway. The > mv643xx_eth driver now is not too different from how I would have written > it had I rewritten it from scratch, and refactoring it took about a > hundred commits and probably a bunch more effort than just rewriting it > would have taken, but in the end I probably _saved_ myself time by being > able to (have users) bisect problems instead of having to spend time > trying to figure out why driver A works but B doesn't or vice versa, not > having to chase people to switch their platforms over to the new driver, > etc. > > (I'm not saying that there's absolutely no other way for you to go than > to do the same thing -- it's just a thought.) I've gone that way with the fec.c driver recently, now I'm trying the other way ;) The problem with the cs89x0 driver is that it is an ISA driver. I think it will be hard to find testers owning an ISA card with a cs89x0 chip. (If you, dear reader, are one of those, please speak up) For the embedded users it's simple. There are some Freescale i.MX Board which I own myself or stay in contact with people who have one and some IXP boards. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add new cs89x0 driver 2009-04-22 7:59 [PATCH] Add new cs89x0 driver Sascha Hauer 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer 2009-04-22 22:53 ` [PATCH] Add new " Lennert Buytenhek @ 2009-10-20 9:55 ` Ben Dooks 2 siblings, 0 replies; 17+ messages in thread From: Ben Dooks @ 2009-10-20 9:55 UTC (permalink / raw) To: Sascha Hauer Cc: netdev, Lennert Buytenhek, Ivo Clarysse, Gilles Chanteperdrix On Wed, Apr 22, 2009 at 09:59:30AM +0200, Sascha Hauer wrote: > While this is a very old chip it is still in use on some embedded boards. > I see myself unable to fix the in Kernel driver to bring it to driver > model support, so this patch adds a new driver designed to replace > the old one, at least for non-ISA hardware. I think it is worthwile, there's a number of SMDK boards and similar which have used this board, including boards released in the last year or so. I will try and see if I can do some reviewing and testing of this in the next few days. -- Ben (ben@fluff.org, http://www.fluff.org/) 'a smiley only costs 4 bytes' ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2009-10-20 9:55 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-04-22 7:59 [PATCH] Add new cs89x0 driver Sascha Hauer 2009-04-22 7:59 ` [PATCH 1/2] Add an alternative " Sascha Hauer 2009-04-22 7:59 ` [PATCH 2/2] mx1ads: Add cs89x0 network support Sascha Hauer 2009-04-22 9:28 ` [PATCH 1/2] Add an alternative cs89x0 driver Ivo Clarysse 2009-04-22 12:18 ` Sascha Hauer 2009-04-22 9:42 ` Gilles Chanteperdrix 2009-04-22 12:20 ` Sascha Hauer 2009-04-22 12:25 ` Gilles Chanteperdrix 2009-04-22 13:05 ` Sascha Hauer 2009-08-26 10:46 ` Kurt Van Dijck 2009-09-07 10:24 ` Sascha Hauer 2009-09-07 12:35 ` Kurt Van Dijck 2009-09-07 13:21 ` Sascha Hauer 2009-10-16 9:37 ` Kurt Van Dijck 2009-04-22 22:53 ` [PATCH] Add new " Lennert Buytenhek 2009-04-23 7:03 ` Sascha Hauer 2009-10-20 9:55 ` Ben Dooks
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.