3 This file contains the routines related to Quality of Service.
7 static void EThCSGetPktInfo(PMINI_ADAPTER Adapter
,PVOID pvEthPayload
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
);
8 static BOOLEAN
EThCSClassifyPkt(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
,S_CLASSIFIER_RULE
*pstClassifierRule
, B_UINT8 EthCSCupport
);
10 static USHORT
IpVersion4(PMINI_ADAPTER Adapter
, struct iphdr
*iphd
,
11 S_CLASSIFIER_RULE
*pstClassifierRule
);
13 static VOID
PruneQueue(PMINI_ADAPTER Adapter
, INT iIndex
);
16 /*******************************************************************
17 * Function - MatchSrcIpAddress()
19 * Description - Checks whether the Source IP address from the packet
20 * matches with that of Queue.
22 * Parameters - pstClassifierRule: Pointer to the packet info structure.
23 * - ulSrcIP : Source IP address from the packet.
25 * Returns - TRUE(If address matches) else FAIL .
26 *********************************************************************/
27 BOOLEAN
MatchSrcIpAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,ULONG ulSrcIP
)
31 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
33 ulSrcIP
=ntohl(ulSrcIP
);
34 if(0 == pstClassifierRule
->ucIPSourceAddressLength
)
36 for(ucLoopIndex
=0; ucLoopIndex
< (pstClassifierRule
->ucIPSourceAddressLength
);ucLoopIndex
++)
38 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", (UINT
)pstClassifierRule
->stSrcIpAddress
.ulIpv4Mask
[ucLoopIndex
], (UINT
)ulSrcIP
, (UINT
)pstClassifierRule
->stSrcIpAddress
.ulIpv6Addr
[ucLoopIndex
]);
39 if((pstClassifierRule
->stSrcIpAddress
.ulIpv4Mask
[ucLoopIndex
] & ulSrcIP
)==
40 (pstClassifierRule
->stSrcIpAddress
.ulIpv4Addr
[ucLoopIndex
] & pstClassifierRule
->stSrcIpAddress
.ulIpv4Mask
[ucLoopIndex
] ))
45 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Ip Address Not Matched");
50 /*******************************************************************
51 * Function - MatchDestIpAddress()
53 * Description - Checks whether the Destination IP address from the packet
54 * matches with that of Queue.
56 * Parameters - pstClassifierRule: Pointer to the packet info structure.
57 * - ulDestIP : Destination IP address from the packet.
59 * Returns - TRUE(If address matches) else FAIL .
60 *********************************************************************/
61 BOOLEAN
MatchDestIpAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,ULONG ulDestIP
)
64 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
66 ulDestIP
=ntohl(ulDestIP
);
67 if(0 == pstClassifierRule
->ucIPDestinationAddressLength
)
69 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination Ip Address 0x%x 0x%x 0x%x ", (UINT
)ulDestIP
, (UINT
)pstClassifierRule
->stDestIpAddress
.ulIpv4Mask
[ucLoopIndex
], (UINT
)pstClassifierRule
->stDestIpAddress
.ulIpv4Addr
[ucLoopIndex
]);
71 for(ucLoopIndex
=0;ucLoopIndex
<(pstClassifierRule
->ucIPDestinationAddressLength
);ucLoopIndex
++)
73 if((pstClassifierRule
->stDestIpAddress
.ulIpv4Mask
[ucLoopIndex
] & ulDestIP
)==
74 (pstClassifierRule
->stDestIpAddress
.ulIpv4Addr
[ucLoopIndex
] & pstClassifierRule
->stDestIpAddress
.ulIpv4Mask
[ucLoopIndex
]))
79 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination Ip Address Not Matched");
84 /************************************************************************
85 * Function - MatchTos()
87 * Description - Checks the TOS from the packet matches with that of queue.
89 * Parameters - pstClassifierRule : Pointer to the packet info structure.
90 * - ucTypeOfService: TOS from the packet.
92 * Returns - TRUE(If address matches) else FAIL.
93 **************************************************************************/
94 BOOLEAN
MatchTos(S_CLASSIFIER_RULE
*pstClassifierRule
,UCHAR ucTypeOfService
)
97 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
98 if( 3 != pstClassifierRule
->ucIPTypeOfServiceLength
)
101 if(((pstClassifierRule
->ucTosMask
& ucTypeOfService
)<=pstClassifierRule
->ucTosHigh
) && ((pstClassifierRule
->ucTosMask
& ucTypeOfService
)>=pstClassifierRule
->ucTosLow
))
105 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Type Of Service Not Matched");
110 /***************************************************************************
111 * Function - MatchProtocol()
113 * Description - Checks the protocol from the packet matches with that of queue.
115 * Parameters - pstClassifierRule: Pointer to the packet info structure.
116 * - ucProtocol : Protocol from the packet.
118 * Returns - TRUE(If address matches) else FAIL.
119 ****************************************************************************/
120 BOOLEAN
MatchProtocol(S_CLASSIFIER_RULE
*pstClassifierRule
,UCHAR ucProtocol
)
123 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
124 if(0 == pstClassifierRule
->ucProtocolLength
)
126 for(ucLoopIndex
=0;ucLoopIndex
<pstClassifierRule
->ucProtocolLength
;ucLoopIndex
++)
128 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Protocol:0x%X Classification Protocol:0x%X",ucProtocol
,pstClassifierRule
->ucProtocol
[ucLoopIndex
]);
129 if(pstClassifierRule
->ucProtocol
[ucLoopIndex
]==ucProtocol
)
134 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Protocol Not Matched");
139 /***********************************************************************
140 * Function - MatchSrcPort()
142 * Description - Checks, Source port from the packet matches with that of queue.
144 * Parameters - pstClassifierRule: Pointer to the packet info structure.
145 * - ushSrcPort : Source port from the packet.
147 * Returns - TRUE(If address matches) else FAIL.
148 ***************************************************************************/
149 BOOLEAN
MatchSrcPort(S_CLASSIFIER_RULE
*pstClassifierRule
,USHORT ushSrcPort
)
153 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
156 if(0 == pstClassifierRule
->ucSrcPortRangeLength
)
158 for(ucLoopIndex
=0;ucLoopIndex
<pstClassifierRule
->ucSrcPortRangeLength
;ucLoopIndex
++)
160 if(ushSrcPort
<= pstClassifierRule
->usSrcPortRangeHi
[ucLoopIndex
] &&
161 ushSrcPort
>= pstClassifierRule
->usSrcPortRangeLo
[ucLoopIndex
])
166 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Port: %x Not Matched ",ushSrcPort
);
171 /***********************************************************************
172 * Function - MatchDestPort()
174 * Description - Checks, Destination port from packet matches with that of queue.
176 * Parameters - pstClassifierRule: Pointer to the packet info structure.
177 * - ushDestPort : Destination port from the packet.
179 * Returns - TRUE(If address matches) else FAIL.
180 ***************************************************************************/
181 BOOLEAN
MatchDestPort(S_CLASSIFIER_RULE
*pstClassifierRule
,USHORT ushDestPort
)
184 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
186 if(0 == pstClassifierRule
->ucDestPortRangeLength
)
189 for(ucLoopIndex
=0;ucLoopIndex
<pstClassifierRule
->ucDestPortRangeLength
;ucLoopIndex
++)
191 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Matching Port:0x%X 0x%X 0x%X",ushDestPort
,pstClassifierRule
->usDestPortRangeLo
[ucLoopIndex
],pstClassifierRule
->usDestPortRangeHi
[ucLoopIndex
]);
193 if(ushDestPort
<= pstClassifierRule
->usDestPortRangeHi
[ucLoopIndex
] &&
194 ushDestPort
>= pstClassifierRule
->usDestPortRangeLo
[ucLoopIndex
])
199 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Dest Port: %x Not Matched",ushDestPort
);
203 @ingroup tx_functions
204 Compares IPV4 Ip address and port number
207 static USHORT
IpVersion4(PMINI_ADAPTER Adapter
,
209 S_CLASSIFIER_RULE
*pstClassifierRule
)
211 xporthdr
*xprt_hdr
=NULL
;
212 BOOLEAN bClassificationSucceed
=FALSE
;
214 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "========>");
216 xprt_hdr
=(xporthdr
*)((PUCHAR
)iphd
+ sizeof(struct iphdr
));
219 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Trying to see Direction = %d %d",
220 pstClassifierRule
->ucDirection
,
221 pstClassifierRule
->usVCID_Value
);
223 //Checking classifier validity
224 if(!pstClassifierRule
->bUsed
|| pstClassifierRule
->ucDirection
== DOWNLINK_DIR
)
226 bClassificationSucceed
= FALSE
;
230 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "is IPv6 check!");
231 if(pstClassifierRule
->bIpv6Protocol
)
234 //**************Checking IP header parameter**************************//
235 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Trying to match Source IP Address");
236 if(FALSE
== (bClassificationSucceed
=
237 MatchSrcIpAddress(pstClassifierRule
, iphd
->saddr
)))
239 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Source IP Address Matched");
241 if(FALSE
== (bClassificationSucceed
=
242 MatchDestIpAddress(pstClassifierRule
, iphd
->daddr
)))
244 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination IP Address Matched");
246 if(FALSE
== (bClassificationSucceed
=
247 MatchTos(pstClassifierRule
, iphd
->tos
)))
249 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "TOS Match failed\n");
252 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "TOS Matched");
254 if(FALSE
== (bClassificationSucceed
=
255 MatchProtocol(pstClassifierRule
,iphd
->protocol
)))
257 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Protocol Matched");
259 //if protocol is not TCP or UDP then no need of comparing source port and destination port
260 if(iphd
->protocol
!=TCP
&& iphd
->protocol
!=UDP
)
262 //******************Checking Transport Layer Header field if present *****************//
263 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Source Port %04x",
264 (iphd
->protocol
==UDP
)?xprt_hdr
->uhdr
.source
:xprt_hdr
->thdr
.source
);
266 if(FALSE
== (bClassificationSucceed
=
267 MatchSrcPort(pstClassifierRule
,
268 ntohs((iphd
->protocol
== UDP
)?
269 xprt_hdr
->uhdr
.source
:xprt_hdr
->thdr
.source
))))
271 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Port Matched");
273 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination Port %04x",
274 (iphd
->protocol
==UDP
)?xprt_hdr
->uhdr
.dest
:
275 xprt_hdr
->thdr
.dest
);
276 if(FALSE
== (bClassificationSucceed
=
277 MatchDestPort(pstClassifierRule
,
278 ntohs((iphd
->protocol
== UDP
)?
279 xprt_hdr
->uhdr
.dest
:xprt_hdr
->thdr
.dest
))))
283 if(TRUE
==bClassificationSucceed
)
285 INT iMatchedSFQueueIndex
= 0;
286 iMatchedSFQueueIndex
= SearchSfid(Adapter
,pstClassifierRule
->ulSFID
);
287 if(iMatchedSFQueueIndex
>= NO_OF_QUEUES
)
289 bClassificationSucceed
= FALSE
;
293 if(FALSE
== Adapter
->PackInfo
[iMatchedSFQueueIndex
].bActive
)
295 bClassificationSucceed
= FALSE
;
300 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "IpVersion4 <==========");
302 return bClassificationSucceed
;
305 VOID
PruneQueueAllSF(PMINI_ADAPTER Adapter
)
309 for(iIndex
= 0; iIndex
< HiPriority
; iIndex
++)
311 if(!Adapter
->PackInfo
[iIndex
].bValid
)
314 PruneQueue(Adapter
, iIndex
);
320 @ingroup tx_functions
321 This function checks if the max queue size for a queue
322 is less than number of bytes in the queue. If so -
323 drops packets from the Head till the number of bytes is
324 less than or equal to max queue size for the queue.
326 static VOID
PruneQueue(PMINI_ADAPTER Adapter
, INT iIndex
)
328 struct sk_buff
* PacketToDrop
=NULL
;
329 struct net_device_stats
*netstats
;
331 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "=====> Index %d",iIndex
);
333 if(iIndex
== HiPriority
)
336 if(!Adapter
|| (iIndex
< 0) || (iIndex
> HiPriority
))
339 /* To Store the netdevice statistic */
340 netstats
= &Adapter
->dev
->stats
;
342 spin_lock_bh(&Adapter
->PackInfo
[iIndex
].SFQueueLock
);
345 // while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost >
346 // SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
348 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
349 Adapter
->PackInfo
[iIndex
].uiCurrentBytesOnHost
,
350 Adapter
->PackInfo
[iIndex
].uiMaxBucketSize
);
352 PacketToDrop
= Adapter
->PackInfo
[iIndex
].FirstTxQueue
;
354 if(PacketToDrop
== NULL
)
356 if((Adapter
->PackInfo
[iIndex
].uiCurrentPacketsOnHost
< SF_MAX_ALLOWED_PACKETS_TO_BACKUP
) &&
357 ((1000*(jiffies
- *((B_UINT32
*)(PacketToDrop
->cb
)+SKB_CB_LATENCY_OFFSET
))/HZ
) <= Adapter
->PackInfo
[iIndex
].uiMaxLatency
))
362 struct netdev_queue
*txq
= netdev_get_tx_queue(Adapter
->dev
, iIndex
);
363 if (netif_msg_tx_err(Adapter
))
364 pr_info(PFX
"%s: tx queue %d overlimit\n",
365 Adapter
->dev
->name
, iIndex
);
369 DEQUEUEPACKET(Adapter
->PackInfo
[iIndex
].FirstTxQueue
,
370 Adapter
->PackInfo
[iIndex
].LastTxQueue
);
371 /// update current bytes and packets count
372 Adapter
->PackInfo
[iIndex
].uiCurrentBytesOnHost
-=
374 Adapter
->PackInfo
[iIndex
].uiCurrentPacketsOnHost
--;
375 /// update dropped bytes and packets counts
376 Adapter
->PackInfo
[iIndex
].uiDroppedCountBytes
+= PacketToDrop
->len
;
377 Adapter
->PackInfo
[iIndex
].uiDroppedCountPackets
++;
378 dev_kfree_skb(PacketToDrop
);
382 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "Dropped Bytes:%x Dropped Packets:%x",
383 Adapter
->PackInfo
[iIndex
].uiDroppedCountBytes
,
384 Adapter
->PackInfo
[iIndex
].uiDroppedCountPackets
);
386 atomic_dec(&Adapter
->TotalPacketCount
);
389 spin_unlock_bh(&Adapter
->PackInfo
[iIndex
].SFQueueLock
);
391 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "TotalPacketCount:%x",
392 atomic_read(&Adapter
->TotalPacketCount
));
393 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "<=====");
396 VOID
flush_all_queues(PMINI_ADAPTER Adapter
)
399 UINT uiTotalPacketLength
;
400 struct sk_buff
* PacketToDrop
=NULL
;
402 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "=====>");
404 // down(&Adapter->data_packet_queue_lock);
405 for(iQIndex
=LowPriority
; iQIndex
<HiPriority
; iQIndex
++)
407 struct netdev_queue
*txq
= netdev_get_tx_queue(Adapter
->dev
, iQIndex
);
409 spin_lock_bh(&Adapter
->PackInfo
[iQIndex
].SFQueueLock
);
410 while(Adapter
->PackInfo
[iQIndex
].FirstTxQueue
)
412 PacketToDrop
= Adapter
->PackInfo
[iQIndex
].FirstTxQueue
;
415 uiTotalPacketLength
= PacketToDrop
->len
;
419 uiTotalPacketLength
= 0;
421 DEQUEUEPACKET(Adapter
->PackInfo
[iQIndex
].FirstTxQueue
,
422 Adapter
->PackInfo
[iQIndex
].LastTxQueue
);
425 dev_kfree_skb(PacketToDrop
);
427 /// update current bytes and packets count
428 Adapter
->PackInfo
[iQIndex
].uiCurrentBytesOnHost
-= uiTotalPacketLength
;
429 Adapter
->PackInfo
[iQIndex
].uiCurrentPacketsOnHost
--;
431 /// update dropped bytes and packets counts
432 Adapter
->PackInfo
[iQIndex
].uiDroppedCountBytes
+= uiTotalPacketLength
;
433 Adapter
->PackInfo
[iQIndex
].uiDroppedCountPackets
++;
435 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "Dropped Bytes:%x Dropped Packets:%x",
436 Adapter
->PackInfo
[iQIndex
].uiDroppedCountBytes
,
437 Adapter
->PackInfo
[iQIndex
].uiDroppedCountPackets
);
438 atomic_dec(&Adapter
->TotalPacketCount
);
440 spin_unlock_bh(&Adapter
->PackInfo
[iQIndex
].SFQueueLock
);
442 // up(&Adapter->data_packet_queue_lock);
443 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "<=====");
446 USHORT
ClassifyPacket(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
)
449 S_CLASSIFIER_RULE
*pstClassifierRule
= NULL
;
450 S_ETHCS_PKT_INFO stEthCsPktInfo
;
451 PVOID pvEThPayload
= NULL
;
452 struct iphdr
*pIpHeader
= NULL
;
454 USHORT usIndex
=Adapter
->usBestEffortQueueIndex
;
455 BOOLEAN bFragmentedPkt
=FALSE
,bClassificationSucceed
=FALSE
;
456 USHORT usCurrFragment
=0;
458 PTCP_HEADER pTcpHeader
;
459 UCHAR IpHeaderLength
;
460 UCHAR TcpHeaderLength
;
462 pvEThPayload
= skb
->data
;
463 *((UINT32
*) (skb
->cb
) +SKB_CB_TCPACK_OFFSET
) = 0;
464 EThCSGetPktInfo(Adapter
,pvEThPayload
,&stEthCsPktInfo
);
466 switch(stEthCsPktInfo
.eNwpktEthFrameType
)
468 case eEth802LLCFrame
:
470 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802LLCFrame\n");
471 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_LLC_FRAME
);
475 case eEth802LLCSNAPFrame
:
477 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802LLC SNAP Frame\n");
478 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_LLC_SNAP_FRAME
);
481 case eEth802QVLANFrame
:
483 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802.1Q VLANFrame\n");
484 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_Q_FRAME
);
489 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : ETH Other Frame\n");
490 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_ETH2_FRAME
);
495 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : Unrecognized ETH Frame\n");
496 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_ETH2_FRAME
);
501 if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv4Packet
)
503 usCurrFragment
= (ntohs(pIpHeader
->frag_off
) & IP_OFFSET
);
504 if((ntohs(pIpHeader
->frag_off
) & IP_MF
) || usCurrFragment
)
505 bFragmentedPkt
= TRUE
;
509 //Fragmented Packet. Get Frag Classifier Entry.
510 pstClassifierRule
= GetFragIPClsEntry(Adapter
,pIpHeader
->id
, pIpHeader
->saddr
);
511 if(pstClassifierRule
)
513 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
,"It is next Fragmented pkt");
514 bClassificationSucceed
=TRUE
;
516 if(!(ntohs(pIpHeader
->frag_off
) & IP_MF
))
518 //Fragmented Last packet . Remove Frag Classifier Entry
519 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
,"This is the last fragmented Pkt");
520 DelFragIPClsEntry(Adapter
,pIpHeader
->id
, pIpHeader
->saddr
);
525 for(uiLoopIndex
= MAX_CLASSIFIERS
- 1; uiLoopIndex
>= 0; uiLoopIndex
--)
527 if(bClassificationSucceed
)
529 //Iterate through all classifiers which are already in order of priority
530 //to classify the packet until match found
533 if(FALSE
==Adapter
->astClassifierTable
[uiLoopIndex
].bUsed
)
535 bClassificationSucceed
=FALSE
;
538 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex
);
540 if(0 == Adapter
->astClassifierTable
[uiLoopIndex
].ucDirection
)
542 bClassificationSucceed
=FALSE
;//cannot be processed for classification.
543 break; // it is a down link connection
546 pstClassifierRule
= &Adapter
->astClassifierTable
[uiLoopIndex
];
548 uiSfIndex
= SearchSfid(Adapter
,pstClassifierRule
->ulSFID
);
549 if (uiSfIndex
>= NO_OF_QUEUES
) {
550 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Queue Not Valid. SearchSfid for this classifier Failed\n");
554 if(Adapter
->PackInfo
[uiSfIndex
].bEthCSSupport
)
557 if(eEthUnsupportedFrame
==stEthCsPktInfo
.eNwpktEthFrameType
)
559 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame \n");
560 bClassificationSucceed
= FALSE
;
566 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",pstClassifierRule
->uiClassifierRuleIndex
,Adapter
->PackInfo
[uiSfIndex
].ulSFID
);
567 bClassificationSucceed
= EThCSClassifyPkt(Adapter
,skb
,&stEthCsPktInfo
,pstClassifierRule
, Adapter
->PackInfo
[uiSfIndex
].bEthCSSupport
);
569 if(!bClassificationSucceed
)
571 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : Ethernet CS Classification Failed\n");
576 else // No ETH Supported on this SF
578 if(eEthOtherFrame
!= stEthCsPktInfo
.eNwpktEthFrameType
)
580 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF \n");
581 bClassificationSucceed
= FALSE
;
586 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Proceeding to IP CS Clasification");
588 if(Adapter
->PackInfo
[uiSfIndex
].bIPCSSupport
)
591 if(stEthCsPktInfo
.eNwpktIPFrameType
== eNonIPPacket
)
593 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet is Not an IP Packet \n");
594 bClassificationSucceed
= FALSE
;
597 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Dump IP Header : \n");
598 DumpFullPacket((PUCHAR
)pIpHeader
,20);
600 if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv4Packet
)
601 bClassificationSucceed
= IpVersion4(Adapter
,pIpHeader
,pstClassifierRule
);
602 else if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv6Packet
)
603 bClassificationSucceed
= IpVersion6(Adapter
,pIpHeader
,pstClassifierRule
);
609 if(bClassificationSucceed
== TRUE
)
611 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "CF id : %d, SF ID is =%lu",pstClassifierRule
->uiClassifierRuleIndex
, pstClassifierRule
->ulSFID
);
613 //Store The matched Classifier in SKB
614 *((UINT32
*)(skb
->cb
)+SKB_CB_CLASSIFICATION_OFFSET
) = pstClassifierRule
->uiClassifierRuleIndex
;
615 if((TCP
== pIpHeader
->protocol
) && !bFragmentedPkt
&& (ETH_AND_IP_HEADER_LEN
+ TCP_HEADER_LEN
<= skb
->len
) )
617 IpHeaderLength
= pIpHeader
->ihl
;
618 pTcpHeader
= (PTCP_HEADER
)(((PUCHAR
)pIpHeader
)+(IpHeaderLength
*4));
619 TcpHeaderLength
= GET_TCP_HEADER_LEN(pTcpHeader
->HeaderLength
);
621 if((pTcpHeader
->ucFlags
& TCP_ACK
) &&
622 (ntohs(pIpHeader
->tot_len
) == (IpHeaderLength
*4)+(TcpHeaderLength
*4)))
624 *((UINT32
*) (skb
->cb
) +SKB_CB_TCPACK_OFFSET
) = TCP_ACK
;
628 usIndex
= SearchSfid(Adapter
, pstClassifierRule
->ulSFID
);
629 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "index is =%d", usIndex
);
631 //If this is the first fragment of a Fragmented pkt, add this CF. Only This CF should be used for all other fragment of this Pkt.
632 if(bFragmentedPkt
&& (usCurrFragment
== 0))
634 //First Fragment of Fragmented Packet. Create Frag CLS Entry
635 S_FRAGMENTED_PACKET_INFO stFragPktInfo
;
636 stFragPktInfo
.bUsed
= TRUE
;
637 stFragPktInfo
.ulSrcIpAddress
= pIpHeader
->saddr
;
638 stFragPktInfo
.usIpIdentification
= pIpHeader
->id
;
639 stFragPktInfo
.pstMatchedClassifierEntry
= pstClassifierRule
;
640 stFragPktInfo
.bOutOfOrderFragment
= FALSE
;
641 AddFragIPClsEntry(Adapter
,&stFragPktInfo
);
647 if(bClassificationSucceed
)
650 return INVALID_QUEUE_INDEX
;
653 static BOOLEAN
EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,PUCHAR Mac
)
656 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
657 if(pstClassifierRule
->ucEthCSSrcMACLen
==0)
659 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s \n",__FUNCTION__
);
660 for(i
=0;i
<MAC_ADDRESS_SIZE
;i
++)
662 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i
,Mac
[i
],pstClassifierRule
->au8EThCSSrcMAC
[i
],pstClassifierRule
->au8EThCSSrcMACMask
[i
]);
663 if((pstClassifierRule
->au8EThCSSrcMAC
[i
] & pstClassifierRule
->au8EThCSSrcMACMask
[i
])!=
664 (Mac
[i
] & pstClassifierRule
->au8EThCSSrcMACMask
[i
]))
670 static BOOLEAN
EthCSMatchDestMACAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,PUCHAR Mac
)
673 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
674 if(pstClassifierRule
->ucEthCSDestMACLen
==0)
676 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s \n",__FUNCTION__
);
677 for(i
=0;i
<MAC_ADDRESS_SIZE
;i
++)
679 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i
,Mac
[i
],pstClassifierRule
->au8EThCSDestMAC
[i
],pstClassifierRule
->au8EThCSDestMACMask
[i
]);
680 if((pstClassifierRule
->au8EThCSDestMAC
[i
] & pstClassifierRule
->au8EThCSDestMACMask
[i
])!=
681 (Mac
[i
] & pstClassifierRule
->au8EThCSDestMACMask
[i
]))
687 static BOOLEAN
EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE
*pstClassifierRule
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
689 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
690 if((pstClassifierRule
->ucEtherTypeLen
==0)||
691 (pstClassifierRule
->au8EthCSEtherType
[0] == 0))
694 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s SrcEtherType:%x CLS EtherType[0]:%x\n",__FUNCTION__
,pstEthCsPktInfo
->usEtherType
,pstClassifierRule
->au8EthCSEtherType
[0]);
695 if(pstClassifierRule
->au8EthCSEtherType
[0] == 1)
697 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s CLS EtherType[1]:%x EtherType[2]:%x\n",__FUNCTION__
,pstClassifierRule
->au8EthCSEtherType
[1],pstClassifierRule
->au8EthCSEtherType
[2]);
699 if(memcmp(&pstEthCsPktInfo
->usEtherType
,&pstClassifierRule
->au8EthCSEtherType
[1],2)==0)
705 if(pstClassifierRule
->au8EthCSEtherType
[0] == 2)
707 if(eEth802LLCFrame
!= pstEthCsPktInfo
->eNwpktEthFrameType
)
710 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s EthCS DSAP:%x EtherType[2]:%x\n",__FUNCTION__
,pstEthCsPktInfo
->ucDSAP
,pstClassifierRule
->au8EthCSEtherType
[2]);
711 if(pstEthCsPktInfo
->ucDSAP
== pstClassifierRule
->au8EthCSEtherType
[2])
722 static BOOLEAN
EthCSMatchVLANRules(S_CLASSIFIER_RULE
*pstClassifierRule
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
724 BOOLEAN bClassificationSucceed
= FALSE
;
726 B_UINT8 uPriority
= 0;
727 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
729 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s CLS UserPrio:%x CLS VLANID:%x\n",__FUNCTION__
,ntohs(*((USHORT
*)pstClassifierRule
->usUserPriority
)),pstClassifierRule
->usVLANID
);
731 /* In case FW didn't recieve the TLV, the priority field should be ignored */
732 if(pstClassifierRule
->usValidityBitMap
& (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID
))
734 if(pstEthCsPktInfo
->eNwpktEthFrameType
!=eEth802QVLANFrame
)
737 uPriority
= (ntohs(*(USHORT
*)(skb
->data
+ sizeof(ETH_HEADER_STRUC
))) & 0xF000) >> 13;
739 if((uPriority
>= pstClassifierRule
->usUserPriority
[0]) && (uPriority
<= pstClassifierRule
->usUserPriority
[1]))
740 bClassificationSucceed
= TRUE
;
742 if(!bClassificationSucceed
)
746 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 D User Priority Rule Matched\n");
748 bClassificationSucceed
= FALSE
;
750 if(pstClassifierRule
->usValidityBitMap
& (1<<PKT_CLASSIFICATION_VLANID_VALID
))
752 if(pstEthCsPktInfo
->eNwpktEthFrameType
!=eEth802QVLANFrame
)
755 usVLANID
= ntohs(*(USHORT
*)(skb
->data
+ sizeof(ETH_HEADER_STRUC
))) & 0xFFF;
757 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__
,usVLANID
, uPriority
);
759 if(usVLANID
== ((pstClassifierRule
->usVLANID
& 0xFFF0) >> 4))
760 bClassificationSucceed
= TRUE
;
762 if(!bClassificationSucceed
)
766 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 Q VLAN ID Rule Matched\n");
772 static BOOLEAN
EThCSClassifyPkt(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
,
773 PS_ETHCS_PKT_INFO pstEthCsPktInfo
,
774 S_CLASSIFIER_RULE
*pstClassifierRule
,
775 B_UINT8 EthCSCupport
)
777 BOOLEAN bClassificationSucceed
= FALSE
;
778 bClassificationSucceed
= EthCSMatchSrcMACAddress(pstClassifierRule
,((ETH_HEADER_STRUC
*)(skb
->data
))->au8SourceAddress
);
779 if(!bClassificationSucceed
)
781 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS SrcMAC Matched\n");
783 bClassificationSucceed
= EthCSMatchDestMACAddress(pstClassifierRule
,((ETH_HEADER_STRUC
*)(skb
->data
))->au8DestinationAddress
);
784 if(!bClassificationSucceed
)
786 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS DestMAC Matched\n");
788 //classify on ETHType/802.2SAP TLV
789 bClassificationSucceed
= EthCSMatchEThTypeSAP(pstClassifierRule
,skb
,pstEthCsPktInfo
);
790 if(!bClassificationSucceed
)
793 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS EthType/802.2SAP Matched\n");
795 //classify on 802.1VLAN Header Parameters
797 bClassificationSucceed
= EthCSMatchVLANRules(pstClassifierRule
,skb
,pstEthCsPktInfo
);
798 if(!bClassificationSucceed
)
800 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 VLAN Rules Matched\n");
802 return bClassificationSucceed
;
805 static void EThCSGetPktInfo(PMINI_ADAPTER Adapter
,PVOID pvEthPayload
,
806 PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
808 USHORT u16Etype
= ntohs(((ETH_HEADER_STRUC
*)pvEthPayload
)->u16Etype
);
810 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype
);
813 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCSGetPktInfo : ETH2 Frame \n");
815 if(u16Etype
== ETHERNET_FRAMETYPE_802QVLAN
)
818 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802QVLANFrame
;
819 u16Etype
= ((ETH_CS_802_Q_FRAME
*)pvEthPayload
)->EthType
;
820 //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority
824 pstEthCsPktInfo
->eNwpktEthFrameType
= eEthOtherFrame
;
825 u16Etype
= ntohs(u16Etype
);
832 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "802.2 LLC Frame \n");
833 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802LLCFrame
;
834 pstEthCsPktInfo
->ucDSAP
= ((ETH_CS_802_LLC_FRAME
*)pvEthPayload
)->DSAP
;
835 if(pstEthCsPktInfo
->ucDSAP
== 0xAA && ((ETH_CS_802_LLC_FRAME
*)pvEthPayload
)->SSAP
== 0xAA)
838 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802LLCSNAPFrame
;
839 u16Etype
= ((ETH_CS_802_LLC_SNAP_FRAME
*)pvEthPayload
)->usEtherType
;
842 if(u16Etype
== ETHERNET_FRAMETYPE_IPV4
)
843 pstEthCsPktInfo
->eNwpktIPFrameType
= eIPv4Packet
;
844 else if(u16Etype
== ETHERNET_FRAMETYPE_IPV6
)
845 pstEthCsPktInfo
->eNwpktIPFrameType
= eIPv6Packet
;
847 pstEthCsPktInfo
->eNwpktIPFrameType
= eNonIPPacket
;
849 pstEthCsPktInfo
->usEtherType
= ((ETH_HEADER_STRUC
*)pvEthPayload
)->u16Etype
;
850 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo
->eNwpktIPFrameType
);
851 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo
->eNwpktEthFrameType
);
852 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo
->usEtherType
);