/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *
 * File: int.c
 *
 * Purpose: Handle USB interrupt endpoint
 *
 * Author: Jerry Chen
 *
 * Date: Apr. 2, 2004
 *
 * Functions:
 *
 * Revision History:
 *      04-02-2004 Jerry Chen:  Initial release
 *
 */

#include "int.h"
#include "tmacro.h"
#include "mac.h"
#include "power.h"
#include "bssdb.h"
#include "usbpipe.h"

static int msglevel = MSG_LEVEL_INFO; /* MSG_LEVEL_DEBUG */

/*+
 *
 *  Function:   InterruptPollingThread
 *
 *  Synopsis:   Thread running at IRQL PASSIVE_LEVEL.
 *
 *  Arguments: Device Extension
 *
 *  Returns:
 *
 *  Algorithm:  Call USBD for input data;
 *
 *  History:    dd-mm-yyyy   Author    Comment
 *
 *
 *  Notes:
 *
 *  USB reads are by nature 'Blocking', and when in a read, the device looks
 *  like it's in a 'stall' condition, so we deliberately time out every second
 *  if we've gotten no data
 *
-*/
void INTvWorkItem(struct vnt_private *pDevice)
{
	int ntStatus;

	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");

	spin_lock_irq(&pDevice->lock);

	ntStatus = PIPEnsInterruptRead(pDevice);

	spin_unlock_irq(&pDevice->lock);
}

void INTnsProcessData(struct vnt_private *priv)
{
	struct vnt_interrupt_data *int_data;
	struct vnt_manager *mgmt = &priv->vnt_mgmt;
	struct net_device_stats *stats = &priv->stats;

	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");

	int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf;

	if (int_data->tsr0 & TSR_VALID) {
		if (int_data->tsr0 & (TSR_TMO | TSR_RETRYTMO))
			priv->wstats.discard.retries++;
		else
			stats->tx_packets++;

		BSSvUpdateNodeTxCounter(priv,
					int_data->tsr0,
					int_data->pkt0);
	}

	if (int_data->tsr1 & TSR_VALID) {
		if (int_data->tsr1 & (TSR_TMO | TSR_RETRYTMO))
			priv->wstats.discard.retries++;
		else
			stats->tx_packets++;


		BSSvUpdateNodeTxCounter(priv,
					int_data->tsr1,
					int_data->pkt1);
	}

	if (int_data->tsr2 & TSR_VALID) {
		if (int_data->tsr2 & (TSR_TMO | TSR_RETRYTMO))
			priv->wstats.discard.retries++;
		else
			stats->tx_packets++;

		BSSvUpdateNodeTxCounter(priv,
					int_data->tsr2,
					int_data->pkt2);
	}

	if (int_data->tsr3 & TSR_VALID) {
		if (int_data->tsr3 & (TSR_TMO | TSR_RETRYTMO))
			priv->wstats.discard.retries++;
		else
			stats->tx_packets++;

		BSSvUpdateNodeTxCounter(priv,
					int_data->tsr3,
					int_data->pkt3);
	}

	if (int_data->isr0 != 0) {
		if (int_data->isr0 & ISR_BNTX) {
			if (priv->op_mode == NL80211_IFTYPE_AP) {
				if (mgmt->byDTIMCount > 0) {
					mgmt->byDTIMCount--;
					mgmt->sNodeDBTable[0].bRxPSPoll =
						false;
				} else if (mgmt->byDTIMCount == 0) {
					/* check if multicast tx buffering */
					mgmt->byDTIMCount =
						mgmt->byDTIMPeriod-1;
					mgmt->sNodeDBTable[0].bRxPSPoll = true;
					if (mgmt->sNodeDBTable[0].bPSEnable)
						bScheduleCommand((void *) priv,
								 WLAN_CMD_RX_PSPOLL,
								 NULL);
				}
				bScheduleCommand((void *) priv,
						WLAN_CMD_BECON_SEND,
						NULL);
			}
			priv->bBeaconSent = true;
		} else {
			priv->bBeaconSent = false;
		}

		if (int_data->isr0 & ISR_TBTT) {
			if (priv->bEnablePSMode)
				bScheduleCommand((void *) priv,
						WLAN_CMD_TBTT_WAKEUP,
						NULL);
			if (priv->bChannelSwitch) {
				priv->byChannelSwitchCount--;
				if (priv->byChannelSwitchCount == 0)
					bScheduleCommand((void *) priv,
							WLAN_CMD_11H_CHSW,
							NULL);
			}
		}
		priv->qwCurrTSF = le64_to_cpu(int_data->tsf);
	}

	if (int_data->isr1 != 0)
		if (int_data->isr1 & ISR_GPIO3)
			bScheduleCommand((void *) priv,
					WLAN_CMD_RADIO,
					NULL);

	priv->int_buf.in_use = false;

	stats->tx_errors = priv->wstats.discard.retries;
	stats->tx_dropped = priv->wstats.discard.retries;
}
