at v3.7 51 kB view raw
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 suppresses the header by invoking PHS exported compress routine. 58 The header data after suppression is copied back to the NDIS_PACKET. 59 60 61Input parameters: IN struct bcm_mini_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 occurred. 70*/ 71 72int PHSTransmit(struct bcm_mini_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.ucaHdrSuppressionInBuf; 88 /* Pointer to PHS OUT Hdr Buffer */ 89 PUCHAR pucPHSPktHdrOutBuf = 90 Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; 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 suppression 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 Suppress 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 PHSReceive(struct bcm_mini_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 nTotalsuppressedPktHdrBytes = 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_RECEIVE,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 &nTotalsuppressedPktHdrBytes, 239 &nStandardPktHdrLen); 240 241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", 242 nTotalsuppressedPktHdrBytes,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 - nTotalsuppressedPktHdrBytes - 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 struct bcm_mini_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, struct bcm_mini_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 Successful"); 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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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_RECEIVE,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_RECEIVE,DBG_LVL_ALL,"Restoring header\n"); 794 795 phsi = *((unsigned char *)(pvInputBuffer)); 796 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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_RECEIVE,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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_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 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); 1419 in_buf++; 1420 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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_RECEIVE,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_RECEIVE,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_RECEIVE,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_RECEIVE,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 suppress = 0; 1498 struct bcm_mini_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 suppress = 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(suppress == 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 suppress; 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 struct bcm_mini_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