/*
 *  Copyright (c) 1996-2002 Winbond Electronic Corporation
 *
 *  Module Name:
 *    Wb35Tx.c
 *
 *  Abstract:
 *    Processing the Tx message and put into down layer
 *
 */
#include <linux/usb.h>
#include <linux/gfp.h>

#include "wb35tx_f.h"
#include "mds_f.h"

unsigned char
Wb35Tx_get_tx_buffer(struct hw_data *pHwData, u8 **pBuffer)
{
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;

	*pBuffer = pWb35Tx->TxBuffer[0];
	return true;
}

static void Wb35Tx(struct wbsoft_priv *adapter);

static void Wb35Tx_complete(struct urb *pUrb)
{
	struct wbsoft_priv *adapter = pUrb->context;
	struct hw_data *pHwData = &adapter->sHwData;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
	struct wb35_mds *pMds = &adapter->Mds;

	printk("wb35: tx complete\n");
	/* Variable setting */
	pWb35Tx->EP4vm_state = VM_COMPLETED;
	pWb35Tx->EP4VM_status = pUrb->status; /* Store the last result of Irp */
	/* Set the owner. Free the owner bit always. */
	pMds->TxOwner[pWb35Tx->TxSendIndex] = 0;
	pWb35Tx->TxSendIndex++;
	pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER;

	if (pHwData->SurpriseRemove) /* Let WbWlanHalt handle surprise remove */
		goto error;

	if (pWb35Tx->tx_halt)
		goto error;

	/* The URB is completed, check the result */
	if (pWb35Tx->EP4VM_status != 0) {
		printk("URB submission failed\n");
		pWb35Tx->EP4vm_state = VM_STOP;
		goto error;
	}

	Mds_Tx(adapter);
	Wb35Tx(adapter);
	return;

error:
	atomic_dec(&pWb35Tx->TxFireCounter);
	pWb35Tx->EP4vm_state = VM_STOP;
}

static void Wb35Tx(struct wbsoft_priv *adapter)
{
	struct hw_data *pHwData = &adapter->sHwData;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
	u8		*pTxBufferAddress;
	struct wb35_mds *pMds = &adapter->Mds;
	struct urb *pUrb = (struct urb *)pWb35Tx->Tx4Urb;
	int		retv;
	u32		SendIndex;

	if (pHwData->SurpriseRemove)
		goto cleanup;

	if (pWb35Tx->tx_halt)
		goto cleanup;

	/* Ownership checking */
	SendIndex = pWb35Tx->TxSendIndex;
	/* No more data need to be sent, return immediately */
	if (!pMds->TxOwner[SendIndex])
		goto cleanup;

	pTxBufferAddress = pWb35Tx->TxBuffer[SendIndex];

	/* Issuing URB */
	usb_fill_bulk_urb(pUrb, pHwData->udev,
			  usb_sndbulkpipe(pHwData->udev, 4),
			  pTxBufferAddress, pMds->TxBufferSize[SendIndex],
			  Wb35Tx_complete, adapter);

	pWb35Tx->EP4vm_state = VM_RUNNING;
	retv = usb_submit_urb(pUrb, GFP_ATOMIC);
	if (retv < 0) {
		printk("EP4 Tx Irp sending error\n");
		goto cleanup;
	}

	/* Check if driver needs issue Irp for EP2 */
	pWb35Tx->TxFillCount += pMds->TxCountInBuffer[SendIndex];
	if (pWb35Tx->TxFillCount > 12)
		Wb35Tx_EP2VM_start(adapter);

	pWb35Tx->ByteTransfer += pMds->TxBufferSize[SendIndex];
	return;

 cleanup:
	pWb35Tx->EP4vm_state = VM_STOP;
	atomic_dec(&pWb35Tx->TxFireCounter);
}

void Wb35Tx_start(struct wbsoft_priv *adapter)
{
	struct hw_data *pHwData = &adapter->sHwData;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;

	/* Allow only one thread to run into function */
	if (atomic_inc_return(&pWb35Tx->TxFireCounter) == 1) {
		pWb35Tx->EP4vm_state = VM_RUNNING;
		Wb35Tx(adapter);
	} else
		atomic_dec(&pWb35Tx->TxFireCounter);
}

unsigned char Wb35Tx_initial(struct hw_data *pHwData)
{
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;

	pWb35Tx->Tx4Urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!pWb35Tx->Tx4Urb)
		return false;

	pWb35Tx->Tx2Urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!pWb35Tx->Tx2Urb) {
		usb_free_urb(pWb35Tx->Tx4Urb);
		return false;
	}

	return true;
}

