/**
 * @file Transmit.c
 * @defgroup tx_functions Transmission
 * @section Queueing
 * @dot
 * digraph transmit1 {
 * node[shape=box]
 * edge[weight=5;color=red]
 *
 * bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
 * GetPacketQueueIndex->IpVersion4[label="IPV4"]
 * GetPacketQueueIndex->IpVersion6[label="IPV6"]
 * }
 *
 * @enddot
 *
 * @section De-Queueing
 * @dot
 * digraph transmit2 {
 * node[shape=box]
 * edge[weight=5;color=red]
 * interrupt_service_thread->transmit_packets
 * tx_pkt_hdler->transmit_packets
 * transmit_packets->CheckAndSendPacketFromIndex
 * transmit_packets->UpdateTokenCount
 * CheckAndSendPacketFromIndex->PruneQueue
 * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
 * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
 * SendControlPacket->bcm_cmd53
 * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
 * SendPacketFromQueue->SetupNextSend->bcm_cmd53
 * }
 * @enddot
 */

#include "headers.h"

/**
 * @ingroup ctrl_pkt_functions
 * This function dispatches control packet to the h/w interface
 * @return zero(success) or -ve value(failure)
 */
int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket)
{
	struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
	if (!pControlPacket || !Adapter) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL,
				"Got NULL Control Packet or Adapter");
		return STATUS_FAILURE;
	}
	if ((atomic_read(&Adapter->CurrNumFreeTxDesc) <
			((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))	{
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL,
				"NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
		return STATUS_FAILURE;
	}

	/* Update the netdevice statistics */
	/* Dump Packet  */
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x", PLeader->Vcid);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x", PLeader->PLength);
	if (Adapter->device_removed)
		return 0;

	if (netif_msg_pktdata(Adapter))
		print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,
			16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);

	Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
				pControlPacket, (PLeader->PLength + LEADER_SIZE));

	atomic_dec(&Adapter->CurrNumFreeTxDesc);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
	return STATUS_SUCCESS;
}

/**
 * @ingroup tx_functions
 * This function despatches the IP packets with the given vcid
 * to the target via the host h/w interface.
 * @return  zero(success) or -ve value(failure)
 */
int SetupNextSend(struct bcm_mini_adapter *Adapter,  struct sk_buff *Packet, USHORT Vcid)
{
	int	status = 0;
	bool	bHeaderSupressionEnabled = false;
	B_UINT16 uiClassifierRuleID;
	u16	QueueIndex = skb_get_queue_mapping(Packet);
	struct bcm_leader Leader = {0};

	if (Packet->len > MAX_DEVICE_DESC_SIZE) {
		status = STATUS_FAILURE;
		goto errExit;
	}

	/* Get the Classifier Rule ID */
	uiClassifierRuleID = *((UINT32 *) (Packet->cb) + SKB_CB_CLASSIFICATION_OFFSET);

	bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
		& Adapter->bPHSEnabled;

	if (Adapter->device_removed) {
		status = STATUS_FAILURE;
		goto errExit;
	}

	status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
			(UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);

	if (status != STATUS_SUCCESS) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
				"PHS Transmit failed..\n");
		goto errExit;
	}

	Leader.Vcid = Vcid;

	if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET))
		Leader.Status = LEADER_STATUS_TCP_ACK;
	else
		Leader.Status = LEADER_STATUS;

	if (Adapter->PackInfo[QueueIndex].bEthCSSupport) {
		Leader.PLength = Packet->len;
		if (skb_headroom(Packet) < LEADER_SIZE) {
			status = skb_cow(Packet, LEADER_SIZE);
			if (status) {
				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n");
				goto errExit;
			}
		}
		skb_push(Packet, LEADER_SIZE);
		memcpy(Packet->data, &Leader, LEADER_SIZE);
	} else {
		Leader.PLength = Packet->len - ETH_HLEN;
		memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
	}

	status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
					Packet->data, (Leader.PLength + LEADER_SIZE));
	if (status) {
		++Adapter->dev->stats.tx_errors;
		if (netif_msg_tx_err(Adapter))
			pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
				status);
	} else {
		struct net_device_stats *netstats = &Adapter->dev->stats;
		Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;

		netstats->tx_bytes += Leader.PLength;
		++netstats->tx_packets;

		Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
		Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
		Adapter->PackInfo[QueueIndex].uiSentPackets++;
		Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;

		atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
		Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
	}

	atomic_dec(&Adapter->CurrNumFreeTxDesc);

errExit:
	dev_kfree_skb(Packet);
	return status;
}

static int tx_pending(struct bcm_mini_adapter *Adapter)
{
	return (atomic_read(&Adapter->TxPktAvail)
		&& MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
		|| Adapter->device_removed || (1 == Adapter->downloadDDR);
}

/**
 * @ingroup tx_functions
 * Transmit thread
 */
int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/)
{
	int status = 0;

	while (!kthread_should_stop()) {
		/* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
		if (Adapter->LinkUpStatus)
			wait_event_timeout(Adapter->tx_packet_wait_queue,
					tx_pending(Adapter), msecs_to_jiffies(10));
		else
			wait_event_interruptible(Adapter->tx_packet_wait_queue,
						tx_pending(Adapter));

		if (Adapter->device_removed)
			break;

		if (Adapter->downloadDDR == 1) {
			Adapter->downloadDDR += 1;
			status = download_ddr_settings(Adapter);
			if (status)
				pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
			continue;
		}

		/* Check end point for halt/stall. */
		if (Adapter->bEndPointHalted == TRUE) {
			Bcm_clear_halt_of_endpoints(Adapter);
			Adapter->bEndPointHalted = false;
			StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
		}

		if (Adapter->LinkUpStatus && !Adapter->IdleMode) {
			if (atomic_read(&Adapter->TotalPacketCount))
				update_per_sf_desc_cnts(Adapter);
		}

		if (atomic_read(&Adapter->CurrNumFreeTxDesc) &&
			Adapter->LinkStatus == SYNC_UP_REQUEST &&
			!Adapter->bSyncUpRequestSent) {

			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS,
					DBG_LVL_ALL, "Calling LinkMessage");
			LinkMessage(Adapter);
		}

		if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX,
					TX_PACKETS, DBG_LVL_ALL,
					"Device in Low Power mode...waking up");
			Adapter->usIdleModePattern = ABORT_IDLE_MODE;
			Adapter->bWakeUpDevice = TRUE;
			wake_up(&Adapter->process_rx_cntrlpkt);
		}

		transmit_packets(Adapter);
		atomic_set(&Adapter->TxPktAvail, 0);
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
			"Exiting the tx thread..\n");
	Adapter->transmit_packet_thread = NULL;
	return 0;
}
