3 * This file contains the routines related to Quality of Service.
7 static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
9 struct bcm_eth_packet_info *pstEthCsPktInfo);
11 static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
13 struct bcm_eth_packet_info *pstEthCsPktInfo,
14 struct bcm_classifier_rule *pstClassifierRule,
15 B_UINT8 EthCSCupport);
17 static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd,
18 struct bcm_classifier_rule *pstClassifierRule);
20 static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex);
23 /*******************************************************************
24 * Function - MatchSrcIpAddress()
26 * Description - Checks whether the Source IP address from the packet
27 * matches with that of Queue.
29 * Parameters - pstClassifierRule: Pointer to the packet info structure.
30 * - ulSrcIP : Source IP address from the packet.
32 * Returns - TRUE(If address matches) else FAIL .
33 *********************************************************************/
34 static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule,
37 UCHAR ucLoopIndex = 0;
39 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
40 union u_ip_address *src_addr;
42 ulSrcIP = ntohl(ulSrcIP);
43 if (0 == pstClassifierRule->ucIPSourceAddressLength)
46 ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);
48 src_addr = &pstClassifierRule->stSrcIpAddress;
49 BCM_DEBUG_PRINT(Adapter,
53 "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x",
54 (UINT)src_addr->ulIpv4Mask[ucLoopIndex],
56 (UINT)src_addr->ulIpv6Addr[ucLoopIndex]);
58 if ((src_addr->ulIpv4Mask[ucLoopIndex] & ulSrcIP) ==
59 (src_addr->ulIpv4Addr[ucLoopIndex] &
60 src_addr->ulIpv4Mask[ucLoopIndex]))
63 BCM_DEBUG_PRINT(Adapter,
67 "Src Ip Address Not Matched");
72 /*******************************************************************
73 * Function - MatchDestIpAddress()
75 * Description - Checks whether the Destination IP address from the packet
76 * matches with that of Queue.
78 * Parameters - pstClassifierRule: Pointer to the packet info structure.
79 * - ulDestIP : Destination IP address from the packet.
81 * Returns - TRUE(If address matches) else FAIL .
82 *********************************************************************/
83 static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP)
85 UCHAR ucLoopIndex = 0;
86 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
87 union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress;
89 ulDestIP = ntohl(ulDestIP);
90 if (0 == pstClassifierRule->ucIPDestinationAddressLength)
92 BCM_DEBUG_PRINT(Adapter,
96 "Destination Ip Address 0x%x 0x%x 0x%x ",
98 (UINT)dest_addr->ulIpv4Mask[ucLoopIndex],
99 (UINT)dest_addr->ulIpv4Addr[ucLoopIndex]);
101 for (ucLoopIndex = 0;
102 ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength);
104 if ((dest_addr->ulIpv4Mask[ucLoopIndex] & ulDestIP) ==
105 (dest_addr->ulIpv4Addr[ucLoopIndex] &
106 dest_addr->ulIpv4Mask[ucLoopIndex]))
109 BCM_DEBUG_PRINT(Adapter,
113 "Destination Ip Address Not Matched");
118 /************************************************************************
119 * Function - MatchTos()
121 * Description - Checks the TOS from the packet matches with that of queue.
123 * Parameters - pstClassifierRule : Pointer to the packet info structure.
124 * - ucTypeOfService: TOS from the packet.
126 * Returns - TRUE(If address matches) else FAIL.
127 **************************************************************************/
128 static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule,
129 UCHAR ucTypeOfService)
131 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
133 if (3 != pstClassifierRule->ucIPTypeOfServiceLength)
136 if (((pstClassifierRule->ucTosMask & ucTypeOfService) <=
137 pstClassifierRule->ucTosHigh) &&
138 ((pstClassifierRule->ucTosMask & ucTypeOfService) >=
139 pstClassifierRule->ucTosLow))
142 BCM_DEBUG_PRINT(Adapter,
146 "Type Of Service Not Matched");
151 /***************************************************************************
152 * Function - MatchProtocol()
154 * Description - Checks the protocol from the packet matches with that of queue.
156 * Parameters - pstClassifierRule: Pointer to the packet info structure.
157 * - ucProtocol : Protocol from the packet.
159 * Returns - TRUE(If address matches) else FAIL.
160 ****************************************************************************/
161 bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,
164 UCHAR ucLoopIndex = 0;
165 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
167 if (0 == pstClassifierRule->ucProtocolLength)
169 for (ucLoopIndex = 0;
170 ucLoopIndex < pstClassifierRule->ucProtocolLength;
172 BCM_DEBUG_PRINT(Adapter,
176 "Protocol:0x%X Classification Protocol:0x%X",
178 pstClassifierRule->ucProtocol[ucLoopIndex]);
179 if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol)
182 BCM_DEBUG_PRINT(Adapter,
186 "Protocol Not Matched");
191 /***********************************************************************
192 * Function - MatchSrcPort()
194 * Description - Checks, Source port from the packet matches with that of queue.
196 * Parameters - pstClassifierRule: Pointer to the packet info structure.
197 * - ushSrcPort : Source port from the packet.
199 * Returns - TRUE(If address matches) else FAIL.
200 ***************************************************************************/
201 bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,
204 UCHAR ucLoopIndex = 0;
206 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
209 if (0 == pstClassifierRule->ucSrcPortRangeLength)
211 for (ucLoopIndex = 0;
212 ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength;
214 if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] &&
215 ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex])
218 BCM_DEBUG_PRINT(Adapter,
222 "Src Port: %x Not Matched ",
228 /***********************************************************************
229 * Function - MatchDestPort()
231 * Description - Checks, Destination port from packet matches with that of queue.
233 * Parameters - pstClassifierRule: Pointer to the packet info structure.
234 * - ushDestPort : Destination port from the packet.
236 * Returns - TRUE(If address matches) else FAIL.
237 ***************************************************************************/
238 bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,
241 UCHAR ucLoopIndex = 0;
242 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
244 if (0 == pstClassifierRule->ucDestPortRangeLength)
247 for (ucLoopIndex = 0;
248 ucLoopIndex < pstClassifierRule->ucDestPortRangeLength;
250 BCM_DEBUG_PRINT(Adapter,
254 "Matching Port:0x%X 0x%X 0x%X",
256 pstClassifierRule->usDestPortRangeLo[ucLoopIndex],
257 pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
259 if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] &&
260 ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex])
263 BCM_DEBUG_PRINT(Adapter,
267 "Dest Port: %x Not Matched",
272 * @ingroup tx_functions
273 * Compares IPV4 Ip address and port number
274 * @return Queue Index.
276 static USHORT IpVersion4(struct bcm_mini_adapter *Adapter,
278 struct bcm_classifier_rule *pstClassifierRule)
280 struct bcm_transport_header *xprt_hdr = NULL;
281 bool bClassificationSucceed = false;
283 BCM_DEBUG_PRINT(Adapter,
289 xprt_hdr = (struct bcm_transport_header *)((PUCHAR)iphd + sizeof(struct iphdr));
291 BCM_DEBUG_PRINT(Adapter,
295 "Trying to see Direction = %d %d",
296 pstClassifierRule->ucDirection,
297 pstClassifierRule->usVCID_Value);
299 /* Checking classifier validity */
300 if (!pstClassifierRule->bUsed ||
301 pstClassifierRule->ucDirection == DOWNLINK_DIR)
304 BCM_DEBUG_PRINT(Adapter,
309 if (pstClassifierRule->bIpv6Protocol)
312 /* Checking IP header parameter */
313 BCM_DEBUG_PRINT(Adapter,
317 "Trying to match Source IP Address");
318 if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr))
320 BCM_DEBUG_PRINT(Adapter,
324 "Source IP Address Matched");
326 if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr))
328 BCM_DEBUG_PRINT(Adapter,
332 "Destination IP Address Matched");
334 if (!MatchTos(pstClassifierRule, iphd->tos)) {
335 BCM_DEBUG_PRINT(Adapter,
339 "TOS Match failed\n");
342 BCM_DEBUG_PRINT(Adapter,
348 if (!MatchProtocol(pstClassifierRule, iphd->protocol))
350 BCM_DEBUG_PRINT(Adapter,
357 * if protocol is not TCP or UDP then no
358 * need of comparing source port and destination port
360 if (iphd->protocol != TCP && iphd->protocol != UDP) {
361 bClassificationSucceed = TRUE;
364 /* Checking Transport Layer Header field if present */
365 BCM_DEBUG_PRINT(Adapter,
370 (iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source);
372 if (!MatchSrcPort(pstClassifierRule,
373 ntohs((iphd->protocol == UDP) ?
374 xprt_hdr->uhdr.source : xprt_hdr->thdr.source)))
376 BCM_DEBUG_PRINT(Adapter,
382 BCM_DEBUG_PRINT(Adapter,
386 "Destination Port %04x",
387 (iphd->protocol == UDP) ? xprt_hdr->uhdr.dest :
388 xprt_hdr->thdr.dest);
390 if (!MatchDestPort(pstClassifierRule,
391 ntohs((iphd->protocol == UDP) ?
392 xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest)))
394 bClassificationSucceed = TRUE;
397 if (TRUE == bClassificationSucceed) {
398 INT iMatchedSFQueueIndex = 0;
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;
408 BCM_DEBUG_PRINT(Adapter,
412 "IpVersion4 <==========");
414 return bClassificationSucceed;
417 VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter)
421 for (iIndex = 0; iIndex < HiPriority; iIndex++) {
422 if (!Adapter->PackInfo[iIndex].bValid)
425 PruneQueue(Adapter, iIndex);
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.
437 static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex)
439 struct sk_buff *PacketToDrop = NULL;
440 struct net_device_stats *netstats;
441 struct bcm_packet_info *curr_pack_info = &Adapter->PackInfo[iIndex];
443 BCM_DEBUG_PRINT(Adapter,
450 if (iIndex == HiPriority)
453 if (!Adapter || (iIndex < 0) || (iIndex > HiPriority))
456 /* To Store the netdevice statistic */
457 netstats = &Adapter->dev->stats;
459 spin_lock_bh(&curr_pack_info->SFQueueLock);
462 /* while((UINT)curr_pack_info->uiCurrentPacketsOnHost >
463 SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { */
465 BCM_DEBUG_PRINT(Adapter,
469 "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
470 curr_pack_info->uiCurrentBytesOnHost,
471 curr_pack_info->uiMaxBucketSize);
473 PacketToDrop = curr_pack_info->FirstTxQueue;
475 if (PacketToDrop == NULL)
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))
485 if (netif_msg_tx_err(Adapter))
486 pr_info(PFX "%s: tx queue %d overlimit\n",
487 Adapter->dev->name, iIndex);
489 netstats->tx_dropped++;
491 DEQUEUEPACKET(curr_pack_info->FirstTxQueue,
492 curr_pack_info->LastTxQueue);
493 /* update current bytes and packets count */
494 curr_pack_info->uiCurrentBytesOnHost -=
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);
504 BCM_DEBUG_PRINT(Adapter,
508 "Dropped Bytes:%x Dropped Packets:%x",
509 curr_pack_info->uiDroppedCountBytes,
510 curr_pack_info->uiDroppedCountPackets);
512 atomic_dec(&Adapter->TotalPacketCount);
515 spin_unlock_bh(&curr_pack_info->SFQueueLock);
517 BCM_DEBUG_PRINT(Adapter,
521 "TotalPacketCount:%x",
522 atomic_read(&Adapter->TotalPacketCount));
523 BCM_DEBUG_PRINT(Adapter,
530 VOID flush_all_queues(struct bcm_mini_adapter *Adapter)
533 UINT uiTotalPacketLength;
534 struct sk_buff *PacketToDrop = NULL;
535 struct bcm_packet_info *curr_packet_info;
537 BCM_DEBUG_PRINT(Adapter,
543 /* down(&Adapter->data_packet_queue_lock); */
544 for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) {
545 struct net_device_stats *netstats = &Adapter->dev->stats;
547 curr_packet_info = &Adapter->PackInfo[iQIndex];
549 spin_lock_bh(&curr_packet_info->SFQueueLock);
550 while (curr_packet_info->FirstTxQueue) {
551 PacketToDrop = curr_packet_info->FirstTxQueue;
553 uiTotalPacketLength = PacketToDrop->len;
554 netstats->tx_dropped++;
556 uiTotalPacketLength = 0;
558 DEQUEUEPACKET(curr_packet_info->FirstTxQueue,
559 curr_packet_info->LastTxQueue);
562 dev_kfree_skb(PacketToDrop);
564 /* update current bytes and packets count */
565 curr_packet_info->uiCurrentBytesOnHost -= uiTotalPacketLength;
566 curr_packet_info->uiCurrentPacketsOnHost--;
568 /* update dropped bytes and packets counts */
569 curr_packet_info->uiDroppedCountBytes += uiTotalPacketLength;
570 curr_packet_info->uiDroppedCountPackets++;
572 BCM_DEBUG_PRINT(Adapter,
576 "Dropped Bytes:%x Dropped Packets:%x",
577 curr_packet_info->uiDroppedCountBytes,
578 curr_packet_info->uiDroppedCountPackets);
579 atomic_dec(&Adapter->TotalPacketCount);
581 spin_unlock_bh(&curr_packet_info->SFQueueLock);
583 /* up(&Adapter->data_packet_queue_lock); */
584 BCM_DEBUG_PRINT(Adapter,
591 USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
594 struct bcm_classifier_rule *pstClassifierRule = NULL;
595 struct bcm_eth_packet_info stEthCsPktInfo;
596 PVOID pvEThPayload = NULL;
597 struct iphdr *pIpHeader = NULL;
599 USHORT usIndex = Adapter->usBestEffortQueueIndex;
600 bool bFragmentedPkt = false, bClassificationSucceed = false;
601 USHORT usCurrFragment = 0;
603 struct bcm_tcp_header *pTcpHeader;
604 UCHAR IpHeaderLength;
605 UCHAR TcpHeaderLength;
607 pvEThPayload = skb->data;
608 *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = 0;
609 EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo);
611 switch (stEthCsPktInfo.eNwpktEthFrameType) {
612 case eEth802LLCFrame:
613 BCM_DEBUG_PRINT(Adapter,
617 "ClassifyPacket : 802LLCFrame\n");
618 pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame);
620 case eEth802LLCSNAPFrame:
621 BCM_DEBUG_PRINT(Adapter,
625 "ClassifyPacket : 802LLC SNAP Frame\n");
626 pIpHeader = pvEThPayload +
627 sizeof(struct bcm_eth_llc_snap_frame);
629 case eEth802QVLANFrame:
630 BCM_DEBUG_PRINT(Adapter,
634 "ClassifyPacket : 802.1Q VLANFrame\n");
635 pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame);
638 BCM_DEBUG_PRINT(Adapter,
642 "ClassifyPacket : ETH Other Frame\n");
643 pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
646 BCM_DEBUG_PRINT(Adapter,
650 "ClassifyPacket : Unrecognized ETH Frame\n");
651 pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
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;
660 if (bFragmentedPkt) {
661 /* Fragmented Packet. Get Frag Classifier Entry. */
662 pstClassifierRule = GetFragIPClsEntry(Adapter,
665 if (pstClassifierRule) {
666 BCM_DEBUG_PRINT(Adapter,
670 "It is next Fragmented pkt");
671 bClassificationSucceed = TRUE;
673 if (!(ntohs(pIpHeader->frag_off) & IP_MF)) {
674 /* Fragmented Last packet . Remove Frag Classifier Entry */
675 BCM_DEBUG_PRINT(Adapter,
679 "This is the last fragmented Pkt");
680 DelFragIPClsEntry(Adapter,
687 for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) {
688 if (bClassificationSucceed)
691 * Iterate through all classifiers which are already in order of priority
692 * to classify the packet until match found
694 if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) {
695 bClassificationSucceed = false;
698 BCM_DEBUG_PRINT(Adapter,
702 "Adapter->PackInfo[%d].bvalid=True\n",
705 if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) {
706 bClassificationSucceed = false; /* cannot be processed for classification. */
707 continue; /* it is a down link connection */
710 pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex];
712 uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
713 if (uiSfIndex >= NO_OF_QUEUES) {
714 BCM_DEBUG_PRINT(Adapter,
718 "Queue Not Valid. SearchSfid for this classifier Failed\n");
722 if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) {
724 if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) {
725 BCM_DEBUG_PRINT(Adapter,
729 " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
730 bClassificationSucceed = false;
736 BCM_DEBUG_PRINT(Adapter,
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,
747 Adapter->PackInfo[uiSfIndex].bEthCSSupport);
749 if (!bClassificationSucceed) {
750 BCM_DEBUG_PRINT(Adapter,
754 "ClassifyPacket : Ethernet CS Classification Failed\n");
757 } else { /* No ETH Supported on this SF */
758 if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) {
759 BCM_DEBUG_PRINT(Adapter,
763 " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
764 bClassificationSucceed = false;
769 BCM_DEBUG_PRINT(Adapter,
773 "Proceeding to IP CS Clasification");
775 if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) {
777 if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) {
778 BCM_DEBUG_PRINT(Adapter,
782 " ClassifyPacket : Packet is Not an IP Packet\n");
783 bClassificationSucceed = false;
786 BCM_DEBUG_PRINT(Adapter,
790 "Dump IP Header :\n");
791 DumpFullPacket((PUCHAR)pIpHeader, 20);
793 if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
794 bClassificationSucceed = IpVersion4(Adapter,
797 else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet)
798 bClassificationSucceed = IpVersion6(Adapter,
804 if (bClassificationSucceed == TRUE) {
805 BCM_DEBUG_PRINT(Adapter,
809 "CF id : %d, SF ID is =%lu",
810 pstClassifierRule->uiClassifierRuleIndex,
811 pstClassifierRule->ulSFID);
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 <=
819 IpHeaderLength = pIpHeader->ihl;
821 (struct bcm_tcp_header *)(((PUCHAR)pIpHeader) +
823 TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
825 if ((pTcpHeader->ucFlags & TCP_ACK) &&
826 (ntohs(pIpHeader->tot_len) ==
827 (IpHeaderLength*4)+(TcpHeaderLength*4)))
828 *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) =
832 usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
833 BCM_DEBUG_PRINT(Adapter,
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.
845 if (bFragmentedPkt && (usCurrFragment == 0)) {
847 * First Fragment of Fragmented Packet.
848 * Create Frag CLS Entry
850 struct bcm_fragmented_packet_info stFragPktInfo;
852 stFragPktInfo.bUsed = TRUE;
853 stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr;
854 stFragPktInfo.usIpIdentification = pIpHeader->id;
855 stFragPktInfo.pstMatchedClassifierEntry =
857 stFragPktInfo.bOutOfOrderFragment = false;
858 AddFragIPClsEntry(Adapter, &stFragPktInfo);
864 return bClassificationSucceed ? usIndex : INVALID_QUEUE_INDEX;
867 static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule,
871 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
873 if (pstClassifierRule->ucEthCSSrcMACLen == 0)
875 BCM_DEBUG_PRINT(Adapter,
880 for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
881 BCM_DEBUG_PRINT(Adapter,
885 "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
888 pstClassifierRule->au8EThCSSrcMAC[i],
889 pstClassifierRule->au8EThCSSrcMACMask[i]);
890 if ((pstClassifierRule->au8EThCSSrcMAC[i] &
891 pstClassifierRule->au8EThCSSrcMACMask[i]) !=
892 (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
898 static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule,
902 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
904 if (pstClassifierRule->ucEthCSDestMACLen == 0)
906 BCM_DEBUG_PRINT(Adapter,
912 for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
913 BCM_DEBUG_PRINT(Adapter,
917 "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
920 pstClassifierRule->au8EThCSDestMAC[i],
921 pstClassifierRule->au8EThCSDestMACMask[i]);
922 if ((pstClassifierRule->au8EThCSDestMAC[i] &
923 pstClassifierRule->au8EThCSDestMACMask[i]) !=
924 (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
930 static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,
932 struct bcm_eth_packet_info *pstEthCsPktInfo)
934 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
936 if ((pstClassifierRule->ucEtherTypeLen == 0) ||
937 (pstClassifierRule->au8EthCSEtherType[0] == 0))
940 BCM_DEBUG_PRINT(Adapter,
944 "%s SrcEtherType:%x CLS EtherType[0]:%x\n",
946 pstEthCsPktInfo->usEtherType,
947 pstClassifierRule->au8EthCSEtherType[0]);
948 if (pstClassifierRule->au8EthCSEtherType[0] == 1) {
949 BCM_DEBUG_PRINT(Adapter,
953 "%s CLS EtherType[1]:%x EtherType[2]:%x\n",
955 pstClassifierRule->au8EthCSEtherType[1],
956 pstClassifierRule->au8EthCSEtherType[2]);
958 if (memcmp(&pstEthCsPktInfo->usEtherType,
959 &pstClassifierRule->au8EthCSEtherType[1],
966 if (pstClassifierRule->au8EthCSEtherType[0] == 2) {
967 if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
970 BCM_DEBUG_PRINT(Adapter,
974 "%s EthCS DSAP:%x EtherType[2]:%x\n",
976 pstEthCsPktInfo->ucDSAP,
977 pstClassifierRule->au8EthCSEtherType[2]);
978 if (pstEthCsPktInfo->ucDSAP ==
979 pstClassifierRule->au8EthCSEtherType[2])
990 static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule,
992 struct bcm_eth_packet_info *pstEthCsPktInfo)
994 bool bClassificationSucceed = false;
996 B_UINT8 uPriority = 0;
997 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
999 BCM_DEBUG_PRINT(Adapter,
1003 "%s CLS UserPrio:%x CLS VLANID:%x\n",
1005 ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),
1006 pstClassifierRule->usVLANID);
1009 * In case FW didn't receive the TLV,
1010 * the priority field should be ignored
1012 if (pstClassifierRule->usValidityBitMap &
1013 (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) {
1014 if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
1017 uPriority = (ntohs(*(USHORT *)(skb->data +
1018 sizeof(struct bcm_eth_header))) &
1021 if ((uPriority >= pstClassifierRule->usUserPriority[0]) &&
1023 pstClassifierRule->usUserPriority[1]))
1024 bClassificationSucceed = TRUE;
1026 if (!bClassificationSucceed)
1030 BCM_DEBUG_PRINT(Adapter,
1034 "ETH CS 802.1 D User Priority Rule Matched\n");
1036 bClassificationSucceed = false;
1038 if (pstClassifierRule->usValidityBitMap &
1039 (1<<PKT_CLASSIFICATION_VLANID_VALID)) {
1040 if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
1043 usVLANID = ntohs(*(USHORT *)(skb->data +
1044 sizeof(struct bcm_eth_header))) & 0xFFF;
1046 BCM_DEBUG_PRINT(Adapter,
1050 "%s Pkt VLANID %x Priority: %d\n",
1055 if (usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4))
1056 bClassificationSucceed = TRUE;
1058 if (!bClassificationSucceed)
1062 BCM_DEBUG_PRINT(Adapter,
1066 "ETH CS 802.1 Q VLAN ID Rule Matched\n");
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)
1078 bool bClassificationSucceed = false;
1080 bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,
1081 ((struct bcm_eth_header *)(skb->data))->au8SourceAddress);
1082 if (!bClassificationSucceed)
1084 BCM_DEBUG_PRINT(Adapter,
1088 "ETH CS SrcMAC Matched\n");
1090 bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,
1091 ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress);
1092 if (!bClassificationSucceed)
1094 BCM_DEBUG_PRINT(Adapter,
1098 "ETH CS DestMAC Matched\n");
1100 /* classify on ETHType/802.2SAP TLV */
1101 bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,
1104 if (!bClassificationSucceed)
1107 BCM_DEBUG_PRINT(Adapter,
1111 "ETH CS EthType/802.2SAP Matched\n");
1113 /* classify on 802.1VLAN Header Parameters */
1114 bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,
1117 if (!bClassificationSucceed)
1119 BCM_DEBUG_PRINT(Adapter,
1123 "ETH CS 802.1 VLAN Rules Matched\n");
1125 return bClassificationSucceed;
1128 static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
1130 struct bcm_eth_packet_info *pstEthCsPktInfo)
1132 USHORT u16Etype = ntohs(
1133 ((struct bcm_eth_header *)pvEthPayload)->u16Etype);
1135 BCM_DEBUG_PRINT(Adapter,
1139 "EthCSGetPktInfo : Eth Hdr Type : %X\n",
1141 if (u16Etype > 0x5dc) {
1142 BCM_DEBUG_PRINT(Adapter,
1146 "EthCSGetPktInfo : ETH2 Frame\n");
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 */
1154 pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame;
1155 u16Etype = ntohs(u16Etype);
1159 BCM_DEBUG_PRINT(Adapter,
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) {
1169 pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame;
1170 u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType;
1173 if (u16Etype == ETHERNET_FRAMETYPE_IPV4)
1174 pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet;
1175 else if (u16Etype == ETHERNET_FRAMETYPE_IPV6)
1176 pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet;
1178 pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket;
1180 pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype;
1181 BCM_DEBUG_PRINT(Adapter,
1185 "EthCsPktInfo->eNwpktIPFrameType : %x\n",
1186 pstEthCsPktInfo->eNwpktIPFrameType);
1187 BCM_DEBUG_PRINT(Adapter,
1191 "EthCsPktInfo->eNwpktEthFrameType : %x\n",
1192 pstEthCsPktInfo->eNwpktEthFrameType);
1193 BCM_DEBUG_PRINT(Adapter,
1197 "EthCsPktInfo->usEtherType : %x\n",
1198 pstEthCsPktInfo->usEtherType);