From 99775409e957ddca7c78ce8c2abf336d3d468719 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Wed, 20 Jun 2007 23:56:56 -0400 Subject: [PATCH] Convert management timer/work to a delayed work This is likely not the final approch, as the code handles several different timeouts and may need to be split. Anyway, it would be easier to split a single delayed work than a timer and a work. When handling beacons, cancel the work first, as we want the timeout handler to be deferred. The delayed workqueue API doesn't seem to provide a nicer way to do it. Signed-off-by: Pavel Roskin --- at76_usb.c | 65 ++++++++++++++++++++++++++++---------------------------------- at76_usb.h | 3 +-- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/at76_usb.c b/at76_usb.c index 16b82c8..4bb671a 100644 --- a/at76_usb.c +++ b/at76_usb.c @@ -1989,13 +1989,6 @@ static void at76_dump_bss_table(struct at76_priv *priv) spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); } -/* We got a timeout for a infrastructure mgmt packet */ -static void at76_mgmt_timeout(unsigned long par) -{ - struct at76_priv *priv = (struct at76_priv *)par; - schedule_work(&priv->work_mgmt_timeout); -} - /* Expiry of management timer in istate SCANNING */ static void at76_handle_mgmt_timeout_scan(struct at76_priv *priv) { @@ -2027,7 +2020,7 @@ static void at76_handle_mgmt_timeout_scan(struct at76_priv *priv) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); - mod_timer(&priv->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + schedule_delayed_work(&priv->dwork_mgmt, SCAN_POLL_INTERVAL); return; } @@ -2056,7 +2049,7 @@ static void at76_handle_mgmt_timeout_scan(struct at76_priv *priv) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); - mod_timer(&priv->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + schedule_delayed_work(&priv->dwork_mgmt, SCAN_POLL_INTERVAL); break; case 2: @@ -2068,7 +2061,7 @@ static void at76_handle_mgmt_timeout_scan(struct at76_priv *priv) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); - mod_timer(&priv->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + schedule_delayed_work(&priv->dwork_mgmt, SCAN_POLL_INTERVAL); break; case 3: @@ -2180,7 +2173,7 @@ static void at76_delete_device(struct at76_priv *priv) at76_free_bss_list(priv); del_timer_sync(&priv->bss_list_timer); - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); if (priv->istate == CONNECTED) { at76_iwevent_bss_disconnect(priv->netdev); @@ -2328,7 +2321,7 @@ static int at76_iw_handler_commit(struct net_device *netdev, if (priv->istate != INIT) { priv->istate = INIT; /* stop pending management stuff */ - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); spin_lock_irqsave(&priv->mgmt_spinlock, flags); if (priv->next_mgmt_bulk) { @@ -2690,7 +2683,7 @@ static int at76_iw_handler_set_scan(struct net_device *netdev, priv->scan_state = SCAN_IN_PROGRESS; /* stop pending management stuff */ - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); spin_lock_irqsave(&priv->mgmt_spinlock, flags); if (priv->next_mgmt_bulk) { @@ -3922,7 +3915,7 @@ static int at76_stop(struct net_device *netdev) usb_kill_urb(priv->read_urb); } - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); cancel_delayed_work(&priv->dwork_restart); spin_lock_irqsave(&priv->mgmt_spinlock, flags); @@ -4335,7 +4328,7 @@ static void at76_work_join(struct work_struct *work) netif_carrier_on(priv->netdev); netif_start_queue(priv->netdev); /* just to be sure */ - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); } else { /* send auth req */ priv->istate = AUTHENTICATING; @@ -4343,7 +4336,7 @@ static void at76_work_join(struct work_struct *work) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); } goto end_join; } @@ -4366,7 +4359,7 @@ static void at76_work_join(struct work_struct *work) static void at76_work_mgmt_timeout(struct work_struct *work) { struct at76_priv *priv = container_of(work, struct at76_priv, - work_mgmt_timeout); + dwork_mgmt.work); mutex_lock(&priv->mtx); @@ -4407,7 +4400,7 @@ static void at76_work_mgmt_timeout(struct work_struct *work) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); } else { /* try to get next matching BSS */ priv->istate = JOINING; @@ -4421,7 +4414,7 @@ static void at76_work_mgmt_timeout(struct work_struct *work) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); } else { /* jal: TODO: we may be authenticated to several BSS and may try to associate to the next of them here @@ -4445,7 +4438,7 @@ static void at76_work_mgmt_timeout(struct work_struct *work) } at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); break; case DISASSOCIATING: @@ -4454,7 +4447,7 @@ static void at76_work_mgmt_timeout(struct work_struct *work) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); } else { /* we scan again ... */ priv->istate = SCANNING; @@ -4680,7 +4673,7 @@ static void at76_work_scan(struct work_struct *work) at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); - mod_timer(&priv->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + schedule_delayed_work(&priv->dwork_mgmt, SCAN_POLL_INTERVAL); } mutex_unlock(&priv->mtx); @@ -4751,7 +4744,7 @@ static void at76_rx_mgmt_assoc(struct at76_priv *priv, priv->istate = JOINING; schedule_work(&priv->work_join); } - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); } else { printk(KERN_INFO "%s: AssocResp in state %d ignored\n", priv->netdev->name, priv->istate); @@ -4800,7 +4793,7 @@ static void at76_rx_mgmt_reassoc(struct at76_priv *priv, priv->netdev->name, mac2str(priv->bssid)); schedule_work(&priv->work_assoc_done); } else { - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); priv->istate = JOINING; schedule_work(&priv->work_join); } @@ -4848,7 +4841,7 @@ static void at76_rx_mgmt_disassoc(struct at76_priv *priv, netif_stop_queue(priv->netdev); at76_iwevent_bss_disconnect(priv->netdev); } - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); priv->istate = JOINING; schedule_work(&priv->work_join); } else { @@ -4898,7 +4891,7 @@ static void at76_rx_mgmt_auth(struct at76_priv *priv, /* this is a AuthFrame from the BSS we are connected or trying to connect to, directed to us */ if (status != WLAN_STATUS_SUCCESS) { - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); /* try to join next bss */ priv->istate = JOINING; schedule_work(&priv->work_join); @@ -4912,7 +4905,7 @@ static void at76_rx_mgmt_auth(struct at76_priv *priv, at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); return; } @@ -4921,7 +4914,7 @@ static void at76_rx_mgmt_auth(struct at76_priv *priv, resp->info_element); at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __FUNCTION__, __LINE__); - mod_timer(&priv->mgmt_timer, jiffies + HZ); + schedule_delayed_work(&priv->dwork_mgmt, HZ); } /* else: ignore AuthFrames to other recipients */ } @@ -4955,7 +4948,7 @@ static void at76_rx_mgmt_deauth(struct at76_priv *priv, } priv->istate = JOINING; schedule_work(&priv->work_join); - del_timer_sync(&priv->mgmt_timer); + cancel_delayed_work(&priv->dwork_mgmt); } /* ignore DeAuth to other STA or from other BSSID */ } else { @@ -4996,8 +4989,12 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv, if (priv->curr_bss == NULL) goto rx_mgmt_beacon_end; if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) { - mod_timer(&priv->mgmt_timer, - jiffies + BEACON_TIMEOUT * HZ); + /* We got our AP's beacon, defer the timeout handler. + Kill pending work first, as schedule_delayed_work() + won't do it. */ + cancel_delayed_work(&priv->dwork_mgmt); + schedule_delayed_work(&priv->dwork_mgmt, + jiffies + BEACON_TIMEOUT * HZ); priv->curr_bss->rssi = buf->rssi; priv->beacons_received++; goto rx_mgmt_beacon_end; @@ -5844,19 +5841,15 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev) mutex_init(&priv->mtx); INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done); INIT_WORK(&priv->work_join, at76_work_join); - INIT_WORK(&priv->work_mgmt_timeout, at76_work_mgmt_timeout); INIT_WORK(&priv->work_new_bss, at76_work_new_bss); INIT_WORK(&priv->work_scan, at76_work_scan); INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); INIT_DELAYED_WORK(&priv->dwork_restart, at76_work_restart); + INIT_DELAYED_WORK(&priv->dwork_mgmt, at76_work_mgmt_timeout); priv->open_count = 0; - init_timer(&priv->mgmt_timer); - priv->mgmt_timer.data = (unsigned long)priv; - priv->mgmt_timer.function = at76_mgmt_timeout; - spin_lock_init(&priv->mgmt_spinlock); priv->next_mgmt_bulk = NULL; priv->istate = INIT; diff --git a/at76_usb.h b/at76_usb.h index 691b837..111a5ee 100644 --- a/at76_usb.h +++ b/at76_usb.h @@ -468,12 +468,12 @@ struct at76_priv { /* work queues */ struct work_struct work_assoc_done; struct work_struct work_join; - struct work_struct work_mgmt_timeout; struct work_struct work_new_bss; struct work_struct work_scan; struct work_struct work_set_promisc; struct work_struct work_submit_rx; struct delayed_work dwork_restart; + struct delayed_work dwork_mgmt; int nr_submit_rx_tries; /* number of tries to submit an rx urb left */ struct tasklet_struct rx_tasklet; @@ -540,7 +540,6 @@ struct at76_priv { } scan_state; time_t last_scan; - struct timer_list mgmt_timer; /* the timer we use to repeat auth_req etc. */ int retries; /* counts backwards while re-trying to send auth/assoc_req's */ u8 pm_mode; /* power management mode: AT76_PM_{OFF, ON, SMART} */ u32 pm_period; /* power manag. period in us */ -- cgit v1.2.3