Skip to content

Commit 61b9da9

Browse files
committed
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: David S. Miller <[email protected]>
2 parents 4b3418f + 59fbcbc commit 61b9da9

File tree

6 files changed

+277
-18
lines changed

6 files changed

+277
-18
lines changed

drivers/net/arcnet/arcdevice.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ struct Outgoing {
237237
numsegs; /* number of segments */
238238
};
239239

240+
#define ARCNET_LED_NAME_SZ (IFNAMSIZ + 6)
241+
240242
struct arcnet_local {
241243
uint8_t config, /* current value of CONFIG register */
242244
timeout, /* Extended timeout for COM20020 */
@@ -260,6 +262,13 @@ struct arcnet_local {
260262
/* On preemtive and SMB a lock is needed */
261263
spinlock_t lock;
262264

265+
struct led_trigger *tx_led_trig;
266+
char tx_led_trig_name[ARCNET_LED_NAME_SZ];
267+
struct led_trigger *recon_led_trig;
268+
char recon_led_trig_name[ARCNET_LED_NAME_SZ];
269+
270+
struct timer_list timer;
271+
263272
/*
264273
* Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
265274
* which can be used for either sending or receiving. The new dynamic
@@ -309,6 +318,8 @@ struct arcnet_local {
309318
int (*reset)(struct net_device *dev, int really_reset);
310319
void (*open)(struct net_device *dev);
311320
void (*close)(struct net_device *dev);
321+
void (*datatrigger) (struct net_device * dev, int enable);
322+
void (*recontrigger) (struct net_device * dev, int enable);
312323

313324
void (*copy_to_card)(struct net_device *dev, int bufnum,
314325
int offset, void *buf, int count);
@@ -319,6 +330,16 @@ struct arcnet_local {
319330
void __iomem *mem_start; /* pointer to ioremap'ed MMIO */
320331
};
321332

333+
enum arcnet_led_event {
334+
ARCNET_LED_EVENT_RECON,
335+
ARCNET_LED_EVENT_OPEN,
336+
ARCNET_LED_EVENT_STOP,
337+
ARCNET_LED_EVENT_TX,
338+
};
339+
340+
void arcnet_led_event(struct net_device *netdev, enum arcnet_led_event event);
341+
void devm_arcnet_led_init(struct net_device *netdev, int index, int subid);
342+
322343
#if ARCNET_DEBUG_MAX & D_SKB
323344
void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc);
324345
#else

drivers/net/arcnet/arcnet.c

Lines changed: 99 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
#include <linux/init.h>
5353
#include <linux/jiffies.h>
5454

55+
#include <linux/leds.h>
56+
5557
#include "arcdevice.h"
5658
#include "com9026.h"
5759

@@ -189,6 +191,71 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
189191

190192
#endif
191193

