349fa79498
Add control packet information is useful for debugging. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
223 lines
6.7 KiB
C
223 lines
6.7 KiB
C
/**
|
|
@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(PMINI_ADAPTER Adapter, struct sk_buff *skb)
|
|
{
|
|
PPER_TARANG_DATA pTarang = NULL;
|
|
BOOLEAN HighPriorityMessage = FALSE;
|
|
struct sk_buff * newPacket = NULL;
|
|
CHAR cntrl_msg_mask_bit = 0;
|
|
BOOLEAN 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 (PMINI_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)
|
|
{
|
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
|
PPER_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(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
|
|
|
|
}
|
|
return STATUS_SUCCESS ;
|
|
}
|
|
|
|
|