• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file Qos.C
3  * This file contains the routines related to Quality of Service.
4 */
5 #include "headers.h"
6 
7 static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
8 			    PVOID pvEthPayload,
9 			    struct bcm_eth_packet_info *pstEthCsPktInfo);
10 
11 static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
12 			     struct sk_buff *skb,
13 			     struct bcm_eth_packet_info *pstEthCsPktInfo,
14 			     struct bcm_classifier_rule *pstClassifierRule,
15 			     B_UINT8 EthCSCupport);
16 
17 static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd,
18 			 struct bcm_classifier_rule *pstClassifierRule);
19 
20 static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex);
21 
22 
23 /*******************************************************************
24 * Function    - MatchSrcIpAddress()
25 *
26 * Description - Checks whether the Source IP address from the packet
27 *				matches with that of Queue.
28 *
29 * Parameters  - pstClassifierRule: Pointer to the packet info structure.
30 *		- ulSrcIP	    : Source IP address from the packet.
31 *
32 * Returns     - TRUE(If address matches) else FAIL .
33 *********************************************************************/
MatchSrcIpAddress(struct bcm_classifier_rule * pstClassifierRule,ULONG ulSrcIP)34 static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule,
35 			      ULONG ulSrcIP)
36 {
37 	UCHAR ucLoopIndex = 0;
38 
39 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
40 	union u_ip_address	*src_addr;
41 
42 	ulSrcIP = ntohl(ulSrcIP);
43 	if (0 == pstClassifierRule->ucIPSourceAddressLength)
44 		return TRUE;
45 	for (ucLoopIndex = 0;
46 	     ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);
47 	     ucLoopIndex++) {
48 		src_addr = &pstClassifierRule->stSrcIpAddress;
49 		BCM_DEBUG_PRINT(Adapter,
50 				DBG_TYPE_TX,
51 				IPV4_DBG,
52 				DBG_LVL_ALL,
53 				"Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x",
54 				(UINT)src_addr->ulIpv4Mask[ucLoopIndex],
55 				(UINT)ulSrcIP,
56 				(UINT)src_addr->ulIpv6Addr[ucLoopIndex]);
57 
58 		if ((src_addr->ulIpv4Mask[ucLoopIndex] & ulSrcIP) ==
59 				(src_addr->ulIpv4Addr[ucLoopIndex] &
60 				 src_addr->ulIpv4Mask[ucLoopIndex]))
61 			return TRUE;
62 	}
63 	BCM_DEBUG_PRINT(Adapter,
64 			DBG_TYPE_TX,
65 			IPV4_DBG,
66 			DBG_LVL_ALL,
67 			"Src Ip Address Not Matched");
68 	return false;
69 }
70 
71 
72 /*******************************************************************
73 * Function    - MatchDestIpAddress()
74 *
75 * Description - Checks whether the Destination IP address from the packet
76 *				matches with that of Queue.
77 *
78 * Parameters  - pstClassifierRule: Pointer to the packet info structure.
79 *		- ulDestIP    : Destination IP address from the packet.
80 *
81 * Returns     - TRUE(If address matches) else FAIL .
82 *********************************************************************/
MatchDestIpAddress(struct bcm_classifier_rule * pstClassifierRule,ULONG ulDestIP)83 static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP)
84 {
85 	UCHAR ucLoopIndex = 0;
86 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
87 	union u_ip_address	*dest_addr = &pstClassifierRule->stDestIpAddress;
88 
89 	ulDestIP = ntohl(ulDestIP);
90 	if (0 == pstClassifierRule->ucIPDestinationAddressLength)
91 		return TRUE;
92 	BCM_DEBUG_PRINT(Adapter,
93 			DBG_TYPE_TX,
94 			IPV4_DBG,
95 			DBG_LVL_ALL,
96 			"Destination Ip Address 0x%x 0x%x 0x%x  ",
97 			(UINT)ulDestIP,
98 			(UINT)dest_addr->ulIpv4Mask[ucLoopIndex],
99 			(UINT)dest_addr->ulIpv4Addr[ucLoopIndex]);
100 
101 	for (ucLoopIndex = 0;
102 	     ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength);
103 	     ucLoopIndex++) {
104 		if ((dest_addr->ulIpv4Mask[ucLoopIndex] & ulDestIP) ==
105 				(dest_addr->ulIpv4Addr[ucLoopIndex] &
106 				 dest_addr->ulIpv4Mask[ucLoopIndex]))
107 			return TRUE;
108 	}
109 	BCM_DEBUG_PRINT(Adapter,
110 			DBG_TYPE_TX,
111 			IPV4_DBG,
112 			DBG_LVL_ALL,
113 			"Destination Ip Address Not Matched");
114 	return false;
115 }
116 
117 
118 /************************************************************************
119 * Function    - MatchTos()
120 *
121 * Description - Checks the TOS from the packet matches with that of queue.
122 *
123 * Parameters  - pstClassifierRule   : Pointer to the packet info structure.
124 *		- ucTypeOfService: TOS from the packet.
125 *
126 * Returns     - TRUE(If address matches) else FAIL.
127 **************************************************************************/
MatchTos(struct bcm_classifier_rule * pstClassifierRule,UCHAR ucTypeOfService)128 static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule,
129 		     UCHAR ucTypeOfService)
130 {
131 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
132 
133 	if (3 != pstClassifierRule->ucIPTypeOfServiceLength)
134 		return TRUE;
135 
136 	if (((pstClassifierRule->ucTosMask & ucTypeOfService) <=
137 				pstClassifierRule->ucTosHigh) &&
138 			((pstClassifierRule->ucTosMask & ucTypeOfService) >=
139 				pstClassifierRule->ucTosLow))
140 		return TRUE;
141 
142 	BCM_DEBUG_PRINT(Adapter,
143 			DBG_TYPE_TX,
144 			IPV4_DBG,
145 			DBG_LVL_ALL,
146 			"Type Of Service Not Matched");
147 	return false;
148 }
149 
150 
151 /***************************************************************************
152 * Function    - MatchProtocol()
153 *
154 * Description - Checks the protocol from the packet matches with that of queue.
155 *
156 * Parameters  - pstClassifierRule: Pointer to the packet info structure.
157 *		- ucProtocol	: Protocol from the packet.
158 *
159 * Returns     - TRUE(If address matches) else FAIL.
160 ****************************************************************************/
MatchProtocol(struct bcm_classifier_rule * pstClassifierRule,UCHAR ucProtocol)161 bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,
162 		   UCHAR ucProtocol)
163 {
164 	UCHAR ucLoopIndex = 0;
165 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
166 
167 	if (0 == pstClassifierRule->ucProtocolLength)
168 		return TRUE;
169 	for (ucLoopIndex = 0;
170 	     ucLoopIndex < pstClassifierRule->ucProtocolLength;
171 	     ucLoopIndex++) {
172 		BCM_DEBUG_PRINT(Adapter,
173 				DBG_TYPE_TX,
174 				IPV4_DBG,
175 				DBG_LVL_ALL,
176 				"Protocol:0x%X Classification Protocol:0x%X",
177 				ucProtocol,
178 				pstClassifierRule->ucProtocol[ucLoopIndex]);
179 		if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol)
180 			return TRUE;
181 	}
182 	BCM_DEBUG_PRINT(Adapter,
183 			DBG_TYPE_TX,
184 			IPV4_DBG,
185 			DBG_LVL_ALL,
186 			"Protocol Not Matched");
187 	return false;
188 }
189 
190 
191 /***********************************************************************
192 * Function    - MatchSrcPort()
193 *
194 * Description - Checks, Source port from the packet matches with that of queue.
195 *
196 * Parameters  - pstClassifierRule: Pointer to the packet info structure.
197 *		- ushSrcPort	: Source port from the packet.
198 *
199 * Returns     - TRUE(If address matches) else FAIL.
200 ***************************************************************************/
MatchSrcPort(struct bcm_classifier_rule * pstClassifierRule,USHORT ushSrcPort)201 bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,
202 		  USHORT ushSrcPort)
203 {
204 	UCHAR ucLoopIndex = 0;
205 
206 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
207 
208 
209 	if (0 == pstClassifierRule->ucSrcPortRangeLength)
210 		return TRUE;
211 	for (ucLoopIndex = 0;
212 	     ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength;
213 	     ucLoopIndex++) {
214 		if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] &&
215 			ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex])
216 			return TRUE;
217 	}
218 	BCM_DEBUG_PRINT(Adapter,
219 			DBG_TYPE_TX,
220 			IPV4_DBG,
221 			DBG_LVL_ALL,
222 			"Src Port: %x Not Matched ",
223 			ushSrcPort);
224 	return false;
225 }
226 
227 
228 /***********************************************************************
229 * Function    - MatchDestPort()
230 *
231 * Description - Checks, Destination port from packet matches with that of queue.
232 *
233 * Parameters  - pstClassifierRule: Pointer to the packet info structure.
234 *		- ushDestPort	: Destination port from the packet.
235 *
236 * Returns     - TRUE(If address matches) else FAIL.
237 ***************************************************************************/
MatchDestPort(struct bcm_classifier_rule * pstClassifierRule,USHORT ushDestPort)238 bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,
239 		   USHORT ushDestPort)
240 {
241 	UCHAR ucLoopIndex = 0;
242 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
243 
244 	if (0 == pstClassifierRule->ucDestPortRangeLength)
245 		return TRUE;
246 
247 	for (ucLoopIndex = 0;
248 	     ucLoopIndex < pstClassifierRule->ucDestPortRangeLength;
249 	     ucLoopIndex++) {
250 		BCM_DEBUG_PRINT(Adapter,
251 				DBG_TYPE_TX,
252 				IPV4_DBG,
253 				DBG_LVL_ALL,
254 				"Matching Port:0x%X   0x%X  0x%X",
255 				ushDestPort,
256 				pstClassifierRule->usDestPortRangeLo[ucLoopIndex],
257 				pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
258 
259 		if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] &&
260 			ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex])
261 			return TRUE;
262 	}
263 	BCM_DEBUG_PRINT(Adapter,
264 			DBG_TYPE_TX,
265 			IPV4_DBG,
266 			DBG_LVL_ALL,
267 			"Dest Port: %x Not Matched",
268 			ushDestPort);
269 	return false;
270 }
271 /**
272  * @ingroup tx_functions
273  * Compares IPV4 Ip address and port number
274  * @return Queue Index.
275 */
IpVersion4(struct bcm_mini_adapter * Adapter,struct iphdr * iphd,struct bcm_classifier_rule * pstClassifierRule)276 static USHORT	IpVersion4(struct bcm_mini_adapter *Adapter,
277 			   struct iphdr *iphd,
278 			   struct bcm_classifier_rule *pstClassifierRule)
279 {
280 	struct bcm_transport_header *xprt_hdr = NULL;
281 	bool	bClassificationSucceed = false;
282 
283 	BCM_DEBUG_PRINT(Adapter,
284 			DBG_TYPE_TX,
285 			IPV4_DBG,
286 			DBG_LVL_ALL,
287 			"========>");
288 
289 	xprt_hdr = (struct bcm_transport_header *)((PUCHAR)iphd + sizeof(struct iphdr));
290 
291 	BCM_DEBUG_PRINT(Adapter,
292 			DBG_TYPE_TX,
293 			IPV4_DBG,
294 			DBG_LVL_ALL,
295 			"Trying to see Direction = %d %d",
296 			pstClassifierRule->ucDirection,
297 			pstClassifierRule->usVCID_Value);
298 
299 	/* Checking classifier validity */
300 	if (!pstClassifierRule->bUsed ||
301 			pstClassifierRule->ucDirection == DOWNLINK_DIR)
302 		goto out;
303 
304 	BCM_DEBUG_PRINT(Adapter,
305 			DBG_TYPE_TX,
306 			IPV4_DBG,
307 			DBG_LVL_ALL,
308 			"is IPv6 check!");
309 	if (pstClassifierRule->bIpv6Protocol)
310 		goto out;
311 
312 	/* Checking IP header parameter */
313 	BCM_DEBUG_PRINT(Adapter,
314 			DBG_TYPE_TX,
315 			IPV4_DBG,
316 			DBG_LVL_ALL,
317 			"Trying to match Source IP Address");
318 	if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr))
319 		goto out;
320 	BCM_DEBUG_PRINT(Adapter,
321 			DBG_TYPE_TX,
322 			IPV4_DBG,
323 			DBG_LVL_ALL,
324 			"Source IP Address Matched");
325 
326 	if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr))
327 		goto out;
328 	BCM_DEBUG_PRINT(Adapter,
329 			DBG_TYPE_TX,
330 			IPV4_DBG,
331 			DBG_LVL_ALL,
332 			"Destination IP Address Matched");
333 
334 	if (!MatchTos(pstClassifierRule, iphd->tos)) {
335 		BCM_DEBUG_PRINT(Adapter,
336 				DBG_TYPE_TX,
337 				IPV4_DBG,
338 				DBG_LVL_ALL,
339 				"TOS Match failed\n");
340 		goto out;
341 	}
342 	BCM_DEBUG_PRINT(Adapter,
343 			DBG_TYPE_TX,
344 			IPV4_DBG,
345 			DBG_LVL_ALL,
346 			"TOS Matched");
347 
348 	if (!MatchProtocol(pstClassifierRule, iphd->protocol))
349 		goto out;
350 	BCM_DEBUG_PRINT(Adapter,
351 			DBG_TYPE_TX,
352 			IPV4_DBG,
353 			DBG_LVL_ALL,
354 			"Protocol Matched");
355 
356 	/*
357 	 * if protocol is not TCP or UDP then no
358 	 * need of comparing source port and destination port
359 	 */
360 	if (iphd->protocol != TCP && iphd->protocol != UDP) {
361 		bClassificationSucceed = TRUE;
362 		goto out;
363 	}
364 	/* Checking Transport Layer Header field if present */
365 	BCM_DEBUG_PRINT(Adapter,
366 			DBG_TYPE_TX,
367 			IPV4_DBG,
368 			DBG_LVL_ALL,
369 			"Source Port %04x",
370 			(iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source);
371 
372 	if (!MatchSrcPort(pstClassifierRule,
373 			  ntohs((iphd->protocol == UDP) ?
374 			  xprt_hdr->uhdr.source : xprt_hdr->thdr.source)))
375 		goto out;
376 	BCM_DEBUG_PRINT(Adapter,
377 			DBG_TYPE_TX,
378 			IPV4_DBG,
379 			DBG_LVL_ALL,
380 			"Src Port Matched");
381 
382 	BCM_DEBUG_PRINT(Adapter,
383 			DBG_TYPE_TX,
384 			IPV4_DBG,
385 			DBG_LVL_ALL,
386 			"Destination Port %04x",
387 			(iphd->protocol == UDP) ? xprt_hdr->uhdr.dest :
388 				xprt_hdr->thdr.dest);
389 
390 	if (!MatchDestPort(pstClassifierRule,
391 			   ntohs((iphd->protocol == UDP) ?
392 			   xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest)))
393 		goto out;
394 	bClassificationSucceed = TRUE;
395 
396 out:
397 	if (TRUE == bClassificationSucceed) {
398 		INT iMatchedSFQueueIndex = 0;
399 
400 		iMatchedSFQueueIndex =
401 			SearchSfid(Adapter, pstClassifierRule->ulSFID);
402 		if (iMatchedSFQueueIndex >= NO_OF_QUEUES)
403 			bClassificationSucceed = false;
404 		else if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
405 			bClassificationSucceed = false;
406 	}
407 
408 	BCM_DEBUG_PRINT(Adapter,
409 			DBG_TYPE_TX,
410 			IPV4_DBG,
411 			DBG_LVL_ALL,
412 			"IpVersion4 <==========");
413 
414 	return bClassificationSucceed;
415 }
416 
PruneQueueAllSF(struct bcm_mini_adapter * Adapter)417 VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter)
418 {
419 	UINT iIndex = 0;
420 
421 	for (iIndex = 0; iIndex < HiPriority; iIndex++) {
422 		if (!Adapter->PackInfo[iIndex].bValid)
423 			continue;
424 
425 		PruneQueue(Adapter, iIndex);
426 	}
427 }
428 
429 
430 /**
431  * @ingroup tx_functions
432  * This function checks if the max queue size for a queue
433  * is less than number of bytes in the queue. If so -
434  * drops packets from the Head till the number of bytes is
435  * less than or equal to max queue size for the queue.
436  */
PruneQueue(struct bcm_mini_adapter * Adapter,INT iIndex)437 static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex)
438 {
439 	struct sk_buff *PacketToDrop = NULL;
440 	struct net_device_stats *netstats;
441 	struct bcm_packet_info	*curr_pack_info = &Adapter->PackInfo[iIndex];
442 
443 	BCM_DEBUG_PRINT(Adapter,
444 			DBG_TYPE_TX,
445 			PRUNE_QUEUE,
446 			DBG_LVL_ALL,
447 			"=====> Index %d",
448 			iIndex);
449 
450 	if (iIndex == HiPriority)
451 		return;
452 
453 	if (!Adapter || (iIndex < 0) || (iIndex > HiPriority))
454 		return;
455 
456 	/* To Store the netdevice statistic */
457 	netstats = &Adapter->dev->stats;
458 
459 	spin_lock_bh(&curr_pack_info->SFQueueLock);
460 
461 	while (1) {
462 /*	while((UINT)curr_pack_info->uiCurrentPacketsOnHost >
463 		SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { */
464 
465 		BCM_DEBUG_PRINT(Adapter,
466 				DBG_TYPE_TX,
467 				PRUNE_QUEUE,
468 				DBG_LVL_ALL,
469 				"uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
470 				curr_pack_info->uiCurrentBytesOnHost,
471 				curr_pack_info->uiMaxBucketSize);
472 
473 		PacketToDrop = curr_pack_info->FirstTxQueue;
474 
475 		if (PacketToDrop == NULL)
476 			break;
477 		if ((curr_pack_info->uiCurrentPacketsOnHost <
478 					SF_MAX_ALLOWED_PACKETS_TO_BACKUP) &&
479 			((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb) +
480 					    SKB_CB_LATENCY_OFFSET))/HZ) <=
481 				curr_pack_info->uiMaxLatency))
482 			break;
483 
484 		if (PacketToDrop) {
485 			if (netif_msg_tx_err(Adapter))
486 				pr_info(PFX "%s: tx queue %d overlimit\n",
487 					Adapter->dev->name, iIndex);
488 
489 			netstats->tx_dropped++;
490 
491 			DEQUEUEPACKET(curr_pack_info->FirstTxQueue,
492 				      curr_pack_info->LastTxQueue);
493 			/* update current bytes and packets count */
494 			curr_pack_info->uiCurrentBytesOnHost -=
495 				PacketToDrop->len;
496 			curr_pack_info->uiCurrentPacketsOnHost--;
497 			/* update dropped bytes and packets counts */
498 			curr_pack_info->uiDroppedCountBytes += PacketToDrop->len;
499 			curr_pack_info->uiDroppedCountPackets++;
500 			dev_kfree_skb(PacketToDrop);
501 
502 		}
503 
504 		BCM_DEBUG_PRINT(Adapter,
505 				DBG_TYPE_TX,
506 				PRUNE_QUEUE,
507 				DBG_LVL_ALL,
508 				"Dropped Bytes:%x Dropped Packets:%x",
509 				curr_pack_info->uiDroppedCountBytes,
510 				curr_pack_info->uiDroppedCountPackets);
511 
512 		atomic_dec(&Adapter->TotalPacketCount);
513 	}
514 
515 	spin_unlock_bh(&curr_pack_info->SFQueueLock);
516 
517 	BCM_DEBUG_PRINT(Adapter,
518 			DBG_TYPE_TX,
519 			PRUNE_QUEUE,
520 			DBG_LVL_ALL,
521 			"TotalPacketCount:%x",
522 			atomic_read(&Adapter->TotalPacketCount));
523 	BCM_DEBUG_PRINT(Adapter,
524 			DBG_TYPE_TX,
525 			PRUNE_QUEUE,
526 			DBG_LVL_ALL,
527 			"<=====");
528 }
529 
flush_all_queues(struct bcm_mini_adapter * Adapter)530 VOID flush_all_queues(struct bcm_mini_adapter *Adapter)
531 {
532 	INT	iQIndex;
533 	UINT uiTotalPacketLength;
534 	struct sk_buff *PacketToDrop = NULL;
535 	struct bcm_packet_info *curr_packet_info;
536 
537 	BCM_DEBUG_PRINT(Adapter,
538 			DBG_TYPE_OTHERS,
539 			DUMP_INFO,
540 			DBG_LVL_ALL,
541 			"=====>");
542 
543 	/* down(&Adapter->data_packet_queue_lock); */
544 	for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) {
545 		struct net_device_stats *netstats = &Adapter->dev->stats;
546 
547 		curr_packet_info = &Adapter->PackInfo[iQIndex];
548 
549 		spin_lock_bh(&curr_packet_info->SFQueueLock);
550 		while (curr_packet_info->FirstTxQueue) {
551 			PacketToDrop = curr_packet_info->FirstTxQueue;
552 			if (PacketToDrop) {
553 				uiTotalPacketLength = PacketToDrop->len;
554 				netstats->tx_dropped++;
555 			} else
556 				uiTotalPacketLength = 0;
557 
558 			DEQUEUEPACKET(curr_packet_info->FirstTxQueue,
559 				      curr_packet_info->LastTxQueue);
560 
561 			/* Free the skb */
562 			dev_kfree_skb(PacketToDrop);
563 
564 			/* update current bytes and packets count */
565 			curr_packet_info->uiCurrentBytesOnHost -= uiTotalPacketLength;
566 			curr_packet_info->uiCurrentPacketsOnHost--;
567 
568 			/* update dropped bytes and packets counts */
569 			curr_packet_info->uiDroppedCountBytes += uiTotalPacketLength;
570 			curr_packet_info->uiDroppedCountPackets++;
571 
572 			BCM_DEBUG_PRINT(Adapter,
573 					DBG_TYPE_OTHERS,
574 					DUMP_INFO,
575 					DBG_LVL_ALL,
576 					"Dropped Bytes:%x Dropped Packets:%x",
577 					curr_packet_info->uiDroppedCountBytes,
578 					curr_packet_info->uiDroppedCountPackets);
579 			atomic_dec(&Adapter->TotalPacketCount);
580 		}
581 		spin_unlock_bh(&curr_packet_info->SFQueueLock);
582 	}
583 	/* up(&Adapter->data_packet_queue_lock); */
584 	BCM_DEBUG_PRINT(Adapter,
585 			DBG_TYPE_OTHERS,
586 			DUMP_INFO,
587 			DBG_LVL_ALL,
588 			"<=====");
589 }
590 
ClassifyPacket(struct bcm_mini_adapter * Adapter,struct sk_buff * skb)591 USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
592 {
593 	INT uiLoopIndex = 0;
594 	struct bcm_classifier_rule *pstClassifierRule = NULL;
595 	struct bcm_eth_packet_info stEthCsPktInfo;
596 	PVOID pvEThPayload = NULL;
597 	struct iphdr *pIpHeader = NULL;
598 	INT uiSfIndex = 0;
599 	USHORT usIndex = Adapter->usBestEffortQueueIndex;
600 	bool bFragmentedPkt = false, bClassificationSucceed = false;
601 	USHORT usCurrFragment = 0;
602 
603 	struct bcm_tcp_header *pTcpHeader;
604 	UCHAR IpHeaderLength;
605 	UCHAR TcpHeaderLength;
606 
607 	pvEThPayload = skb->data;
608 	*((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = 0;
609 	EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo);
610 
611 	switch (stEthCsPktInfo.eNwpktEthFrameType) {
612 	case eEth802LLCFrame:
613 		BCM_DEBUG_PRINT(Adapter,
614 				DBG_TYPE_TX,
615 				IPV4_DBG,
616 				DBG_LVL_ALL,
617 				"ClassifyPacket : 802LLCFrame\n");
618 		pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame);
619 		break;
620 	case eEth802LLCSNAPFrame:
621 		BCM_DEBUG_PRINT(Adapter,
622 				DBG_TYPE_TX,
623 				IPV4_DBG,
624 				DBG_LVL_ALL,
625 				"ClassifyPacket : 802LLC SNAP Frame\n");
626 		pIpHeader = pvEThPayload +
627 			sizeof(struct bcm_eth_llc_snap_frame);
628 		break;
629 	case eEth802QVLANFrame:
630 		BCM_DEBUG_PRINT(Adapter,
631 				DBG_TYPE_TX,
632 				IPV4_DBG,
633 				DBG_LVL_ALL,
634 				"ClassifyPacket : 802.1Q VLANFrame\n");
635 		pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame);
636 		break;
637 	case eEthOtherFrame:
638 		BCM_DEBUG_PRINT(Adapter,
639 				DBG_TYPE_TX,
640 				IPV4_DBG,
641 				DBG_LVL_ALL,
642 				"ClassifyPacket : ETH Other Frame\n");
643 		pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
644 		break;
645 	default:
646 		BCM_DEBUG_PRINT(Adapter,
647 				DBG_TYPE_TX,
648 				IPV4_DBG,
649 				DBG_LVL_ALL,
650 				"ClassifyPacket : Unrecognized ETH Frame\n");
651 		pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
652 		break;
653 	}
654 
655 	if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) {
656 		usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET);
657 		if ((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment)
658 			bFragmentedPkt = TRUE;
659 
660 		if (bFragmentedPkt) {
661 			/* Fragmented  Packet. Get Frag Classifier Entry. */
662 			pstClassifierRule = GetFragIPClsEntry(Adapter,
663 							      pIpHeader->id,
664 							      pIpHeader->saddr);
665 			if (pstClassifierRule) {
666 					BCM_DEBUG_PRINT(Adapter,
667 							DBG_TYPE_TX,
668 							IPV4_DBG,
669 							DBG_LVL_ALL,
670 							"It is next Fragmented pkt");
671 					bClassificationSucceed = TRUE;
672 			}
673 			if (!(ntohs(pIpHeader->frag_off) & IP_MF)) {
674 				/* Fragmented Last packet . Remove Frag Classifier Entry */
675 				BCM_DEBUG_PRINT(Adapter,
676 						DBG_TYPE_TX,
677 						IPV4_DBG,
678 						DBG_LVL_ALL,
679 						"This is the last fragmented Pkt");
680 				DelFragIPClsEntry(Adapter,
681 						  pIpHeader->id,
682 						  pIpHeader->saddr);
683 			}
684 		}
685 	}
686 
687 	for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) {
688 		if (bClassificationSucceed)
689 			break;
690 		/*
691 		 * Iterate through all classifiers which are already in order of priority
692 		 * to classify the packet until match found
693 		 */
694 		if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) {
695 			bClassificationSucceed = false;
696 			continue;
697 		}
698 		BCM_DEBUG_PRINT(Adapter,
699 				DBG_TYPE_TX,
700 				IPV4_DBG,
701 				DBG_LVL_ALL,
702 				"Adapter->PackInfo[%d].bvalid=True\n",
703 				uiLoopIndex);
704 
705 		if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) {
706 			bClassificationSucceed = false; /* cannot be processed for classification. */
707 			continue;	/* it is a down link connection */
708 		}
709 
710 		pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex];
711 
712 		uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
713 		if (uiSfIndex >= NO_OF_QUEUES) {
714 			BCM_DEBUG_PRINT(Adapter,
715 					DBG_TYPE_TX,
716 					IPV4_DBG,
717 					DBG_LVL_ALL,
718 					"Queue Not Valid. SearchSfid for this classifier Failed\n");
719 			continue;
720 		}
721 
722 		if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) {
723 
724 			if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) {
725 				BCM_DEBUG_PRINT(Adapter,
726 						DBG_TYPE_TX,
727 						IPV4_DBG,
728 						DBG_LVL_ALL,
729 						" ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
730 				bClassificationSucceed = false;
731 				continue;
732 			}
733 
734 
735 
736 			BCM_DEBUG_PRINT(Adapter,
737 					DBG_TYPE_TX,
738 					IPV4_DBG,
739 					DBG_LVL_ALL,
740 					"Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",
741 					pstClassifierRule->uiClassifierRuleIndex,
742 					Adapter->PackInfo[uiSfIndex].ulSFID);
743 			bClassificationSucceed = EThCSClassifyPkt(Adapter,
744 								  skb,
745 								  &stEthCsPktInfo,
746 								  pstClassifierRule,
747 								  Adapter->PackInfo[uiSfIndex].bEthCSSupport);
748 
749 			if (!bClassificationSucceed) {
750 				BCM_DEBUG_PRINT(Adapter,
751 						DBG_TYPE_TX,
752 						IPV4_DBG,
753 						DBG_LVL_ALL,
754 						"ClassifyPacket : Ethernet CS Classification Failed\n");
755 				continue;
756 			}
757 		} else { /* No ETH Supported on this SF */
758 			if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) {
759 				BCM_DEBUG_PRINT(Adapter,
760 						DBG_TYPE_TX,
761 						IPV4_DBG,
762 						DBG_LVL_ALL,
763 						" ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
764 				bClassificationSucceed = false;
765 				continue;
766 			}
767 		}
768 
769 		BCM_DEBUG_PRINT(Adapter,
770 				DBG_TYPE_TX,
771 				IPV4_DBG,
772 				DBG_LVL_ALL,
773 				"Proceeding to IP CS Clasification");
774 
775 		if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) {
776 
777 			if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) {
778 				BCM_DEBUG_PRINT(Adapter,
779 						DBG_TYPE_TX,
780 						IPV4_DBG,
781 						DBG_LVL_ALL,
782 						" ClassifyPacket : Packet is Not an IP Packet\n");
783 				bClassificationSucceed = false;
784 				continue;
785 			}
786 			BCM_DEBUG_PRINT(Adapter,
787 					DBG_TYPE_TX,
788 					IPV4_DBG,
789 					DBG_LVL_ALL,
790 					"Dump IP Header :\n");
791 			DumpFullPacket((PUCHAR)pIpHeader, 20);
792 
793 			if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
794 				bClassificationSucceed = IpVersion4(Adapter,
795 								    pIpHeader,
796 								    pstClassifierRule);
797 			else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet)
798 				bClassificationSucceed = IpVersion6(Adapter,
799 								    pIpHeader,
800 								    pstClassifierRule);
801 		}
802 	}
803 
804 	if (bClassificationSucceed == TRUE) {
805 		BCM_DEBUG_PRINT(Adapter,
806 				DBG_TYPE_TX,
807 				IPV4_DBG,
808 				DBG_LVL_ALL,
809 				"CF id : %d, SF ID is =%lu",
810 				pstClassifierRule->uiClassifierRuleIndex,
811 				pstClassifierRule->ulSFID);
812 
813 		/* Store The matched Classifier in SKB */
814 		*((UINT32 *)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) =
815 			pstClassifierRule->uiClassifierRuleIndex;
816 		if ((TCP == pIpHeader->protocol) && !bFragmentedPkt &&
817 				(ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <=
818 					skb->len)) {
819 			IpHeaderLength = pIpHeader->ihl;
820 			pTcpHeader =
821 				(struct bcm_tcp_header *)(((PUCHAR)pIpHeader) +
822 						(IpHeaderLength*4));
823 			TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
824 
825 			if ((pTcpHeader->ucFlags & TCP_ACK) &&
826 				   (ntohs(pIpHeader->tot_len) ==
827 				    (IpHeaderLength*4)+(TcpHeaderLength*4)))
828 				*((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) =
829 					TCP_ACK;
830 		}
831 
832 		usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
833 		BCM_DEBUG_PRINT(Adapter,
834 				DBG_TYPE_TX,
835 				IPV4_DBG,
836 				DBG_LVL_ALL,
837 				"index is =%d",
838 				usIndex);
839 
840 		/*
841 		 * If this is the first fragment of a Fragmented pkt,
842 		 * add this CF. Only This CF should be used for all other
843 		 * fragment of this Pkt.
844 		 */
845 		if (bFragmentedPkt && (usCurrFragment == 0)) {
846 			/*
847 			 * First Fragment of Fragmented Packet.
848 			 * Create Frag CLS Entry
849 			 */
850 			struct bcm_fragmented_packet_info stFragPktInfo;
851 
852 			stFragPktInfo.bUsed = TRUE;
853 			stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr;
854 			stFragPktInfo.usIpIdentification = pIpHeader->id;
855 			stFragPktInfo.pstMatchedClassifierEntry =
856 				pstClassifierRule;
857 			stFragPktInfo.bOutOfOrderFragment = false;
858 			AddFragIPClsEntry(Adapter, &stFragPktInfo);
859 		}
860 
861 
862 	}
863 
864 	return bClassificationSucceed ? usIndex : INVALID_QUEUE_INDEX;
865 }
866 
EthCSMatchSrcMACAddress(struct bcm_classifier_rule * pstClassifierRule,PUCHAR Mac)867 static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule,
868 				    PUCHAR Mac)
869 {
870 	UINT i = 0;
871 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
872 
873 	if (pstClassifierRule->ucEthCSSrcMACLen == 0)
874 		return TRUE;
875 	BCM_DEBUG_PRINT(Adapter,
876 			DBG_TYPE_TX,
877 			IPV4_DBG,
878 			DBG_LVL_ALL,
879 			"%s\n", __func__);
880 	for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
881 		BCM_DEBUG_PRINT(Adapter,
882 				DBG_TYPE_TX,
883 				IPV4_DBG,
884 				DBG_LVL_ALL,
885 				"SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
886 				i,
887 				Mac[i],
888 				pstClassifierRule->au8EThCSSrcMAC[i],
889 				pstClassifierRule->au8EThCSSrcMACMask[i]);
890 		if ((pstClassifierRule->au8EThCSSrcMAC[i] &
891 					pstClassifierRule->au8EThCSSrcMACMask[i]) !=
892 				(Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
893 			return false;
894 	}
895 	return TRUE;
896 }
897 
EthCSMatchDestMACAddress(struct bcm_classifier_rule * pstClassifierRule,PUCHAR Mac)898 static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule,
899 				     PUCHAR Mac)
900 {
901 	UINT i = 0;
902 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
903 
904 	if (pstClassifierRule->ucEthCSDestMACLen == 0)
905 		return TRUE;
906 	BCM_DEBUG_PRINT(Adapter,
907 			DBG_TYPE_TX,
908 			IPV4_DBG,
909 			DBG_LVL_ALL,
910 			"%s\n",
911 			__func__);
912 	for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
913 		BCM_DEBUG_PRINT(Adapter,
914 				DBG_TYPE_TX,
915 				IPV4_DBG,
916 				DBG_LVL_ALL,
917 				"SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
918 				i,
919 				Mac[i],
920 				pstClassifierRule->au8EThCSDestMAC[i],
921 				pstClassifierRule->au8EThCSDestMACMask[i]);
922 		if ((pstClassifierRule->au8EThCSDestMAC[i] &
923 					pstClassifierRule->au8EThCSDestMACMask[i]) !=
924 				(Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
925 			return false;
926 	}
927 	return TRUE;
928 }
929 
EthCSMatchEThTypeSAP(struct bcm_classifier_rule * pstClassifierRule,struct sk_buff * skb,struct bcm_eth_packet_info * pstEthCsPktInfo)930 static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,
931 				 struct sk_buff *skb,
932 				 struct bcm_eth_packet_info *pstEthCsPktInfo)
933 {
934 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
935 
936 	if ((pstClassifierRule->ucEtherTypeLen == 0) ||
937 		(pstClassifierRule->au8EthCSEtherType[0] == 0))
938 		return TRUE;
939 
940 	BCM_DEBUG_PRINT(Adapter,
941 			DBG_TYPE_TX,
942 			IPV4_DBG,
943 			DBG_LVL_ALL,
944 			"%s SrcEtherType:%x CLS EtherType[0]:%x\n",
945 			__func__,
946 			pstEthCsPktInfo->usEtherType,
947 			pstClassifierRule->au8EthCSEtherType[0]);
948 	if (pstClassifierRule->au8EthCSEtherType[0] == 1) {
949 		BCM_DEBUG_PRINT(Adapter,
950 				DBG_TYPE_TX,
951 				IPV4_DBG,
952 				DBG_LVL_ALL,
953 				"%s  CLS EtherType[1]:%x EtherType[2]:%x\n",
954 				__func__,
955 				pstClassifierRule->au8EthCSEtherType[1],
956 				pstClassifierRule->au8EthCSEtherType[2]);
957 
958 		if (memcmp(&pstEthCsPktInfo->usEtherType,
959 			   &pstClassifierRule->au8EthCSEtherType[1],
960 			   2) == 0)
961 			return TRUE;
962 		else
963 			return false;
964 	}
965 
966 	if (pstClassifierRule->au8EthCSEtherType[0] == 2) {
967 		if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
968 			return false;
969 
970 		BCM_DEBUG_PRINT(Adapter,
971 				DBG_TYPE_TX,
972 				IPV4_DBG,
973 				DBG_LVL_ALL,
974 				"%s  EthCS DSAP:%x EtherType[2]:%x\n",
975 				__func__,
976 				pstEthCsPktInfo->ucDSAP,
977 				pstClassifierRule->au8EthCSEtherType[2]);
978 		if (pstEthCsPktInfo->ucDSAP ==
979 				pstClassifierRule->au8EthCSEtherType[2])
980 			return TRUE;
981 		else
982 			return false;
983 
984 	}
985 
986 	return false;
987 
988 }
989 
EthCSMatchVLANRules(struct bcm_classifier_rule * pstClassifierRule,struct sk_buff * skb,struct bcm_eth_packet_info * pstEthCsPktInfo)990 static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule,
991 				struct sk_buff *skb,
992 				struct bcm_eth_packet_info *pstEthCsPktInfo)
993 {
994 	bool bClassificationSucceed = false;
995 	USHORT usVLANID;
996 	B_UINT8 uPriority = 0;
997 	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
998 
999 	BCM_DEBUG_PRINT(Adapter,
1000 			DBG_TYPE_TX,
1001 			IPV4_DBG,
1002 			DBG_LVL_ALL,
1003 			"%s  CLS UserPrio:%x CLS VLANID:%x\n",
1004 			__func__,
1005 			ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),
1006 			pstClassifierRule->usVLANID);
1007 
1008 	/*
1009 	 * In case FW didn't receive the TLV,
1010 	 * the priority field should be ignored
1011 	 */
1012 	if (pstClassifierRule->usValidityBitMap &
1013 			(1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) {
1014 		if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
1015 				return false;
1016 
1017 		uPriority = (ntohs(*(USHORT *)(skb->data +
1018 				   sizeof(struct bcm_eth_header))) &
1019 				   0xF000) >> 13;
1020 
1021 		if ((uPriority >= pstClassifierRule->usUserPriority[0]) &&
1022 				(uPriority <=
1023 				 pstClassifierRule->usUserPriority[1]))
1024 			bClassificationSucceed = TRUE;
1025 
1026 		if (!bClassificationSucceed)
1027 			return false;
1028 	}
1029 
1030 	BCM_DEBUG_PRINT(Adapter,
1031 			DBG_TYPE_TX,
1032 			IPV4_DBG,
1033 			DBG_LVL_ALL,
1034 			"ETH CS 802.1 D  User Priority Rule Matched\n");
1035 
1036 	bClassificationSucceed = false;
1037 
1038 	if (pstClassifierRule->usValidityBitMap &
1039 			(1<<PKT_CLASSIFICATION_VLANID_VALID)) {
1040 		if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
1041 				return false;
1042 
1043 		usVLANID = ntohs(*(USHORT *)(skb->data +
1044 					sizeof(struct bcm_eth_header))) & 0xFFF;
1045 
1046 		BCM_DEBUG_PRINT(Adapter,
1047 				DBG_TYPE_TX,
1048 				IPV4_DBG,
1049 				DBG_LVL_ALL,
1050 				"%s  Pkt VLANID %x Priority: %d\n",
1051 				__func__,
1052 				usVLANID,
1053 				uPriority);
1054 
1055 		if (usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4))
1056 			bClassificationSucceed = TRUE;
1057 
1058 		if (!bClassificationSucceed)
1059 			return false;
1060 	}
1061 
1062 	BCM_DEBUG_PRINT(Adapter,
1063 			DBG_TYPE_TX,
1064 			IPV4_DBG,
1065 			DBG_LVL_ALL,
1066 			"ETH CS 802.1 Q VLAN ID Rule Matched\n");
1067 
1068 	return TRUE;
1069 }
1070 
1071 
EThCSClassifyPkt(struct bcm_mini_adapter * Adapter,struct sk_buff * skb,struct bcm_eth_packet_info * pstEthCsPktInfo,struct bcm_classifier_rule * pstClassifierRule,B_UINT8 EthCSCupport)1072 static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
1073 			     struct sk_buff *skb,
1074 			     struct bcm_eth_packet_info *pstEthCsPktInfo,
1075 			     struct bcm_classifier_rule *pstClassifierRule,
1076 			     B_UINT8 EthCSCupport)
1077 {
1078 	bool bClassificationSucceed = false;
1079 
1080 	bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,
1081 			((struct bcm_eth_header *)(skb->data))->au8SourceAddress);
1082 	if (!bClassificationSucceed)
1083 		return false;
1084 	BCM_DEBUG_PRINT(Adapter,
1085 			DBG_TYPE_TX,
1086 			IPV4_DBG,
1087 			DBG_LVL_ALL,
1088 			"ETH CS SrcMAC Matched\n");
1089 
1090 	bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,
1091 			((struct bcm_eth_header *)(skb->data))->au8DestinationAddress);
1092 	if (!bClassificationSucceed)
1093 		return false;
1094 	BCM_DEBUG_PRINT(Adapter,
1095 			DBG_TYPE_TX,
1096 			IPV4_DBG,
1097 			DBG_LVL_ALL,
1098 			"ETH CS DestMAC Matched\n");
1099 
1100 	/* classify on ETHType/802.2SAP TLV */
1101 	bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,
1102 						      skb,
1103 						      pstEthCsPktInfo);
1104 	if (!bClassificationSucceed)
1105 		return false;
1106 
1107 	BCM_DEBUG_PRINT(Adapter,
1108 			DBG_TYPE_TX,
1109 			IPV4_DBG,
1110 			DBG_LVL_ALL,
1111 			"ETH CS EthType/802.2SAP Matched\n");
1112 
1113 	/* classify on 802.1VLAN Header Parameters */
1114 	bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,
1115 						     skb,
1116 						     pstEthCsPktInfo);
1117 	if (!bClassificationSucceed)
1118 		return false;
1119 	BCM_DEBUG_PRINT(Adapter,
1120 			DBG_TYPE_TX,
1121 			IPV4_DBG,
1122 			DBG_LVL_ALL,
1123 			"ETH CS 802.1 VLAN Rules Matched\n");
1124 
1125 	return bClassificationSucceed;
1126 }
1127 
EThCSGetPktInfo(struct bcm_mini_adapter * Adapter,PVOID pvEthPayload,struct bcm_eth_packet_info * pstEthCsPktInfo)1128 static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
1129 			    PVOID pvEthPayload,
1130 			    struct bcm_eth_packet_info *pstEthCsPktInfo)
1131 {
1132 	USHORT u16Etype = ntohs(
1133 			((struct bcm_eth_header *)pvEthPayload)->u16Etype);
1134 
1135 	BCM_DEBUG_PRINT(Adapter,
1136 			DBG_TYPE_TX,
1137 			IPV4_DBG,
1138 			DBG_LVL_ALL,
1139 			"EthCSGetPktInfo : Eth Hdr Type : %X\n",
1140 			u16Etype);
1141 	if (u16Etype > 0x5dc) {
1142 		BCM_DEBUG_PRINT(Adapter,
1143 				DBG_TYPE_TX,
1144 				IPV4_DBG,
1145 				DBG_LVL_ALL,
1146 				"EthCSGetPktInfo : ETH2 Frame\n");
1147 		/* ETH2 Frame */
1148 		if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN) {
1149 			/* 802.1Q VLAN Header */
1150 			pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame;
1151 			u16Etype = ((struct bcm_eth_q_frame *)pvEthPayload)->EthType;
1152 			/* ((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority */
1153 		} else {
1154 			pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame;
1155 			u16Etype = ntohs(u16Etype);
1156 		}
1157 	} else {
1158 		/* 802.2 LLC */
1159 		BCM_DEBUG_PRINT(Adapter,
1160 				DBG_TYPE_TX,
1161 				IPV4_DBG,
1162 				DBG_LVL_ALL,
1163 				"802.2 LLC Frame\n");
1164 		pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame;
1165 		pstEthCsPktInfo->ucDSAP =
1166 			((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP;
1167 		if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA) {
1168 			/* SNAP Frame */
1169 			pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame;
1170 			u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType;
1171 		}
1172 	}
1173 	if (u16Etype == ETHERNET_FRAMETYPE_IPV4)
1174 		pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet;
1175 	else if (u16Etype == ETHERNET_FRAMETYPE_IPV6)
1176 		pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet;
1177 	else
1178 		pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket;
1179 
1180 	pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype;
1181 	BCM_DEBUG_PRINT(Adapter,
1182 			DBG_TYPE_TX,
1183 			IPV4_DBG,
1184 			DBG_LVL_ALL,
1185 			"EthCsPktInfo->eNwpktIPFrameType : %x\n",
1186 			pstEthCsPktInfo->eNwpktIPFrameType);
1187 	BCM_DEBUG_PRINT(Adapter,
1188 			DBG_TYPE_TX,
1189 			IPV4_DBG,
1190 			DBG_LVL_ALL,
1191 			"EthCsPktInfo->eNwpktEthFrameType : %x\n",
1192 			pstEthCsPktInfo->eNwpktEthFrameType);
1193 	BCM_DEBUG_PRINT(Adapter,
1194 			DBG_TYPE_TX,
1195 			IPV4_DBG,
1196 			DBG_LVL_ALL,
1197 			"EthCsPktInfo->usEtherType : %x\n",
1198 			pstEthCsPktInfo->usEtherType);
1199 }
1200 
1201