/**
 * @file HandleControlPacket.c
 * This file contains the routines to deal with
 * sending and receiving of control packets.
 */
#include "headers.h"

/**
 * When a control packet is received, analyze the
 * "status" and call appropriate response function.
 * Enqueue the control packet for Application.
 * @return None
 */
static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
{
	struct bcm_tarang_data *pTarang = NULL;
	bool HighPriorityMessage = false;
	struct sk_buff *newPacket = NULL;
	CHAR cntrl_msg_mask_bit = 0;
	bool drop_pkt_flag = TRUE;
	USHORT usStatus = *(PUSHORT)(skb->data);

	if (netif_msg_pktdata(Adapter))
		print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
				16, 1, skb->data, skb->len, 0);

	switch (usStatus) {
	case CM_RESPONSES:               /* 0xA0 */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL,
			"MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
		HighPriorityMessage = TRUE;
		break;
	case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
		HighPriorityMessage = TRUE;
		if (Adapter->LinkStatus == LINKUP_DONE)
			CmControlResponseMessage(Adapter,
				(skb->data + sizeof(USHORT)));
		break;
	case LINK_CONTROL_RESP:          /* 0xA2 */
	case STATUS_RSP:                 /* 0xA1 */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL, "LINK_CONTROL_RESP");
		HighPriorityMessage = TRUE;
		LinkControlResponseMessage(Adapter,
			(skb->data + sizeof(USHORT)));
		break;
	case STATS_POINTER_RESP:         /* 0xA6 */
		HighPriorityMessage = TRUE;
		StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
		break;
	case IDLE_MODE_STATUS:           /* 0xA3 */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL,
			"IDLE_MODE_STATUS Type Message Got from F/W");
		InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
					sizeof(USHORT)));
		HighPriorityMessage = TRUE;
		break;

	case AUTH_SS_HOST_MSG:
		HighPriorityMessage = TRUE;
		break;

	default:
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL, "Got Default Response");
		/* Let the Application Deal with This Packet */
		break;
	}

	/* Queue The Control Packet to The Application Queues */
	down(&Adapter->RxAppControlQueuelock);

	for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
		if (Adapter->device_removed)
			break;

		drop_pkt_flag = TRUE;
		/*
		 * There are cntrl msg from A0 to AC. It has been mapped to 0 to
		 * C bit in the cntrl mask.
		 * Also, by default AD to BF has been masked to the rest of the
		 * bits... which wil be ON by default.
		 * if mask bit is enable to particular pkt status, send it out
		 * to app else stop it.
		 */
		cntrl_msg_mask_bit = (usStatus & 0x1F);
		/*
		 * printk("\ninew  msg  mask bit which is disable in mask:%X",
		 *	cntrl_msg_mask_bit);
		 */
		if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit))
			drop_pkt_flag = false;

		if ((drop_pkt_flag == TRUE) ||
				(pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN)
				|| ((pTarang->AppCtrlQueueLen >
					MAX_APP_QUEUE_LEN / 2) &&
				    (HighPriorityMessage == false))) {
			/*
			 * Assumption:-
			 * 1. every tarang manages it own dropped pkt
			 *    statitistics
			 * 2. Total packet dropped per tarang will be equal to
			 *    the sum of all types of dropped pkt by that
			 *    tarang only.
			 */
			switch (*(PUSHORT)skb->data) {
			case CM_RESPONSES:
				pTarang->stDroppedAppCntrlMsgs.cm_responses++;
				break;
			case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
				pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
				break;
			case LINK_CONTROL_RESP:
				pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
				break;
			case STATUS_RSP:
				pTarang->stDroppedAppCntrlMsgs.status_rsp++;
				break;
			case STATS_POINTER_RESP:
				pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
				break;
			case IDLE_MODE_STATUS:
				pTarang->stDroppedAppCntrlMsgs.idle_mode_status++;
				break;
			case AUTH_SS_HOST_MSG:
				pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++;
				break;
			default:
				pTarang->stDroppedAppCntrlMsgs.low_priority_message++;
				break;
			}

			continue;
		}

		newPacket = skb_clone(skb, GFP_KERNEL);
		if (!newPacket)
			break;
		ENQUEUEPACKET(pTarang->RxAppControlHead,
				pTarang->RxAppControlTail, newPacket);
		pTarang->AppCtrlQueueLen++;
	}
	up(&Adapter->RxAppControlQueuelock);
	wake_up(&Adapter->process_read_wait_queue);
	dev_kfree_skb(skb);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
			"After wake_up_interruptible");
}

/**
 * @ingroup ctrl_pkt_functions
 * Thread to handle control pkt reception
 */
int control_packet_handler(struct bcm_mini_adapter *Adapter /* pointer to adapter object*/)
{
	struct sk_buff *ctrl_packet = NULL;
	unsigned long flags = 0;
	/* struct timeval tv; */
	/* int *puiBuffer = NULL; */
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
		"Entering to make thread wait on control packet event!");
	while (1) {
		wait_event_interruptible(Adapter->process_rx_cntrlpkt,
			atomic_read(&Adapter->cntrlpktCnt) ||
			Adapter->bWakeUpDevice ||
			kthread_should_stop());


		if (kthread_should_stop()) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
				DBG_LVL_ALL, "Exiting\n");
			return 0;
		}
		if (TRUE == Adapter->bWakeUpDevice) {
			Adapter->bWakeUpDevice = false;
			if ((false == Adapter->bTriedToWakeUpFromlowPowerMode)
					&& ((TRUE == Adapter->IdleMode) ||
					    (TRUE == Adapter->bShutStatus))) {
				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					CP_CTRL_PKT, DBG_LVL_ALL,
					"Calling InterfaceAbortIdlemode\n");
				/*
				 * Adapter->bTriedToWakeUpFromlowPowerMode
				 *					= TRUE;
				 */
				InterfaceIdleModeWakeup(Adapter);
			}
			continue;
		}

		while (atomic_read(&Adapter->cntrlpktCnt)) {
			spin_lock_irqsave(&Adapter->control_queue_lock, flags);
			ctrl_packet = Adapter->RxControlHead;
			if (ctrl_packet) {
				DEQUEUEPACKET(Adapter->RxControlHead,
					Adapter->RxControlTail);
				/* Adapter->RxControlHead=ctrl_packet->next; */
			}

			spin_unlock_irqrestore(&Adapter->control_queue_lock,
						flags);
			handle_rx_control_packet(Adapter, ctrl_packet);
			atomic_dec(&Adapter->cntrlpktCnt);
		}

		SetUpTargetDsxBuffers(Adapter);
	}
	return STATUS_SUCCESS;
}

INT flushAllAppQ(void)
{
	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
	struct bcm_tarang_data *pTarang = NULL;
	struct sk_buff *PacketToDrop = NULL;
	for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
		while (pTarang->RxAppControlHead != NULL) {
			PacketToDrop = pTarang->RxAppControlHead;
			DEQUEUEPACKET(pTarang->RxAppControlHead,
					pTarang->RxAppControlTail);
			dev_kfree_skb(PacketToDrop);
		}
		pTarang->AppCtrlQueueLen = 0;
		/* dropped contrl packet statistics also should be reset. */
		memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0,
			sizeof(struct bcm_mibs_dropped_cntrl_msg));

	}
	return STATUS_SUCCESS;
}


