aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMithlesh Thukral <mithlesh@linsyssoft.com>2009-03-20 08:07:32 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-03 17:53:13 -0400
commite5ea8da06ba610551a75c79c1467aae379e953ce (patch)
treec9f6aa8454e3d64f51aecc2eeb1272a3d0115bf3
parent524ca9c196605ff38ae0532aad29ec2e91ad45d6 (diff)
Staging: sxg: Add watchdog timer for managing Link states for SXG driver
Add a watchdog timer to take care of link change notifications. Link changes would now be handled asynchronously as they involve large delays. Signed-off-by: LinSysSoft Sahara Team <saharaproj@linsyssoft.com> Signed-off-by: Mithlesh Thukral <mithlesh@linsyssoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/sxg/sxg.c72
-rw-r--r--drivers/staging/sxg/sxg.h3
2 files changed, 59 insertions, 16 deletions
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c
index c41dea0013b..dbda031d405 100644
--- a/drivers/staging/sxg/sxg.c
+++ b/drivers/staging/sxg/sxg.c
@@ -136,6 +136,9 @@ static int sxg_register_interrupt(struct adapter_t *adapter);
136static void sxg_remove_isr(struct adapter_t *adapter); 136static void sxg_remove_isr(struct adapter_t *adapter);
137static irqreturn_t sxg_isr(int irq, void *dev_id); 137static irqreturn_t sxg_isr(int irq, void *dev_id);
138 138
139static void sxg_watchdog(unsigned long data);
140static void sxg_update_link_status (struct work_struct *work);
141
139#define XXXTODO 0 142#define XXXTODO 0
140 143
141#if XXXTODO 144#if XXXTODO
@@ -1122,6 +1125,12 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
1122 1125
1123 netif_napi_add(netdev, &adapter->napi, 1126 netif_napi_add(netdev, &adapter->napi,
1124 sxg_poll, SXG_NETDEV_WEIGHT); 1127 sxg_poll, SXG_NETDEV_WEIGHT);
1128 netdev->watchdog_timeo = 2 * HZ;
1129 init_timer(&adapter->watchdog_timer);
1130 adapter->watchdog_timer.function = &sxg_watchdog;
1131 adapter->watchdog_timer.data = (unsigned long) adapter;
1132 INIT_WORK(&adapter->update_link_status, sxg_update_link_status);
1133
1125 DBG_ERROR 1134 DBG_ERROR
1126 ("sxg: %s addr 0x%lx, irq %d, MAC addr \ 1135 ("sxg: %s addr 0x%lx, irq %d, MAC addr \
1127 %02X:%02X:%02X:%02X:%02X:%02X\n", 1136 %02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -1441,7 +1450,10 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
1441 } 1450 }
1442 /* Link event */ 1451 /* Link event */
1443 if (Isr & SXG_ISR_LINK) { 1452 if (Isr & SXG_ISR_LINK) {
1444 sxg_link_event(adapter); 1453 if (adapter->state != ADAPT_DOWN) {
1454 adapter->link_status_changed = 1;
1455 schedule_work(&adapter->update_link_status);
1456 }
1445 } 1457 }
1446 /* Debug - breakpoint hit */ 1458 /* Debug - breakpoint hit */
1447 if (Isr & SXG_ISR_BREAK) { 1459 if (Isr & SXG_ISR_BREAK) {
@@ -2260,6 +2272,7 @@ int sxg_second_open(struct net_device * dev)
2260 2272
2261 sxg_register_intr(adapter); 2273 sxg_register_intr(adapter);
2262 spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); 2274 spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
2275 mod_timer(&adapter->watchdog_timer, jiffies);
2263 return (STATUS_SUCCESS); 2276 return (STATUS_SUCCESS);
2264 2277
2265} 2278}
@@ -2312,27 +2325,28 @@ static int sxg_entry_halt(struct net_device *dev)
2312 2325
2313 RssIds = SXG_RSS_CPU_COUNT(adapter); 2326 RssIds = SXG_RSS_CPU_COUNT(adapter);
2314 IsrCount = adapter->msi_enabled ? RssIds : 1; 2327 IsrCount = adapter->msi_enabled ? RssIds : 1;
2315 2328 /* Disable interrupts */
2316 napi_disable(&adapter->napi);
2317 spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); 2329 spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
2318 DBG_ERROR("sxg: %s (%s) ENTER\n", __func__, dev->name); 2330 SXG_DISABLE_ALL_INTERRUPTS(adapter);
2319
2320 WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true);
2321 netif_stop_queue(adapter->netdev);
2322 adapter->state = ADAPT_DOWN; 2331 adapter->state = ADAPT_DOWN;
2323 adapter->linkstate = LINK_DOWN; 2332 adapter->linkstate = LINK_DOWN;
2324 adapter->devflags_prev = 0;
2325 DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
2326 __func__, dev->name, adapter, adapter->state);
2327
2328 /* Disable interrupts */
2329 SXG_DISABLE_ALL_INTERRUPTS(adapter);
2330 2333
2331 spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); 2334 spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
2332
2333 sxg_deregister_interrupt(adapter); 2335 sxg_deregister_interrupt(adapter);
2334 WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH); 2336 WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
2335 mdelay(5000); 2337 mdelay(5000);
2338
2339 del_timer_sync(&adapter->watchdog_timer);
2340 netif_stop_queue(dev);
2341 netif_carrier_off(dev);
2342
2343 napi_disable(&adapter->napi);
2344
2345 WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true);
2346 adapter->devflags_prev = 0;
2347 DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
2348 __func__, dev->name, adapter, adapter->state);
2349
2336 spin_lock(&adapter->RcvQLock); 2350 spin_lock(&adapter->RcvQLock);
2337 /* Free all the blocks and the buffers, moved from remove() routine */ 2351 /* Free all the blocks and the buffers, moved from remove() routine */
2338 if (!(IsListEmpty(&adapter->AllRcvBlocks))) { 2352 if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
@@ -3013,6 +3027,8 @@ static void sxg_link_event(struct adapter_t *adapter)
3013 int status; 3027 int status;
3014 u32 Value; 3028 u32 Value;
3015 3029
3030 if (adapter->state == ADAPT_DOWN)
3031 return;
3016 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt", 3032 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
3017 adapter, 0, 0, 0); 3033 adapter, 0, 0, 0);
3018 DBG_ERROR("ENTER %s\n", __func__); 3034 DBG_ERROR("ENTER %s\n", __func__);
@@ -3053,10 +3069,13 @@ static void sxg_link_event(struct adapter_t *adapter)
3053 sxg_link_state(adapter, LinkState); 3069 sxg_link_state(adapter, LinkState);
3054 DBG_ERROR("SXG: Link Alarm occurred. Link is %s\n", 3070 DBG_ERROR("SXG: Link Alarm occurred. Link is %s\n",
3055 ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN")); 3071 ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN"));
3056 if (LinkState == SXG_LINK_UP) 3072 if (LinkState == SXG_LINK_UP) {
3057 netif_carrier_on(netdev); 3073 netif_carrier_on(netdev);
3058 else 3074 netif_tx_start_all_queues(netdev);
3075 } else {
3076 netif_tx_stop_all_queues(netdev);
3059 netif_carrier_off(netdev); 3077 netif_carrier_off(netdev);
3078 }
3060 } else { 3079 } else {
3061 /* 3080 /*
3062 * XXXTODO - Assuming Link Attention is only being generated 3081 * XXXTODO - Assuming Link Attention is only being generated
@@ -4435,6 +4454,27 @@ static struct net_device_stats *sxg_get_stats(struct net_device * dev)
4435 return (&adapter->stats); 4454 return (&adapter->stats);
4436} 4455}
4437 4456
4457static void sxg_watchdog(unsigned long data)
4458{
4459 struct adapter_t *adapter = (struct adapter_t *) data;
4460
4461 if (adapter->state != ADAPT_DOWN) {
4462 sxg_link_event(adapter);
4463 /* Reset the timer */
4464 mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
4465 }
4466}
4467
4468static void sxg_update_link_status (struct work_struct *work)
4469{
4470 struct adapter_t *adapter = (struct adapter_t *)container_of
4471 (work, struct adapter_t, update_link_status);
4472 if (likely(adapter->link_status_changed)) {
4473 sxg_link_event(adapter);
4474 adapter->link_status_changed = 0;
4475 }
4476}
4477
4438static struct pci_driver sxg_driver = { 4478static struct pci_driver sxg_driver = {
4439 .name = sxg_driver_name, 4479 .name = sxg_driver_name,
4440 .id_table = sxg_pci_tbl, 4480 .id_table = sxg_pci_tbl,
diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h
index 899cf1510f9..f07aa708d86 100644
--- a/drivers/staging/sxg/sxg.h
+++ b/drivers/staging/sxg/sxg.h
@@ -715,6 +715,9 @@ struct adapter_t {
715 /*MSI-X related data elements*/ 715 /*MSI-X related data elements*/
716 u32 nr_msix_entries; 716 u32 nr_msix_entries;
717 struct msix_entry *msi_entries; 717 struct msix_entry *msi_entries;
718 struct timer_list watchdog_timer;
719 struct work_struct update_link_status;
720 u32 link_status_changed;
718}; 721};
719 722
720#if SLIC_DUMP_ENABLED 723#if SLIC_DUMP_ENABLED