blob: 5f4e503d54ec514b38a3effd7cde29fcd4bf75ba [file] [log] [blame]
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001#include "headers.h"
2
Matthias Beyerca89a292014-07-15 09:42:54 +02003static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,
4 B_UINT16 uiClsId,
5 struct bcm_phs_table *psServiceFlowTable,
6 struct bcm_phs_rule *psPhsRule,
7 B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04008
Matthias Beyerca89a292014-07-15 09:42:54 +02009static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,
10 B_UINT16 uiClsId,
11 struct bcm_phs_entry *pstServiceFlowEntry,
12 struct bcm_phs_rule *psPhsRule,
13 B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040014
Matthias Beyerca89a292014-07-15 09:42:54 +020015static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,
16 struct bcm_phs_classifier_table *psaClassifiertable,
17 struct bcm_phs_rule *psPhsRule,
18 enum bcm_phs_classifier_context eClsContext,
19 B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040020
Matthias Beyerca89a292014-07-15 09:42:54 +020021static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,
22 struct bcm_phs_classifier_entry *pstClassifierEntry,
23 struct bcm_phs_classifier_table *psaClassifiertable,
24 struct bcm_phs_rule *psPhsRule,
25 B_UINT8 u8AssociatedPHSI);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040026
Matthias Beyer14d8e912014-07-15 09:43:08 +020027static bool ValidatePHSRuleComplete(const struct bcm_phs_rule *psPhsRule);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040028
Matthias Beyerca89a292014-07-15 09:42:54 +020029static bool DerefPhsRule(B_UINT16 uiClsId,
30 struct bcm_phs_classifier_table *psaClassifiertable,
31 struct bcm_phs_rule *pstPhsRule);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040032
Matthias Beyerca89a292014-07-15 09:42:54 +020033static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable,
34 B_UINT32 uiClsid,
35 enum bcm_phs_classifier_context eClsContext,
36 struct bcm_phs_classifier_entry **ppstClassifierEntry);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040037
Matthias Beyerca89a292014-07-15 09:42:54 +020038static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable,
39 B_UINT32 uiPHSI,
40 enum bcm_phs_classifier_context eClsContext,
41 struct bcm_phs_rule **ppstPhsRule);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040042
Kevin McKinneyda4d1502012-12-20 00:31:29 -050043static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040044
Matthias Beyerca89a292014-07-15 09:42:54 +020045static int phs_compress(struct bcm_phs_rule *phs_members,
46 unsigned char *in_buf,
47 unsigned char *out_buf,
48 unsigned int *header_size,
49 UINT *new_header_size);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040050
Matthias Beyerca89a292014-07-15 09:42:54 +020051static int verify_suppress_phsf(unsigned char *in_buffer,
52 unsigned char *out_buffer,
53 unsigned char *phsf,
54 unsigned char *phsm,
55 unsigned int phss,
56 unsigned int phsv,
57 UINT *new_header_size);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040058
Matthias Beyerca89a292014-07-15 09:42:54 +020059static int phs_decompress(unsigned char *in_buf,
60 unsigned char *out_buf,
61 struct bcm_phs_rule *phs_rules,
62 UINT *header_size);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040063
Kevin McKinney6c259f42013-02-20 23:25:27 -050064static ULONG PhsCompress(void *pvContext,
Matthias Beyerca89a292014-07-15 09:42:54 +020065 B_UINT16 uiVcid,
66 B_UINT16 uiClsId,
67 void *pvInputBuffer,
68 void *pvOutputBuffer,
69 UINT *pOldHeaderSize,
70 UINT *pNewHeaderSize);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040071
Kevin McKinney6c259f42013-02-20 23:25:27 -050072static ULONG PhsDeCompress(void *pvContext,
Matthias Beyerca89a292014-07-15 09:42:54 +020073 B_UINT16 uiVcid,
74 void *pvInputBuffer,
75 void *pvOutputBuffer,
76 UINT *pInHeaderSize,
77 UINT *pOutHeaderSize);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -040078
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070079#define IN
80#define OUT
81
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070082/*
Kevin McKinney14b3a402013-02-20 23:25:29 -050083 * Function: PHSTransmit
84 * Description: This routine handle PHS(Payload Header Suppression for Tx path.
85 * It extracts a fragment of the NDIS_PACKET containing the header
86 * to be suppressed. It then suppresses the header by invoking PHS exported compress routine.
87 * The header data after suppression is copied back to the NDIS_PACKET.
88 *
89 * Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
90 * IN Packet - NDIS packet containing data to be transmitted
91 * IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to
92 * identify PHS rule to be applied.
93 * B_UINT16 uiClassifierRuleID - Classifier Rule ID
94 * BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
95 *
96 * Return: STATUS_SUCCESS - If the send was successful.
97 * Other - If an error occurred.
98 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070099
Kevin McKinney29794602012-05-26 12:05:12 -0400100int PHSTransmit(struct bcm_mini_adapter *Adapter,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500101 struct sk_buff **pPacket,
102 USHORT Vcid,
103 B_UINT16 uiClassifierRuleID,
Lisa Nguyen3abd6f12013-10-28 01:35:59 -0700104 bool bHeaderSuppressionEnabled,
Kevin McKinney6c259f42013-02-20 23:25:27 -0500105 UINT *PacketLen,
106 UCHAR bEthCSSupport)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700107{
Kevin McKinney14b3a402013-02-20 23:25:29 -0500108 /* PHS Sepcific */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500109 UINT unPHSPktHdrBytesCopied = 0;
110 UINT unPhsOldHdrSize = 0;
111 UINT unPHSNewPktHeaderLen = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700112 /* Pointer to PHS IN Hdr Buffer */
Matthias Beyere86bd612014-07-15 09:43:15 +0200113 PUCHAR pucPHSPktHdrInBuf =
114 Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700115 /* Pointer to PHS OUT Hdr Buffer */
Matthias Beyere86bd612014-07-15 09:43:15 +0200116 PUCHAR pucPHSPktHdrOutBuf =
117 Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500118 UINT usPacketType;
119 UINT BytesToRemove = 0;
Lisa Nguyen3abd6f12013-10-28 01:35:59 -0700120 bool bPHSI = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700121 LONG ulPhsStatus = 0;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500122 UINT numBytesCompressed = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700123 struct sk_buff *newPacket = NULL;
124 struct sk_buff *Packet = *pPacket;
125
Matthias Beyerca89a292014-07-15 09:42:54 +0200126 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
127 "In PHSTransmit");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700128
Kevin McKinney6c259f42013-02-20 23:25:27 -0500129 if (!bEthCSSupport)
130 BytesToRemove = ETH_HLEN;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700131 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -0500132 * Accumulate the header upto the size we support suppression
133 * from NDIS packet
134 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700135
Kevin McKinney6c259f42013-02-20 23:25:27 -0500136 usPacketType = ((struct ethhdr *)(Packet->data))->h_proto;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700137
138 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
Kevin McKinney14b3a402013-02-20 23:25:29 -0500139 /* considering data after ethernet header */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500140 if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700141 unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700142 else
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700143 unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700144
Kevin McKinney6c259f42013-02-20 23:25:27 -0500145 if ((unPHSPktHdrBytesCopied > 0) &&
Kevin McKinney69493872013-02-20 23:25:28 -0500146 (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) {
147
Kevin McKinney14b3a402013-02-20 23:25:29 -0500148 /*
Matthias Beyere86bd612014-07-15 09:43:15 +0200149 * Step 2 Suppress Header using PHS and fill into intermediate
150 * ucaPHSPktHdrOutBuf.
151 * Suppress only if IP Header and PHS Enabled For the
152 * Service Flow
Kevin McKinney14b3a402013-02-20 23:25:29 -0500153 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500154 if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
155 (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
Kevin McKinney69493872013-02-20 23:25:28 -0500156 (bHeaderSuppressionEnabled)) {
157
Matthias Beyerca89a292014-07-15 09:42:54 +0200158 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND,
159 DBG_LVL_ALL,
160 "\nTrying to PHS Compress Using Classifier rule 0x%X",
161 uiClassifierRuleID);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500162 unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
163 ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
Matthias Beyerca89a292014-07-15 09:42:54 +0200164 Vcid,
165 uiClassifierRuleID,
166 pucPHSPktHdrInBuf,
167 pucPHSPktHdrOutBuf,
168 &unPhsOldHdrSize,
169 &unPHSNewPktHeaderLen);
170 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND,
171 DBG_LVL_ALL,
172 "\nPHS Old header Size : %d New Header Size %d\n",
173 unPhsOldHdrSize, unPHSNewPktHeaderLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700174
Kevin McKinney69493872013-02-20 23:25:28 -0500175 if (unPHSNewPktHeaderLen == unPhsOldHdrSize) {
176
Kevin McKinney6c259f42013-02-20 23:25:27 -0500177 if (ulPhsStatus == STATUS_PHS_COMPRESSED)
178 bPHSI = *pucPHSPktHdrOutBuf;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700179
Kevin McKinney6c259f42013-02-20 23:25:27 -0500180 ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
181 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700182
Kevin McKinney69493872013-02-20 23:25:28 -0500183 if (ulPhsStatus == STATUS_PHS_COMPRESSED) {
184
Matthias Beyerca89a292014-07-15 09:42:54 +0200185 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
186 PHS_SEND, DBG_LVL_ALL,
187 "PHS Sending packet Compressed");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500188
Kevin McKinney69493872013-02-20 23:25:28 -0500189 if (skb_cloned(Packet)) {
Matthias Beyere86bd612014-07-15 09:43:15 +0200190 newPacket =
191 skb_copy(Packet, GFP_ATOMIC);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500192
193 if (newPacket == NULL)
194 return STATUS_FAILURE;
195
196 dev_kfree_skb(Packet);
197 *pPacket = Packet = newPacket;
Matthias Beyerca89a292014-07-15 09:42:54 +0200198 pucPHSPktHdrInBuf =
199 Packet->data + BytesToRemove;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700200 }
201
Matthias Beyerca89a292014-07-15 09:42:54 +0200202 numBytesCompressed = unPhsOldHdrSize -
203 (unPHSNewPktHeaderLen + PHSI_LEN);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500204
Matthias Beyerca89a292014-07-15 09:42:54 +0200205 memcpy(pucPHSPktHdrInBuf + numBytesCompressed,
206 pucPHSPktHdrOutBuf,
207 unPHSNewPktHeaderLen + PHSI_LEN);
208 memcpy(Packet->data + numBytesCompressed,
209 Packet->data, BytesToRemove);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500210 skb_pull(Packet, numBytesCompressed);
211
212 return STATUS_SUCCESS;
Kevin McKinney69493872013-02-20 23:25:28 -0500213 } else {
Matthias Beyerca89a292014-07-15 09:42:54 +0200214 /* if one byte headroom is not available,
215 * increase it through skb_cow
216 */
Kevin McKinney69493872013-02-20 23:25:28 -0500217 if (!(skb_headroom(Packet) > 0)) {
218
219 if (skb_cow(Packet, 1)) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200220 BCM_DEBUG_PRINT(Adapter,
221 DBG_TYPE_PRINTK,
222 0, 0,
223 "SKB Cow Failed\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500224 return STATUS_FAILURE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700225 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700226 }
Kevin McKinney6c259f42013-02-20 23:25:27 -0500227 skb_push(Packet, 1);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700228
Kevin McKinney14b3a402013-02-20 23:25:29 -0500229 /*
230 * CAUTION: The MAC Header is getting corrupted
231 * here for IP CS - can be saved by copying 14
232 * Bytes. not needed .... hence corrupting it.
233 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500234 *(Packet->data + BytesToRemove) = bPHSI;
235 return STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700236 }
Kevin McKinney69493872013-02-20 23:25:28 -0500237 } else {
238
Kevin McKinney6c259f42013-02-20 23:25:27 -0500239 if (!bHeaderSuppressionEnabled)
Matthias Beyerca89a292014-07-15 09:42:54 +0200240 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
241 PHS_SEND, DBG_LVL_ALL,
242 "\nHeader Suppression Disabled For SF: No PHS\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700243
244 return STATUS_SUCCESS;
245 }
246 }
247
Matthias Beyere86bd612014-07-15 09:43:15 +0200248 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
249 * "PHSTransmit : Dumping data packet After PHS"); */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700250 return STATUS_SUCCESS;
251}
252
Kevin McKinney29794602012-05-26 12:05:12 -0400253int PHSReceive(struct bcm_mini_adapter *Adapter,
Matthias Beyerca89a292014-07-15 09:42:54 +0200254 USHORT usVcid,
255 struct sk_buff *packet,
256 UINT *punPacketLen,
257 UCHAR *pucEthernetHdr,
258 UINT bHeaderSuppressionEnabled)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700259{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500260 u32 nStandardPktHdrLen = 0;
261 u32 nTotalsuppressedPktHdrBytes = 0;
262 int ulPhsStatus = 0;
263 PUCHAR pucInBuff = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700264 UINT TotalBytesAdded = 0;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500265
Kevin McKinney69493872013-02-20 23:25:28 -0500266 if (!bHeaderSuppressionEnabled) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200267 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
268 DBG_LVL_ALL,
269 "\nPhs Disabled for incoming packet");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700270 return ulPhsStatus;
271 }
272
273 pucInBuff = packet->data;
274
Kevin McKinney14b3a402013-02-20 23:25:29 -0500275 /* Restore PHS suppressed header */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700276 nStandardPktHdrLen = packet->len;
277 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
Matthias Beyerca89a292014-07-15 09:42:54 +0200278 usVcid,
279 pucInBuff,
280 Adapter->ucaPHSPktRestoreBuf,
281 &nTotalsuppressedPktHdrBytes,
282 &nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700283
Matthias Beyerca89a292014-07-15 09:42:54 +0200284 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
285 "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
Kevin McKinney6c259f42013-02-20 23:25:27 -0500286 nTotalsuppressedPktHdrBytes, nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700287
Kevin McKinney69493872013-02-20 23:25:28 -0500288 if (ulPhsStatus != STATUS_PHS_COMPRESSED) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700289 skb_pull(packet, 1);
290 return STATUS_SUCCESS;
Kevin McKinney69493872013-02-20 23:25:28 -0500291 } else {
Matthias Beyerca89a292014-07-15 09:42:54 +0200292 TotalBytesAdded = nStandardPktHdrLen -
293 nTotalsuppressedPktHdrBytes - PHSI_LEN;
Kevin McKinney69493872013-02-20 23:25:28 -0500294
295 if (TotalBytesAdded) {
Kevin McKinney6c259f42013-02-20 23:25:27 -0500296 if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700297 skb_push(packet, TotalBytesAdded);
Kevin McKinney69493872013-02-20 23:25:28 -0500298 else {
299 if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200300 BCM_DEBUG_PRINT(Adapter,
301 DBG_TYPE_PRINTK, 0, 0,
302 "cow failed in receive\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700303 return STATUS_FAILURE;
304 }
305
306 skb_push(packet, TotalBytesAdded);
307 }
308 }
309
Matthias Beyerca89a292014-07-15 09:42:54 +0200310 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf,
311 nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700312 }
313
314 return STATUS_SUCCESS;
315}
316
Kevin McKinney6c259f42013-02-20 23:25:27 -0500317void DumpFullPacket(UCHAR *pBuf, UINT nPktLen)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700318{
Kevin McKinney29794602012-05-26 12:05:12 -0400319 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500320
Matthias Beyerca89a292014-07-15 09:42:54 +0200321 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,
322 "Dumping Data Packet");
323 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,
324 pBuf, nPktLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700325}
326
Kevin McKinney14b3a402013-02-20 23:25:29 -0500327/*
328 * Procedure: phs_init
329 *
Matthias Beyere86bd612014-07-15 09:43:15 +0200330 * Description: This routine is responsible for allocating memory for classifier
331 * and PHS rules.
Kevin McKinney14b3a402013-02-20 23:25:29 -0500332 *
333 * Arguments:
Matthias Beyere86bd612014-07-15 09:43:15 +0200334 * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules
335 * and PHS Rules , RX, TX buffer etc
Kevin McKinney14b3a402013-02-20 23:25:29 -0500336 *
337 * Returns:
Kevin McKinney175c5122013-02-20 23:25:30 -0500338 * TRUE(1) -If allocation of memory was successful.
Kevin McKinney14b3a402013-02-20 23:25:29 -0500339 * FALSE -If allocation of memory fails.
340 */
Matthias Beyerca89a292014-07-15 09:42:54 +0200341int phs_init(struct bcm_phs_extension *pPhsdeviceExtension,
342 struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700343{
344 int i;
Kevin McKinneyda4d1502012-12-20 00:31:29 -0500345 struct bcm_phs_table *pstServiceFlowTable;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700346
Matthias Beyerca89a292014-07-15 09:42:54 +0200347 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
348 "\nPHS:phs_init function");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500349
350 if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700351 return -EINVAL;
352
Matthias Beyerca89a292014-07-15 09:42:54 +0200353 pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
354 kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700355
Kevin McKinney69493872013-02-20 23:25:28 -0500356 if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200357 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
358 DBG_LVL_ALL,
359 "\nAllocation ServiceFlowPhsRulesTable failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700360 return -ENOMEM;
361 }
362
363 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
Kevin McKinney69493872013-02-20 23:25:28 -0500364 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200365 struct bcm_phs_entry sServiceFlow =
366 pstServiceFlowTable->stSFList[i];
367 sServiceFlow.pstClassifierTable =
368 kzalloc(sizeof(struct bcm_phs_classifier_table),
369 GFP_KERNEL);
Kevin McKinney69493872013-02-20 23:25:28 -0500370 if (!sServiceFlow.pstClassifierTable) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200371 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
372 DBG_LVL_ALL, "\nAllocation failed");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500373 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700374 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
375 return -ENOMEM;
376 }
377 }
378
Stephen Hemminger082e8892010-11-01 09:35:21 -0400379 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
Kevin McKinney69493872013-02-20 23:25:28 -0500380 if (pPhsdeviceExtension->CompressedTxBuffer == NULL) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200381 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
382 DBG_LVL_ALL, "\nAllocation failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700383 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
384 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
385 return -ENOMEM;
386 }
387
Matthias Beyerca89a292014-07-15 09:42:54 +0200388 pPhsdeviceExtension->UnCompressedRxBuffer =
389 kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
Kevin McKinney69493872013-02-20 23:25:28 -0500390 if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200391 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
392 DBG_LVL_ALL, "\nAllocation failed");
Stephen Hemminger082e8892010-11-01 09:35:21 -0400393 kfree(pPhsdeviceExtension->CompressedTxBuffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700394 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
395 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
396 return -ENOMEM;
397 }
398
Matthias Beyerca89a292014-07-15 09:42:54 +0200399 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
400 "\n phs_init Successful");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700401 return STATUS_SUCCESS;
402}
403
Kevin McKinney60dadf92012-12-20 00:31:28 -0500404int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700405{
Kevin McKinney69493872013-02-20 23:25:28 -0500406 if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700407 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
408 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
409 }
410
Stephen Hemminger082e8892010-11-01 09:35:21 -0400411 kfree(pPHSDeviceExt->CompressedTxBuffer);
412 pPHSDeviceExt->CompressedTxBuffer = NULL;
413
414 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
415 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700416
417 return 0;
418}
419
Kevin McKinney14b3a402013-02-20 23:25:29 -0500420/*
421 * PHS functions
422 * PhsUpdateClassifierRule
423 *
424 * Routine Description:
425 * Exported function to add or modify a PHS Rule.
426 *
427 * Arguments:
428 * IN void* pvContext - PHS Driver Specific Context
429 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
430 * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
431 * IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
432 *
433 * Return Value:
434 *
435 * 0 if successful,
436 * >0 Error.
437 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500438ULONG PhsUpdateClassifierRule(IN void *pvContext,
Matthias Beyerca89a292014-07-15 09:42:54 +0200439 IN B_UINT16 uiVcid ,
440 IN B_UINT16 uiClsId ,
441 IN struct bcm_phs_rule *psPhsRule,
442 IN B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700443{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500444 ULONG lStatus = 0;
445 UINT nSFIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500446 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400447 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Matthias Beyere86bd612014-07-15 09:43:15 +0200448 struct bcm_phs_extension *pDeviceExtension =
449 (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700450
Matthias Beyerca89a292014-07-15 09:42:54 +0200451 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
452 "PHS With Corr2 Changes\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700453
Kevin McKinney69493872013-02-20 23:25:28 -0500454 if (pDeviceExtension == NULL) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200455 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
456 DBG_LVL_ALL, "Invalid Device Extension\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700457 return ERR_PHS_INVALID_DEVICE_EXETENSION;
458 }
459
Kevin McKinney6c259f42013-02-20 23:25:27 -0500460 if (u8AssociatedPHSI == 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700461 return ERR_PHS_INVALID_PHS_RULE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700462
463 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700464 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Matthias Beyerca89a292014-07-15 09:42:54 +0200465 uiVcid, &pstServiceFlowEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700466
Kevin McKinney69493872013-02-20 23:25:28 -0500467 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700468 /* This is a new SF. Create a mapping entry for this */
469 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
Matthias Beyerca89a292014-07-15 09:42:54 +0200470 pDeviceExtension->pstServiceFlowPhsRulesTable,
471 psPhsRule,
472 u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700473 return lStatus;
474 }
475
476 /* SF already Exists Add PHS Rule to existing SF */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500477 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
Matthias Beyerca89a292014-07-15 09:42:54 +0200478 pstServiceFlowEntry,
479 psPhsRule,
480 u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700481
Kevin McKinney6c259f42013-02-20 23:25:27 -0500482 return lStatus;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700483}
484
Kevin McKinney14b3a402013-02-20 23:25:29 -0500485/*
486 * PhsDeletePHSRule
487 *
488 * Routine Description:
489 * Deletes the specified phs Rule within Vcid
490 *
491 * Arguments:
492 * IN void* pvContext - PHS Driver Specific Context
493 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
494 * IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
495 *
496 * Return Value:
497 *
498 * 0 if successful,
499 * >0 Error.
500 */
Matthias Beyerca89a292014-07-15 09:42:54 +0200501ULONG PhsDeletePHSRule(IN void *pvContext,
502 IN B_UINT16 uiVcid,
503 IN B_UINT8 u8PHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700504{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500505 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500506 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500507 struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400508 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500509 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
Matthias Beyer413852b2014-07-15 09:42:57 +0200510 struct bcm_phs_classifier_entry *curr_entry;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700511
Matthias Beyerca89a292014-07-15 09:42:54 +0200512 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
513 "======>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700514
Kevin McKinney69493872013-02-20 23:25:28 -0500515 if (pDeviceExtension) {
Kevin McKinney14b3a402013-02-20 23:25:29 -0500516 /* Retrieve the SFID Entry Index for requested Service Flow */
Matthias Beyerca89a292014-07-15 09:42:54 +0200517 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
518 uiVcid, &pstServiceFlowEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700519
Kevin McKinney69493872013-02-20 23:25:28 -0500520 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200521 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
522 DBG_LVL_ALL, "SFID Match Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700523 return ERR_SF_MATCH_FAIL;
524 }
525
Kevin McKinney6c259f42013-02-20 23:25:27 -0500526 pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
Kevin McKinney69493872013-02-20 23:25:28 -0500527 if (pstClassifierRulesTable) {
528 for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
Matthias Beyer413852b2014-07-15 09:42:57 +0200529 curr_entry = &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex];
Matthias Beyer31f4f3f2014-07-15 09:42:58 +0200530 if (curr_entry->bUsed &&
531 curr_entry->pstPhsRule &&
532 (curr_entry->pstPhsRule->u8PHSI == u8PHSI)) {
Kevin McKinney69493872013-02-20 23:25:28 -0500533
Matthias Beyer31f4f3f2014-07-15 09:42:58 +0200534 if (curr_entry->pstPhsRule->u8RefCnt)
535 curr_entry->pstPhsRule->u8RefCnt--;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500536
Matthias Beyer31f4f3f2014-07-15 09:42:58 +0200537 if (0 == curr_entry->pstPhsRule->u8RefCnt)
538 kfree(curr_entry->pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500539
Matthias Beyer31f4f3f2014-07-15 09:42:58 +0200540 memset(curr_entry,
541 0,
542 sizeof(struct bcm_phs_classifier_entry));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700543 }
544 }
545 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700546 }
Peter Senna Tschudin4764ca92014-05-26 16:08:50 +0200547 return 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700548}
549
Kevin McKinney14b3a402013-02-20 23:25:29 -0500550/*
551 * PhsDeleteClassifierRule
552 *
553 * Routine Description:
554 * Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
555 *
556 * Arguments:
557 * IN void* pvContext - PHS Driver Specific Context
558 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
559 * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
560 *
561 * Return Value:
562 *
563 * 0 if successful,
564 * >0 Error.
565 */
Matthias Beyere86bd612014-07-15 09:43:15 +0200566ULONG PhsDeleteClassifierRule(IN void *pvContext,
567 IN B_UINT16 uiVcid,
568 IN B_UINT16 uiClsId)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700569{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500570 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500571 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinney2212e932012-12-20 00:31:32 -0500572 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400573 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Matthias Beyerca89a292014-07-15 09:42:54 +0200574 struct bcm_phs_extension *pDeviceExtension =
575 (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700576
Matthias Beyer525afdd2014-07-15 09:42:59 +0200577 if (!pDeviceExtension)
578 goto out;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700579
Matthias Beyer525afdd2014-07-15 09:42:59 +0200580 /* Retrieve the SFID Entry Index for requested Service Flow */
581 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
582 uiVcid, &pstServiceFlowEntry);
583 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
584 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
585 DBG_LVL_ALL, "SFID Match Failed\n");
586 return ERR_SF_MATCH_FAIL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700587 }
Matthias Beyer525afdd2014-07-15 09:42:59 +0200588
Matthias Beyer93cc6ae2014-07-15 09:43:00 +0200589 nClsidIndex =
590 GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
591 uiClsId,
592 eActiveClassifierRuleContext,
593 &pstClassifierEntry);
Matthias Beyer525afdd2014-07-15 09:42:59 +0200594
Matthias Beyer93cc6ae2014-07-15 09:43:00 +0200595 if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) &&
596 (!pstClassifierEntry->bUnclassifiedPHSRule)) {
Matthias Beyer525afdd2014-07-15 09:42:59 +0200597 if (pstClassifierEntry->pstPhsRule) {
598 if (pstClassifierEntry->pstPhsRule->u8RefCnt)
599 pstClassifierEntry->pstPhsRule->u8RefCnt--;
600
601 if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt)
602 kfree(pstClassifierEntry->pstPhsRule);
603 }
604 memset(pstClassifierEntry, 0,
605 sizeof(struct bcm_phs_classifier_entry));
606 }
607
Matthias Beyer93cc6ae2014-07-15 09:43:00 +0200608 nClsidIndex =
609 GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
610 uiClsId,
611 eOldClassifierRuleContext,
612 &pstClassifierEntry);
Matthias Beyer525afdd2014-07-15 09:42:59 +0200613
Matthias Beyer93cc6ae2014-07-15 09:43:00 +0200614 if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) &&
615 (!pstClassifierEntry->bUnclassifiedPHSRule)) {
Matthias Beyer525afdd2014-07-15 09:42:59 +0200616 kfree(pstClassifierEntry->pstPhsRule);
617 memset(pstClassifierEntry, 0,
618 sizeof(struct bcm_phs_classifier_entry));
619 }
620
621out:
Peter Senna Tschudin4764ca92014-05-26 16:08:50 +0200622 return 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700623}
624
Kevin McKinney14b3a402013-02-20 23:25:29 -0500625/*
626 * PhsDeleteSFRules
627 *
628 * Routine Description:
629 * Exported function to Delete a all PHS Rules for the SFID.
630 *
631 * Arguments:
632 * IN void* pvContext - PHS Driver Specific Context
633 * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
634 *
635 * Return Value:
636 *
637 * 0 if successful,
638 * >0 Error.
639 */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500640ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700641{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500642 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500643 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinneya700dbd2012-12-20 00:31:31 -0500644 struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -0400645 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Matthias Beyerca89a292014-07-15 09:42:54 +0200646 struct bcm_phs_extension *pDeviceExtension =
647 (struct bcm_phs_extension *)pvContext;
Matthias Beyera984b122014-07-15 09:43:02 +0200648 struct bcm_phs_classifier_entry *curr_clsf_entry;
649 struct bcm_phs_classifier_entry *curr_rules_list;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700650
Matthias Beyerca89a292014-07-15 09:42:54 +0200651 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
652 "====>\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500653
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200654 if (!pDeviceExtension)
655 goto out;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700656
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200657 /* Retrieve the SFID Entry Index for requested Service Flow */
658 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
659 uiVcid, &pstServiceFlowEntry);
660 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
661 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
662 DBG_LVL_ALL, "SFID Match Failed\n");
663 return ERR_SF_MATCH_FAIL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700664 }
665
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200666 pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
667 if (pstClassifierRulesTable) {
668 for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
Matthias Beyera984b122014-07-15 09:43:02 +0200669 curr_clsf_entry =
670 &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex];
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200671
Matthias Beyera984b122014-07-15 09:43:02 +0200672 curr_rules_list =
673 &pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex];
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200674
Matthias Beyera984b122014-07-15 09:43:02 +0200675 if (curr_clsf_entry->pstPhsRule) {
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200676
Matthias Beyera984b122014-07-15 09:43:02 +0200677 if (curr_clsf_entry->pstPhsRule->u8RefCnt)
678 curr_clsf_entry->pstPhsRule->u8RefCnt--;
679
680 if (0 == curr_clsf_entry->pstPhsRule->u8RefCnt)
681 kfree(curr_clsf_entry->pstPhsRule);
682
683 curr_clsf_entry->pstPhsRule = NULL;
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200684 }
Matthias Beyera984b122014-07-15 09:43:02 +0200685 memset(curr_clsf_entry, 0,
686 sizeof(struct bcm_phs_classifier_entry));
687 if (curr_rules_list->pstPhsRule) {
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200688
Matthias Beyera984b122014-07-15 09:43:02 +0200689 if (curr_rules_list->pstPhsRule->u8RefCnt)
690 curr_rules_list->pstPhsRule->u8RefCnt--;
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200691
Matthias Beyera984b122014-07-15 09:43:02 +0200692 if (0 == curr_rules_list->pstPhsRule->u8RefCnt)
693 kfree(curr_rules_list->pstPhsRule);
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200694
Matthias Beyera984b122014-07-15 09:43:02 +0200695 curr_rules_list->pstPhsRule = NULL;
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200696 }
Matthias Beyera984b122014-07-15 09:43:02 +0200697 memset(curr_rules_list, 0,
698 sizeof(struct bcm_phs_classifier_entry));
Matthias Beyerfc38bc12014-07-15 09:43:01 +0200699 }
700 }
701 pstServiceFlowEntry->bUsed = false;
702 pstServiceFlowEntry->uiVcid = 0;
703
704out:
Peter Senna Tschudin4764ca92014-05-26 16:08:50 +0200705 return 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700706}
707
Kevin McKinney14b3a402013-02-20 23:25:29 -0500708/*
709 * PhsCompress
710 *
711 * Routine Description:
712 * Exported function to compress the data using PHS.
713 *
714 * Arguments:
Matthias Beyere86bd612014-07-15 09:43:15 +0200715 * IN void* pvContext - PHS Driver Specific Context.
716 * IN B_UINT16 uiVcid - The Service Flow ID to which current
717 * packet header compression applies.
718 * IN UINT uiClsId - The Classifier ID to which current packet
719 * header compression applies.
720 * IN void *pvInputBuffer - The Input buffer containg packet header
721 * data
722 * IN void *pvOutputBuffer - The output buffer returned by this
723 * function after PHS
724 * IN UINT *pOldHeaderSize - The actual size of the header before PHS
725 * IN UINT *pNewHeaderSize - The new size of the header after applying
726 * PHS
Kevin McKinney14b3a402013-02-20 23:25:29 -0500727 *
728 * Return Value:
729 *
730 * 0 if successful,
731 * >0 Error.
732 */
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700733static ULONG PhsCompress(IN void *pvContext,
Matthias Beyerca89a292014-07-15 09:42:54 +0200734 IN B_UINT16 uiVcid,
735 IN B_UINT16 uiClsId,
736 IN void *pvInputBuffer,
737 OUT void *pvOutputBuffer,
738 OUT UINT *pOldHeaderSize,
739 OUT UINT *pNewHeaderSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700740{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500741 UINT nSFIndex = 0, nClsidIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500742 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinney2212e932012-12-20 00:31:32 -0500743 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
Kevin McKinneya903d652012-12-20 00:31:34 -0500744 struct bcm_phs_rule *pstPhsRule = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500745 ULONG lStatus = 0;
Kevin McKinney29794602012-05-26 12:05:12 -0400746 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Matthias Beyerca89a292014-07-15 09:42:54 +0200747 struct bcm_phs_extension *pDeviceExtension =
748 (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700749
Kevin McKinney69493872013-02-20 23:25:28 -0500750 if (pDeviceExtension == NULL) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200751 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
752 "Invalid Device Extension\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500753 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700754 return lStatus;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700755 }
756
Matthias Beyerca89a292014-07-15 09:42:54 +0200757 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
758 "Suppressing header\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700759
Kevin McKinney14b3a402013-02-20 23:25:29 -0500760 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700761 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Matthias Beyerbabb7f92014-07-15 09:43:03 +0200762 uiVcid, &pstServiceFlowEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500763 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200764 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
765 "SFID Match Failed\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500766 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700767 return lStatus;
768 }
769
770 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
Matthias Beyerca89a292014-07-15 09:42:54 +0200771 uiClsId, eActiveClassifierRuleContext,
772 &pstClassifierEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700773
Kevin McKinney69493872013-02-20 23:25:28 -0500774 if (nClsidIndex == PHS_INVALID_TABLE_INDEX) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200775 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
776 "No PHS Rule Defined For Classifier\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500777 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700778 return lStatus;
779 }
780
Kevin McKinney14b3a402013-02-20 23:25:29 -0500781 /* get rule from SF id,Cls ID pair and proceed */
Kevin McKinney6c259f42013-02-20 23:25:27 -0500782 pstPhsRule = pstClassifierEntry->pstPhsRule;
Kevin McKinney69493872013-02-20 23:25:28 -0500783 if (!ValidatePHSRuleComplete(pstPhsRule)) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200784 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
785 "PHS Rule Defined For Classifier But Not Complete\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -0500786 lStatus = STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700787 return lStatus;
788 }
789
Kevin McKinney14b3a402013-02-20 23:25:29 -0500790 /* Compress Packet */
Matthias Beyerbabb7f92014-07-15 09:43:03 +0200791 lStatus = phs_compress(pstPhsRule,
792 (PUCHAR)pvInputBuffer,
793 (PUCHAR)pvOutputBuffer,
794 pOldHeaderSize,
795 pNewHeaderSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700796
Kevin McKinney69493872013-02-20 23:25:28 -0500797 if (lStatus == STATUS_PHS_COMPRESSED) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200798 pstPhsRule->PHSModifiedBytes +=
799 *pOldHeaderSize - *pNewHeaderSize - 1;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700800 pstPhsRule->PHSModifiedNumPackets++;
Matthias Beyerb43b2452014-07-15 09:43:04 +0200801 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700802 pstPhsRule->PHSErrorNumPackets++;
Matthias Beyerb43b2452014-07-15 09:43:04 +0200803 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700804
805 return lStatus;
806}
807
Kevin McKinney14b3a402013-02-20 23:25:29 -0500808/*
809 * PhsDeCompress
810 *
811 * Routine Description:
812 * Exported function to restore the packet header in Rx path.
813 *
814 * Arguments:
Matthias Beyere86bd612014-07-15 09:43:15 +0200815 * IN void* pvContext - PHS Driver Specific Context.
816 * IN B_UINT16 uiVcid - The Service Flow ID to which current
817 * packet header restoration applies.
818 * IN void *pvInputBuffer - The Input buffer containg suppressed
819 * packet header data
820 * OUT void *pvOutputBuffer - The output buffer returned by this
821 * function after restoration
822 * OUT UINT *pHeaderSize - The packet header size after restoration
823 * is returned in this parameter.
Kevin McKinney14b3a402013-02-20 23:25:29 -0500824 *
825 * Return Value:
826 *
827 * 0 if successful,
828 * >0 Error.
829 */
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700830static ULONG PhsDeCompress(IN void *pvContext,
Matthias Beyerca89a292014-07-15 09:42:54 +0200831 IN B_UINT16 uiVcid,
832 IN void *pvInputBuffer,
833 OUT void *pvOutputBuffer,
834 OUT UINT *pInHeaderSize,
835 OUT UINT *pOutHeaderSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700836{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500837 UINT nSFIndex = 0, nPhsRuleIndex = 0;
Kevin McKinneydb134a62012-12-20 00:31:30 -0500838 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
Kevin McKinneya903d652012-12-20 00:31:34 -0500839 struct bcm_phs_rule *pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700840 UINT phsi;
Kevin McKinney29794602012-05-26 12:05:12 -0400841 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Matthias Beyerca89a292014-07-15 09:42:54 +0200842 struct bcm_phs_extension *pDeviceExtension =
843 (struct bcm_phs_extension *)pvContext;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700844
845 *pInHeaderSize = 0;
Kevin McKinney69493872013-02-20 23:25:28 -0500846 if (pDeviceExtension == NULL) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200847 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
848 DBG_LVL_ALL, "Invalid Device Extension\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700849 return ERR_PHS_INVALID_DEVICE_EXETENSION;
850 }
851
Matthias Beyerca89a292014-07-15 09:42:54 +0200852 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
853 "Restoring header\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700854
855 phsi = *((unsigned char *)(pvInputBuffer));
Matthias Beyerca89a292014-07-15 09:42:54 +0200856 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
857 "PHSI To Be Used For restore : %x\n", phsi);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500858 if (phsi == UNCOMPRESSED_PACKET)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700859 return STATUS_PHS_NOCOMPRESSION;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700860
Kevin McKinney14b3a402013-02-20 23:25:29 -0500861 /* Retrieve the SFID Entry Index for requested Service Flow */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700862 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
Matthias Beyerca89a292014-07-15 09:42:54 +0200863 uiVcid, &pstServiceFlowEntry);
Kevin McKinney69493872013-02-20 23:25:28 -0500864 if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
Matthias Beyerca89a292014-07-15 09:42:54 +0200865 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
866 DBG_LVL_ALL,
867 "SFID Match Failed During Lookup\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700868 return ERR_SF_MATCH_FAIL;
869 }
870
Matthias Beyerca89a292014-07-15 09:42:54 +0200871 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
872 phsi,
873 eActiveClassifierRuleContext,
874 &pstPhsRule);
Kevin McKinney69493872013-02-20 23:25:28 -0500875 if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) {
Matthias Beyere86bd612014-07-15 09:43:15 +0200876 /* Phs Rule does not exist in active rules table. Lets try
877 * in the old rules table. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700878 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
Matthias Beyerca89a292014-07-15 09:42:54 +0200879 phsi,
880 eOldClassifierRuleContext,
881 &pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500882 if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700883 return ERR_PHSRULE_MATCH_FAIL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700884 }
885
886 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
Matthias Beyerca89a292014-07-15 09:42:54 +0200887 (PUCHAR)pvOutputBuffer,
888 pstPhsRule,
889 pOutHeaderSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700890
891 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
892
893 pstPhsRule->PHSModifiedNumPackets++;
894 return STATUS_PHS_COMPRESSED;
895}
896
Kevin McKinney14b3a402013-02-20 23:25:29 -0500897/*
898 * Procedure: free_phs_serviceflow_rules
899 *
Matthias Beyere86bd612014-07-15 09:43:15 +0200900 * Description: This routine is responsible for freeing memory allocated for
901 * PHS rules.
Kevin McKinney14b3a402013-02-20 23:25:29 -0500902 *
903 * Arguments:
904 * rules - ptr to S_SERVICEFLOW_TABLE structure.
905 *
906 * Returns:
907 * Does not return any value.
908 */
Kevin McKinneyda4d1502012-12-20 00:31:29 -0500909static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700910{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500911 int i, j;
Kevin McKinney29794602012-05-26 12:05:12 -0400912 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Matthias Beyer3ed150a2014-07-15 09:43:05 +0200913 struct bcm_phs_classifier_entry *curr_act_rules_list;
914 struct bcm_phs_classifier_entry *curr_old_rules_list;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700915
Matthias Beyerca89a292014-07-15 09:42:54 +0200916 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
917 "=======>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700918
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200919 if (!psServiceFlowRulesTable)
920 goto out;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500921
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200922 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
923 struct bcm_phs_entry stServiceFlowEntry =
924 psServiceFlowRulesTable->stSFList[i];
925 struct bcm_phs_classifier_table *pstClassifierRulesTable =
926 stServiceFlowEntry.pstClassifierTable;
Kevin McKinney69493872013-02-20 23:25:28 -0500927
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200928 if (pstClassifierRulesTable) {
929 for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
930 curr_act_rules_list =
931 &pstClassifierRulesTable->stActivePhsRulesList[j];
Kevin McKinney6c259f42013-02-20 23:25:27 -0500932
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200933 curr_old_rules_list =
934 &pstClassifierRulesTable->stOldPhsRulesList[j];
Kevin McKinney6c259f42013-02-20 23:25:27 -0500935
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200936 if (curr_act_rules_list->pstPhsRule) {
Matthias Beyer3ed150a2014-07-15 09:43:05 +0200937
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200938 if (curr_act_rules_list->pstPhsRule->u8RefCnt)
939 curr_act_rules_list->pstPhsRule->u8RefCnt--;
Matthias Beyer3ed150a2014-07-15 09:43:05 +0200940
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200941 if (0 == curr_act_rules_list->pstPhsRule->u8RefCnt)
942 kfree(curr_act_rules_list->pstPhsRule);
Kevin McKinney6c259f42013-02-20 23:25:27 -0500943
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200944 curr_act_rules_list->pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700945 }
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200946
947 if (curr_old_rules_list->pstPhsRule) {
948
949 if (curr_old_rules_list->pstPhsRule->u8RefCnt)
950 curr_old_rules_list->pstPhsRule->u8RefCnt--;
951
952 if (0 == curr_old_rules_list->pstPhsRule->u8RefCnt)
953 kfree(curr_old_rules_list->pstPhsRule);
954
955 curr_old_rules_list->pstPhsRule = NULL;
956 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700957 }
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200958 kfree(pstClassifierRulesTable);
959 stServiceFlowEntry.pstClassifierTable =
960 pstClassifierRulesTable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700961 }
962 }
963
Matthias Beyerc8020cc2014-07-15 09:43:06 +0200964out:
965
Kevin McKinney6c259f42013-02-20 23:25:27 -0500966 kfree(psServiceFlowRulesTable);
967 psServiceFlowRulesTable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700968}
969
Matthias Beyer14d8e912014-07-15 09:43:08 +0200970static bool ValidatePHSRuleComplete(IN const struct bcm_phs_rule *psPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700971{
Matthias Beyercc872f82014-07-15 09:43:07 +0200972 return (psPhsRule &&
973 psPhsRule->u8PHSI &&
974 psPhsRule->u8PHSS &&
975 psPhsRule->u8PHSFLength);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700976}
977
Kevin McKinneyda4d1502012-12-20 00:31:29 -0500978UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
Matthias Beyerca89a292014-07-15 09:42:54 +0200979 IN B_UINT16 uiVcid,
980 struct bcm_phs_entry **ppstServiceFlowEntry)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700981{
Kevin McKinney6c259f42013-02-20 23:25:27 -0500982 int i;
Matthias Beyercf423562014-07-15 09:43:09 +0200983 struct bcm_phs_entry *curr_sf_list;
Kevin McKinney6c259f42013-02-20 23:25:27 -0500984
Kevin McKinney69493872013-02-20 23:25:28 -0500985 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
Matthias Beyercf423562014-07-15 09:43:09 +0200986 curr_sf_list = &psServiceFlowTable->stSFList[i];
Matthias Beyerc842dd22014-07-15 09:43:10 +0200987 if (curr_sf_list->bUsed && (curr_sf_list->uiVcid == uiVcid)) {
988 *ppstServiceFlowEntry = curr_sf_list;
989 return i;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700990 }
991 }
992
993 *ppstServiceFlowEntry = NULL;
994 return PHS_INVALID_TABLE_INDEX;
995}
996
Shalin Mehtaf2be6352013-09-17 00:42:17 -0700997static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
Matthias Beyerca89a292014-07-15 09:42:54 +0200998 IN B_UINT32 uiClsid,
999 enum bcm_phs_classifier_context eClsContext,
1000 OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001001{
1002 int i;
Kevin McKinney2212e932012-12-20 00:31:32 -05001003 struct bcm_phs_classifier_entry *psClassifierRules = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001004
Kevin McKinney69493872013-02-20 23:25:28 -05001005 for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001006
Kevin McKinney69493872013-02-20 23:25:28 -05001007 if (eClsContext == eActiveClassifierRuleContext)
Matthias Beyerca89a292014-07-15 09:42:54 +02001008 psClassifierRules =
1009 &pstClassifierTable->stActivePhsRulesList[i];
Kevin McKinney69493872013-02-20 23:25:28 -05001010 else
Matthias Beyerca89a292014-07-15 09:42:54 +02001011 psClassifierRules =
1012 &pstClassifierTable->stOldPhsRulesList[i];
Kevin McKinney69493872013-02-20 23:25:28 -05001013
Matthias Beyer1c53f082014-07-15 09:43:11 +02001014 if (psClassifierRules->bUsed &&
1015 (psClassifierRules->uiClassifierRuleId == uiClsid)) {
1016 *ppstClassifierEntry = psClassifierRules;
1017 return i;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001018 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001019 }
1020
1021 *ppstClassifierEntry = NULL;
1022 return PHS_INVALID_TABLE_INDEX;
1023}
1024
Kevin McKinneya700dbd2012-12-20 00:31:31 -05001025static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
Matthias Beyerca89a292014-07-15 09:42:54 +02001026 IN B_UINT32 uiPHSI,
1027 enum bcm_phs_classifier_context eClsContext,
1028 OUT struct bcm_phs_rule **ppstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001029{
1030 int i;
Kevin McKinney2212e932012-12-20 00:31:32 -05001031 struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001032
Kevin McKinney69493872013-02-20 23:25:28 -05001033 for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001034 if (eClsContext == eActiveClassifierRuleContext)
Matthias Beyerca89a292014-07-15 09:42:54 +02001035 pstClassifierRule =
1036 &pstClassifierTable->stActivePhsRulesList[i];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001037 else
Matthias Beyerca89a292014-07-15 09:42:54 +02001038 pstClassifierRule =
1039 &pstClassifierTable->stOldPhsRulesList[i];
Kevin McKinney6c259f42013-02-20 23:25:27 -05001040
Matthias Beyer18002f52014-07-15 09:43:12 +02001041 if (pstClassifierRule->bUsed &&
1042 (pstClassifierRule->u8PHSI == uiPHSI)) {
1043 *ppstPhsRule = pstClassifierRule->pstPhsRule;
1044 return i;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001045 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001046 }
1047
1048 *ppstPhsRule = NULL;
1049 return PHS_INVALID_TABLE_INDEX;
1050}
1051
Matthias Beyerca89a292014-07-15 09:42:54 +02001052static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,
1053 IN B_UINT16 uiClsId,
1054 IN struct bcm_phs_table *psServiceFlowTable,
1055 struct bcm_phs_rule *psPhsRule,
1056 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001057{
Kevin McKinneya700dbd2012-12-20 00:31:31 -05001058 struct bcm_phs_classifier_table *psaClassifiertable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001059 UINT uiStatus = 0;
1060 int iSfIndex;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001061 bool bFreeEntryFound = false;
Matthias Beyer91283492014-07-15 09:43:13 +02001062 struct bcm_phs_entry *curr_list;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001063
Kevin McKinney14b3a402013-02-20 23:25:29 -05001064 /* Check for a free entry in SFID table */
Kevin McKinney69493872013-02-20 23:25:28 -05001065 for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) {
Matthias Beyer91283492014-07-15 09:43:13 +02001066 curr_list = &psServiceFlowTable->stSFList[iSfIndex];
1067 if (!curr_list->bUsed) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001068 bFreeEntryFound = TRUE;
1069 break;
1070 }
1071 }
1072
Kevin McKinney6c259f42013-02-20 23:25:27 -05001073 if (!bFreeEntryFound)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001074 return ERR_SFTABLE_FULL;
1075
Matthias Beyer91283492014-07-15 09:43:13 +02001076 psaClassifiertable = curr_list->pstClassifierTable;
1077 uiStatus = CreateClassifierPHSRule(uiClsId,
1078 psaClassifiertable,
1079 psPhsRule,
1080 eActiveClassifierRuleContext,
1081 u8AssociatedPHSI);
Kevin McKinney69493872013-02-20 23:25:28 -05001082 if (uiStatus == PHS_SUCCESS) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001083 /* Add entry at free index to the SF */
Matthias Beyer91283492014-07-15 09:43:13 +02001084 curr_list->bUsed = TRUE;
1085 curr_list->uiVcid = uiVcid;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001086 }
1087
1088 return uiStatus;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001089}
1090
Shalin Mehtaf2be6352013-09-17 00:42:17 -07001091static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
Matthias Beyerca89a292014-07-15 09:42:54 +02001092 IN B_UINT16 uiClsId,
1093 IN struct bcm_phs_entry *pstServiceFlowEntry,
1094 struct bcm_phs_rule *psPhsRule,
1095 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001096{
Kevin McKinney2212e932012-12-20 00:31:32 -05001097 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001098 UINT uiStatus = PHS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001099 UINT nClassifierIndex = 0;
Kevin McKinneya700dbd2012-12-20 00:31:31 -05001100 struct bcm_phs_classifier_table *psaClassifiertable = NULL;
Kevin McKinney29794602012-05-26 12:05:12 -04001101 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001102
Kevin McKinney6c259f42013-02-20 23:25:27 -05001103 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
1104
Matthias Beyerca89a292014-07-15 09:42:54 +02001105 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
1106 "==>");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001107
1108 /* Check if the supplied Classifier already exists */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001109 nClassifierIndex = GetClassifierEntry(
1110 pstServiceFlowEntry->pstClassifierTable,
1111 uiClsId,
1112 eActiveClassifierRuleContext,
1113 &pstClassifierEntry);
1114
Kevin McKinney69493872013-02-20 23:25:28 -05001115 if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001116 /*
Matthias Beyere86bd612014-07-15 09:43:15 +02001117 * The Classifier doesn't exist. So its a new classifier being
1118 * added.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001119 * Add new entry to associate PHS Rule to the Classifier
1120 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001121
Kevin McKinney6c259f42013-02-20 23:25:27 -05001122 uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable,
Matthias Beyerca89a292014-07-15 09:42:54 +02001123 psPhsRule,
1124 eActiveClassifierRuleContext,
1125 u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001126 return uiStatus;
1127 }
1128
1129 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -05001130 * The Classifier exists.The PHS Rule for this classifier
1131 * is being modified
1132 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001133
Kevin McKinney69493872013-02-20 23:25:28 -05001134 if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001135 if (pstClassifierEntry->pstPhsRule == NULL)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001136 return ERR_PHS_INVALID_PHS_RULE;
1137
1138 /*
Matthias Beyere86bd612014-07-15 09:43:15 +02001139 * This rule already exists if any fields are changed for this
1140 * PHS rule update them.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001141 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001142 /* If any part of PHSF is valid then we update PHSF */
Kevin McKinney69493872013-02-20 23:25:28 -05001143 if (psPhsRule->u8PHSFLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001144 /* update PHSF */
Stephen Hemminger082e8892010-11-01 09:35:21 -04001145 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
Matthias Beyerca89a292014-07-15 09:42:54 +02001146 psPhsRule->u8PHSF,
1147 MAX_PHS_LENGTHS);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001148 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001149
Kevin McKinney69493872013-02-20 23:25:28 -05001150 if (psPhsRule->u8PHSFLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001151 /* update PHSFLen */
Matthias Beyerca89a292014-07-15 09:42:54 +02001152 pstClassifierEntry->pstPhsRule->u8PHSFLength =
1153 psPhsRule->u8PHSFLength;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001154 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001155
Kevin McKinney69493872013-02-20 23:25:28 -05001156 if (psPhsRule->u8PHSMLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001157 /* update PHSM */
Stephen Hemminger082e8892010-11-01 09:35:21 -04001158 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
Matthias Beyerca89a292014-07-15 09:42:54 +02001159 psPhsRule->u8PHSM,
1160 MAX_PHS_LENGTHS);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001161 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001162
Kevin McKinney69493872013-02-20 23:25:28 -05001163 if (psPhsRule->u8PHSMLength) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001164 /* update PHSM Len */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001165 pstClassifierEntry->pstPhsRule->u8PHSMLength =
Kevin McKinney6c259f42013-02-20 23:25:27 -05001166 psPhsRule->u8PHSMLength;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001167 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001168
Kevin McKinney69493872013-02-20 23:25:28 -05001169 if (psPhsRule->u8PHSS) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001170 /* update PHSS */
Matthias Beyerca89a292014-07-15 09:42:54 +02001171 pstClassifierEntry->pstPhsRule->u8PHSS =
1172 psPhsRule->u8PHSS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001173 }
1174
Kevin McKinney14b3a402013-02-20 23:25:29 -05001175 /* update PHSV */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001176 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
Kevin McKinney69493872013-02-20 23:25:28 -05001177 } else {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001178 /* A new rule is being set for this classifier. */
Matthias Beyerca89a292014-07-15 09:42:54 +02001179 uiStatus = UpdateClassifierPHSRule(uiClsId,
1180 pstClassifierEntry,
1181 psaClassifiertable,
1182 psPhsRule,
1183 u8AssociatedPHSI);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001184 }
1185
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001186 return uiStatus;
1187}
1188
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001189static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
Matthias Beyerca89a292014-07-15 09:42:54 +02001190 struct bcm_phs_classifier_table *psaClassifiertable,
1191 struct bcm_phs_rule *psPhsRule,
1192 enum bcm_phs_classifier_context eClsContext,
1193 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001194{
1195 UINT iClassifierIndex = 0;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001196 bool bFreeEntryFound = false;
Kevin McKinney2212e932012-12-20 00:31:32 -05001197 struct bcm_phs_classifier_entry *psClassifierRules = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001198 UINT nStatus = PHS_SUCCESS;
Kevin McKinney29794602012-05-26 12:05:12 -04001199 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001200
Matthias Beyerca89a292014-07-15 09:42:54 +02001201 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
1202 "Inside CreateClassifierPHSRule");
Kevin McKinney6c259f42013-02-20 23:25:27 -05001203
1204 if (psaClassifiertable == NULL)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001205 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001206
Kevin McKinney69493872013-02-20 23:25:28 -05001207 if (eClsContext == eOldClassifierRuleContext) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001208 /*
1209 * If An Old Entry for this classifier ID already exists in the
1210 * old rules table replace it.
1211 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001212
Matthias Beyerca89a292014-07-15 09:42:54 +02001213 iClassifierIndex = GetClassifierEntry(psaClassifiertable,
1214 uiClsId,
1215 eClsContext,
1216 &psClassifierRules);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001217
Kevin McKinney69493872013-02-20 23:25:28 -05001218 if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001219 /*
Kevin McKinney14b3a402013-02-20 23:25:29 -05001220 * The Classifier already exists in the old rules table
1221 * Lets replace the old classifier with the new one.
1222 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001223 bFreeEntryFound = TRUE;
1224 }
1225 }
1226
Kevin McKinney69493872013-02-20 23:25:28 -05001227 if (!bFreeEntryFound) {
Kevin McKinney14b3a402013-02-20 23:25:29 -05001228 /* Continue to search for a free location to add the rule */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001229 for (iClassifierIndex = 0; iClassifierIndex <
Kevin McKinney69493872013-02-20 23:25:28 -05001230 MAX_PHSRULE_PER_SF; iClassifierIndex++) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001231 if (eClsContext == eActiveClassifierRuleContext)
Kevin McKinney6c259f42013-02-20 23:25:27 -05001232 psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001233 else
Kevin McKinney6c259f42013-02-20 23:25:27 -05001234 psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001235
Kevin McKinney69493872013-02-20 23:25:28 -05001236 if (!psClassifierRules->bUsed) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001237 bFreeEntryFound = TRUE;
1238 break;
1239 }
1240 }
1241 }
1242
Kevin McKinney69493872013-02-20 23:25:28 -05001243 if (!bFreeEntryFound) {
1244
Kevin McKinney6c259f42013-02-20 23:25:27 -05001245 if (eClsContext == eActiveClassifierRuleContext)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001246 return ERR_CLSASSIFIER_TABLE_FULL;
Kevin McKinney69493872013-02-20 23:25:28 -05001247 else {
Matthias Beyere86bd612014-07-15 09:43:15 +02001248 /* Lets replace the oldest rule if we are looking in
1249 * old Rule table */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001250 if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF)
Kevin McKinney6c259f42013-02-20 23:25:27 -05001251 psaClassifiertable->uiOldestPhsRuleIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001252
Matthias Beyerca89a292014-07-15 09:42:54 +02001253 iClassifierIndex =
1254 psaClassifiertable->uiOldestPhsRuleIndex;
1255 psClassifierRules =
1256 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001257
Kevin McKinney6c259f42013-02-20 23:25:27 -05001258 (psaClassifiertable->uiOldestPhsRuleIndex)++;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001259 }
1260 }
1261
Kevin McKinney69493872013-02-20 23:25:28 -05001262 if (eClsContext == eOldClassifierRuleContext) {
1263
1264 if (psClassifierRules->pstPhsRule == NULL) {
1265
Matthias Beyerca89a292014-07-15 09:42:54 +02001266 psClassifierRules->pstPhsRule =
1267 kmalloc(sizeof(struct bcm_phs_rule),
1268 GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001269
Kevin McKinney6c259f42013-02-20 23:25:27 -05001270 if (NULL == psClassifierRules->pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001271 return ERR_PHSRULE_MEMALLOC_FAIL;
1272 }
1273
1274 psClassifierRules->bUsed = TRUE;
1275 psClassifierRules->uiClassifierRuleId = uiClsId;
1276 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
Matthias Beyerca89a292014-07-15 09:42:54 +02001277 psClassifierRules->bUnclassifiedPHSRule =
1278 psPhsRule->bUnclassifiedPHSRule;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001279
Kevin McKinney6c259f42013-02-20 23:25:27 -05001280 /* Update The PHS rule */
Matthias Beyerca89a292014-07-15 09:42:54 +02001281 memcpy(psClassifierRules->pstPhsRule, psPhsRule,
1282 sizeof(struct bcm_phs_rule));
Kevin McKinney69493872013-02-20 23:25:28 -05001283 } else
Matthias Beyerca89a292014-07-15 09:42:54 +02001284 nStatus = UpdateClassifierPHSRule(uiClsId,
1285 psClassifierRules,
1286 psaClassifiertable,
1287 psPhsRule,
1288 u8AssociatedPHSI);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001289
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001290 return nStatus;
1291}
1292
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001293static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
Matthias Beyerca89a292014-07-15 09:42:54 +02001294 IN struct bcm_phs_classifier_entry *pstClassifierEntry,
1295 struct bcm_phs_classifier_table *psaClassifiertable,
1296 struct bcm_phs_rule *psPhsRule,
1297 B_UINT8 u8AssociatedPHSI)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001298{
Kevin McKinneya903d652012-12-20 00:31:34 -05001299 struct bcm_phs_rule *pstAddPhsRule = NULL;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001300 UINT nPhsRuleIndex = 0;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001301 bool bPHSRuleOrphaned = false;
Kevin McKinney29794602012-05-26 12:05:12 -04001302 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001303
1304 psPhsRule->u8RefCnt = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001305
Kevin McKinney14b3a402013-02-20 23:25:29 -05001306 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001307 bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable,
1308 pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001309
Matthias Beyere86bd612014-07-15 09:43:15 +02001310 /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in
1311 * Classifier table for this SF */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001312 nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI,
Matthias Beyerca89a292014-07-15 09:42:54 +02001313 eActiveClassifierRuleContext,
1314 &pstAddPhsRule);
Kevin McKinney69493872013-02-20 23:25:28 -05001315 if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) {
1316
Matthias Beyerca89a292014-07-15 09:42:54 +02001317 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
1318 DBG_LVL_ALL,
1319 "\nAdding New PHSRuleEntry For Classifier");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001320
Kevin McKinney69493872013-02-20 23:25:28 -05001321 if (psPhsRule->u8PHSI == 0) {
Matthias Beyerca89a292014-07-15 09:42:54 +02001322 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
1323 DBG_LVL_ALL, "\nError PHSI is Zero\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001324 return ERR_PHS_INVALID_PHS_RULE;
1325 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001326
Matthias Beyere86bd612014-07-15 09:43:15 +02001327 /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for
1328 * uiClsId */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001329 if (false == bPHSRuleOrphaned) {
Kevin McKinney69493872013-02-20 23:25:28 -05001330
Matthias Beyerca89a292014-07-15 09:42:54 +02001331 pstClassifierEntry->pstPhsRule =
1332 kmalloc(sizeof(struct bcm_phs_rule),
1333 GFP_KERNEL);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001334 if (NULL == pstClassifierEntry->pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001335 return ERR_PHSRULE_MEMALLOC_FAIL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001336 }
Matthias Beyerca89a292014-07-15 09:42:54 +02001337 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule,
1338 sizeof(struct bcm_phs_rule));
Kevin McKinney69493872013-02-20 23:25:28 -05001339 } else {
Matthias Beyere86bd612014-07-15 09:43:15 +02001340 /* Step 2.b PHS Rule Exists Tie uiClsId with the existing
1341 * PHS Rule */
Matthias Beyerca89a292014-07-15 09:42:54 +02001342 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
1343 DBG_LVL_ALL,
1344 "\nTying Classifier to Existing PHS Rule");
Kevin McKinney69493872013-02-20 23:25:28 -05001345 if (bPHSRuleOrphaned) {
Stephen Hemminger082e8892010-11-01 09:35:21 -04001346 kfree(pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001347 pstClassifierEntry->pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001348 }
1349 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001350 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001351
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001352 pstClassifierEntry->bUsed = TRUE;
1353 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1354 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1355 pstClassifierEntry->pstPhsRule->u8RefCnt++;
Matthias Beyerca89a292014-07-15 09:42:54 +02001356 pstClassifierEntry->bUnclassifiedPHSRule =
1357 pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001358
1359 return PHS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001360}
1361
Matthias Beyerca89a292014-07-15 09:42:54 +02001362static bool DerefPhsRule(IN B_UINT16 uiClsId,
1363 struct bcm_phs_classifier_table *psaClassifiertable,
1364 struct bcm_phs_rule *pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001365{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001366 if (pstPhsRule == NULL)
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001367 return false;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001368
1369 if (pstPhsRule->u8RefCnt)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001370 pstPhsRule->u8RefCnt--;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001371
Matthias Beyer3be738a2014-07-15 09:43:14 +02001372 return (0 == pstPhsRule->u8RefCnt);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001373}
1374
Matthias Beyerc50e0b52014-07-15 09:42:56 +02001375static void dbg_print_st_cls_entry(struct bcm_mini_adapter *ad,
1376 struct bcm_phs_entry *st_serv_flow_entry,
1377 struct bcm_phs_classifier_entry *st_cls_entry)
1378{
1379 int k;
1380
1381 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", st_serv_flow_entry->uiVcid);
1382 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", st_cls_entry->uiClassifierRuleId);
1383 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", st_cls_entry->u8PHSI);
1384 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
1385 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", st_cls_entry->pstPhsRule->u8PHSI);
1386 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", st_cls_entry->pstPhsRule->u8PHSFLength);
1387 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
1388
1389 for (k = 0 ; k < st_cls_entry->pstPhsRule->u8PHSFLength; k++)
1390 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSF[k]);
1391 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", st_cls_entry->pstPhsRule->u8PHSMLength);
1392 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
1393
1394 for (k = 0; k < st_cls_entry->pstPhsRule->u8PHSMLength; k++)
1395 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSM[k]);
1396 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", st_cls_entry->pstPhsRule->u8PHSS);
1397 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", st_cls_entry->pstPhsRule->u8PHSV);
1398 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
1399}
1400
Matthias Beyer20d174e2014-07-15 09:42:55 +02001401static void phsrules_per_sf_dbg_print(struct bcm_mini_adapter *ad,
1402 struct bcm_phs_entry *st_serv_flow_entry)
1403{
1404 int j, l;
1405 struct bcm_phs_classifier_entry st_cls_entry;
1406
1407 for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
1408
1409 for (l = 0; l < 2; l++) {
1410
1411 if (l == 0) {
1412 st_cls_entry = st_serv_flow_entry->pstClassifierTable->stActivePhsRulesList[j];
1413 if (st_cls_entry.bUsed)
1414 BCM_DEBUG_PRINT(ad,
1415 DBG_TYPE_OTHERS,
1416 DUMP_INFO,
1417 (DBG_LVL_ALL | DBG_NO_FUNC_PRINT),
1418 "\n Active PHS Rule :\n");
1419 } else {
1420 st_cls_entry = st_serv_flow_entry->pstClassifierTable->stOldPhsRulesList[j];
1421 if (st_cls_entry.bUsed)
1422 BCM_DEBUG_PRINT(ad,
1423 DBG_TYPE_OTHERS,
1424 DUMP_INFO,
1425 (DBG_LVL_ALL | DBG_NO_FUNC_PRINT),
1426 "\n Old PHS Rule :\n");
1427 }
1428
1429 if (st_cls_entry.bUsed) {
Matthias Beyerc50e0b52014-07-15 09:42:56 +02001430 dbg_print_st_cls_entry(ad,
1431 st_serv_flow_entry,
1432 &st_cls_entry);
Matthias Beyer20d174e2014-07-15 09:42:55 +02001433 }
1434 }
1435 }
1436}
1437
Kevin McKinney60dadf92012-12-20 00:31:28 -05001438void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001439{
Matthias Beyer20d174e2014-07-15 09:42:55 +02001440 int i;
Kevin McKinney29794602012-05-26 12:05:12 -04001441 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001442
Matthias Beyerca89a292014-07-15 09:42:54 +02001443 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,
1444 "\n Dumping PHS Rules :\n");
Kevin McKinney6c259f42013-02-20 23:25:27 -05001445
Kevin McKinney69493872013-02-20 23:25:28 -05001446 for (i = 0; i < MAX_SERVICEFLOWS; i++) {
1447
Kevin McKinneydb134a62012-12-20 00:31:30 -05001448 struct bcm_phs_entry stServFlowEntry =
Kevin McKinney6c259f42013-02-20 23:25:27 -05001449 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
Kevin McKinney69493872013-02-20 23:25:28 -05001450
Matthias Beyer20d174e2014-07-15 09:42:55 +02001451 if (!stServFlowEntry.bUsed)
1452 continue;
Kevin McKinney69493872013-02-20 23:25:28 -05001453
Matthias Beyer20d174e2014-07-15 09:42:55 +02001454 phsrules_per_sf_dbg_print(Adapter, &stServFlowEntry);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001455 }
1456}
1457
Kevin McKinney14b3a402013-02-20 23:25:29 -05001458/*
1459 * Procedure: phs_decompress
1460 *
1461 * Description: This routine restores the static fields within the packet.
1462 *
1463 * Arguments:
1464 * in_buf - ptr to incoming packet buffer.
Matthias Beyere86bd612014-07-15 09:43:15 +02001465 * out_buf - ptr to output buffer where the suppressed
1466 * header is copied.
1467 * decomp_phs_rules - ptr to PHS rule.
1468 * header_size - ptr to field which holds the phss or
1469 * phsf_length.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001470 *
1471 * Returns:
Matthias Beyere86bd612014-07-15 09:43:15 +02001472 * size - The number of bytes of dynamic fields present with in the
1473 * incoming packet header.
1474 * 0 - If PHS rule is NULL.If PHSI is 0 indicateing packet as
1475 * uncompressed.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001476 */
Shalin Mehtaf2be6352013-09-17 00:42:17 -07001477static int phs_decompress(unsigned char *in_buf,
Matthias Beyerca89a292014-07-15 09:42:54 +02001478 unsigned char *out_buf,
1479 struct bcm_phs_rule *decomp_phs_rules,
1480 UINT *header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001481{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001482 int phss, size = 0;
Kevin McKinneya903d652012-12-20 00:31:34 -05001483 struct bcm_phs_rule *tmp_memb;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001484 int bit, i = 0;
1485 unsigned char *phsf, *phsm;
1486 int in_buf_len = *header_size - 1;
Kevin McKinney29794602012-05-26 12:05:12 -04001487 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001488
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001489 in_buf++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001490
Matthias Beyerca89a292014-07-15 09:42:54 +02001491 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
1492 "====>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001493 *header_size = 0;
1494
Masanari Iidaa2745cc2014-06-17 23:48:54 +09001495 if (decomp_phs_rules == NULL)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001496 return 0;
1497
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001498 tmp_memb = decomp_phs_rules;
Kevin McKinney14b3a402013-02-20 23:25:29 -05001499 /*
Matthias Beyere86bd612014-07-15 09:43:15 +02001500 * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,
1501 * "\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
Kevin McKinney14b3a402013-02-20 23:25:29 -05001502 * header_size = tmp_memb->u8PHSFLength;
1503 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001504 phss = tmp_memb->u8PHSS;
1505 phsf = tmp_memb->u8PHSF;
1506 phsm = tmp_memb->u8PHSM;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001507
Kevin McKinney6c259f42013-02-20 23:25:27 -05001508 if (phss > MAX_PHS_LENGTHS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001509 phss = MAX_PHS_LENGTHS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001510
Kevin McKinney14b3a402013-02-20 23:25:29 -05001511 /*
Matthias Beyere86bd612014-07-15 09:43:15 +02001512 * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,
1513 * "\nDECOMP:
Kevin McKinney14b3a402013-02-20 23:25:29 -05001514 * In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
1515 */
Kevin McKinney69493872013-02-20 23:25:28 -05001516 while ((phss > 0) && (size < in_buf_len)) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001517 bit = ((*phsm << i) & SUPPRESS);
1518
Kevin McKinney69493872013-02-20 23:25:28 -05001519 if (bit == SUPPRESS) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001520 *out_buf = *phsf;
Matthias Beyerca89a292014-07-15 09:42:54 +02001521 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
1522 DBG_LVL_ALL,
1523 "\nDECOMP:In phss %d phsf %d output %d",
Kevin McKinney6c259f42013-02-20 23:25:27 -05001524 phss, *phsf, *out_buf);
Kevin McKinney69493872013-02-20 23:25:28 -05001525 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001526 *out_buf = *in_buf;
Matthias Beyerca89a292014-07-15 09:42:54 +02001527 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
1528 DBG_LVL_ALL,
1529 "\nDECOMP:In phss %d input %d output %d",
Kevin McKinney6c259f42013-02-20 23:25:27 -05001530 phss, *in_buf, *out_buf);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001531 in_buf++;
1532 size++;
1533 }
1534 out_buf++;
1535 phsf++;
1536 phss--;
1537 i++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001538 *header_size = *header_size + 1;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001539
Kevin McKinney69493872013-02-20 23:25:28 -05001540 if (i > MAX_NO_BIT) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001541 i = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001542 phsm++;
1543 }
1544 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001545
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001546 return size;
1547}
1548
Kevin McKinney14b3a402013-02-20 23:25:29 -05001549/*
1550 * Procedure: phs_compress
1551 *
Matthias Beyere86bd612014-07-15 09:43:15 +02001552 * Description: This routine suppresses the static fields within the packet.
1553 * Before that it will verify the fields to be suppressed with the corresponding
1554 * fields in the phsf. For verification it checks the phsv field of PHS rule.
1555 * If set and verification succeeds it suppresses the field.If any one static
1556 * field is found different none of the static fields are suppressed then the
1557 * packet is sent as uncompressed packet with phsi=0.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001558 *
1559 * Arguments:
1560 * phs_rule - ptr to PHS rule.
1561 * in_buf - ptr to incoming packet buffer.
Matthias Beyere86bd612014-07-15 09:43:15 +02001562 * out_buf - ptr to output buffer where the suppressed header is
1563 * copied.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001564 * header_size - ptr to field which holds the phss.
1565 *
1566 * Returns:
Matthias Beyere86bd612014-07-15 09:43:15 +02001567 * size - The number of bytes copied into the output buffer i.e
1568 * dynamic fields
1569 * 0 - If PHS rule is NULL.If PHSV field is not set. If the
1570 * verification fails.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001571 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001572static int phs_compress(struct bcm_phs_rule *phs_rule,
1573 unsigned char *in_buf,
1574 unsigned char *out_buf,
1575 UINT *header_size,
1576 UINT *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001577{
1578 unsigned char *old_addr = out_buf;
Peter Meerwaldb38e2742012-06-13 20:44:35 +02001579 int suppress = 0;
Kevin McKinney29794602012-05-26 12:05:12 -04001580 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinney6c259f42013-02-20 23:25:27 -05001581
Kevin McKinney69493872013-02-20 23:25:28 -05001582 if (phs_rule == NULL) {
Matthias Beyerca89a292014-07-15 09:42:54 +02001583 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
1584 "\nphs_compress(): phs_rule null!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001585 *out_buf = ZERO_PHSI;
1586 return STATUS_PHS_NOCOMPRESSION;
1587 }
1588
Kevin McKinney6c259f42013-02-20 23:25:27 -05001589 if (phs_rule->u8PHSS <= *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001590 *header_size = phs_rule->u8PHSS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001591 else
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001592 *header_size = *new_header_size;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001593
Kevin McKinney14b3a402013-02-20 23:25:29 -05001594 /* To copy PHSI */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001595 out_buf++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001596 suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF,
1597 phs_rule->u8PHSM, phs_rule->u8PHSS,
1598 phs_rule->u8PHSV, new_header_size);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001599
Kevin McKinney69493872013-02-20 23:25:28 -05001600 if (suppress == STATUS_PHS_COMPRESSED) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001601 *old_addr = (unsigned char)phs_rule->u8PHSI;
Matthias Beyerca89a292014-07-15 09:42:54 +02001602 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
1603 "\nCOMP:In phs_compress phsi %d",
1604 phs_rule->u8PHSI);
Kevin McKinney69493872013-02-20 23:25:28 -05001605 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001606 *old_addr = ZERO_PHSI;
Matthias Beyerca89a292014-07-15 09:42:54 +02001607 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
1608 "\nCOMP:In phs_compress PHSV Verification failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001609 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001610
Peter Meerwaldb38e2742012-06-13 20:44:35 +02001611 return suppress;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001612}
1613
Kevin McKinney14b3a402013-02-20 23:25:29 -05001614/*
1615 * Procedure: verify_suppress_phsf
1616 *
1617 * Description: This routine verifies the fields of the packet and if all the
1618 * static fields are equal it adds the phsi of that PHS rule.If any static
1619 * field differs it woun't suppress any field.
1620 *
1621 * Arguments:
1622 * rules_set - ptr to classifier_rules.
1623 * in_buffer - ptr to incoming packet buffer.
1624 * out_buffer - ptr to output buffer where the suppressed header is copied.
Matthias Beyere86bd612014-07-15 09:43:15 +02001625 * phsf - ptr to phsf.
1626 * phsm - ptr to phsm.
1627 * phss - variable holding phss.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001628 *
1629 * Returns:
Matthias Beyere86bd612014-07-15 09:43:15 +02001630 * size - The number of bytes copied into the output buffer i.e dynamic
1631 * fields.
1632 * 0 - Packet has failed the verification.
Kevin McKinney14b3a402013-02-20 23:25:29 -05001633 */
Kevin McKinney6c259f42013-02-20 23:25:27 -05001634static int verify_suppress_phsf(unsigned char *in_buffer,
1635 unsigned char *out_buffer,
1636 unsigned char *phsf,
1637 unsigned char *phsm,
1638 unsigned int phss,
1639 unsigned int phsv,
1640 UINT *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001641{
Kevin McKinney6c259f42013-02-20 23:25:27 -05001642 unsigned int size = 0;
1643 int bit, i = 0;
Kevin McKinney29794602012-05-26 12:05:12 -04001644 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001645
Matthias Beyerca89a292014-07-15 09:42:54 +02001646 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
1647 "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001648
Kevin McKinney6c259f42013-02-20 23:25:27 -05001649 if (phss > (*new_header_size))
Kevin McKinney6c259f42013-02-20 23:25:27 -05001650 phss = *new_header_size;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001651
Kevin McKinney69493872013-02-20 23:25:28 -05001652 while (phss > 0) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001653 bit = ((*phsm << i) & SUPPRESS);
Kevin McKinney69493872013-02-20 23:25:28 -05001654 if (bit == SUPPRESS) {
1655 if (*in_buffer != *phsf) {
1656 if (phsv == VERIFY) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001657 BCM_DEBUG_PRINT(Adapter,
1658 DBG_TYPE_OTHERS,
1659 PHS_SEND,
1660 DBG_LVL_ALL,
1661 "\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",
1662 phss,
1663 *in_buffer,
1664 *phsf);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001665 return STATUS_PHS_NOCOMPRESSION;
1666 }
Kevin McKinney69493872013-02-20 23:25:28 -05001667 } else
Kevin McKinney6c259f42013-02-20 23:25:27 -05001668 BCM_DEBUG_PRINT(Adapter,
1669 DBG_TYPE_OTHERS,
1670 PHS_SEND,
1671 DBG_LVL_ALL,
1672 "\nCOMP:In verify_phsf success for field %d buf %d phsf %d",
1673 phss,
1674 *in_buffer,
1675 *phsf);
Kevin McKinney69493872013-02-20 23:25:28 -05001676 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001677 *out_buffer = *in_buffer;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001678 BCM_DEBUG_PRINT(Adapter,
1679 DBG_TYPE_OTHERS,
1680 PHS_SEND,
1681 DBG_LVL_ALL,
1682 "\nCOMP:In copying_header input %d out %d",
1683 *in_buffer,
1684 *out_buffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001685 out_buffer++;
1686 size++;
1687 }
Kevin McKinney6c259f42013-02-20 23:25:27 -05001688
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001689 in_buffer++;
1690 phsf++;
1691 phss--;
1692 i++;
Kevin McKinney6c259f42013-02-20 23:25:27 -05001693
Kevin McKinney69493872013-02-20 23:25:28 -05001694 if (i > MAX_NO_BIT) {
Kevin McKinney6c259f42013-02-20 23:25:27 -05001695 i = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001696 phsm++;
1697 }
1698 }
Matthias Beyerca89a292014-07-15 09:42:54 +02001699 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
1700 "\nCOMP:In verify_phsf success");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001701 *new_header_size = size;
1702 return STATUS_PHS_COMPRESSED;
1703}