Commit | Line | Data |
---|---|---|
f8942e07 SH |
1 | /** |
2 | @file Qos.C | |
3 | This file contains the routines related to Quality of Service. | |
4 | */ | |
5 | #include "headers.h" | |
6 | ||
7 | BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP); | |
8 | BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService); | |
9 | BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort); | |
10 | BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort); | |
11 | BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol); | |
12 | BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP); | |
13 | USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb); | |
14 | void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo); | |
15 | BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport); | |
16 | ||
17 | /******************************************************************* | |
18 | * Function - MatchSrcIpAddress() | |
19 | * | |
20 | * Description - Checks whether the Source IP address from the packet | |
21 | * matches with that of Queue. | |
22 | * | |
23 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
24 | * - ulSrcIP : Source IP address from the packet. | |
25 | * | |
26 | * Returns - TRUE(If address matches) else FAIL . | |
27 | *********************************************************************/ | |
28 | BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP) | |
29 | { | |
30 | UCHAR ucLoopIndex=0; | |
31 | ||
32 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
33 | ||
34 | ulSrcIP=ntohl(ulSrcIP); | |
35 | if(0 == pstClassifierRule->ucIPSourceAddressLength) | |
36 | return TRUE; | |
37 | for(ucLoopIndex=0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);ucLoopIndex++) | |
38 | { | |
39 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", (UINT)pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)ulSrcIP, (UINT)pstClassifierRule->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]); | |
40 | if((pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] & ulSrcIP)== | |
41 | (pstClassifierRule->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] )) | |
42 | { | |
43 | return TRUE; | |
44 | } | |
45 | } | |
46 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched"); | |
47 | return FALSE; | |
48 | } | |
49 | ||
50 | ||
51 | /******************************************************************* | |
52 | * Function - MatchDestIpAddress() | |
53 | * | |
54 | * Description - Checks whether the Destination IP address from the packet | |
55 | * matches with that of Queue. | |
56 | * | |
57 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
58 | * - ulDestIP : Destination IP address from the packet. | |
59 | * | |
60 | * Returns - TRUE(If address matches) else FAIL . | |
61 | *********************************************************************/ | |
62 | BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP) | |
63 | { | |
64 | UCHAR ucLoopIndex=0; | |
65 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
66 | ||
67 | ulDestIP=ntohl(ulDestIP); | |
68 | if(0 == pstClassifierRule->ucIPDestinationAddressLength) | |
69 | return TRUE; | |
70 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address 0x%x 0x%x 0x%x ", (UINT)ulDestIP, (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); | |
71 | ||
72 | for(ucLoopIndex=0;ucLoopIndex<(pstClassifierRule->ucIPDestinationAddressLength);ucLoopIndex++) | |
73 | { | |
74 | if((pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex] & ulDestIP)== | |
75 | (pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex])) | |
76 | { | |
77 | return TRUE; | |
78 | } | |
79 | } | |
80 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched"); | |
81 | return FALSE; | |
82 | } | |
83 | ||
84 | ||
85 | /************************************************************************ | |
86 | * Function - MatchTos() | |
87 | * | |
88 | * Description - Checks the TOS from the packet matches with that of queue. | |
89 | * | |
90 | * Parameters - pstClassifierRule : Pointer to the packet info structure. | |
91 | * - ucTypeOfService: TOS from the packet. | |
92 | * | |
93 | * Returns - TRUE(If address matches) else FAIL. | |
94 | **************************************************************************/ | |
95 | BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService) | |
96 | { | |
97 | ||
98 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
99 | if( 3 != pstClassifierRule->ucIPTypeOfServiceLength ) | |
100 | return TRUE; | |
101 | ||
102 | if(((pstClassifierRule->ucTosMask & ucTypeOfService)<=pstClassifierRule->ucTosHigh) && ((pstClassifierRule->ucTosMask & ucTypeOfService)>=pstClassifierRule->ucTosLow)) | |
103 | { | |
104 | return TRUE; | |
105 | } | |
106 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched"); | |
107 | return FALSE; | |
108 | } | |
109 | ||
110 | ||
111 | /*************************************************************************** | |
112 | * Function - MatchProtocol() | |
113 | * | |
114 | * Description - Checks the protocol from the packet matches with that of queue. | |
115 | * | |
116 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
117 | * - ucProtocol : Protocol from the packet. | |
118 | * | |
119 | * Returns - TRUE(If address matches) else FAIL. | |
120 | ****************************************************************************/ | |
121 | BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol) | |
122 | { | |
123 | UCHAR ucLoopIndex=0; | |
124 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
125 | if(0 == pstClassifierRule->ucProtocolLength) | |
126 | return TRUE; | |
127 | for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucProtocolLength;ucLoopIndex++) | |
128 | { | |
129 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol:0x%X Classification Protocol:0x%X",ucProtocol,pstClassifierRule->ucProtocol[ucLoopIndex]); | |
130 | if(pstClassifierRule->ucProtocol[ucLoopIndex]==ucProtocol) | |
131 | { | |
132 | return TRUE; | |
133 | } | |
134 | } | |
135 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched"); | |
136 | return FALSE; | |
137 | } | |
138 | ||
139 | ||
140 | /*********************************************************************** | |
141 | * Function - MatchSrcPort() | |
142 | * | |
143 | * Description - Checks, Source port from the packet matches with that of queue. | |
144 | * | |
145 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
146 | * - ushSrcPort : Source port from the packet. | |
147 | * | |
148 | * Returns - TRUE(If address matches) else FAIL. | |
149 | ***************************************************************************/ | |
150 | BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort) | |
151 | { | |
152 | UCHAR ucLoopIndex=0; | |
153 | ||
154 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
155 | ||
156 | ||
157 | if(0 == pstClassifierRule->ucSrcPortRangeLength) | |
158 | return TRUE; | |
159 | for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucSrcPortRangeLength;ucLoopIndex++) | |
160 | { | |
161 | if(ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] && | |
162 | ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex]) | |
163 | { | |
164 | return TRUE; | |
165 | } | |
166 | } | |
167 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ",ushSrcPort); | |
168 | return FALSE; | |
169 | } | |
170 | ||
171 | ||
172 | /*********************************************************************** | |
173 | * Function - MatchDestPort() | |
174 | * | |
175 | * Description - Checks, Destination port from packet matches with that of queue. | |
176 | * | |
177 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
178 | * - ushDestPort : Destination port from the packet. | |
179 | * | |
180 | * Returns - TRUE(If address matches) else FAIL. | |
181 | ***************************************************************************/ | |
182 | BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort) | |
183 | { | |
184 | UCHAR ucLoopIndex=0; | |
185 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
186 | ||
187 | if(0 == pstClassifierRule->ucDestPortRangeLength) | |
188 | return TRUE; | |
189 | ||
190 | for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucDestPortRangeLength;ucLoopIndex++) | |
191 | { | |
192 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Matching Port:0x%X 0x%X 0x%X",ushDestPort,pstClassifierRule->usDestPortRangeLo[ucLoopIndex],pstClassifierRule->usDestPortRangeHi[ucLoopIndex]); | |
193 | ||
194 | if(ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] && | |
195 | ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex]) | |
196 | { | |
197 | return TRUE; | |
198 | } | |
199 | } | |
200 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched",ushDestPort); | |
201 | return FALSE; | |
202 | } | |
203 | /** | |
204 | @ingroup tx_functions | |
205 | Compares IPV4 Ip address and port number | |
206 | @return Queue Index. | |
207 | */ | |
208 | USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ | |
209 | struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/ | |
210 | S_CLASSIFIER_RULE *pstClassifierRule ) | |
211 | { | |
212 | //IPHeaderFormat *pIpHeader=NULL; | |
213 | xporthdr *xprt_hdr=NULL; | |
214 | BOOLEAN bClassificationSucceed=FALSE; | |
215 | ||
216 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "========>"); | |
217 | ||
218 | xprt_hdr=(xporthdr *)((PUCHAR)iphd + sizeof(struct iphdr)); | |
219 | ||
220 | do { | |
221 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to see Direction = %d %d", | |
222 | pstClassifierRule->ucDirection, | |
223 | pstClassifierRule->usVCID_Value); | |
224 | ||
225 | //Checking classifier validity | |
226 | if(!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR) | |
227 | { | |
228 | bClassificationSucceed = FALSE; | |
229 | break; | |
230 | } | |
231 | ||
232 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "is IPv6 check!"); | |
233 | if(pstClassifierRule->bIpv6Protocol) | |
234 | break; | |
235 | ||
236 | //**************Checking IP header parameter**************************// | |
237 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to match Source IP Address"); | |
238 | if(FALSE == (bClassificationSucceed = | |
239 | MatchSrcIpAddress(pstClassifierRule, iphd->saddr))) | |
240 | break; | |
241 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched"); | |
242 | ||
243 | if(FALSE == (bClassificationSucceed = | |
244 | MatchDestIpAddress(pstClassifierRule, iphd->daddr))) | |
245 | break; | |
246 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched"); | |
247 | ||
248 | if(FALSE == (bClassificationSucceed = | |
249 | MatchTos(pstClassifierRule, iphd->tos))) | |
250 | { | |
251 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n"); | |
252 | break; | |
253 | } | |
254 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched"); | |
255 | ||
256 | if(FALSE == (bClassificationSucceed = | |
257 | MatchProtocol(pstClassifierRule,iphd->protocol))) | |
258 | break; | |
259 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched"); | |
260 | ||
261 | //if protocol is not TCP or UDP then no need of comparing source port and destination port | |
262 | if(iphd->protocol!=TCP && iphd->protocol!=UDP) | |
263 | break; | |
264 | #if 0 | |
265 | //check if memory is available of src and Dest port | |
266 | if(ETH_AND_IP_HEADER_LEN + L4_SRC_PORT_LEN + L4_DEST_PORT_LEN > Packet->len) | |
267 | { | |
268 | //This is not an erroneous condition and pkt will be checked for next classification. | |
269 | bClassificationSucceed = FALSE; | |
270 | break; | |
271 | } | |
272 | #endif | |
273 | //******************Checking Transport Layer Header field if present *****************// | |
274 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x", | |
275 | (iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source); | |
276 | ||
277 | if(FALSE == (bClassificationSucceed = | |
278 | MatchSrcPort(pstClassifierRule, | |
279 | ntohs((iphd->protocol == UDP)? | |
280 | xprt_hdr->uhdr.source:xprt_hdr->thdr.source)))) | |
281 | break; | |
282 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port Matched"); | |
283 | ||
284 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Port %04x", | |
285 | (iphd->protocol==UDP)?xprt_hdr->uhdr.dest: | |
286 | xprt_hdr->thdr.dest); | |
287 | if(FALSE == (bClassificationSucceed = | |
288 | MatchDestPort(pstClassifierRule, | |
289 | ntohs((iphd->protocol == UDP)? | |
290 | xprt_hdr->uhdr.dest:xprt_hdr->thdr.dest)))) | |
291 | break; | |
292 | } while(0); | |
293 | ||
294 | if(TRUE==bClassificationSucceed) | |
295 | { | |
296 | INT iMatchedSFQueueIndex = 0; | |
297 | iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); | |
298 | if(iMatchedSFQueueIndex >= NO_OF_QUEUES) | |
299 | { | |
300 | bClassificationSucceed = FALSE; | |
301 | } | |
302 | else | |
303 | { | |
304 | if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) | |
305 | { | |
306 | bClassificationSucceed = FALSE; | |
307 | } | |
308 | } | |
309 | } | |
310 | ||
311 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "IpVersion4 <=========="); | |
312 | ||
313 | return bClassificationSucceed; | |
314 | } | |
315 | /** | |
316 | @ingroup tx_functions | |
317 | @return Queue Index based on priority. | |
318 | */ | |
319 | USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */ | |
320 | struct sk_buff* Packet /**< Pointer to the Packet to be sent*/ | |
321 | ) | |
322 | { | |
323 | USHORT usIndex=-1; | |
324 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "=====>"); | |
325 | ||
326 | if(NULL==Adapter || NULL==Packet) | |
327 | { | |
328 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got NULL Values<======"); | |
329 | return -1; | |
330 | } | |
331 | ||
332 | usIndex = ClassifyPacket(Adapter,Packet); | |
333 | ||
334 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got Queue Index %x",usIndex); | |
335 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "GetPacketQueueIndex <=============="); | |
336 | return usIndex; | |
337 | } | |
338 | ||
339 | VOID PruneQueueAllSF(PMINI_ADAPTER Adapter) | |
340 | { | |
341 | UINT iIndex = 0; | |
342 | ||
343 | for(iIndex = 0; iIndex < HiPriority; iIndex++) | |
344 | { | |
345 | if(!Adapter->PackInfo[iIndex].bValid) | |
346 | continue; | |
347 | ||
348 | PruneQueue(Adapter, iIndex); | |
349 | } | |
350 | } | |
351 | ||
352 | ||
353 | /** | |
354 | @ingroup tx_functions | |
355 | This function checks if the max queue size for a queue | |
356 | is less than number of bytes in the queue. If so - | |
357 | drops packets from the Head till the number of bytes is | |
358 | less than or equal to max queue size for the queue. | |
359 | */ | |
360 | VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/ | |
361 | INT iIndex/**<Queue Index*/ | |
362 | ) | |
363 | { | |
364 | struct sk_buff* PacketToDrop=NULL; | |
365 | struct net_device_stats* netstats=NULL; | |
366 | ||
367 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d",iIndex); | |
368 | ||
369 | if(iIndex == HiPriority) | |
370 | return; | |
371 | ||
372 | if(!Adapter || (iIndex < 0) || (iIndex > HiPriority)) | |
373 | return; | |
374 | ||
375 | /* To Store the netdevice statistic */ | |
376 | netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; | |
377 | ||
378 | spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); | |
379 | ||
380 | while(1) | |
381 | // while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost > | |
382 | // SF_MAX_ALLOWED_PACKETS_TO_BACKUP) | |
383 | { | |
384 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x", | |
385 | Adapter->PackInfo[iIndex].uiCurrentBytesOnHost, | |
386 | Adapter->PackInfo[iIndex].uiMaxBucketSize); | |
387 | ||
388 | PacketToDrop = Adapter->PackInfo[iIndex].FirstTxQueue; | |
389 | ||
390 | if(PacketToDrop == NULL) | |
391 | break; | |
392 | if((Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost < SF_MAX_ALLOWED_PACKETS_TO_BACKUP) && | |
393 | ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb)+SKB_CB_LATENCY_OFFSET))/HZ) <= Adapter->PackInfo[iIndex].uiMaxLatency)) | |
394 | break; | |
395 | ||
396 | if(PacketToDrop) | |
397 | { | |
398 | if(netstats) | |
399 | netstats->tx_dropped++; | |
400 | atomic_inc(&Adapter->TxDroppedPacketCount); | |
401 | DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue, | |
402 | Adapter->PackInfo[iIndex].LastTxQueue); | |
403 | /// update current bytes and packets count | |
404 | Adapter->PackInfo[iIndex].uiCurrentBytesOnHost -= | |
405 | PacketToDrop->len; | |
406 | Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost--; | |
407 | /// update dropped bytes and packets counts | |
408 | Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len; | |
409 | Adapter->PackInfo[iIndex].uiDroppedCountPackets++; | |
410 | bcm_kfree_skb(PacketToDrop); | |
411 | ||
412 | } | |
413 | ||
414 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x", | |
415 | Adapter->PackInfo[iIndex].uiDroppedCountBytes, | |
416 | Adapter->PackInfo[iIndex].uiDroppedCountPackets); | |
417 | ||
418 | atomic_dec(&Adapter->TotalPacketCount); | |
419 | Adapter->bcm_jiffies = jiffies; | |
420 | } | |
421 | ||
422 | spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); | |
423 | ||
424 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "TotalPacketCount:%x", | |
425 | atomic_read(&Adapter->TotalPacketCount)); | |
426 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "<====="); | |
427 | } | |
428 | ||
429 | VOID flush_all_queues(PMINI_ADAPTER Adapter) | |
430 | { | |
431 | INT iQIndex; | |
432 | UINT uiTotalPacketLength; | |
433 | struct sk_buff* PacketToDrop=NULL; | |
434 | struct net_device_stats* netstats=NULL; | |
435 | ||
436 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>"); | |
437 | /* To Store the netdevice statistic */ | |
438 | netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; | |
439 | ||
440 | // down(&Adapter->data_packet_queue_lock); | |
441 | for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++) | |
442 | { | |
443 | spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); | |
444 | while(Adapter->PackInfo[iQIndex].FirstTxQueue) | |
445 | { | |
446 | PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; | |
447 | if(PacketToDrop) | |
448 | { | |
449 | uiTotalPacketLength = PacketToDrop->len; | |
450 | netstats->tx_dropped++; | |
451 | atomic_inc(&Adapter->TxDroppedPacketCount); | |
452 | } | |
453 | else | |
454 | uiTotalPacketLength = 0; | |
455 | ||
456 | DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, | |
457 | Adapter->PackInfo[iQIndex].LastTxQueue); | |
458 | ||
459 | /* Free the skb */ | |
460 | bcm_kfree_skb(PacketToDrop); | |
461 | ||
462 | /// update current bytes and packets count | |
463 | Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength; | |
464 | Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; | |
465 | ||
466 | /// update dropped bytes and packets counts | |
467 | Adapter->PackInfo[iQIndex].uiDroppedCountBytes += uiTotalPacketLength; | |
468 | Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; | |
469 | ||
470 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x", | |
471 | Adapter->PackInfo[iQIndex].uiDroppedCountBytes, | |
472 | Adapter->PackInfo[iQIndex].uiDroppedCountPackets); | |
473 | atomic_dec(&Adapter->TotalPacketCount); | |
474 | } | |
475 | spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); | |
476 | } | |
477 | // up(&Adapter->data_packet_queue_lock); | |
478 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "<====="); | |
479 | } | |
480 | ||
481 | USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) | |
482 | { | |
483 | INT uiLoopIndex=0; | |
484 | S_CLASSIFIER_RULE *pstClassifierRule = NULL; | |
485 | S_ETHCS_PKT_INFO stEthCsPktInfo; | |
486 | PVOID pvEThPayload = NULL; | |
487 | struct iphdr *pIpHeader = NULL; | |
488 | INT uiSfIndex=0; | |
489 | USHORT usIndex=Adapter->usBestEffortQueueIndex; | |
490 | BOOLEAN bFragmentedPkt=FALSE,bClassificationSucceed=FALSE; | |
491 | USHORT usCurrFragment =0; | |
492 | ||
493 | PTCP_HEADER pTcpHeader; | |
494 | UCHAR IpHeaderLength; | |
495 | UCHAR TcpHeaderLength; | |
496 | ||
497 | pvEThPayload = skb->data; | |
498 | *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = 0; | |
499 | EThCSGetPktInfo(Adapter,pvEThPayload,&stEthCsPktInfo); | |
500 | ||
501 | switch(stEthCsPktInfo.eNwpktEthFrameType) | |
502 | { | |
503 | case eEth802LLCFrame: | |
504 | { | |
505 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLCFrame\n"); | |
506 | pIpHeader = pvEThPayload + sizeof(ETH_CS_802_LLC_FRAME); | |
507 | break; | |
508 | } | |
509 | ||
510 | case eEth802LLCSNAPFrame: | |
511 | { | |
512 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLC SNAP Frame\n"); | |
513 | pIpHeader = pvEThPayload + sizeof(ETH_CS_802_LLC_SNAP_FRAME); | |
514 | break; | |
515 | } | |
516 | case eEth802QVLANFrame: | |
517 | { | |
518 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802.1Q VLANFrame\n"); | |
519 | pIpHeader = pvEThPayload + sizeof(ETH_CS_802_Q_FRAME); | |
520 | break; | |
521 | } | |
522 | case eEthOtherFrame: | |
523 | { | |
524 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : ETH Other Frame\n"); | |
525 | pIpHeader = pvEThPayload + sizeof(ETH_CS_ETH2_FRAME); | |
526 | break; | |
527 | } | |
528 | default: | |
529 | { | |
530 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Unrecognized ETH Frame\n"); | |
531 | pIpHeader = pvEThPayload + sizeof(ETH_CS_ETH2_FRAME); | |
532 | break; | |
533 | } | |
534 | } | |
535 | ||
536 | if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) | |
537 | { | |
538 | usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET); | |
539 | if((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment) | |
540 | bFragmentedPkt = TRUE; | |
541 | ||
542 | if(bFragmentedPkt) | |
543 | { | |
544 | //Fragmented Packet. Get Frag Classifier Entry. | |
545 | pstClassifierRule = GetFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr); | |
546 | if(pstClassifierRule) | |
547 | { | |
548 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"It is next Fragmented pkt"); | |
549 | bClassificationSucceed=TRUE; | |
550 | } | |
551 | if(!(ntohs(pIpHeader->frag_off) & IP_MF)) | |
552 | { | |
553 | //Fragmented Last packet . Remove Frag Classifier Entry | |
554 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"This is the last fragmented Pkt"); | |
555 | DelFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr); | |
556 | } | |
557 | } | |
558 | } | |
559 | ||
560 | for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) | |
561 | { | |
562 | if (Adapter->device_removed) | |
563 | { | |
564 | bClassificationSucceed = FALSE; | |
565 | break; | |
566 | } | |
567 | ||
568 | if(bClassificationSucceed) | |
569 | break; | |
570 | //Iterate through all classifiers which are already in order of priority | |
571 | //to classify the packet until match found | |
572 | do | |
573 | { | |
574 | if(FALSE==Adapter->astClassifierTable[uiLoopIndex].bUsed) | |
575 | { | |
576 | bClassificationSucceed=FALSE; | |
577 | break; | |
578 | } | |
579 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex); | |
580 | ||
581 | if(0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) | |
582 | { | |
583 | bClassificationSucceed=FALSE;//cannot be processed for classification. | |
584 | break; // it is a down link connection | |
585 | } | |
586 | ||
587 | pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex]; | |
588 | ||
589 | uiSfIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); | |
370adc7c | 590 | if (uiSfIndex >= NO_OF_QUEUES) { |
f8942e07 SH |
591 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Queue Not Valid. SearchSfid for this classifier Failed\n"); |
592 | break; | |
593 | } | |
594 | ||
595 | if(Adapter->PackInfo[uiSfIndex].bEthCSSupport) | |
596 | { | |
597 | ||
598 | if(eEthUnsupportedFrame==stEthCsPktInfo.eNwpktEthFrameType) | |
599 | { | |
600 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame \n"); | |
601 | bClassificationSucceed = FALSE; | |
602 | break; | |
603 | } | |
604 | ||
605 | ||
606 | ||
607 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",pstClassifierRule->uiClassifierRuleIndex,Adapter->PackInfo[uiSfIndex].ulSFID); | |
608 | bClassificationSucceed = EThCSClassifyPkt(Adapter,skb,&stEthCsPktInfo,pstClassifierRule, Adapter->PackInfo[uiSfIndex].bEthCSSupport); | |
609 | ||
610 | if(!bClassificationSucceed) | |
611 | { | |
612 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Ethernet CS Classification Failed\n"); | |
613 | break; | |
614 | } | |
615 | } | |
616 | ||
617 | else // No ETH Supported on this SF | |
618 | { | |
619 | if(eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) | |
620 | { | |
621 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF \n"); | |
622 | bClassificationSucceed = FALSE; | |
623 | break; | |
624 | } | |
625 | } | |
626 | ||
627 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Proceeding to IP CS Clasification"); | |
628 | ||
629 | if(Adapter->PackInfo[uiSfIndex].bIPCSSupport) | |
630 | { | |
631 | ||
632 | if(stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) | |
633 | { | |
634 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet \n"); | |
635 | bClassificationSucceed = FALSE; | |
636 | break; | |
637 | } | |
638 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dump IP Header : \n"); | |
639 | DumpFullPacket((PUCHAR)pIpHeader,20); | |
640 | ||
641 | if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) | |
642 | bClassificationSucceed = IpVersion4(Adapter,pIpHeader,pstClassifierRule); | |
643 | else if(stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet) | |
644 | bClassificationSucceed = IpVersion6(Adapter,pIpHeader,pstClassifierRule); | |
645 | } | |
646 | ||
647 | }while(0); | |
648 | } | |
649 | ||
650 | if(bClassificationSucceed == TRUE) | |
651 | { | |
652 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "CF id : %d, SF ID is =%lu",pstClassifierRule->uiClassifierRuleIndex, pstClassifierRule->ulSFID); | |
653 | ||
654 | //Store The matched Classifier in SKB | |
655 | *((UINT32*)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = pstClassifierRule->uiClassifierRuleIndex; | |
656 | if((TCP == pIpHeader->protocol ) && !bFragmentedPkt && (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= skb->len) ) | |
657 | { | |
658 | IpHeaderLength = pIpHeader->ihl; | |
659 | pTcpHeader = (PTCP_HEADER)(((PUCHAR)pIpHeader)+(IpHeaderLength*4)); | |
660 | TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength); | |
661 | ||
662 | if((pTcpHeader->ucFlags & TCP_ACK) && | |
663 | (ntohs(pIpHeader->tot_len) == (IpHeaderLength*4)+(TcpHeaderLength*4))) | |
664 | { | |
665 | *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = TCP_ACK; | |
666 | } | |
667 | } | |
668 | ||
669 | usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); | |
670 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "index is =%d", usIndex); | |
671 | ||
672 | //If this is the first fragment of a Fragmented pkt, add this CF. Only This CF should be used for all other fragment of this Pkt. | |
673 | if(bFragmentedPkt && (usCurrFragment == 0)) | |
674 | { | |
675 | //First Fragment of Fragmented Packet. Create Frag CLS Entry | |
676 | S_FRAGMENTED_PACKET_INFO stFragPktInfo; | |
677 | stFragPktInfo.bUsed = TRUE; | |
678 | stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr; | |
679 | stFragPktInfo.usIpIdentification = pIpHeader->id; | |
680 | stFragPktInfo.pstMatchedClassifierEntry = pstClassifierRule; | |
681 | stFragPktInfo.bOutOfOrderFragment = FALSE; | |
682 | AddFragIPClsEntry(Adapter,&stFragPktInfo); | |
683 | } | |
684 | ||
685 | ||
686 | } | |
687 | ||
688 | if(bClassificationSucceed) | |
689 | return usIndex; | |
690 | else | |
691 | return INVALID_QUEUE_INDEX; | |
692 | } | |
693 | ||
44a17eff | 694 | static BOOLEAN EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac) |
f8942e07 SH |
695 | { |
696 | UINT i=0; | |
697 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
698 | if(pstClassifierRule->ucEthCSSrcMACLen==0) | |
699 | return TRUE; | |
700 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__); | |
701 | for(i=0;i<MAC_ADDRESS_SIZE;i++) | |
702 | { | |
703 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i,Mac[i],pstClassifierRule->au8EThCSSrcMAC[i],pstClassifierRule->au8EThCSSrcMACMask[i]); | |
704 | if((pstClassifierRule->au8EThCSSrcMAC[i] & pstClassifierRule->au8EThCSSrcMACMask[i])!= | |
705 | (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i])) | |
706 | return FALSE; | |
707 | } | |
708 | return TRUE; | |
709 | } | |
710 | ||
44a17eff | 711 | static BOOLEAN EthCSMatchDestMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac) |
f8942e07 SH |
712 | { |
713 | UINT i=0; | |
714 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
715 | if(pstClassifierRule->ucEthCSDestMACLen==0) | |
716 | return TRUE; | |
717 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__); | |
718 | for(i=0;i<MAC_ADDRESS_SIZE;i++) | |
719 | { | |
720 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i,Mac[i],pstClassifierRule->au8EThCSDestMAC[i],pstClassifierRule->au8EThCSDestMACMask[i]); | |
721 | if((pstClassifierRule->au8EThCSDestMAC[i] & pstClassifierRule->au8EThCSDestMACMask[i])!= | |
722 | (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i])) | |
723 | return FALSE; | |
724 | } | |
725 | return TRUE; | |
726 | } | |
727 | ||
44a17eff | 728 | static BOOLEAN EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) |
f8942e07 SH |
729 | { |
730 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
731 | if((pstClassifierRule->ucEtherTypeLen==0)|| | |
732 | (pstClassifierRule->au8EthCSEtherType[0] == 0)) | |
733 | return TRUE; | |
734 | ||
735 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s SrcEtherType:%x CLS EtherType[0]:%x\n",__FUNCTION__,pstEthCsPktInfo->usEtherType,pstClassifierRule->au8EthCSEtherType[0]); | |
736 | if(pstClassifierRule->au8EthCSEtherType[0] == 1) | |
737 | { | |
738 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS EtherType[1]:%x EtherType[2]:%x\n",__FUNCTION__,pstClassifierRule->au8EthCSEtherType[1],pstClassifierRule->au8EthCSEtherType[2]); | |
739 | ||
740 | if(memcmp(&pstEthCsPktInfo->usEtherType,&pstClassifierRule->au8EthCSEtherType[1],2)==0) | |
741 | return TRUE; | |
742 | else | |
743 | return FALSE; | |
744 | } | |
745 | ||
746 | if(pstClassifierRule->au8EthCSEtherType[0] == 2) | |
747 | { | |
748 | if(eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType) | |
749 | return FALSE; | |
750 | ||
751 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s EthCS DSAP:%x EtherType[2]:%x\n",__FUNCTION__,pstEthCsPktInfo->ucDSAP,pstClassifierRule->au8EthCSEtherType[2]); | |
752 | if(pstEthCsPktInfo->ucDSAP == pstClassifierRule->au8EthCSEtherType[2]) | |
753 | return TRUE; | |
754 | else | |
755 | return FALSE; | |
756 | ||
757 | } | |
758 | ||
759 | return FALSE; | |
760 | ||
761 | } | |
762 | ||
44a17eff | 763 | static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) |
f8942e07 SH |
764 | { |
765 | BOOLEAN bClassificationSucceed = FALSE; | |
766 | USHORT usVLANID; | |
767 | B_UINT8 uPriority = 0; | |
768 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
769 | ||
770 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n",__FUNCTION__,ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),pstClassifierRule->usVLANID); | |
771 | ||
772 | /* In case FW didn't recieve the TLV, the priority field should be ignored */ | |
773 | if(pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) | |
774 | { | |
775 | if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame) | |
776 | return FALSE; | |
777 | ||
778 | uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xF000) >> 13; | |
779 | ||
780 | if((uPriority >= pstClassifierRule->usUserPriority[0]) && (uPriority <= pstClassifierRule->usUserPriority[1])) | |
781 | bClassificationSucceed = TRUE; | |
782 | ||
783 | if(!bClassificationSucceed) | |
784 | return FALSE; | |
785 | } | |
786 | ||
787 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 D User Priority Rule Matched\n"); | |
788 | ||
789 | bClassificationSucceed = FALSE; | |
790 | ||
791 | if(pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID)) | |
792 | { | |
793 | if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame) | |
794 | return FALSE; | |
795 | ||
796 | usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xFFF; | |
797 | ||
798 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__,usVLANID, uPriority); | |
799 | ||
800 | if(usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4)) | |
801 | bClassificationSucceed = TRUE; | |
802 | ||
803 | if(!bClassificationSucceed) | |
804 | return FALSE; | |
805 | } | |
806 | ||
807 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 Q VLAN ID Rule Matched\n"); | |
808 | ||
809 | return TRUE; | |
810 | } | |
811 | ||
812 | ||
813 | BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport) | |
814 | { | |
815 | BOOLEAN bClassificationSucceed = FALSE; | |
816 | bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress); | |
817 | if(!bClassificationSucceed) | |
818 | return FALSE; | |
819 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS SrcMAC Matched\n"); | |
820 | ||
821 | bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,((ETH_HEADER_STRUC*)(skb->data))->au8DestinationAddress); | |
822 | if(!bClassificationSucceed) | |
823 | return FALSE; | |
824 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS DestMAC Matched\n"); | |
825 | ||
826 | //classify on ETHType/802.2SAP TLV | |
827 | bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,skb,pstEthCsPktInfo); | |
828 | if(!bClassificationSucceed) | |
829 | return FALSE; | |
830 | ||
831 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS EthType/802.2SAP Matched\n"); | |
832 | ||
833 | //classify on 802.1VLAN Header Parameters | |
834 | ||
835 | bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,skb,pstEthCsPktInfo); | |
836 | if(!bClassificationSucceed) | |
837 | return FALSE; | |
838 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 VLAN Rules Matched\n"); | |
839 | ||
840 | return bClassificationSucceed; | |
841 | } | |
842 | ||
843 | void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo) | |
844 | { | |
845 | USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype); | |
846 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype); | |
847 | if(u16Etype > 0x5dc) | |
848 | { | |
849 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : ETH2 Frame \n"); | |
850 | //ETH2 Frame | |
851 | if(u16Etype == ETHERNET_FRAMETYPE_802QVLAN) | |
852 | { | |
853 | //802.1Q VLAN Header | |
854 | pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame; | |
855 | u16Etype = ((ETH_CS_802_Q_FRAME*)pvEthPayload)->EthType; | |
856 | //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority | |
857 | } | |
858 | else | |
859 | { | |
860 | pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame; | |
861 | u16Etype = ntohs(u16Etype); | |
862 | } | |
863 | ||
864 | } | |
865 | else | |
866 | { | |
867 | //802.2 LLC | |
868 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "802.2 LLC Frame \n"); | |
869 | pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame; | |
870 | pstEthCsPktInfo->ucDSAP = ((ETH_CS_802_LLC_FRAME*)pvEthPayload)->DSAP; | |
871 | if(pstEthCsPktInfo->ucDSAP == 0xAA && ((ETH_CS_802_LLC_FRAME*)pvEthPayload)->SSAP == 0xAA) | |
872 | { | |
873 | //SNAP Frame | |
874 | pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame; | |
875 | u16Etype = ((ETH_CS_802_LLC_SNAP_FRAME*)pvEthPayload)->usEtherType; | |
876 | } | |
877 | } | |
878 | if(u16Etype == ETHERNET_FRAMETYPE_IPV4) | |
879 | pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet; | |
880 | else if(u16Etype == ETHERNET_FRAMETYPE_IPV6) | |
881 | pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet; | |
882 | else | |
883 | pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket; | |
884 | ||
885 | pstEthCsPktInfo->usEtherType = ((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype; | |
886 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo->eNwpktIPFrameType); | |
887 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo->eNwpktEthFrameType); | |
888 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo->usEtherType); | |
889 | } | |
890 | ||
891 | ||
892 |