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