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