Commit 61b9da92 authored by David S. Miller's avatar David S. Miller

Merge tag 'arcnet-for-4.4-rc1' of git://git.pengutronix.de/git/mgr/linux

Michael Grzeschik says:

====================
This series includes code simplifaction. The main changes are the correct
xceiver handling (enable/disable) of the com20020 cards. The driver now handles
link status change detection. The EAE PCI-ARCNET cards now make use of the
rotary encoded subdevice indexing and got support for led triggers on transmit
and reconnection events.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4b3418fb 59fbcbc6
...@@ -237,6 +237,8 @@ struct Outgoing { ...@@ -237,6 +237,8 @@ struct Outgoing {
numsegs; /* number of segments */ numsegs; /* number of segments */
}; };
#define ARCNET_LED_NAME_SZ (IFNAMSIZ + 6)
struct arcnet_local { struct arcnet_local {
uint8_t config, /* current value of CONFIG register */ uint8_t config, /* current value of CONFIG register */
timeout, /* Extended timeout for COM20020 */ timeout, /* Extended timeout for COM20020 */
...@@ -260,6 +262,13 @@ struct arcnet_local { ...@@ -260,6 +262,13 @@ struct arcnet_local {
/* On preemtive and SMB a lock is needed */ /* On preemtive and SMB a lock is needed */
spinlock_t lock; spinlock_t lock;
struct led_trigger *tx_led_trig;
char tx_led_trig_name[ARCNET_LED_NAME_SZ];
struct led_trigger *recon_led_trig;
char recon_led_trig_name[ARCNET_LED_NAME_SZ];
struct timer_list timer;
/* /*
* Buffer management: an ARCnet card has 4 x 512-byte buffers, each of * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
* which can be used for either sending or receiving. The new dynamic * which can be used for either sending or receiving. The new dynamic
...@@ -309,6 +318,8 @@ struct arcnet_local { ...@@ -309,6 +318,8 @@ struct arcnet_local {
int (*reset)(struct net_device *dev, int really_reset); int (*reset)(struct net_device *dev, int really_reset);
void (*open)(struct net_device *dev); void (*open)(struct net_device *dev);
void (*close)(struct net_device *dev); void (*close)(struct net_device *dev);
void (*datatrigger) (struct net_device * dev, int enable);
void (*recontrigger) (struct net_device * dev, int enable);
void (*copy_to_card)(struct net_device *dev, int bufnum, void (*copy_to_card)(struct net_device *dev, int bufnum,
int offset, void *buf, int count); int offset, void *buf, int count);
...@@ -319,6 +330,16 @@ struct arcnet_local { ...@@ -319,6 +330,16 @@ struct arcnet_local {
void __iomem *mem_start; /* pointer to ioremap'ed MMIO */ void __iomem *mem_start; /* pointer to ioremap'ed MMIO */
}; };
enum arcnet_led_event {
ARCNET_LED_EVENT_RECON,
ARCNET_LED_EVENT_OPEN,
ARCNET_LED_EVENT_STOP,
ARCNET_LED_EVENT_TX,
};
void arcnet_led_event(struct net_device *netdev, enum arcnet_led_event event);
void devm_arcnet_led_init(struct net_device *netdev, int index, int subid);
#if ARCNET_DEBUG_MAX & D_SKB #if ARCNET_DEBUG_MAX & D_SKB
void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc); void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc);
#else #else
......
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/leds.h>
#include "arcdevice.h" #include "arcdevice.h"
#include "com9026.h" #include "com9026.h"
...@@ -189,6 +191,71 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, ...@@ -189,6 +191,71 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
#endif #endif
/* Trigger a LED event in response to a ARCNET device event */
void arcnet_led_event(struct net_device *dev, enum arcnet_led_event event)
{
struct arcnet_local *lp = netdev_priv(dev);
unsigned long led_delay = 350;
unsigned long tx_delay = 50;
switch (event) {
case ARCNET_LED_EVENT_RECON:
led_trigger_blink_oneshot(lp->recon_led_trig,
&led_delay, &led_delay, 0);
break;
case ARCNET_LED_EVENT_OPEN:
led_trigger_event(lp->tx_led_trig, LED_OFF);
led_trigger_event(lp->recon_led_trig, LED_OFF);
break;
case ARCNET_LED_EVENT_STOP:
led_trigger_event(lp->tx_led_trig, LED_OFF);
led_trigger_event(lp->recon_led_trig, LED_OFF);
break;
case ARCNET_LED_EVENT_TX:
led_trigger_blink_oneshot(lp->tx_led_trig,
&tx_delay, &tx_delay, 0);
break;
}
}
EXPORT_SYMBOL_GPL(arcnet_led_event);
static void arcnet_led_release(struct device *gendev, void *res)
{
struct arcnet_local *lp = netdev_priv(to_net_dev(gendev));
led_trigger_unregister_simple(lp->tx_led_trig);
led_trigger_unregister_simple(lp->recon_led_trig);
}
/* Register ARCNET LED triggers for a arcnet device
*
* This is normally called from a driver's probe function
*/
void devm_arcnet_led_init(struct net_device *netdev, int index, int subid)
{
struct arcnet_local *lp = netdev_priv(netdev);
void *res;
res = devres_alloc(arcnet_led_release, 0, GFP_KERNEL);
if (!res) {
netdev_err(netdev, "cannot register LED triggers\n");
return;
}
snprintf(lp->tx_led_trig_name, sizeof(lp->tx_led_trig_name),
"arc%d-%d-tx", index, subid);
snprintf(lp->recon_led_trig_name, sizeof(lp->recon_led_trig_name),
"arc%d-%d-recon", index, subid);
led_trigger_register_simple(lp->tx_led_trig_name,
&lp->tx_led_trig);
led_trigger_register_simple(lp->recon_led_trig_name,
&lp->recon_led_trig);
devres_add(&netdev->dev, res);
}
EXPORT_SYMBOL_GPL(devm_arcnet_led_init);
/* Unregister a protocol driver from the arc_proto_map. Protocol drivers /* Unregister a protocol driver from the arc_proto_map. Protocol drivers
* are responsible for registering themselves, but the unregister routine * are responsible for registering themselves, but the unregister routine
* is pretty generic so we'll do it here. * is pretty generic so we'll do it here.
...@@ -314,6 +381,16 @@ static void arcdev_setup(struct net_device *dev) ...@@ -314,6 +381,16 @@ static void arcdev_setup(struct net_device *dev)
dev->flags = IFF_BROADCAST; dev->flags = IFF_BROADCAST;
} }
static void arcnet_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
netdev_info(dev, "link up\n");
}
}
struct net_device *alloc_arcdev(const char *name) struct net_device *alloc_arcdev(const char *name)
{ {
struct net_device *dev; struct net_device *dev;
...@@ -325,6 +402,9 @@ struct net_device *alloc_arcdev(const char *name) ...@@ -325,6 +402,9 @@ struct net_device *alloc_arcdev(const char *name)
struct arcnet_local *lp = netdev_priv(dev); struct arcnet_local *lp = netdev_priv(dev);
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
init_timer(&lp->timer);
lp->timer.data = (unsigned long) dev;
lp->timer.function = arcnet_timer;
} }
return dev; return dev;
...@@ -423,8 +503,11 @@ int arcnet_open(struct net_device *dev) ...@@ -423,8 +503,11 @@ int arcnet_open(struct net_device *dev)
lp->hw.intmask(dev, lp->intmask); lp->hw.intmask(dev, lp->intmask);
arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__); arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
netif_carrier_off(dev);
netif_start_queue(dev); netif_start_queue(dev);
mod_timer(&lp->timer, jiffies + msecs_to_jiffies(1000));
arcnet_led_event(dev, ARCNET_LED_EVENT_OPEN);
return 0; return 0;
out_module_put: out_module_put:
...@@ -438,7 +521,11 @@ int arcnet_close(struct net_device *dev) ...@@ -438,7 +521,11 @@ int arcnet_close(struct net_device *dev)
{ {
struct arcnet_local *lp = netdev_priv(dev); struct arcnet_local *lp = netdev_priv(dev);
arcnet_led_event(dev, ARCNET_LED_EVENT_STOP);
del_timer_sync(&lp->timer);
netif_stop_queue(dev); netif_stop_queue(dev);
netif_carrier_off(dev);
/* flush TX and disable RX */ /* flush TX and disable RX */
lp->hw.intmask(dev, 0); lp->hw.intmask(dev, 0);
...@@ -515,7 +602,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, ...@@ -515,7 +602,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
struct ArcProto *proto; struct ArcProto *proto;
int txbuf; int txbuf;
unsigned long flags; unsigned long flags;
int freeskb, retval; int retval;
arc_printk(D_DURING, dev, arc_printk(D_DURING, dev,
"transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
...@@ -554,15 +641,13 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, ...@@ -554,15 +641,13 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
* the package later - forget about it now * the package later - forget about it now
*/ */
dev->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
freeskb = 1; dev_kfree_skb(skb);
} else { } else {
/* do it the 'split' way */ /* do it the 'split' way */
lp->outgoing.proto = proto; lp->outgoing.proto = proto;
lp->outgoing.skb = skb; lp->outgoing.skb = skb;
lp->outgoing.pkt = pkt; lp->outgoing.pkt = pkt;
freeskb = 0;
if (proto->continue_tx && if (proto->continue_tx &&
proto->continue_tx(dev, txbuf)) { proto->continue_tx(dev, txbuf)) {
arc_printk(D_NORMAL, dev, arc_printk(D_NORMAL, dev,
...@@ -574,7 +659,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, ...@@ -574,7 +659,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
lp->next_tx = txbuf; lp->next_tx = txbuf;
} else { } else {
retval = NETDEV_TX_BUSY; retval = NETDEV_TX_BUSY;
freeskb = 0;
} }
arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n", arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n",
...@@ -588,10 +672,9 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, ...@@ -588,10 +672,9 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n", arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n",
__FILE__, __LINE__, __func__, lp->hw.status(dev)); __FILE__, __LINE__, __func__, lp->hw.status(dev));
spin_unlock_irqrestore(&lp->lock, flags); arcnet_led_event(dev, ARCNET_LED_EVENT_TX);
if (freeskb)
dev_kfree_skb(skb);
spin_unlock_irqrestore(&lp->lock, flags);
return retval; /* no need to try again */ return retval; /* no need to try again */
} }
EXPORT_SYMBOL(arcnet_send_packet); EXPORT_SYMBOL(arcnet_send_packet);
...@@ -843,6 +926,13 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) ...@@ -843,6 +926,13 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
arc_printk(D_RECON, dev, "Network reconfiguration detected (status=%Xh)\n", arc_printk(D_RECON, dev, "Network reconfiguration detected (status=%Xh)\n",
status); status);
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
netdev_info(dev, "link down\n");
}
mod_timer(&lp->timer, jiffies + msecs_to_jiffies(1000));
arcnet_led_event(dev, ARCNET_LED_EVENT_RECON);
/* MYRECON bit is at bit 7 of diagstatus */ /* MYRECON bit is at bit 7 of diagstatus */
if (diagstatus & 0x80) if (diagstatus & 0x80)
arc_printk(D_RECON, dev, "Put out that recon myself\n"); arc_printk(D_RECON, dev, "Put out that recon myself\n");
...@@ -893,6 +983,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) ...@@ -893,6 +983,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
lp->num_recons = lp->network_down = 0; lp->num_recons = lp->network_down = 0;
arc_printk(D_DURING, dev, "not recon: clearing counters anyway.\n"); arc_printk(D_DURING, dev, "not recon: clearing counters anyway.\n");
netif_carrier_on(dev);
} }
if (didsomething) if (didsomething)
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/leds.h>
#include "arcdevice.h" #include "arcdevice.h"
#include "com20020.h" #include "com20020.h"
...@@ -62,12 +63,43 @@ module_param(clockp, int, 0); ...@@ -62,12 +63,43 @@ module_param(clockp, int, 0);
module_param(clockm, int, 0); module_param(clockm, int, 0);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static void led_tx_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct com20020_dev *card;
struct com20020_priv *priv;
struct com20020_pci_card_info *ci;
card = container_of(led_cdev, struct com20020_dev, tx_led);
priv = card->pci_priv;
ci = priv->ci;
outb(!!value, priv->misc + ci->leds[card->index].green);
}
static void led_recon_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct com20020_dev *card;
struct com20020_priv *priv;
struct com20020_pci_card_info *ci;
card = container_of(led_cdev, struct com20020_dev, recon_led);
priv = card->pci_priv;
ci = priv->ci;
outb(!!value, priv->misc + ci->leds[card->index].red);
}
static void com20020pci_remove(struct pci_dev *pdev); static void com20020pci_remove(struct pci_dev *pdev);
static int com20020pci_probe(struct pci_dev *pdev, static int com20020pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct com20020_pci_card_info *ci; struct com20020_pci_card_info *ci;
struct com20020_pci_channel_map *mm;
struct net_device *dev; struct net_device *dev;
struct arcnet_local *lp; struct arcnet_local *lp;
struct com20020_priv *priv; struct com20020_priv *priv;
...@@ -84,9 +116,22 @@ static int com20020pci_probe(struct pci_dev *pdev, ...@@ -84,9 +116,22 @@ static int com20020pci_probe(struct pci_dev *pdev,
ci = (struct com20020_pci_card_info *)id->driver_data; ci = (struct com20020_pci_card_info *)id->driver_data;
priv->ci = ci; priv->ci = ci;
mm = &ci->misc_map;
INIT_LIST_HEAD(&priv->list_dev); INIT_LIST_HEAD(&priv->list_dev);
if (mm->size) {
ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset;
r = devm_request_region(&pdev->dev, ioaddr, mm->size,
"com20020-pci");
if (!r) {
pr_err("IO region %xh-%xh already allocated.\n",
ioaddr, ioaddr + mm->size - 1);
return -EBUSY;
}
priv->misc = ioaddr;
}
for (i = 0; i < ci->devcount; i++) { for (i = 0; i < ci->devcount; i++) {
struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i]; struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
struct com20020_dev *card; struct com20020_dev *card;
...@@ -96,6 +141,7 @@ static int com20020pci_probe(struct pci_dev *pdev, ...@@ -96,6 +141,7 @@ static int com20020pci_probe(struct pci_dev *pdev,
ret = -ENOMEM; ret = -ENOMEM;
goto out_port; goto out_port;
} }
dev->dev_port = i;
dev->netdev_ops = &com20020_netdev_ops; dev->netdev_ops = &com20020_netdev_ops;
...@@ -131,6 +177,13 @@ static int com20020pci_probe(struct pci_dev *pdev, ...@@ -131,6 +177,13 @@ static int com20020pci_probe(struct pci_dev *pdev,
lp->timeout = timeout; lp->timeout = timeout;
lp->hw.owner = THIS_MODULE; lp->hw.owner = THIS_MODULE;
/* Get the dev_id from the PLX rotary coder */
if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
dev->dev_id = 0xc;
dev->dev_id ^= inb(priv->misc + ci->rotary) >> 4;
snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
pr_err("IO address %Xh is empty!\n", ioaddr); pr_err("IO address %Xh is empty!\n", ioaddr);
ret = -EIO; ret = -EIO;
...@@ -148,14 +201,41 @@ static int com20020pci_probe(struct pci_dev *pdev, ...@@ -148,14 +201,41 @@ static int com20020pci_probe(struct pci_dev *pdev,
card->index = i; card->index = i;
card->pci_priv = priv; card->pci_priv = priv;
card->tx_led.brightness_set = led_tx_set;
card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
GFP_KERNEL, "arc%d-%d-tx",
dev->dev_id, i);
card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"pci:green:tx:%d-%d",
dev->dev_id, i);
card->tx_led.dev = &dev->dev;
card->recon_led.brightness_set = led_recon_set;
card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
GFP_KERNEL, "arc%d-%d-recon",
dev->dev_id, i);
card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"pci:red:recon:%d-%d",
dev->dev_id, i);
card->recon_led.dev = &dev->dev;
card->dev = dev; card->dev = dev;
ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
if (ret)
goto out_port;
ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
if (ret)
goto out_port;
dev_set_drvdata(&dev->dev, card); dev_set_drvdata(&dev->dev, card);
ret = com20020_found(dev, IRQF_SHARED); ret = com20020_found(dev, IRQF_SHARED);
if (ret) if (ret)
goto out_port; goto out_port;
devm_arcnet_led_init(dev, dev->dev_id, i);
list_add(&card->list, &priv->list_dev); list_add(&card->list, &priv->list_dev);
} }
...@@ -234,6 +314,18 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { ...@@ -234,6 +314,18 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
.size = 0x08, .size = 0x08,
}, },
}, },
.misc_map = {
.bar = 2,
.offset = 0x10,
.size = 0x04,
},
.leds = {
{
.green = 0x0,
.red = 0x1,
},
},
.rotary = 0x0,
.flags = ARC_CAN_10MBIT, .flags = ARC_CAN_10MBIT,
}; };
...@@ -251,6 +343,21 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { ...@@ -251,6 +343,21 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
.size = 0x08, .size = 0x08,
} }
}, },
.misc_map = {
.bar = 2,
.offset = 0x10,
.size = 0x04,
},
.leds = {
{
.green = 0x0,
.red = 0x1,
}, {
.green = 0x2,
.red = 0x3,
},
},
.rotary = 0x0,
.flags = ARC_CAN_10MBIT, .flags = ARC_CAN_10MBIT,
}; };
......
...@@ -118,7 +118,7 @@ int com20020_check(struct net_device *dev) ...@@ -118,7 +118,7 @@ int com20020_check(struct net_device *dev)
arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND); arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND);
} }
lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; lp->config = (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE;
/* set node ID to 0x42 (but transmitter is disabled, so it's okay) */ /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG); arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
arcnet_outb(0x42, ioaddr, COM20020_REG_W_XREG); arcnet_outb(0x42, ioaddr, COM20020_REG_W_XREG);
...@@ -131,11 +131,6 @@ int com20020_check(struct net_device *dev) ...@@ -131,11 +131,6 @@ int com20020_check(struct net_device *dev)
} }
arc_printk(D_INIT_REASONS, dev, "status after reset: %X\n", status); arc_printk(D_INIT_REASONS, dev, "status after reset: %X\n", status);
/* Enable TX */
lp->config |= TXENcfg;
arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
arcnet_outb(arcnet_inb(ioaddr, 8), ioaddr, COM20020_REG_W_XREG);
arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear, arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
ioaddr, COM20020_REG_W_COMMAND); ioaddr, COM20020_REG_W_COMMAND);
status = arcnet_inb(ioaddr, COM20020_REG_R_STATUS); status = arcnet_inb(ioaddr, COM20020_REG_R_STATUS);
...@@ -169,9 +164,33 @@ static int com20020_set_hwaddr(struct net_device *dev, void *addr) ...@@ -169,9 +164,33 @@ static int com20020_set_hwaddr(struct net_device *dev, void *addr)
return 0; return 0;
} }
static int com20020_netdev_open(struct net_device *dev)
{
int ioaddr = dev->base_addr;
struct arcnet_local *lp = netdev_priv(dev);
lp->config |= TXENcfg;
arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
return arcnet_open(dev);
}
static int com20020_netdev_close(struct net_device *dev)
{
int ioaddr = dev->base_addr;
struct arcnet_local *lp = netdev_priv(dev);
arcnet_close(dev);
/* disable transmitter */
lp->config &= ~TXENcfg;
arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
return 0;
}
const struct net_device_ops com20020_netdev_ops = { const struct net_device_ops com20020_netdev_ops = {
.ndo_open = arcnet_open, .ndo_open = com20020_netdev_open,
.ndo_stop = arcnet_close, .ndo_stop = com20020_netdev_close,
.ndo_start_xmit = arcnet_send_packet, .ndo_start_xmit = arcnet_send_packet,
.ndo_tx_timeout = arcnet_timeout, .ndo_tx_timeout = arcnet_timeout,
.ndo_set_mac_address = com20020_set_hwaddr, .ndo_set_mac_address = com20020_set_hwaddr,
...@@ -215,7 +234,7 @@ int com20020_found(struct net_device *dev, int shared) ...@@ -215,7 +234,7 @@ int com20020_found(struct net_device *dev, int shared)
arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND); arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND);
} }
lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; lp->config = (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE;
/* Default 0x38 + register: Node ID */ /* Default 0x38 + register: Node ID */
arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG); arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
arcnet_outb(dev->dev_addr[0], ioaddr, COM20020_REG_W_XREG); arcnet_outb(dev->dev_addr[0], ioaddr, COM20020_REG_W_XREG);
...@@ -274,7 +293,7 @@ static int com20020_reset(struct net_device *dev, int really_reset) ...@@ -274,7 +293,7 @@ static int com20020_reset(struct net_device *dev, int really_reset)
dev->name, arcnet_inb(ioaddr, COM20020_REG_R_STATUS)); dev->name, arcnet_inb(ioaddr, COM20020_REG_R_STATUS));
arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__); arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2); lp->config |= (lp->timeout << 3) | (lp->backplane << 2);
/* power-up defaults */ /* power-up defaults */
arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG); arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__); arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
*/ */
#ifndef __COM20020_H #ifndef __COM20020_H
#define __COM20020_H #define __COM20020_H
#include <linux/leds.h>
int com20020_check(struct net_device *dev); int com20020_check(struct net_device *dev);
int com20020_found(struct net_device *dev, int shared); int com20020_found(struct net_device *dev, int shared);
...@@ -36,6 +37,11 @@ extern const struct net_device_ops com20020_netdev_ops; ...@@ -36,6 +37,11 @@ extern const struct net_device_ops com20020_netdev_ops;
#define PLX_PCI_MAX_CARDS 2 #define PLX_PCI_MAX_CARDS 2
struct ledoffsets {
int green;
int red;
};
struct com20020_pci_channel_map { struct com20020_pci_channel_map {
u32 bar; u32 bar;
u32 offset; u32 offset;
...@@ -47,6 +53,10 @@ struct com20020_pci_card_info { ...@@ -47,6 +53,10 @@ struct com20020_pci_card_info {
int devcount; int devcount;
struct com20020_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CARDS]; struct com20020_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CARDS];
struct com20020_pci_channel_map misc_map;
struct ledoffsets leds[PLX_PCI_MAX_CARDS];
int rotary;
unsigned int flags; unsigned int flags;
}; };
...@@ -54,12 +64,16 @@ struct com20020_pci_card_info { ...@@ -54,12 +64,16 @@ struct com20020_pci_card_info {
struct com20020_priv { struct com20020_priv {
struct com20020_pci_card_info *ci; struct com20020_pci_card_info *ci;
struct list_head list_dev; struct list_head list_dev;
resource_size_t misc;
}; };
struct com20020_dev { struct com20020_dev {
struct list_head list; struct list_head list;
struct net_device *dev; struct net_device *dev;
struct led_classdev tx_led;
struct led_classdev recon_led;
struct com20020_priv *pci_priv; struct com20020_priv *pci_priv;
int index; int index;
}; };
......
...@@ -283,6 +283,13 @@ static inline void led_trigger_register_simple(const char *name, ...@@ -283,6 +283,13 @@ static inline void led_trigger_register_simple(const char *name,
static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {}
static inline void led_trigger_event(struct led_trigger *trigger, static inline void led_trigger_event(struct led_trigger *trigger,
enum led_brightness event) {} enum led_brightness event) {}
static inline void led_trigger_blink(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off) {}
static inline void led_trigger_blink_oneshot(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off,
int invert) {}
static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} static inline void led_trigger_set_default(struct led_classdev *led_cdev) {}
static inline void led_trigger_set(struct led_classdev *led_cdev, static inline void led_trigger_set(struct led_classdev *led_cdev,
struct led_trigger *trigger) {} struct led_trigger *trigger) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment