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