194+
/* Trigger a LED event in response to a ARCNET device event */
195+
void arcnet_led_event(struct net_device *dev, enum arcnet_led_event event)
196+
{
197+
struct arcnet_local *lp = netdev_priv(dev);
198+
unsigned long led_delay = 350;
199+
unsigned long tx_delay = 50;
200+
201+
switch (event) {
202+
case ARCNET_LED_EVENT_RECON:
203+
led_trigger_blink_oneshot(lp->recon_led_trig,
204+
&led_delay, &led_delay, 0);
205+
break;
206+
case ARCNET_LED_EVENT_OPEN:
207+
led_trigger_event(lp->tx_led_trig, LED_OFF);
208+
led_trigger_event(lp->recon_led_trig, LED_OFF);
209+
break;
210+
case ARCNET_LED_EVENT_STOP:
211+
led_trigger_event(lp->tx_led_trig, LED_OFF);
212+
led_trigger_event(lp->recon_led_trig, LED_OFF);
213+
break;
214+
case ARCNET_LED_EVENT_TX:
215+
led_trigger_blink_oneshot(lp->tx_led_trig,
216+
&tx_delay, &tx_delay, 0);
217+
break;
218+
}
219+
}
220+
EXPORT_SYMBOL_GPL(arcnet_led_event);
221+
222+
static void arcnet_led_release(struct device *gendev, void *res)
223+
{
224+
struct arcnet_local *lp = netdev_priv(to_net_dev(gendev));
225+
226+
led_trigger_unregister_simple(lp->tx_led_trig);
227+
led_trigger_unregister_simple(lp->recon_led_trig);
228+
}
229+
230+
/* Register ARCNET LED triggers for a arcnet device
231+
*
232+
* This is normally called from a driver's probe function
233+
*/
234+
void devm_arcnet_led_init(struct net_device *netdev, int index, int subid)
235+
{
236+
struct arcnet_local *lp = netdev_priv(netdev);
237+
void *res;
238+
239+
res = devres_alloc(arcnet_led_release, 0, GFP_KERNEL);
240+
if (!res) {
241+
netdev_err(netdev, "cannot register LED triggers\n");
242+
return;
243+
}
244+
245+
snprintf(lp->tx_led_trig_name, sizeof(lp->tx_led_trig_name),
246+
"arc%d-%d-tx", index, subid);
247+
snprintf(lp->recon_led_trig_name, sizeof(lp->recon_led_trig_name),
248+
"arc%d-%d-recon", index, subid);
249+
250+
led_trigger_register_simple(lp->tx_led_trig_name,
251+
&lp->tx_led_trig);
252+
led_trigger_register_simple(lp->recon_led_trig_name,
253+
&lp->recon_led_trig);
254+
255+
devres_add(&netdev->dev, res);
256+
}
257+
EXPORT_SYMBOL_GPL(devm_arcnet_led_init);
258+
192259
/* Unregister a protocol driver from the arc_proto_map. Protocol drivers
193260
* are responsible for registering themselves, but the unregister routine
194261
* is pretty generic so we'll do it here.
@@ -314,6 +381,16 @@ static void arcdev_setup(struct net_device *dev)
314381
dev->flags = IFF_BROADCAST;
315382
}
316383

384+
static void arcnet_timer(unsigned long data)
385+
{
386+
struct net_device *dev = (struct net_device *)data;
387+
388+
if (!netif_carrier_ok(dev)) {
389+
netif_carrier_on(dev);
390+
netdev_info(dev, "link up\n");
391+
}
392+
}
393+
317394
struct net_device *alloc_arcdev(const char *name)
318395
{
319396
struct net_device *dev;
@@ -325,6 +402,9 @@ struct net_device *alloc_arcdev(const char *name)
325402
struct arcnet_local *lp = netdev_priv(dev);
326403

327404
spin_lock_init(&lp->lock);
405+
init_timer(&lp->timer);
406+
lp->timer.data = (unsigned long) dev;
407+
lp->timer.function = arcnet_timer;
328408
}
329409

330410
return dev;
@@ -423,8 +503,11 @@ int arcnet_open(struct net_device *dev)
423503
lp->hw.intmask(dev, lp->intmask);
424504
arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
425505

506+
netif_carrier_off(dev);
426507
netif_start_queue(dev);
508+
mod_timer(&lp->timer, jiffies + msecs_to_jiffies(1000));
427509

510+
arcnet_led_event(dev, ARCNET_LED_EVENT_OPEN);
428511
return 0;
429512

430513
out_module_put:
@@ -438,7 +521,11 @@ int arcnet_close(struct net_device *dev)
438521
{
439522
struct arcnet_local *lp = netdev_priv(dev);
440523

524+
arcnet_led_event(dev, ARCNET_LED_EVENT_STOP);
525+
del_timer_sync(&lp->timer);
526+
441527
netif_stop_queue(dev);
528+
netif_carrier_off(dev);
442529

443530
/* flush TX and disable RX */
444531
lp->hw.intmask(dev, 0);
@@ -515,7 +602,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
515602
struct ArcProto *proto;
516603
int txbuf;
517604
unsigned long flags;
518-
int freeskb, retval;
605+
int retval;
519606

520607
arc_printk(D_DURING, dev,
521608
"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,
554641
* the package later - forget about it now
555642
*/
556643
dev->stats.tx_bytes += skb->len;
557-
freeskb = 1;
644+
dev_kfree_skb(skb);
558645
} else {
559646
/* do it the 'split' way */
560647
lp->outgoing.proto = proto;
561648
lp->outgoing.skb = skb;
562649
lp->outgoing.pkt = pkt;
563650

564-
freeskb = 0;
565-
566651
if (proto->continue_tx &&
567652
proto->continue_tx(dev, txbuf)) {
568653
arc_printk(D_NORMAL, dev,
@@ -574,7 +659,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
574659
lp->next_tx = txbuf;
575660
} else {
576661
retval = NETDEV_TX_BUSY;
577-
freeskb = 0;
578662
}
579663

580664
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,
588672
arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n",
589673
__FILE__, __LINE__, __func__, lp->hw.status(dev));
590674

591-
spin_unlock_irqrestore(&lp->lock, flags);
592-
if (freeskb)
593-
dev_kfree_skb(skb);
675+
arcnet_led_event(dev, ARCNET_LED_EVENT_TX);
594676

677+
spin_unlock_irqrestore(&lp->lock, flags);
595678
return retval; /* no need to try again */
596679
}
597680
EXPORT_SYMBOL(arcnet_send_packet);
@@ -843,6 +926,13 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
843926

844927
arc_printk(D_RECON, dev, "Network reconfiguration detected (status=%Xh)\n",
845928
status);
929+
if (netif_carrier_ok(dev)) {
930+
netif_carrier_off(dev);
931+
netdev_info(dev, "link down\n");
932+
}
933+
mod_timer(&lp->timer, jiffies + msecs_to_jiffies(1000));
934+
935+
arcnet_led_event(dev, ARCNET_LED_EVENT_RECON);
846936
/* MYRECON bit is at bit 7 of diagstatus */
847937
if (diagstatus & 0x80)
848938
arc_printk(D_RECON, dev, "Put out that recon myself\n");
@@ -893,6 +983,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
893983
lp->num_recons = lp->network_down = 0;
894984

895985
arc_printk(D_DURING, dev, "not recon: clearing counters anyway.\n");
986+
netif_carrier_on(dev);
896987
}
897988

898989
if (didsomething)

0 commit comments

Comments
 (0)