void Wb35Tx_stop(struct hw_data *pHwData)
{
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;

	/* Try to cancel the Trp of EP2 */
	if (pWb35Tx->EP2vm_state == VM_RUNNING)
		/* Only use unlink, let Wb35Tx_destroy free them */
		usb_unlink_urb(pWb35Tx->Tx2Urb);
	pr_debug("EP2 Tx stop\n");

	/* Try to cancel the Irp of EP4 */
	if (pWb35Tx->EP4vm_state == VM_RUNNING)
		/* Only use unlink, let Wb35Tx_destroy free them */
		usb_unlink_urb(pWb35Tx->Tx4Urb);
	pr_debug("EP4 Tx stop\n");
}

void Wb35Tx_destroy(struct hw_data *pHwData)
{
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;

	/* Wait for VM stop */
	do {
		msleep(10); /* Delay for waiting function enter 940623.1.a */
	} while ((pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP));
	msleep(10); /* Delay for waiting function enter 940623.1.b */

	usb_free_urb(pWb35Tx->Tx4Urb);
	usb_free_urb(pWb35Tx->Tx2Urb);

	pr_debug("Wb35Tx_destroy OK\n");
}

void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount)
{
	struct hw_data *pHwData = &adapter->sHwData;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
	bool Trigger = false;

	if (pWb35Tx->TxTimer > TimeCount)
		Trigger = true;
	else if (TimeCount > (pWb35Tx->TxTimer+500))
		Trigger = true;

	if (Trigger) {
		pWb35Tx->TxTimer = TimeCount;
		Wb35Tx_EP2VM_start(adapter);
	}
}

static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter);

static void Wb35Tx_EP2VM_complete(struct urb *pUrb)
{
	struct wbsoft_priv *adapter = pUrb->context;
	struct hw_data *pHwData = &adapter->sHwData;
	struct T02_descriptor	T02, TSTATUS;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
	u32 *pltmp = (u32 *)pWb35Tx->EP2_buf;
	u32		i;
	u16		InterruptInLength;

	/* Variable setting */
	pWb35Tx->EP2vm_state = VM_COMPLETED;
	pWb35Tx->EP2VM_status = pUrb->status;

	/* For Linux 2.4. Interrupt will always trigger */
	if (pHwData->SurpriseRemove) /* Let WbWlanHalt handle surprise remove */
		goto error;

	if (pWb35Tx->tx_halt)
		goto error;

	/* The Urb is completed, check the result */
	if (pWb35Tx->EP2VM_status != 0) {
		printk("EP2 IoCompleteRoutine return error\n");
		pWb35Tx->EP2vm_state = VM_STOP;
		goto error;
	}

	/* Update the Tx result */
	InterruptInLength = pUrb->actual_length;
	/* Modify for minimum memory access and DWORD alignment. */
	T02.value = cpu_to_le32(pltmp[0]) >> 8; /* [31:8] -> [24:0] */
	InterruptInLength -= 1; /* 20051221.1.c Modify the follow for more stable */
	InterruptInLength >>= 2; /* InterruptInLength/4 */
	for (i = 1; i <= InterruptInLength; i++) {
		T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24);

		TSTATUS.value = T02.value;  /* 20061009 anson's endian */
		Mds_SendComplete(adapter, &TSTATUS);
		T02.value = cpu_to_le32(pltmp[i]) >> 8;
	}

	return;
error:
	atomic_dec(&pWb35Tx->TxResultCount);
	pWb35Tx->EP2vm_state = VM_STOP;
}

static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
{
	struct hw_data *pHwData = &adapter->sHwData;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
	struct urb *pUrb = (struct urb *)pWb35Tx->Tx2Urb;
	u32 *pltmp = (u32 *)pWb35Tx->EP2_buf;
	int		retv;

	if (pHwData->SurpriseRemove)
		goto error;

	if (pWb35Tx->tx_halt)
		goto error;

	/* Issuing URB */
	usb_fill_int_urb(pUrb, pHwData->udev, usb_rcvintpipe(pHwData->udev, 2),
			 pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete,
			 adapter, 32);

	pWb35Tx->EP2vm_state = VM_RUNNING;
	retv = usb_submit_urb(pUrb, GFP_ATOMIC);

	if (retv < 0) {
		pr_debug("EP2 Tx Irp sending error\n");
		goto error;
	}

	return;
error:
	pWb35Tx->EP2vm_state = VM_STOP;
	atomic_dec(&pWb35Tx->TxResultCount);
}

void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter)
{
	struct hw_data *pHwData = &adapter->sHwData;
	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;

	/* Allow only one thread to run into function */
	if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) {
		pWb35Tx->EP2vm_state = VM_RUNNING;
		Wb35Tx_EP2VM(adapter);
	} else
		atomic_dec(&pWb35Tx->TxResultCount);
}
