PHSModule.c revision 9dd47ee7dd535649a2c32d509631c7a3d793f2e1
1#include "headers.h" 2 3static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); 4 5static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); 6 7static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI); 8 9static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); 10 11static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule); 12 13static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule); 14 15static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry); 16 17static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule); 18 19static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable); 20 21static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf, 22 unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size ); 23 24 25static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, 26 unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size ); 27 28static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\ 29 S_PHS_RULE *phs_rules,UINT *header_size); 30 31 32static ULONG PhsCompress(void* pvContext, 33 B_UINT16 uiVcid, 34 B_UINT16 uiClsId, 35 void *pvInputBuffer, 36 void *pvOutputBuffer, 37 UINT *pOldHeaderSize, 38 UINT *pNewHeaderSize ); 39 40static ULONG PhsDeCompress(void* pvContext, 41 B_UINT16 uiVcid, 42 void *pvInputBuffer, 43 void *pvOutputBuffer, 44 UINT *pInHeaderSize, 45 UINT *pOutHeaderSize); 46 47 48 49#define IN 50#define OUT 51 52/* 53Function: PHSTransmit 54 55Description: This routine handle PHS(Payload Header Suppression for Tx path. 56 It extracts a fragment of the NDIS_PACKET containing the header 57 to be suppressed.It then supresses the header by invoking PHS exported compress routine. 58 The header data after supression is copied back to the NDIS_PACKET. 59 60 61Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context 62 IN Packet - NDIS packet containing data to be transmitted 63 IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to 64 identify PHS rule to be applied. 65 B_UINT16 uiClassifierRuleID - Classifier Rule ID 66 BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. 67 68Return: STATUS_SUCCESS - If the send was successful. 69 Other - If an error occured. 70*/ 71 72int PHSTransmit(PMINI_ADAPTER Adapter, 73 struct sk_buff **pPacket, 74 USHORT Vcid, 75 B_UINT16 uiClassifierRuleID, 76 BOOLEAN bHeaderSuppressionEnabled, 77 UINT *PacketLen, 78 UCHAR bEthCSSupport) 79{ 80 81 //PHS Sepcific 82 UINT unPHSPktHdrBytesCopied = 0; 83 UINT unPhsOldHdrSize = 0; 84 UINT unPHSNewPktHeaderLen = 0; 85 /* Pointer to PHS IN Hdr Buffer */ 86 PUCHAR pucPHSPktHdrInBuf = 87 Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf; 88 /* Pointer to PHS OUT Hdr Buffer */ 89 PUCHAR pucPHSPktHdrOutBuf = 90 Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf; 91 UINT usPacketType; 92 UINT BytesToRemove=0; 93 BOOLEAN bPHSI = 0; 94 LONG ulPhsStatus = 0; 95 UINT numBytesCompressed = 0; 96 struct sk_buff *newPacket = NULL; 97 struct sk_buff *Packet = *pPacket; 98 99 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit"); 100 101 if(!bEthCSSupport) 102 BytesToRemove=ETH_HLEN; 103 /* 104 Accumulate the header upto the size we support supression 105 from NDIS packet 106 */ 107 108 usPacketType=((struct ethhdr *)(Packet->data))->h_proto; 109 110 111 pucPHSPktHdrInBuf = Packet->data + BytesToRemove; 112 //considering data after ethernet header 113 if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) 114 { 115 116 unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); 117 } 118 else 119 { 120 unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; 121 } 122 123 if( (unPHSPktHdrBytesCopied > 0 ) && 124 (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) 125 { 126 127 128 // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. 129 // Suppress only if IP Header and PHS Enabled For the Service Flow 130 if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) || 131 (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && 132 (bHeaderSuppressionEnabled)) 133 { 134 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID); 135 136 137 unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; 138 ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, 139 Vcid, 140 uiClassifierRuleID, 141 pucPHSPktHdrInBuf, 142 pucPHSPktHdrOutBuf, 143 &unPhsOldHdrSize, 144 &unPHSNewPktHeaderLen); 145 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen); 146 147 if(unPHSNewPktHeaderLen == unPhsOldHdrSize) 148 { 149 if( ulPhsStatus == STATUS_PHS_COMPRESSED) 150 bPHSI = *pucPHSPktHdrOutBuf; 151 ulPhsStatus = STATUS_PHS_NOCOMPRESSION; 152 } 153 154 if( ulPhsStatus == STATUS_PHS_COMPRESSED) 155 { 156 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed"); 157 158 if(skb_cloned(Packet)) 159 { 160 newPacket = skb_copy(Packet, GFP_ATOMIC); 161 162 if(newPacket == NULL) 163 return STATUS_FAILURE; 164 165 dev_kfree_skb(Packet); 166 *pPacket = Packet = newPacket; 167 pucPHSPktHdrInBuf = Packet->data + BytesToRemove; 168 } 169 170 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN); 171 172 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN); 173 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove); 174 skb_pull(Packet, numBytesCompressed); 175 176 return STATUS_SUCCESS; 177 } 178 179 else 180 { 181 //if one byte headroom is not available, increase it through skb_cow 182 if(!(skb_headroom(Packet) > 0)) 183 { 184 if(skb_cow(Packet, 1)) 185 { 186 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n"); 187 return STATUS_FAILURE; 188 } 189 } 190 skb_push(Packet, 1); 191 192 // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it. 193 *(Packet->data + BytesToRemove) = bPHSI; 194 return STATUS_SUCCESS; 195 } 196 } 197 else 198 { 199 if(!bHeaderSuppressionEnabled) 200 { 201 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n"); 202 } 203 204 return STATUS_SUCCESS; 205 } 206 } 207 208 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS"); 209 return STATUS_SUCCESS; 210} 211 212int PHSRecieve(PMINI_ADAPTER Adapter, 213 USHORT usVcid, 214 struct sk_buff *packet, 215 UINT *punPacketLen, 216 UCHAR *pucEthernetHdr, 217 UINT bHeaderSuppressionEnabled) 218{ 219 u32 nStandardPktHdrLen = 0; 220 u32 nTotalsupressedPktHdrBytes = 0; 221 int ulPhsStatus = 0; 222 PUCHAR pucInBuff = NULL ; 223 UINT TotalBytesAdded = 0; 224 if(!bHeaderSuppressionEnabled) 225 { 226 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet"); 227 return ulPhsStatus; 228 } 229 230 pucInBuff = packet->data; 231 232 //Restore PHS suppressed header 233 nStandardPktHdrLen = packet->len; 234 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, 235 usVcid, 236 pucInBuff, 237 Adapter->ucaPHSPktRestoreBuf, 238 &nTotalsupressedPktHdrBytes, 239 &nStandardPktHdrLen); 240 241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", 242 nTotalsupressedPktHdrBytes,nStandardPktHdrLen); 243 244 if(ulPhsStatus != STATUS_PHS_COMPRESSED) 245 { 246 skb_pull(packet, 1); 247 return STATUS_SUCCESS; 248 } 249 else 250 { 251 TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN; 252 if(TotalBytesAdded) 253 { 254 if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) 255 skb_push(packet, TotalBytesAdded); 256 else 257 { 258 if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) 259 { 260 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n"); 261 return STATUS_FAILURE; 262 } 263 264 skb_push(packet, TotalBytesAdded); 265 } 266 } 267 268 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen); 269 } 270 271 return STATUS_SUCCESS; 272} 273 274void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) 275{ 276 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 277 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet"); 278 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen); 279} 280 281//----------------------------------------------------------------------------- 282// Procedure: phs_init 283// 284// Description: This routine is responsible for allocating memory for classifier and 285// PHS rules. 286// 287// Arguments: 288// pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc 289// 290// Returns: 291// TRUE(1) -If allocation of memory was success full. 292// FALSE -If allocation of memory fails. 293//----------------------------------------------------------------------------- 294int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) 295{ 296 int i; 297 S_SERVICEFLOW_TABLE *pstServiceFlowTable; 298 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function "); 299 300 if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable) 301 return -EINVAL; 302 303 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = 304 kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL); 305 306 if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) 307 { 308 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed"); 309 return -ENOMEM; 310 } 311 312 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; 313 for(i=0;i<MAX_SERVICEFLOWS;i++) 314 { 315 S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i]; 316 sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL); 317 if(!sServiceFlow.pstClassifierTable) 318 { 319 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); 320 free_phs_serviceflow_rules(pPhsdeviceExtension-> 321 pstServiceFlowPhsRulesTable); 322 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; 323 return -ENOMEM; 324 } 325 } 326 327 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); 328 329 if(pPhsdeviceExtension->CompressedTxBuffer == NULL) 330 { 331 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); 332 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); 333 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; 334 return -ENOMEM; 335 } 336 337 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); 338 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL) 339 { 340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); 341 kfree(pPhsdeviceExtension->CompressedTxBuffer); 342 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); 343 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; 344 return -ENOMEM; 345 } 346 347 348 349 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull"); 350 return STATUS_SUCCESS; 351} 352 353 354int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt) 355{ 356 if(pPHSDeviceExt->pstServiceFlowPhsRulesTable) 357 { 358 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); 359 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; 360 } 361 362 kfree(pPHSDeviceExt->CompressedTxBuffer); 363 pPHSDeviceExt->CompressedTxBuffer = NULL; 364 365 kfree(pPHSDeviceExt->UnCompressedRxBuffer); 366 pPHSDeviceExt->UnCompressedRxBuffer = NULL; 367 368 return 0; 369} 370 371 372 373//PHS functions 374/*++ 375PhsUpdateClassifierRule 376 377Routine Description: 378 Exported function to add or modify a PHS Rule. 379 380Arguments: 381 IN void* pvContext - PHS Driver Specific Context 382 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies 383 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. 384 IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. 385 386Return Value: 387 388 0 if successful, 389 >0 Error. 390 391--*/ 392ULONG PhsUpdateClassifierRule(IN void* pvContext, 393 IN B_UINT16 uiVcid , 394 IN B_UINT16 uiClsId , 395 IN S_PHS_RULE *psPhsRule, 396 IN B_UINT8 u8AssociatedPHSI) 397{ 398 ULONG lStatus =0; 399 UINT nSFIndex =0 ; 400 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; 401 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 402 403 404 405 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; 406 407 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n"); 408 409 if(pDeviceExtension == NULL) 410 { 411 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n"); 412 return ERR_PHS_INVALID_DEVICE_EXETENSION; 413 } 414 415 416 if(u8AssociatedPHSI == 0) 417 { 418 return ERR_PHS_INVALID_PHS_RULE; 419 } 420 421 /* Retrieve the SFID Entry Index for requested Service Flow */ 422 423 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, 424 uiVcid,&pstServiceFlowEntry); 425 426 if(nSFIndex == PHS_INVALID_TABLE_INDEX) 427 { 428 /* This is a new SF. Create a mapping entry for this */ 429 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, 430 pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); 431 return lStatus; 432 } 433 434 /* SF already Exists Add PHS Rule to existing SF */ 435 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, 436 pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI); 437 438 return lStatus; 439} 440 441/*++ 442PhsDeletePHSRule 443 444Routine Description: 445 Deletes the specified phs Rule within Vcid 446 447Arguments: 448 IN void* pvContext - PHS Driver Specific Context 449 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies 450 IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. 451 452Return Value: 453 454 0 if successful, 455 >0 Error. 456 457--*/ 458 459ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) 460{ 461 ULONG lStatus =0; 462 UINT nSFIndex =0, nClsidIndex =0 ; 463 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; 464 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; 465 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 466 467 468 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; 469 470 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); 471 472 if(pDeviceExtension) 473 { 474 475 //Retrieve the SFID Entry Index for requested Service Flow 476 nSFIndex = GetServiceFlowEntry(pDeviceExtension 477 ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry); 478 479 if(nSFIndex == PHS_INVALID_TABLE_INDEX) 480 { 481 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); 482 return ERR_SF_MATCH_FAIL; 483 } 484 485 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; 486 if(pstClassifierRulesTable) 487 { 488 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++) 489 { 490 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) 491 { 492 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) { 493 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) 494 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; 495 if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) 496 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); 497 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, 498 sizeof(S_CLASSIFIER_ENTRY)); 499 } 500 } 501 } 502 } 503 504 } 505 return lStatus; 506} 507 508/*++ 509PhsDeleteClassifierRule 510 511Routine Description: 512 Exported function to Delete a PHS Rule for the SFID,CLSID Pair. 513 514Arguments: 515 IN void* pvContext - PHS Driver Specific Context 516 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies 517 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. 518 519Return Value: 520 521 0 if successful, 522 >0 Error. 523 524--*/ 525ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId) 526{ 527 ULONG lStatus =0; 528 UINT nSFIndex =0, nClsidIndex =0 ; 529 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; 530 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; 531 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 532 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; 533 534 if(pDeviceExtension) 535 { 536 //Retrieve the SFID Entry Index for requested Service Flow 537 nSFIndex = GetServiceFlowEntry(pDeviceExtension 538 ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); 539 if(nSFIndex == PHS_INVALID_TABLE_INDEX) 540 { 541 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n"); 542 return ERR_SF_MATCH_FAIL; 543 } 544 545 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, 546 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); 547 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) 548 { 549 if(pstClassifierEntry->pstPhsRule) 550 { 551 if(pstClassifierEntry->pstPhsRule->u8RefCnt) 552 pstClassifierEntry->pstPhsRule->u8RefCnt--; 553 if(0==pstClassifierEntry->pstPhsRule->u8RefCnt) 554 kfree(pstClassifierEntry->pstPhsRule); 555 556 } 557 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY)); 558 } 559 560 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, 561 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry); 562 563 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) 564 { 565 kfree(pstClassifierEntry->pstPhsRule); 566 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY)); 567 } 568 } 569 return lStatus; 570} 571 572/*++ 573PhsDeleteSFRules 574 575Routine Description: 576 Exported function to Delete a all PHS Rules for the SFID. 577 578Arguments: 579 IN void* pvContext - PHS Driver Specific Context 580 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted 581 582Return Value: 583 584 0 if successful, 585 >0 Error. 586 587--*/ 588ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid) 589{ 590 591 ULONG lStatus =0; 592 UINT nSFIndex =0, nClsidIndex =0 ; 593 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; 594 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; 595 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 596 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; 597 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n"); 598 599 if(pDeviceExtension) 600 { 601 //Retrieve the SFID Entry Index for requested Service Flow 602 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, 603 uiVcid,&pstServiceFlowEntry); 604 if(nSFIndex == PHS_INVALID_TABLE_INDEX) 605 { 606 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); 607 return ERR_SF_MATCH_FAIL; 608 } 609 610 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; 611 if(pstClassifierRulesTable) 612 { 613 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++) 614 { 615 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) 616 { 617 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] 618 .pstPhsRule->u8RefCnt) 619 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] 620 .pstPhsRule->u8RefCnt--; 621 if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] 622 .pstPhsRule->u8RefCnt) 623 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); 624 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] 625 .pstPhsRule = NULL; 626 } 627 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); 628 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) 629 { 630 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] 631 .pstPhsRule->u8RefCnt) 632 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] 633 .pstPhsRule->u8RefCnt--; 634 if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] 635 .pstPhsRule->u8RefCnt) 636 kfree(pstClassifierRulesTable 637 ->stOldPhsRulesList[nClsidIndex].pstPhsRule); 638 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] 639 .pstPhsRule = NULL; 640 } 641 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); 642 } 643 } 644 pstServiceFlowEntry->bUsed = FALSE; 645 pstServiceFlowEntry->uiVcid = 0; 646 647 } 648 649 return lStatus; 650} 651 652 653/*++ 654PhsCompress 655 656Routine Description: 657 Exported function to compress the data using PHS. 658 659Arguments: 660 IN void* pvContext - PHS Driver Specific Context. 661 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies. 662 IN UINT uiClsId - The Classifier ID to which current packet header compression applies. 663 IN void *pvInputBuffer - The Input buffer containg packet header data 664 IN void *pvOutputBuffer - The output buffer returned by this function after PHS 665 IN UINT *pOldHeaderSize - The actual size of the header before PHS 666 IN UINT *pNewHeaderSize - The new size of the header after applying PHS 667 668Return Value: 669 670 0 if successful, 671 >0 Error. 672 673--*/ 674ULONG PhsCompress(IN void* pvContext, 675 IN B_UINT16 uiVcid, 676 IN B_UINT16 uiClsId, 677 IN void *pvInputBuffer, 678 OUT void *pvOutputBuffer, 679 OUT UINT *pOldHeaderSize, 680 OUT UINT *pNewHeaderSize ) 681{ 682 UINT nSFIndex =0, nClsidIndex =0 ; 683 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; 684 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; 685 S_PHS_RULE *pstPhsRule = NULL; 686 ULONG lStatus =0; 687 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 688 689 690 691 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; 692 693 694 if(pDeviceExtension == NULL) 695 { 696 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n"); 697 lStatus = STATUS_PHS_NOCOMPRESSION ; 698 return lStatus; 699 700 } 701 702 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n"); 703 704 705 //Retrieve the SFID Entry Index for requested Service Flow 706 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, 707 uiVcid,&pstServiceFlowEntry); 708 if(nSFIndex == PHS_INVALID_TABLE_INDEX) 709 { 710 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n"); 711 lStatus = STATUS_PHS_NOCOMPRESSION ; 712 return lStatus; 713 } 714 715 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, 716 uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry); 717 718 if(nClsidIndex == PHS_INVALID_TABLE_INDEX) 719 { 720 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n"); 721 lStatus = STATUS_PHS_NOCOMPRESSION ; 722 return lStatus; 723 } 724 725 726 //get rule from SF id,Cls ID pair and proceed 727 pstPhsRule = pstClassifierEntry->pstPhsRule; 728 729 if(!ValidatePHSRuleComplete(pstPhsRule)) 730 { 731 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n"); 732 lStatus = STATUS_PHS_NOCOMPRESSION ; 733 return lStatus; 734 } 735 736 //Compress Packet 737 lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer, 738 (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize); 739 740 if(lStatus == STATUS_PHS_COMPRESSED) 741 { 742 pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1; 743 pstPhsRule->PHSModifiedNumPackets++; 744 } 745 else 746 pstPhsRule->PHSErrorNumPackets++; 747 748 return lStatus; 749} 750 751/*++ 752PhsDeCompress 753 754Routine Description: 755 Exported function to restore the packet header in Rx path. 756 757Arguments: 758 IN void* pvContext - PHS Driver Specific Context. 759 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies. 760 IN void *pvInputBuffer - The Input buffer containg suppressed packet header data 761 OUT void *pvOutputBuffer - The output buffer returned by this function after restoration 762 OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter. 763 764Return Value: 765 766 0 if successful, 767 >0 Error. 768 769--*/ 770ULONG PhsDeCompress(IN void* pvContext, 771 IN B_UINT16 uiVcid, 772 IN void *pvInputBuffer, 773 OUT void *pvOutputBuffer, 774 OUT UINT *pInHeaderSize, 775 OUT UINT *pOutHeaderSize ) 776{ 777 UINT nSFIndex =0, nPhsRuleIndex =0 ; 778 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; 779 S_PHS_RULE *pstPhsRule = NULL; 780 UINT phsi; 781 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 782 PPHS_DEVICE_EXTENSION pDeviceExtension= 783 (PPHS_DEVICE_EXTENSION)pvContext; 784 785 *pInHeaderSize = 0; 786 787 if(pDeviceExtension == NULL) 788 { 789 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n"); 790 return ERR_PHS_INVALID_DEVICE_EXETENSION; 791 } 792 793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n"); 794 795 phsi = *((unsigned char *)(pvInputBuffer)); 796 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi); 797 if(phsi == UNCOMPRESSED_PACKET ) 798 { 799 return STATUS_PHS_NOCOMPRESSION; 800 } 801 802 //Retrieve the SFID Entry Index for requested Service Flow 803 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, 804 uiVcid,&pstServiceFlowEntry); 805 if(nSFIndex == PHS_INVALID_TABLE_INDEX) 806 { 807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n"); 808 return ERR_SF_MATCH_FAIL; 809 } 810 811 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi, 812 eActiveClassifierRuleContext,&pstPhsRule); 813 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) 814 { 815 //Phs Rule does not exist in active rules table. Lets try in the old rules table. 816 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, 817 phsi,eOldClassifierRuleContext,&pstPhsRule); 818 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) 819 { 820 return ERR_PHSRULE_MATCH_FAIL; 821 } 822 823 } 824 825 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, 826 (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize); 827 828 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; 829 830 pstPhsRule->PHSModifiedNumPackets++; 831 return STATUS_PHS_COMPRESSED; 832} 833 834 835//----------------------------------------------------------------------------- 836// Procedure: free_phs_serviceflow_rules 837// 838// Description: This routine is responsible for freeing memory allocated for PHS rules. 839// 840// Arguments: 841// rules - ptr to S_SERVICEFLOW_TABLE structure. 842// 843// Returns: 844// Does not return any value. 845//----------------------------------------------------------------------------- 846 847static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) 848{ 849 int i,j; 850 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 851 852 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); 853 if(psServiceFlowRulesTable) 854 { 855 for(i=0;i<MAX_SERVICEFLOWS;i++) 856 { 857 S_SERVICEFLOW_ENTRY stServiceFlowEntry = 858 psServiceFlowRulesTable->stSFList[i]; 859 S_CLASSIFIER_TABLE *pstClassifierRulesTable = 860 stServiceFlowEntry.pstClassifierTable; 861 862 if(pstClassifierRulesTable) 863 { 864 for(j=0;j<MAX_PHSRULE_PER_SF;j++) 865 { 866 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) 867 { 868 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule 869 ->u8RefCnt) 870 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule 871 ->u8RefCnt--; 872 if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule 873 ->u8RefCnt) 874 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule); 875 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL; 876 } 877 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) 878 { 879 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule 880 ->u8RefCnt) 881 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule 882 ->u8RefCnt--; 883 if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule 884 ->u8RefCnt) 885 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule); 886 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL; 887 } 888 } 889 kfree(pstClassifierRulesTable); 890 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL; 891 } 892 } 893 } 894 895 kfree(psServiceFlowRulesTable); 896 psServiceFlowRulesTable = NULL; 897} 898 899 900 901static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule) 902{ 903 if(psPhsRule) 904 { 905 if(!psPhsRule->u8PHSI) 906 { 907 // PHSI is not valid 908 return FALSE; 909 } 910 911 if(!psPhsRule->u8PHSS) 912 { 913 //PHSS Is Undefined 914 return FALSE; 915 } 916 917 //Check if PHSF is defines for the PHS Rule 918 if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF 919 { 920 return FALSE; 921 } 922 return TRUE; 923 } 924 else 925 { 926 return FALSE; 927 } 928} 929 930UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable, 931 IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry) 932{ 933 int i; 934 for(i=0;i<MAX_SERVICEFLOWS;i++) 935 { 936 if(psServiceFlowTable->stSFList[i].bUsed) 937 { 938 if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid) 939 { 940 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i]; 941 return i; 942 } 943 } 944 } 945 946 *ppstServiceFlowEntry = NULL; 947 return PHS_INVALID_TABLE_INDEX; 948} 949 950 951UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, 952 IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, 953 OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry) 954{ 955 int i; 956 S_CLASSIFIER_ENTRY *psClassifierRules = NULL; 957 for(i=0;i<MAX_PHSRULE_PER_SF;i++) 958 { 959 960 if(eClsContext == eActiveClassifierRuleContext) 961 { 962 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i]; 963 } 964 else 965 { 966 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i]; 967 } 968 969 if(psClassifierRules->bUsed) 970 { 971 if(psClassifierRules->uiClassifierRuleId == uiClsid) 972 { 973 *ppstClassifierEntry = psClassifierRules; 974 return i; 975 } 976 } 977 978 } 979 980 *ppstClassifierEntry = NULL; 981 return PHS_INVALID_TABLE_INDEX; 982} 983 984static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, 985 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, 986 OUT S_PHS_RULE **ppstPhsRule) 987{ 988 int i; 989 S_CLASSIFIER_ENTRY *pstClassifierRule = NULL; 990 for(i=0;i<MAX_PHSRULE_PER_SF;i++) 991 { 992 if(eClsContext == eActiveClassifierRuleContext) 993 { 994 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i]; 995 } 996 else 997 { 998 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i]; 999 } 1000 if(pstClassifierRule->bUsed) 1001 { 1002 if(pstClassifierRule->u8PHSI == uiPHSI) 1003 { 1004 *ppstPhsRule = pstClassifierRule->pstPhsRule; 1005 return i; 1006 } 1007 } 1008 1009 } 1010 1011 *ppstPhsRule = NULL; 1012 return PHS_INVALID_TABLE_INDEX; 1013} 1014 1015UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId, 1016 IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule, 1017 B_UINT8 u8AssociatedPHSI) 1018{ 1019 1020 S_CLASSIFIER_TABLE *psaClassifiertable = NULL; 1021 UINT uiStatus = 0; 1022 int iSfIndex; 1023 BOOLEAN bFreeEntryFound =FALSE; 1024 //Check for a free entry in SFID table 1025 for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++) 1026 { 1027 if(!psServiceFlowTable->stSFList[iSfIndex].bUsed) 1028 { 1029 bFreeEntryFound = TRUE; 1030 break; 1031 } 1032 } 1033 1034 if(!bFreeEntryFound) 1035 return ERR_SFTABLE_FULL; 1036 1037 1038 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable; 1039 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule, 1040 eActiveClassifierRuleContext,u8AssociatedPHSI); 1041 if(uiStatus == PHS_SUCCESS) 1042 { 1043 //Add entry at free index to the SF 1044 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE; 1045 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid; 1046 } 1047 1048 return uiStatus; 1049 1050} 1051 1052UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, 1053 IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry, 1054 S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI) 1055{ 1056 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; 1057 UINT uiStatus =PHS_SUCCESS; 1058 UINT nClassifierIndex = 0; 1059 S_CLASSIFIER_TABLE *psaClassifiertable = NULL; 1060 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1061 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; 1062 1063 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>"); 1064 1065 /* Check if the supplied Classifier already exists */ 1066 nClassifierIndex =GetClassifierEntry( 1067 pstServiceFlowEntry->pstClassifierTable,uiClsId, 1068 eActiveClassifierRuleContext,&pstClassifierEntry); 1069 if(nClassifierIndex == PHS_INVALID_TABLE_INDEX) 1070 { 1071 /* 1072 The Classifier doesn't exist. So its a new classifier being added. 1073 Add new entry to associate PHS Rule to the Classifier 1074 */ 1075 1076 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable, 1077 psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI); 1078 return uiStatus; 1079 } 1080 1081 /* 1082 The Classifier exists.The PHS Rule for this classifier 1083 is being modified 1084 */ 1085 if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) 1086 { 1087 if(pstClassifierEntry->pstPhsRule == NULL) 1088 return ERR_PHS_INVALID_PHS_RULE; 1089 1090 /* 1091 This rule already exists if any fields are changed for this PHS 1092 rule update them. 1093 */ 1094 /* If any part of PHSF is valid then we update PHSF */ 1095 if(psPhsRule->u8PHSFLength) 1096 { 1097 //update PHSF 1098 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, 1099 psPhsRule->u8PHSF , MAX_PHS_LENGTHS); 1100 } 1101 if(psPhsRule->u8PHSFLength) 1102 { 1103 //update PHSFLen 1104 pstClassifierEntry->pstPhsRule->u8PHSFLength = 1105 psPhsRule->u8PHSFLength; 1106 } 1107 if(psPhsRule->u8PHSMLength) 1108 { 1109 //update PHSM 1110 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, 1111 psPhsRule->u8PHSM, MAX_PHS_LENGTHS); 1112 } 1113 if(psPhsRule->u8PHSMLength) 1114 { 1115 //update PHSM Len 1116 pstClassifierEntry->pstPhsRule->u8PHSMLength = 1117 psPhsRule->u8PHSMLength; 1118 } 1119 if(psPhsRule->u8PHSS) 1120 { 1121 //update PHSS 1122 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS; 1123 } 1124 1125 //update PHSV 1126 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; 1127 1128 } 1129 else 1130 { 1131 /* 1132 A new rule is being set for this classifier. 1133 */ 1134 uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry, 1135 psaClassifiertable, psPhsRule, u8AssociatedPHSI); 1136 } 1137 1138 1139 1140 return uiStatus; 1141} 1142 1143static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, 1144 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, 1145 E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI) 1146{ 1147 UINT iClassifierIndex = 0; 1148 BOOLEAN bFreeEntryFound = FALSE; 1149 S_CLASSIFIER_ENTRY *psClassifierRules = NULL; 1150 UINT nStatus = PHS_SUCCESS; 1151 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1152 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule"); 1153 if(psaClassifiertable == NULL) 1154 { 1155 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; 1156 } 1157 1158 if(eClsContext == eOldClassifierRuleContext) 1159 { 1160 /* If An Old Entry for this classifier ID already exists in the 1161 old rules table replace it. */ 1162 1163 iClassifierIndex = 1164 GetClassifierEntry(psaClassifiertable, uiClsId, 1165 eClsContext,&psClassifierRules); 1166 if(iClassifierIndex != PHS_INVALID_TABLE_INDEX) 1167 { 1168 /* 1169 The Classifier already exists in the old rules table 1170 Lets replace the old classifier with the new one. 1171 */ 1172 bFreeEntryFound = TRUE; 1173 } 1174 } 1175 1176 if(!bFreeEntryFound) 1177 { 1178 /* 1179 Continue to search for a free location to add the rule 1180 */ 1181 for(iClassifierIndex = 0; iClassifierIndex < 1182 MAX_PHSRULE_PER_SF; iClassifierIndex++) 1183 { 1184 if(eClsContext == eActiveClassifierRuleContext) 1185 { 1186 psClassifierRules = 1187 &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; 1188 } 1189 else 1190 { 1191 psClassifierRules = 1192 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; 1193 } 1194 1195 if(!psClassifierRules->bUsed) 1196 { 1197 bFreeEntryFound = TRUE; 1198 break; 1199 } 1200 } 1201 } 1202 1203 if(!bFreeEntryFound) 1204 { 1205 if(eClsContext == eActiveClassifierRuleContext) 1206 { 1207 return ERR_CLSASSIFIER_TABLE_FULL; 1208 } 1209 else 1210 { 1211 //Lets replace the oldest rule if we are looking in old Rule table 1212 if(psaClassifiertable->uiOldestPhsRuleIndex >= 1213 MAX_PHSRULE_PER_SF) 1214 { 1215 psaClassifiertable->uiOldestPhsRuleIndex =0; 1216 } 1217 1218 iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex; 1219 psClassifierRules = 1220 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; 1221 1222 (psaClassifiertable->uiOldestPhsRuleIndex)++; 1223 } 1224 } 1225 1226 if(eClsContext == eOldClassifierRuleContext) 1227 { 1228 if(psClassifierRules->pstPhsRule == NULL) 1229 { 1230 psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL); 1231 1232 if(NULL == psClassifierRules->pstPhsRule) 1233 return ERR_PHSRULE_MEMALLOC_FAIL; 1234 } 1235 1236 psClassifierRules->bUsed = TRUE; 1237 psClassifierRules->uiClassifierRuleId = uiClsId; 1238 psClassifierRules->u8PHSI = psPhsRule->u8PHSI; 1239 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule; 1240 1241 /* Update The PHS rule */ 1242 memcpy(psClassifierRules->pstPhsRule, 1243 psPhsRule, sizeof(S_PHS_RULE)); 1244 } 1245 else 1246 { 1247 nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules, 1248 psaClassifiertable,psPhsRule,u8AssociatedPHSI); 1249 } 1250 return nStatus; 1251} 1252 1253 1254static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, 1255 IN S_CLASSIFIER_ENTRY *pstClassifierEntry, 1256 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, 1257 B_UINT8 u8AssociatedPHSI) 1258{ 1259 S_PHS_RULE *pstAddPhsRule = NULL; 1260 UINT nPhsRuleIndex = 0; 1261 BOOLEAN bPHSRuleOrphaned = FALSE; 1262 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1263 psPhsRule->u8RefCnt =0; 1264 1265 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ 1266 bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable, 1267 pstClassifierEntry->pstPhsRule); 1268 1269 //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF 1270 nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI, 1271 eActiveClassifierRuleContext, &pstAddPhsRule); 1272 if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) 1273 { 1274 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); 1275 1276 if(psPhsRule->u8PHSI == 0) 1277 { 1278 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); 1279 return ERR_PHS_INVALID_PHS_RULE; 1280 } 1281 //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId 1282 if(FALSE == bPHSRuleOrphaned) 1283 { 1284 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL); 1285 if(NULL == pstClassifierEntry->pstPhsRule) 1286 { 1287 return ERR_PHSRULE_MEMALLOC_FAIL; 1288 } 1289 } 1290 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); 1291 1292 } 1293 else 1294 { 1295 //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule 1296 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); 1297 if(bPHSRuleOrphaned) 1298 { 1299 kfree(pstClassifierEntry->pstPhsRule); 1300 pstClassifierEntry->pstPhsRule = NULL; 1301 } 1302 pstClassifierEntry->pstPhsRule = pstAddPhsRule; 1303 1304 } 1305 pstClassifierEntry->bUsed = TRUE; 1306 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; 1307 pstClassifierEntry->uiClassifierRuleId = uiClsId; 1308 pstClassifierEntry->pstPhsRule->u8RefCnt++; 1309 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; 1310 1311 return PHS_SUCCESS; 1312 1313} 1314 1315static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule) 1316{ 1317 if(pstPhsRule==NULL) 1318 return FALSE; 1319 if(pstPhsRule->u8RefCnt) 1320 pstPhsRule->u8RefCnt--; 1321 if(0==pstPhsRule->u8RefCnt) 1322 { 1323 /*if(pstPhsRule->u8PHSI) 1324 //Store the currently active rule into the old rules list 1325 CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/ 1326 return TRUE; 1327 } 1328 else 1329 { 1330 return FALSE; 1331 } 1332} 1333 1334void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension) 1335{ 1336 int i,j,k,l; 1337 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1338 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n"); 1339 for(i=0;i<MAX_SERVICEFLOWS;i++) 1340 { 1341 S_SERVICEFLOW_ENTRY stServFlowEntry = 1342 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; 1343 if(stServFlowEntry.bUsed) 1344 { 1345 for(j=0;j<MAX_PHSRULE_PER_SF;j++) 1346 { 1347 for(l=0;l<2;l++) 1348 { 1349 S_CLASSIFIER_ENTRY stClsEntry; 1350 if(l==0) 1351 { 1352 stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j]; 1353 if(stClsEntry.bUsed) 1354 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n"); 1355 } 1356 else 1357 { 1358 stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j]; 1359 if(stClsEntry.bUsed) 1360 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n"); 1361 } 1362 if(stClsEntry.bUsed) 1363 { 1364 1365 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid); 1366 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId); 1367 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI); 1368 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); 1369 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI); 1370 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength); 1371 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); 1372 for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++) 1373 { 1374 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]); 1375 } 1376 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength); 1377 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); 1378 for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++) 1379 { 1380 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]); 1381 } 1382 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS); 1383 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV); 1384 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); 1385 } 1386 } 1387 } 1388 } 1389 } 1390} 1391 1392 1393//----------------------------------------------------------------------------- 1394// Procedure: phs_decompress 1395// 1396// Description: This routine restores the static fields within the packet. 1397// 1398// Arguments: 1399// in_buf - ptr to incoming packet buffer. 1400// out_buf - ptr to output buffer where the suppressed header is copied. 1401// decomp_phs_rules - ptr to PHS rule. 1402// header_size - ptr to field which holds the phss or phsf_length. 1403// 1404// Returns: 1405// size -The number of bytes of dynamic fields present with in the incoming packet 1406// header. 1407// 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed. 1408//----------------------------------------------------------------------------- 1409 1410int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, 1411 S_PHS_RULE *decomp_phs_rules,UINT *header_size) 1412{ 1413 int phss,size=0; 1414 S_PHS_RULE *tmp_memb; 1415 int bit,i=0; 1416 unsigned char *phsf,*phsm; 1417 int in_buf_len = *header_size-1; 1418 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1419 in_buf++; 1420 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n"); 1421 *header_size = 0; 1422 1423 if((decomp_phs_rules == NULL )) 1424 return 0; 1425 1426 1427 tmp_memb = decomp_phs_rules; 1428 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); 1429 //*header_size = tmp_memb->u8PHSFLength; 1430 phss = tmp_memb->u8PHSS; 1431 phsf = tmp_memb->u8PHSF; 1432 phsm = tmp_memb->u8PHSM; 1433 1434 if(phss > MAX_PHS_LENGTHS) 1435 phss = MAX_PHS_LENGTHS; 1436 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); 1437 while((phss > 0) && (size < in_buf_len)) 1438 { 1439 bit = ((*phsm << i)& SUPPRESS); 1440 1441 if(bit == SUPPRESS) 1442 { 1443 *out_buf = *phsf; 1444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", 1445 phss,*phsf,*out_buf); 1446 } 1447 else 1448 { 1449 *out_buf = *in_buf; 1450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", 1451 phss,*in_buf,*out_buf); 1452 in_buf++; 1453 size++; 1454 } 1455 out_buf++; 1456 phsf++; 1457 phss--; 1458 i++; 1459 *header_size=*header_size + 1; 1460 1461 if(i > MAX_NO_BIT) 1462 { 1463 i=0; 1464 phsm++; 1465 } 1466 } 1467 return size; 1468} 1469 1470 1471 1472 1473//----------------------------------------------------------------------------- 1474// Procedure: phs_compress 1475// 1476// Description: This routine suppresses the static fields within the packet.Before 1477// that it will verify the fields to be suppressed with the corresponding fields in the 1478// phsf. For verification it checks the phsv field of PHS rule. If set and verification 1479// succeeds it suppresses the field.If any one static field is found different none of 1480// the static fields are suppressed then the packet is sent as uncompressed packet with 1481// phsi=0. 1482// 1483// Arguments: 1484// phs_rule - ptr to PHS rule. 1485// in_buf - ptr to incoming packet buffer. 1486// out_buf - ptr to output buffer where the suppressed header is copied. 1487// header_size - ptr to field which holds the phss. 1488// 1489// Returns: 1490// size-The number of bytes copied into the output buffer i.e dynamic fields 1491// 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. 1492//----------------------------------------------------------------------------- 1493static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf 1494 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) 1495{ 1496 unsigned char *old_addr = out_buf; 1497 int supress = 0; 1498 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1499 if(phs_rule == NULL) 1500 { 1501 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!"); 1502 *out_buf = ZERO_PHSI; 1503 return STATUS_PHS_NOCOMPRESSION; 1504 } 1505 1506 1507 if(phs_rule->u8PHSS <= *new_header_size) 1508 { 1509 *header_size = phs_rule->u8PHSS; 1510 } 1511 else 1512 { 1513 *header_size = *new_header_size; 1514 } 1515 //To copy PHSI 1516 out_buf++; 1517 supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF, 1518 phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size); 1519 1520 if(supress == STATUS_PHS_COMPRESSED) 1521 { 1522 *old_addr = (unsigned char)phs_rule->u8PHSI; 1523 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI); 1524 } 1525 else 1526 { 1527 *old_addr = ZERO_PHSI; 1528 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed"); 1529 } 1530 return supress; 1531} 1532 1533 1534//----------------------------------------------------------------------------- 1535// Procedure: verify_suppress_phsf 1536// 1537// Description: This routine verifies the fields of the packet and if all the 1538// static fields are equal it adds the phsi of that PHS rule.If any static 1539// field differs it woun't suppress any field. 1540// 1541// Arguments: 1542// rules_set - ptr to classifier_rules. 1543// in_buffer - ptr to incoming packet buffer. 1544// out_buffer - ptr to output buffer where the suppressed header is copied. 1545// phsf - ptr to phsf. 1546// phsm - ptr to phsm. 1547// phss - variable holding phss. 1548// 1549// Returns: 1550// size-The number of bytes copied into the output buffer i.e dynamic fields. 1551// 0 -Packet has failed the verification. 1552//----------------------------------------------------------------------------- 1553 1554static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, 1555 unsigned char *phsf,unsigned char *phsm,unsigned int phss, 1556 unsigned int phsv,UINT* new_header_size) 1557{ 1558 unsigned int size=0; 1559 int bit,i=0; 1560 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 1561 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm); 1562 1563 1564 if(phss>(*new_header_size)) 1565 { 1566 phss=*new_header_size; 1567 } 1568 while(phss > 0) 1569 { 1570 bit = ((*phsm << i)& SUPPRESS); 1571 if(bit == SUPPRESS) 1572 { 1573 1574 if(*in_buffer != *phsf) 1575 { 1576 if(phsv == VERIFY) 1577 { 1578 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf); 1579 return STATUS_PHS_NOCOMPRESSION; 1580 } 1581 } 1582 else 1583 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf); 1584 } 1585 else 1586 { 1587 *out_buffer = *in_buffer; 1588 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer); 1589 out_buffer++; 1590 size++; 1591 } 1592 in_buffer++; 1593 phsf++; 1594 phss--; 1595 i++; 1596 if(i > MAX_NO_BIT) 1597 { 1598 i=0; 1599 phsm++; 1600 } 1601 } 1602 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success"); 1603 *new_header_size = size; 1604 return STATUS_PHS_COMPRESSED; 1605} 1606 1607 1608 1609 1610 1611 1612