blob: afc7bcc3e54b5bce09b7ea36c74b413047ede7a4 [file] [log] [blame]
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001#include "headers.h"
2
Kevin McKinney6c259f42013-02-20 23:25:27 -05003static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_table *psServiceFlowTable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04004
Kevin McKinney6c259f42013-02-20 23:25:27 -05005static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_entry *pstServiceFlowEntry, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04006
Kevin McKinney6c259f42013-02-20 23:25:27 -05007static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, enum bcm_phs_classifier_context eClsContext, B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04008
Kevin McKinney6c259f42013-02-20 23:25:27 -05009static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_entry *pstClassifierEntry, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040010
Lisa Nguyen3abd6f12013-10-28 01:35:59 -070011static bool ValidatePHSRuleComplete(struct bcm_phs_rule *psPhsRule);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040012
Lisa Nguyen3abd6f12013-10-28 01:35:59 -070013static bool DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040014
Kevin McKinney6c259f42013-02-20 23:25:27 -050015static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_classifier_entry **ppstClassifierEntry);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040016
Kevin McKinney6c259f42013-02-20 23:25:27 -050017static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_rule **ppstPhsRule);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040018
Kevin McKinneyda4d1502012-12-20 00:31:29 -050019static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040020
Kevin McKinneya903d652012-12-20 00:31:34 -050021static int phs_compress(struct bcm_phs_rule *phs_members, unsigned char *in_buf,
Kevin McKinney6c259f42013-02-20 23:25:27 -050022 unsigned char *out_buf, unsigned int *header_size, UINT *new_header_size);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040023
Kevin McKinney6c259f42013-02-20 23:25:27 -050024static int verify_suppress_phsf(unsigned char *in_buffer, unsigned char *out_buffer,
25 unsigned char *phsf, unsigned char *phsm, unsigned int phss, unsigned int phsv, UINT *new_header_size);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040026
Kevin McKinney6c259f42013-02-20 23:25:27 -050027static int phs_decompress(unsigned char *in_buf, unsigned char *out_buf,
28 struct bcm_phs_rule *phs_rules, UINT *header_size);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040029
Kevin McKinney6c259f42013-02-20 23:25:27 -050030static ULONG PhsCompress(void *pvContext,
31 B_UINT16 uiVcid,
32 B_UINT16 uiClsId,
33 void *pvInputBuffer,
34 void *pvOutputBuffer,
35 UINT *pOldHeaderSize,
36 UINT *pNewHeaderSize);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040037
Kevin McKinney6c259f42013-02-20 23:25:27 -050038static ULONG PhsDeCompress(void *pvContext,
39 B_UINT16 uiVcid,
40 void *pvInputBuffer,
41 void *pvOutputBuffer,
42 UINT *pInHeaderSize,
43 UINT *pOutHeaderSize);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040044
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070045#define IN
46#define OUT
47
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070048/*
Kevin McKinney14b3a402013-02-20 23:25:29 -050049 * Function: PHSTransmit
50 * Description: This routine handle PHS(Payload Header Suppression for Tx path.
51 * It extracts a fragment of the NDIS_PACKET containing the header
52 * to be suppressed. It then suppresses the header by invoking PHS exported compress routine.
53 * The header data after suppression is copied back to the NDIS_PACKET.
54 *
55 * Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
56 * IN Packet - NDIS packet containing data to be transmitted
57 * IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to
58 * identify PHS rule to be applied.
59 * B_UINT16 uiClassifierRuleID - Classifier Rule ID
60 * BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
61 *
62 * Return: STATUS_SUCCESS - If the send was successful.
63 * Other - If an error occurred.
64 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070065
Kevin McKinney29794602012-05-26 12:05:12 -040066int PHSTransmit(struct bcm_mini_adapter *Adapter,
Kevin McKinney6c259f42013-02-20 23:25:27 -050067 struct sk_buff **pPacket,
68 USHORT Vcid,
69 B_UINT16 uiClassifierRuleID,
Lisa Nguyen3abd6f12013-10-28 01:35:59 -070070 bool bHeaderSuppressionEnabled,
Kevin McKinney6c259f42013-02-20 23:25:27 -050071 UINT *PacketLen,
72 UCHAR bEthCSSupport)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070073{
Kevin McKinney14b3a402013-02-20 23:25:29 -050074 /* PHS Sepcific */
Kevin McKinney6c259f42013-02-20 23:25:27 -050075 UINT unPHSPktHdrBytesCopied = 0;
76 UINT unPhsOldHdrSize = 0;
77 UINT unPHSNewPktHeaderLen = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070078 /* Pointer to PHS IN Hdr Buffer */
Kevin McKinney6c259f42013-02-20 23:25:27 -050079 PUCHAR pucPHSPktHdrInBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070080 /* Pointer to PHS OUT Hdr Buffer */
Kevin McKinney6c259f42013-02-20 23:25:27 -050081 PUCHAR pucPHSPktHdrOutBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
82 UINT usPacketType;
83 UINT BytesToRemove = 0;
Lisa Nguyen3abd6f12013-10-28 01:35:59 -070084 bool bPHSI = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070085 LONG ulPhsStatus = 0;
Kevin McKinney6c259f42013-02-20 23:25:27 -050086 UINT numBytesCompressed = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070087 struct sk_buff *newPacket = NULL;
88 struct sk_buff *Packet = *pPacket;
89
Kevin McKinney6c259f42013-02-20 23:25:27 -050090 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070091
Kevin McKinney6c259f42013-02-20 23:25:27 -050092 if (!bEthCSSupport)
93 BytesToRemove = ETH_HLEN;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070094 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -050095 * Accumulate the header upto the size we support suppression
96 * from NDIS packet
97 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070098
Kevin McKinney6c259f42013-02-20 23:25:27 -050099 usPacketType = ((struct ethhdr *)(Packet->data))->h_proto;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700100
101 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
Kevin McKinney14b3a402013-02-20 23:25:29 -0500102 /* considering data after ethernet header */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500103 if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700104 unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700105 else
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700106 unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700107
Kevin McKinney6c259f42013-02-20 23:25:27 -0500108 if ((unPHSPktHdrBytesCopied > 0) &&
Kevin McKinney69493872013-02-20 23:25:28 -0500109 (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) {
110
Kevin McKinney14b3a402013-02-20 23:25:29 -0500111 /*
112 * Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
113 * Suppress only if IP Header and PHS Enabled For the Service Flow
114 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500115 if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
116 (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
Kevin McKinney69493872013-02-20 23:25:28 -0500117 (bHeaderSuppressionEnabled)) {
118
Kevin McKinney6c259f42013-02-20 23:25:27 -0500119 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nTrying to PHS Compress Using Classifier rule 0x%X", uiClassifierRuleID);
120 unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
121 ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
122 Vcid,
123 uiClassifierRuleID,
124 pucPHSPktHdrInBuf,
125 pucPHSPktHdrOutBuf,
126 &unPhsOldHdrSize,
127 &unPHSNewPktHeaderLen);
128 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nPHS Old header Size : %d New Header Size %d\n", unPhsOldHdrSize, unPHSNewPktHeaderLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700129
Kevin McKinney69493872013-02-20 23:25:28 -0500130 if (unPHSNewPktHeaderLen == unPhsOldHdrSize) {
131
Kevin McKinney6c259f42013-02-20 23:25:27 -0500132 if (ulPhsStatus == STATUS_PHS_COMPRESSED)
133 bPHSI = *pucPHSPktHdrOutBuf;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700134
Kevin McKinney6c259f42013-02-20 23:25:27 -0500135 ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
136 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700137
Kevin McKinney69493872013-02-20 23:25:28 -0500138 if (ulPhsStatus == STATUS_PHS_COMPRESSED) {
139
Kevin McKinney6c259f42013-02-20 23:25:27 -0500140 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "PHS Sending packet Compressed");
141
Kevin McKinney69493872013-02-20 23:25:28 -0500142 if (skb_cloned(Packet)) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500143 newPacket = skb_copy(Packet, GFP_ATOMIC);
144
145 if (newPacket == NULL)
146 return STATUS_FAILURE;
147
148 dev_kfree_skb(Packet);
149 *pPacket = Packet = newPacket;
150 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700151 }
152
Kevin McKinney6c259f42013-02-20 23:25:27 -0500153 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen + PHSI_LEN);
154
155 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
156 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
157 skb_pull(Packet, numBytesCompressed);
158
159 return STATUS_SUCCESS;
Kevin McKinney69493872013-02-20 23:25:28 -0500160 } else {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500161 /* if one byte headroom is not available, increase it through skb_cow */
Kevin McKinney69493872013-02-20 23:25:28 -0500162 if (!(skb_headroom(Packet) > 0)) {
163
164 if (skb_cow(Packet, 1)) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500165 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
166 return STATUS_FAILURE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700167 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700168 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500169 skb_push(Packet, 1);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700170
Kevin McKinney14b3a402013-02-20 23:25:29 -0500171 /*
172 * CAUTION: The MAC Header is getting corrupted
173 * here for IP CS - can be saved by copying 14
174 * Bytes. not needed .... hence corrupting it.
175 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500176 *(Packet->data + BytesToRemove) = bPHSI;
177 return STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700178 }
Kevin McKinney69493872013-02-20 23:25:28 -0500179 } else {
180
Kevin McKinney6c259f42013-02-20 23:25:27 -0500181 if (!bHeaderSuppressionEnabled)
Kevin McKinney6c259f42013-02-20 23:25:27 -0500182 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nHeader Suppression Disabled For SF: No PHS\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700183
184 return STATUS_SUCCESS;
185 }
186 }
187
Kevin McKinney14b3a402013-02-20 23:25:29 -0500188 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS"); */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700189 return STATUS_SUCCESS;
190}
191
Kevin McKinney29794602012-05-26 12:05:12 -0400192int PHSReceive(struct bcm_mini_adapter *Adapter,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500193 USHORT usVcid,
194 struct sk_buff *packet,
195 UINT *punPacketLen,
196 UCHAR *pucEthernetHdr,
197 UINT bHeaderSuppressionEnabled)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700198{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500199 u32 nStandardPktHdrLen = 0;
200 u32 nTotalsuppressedPktHdrBytes = 0;
201 int ulPhsStatus = 0;
202 PUCHAR pucInBuff = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700203 UINT TotalBytesAdded = 0;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500204
Kevin McKinney69493872013-02-20 23:25:28 -0500205 if (!bHeaderSuppressionEnabled) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500206 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nPhs Disabled for incoming packet");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700207 return ulPhsStatus;
208 }
209
210 pucInBuff = packet->data;
211
Kevin McKinney14b3a402013-02-20 23:25:29 -0500212 /* Restore PHS suppressed header */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700213 nStandardPktHdrLen = packet->len;
214 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500215 usVcid,
216 pucInBuff,
217 Adapter->ucaPHSPktRestoreBuf,
218 &nTotalsuppressedPktHdrBytes,
219 &nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700220
Kevin McKinney6c259f42013-02-20 23:25:27 -0500221 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
222 nTotalsuppressedPktHdrBytes, nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700223
Kevin McKinney69493872013-02-20 23:25:28 -0500224 if (ulPhsStatus != STATUS_PHS_COMPRESSED) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700225 skb_pull(packet, 1);
226 return STATUS_SUCCESS;
Kevin McKinney69493872013-02-20 23:25:28 -0500227 } else {
Peter Meerwaldb38e2742012-06-13 20:44:35 +0200228 TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN;
Kevin McKinney69493872013-02-20 23:25:28 -0500229
230 if (TotalBytesAdded) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500231 if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700232 skb_push(packet, TotalBytesAdded);
Kevin McKinney69493872013-02-20 23:25:28 -0500233 else {
234 if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500235 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700236 return STATUS_FAILURE;
237 }
238
239 skb_push(packet, TotalBytesAdded);
240 }
241 }
242
Stephen Hemminger082e8892010-11-01 09:35:21 -0400243 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700244 }
245
246 return STATUS_SUCCESS;
247}
248
Kevin McKinney6c259f42013-02-20 23:25:27 -0500249void DumpFullPacket(UCHAR *pBuf, UINT nPktLen)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700250{
Kevin McKinney29794602012-05-26 12:05:12 -0400251 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500252
253 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dumping Data Packet");
254 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, pBuf, nPktLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700255}
256
Kevin McKinney14b3a402013-02-20 23:25:29 -0500257/*
258 * Procedure: phs_init
259 *
260 * Description: This routine is responsible for allocating memory for classifier and
261 * PHS rules.
262 *
263 * Arguments:
264 * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
265 *
266 * Returns:
Kevin McKinney175c5122013-02-20 23:25:30 -0500267 * TRUE(1) -If allocation of memory was successful.
Kevin McKinney14b3a402013-02-20 23:25:29 -0500268 * FALSE -If allocation of memory fails.
269 */
Kevin McKinney60dadf92012-12-20 00:31:28 -0500270int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700271{
272 int i;
Kevin McKinneyda4d1502012-12-20 00:31:29 -0500273 struct bcm_phs_table *pstServiceFlowTable;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700274
Kevin McKinney6c259f42013-02-20 23:25:27 -0500275 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function");
276
277 if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700278 return -EINVAL;
279
Kevin McKinney6c259f42013-02-20 23:25:27 -0500280 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700281
Kevin McKinney69493872013-02-20 23:25:28 -0500282 if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500283 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700284 return -ENOMEM;
285 }
286
287 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
Kevin McKinney69493872013-02-20 23:25:28 -0500288 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
Kevin McKinneydb134a62012-12-20 00:31:30 -0500289 struct bcm_phs_entry sServiceFlow = pstServiceFlowTable->stSFList[i];
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500290 sServiceFlow.pstClassifierTable = kzalloc(sizeof(struct bcm_phs_classifier_table), GFP_KERNEL);
Kevin McKinney69493872013-02-20 23:25:28 -0500291 if (!sServiceFlow.pstClassifierTable) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500292 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
293 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700294 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
295 return -ENOMEM;
296 }
297 }
298
Stephen Hemminger082e8892010-11-01 09:35:21 -0400299 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
Kevin McKinney69493872013-02-20 23:25:28 -0500300 if (pPhsdeviceExtension->CompressedTxBuffer == NULL) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500301 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700302 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
303 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
304 return -ENOMEM;
305 }
306
Kevin McKinney6c259f42013-02-20 23:25:27 -0500307 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
Kevin McKinney69493872013-02-20 23:25:28 -0500308 if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500309 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
Stephen Hemminger082e8892010-11-01 09:35:21 -0400310 kfree(pPhsdeviceExtension->CompressedTxBuffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700311 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
312 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
313 return -ENOMEM;
314 }
315
Kevin McKinney6c259f42013-02-20 23:25:27 -0500316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700317 return STATUS_SUCCESS;
318}
319
Kevin McKinney60dadf92012-12-20 00:31:28 -0500320int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700321{
Kevin McKinney69493872013-02-20 23:25:28 -0500322 if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700323 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
324 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
325 }
326
Stephen Hemminger082e8892010-11-01 09:35:21 -0400327 kfree(pPHSDeviceExt->CompressedTxBuffer);
328 pPHSDeviceExt->CompressedTxBuffer = NULL;
329
330 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
331 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700332
333 return 0;
334}
335
Kevin McKinney14b3a402013-02-20 23:25:29 -0500336/*
337 * PHS functions
338 * PhsUpdateClassifierRule
339 *
340 * Routine Description:
341 * Exported function to add or modify a PHS Rule.
342 *
343 * Arguments:
344 * IN void* pvContext - PHS Driver Specific Context
345 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
346 * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
347 * IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
348 *
349 * Return Value:
350 *
351 * 0 if successful,
352 * >0 Error.
353 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500354ULONG PhsUpdateClassifierRule(IN void *pvContext,
355 IN B_UINT16 uiVcid ,
356 IN B_UINT16 uiClsId ,
357 IN struct bcm_phs_rule *psPhsRule,
358 IN B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700359{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500360 ULONG lStatus = 0;
361 UINT nSFIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500362 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400363 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500364 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700365
Kevin McKinney6c259f42013-02-20 23:25:27 -0500366 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS With Corr2 Changes\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700367
Kevin McKinney69493872013-02-20 23:25:28 -0500368 if (pDeviceExtension == NULL) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500369 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Invalid Device Extension\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700370 return ERR_PHS_INVALID_DEVICE_EXETENSION;
371 }
372
Kevin McKinney6c259f42013-02-20 23:25:27 -0500373 if (u8AssociatedPHSI == 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700374 return ERR_PHS_INVALID_PHS_RULE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700375
376 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700377 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500378 uiVcid, &pstServiceFlowEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700379
Kevin McKinney69493872013-02-20 23:25:28 -0500380 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700381 /* This is a new SF. Create a mapping entry for this */
382 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500383 pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700384 return lStatus;
385 }
386
387 /* SF already Exists Add PHS Rule to existing SF */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500388 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
389 pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700390
Kevin McKinney6c259f42013-02-20 23:25:27 -0500391 return lStatus;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700392}
393
Kevin McKinney14b3a402013-02-20 23:25:29 -0500394/*
395 * PhsDeletePHSRule
396 *
397 * Routine Description:
398 * Deletes the specified phs Rule within Vcid
399 *
400 * Arguments:
401 * IN void* pvContext - PHS Driver Specific Context
402 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
403 * IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
404 *
405 * Return Value:
406 *
407 * 0 if successful,
408 * >0 Error.
409 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500410ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700411{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500412 ULONG lStatus = 0;
413 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500414 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500415 struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400416 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500417 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700418
Kevin McKinney6c259f42013-02-20 23:25:27 -0500419 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700420
Kevin McKinney69493872013-02-20 23:25:28 -0500421 if (pDeviceExtension) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500422 /* Retrieve the SFID Entry Index for requested Service Flow */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500423 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700424
Kevin McKinney69493872013-02-20 23:25:28 -0500425 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500426 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700427 return ERR_SF_MATCH_FAIL;
428 }
429
Kevin McKinney6c259f42013-02-20 23:25:27 -0500430 pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
Kevin McKinney69493872013-02-20 23:25:28 -0500431 if (pstClassifierRulesTable) {
432 for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
433 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) {
434 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
435
Kevin McKinney6c259f42013-02-20 23:25:27 -0500436 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400437 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500438
439 if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400440 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500441
Stephen Hemminger082e8892010-11-01 09:35:21 -0400442 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
Kevin McKinney2212e932012-12-20 00:31:32 -0500443 sizeof(struct bcm_phs_classifier_entry));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700444 }
445 }
446 }
447 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700448 }
449 return lStatus;
450}
451
Kevin McKinney14b3a402013-02-20 23:25:29 -0500452/*
453 * PhsDeleteClassifierRule
454 *
455 * Routine Description:
456 * Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
457 *
458 * Arguments:
459 * IN void* pvContext - PHS Driver Specific Context
460 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
461 * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
462 *
463 * Return Value:
464 *
465 * 0 if successful,
466 * >0 Error.
467 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500468ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700469{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500470 ULONG lStatus = 0;
471 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500472 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinney2212e932012-12-20 00:31:32 -0500473 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400474 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500475 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700476
Kevin McKinney69493872013-02-20 23:25:28 -0500477 if (pDeviceExtension) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500478 /* Retrieve the SFID Entry Index for requested Service Flow */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500479 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500480 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500481 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700482 return ERR_SF_MATCH_FAIL;
483 }
484
485 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500486 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500487
488 if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) {
489 if (pstClassifierEntry->pstPhsRule) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500490 if (pstClassifierEntry->pstPhsRule->u8RefCnt)
491 pstClassifierEntry->pstPhsRule->u8RefCnt--;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700492
Kevin McKinney6c259f42013-02-20 23:25:27 -0500493 if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt)
494 kfree(pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700495 }
Kevin McKinney2212e932012-12-20 00:31:32 -0500496 memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700497 }
498
499 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500500 uiClsId, eOldClassifierRuleContext, &pstClassifierEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700501
Kevin McKinney69493872013-02-20 23:25:28 -0500502 if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) {
Stephen Hemminger082e8892010-11-01 09:35:21 -0400503 kfree(pstClassifierEntry->pstPhsRule);
Kevin McKinney2212e932012-12-20 00:31:32 -0500504 memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700505 }
506 }
507 return lStatus;
508}
509
Kevin McKinney14b3a402013-02-20 23:25:29 -0500510/*
511 * PhsDeleteSFRules
512 *
513 * Routine Description:
514 * Exported function to Delete a all PHS Rules for the SFID.
515 *
516 * Arguments:
517 * IN void* pvContext - PHS Driver Specific Context
518 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
519 *
520 * Return Value:
521 *
522 * 0 if successful,
523 * >0 Error.
524 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500525ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700526{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500527 ULONG lStatus = 0;
528 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500529 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500530 struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400531 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500532 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700533
Kevin McKinney6c259f42013-02-20 23:25:27 -0500534 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "====>\n");
535
Kevin McKinney69493872013-02-20 23:25:28 -0500536 if (pDeviceExtension) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500537 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700538 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500539 uiVcid, &pstServiceFlowEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500540 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500541 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700542 return ERR_SF_MATCH_FAIL;
543 }
544
Kevin McKinney6c259f42013-02-20 23:25:27 -0500545 pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
Kevin McKinney69493872013-02-20 23:25:28 -0500546 if (pstClassifierRulesTable) {
547 for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
548 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) {
549
Kevin McKinney6c259f42013-02-20 23:25:27 -0500550 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
551 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
552
553 if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400554 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500555
556 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700557 }
Kevin McKinney2212e932012-12-20 00:31:32 -0500558 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
Kevin McKinney69493872013-02-20 23:25:28 -0500559 if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) {
560
Kevin McKinney6c259f42013-02-20 23:25:27 -0500561 if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
562 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
563
564 if (0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
565 kfree(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule);
566
567 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700568 }
Kevin McKinney2212e932012-12-20 00:31:32 -0500569 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700570 }
571 }
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700572 pstServiceFlowEntry->bUsed = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700573 pstServiceFlowEntry->uiVcid = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700574 }
575
576 return lStatus;
577}
578
Kevin McKinney14b3a402013-02-20 23:25:29 -0500579/*
580 * PhsCompress
581 *
582 * Routine Description:
583 * Exported function to compress the data using PHS.
584 *
585 * Arguments:
586 * IN void* pvContext - PHS Driver Specific Context.
587 * IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
588 * IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
589 * IN void *pvInputBuffer - The Input buffer containg packet header data
590 * IN void *pvOutputBuffer - The output buffer returned by this function after PHS
591 * IN UINT *pOldHeaderSize - The actual size of the header before PHS
592 * IN UINT *pNewHeaderSize - The new size of the header after applying PHS
593 *
594 * Return Value:
595 *
596 * 0 if successful,
597 * >0 Error.
598 */
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700599static ULONG PhsCompress(IN void *pvContext,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500600 IN B_UINT16 uiVcid,
601 IN B_UINT16 uiClsId,
602 IN void *pvInputBuffer,
603 OUT void *pvOutputBuffer,
604 OUT UINT *pOldHeaderSize,
605 OUT UINT *pNewHeaderSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700606{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500607 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500608 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinney2212e932012-12-20 00:31:32 -0500609 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
Kevin McKinneya903d652012-12-20 00:31:34 -0500610 struct bcm_phs_rule *pstPhsRule = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500611 ULONG lStatus = 0;
Kevin McKinney29794602012-05-26 12:05:12 -0400612 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500613 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700614
Kevin McKinney69493872013-02-20 23:25:28 -0500615 if (pDeviceExtension == NULL) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500616 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Invalid Device Extension\n");
617 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700618 return lStatus;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700619 }
620
Kevin McKinney6c259f42013-02-20 23:25:27 -0500621 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Suppressing header\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700622
Kevin McKinney14b3a402013-02-20 23:25:29 -0500623 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700624 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500625 uiVcid, &pstServiceFlowEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500626 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500627 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "SFID Match Failed\n");
628 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700629 return lStatus;
630 }
631
632 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500633 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700634
Kevin McKinney69493872013-02-20 23:25:28 -0500635 if (nClsidIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500636 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "No PHS Rule Defined For Classifier\n");
637 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700638 return lStatus;
639 }
640
Kevin McKinney14b3a402013-02-20 23:25:29 -0500641 /* get rule from SF id,Cls ID pair and proceed */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500642 pstPhsRule = pstClassifierEntry->pstPhsRule;
Kevin McKinney69493872013-02-20 23:25:28 -0500643 if (!ValidatePHSRuleComplete(pstPhsRule)) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500644 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS Rule Defined For Classifier But Not Complete\n");
645 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700646 return lStatus;
647 }
648
Kevin McKinney14b3a402013-02-20 23:25:29 -0500649 /* Compress Packet */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500650 lStatus = phs_compress(pstPhsRule, (PUCHAR)pvInputBuffer,
651 (PUCHAR)pvOutputBuffer, pOldHeaderSize, pNewHeaderSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700652
Kevin McKinney69493872013-02-20 23:25:28 -0500653 if (lStatus == STATUS_PHS_COMPRESSED) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700654 pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
655 pstPhsRule->PHSModifiedNumPackets++;
Kevin McKinney69493872013-02-20 23:25:28 -0500656 } else
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700657 pstPhsRule->PHSErrorNumPackets++;
658
659 return lStatus;
660}
661
Kevin McKinney14b3a402013-02-20 23:25:29 -0500662/*
663 * PhsDeCompress
664 *
665 * Routine Description:
666 * Exported function to restore the packet header in Rx path.
667 *
668 * Arguments:
669 * IN void* pvContext - PHS Driver Specific Context.
670 * IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
671 * IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
672 * OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
673 * OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
674 *
675 * Return Value:
676 *
677 * 0 if successful,
678 * >0 Error.
679 */
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700680static ULONG PhsDeCompress(IN void *pvContext,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500681 IN B_UINT16 uiVcid,
682 IN void *pvInputBuffer,
683 OUT void *pvOutputBuffer,
684 OUT UINT *pInHeaderSize,
685 OUT UINT *pOutHeaderSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700686{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500687 UINT nSFIndex = 0, nPhsRuleIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500688 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinneya903d652012-12-20 00:31:34 -0500689 struct bcm_phs_rule *pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700690 UINT phsi;
Kevin McKinney29794602012-05-26 12:05:12 -0400691 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500692 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700693
694 *pInHeaderSize = 0;
Kevin McKinney69493872013-02-20 23:25:28 -0500695 if (pDeviceExtension == NULL) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500696 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Invalid Device Extension\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700697 return ERR_PHS_INVALID_DEVICE_EXETENSION;
698 }
699
Kevin McKinney6c259f42013-02-20 23:25:27 -0500700 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Restoring header\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700701
702 phsi = *((unsigned char *)(pvInputBuffer));
Kevin McKinney6c259f42013-02-20 23:25:27 -0500703 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "PHSI To Be Used For restore : %x\n", phsi);
704 if (phsi == UNCOMPRESSED_PACKET)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700705 return STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700706
Kevin McKinney14b3a402013-02-20 23:25:29 -0500707 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700708 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500709 uiVcid, &pstServiceFlowEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500710 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500711 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "SFID Match Failed During Lookup\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700712 return ERR_SF_MATCH_FAIL;
713 }
714
Kevin McKinney6c259f42013-02-20 23:25:27 -0500715 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi,
716 eActiveClassifierRuleContext, &pstPhsRule);
Kevin McKinney69493872013-02-20 23:25:28 -0500717 if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500718 /* Phs Rule does not exist in active rules table. Lets try in the old rules table. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700719 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500720 phsi, eOldClassifierRuleContext, &pstPhsRule);
721 if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700722 return ERR_PHSRULE_MATCH_FAIL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700723 }
724
725 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500726 (PUCHAR)pvOutputBuffer, pstPhsRule, pOutHeaderSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700727
728 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
729
730 pstPhsRule->PHSModifiedNumPackets++;
731 return STATUS_PHS_COMPRESSED;
732}
733
Kevin McKinney14b3a402013-02-20 23:25:29 -0500734/*
735 * Procedure: free_phs_serviceflow_rules
736 *
737 * Description: This routine is responsible for freeing memory allocated for PHS rules.
738 *
739 * Arguments:
740 * rules - ptr to S_SERVICEFLOW_TABLE structure.
741 *
742 * Returns:
743 * Does not return any value.
744 */
Kevin McKinneyda4d1502012-12-20 00:31:29 -0500745static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700746{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500747 int i, j;
Kevin McKinney29794602012-05-26 12:05:12 -0400748 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700749
Kevin McKinney6c259f42013-02-20 23:25:27 -0500750 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700751
Kevin McKinney69493872013-02-20 23:25:28 -0500752 if (psServiceFlowRulesTable) {
753 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500754 struct bcm_phs_entry stServiceFlowEntry = psServiceFlowRulesTable->stSFList[i];
755 struct bcm_phs_classifier_table *pstClassifierRulesTable = stServiceFlowEntry.pstClassifierTable;
756
Kevin McKinney69493872013-02-20 23:25:28 -0500757 if (pstClassifierRulesTable) {
758 for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
759 if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) {
760
Kevin McKinney6c259f42013-02-20 23:25:27 -0500761 if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt)
762 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt--;
763
764 if (0 == pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400765 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500766
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700767 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
768 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500769
Kevin McKinney69493872013-02-20 23:25:28 -0500770 if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) {
771
Kevin McKinney6c259f42013-02-20 23:25:27 -0500772 if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt)
773 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt--;
774
775 if (0 == pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400776 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500777
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700778 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
779 }
780 }
Stephen Hemminger082e8892010-11-01 09:35:21 -0400781 kfree(pstClassifierRulesTable);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500782 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700783 }
784 }
785 }
786
Kevin McKinney6c259f42013-02-20 23:25:27 -0500787 kfree(psServiceFlowRulesTable);
788 psServiceFlowRulesTable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700789}
790
Lisa Nguyen3abd6f12013-10-28 01:35:59 -0700791static bool ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700792{
Kevin McKinney69493872013-02-20 23:25:28 -0500793 if (psPhsRule) {
794 if (!psPhsRule->u8PHSI) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500795 /* PHSI is not valid */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700796 return false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700797 }
798
Kevin McKinney69493872013-02-20 23:25:28 -0500799 if (!psPhsRule->u8PHSS) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500800 /* PHSS Is Undefined */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700801 return false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700802 }
803
Kevin McKinney14b3a402013-02-20 23:25:29 -0500804 /* Check if PHSF is defines for the PHS Rule */
805 if (!psPhsRule->u8PHSFLength) /* If any part of PHSF is valid then Rule contains valid PHSF */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700806 return false;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500807
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700808 return TRUE;
Kevin McKinney69493872013-02-20 23:25:28 -0500809 } else
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700810 return false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700811}
812
Kevin McKinneyda4d1502012-12-20 00:31:29 -0500813UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500814 IN B_UINT16 uiVcid,
815 struct bcm_phs_entry **ppstServiceFlowEntry)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700816{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500817 int i;
818
Kevin McKinney69493872013-02-20 23:25:28 -0500819 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
820 if (psServiceFlowTable->stSFList[i].bUsed) {
821 if (psServiceFlowTable->stSFList[i].uiVcid == uiVcid) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700822 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
823 return i;
824 }
825 }
826 }
827
828 *ppstServiceFlowEntry = NULL;
829 return PHS_INVALID_TABLE_INDEX;
830}
831
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700832static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500833 IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext,
834 OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700835{
836 int i;
Kevin McKinney2212e932012-12-20 00:31:32 -0500837 struct bcm_phs_classifier_entry *psClassifierRules = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700838
Kevin McKinney69493872013-02-20 23:25:28 -0500839 for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700840
Kevin McKinney69493872013-02-20 23:25:28 -0500841 if (eClsContext == eActiveClassifierRuleContext)
842 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
843 else
844 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
845
846 if (psClassifierRules->bUsed) {
847 if (psClassifierRules->uiClassifierRuleId == uiClsid) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700848 *ppstClassifierEntry = psClassifierRules;
849 return i;
850 }
851 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700852 }
853
854 *ppstClassifierEntry = NULL;
855 return PHS_INVALID_TABLE_INDEX;
856}
857
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500858static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500859 IN B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext,
860 OUT struct bcm_phs_rule **ppstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700861{
862 int i;
Kevin McKinney2212e932012-12-20 00:31:32 -0500863 struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500864
Kevin McKinney69493872013-02-20 23:25:28 -0500865 for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500866 if (eClsContext == eActiveClassifierRuleContext)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700867 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700868 else
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700869 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
Kevin McKinney6c259f42013-02-20 23:25:27 -0500870
Kevin McKinney69493872013-02-20 23:25:28 -0500871 if (pstClassifierRule->bUsed) {
872 if (pstClassifierRule->u8PHSI == uiPHSI) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700873 *ppstPhsRule = pstClassifierRule->pstPhsRule;
874 return i;
875 }
876 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700877 }
878
879 *ppstPhsRule = NULL;
880 return PHS_INVALID_TABLE_INDEX;
881}
882
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700883static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500884 IN struct bcm_phs_table *psServiceFlowTable,
885 struct bcm_phs_rule *psPhsRule,
886 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700887{
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500888 struct bcm_phs_classifier_table *psaClassifiertable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700889 UINT uiStatus = 0;
890 int iSfIndex;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700891 bool bFreeEntryFound = false;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500892
Kevin McKinney14b3a402013-02-20 23:25:29 -0500893 /* Check for a free entry in SFID table */
Kevin McKinney69493872013-02-20 23:25:28 -0500894 for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) {
895 if (!psServiceFlowTable->stSFList[iSfIndex].bUsed) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700896 bFreeEntryFound = TRUE;
897 break;
898 }
899 }
900
Kevin McKinney6c259f42013-02-20 23:25:27 -0500901 if (!bFreeEntryFound)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700902 return ERR_SFTABLE_FULL;
903
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700904 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500905 uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule,
906 eActiveClassifierRuleContext, u8AssociatedPHSI);
Kevin McKinney69493872013-02-20 23:25:28 -0500907 if (uiStatus == PHS_SUCCESS) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500908 /* Add entry at free index to the SF */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700909 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
910 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
911 }
912
913 return uiStatus;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700914}
915
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700916static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500917 IN B_UINT16 uiClsId,
918 IN struct bcm_phs_entry *pstServiceFlowEntry,
919 struct bcm_phs_rule *psPhsRule,
920 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700921{
Kevin McKinney2212e932012-12-20 00:31:32 -0500922 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500923 UINT uiStatus = PHS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700924 UINT nClassifierIndex = 0;
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500925 struct bcm_phs_classifier_table *psaClassifiertable = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400926 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700927
Kevin McKinney6c259f42013-02-20 23:25:27 -0500928 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
929
930 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700931
932 /* Check if the supplied Classifier already exists */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500933 nClassifierIndex = GetClassifierEntry(
934 pstServiceFlowEntry->pstClassifierTable,
935 uiClsId,
936 eActiveClassifierRuleContext,
937 &pstClassifierEntry);
938
Kevin McKinney69493872013-02-20 23:25:28 -0500939 if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700940 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -0500941 * The Classifier doesn't exist. So its a new classifier being added.
942 * Add new entry to associate PHS Rule to the Classifier
943 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700944
Kevin McKinney6c259f42013-02-20 23:25:27 -0500945 uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable,
946 psPhsRule,
947 eActiveClassifierRuleContext,
948 u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700949 return uiStatus;
950 }
951
952 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -0500953 * The Classifier exists.The PHS Rule for this classifier
954 * is being modified
955 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500956
Kevin McKinney69493872013-02-20 23:25:28 -0500957 if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500958 if (pstClassifierEntry->pstPhsRule == NULL)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700959 return ERR_PHS_INVALID_PHS_RULE;
960
961 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -0500962 * This rule already exists if any fields are changed for this PHS
963 * rule update them.
964 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500965 /* If any part of PHSF is valid then we update PHSF */
Kevin McKinney69493872013-02-20 23:25:28 -0500966 if (psPhsRule->u8PHSFLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500967 /* update PHSF */
Stephen Hemminger082e8892010-11-01 09:35:21 -0400968 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500969 psPhsRule->u8PHSF, MAX_PHS_LENGTHS);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700970 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500971
Kevin McKinney69493872013-02-20 23:25:28 -0500972 if (psPhsRule->u8PHSFLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500973 /* update PHSFLen */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500974 pstClassifierEntry->pstPhsRule->u8PHSFLength = psPhsRule->u8PHSFLength;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700975 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500976
Kevin McKinney69493872013-02-20 23:25:28 -0500977 if (psPhsRule->u8PHSMLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500978 /* update PHSM */
Stephen Hemminger082e8892010-11-01 09:35:21 -0400979 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500980 psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700981 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500982
Kevin McKinney69493872013-02-20 23:25:28 -0500983 if (psPhsRule->u8PHSMLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500984 /* update PHSM Len */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700985 pstClassifierEntry->pstPhsRule->u8PHSMLength =
Kevin McKinney6c259f42013-02-20 23:25:27 -0500986 psPhsRule->u8PHSMLength;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700987 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500988
Kevin McKinney69493872013-02-20 23:25:28 -0500989 if (psPhsRule->u8PHSS) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500990 /* update PHSS */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700991 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
992 }
993
Kevin McKinney14b3a402013-02-20 23:25:29 -0500994 /* update PHSV */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700995 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
Kevin McKinney69493872013-02-20 23:25:28 -0500996 } else {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500997 /* A new rule is being set for this classifier. */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500998 uiStatus = UpdateClassifierPHSRule(uiClsId, pstClassifierEntry,
999 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001000 }
1001
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001002 return uiStatus;
1003}
1004
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001005static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
Kevin McKinney6c259f42013-02-20 23:25:27 -05001006 struct bcm_phs_classifier_table *psaClassifiertable,
1007 struct bcm_phs_rule *psPhsRule,
1008 enum bcm_phs_classifier_context eClsContext,
1009 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001010{
1011 UINT iClassifierIndex = 0;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001012 bool bFreeEntryFound = false;
Kevin McKinney2212e932012-12-20 00:31:32 -05001013 struct bcm_phs_classifier_entry *psClassifierRules = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001014 UINT nStatus = PHS_SUCCESS;
Kevin McKinney29794602012-05-26 12:05:12 -04001015 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001016
1017 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Inside CreateClassifierPHSRule");
1018
1019 if (psaClassifiertable == NULL)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001020 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001021
Kevin McKinney69493872013-02-20 23:25:28 -05001022 if (eClsContext == eOldClassifierRuleContext) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001023 /*
1024 * If An Old Entry for this classifier ID already exists in the
1025 * old rules table replace it.
1026 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001027
1028 iClassifierIndex =
Kevin McKinney6c259f42013-02-20 23:25:27 -05001029 GetClassifierEntry(psaClassifiertable, uiClsId,
1030 eClsContext, &psClassifierRules);
1031
Kevin McKinney69493872013-02-20 23:25:28 -05001032 if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001033 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -05001034 * The Classifier already exists in the old rules table
1035 * Lets replace the old classifier with the new one.
1036 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001037 bFreeEntryFound = TRUE;
1038 }
1039 }
1040
Kevin McKinney69493872013-02-20 23:25:28 -05001041 if (!bFreeEntryFound) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001042 /* Continue to search for a free location to add the rule */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001043 for (iClassifierIndex = 0; iClassifierIndex <
Kevin McKinney69493872013-02-20 23:25:28 -05001044 MAX_PHSRULE_PER_SF; iClassifierIndex++) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001045 if (eClsContext == eActiveClassifierRuleContext)
Kevin McKinney6c259f42013-02-20 23:25:27 -05001046 psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001047 else
Kevin McKinney6c259f42013-02-20 23:25:27 -05001048 psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001049
Kevin McKinney69493872013-02-20 23:25:28 -05001050 if (!psClassifierRules->bUsed) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001051 bFreeEntryFound = TRUE;
1052 break;
1053 }
1054 }
1055 }
1056
Kevin McKinney69493872013-02-20 23:25:28 -05001057 if (!bFreeEntryFound) {
1058
Kevin McKinney6c259f42013-02-20 23:25:27 -05001059 if (eClsContext == eActiveClassifierRuleContext)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001060 return ERR_CLSASSIFIER_TABLE_FULL;
Kevin McKinney69493872013-02-20 23:25:28 -05001061 else {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001062 /* Lets replace the oldest rule if we are looking in old Rule table */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001063 if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF)
Kevin McKinney6c259f42013-02-20 23:25:27 -05001064 psaClassifiertable->uiOldestPhsRuleIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001065
1066 iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001067 psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001068
Kevin McKinney6c259f42013-02-20 23:25:27 -05001069 (psaClassifiertable->uiOldestPhsRuleIndex)++;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001070 }
1071 }
1072
Kevin McKinney69493872013-02-20 23:25:28 -05001073 if (eClsContext == eOldClassifierRuleContext) {
1074
1075 if (psClassifierRules->pstPhsRule == NULL) {
1076
Kevin McKinney6c259f42013-02-20 23:25:27 -05001077 psClassifierRules->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001078
Kevin McKinney6c259f42013-02-20 23:25:27 -05001079 if (NULL == psClassifierRules->pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001080 return ERR_PHSRULE_MEMALLOC_FAIL;
1081 }
1082
1083 psClassifierRules->bUsed = TRUE;
1084 psClassifierRules->uiClassifierRuleId = uiClsId;
1085 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
1086 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
1087
Kevin McKinney6c259f42013-02-20 23:25:27 -05001088 /* Update The PHS rule */
1089 memcpy(psClassifierRules->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule));
Kevin McKinney69493872013-02-20 23:25:28 -05001090 } else
Kevin McKinney6c259f42013-02-20 23:25:27 -05001091 nStatus = UpdateClassifierPHSRule(uiClsId, psClassifierRules,
1092 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001093
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001094 return nStatus;
1095}
1096
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001097static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
Kevin McKinney6c259f42013-02-20 23:25:27 -05001098 IN struct bcm_phs_classifier_entry *pstClassifierEntry,
1099 struct bcm_phs_classifier_table *psaClassifiertable,
1100 struct bcm_phs_rule *psPhsRule,
1101 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001102{
Kevin McKinneya903d652012-12-20 00:31:34 -05001103 struct bcm_phs_rule *pstAddPhsRule = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001104 UINT nPhsRuleIndex = 0;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001105 bool bPHSRuleOrphaned = false;
Kevin McKinney29794602012-05-26 12:05:12 -04001106 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001107
1108 psPhsRule->u8RefCnt = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001109
Kevin McKinney14b3a402013-02-20 23:25:29 -05001110 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001111 bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable,
1112 pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001113
Kevin McKinney14b3a402013-02-20 23:25:29 -05001114 /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001115 nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI,
1116 eActiveClassifierRuleContext, &pstAddPhsRule);
Kevin McKinney69493872013-02-20 23:25:28 -05001117 if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) {
1118
Kevin McKinney6c259f42013-02-20 23:25:27 -05001119 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001120
Kevin McKinney69493872013-02-20 23:25:28 -05001121 if (psPhsRule->u8PHSI == 0) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001122 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001123 return ERR_PHS_INVALID_PHS_RULE;
1124 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001125
Kevin McKinney14b3a402013-02-20 23:25:29 -05001126 /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001127 if (false == bPHSRuleOrphaned) {
Kevin McKinney69493872013-02-20 23:25:28 -05001128
Kevin McKinneya903d652012-12-20 00:31:34 -05001129 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001130 if (NULL == pstClassifierEntry->pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001131 return ERR_PHSRULE_MEMALLOC_FAIL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001132 }
Kevin McKinneya903d652012-12-20 00:31:34 -05001133 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule));
Kevin McKinney69493872013-02-20 23:25:28 -05001134 } else {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001135 /* Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001136 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
Kevin McKinney69493872013-02-20 23:25:28 -05001137 if (bPHSRuleOrphaned) {
Stephen Hemminger082e8892010-11-01 09:35:21 -04001138 kfree(pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001139 pstClassifierEntry->pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001140 }
1141 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001142 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001143
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001144 pstClassifierEntry->bUsed = TRUE;
1145 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1146 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1147 pstClassifierEntry->pstPhsRule->u8RefCnt++;
1148 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
1149
1150 return PHS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001151}
1152
Lisa Nguyen3abd6f12013-10-28 01:35:59 -07001153static bool DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001154{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001155 if (pstPhsRule == NULL)
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001156 return false;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001157
1158 if (pstPhsRule->u8RefCnt)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001159 pstPhsRule->u8RefCnt--;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001160
Kevin McKinney69493872013-02-20 23:25:28 -05001161 if (0 == pstPhsRule->u8RefCnt) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001162 /*
1163 * if(pstPhsRule->u8PHSI)
1164 * Store the currently active rule into the old rules list
1165 * CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);
1166 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001167 return TRUE;
Kevin McKinney69493872013-02-20 23:25:28 -05001168 } else
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001169 return false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001170}
1171
Kevin McKinney60dadf92012-12-20 00:31:28 -05001172void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001173{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001174 int i, j, k, l;
Kevin McKinney29794602012-05-26 12:05:12 -04001175 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001176
1177 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules :\n");
1178
Kevin McKinney69493872013-02-20 23:25:28 -05001179 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
1180
Kevin McKinneydb134a62012-12-20 00:31:30 -05001181 struct bcm_phs_entry stServFlowEntry =
Kevin McKinney6c259f42013-02-20 23:25:27 -05001182 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
Kevin McKinney69493872013-02-20 23:25:28 -05001183 if (stServFlowEntry.bUsed) {
1184
1185 for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
1186
1187 for (l = 0; l < 2; l++) {
Kevin McKinney2212e932012-12-20 00:31:32 -05001188 struct bcm_phs_classifier_entry stClsEntry;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001189
Kevin McKinney69493872013-02-20 23:25:28 -05001190 if (l == 0) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001191 stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
Kevin McKinney6c259f42013-02-20 23:25:27 -05001192 if (stClsEntry.bUsed)
1193 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule :\n");
Kevin McKinney69493872013-02-20 23:25:28 -05001194 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001195 stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
Kevin McKinney6c259f42013-02-20 23:25:27 -05001196 if (stClsEntry.bUsed)
1197 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule :\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001198 }
Kevin McKinney69493872013-02-20 23:25:28 -05001199
1200 if (stClsEntry.bUsed) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001201 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", stServFlowEntry.uiVcid);
1202 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", stClsEntry.uiClassifierRuleId);
1203 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", stClsEntry.u8PHSI);
1204 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
1205 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", stClsEntry.pstPhsRule->u8PHSI);
1206 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", stClsEntry.pstPhsRule->u8PHSFLength);
1207 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001208
Kevin McKinney6c259f42013-02-20 23:25:27 -05001209 for (k = 0 ; k < stClsEntry.pstPhsRule->u8PHSFLength; k++)
Kevin McKinney6c259f42013-02-20 23:25:27 -05001210 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSF[k]);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001211 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", stClsEntry.pstPhsRule->u8PHSMLength);
1212 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
1213
1214 for (k = 0; k < stClsEntry.pstPhsRule->u8PHSMLength; k++)
Kevin McKinney6c259f42013-02-20 23:25:27 -05001215 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSM[k]);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001216 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", stClsEntry.pstPhsRule->u8PHSS);
1217 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", stClsEntry.pstPhsRule->u8PHSV);
1218 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001219 }
1220 }
1221 }
1222 }
1223 }
1224}
1225
Kevin McKinney14b3a402013-02-20 23:25:29 -05001226/*
1227 * Procedure: phs_decompress
1228 *
1229 * Description: This routine restores the static fields within the packet.
1230 *
1231 * Arguments:
1232 * in_buf - ptr to incoming packet buffer.
1233 * out_buf - ptr to output buffer where the suppressed header is copied.
1234 * decomp_phs_rules - ptr to PHS rule.
1235 * header_size - ptr to field which holds the phss or phsf_length.
1236 *
1237 * Returns:
1238 * size -The number of bytes of dynamic fields present with in the incoming packet
1239 * header.
1240 * 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
1241 */
Shalin Mehtaf2be6352013-09-17 00:42:17 -07001242static int phs_decompress(unsigned char *in_buf,
Kevin McKinney6c259f42013-02-20 23:25:27 -05001243 unsigned char *out_buf,
1244 struct bcm_phs_rule *decomp_phs_rules,
1245 UINT *header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001246{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001247 int phss, size = 0;
Kevin McKinneya903d652012-12-20 00:31:34 -05001248 struct bcm_phs_rule *tmp_memb;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001249 int bit, i = 0;
1250 unsigned char *phsf, *phsm;
1251 int in_buf_len = *header_size - 1;
Kevin McKinney29794602012-05-26 12:05:12 -04001252 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001253
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001254 in_buf++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001255
1256 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "====>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001257 *header_size = 0;
1258
Kevin McKinney6c259f42013-02-20 23:25:27 -05001259 if ((decomp_phs_rules == NULL))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001260 return 0;
1261
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001262 tmp_memb = decomp_phs_rules;
Kevin McKinney14b3a402013-02-20 23:25:29 -05001263 /*
1264 * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
1265 * header_size = tmp_memb->u8PHSFLength;
1266 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001267 phss = tmp_memb->u8PHSS;
1268 phsf = tmp_memb->u8PHSF;
1269 phsm = tmp_memb->u8PHSM;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001270
Kevin McKinney6c259f42013-02-20 23:25:27 -05001271 if (phss > MAX_PHS_LENGTHS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001272 phss = MAX_PHS_LENGTHS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001273
Kevin McKinney14b3a402013-02-20 23:25:29 -05001274 /*
1275 * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:
1276 * In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
1277 */
Kevin McKinney69493872013-02-20 23:25:28 -05001278 while ((phss > 0) && (size < in_buf_len)) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001279 bit = ((*phsm << i) & SUPPRESS);
1280
Kevin McKinney69493872013-02-20 23:25:28 -05001281 if (bit == SUPPRESS) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001282 *out_buf = *phsf;
Masanari Iida276d30e2014-01-11 11:26:27 +09001283 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d phsf %d output %d",
Kevin McKinney6c259f42013-02-20 23:25:27 -05001284 phss, *phsf, *out_buf);
Kevin McKinney69493872013-02-20 23:25:28 -05001285 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001286 *out_buf = *in_buf;
Masanari Iida276d30e2014-01-11 11:26:27 +09001287 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d input %d output %d",
Kevin McKinney6c259f42013-02-20 23:25:27 -05001288 phss, *in_buf, *out_buf);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001289 in_buf++;
1290 size++;
1291 }
1292 out_buf++;
1293 phsf++;
1294 phss--;
1295 i++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001296 *header_size = *header_size + 1;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001297
Kevin McKinney69493872013-02-20 23:25:28 -05001298 if (i > MAX_NO_BIT) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001299 i = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001300 phsm++;
1301 }
1302 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001303
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001304 return size;
1305}
1306
Kevin McKinney14b3a402013-02-20 23:25:29 -05001307/*
1308 * Procedure: phs_compress
1309 *
1310 * Description: This routine suppresses the static fields within the packet.Before
1311 * that it will verify the fields to be suppressed with the corresponding fields in the
1312 * phsf. For verification it checks the phsv field of PHS rule. If set and verification
1313 * succeeds it suppresses the field.If any one static field is found different none of
1314 * the static fields are suppressed then the packet is sent as uncompressed packet with
1315 * phsi=0.
1316 *
1317 * Arguments:
1318 * phs_rule - ptr to PHS rule.
1319 * in_buf - ptr to incoming packet buffer.
1320 * out_buf - ptr to output buffer where the suppressed header is copied.
1321 * header_size - ptr to field which holds the phss.
1322 *
1323 * Returns:
1324 * size-The number of bytes copied into the output buffer i.e dynamic fields
1325 * 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
1326 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001327static int phs_compress(struct bcm_phs_rule *phs_rule,
1328 unsigned char *in_buf,
1329 unsigned char *out_buf,
1330 UINT *header_size,
1331 UINT *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001332{
1333 unsigned char *old_addr = out_buf;
Peter Meerwaldb38e2742012-06-13 20:44:35 +02001334 int suppress = 0;
Kevin McKinney29794602012-05-26 12:05:12 -04001335 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001336
Kevin McKinney69493872013-02-20 23:25:28 -05001337 if (phs_rule == NULL) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001338 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nphs_compress(): phs_rule null!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001339 *out_buf = ZERO_PHSI;
1340 return STATUS_PHS_NOCOMPRESSION;
1341 }
1342
Kevin McKinney6c259f42013-02-20 23:25:27 -05001343 if (phs_rule->u8PHSS <= *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001344 *header_size = phs_rule->u8PHSS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001345 else
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001346 *header_size = *new_header_size;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001347
Kevin McKinney14b3a402013-02-20 23:25:29 -05001348 /* To copy PHSI */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001349 out_buf++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001350 suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF,
1351 phs_rule->u8PHSM, phs_rule->u8PHSS,
1352 phs_rule->u8PHSV, new_header_size);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001353
Kevin McKinney69493872013-02-20 23:25:28 -05001354 if (suppress == STATUS_PHS_COMPRESSED) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001355 *old_addr = (unsigned char)phs_rule->u8PHSI;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001356 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress phsi %d", phs_rule->u8PHSI);
Kevin McKinney69493872013-02-20 23:25:28 -05001357 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001358 *old_addr = ZERO_PHSI;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001359 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress PHSV Verification failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001360 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001361
Peter Meerwaldb38e2742012-06-13 20:44:35 +02001362 return suppress;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001363}
1364
Kevin McKinney14b3a402013-02-20 23:25:29 -05001365/*
1366 * Procedure: verify_suppress_phsf
1367 *
1368 * Description: This routine verifies the fields of the packet and if all the
1369 * static fields are equal it adds the phsi of that PHS rule.If any static
1370 * field differs it woun't suppress any field.
1371 *
1372 * Arguments:
1373 * rules_set - ptr to classifier_rules.
1374 * in_buffer - ptr to incoming packet buffer.
1375 * out_buffer - ptr to output buffer where the suppressed header is copied.
1376 * phsf - ptr to phsf.
1377 * phsm - ptr to phsm.
1378 * phss - variable holding phss.
1379 *
1380 * Returns:
1381 * size-The number of bytes copied into the output buffer i.e dynamic fields.
1382 * 0 -Packet has failed the verification.
1383 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001384static int verify_suppress_phsf(unsigned char *in_buffer,
1385 unsigned char *out_buffer,
1386 unsigned char *phsf,
1387 unsigned char *phsm,
1388 unsigned int phss,
1389 unsigned int phsv,
1390 UINT *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001391{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001392 unsigned int size = 0;
1393 int bit, i = 0;
Kevin McKinney29794602012-05-26 12:05:12 -04001394 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001395
Kevin McKinney6c259f42013-02-20 23:25:27 -05001396 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001397
Kevin McKinney6c259f42013-02-20 23:25:27 -05001398 if (phss > (*new_header_size))
Kevin McKinney6c259f42013-02-20 23:25:27 -05001399 phss = *new_header_size;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001400
Kevin McKinney69493872013-02-20 23:25:28 -05001401 while (phss > 0) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001402 bit = ((*phsm << i) & SUPPRESS);
Kevin McKinney69493872013-02-20 23:25:28 -05001403 if (bit == SUPPRESS) {
1404 if (*in_buffer != *phsf) {
1405 if (phsv == VERIFY) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001406 BCM_DEBUG_PRINT(Adapter,
1407 DBG_TYPE_OTHERS,
1408 PHS_SEND,
1409 DBG_LVL_ALL,
1410 "\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",
1411 phss,
1412 *in_buffer,
1413 *phsf);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001414 return STATUS_PHS_NOCOMPRESSION;
1415 }
Kevin McKinney69493872013-02-20 23:25:28 -05001416 } else
Kevin McKinney6c259f42013-02-20 23:25:27 -05001417 BCM_DEBUG_PRINT(Adapter,
1418 DBG_TYPE_OTHERS,
1419 PHS_SEND,
1420 DBG_LVL_ALL,
1421 "\nCOMP:In verify_phsf success for field %d buf %d phsf %d",
1422 phss,
1423 *in_buffer,
1424 *phsf);
Kevin McKinney69493872013-02-20 23:25:28 -05001425 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001426 *out_buffer = *in_buffer;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001427 BCM_DEBUG_PRINT(Adapter,
1428 DBG_TYPE_OTHERS,
1429 PHS_SEND,
1430 DBG_LVL_ALL,
1431 "\nCOMP:In copying_header input %d out %d",
1432 *in_buffer,
1433 *out_buffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001434 out_buffer++;
1435 size++;
1436 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001437
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001438 in_buffer++;
1439 phsf++;
1440 phss--;
1441 i++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001442
Kevin McKinney69493872013-02-20 23:25:28 -05001443 if (i > MAX_NO_BIT) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001444 i = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001445 phsm++;
1446 }
1447 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001448 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf success");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001449 *new_header_size = size;
1450 return STATUS_PHS_COMPRESSED;
1451}