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