Exemple #1
0
int lbs_stop_iface(struct lbs_private *priv)
{
	unsigned long flags;
	int ret = 0;

	lbs_deb_enter(LBS_DEB_MAIN);

	spin_lock_irqsave(&priv->driver_lock, flags);
	priv->iface_running = false;
	kfree_skb(priv->currenttxskb);
	priv->currenttxskb = NULL;
	priv->tx_pending_len = 0;
	spin_unlock_irqrestore(&priv->driver_lock, flags);

	cancel_work_sync(&priv->mcast_work);
	del_timer_sync(&priv->tx_lockup_timer);

	/* Disable command processing, and wait for all commands to complete */
	lbs_deb_main("waiting for commands to complete\n");
	wait_event(priv->waitq, lbs_command_queue_empty(priv));
	lbs_deb_main("all commands completed\n");

	if (priv->power_save)
		ret = priv->power_save(priv);

	lbs_deb_leave(LBS_DEB_MAIN);
	return ret;
}
Exemple #2
0
/**
 * auto_deepsleep_timer_fn - put the device back to deep sleep mode when
 * timer expires and no activity (command, event, data etc.) is detected.
 * @data:	&struct lbs_private pointer
 * returns:	N/A
 */
static void auto_deepsleep_timer_fn(unsigned long data)
{
	struct lbs_private *priv = (struct lbs_private *)data;

	lbs_deb_enter(LBS_DEB_CMD);

	if (priv->is_activity_detected) {
		priv->is_activity_detected = 0;
	} else {
		if (priv->is_auto_deep_sleep_enabled &&
		    (!priv->wakeup_dev_required) &&
		    (priv->connect_status != LBS_CONNECTED)) {
			struct cmd_header cmd;

			lbs_deb_main("Entering auto deep sleep mode...\n");
			memset(&cmd, 0, sizeof(cmd));
			cmd.size = cpu_to_le16(sizeof(cmd));
			lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd,
					sizeof(cmd));
		}
	}
	mod_timer(&priv->auto_deepsleep_timer , jiffies +
				(priv->auto_deep_sleep_timeout * HZ)/1000);
	lbs_deb_leave(LBS_DEB_CMD);
}
Exemple #3
0
void lbs_remove_card(struct lbs_private *priv)
{
	struct net_device *dev = priv->dev;

	lbs_remove_mesh(priv);

	if (priv->wiphy_registered)
		lbs_scan_deinit(priv);

	lbs_wait_for_firmware_load(priv);

	/* worker thread destruction blocks on the in-flight command which
	 * should have been cleared already in lbs_stop_card().
	 */
	lbs_deb_main("destroying worker thread\n");
	destroy_workqueue(priv->work_thread);
	lbs_deb_main("done destroying worker thread\n");

	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
		priv->psmode = LBS802_11POWERMODECAM;
		/* no need to wakeup if already woken up,
		 * on suspend, this exit ps command is not processed
		 * the driver hangs
		 */
		if (priv->psstate != PS_STATE_FULL_POWER)
			lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true);
	}

	if (priv->is_deep_sleep) {
		priv->is_deep_sleep = 0;
		wake_up_interruptible(&priv->ds_awake_q);
	}

	priv->is_host_sleep_configured = 0;
	priv->is_host_sleep_activated = 0;
	wake_up_interruptible(&priv->host_sleep_q);

	/* Stop the thread servicing the interrupts */
	priv->surpriseremoved = 1;
	kthread_stop(priv->main_thread);

	lbs_free_adapter(priv);
	lbs_cfg_free(priv);
	free_netdev(dev);
}
Exemple #4
0
void lbs_remove_card(struct lbs_private *priv)
{
	struct net_device *dev = priv->dev;

	lbs_deb_enter(LBS_DEB_MAIN);

	lbs_remove_mesh(priv);
	lbs_scan_deinit(priv);

	/* worker thread destruction blocks on the in-flight command which
	 * should have been cleared already in lbs_stop_card().
	 */
	lbs_deb_main("destroying worker thread\n");
	destroy_workqueue(priv->work_thread);
	lbs_deb_main("done destroying worker thread\n");

	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
		priv->psmode = LBS802_11POWERMODECAM;
		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true);
	}

	if (priv->is_deep_sleep) {
		priv->is_deep_sleep = 0;
		wake_up_interruptible(&priv->ds_awake_q);
	}

	priv->is_host_sleep_configured = 0;
	priv->is_host_sleep_activated = 0;
	wake_up_interruptible(&priv->host_sleep_q);

	/* Stop the thread servicing the interrupts */
	priv->surpriseremoved = 1;
	kthread_stop(priv->main_thread);

	lbs_free_adapter(priv);
	lbs_cfg_free(priv);
	free_netdev(dev);

	lbs_deb_leave(LBS_DEB_MAIN);
}