Beispiel #1
0
static void handle_sqn_state_change_msg(struct sqn_private *priv
	, struct sqn_lsp_packet *lsp)
{
	struct sqn_sdio_card *card = priv->card;
	struct sk_buff *skb_reply = 0;
	unsigned long irq_flags = 0;
	const int card_state = ntohl(lsp->lsp_header.u.fw_state.state);

	sqn_pr_enter();

	switch (card_state) {
	case LSP_SQN_ACTIVE:
		sqn_pr_info("card switched to ACTIVE state (OPT)\n");
		spin_lock_irqsave(&priv->drv_lock, irq_flags);
		card->is_card_sleeps = 0;
		spin_unlock_irqrestore(&priv->drv_lock, irq_flags);
		break;
	case LSP_SQN_IDLE:
		sqn_pr_info("card switched to IDLE state (LPM)\n");
		spin_lock_irqsave(&priv->drv_lock, irq_flags);
		card->is_card_sleeps = 1;
		spin_unlock_irqrestore(&priv->drv_lock, irq_flags);
		break;
	case LSP_SQN_DROPPED:
		sqn_pr_info("card switched to DROPPED state (LPM)\n");
		spin_lock_irqsave(&priv->drv_lock, irq_flags);
		card->is_card_sleeps = 1;
		spin_unlock_irqrestore(&priv->drv_lock, irq_flags);
		break;
	case LSP_SQN_REENTRY:
		sqn_pr_info("card switched to REENTRY state (LPM)\n");
		spin_lock_irqsave(&priv->drv_lock, irq_flags);
		card->is_card_sleeps = 1;
		spin_unlock_irqrestore(&priv->drv_lock, irq_flags);
		break;
	default:
		sqn_pr_info("card switched to UNSUPPORTED mode %d/0x%x\n"
			, card_state, card_state);
		spin_lock_irqsave(&priv->drv_lock, irq_flags);
		card->is_card_sleeps = 0;
		spin_unlock_irqrestore(&priv->drv_lock, irq_flags);
		break;
	}
	skb_reply = construct_lsp_packet(THSP_SQN_STATE_CHANGE_REPLY
			, ntohl(lsp->lsp_header.u.thp_avl.tid), 0);
	if (0 != (skb_reply = sqn_sdio_prepare_skb_for_tx(skb_reply)))
		sqn_sdio_tx_skb(card, skb_reply, 0);
	wake_up_interruptible(&g_card_sleep_waitq);

	sqn_pr_leave();
}
Beispiel #2
0
static void handle_thp_avl_msg(struct sqn_private *priv
	, struct sqn_lsp_packet *lsp)
{
	struct sqn_sdio_card *card = priv->card;
	struct sk_buff *skb_reply = 0;
	enum sqn_thp_available_reply thp_rpl; 
	unsigned long irq_flags = 0;

	sqn_pr_enter();

	spin_lock_irqsave(&priv->drv_lock, irq_flags);
	/* if (card->is_card_sleeps) { */
	if (priv->is_tx_queue_empty(priv)) {
		if (mmc_wimax_get_sdio_lsp_log()) {
			sqn_pr_info("TX queue empty, thp_rpl=FINISH\n");
		}
		/* sqn_pr_dbg("card was asleep, thp_rpl=FINISH\n"); */
		thp_rpl = LSP_THPA_FINISHED;
		card->is_card_sleeps = 1;
		gHostWakeupFWEvent = 0;
	/* } else if (priv->is_tx_queue_empty(priv)) { */
		/* sqn_pr_dbg("card was not asleep and tx_queue is empty, thp_rpl=FINISHED\n"); */
		/* thp_rpl = LSP_THPA_FINISHED; */
		/* card->is_card_sleeps = 1; */
	} else {
		/* sqn_pr_info("card was not asleep but tx_queue is no empty, thp_rpl=EXIT\n"); */
		if (mmc_wimax_get_sdio_lsp_log()) {
			sqn_pr_info("TX queue not empty, thp_rpl=ACK\n");
		}
		/* sqn_pr_dbg("card was not asleep, thp_rpl=ACK\n"); */
		thp_rpl = LSP_THPA_ACK;
		card->is_card_sleeps = 0;
	}
	spin_unlock_irqrestore(&priv->drv_lock, irq_flags);
	skb_reply = construct_lsp_packet(THSP_THP_AVAILABLE_REPLY
			, ntohl(lsp->lsp_header.u.thp_avl.tid)
			, thp_rpl);
	if (0 != (skb_reply = sqn_sdio_prepare_skb_for_tx(skb_reply)))
		sqn_sdio_tx_skb(card, skb_reply, 0);
	wake_up_interruptible(&g_card_sleep_waitq);
	if (netif_queue_stopped(priv->dev))
		netif_wake_queue(priv->dev);

	if (!card->is_card_sleeps && !gHostWakeupFWEvent) {
		gHostWakeupFWEvent = 1; // Dump next TX packet after LSP ThpAvailableReply(ACK);
	}

	sqn_pr_leave();
}