/**
 * @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.
			 */
			struct bcm_mibs_dropped_cntrl_msg *msg =
				&pTarang->stDroppedAppCntrlMsgs;
			switch (*(PUSHORT)skb->data) {
			case CM_RESPONSES:
				msg->cm_responses++;
				break;
			case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
				msg->cm_control_newdsx_multiclassifier_resp++;
				break;
			case LINK_CONTROL_RESP:
				msg->link_control_resp++;
				break;
			case STATUS_RSP:
				msg->status_rsp++;
				break;
			case STATS_POINTER_RESP:
				msg->stats_pointer_resp++;
				break;
			case IDLE_MODE_STATUS:
				msg->idle_mode_status++;
				break;
			case AUTH_SS_HOST_MSG:
				msg->auth_ss_host_msg++;
				break;
			default:
				msg->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;
}


