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 if (netif_msg_tx_err(Adapter
))
363 pr_info(PFX
"%s: tx queue %d overlimit\n",
364 Adapter
->dev
->name
, iIndex
);
366 netstats
->tx_dropped
++;
368 DEQUEUEPACKET(Adapter
->PackInfo
[iIndex
].FirstTxQueue
,
369 Adapter
->PackInfo
[iIndex
].LastTxQueue
);
370 /// update current bytes and packets count
371 Adapter
->PackInfo
[iIndex
].uiCurrentBytesOnHost
-=
373 Adapter
->PackInfo
[iIndex
].uiCurrentPacketsOnHost
--;
374 /// update dropped bytes and packets counts
375 Adapter
->PackInfo
[iIndex
].uiDroppedCountBytes
+= PacketToDrop
->len
;
376 Adapter
->PackInfo
[iIndex
].uiDroppedCountPackets
++;
377 dev_kfree_skb(PacketToDrop
);
381 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "Dropped Bytes:%x Dropped Packets:%x",
382 Adapter
->PackInfo
[iIndex
].uiDroppedCountBytes
,
383 Adapter
->PackInfo
[iIndex
].uiDroppedCountPackets
);
385 atomic_dec(&Adapter
->TotalPacketCount
);
388 spin_unlock_bh(&Adapter
->PackInfo
[iIndex
].SFQueueLock
);
390 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "TotalPacketCount:%x",
391 atomic_read(&Adapter
->TotalPacketCount
));
392 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "<=====");
395 VOID
flush_all_queues(PMINI_ADAPTER Adapter
)
398 UINT uiTotalPacketLength
;
399 struct sk_buff
* PacketToDrop
=NULL
;
401 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "=====>");
403 // down(&Adapter->data_packet_queue_lock);
404 for(iQIndex
=LowPriority
; iQIndex
<HiPriority
; iQIndex
++)
406 struct net_device_stats
*netstats
= &Adapter
->dev
->stats
;
408 spin_lock_bh(&Adapter
->PackInfo
[iQIndex
].SFQueueLock
);
409 while(Adapter
->PackInfo
[iQIndex
].FirstTxQueue
)
411 PacketToDrop
= Adapter
->PackInfo
[iQIndex
].FirstTxQueue
;
414 uiTotalPacketLength
= PacketToDrop
->len
;
415 netstats
->tx_dropped
++;
418 uiTotalPacketLength
= 0;
420 DEQUEUEPACKET(Adapter
->PackInfo
[iQIndex
].FirstTxQueue
,
421 Adapter
->PackInfo
[iQIndex
].LastTxQueue
);
424 dev_kfree_skb(PacketToDrop
);
426 /// update current bytes and packets count
427 Adapter
->PackInfo
[iQIndex
].uiCurrentBytesOnHost
-= uiTotalPacketLength
;
428 Adapter
->PackInfo
[iQIndex
].uiCurrentPacketsOnHost
--;
430 /// update dropped bytes and packets counts
431 Adapter
->PackInfo
[iQIndex
].uiDroppedCountBytes
+= uiTotalPacketLength
;
432 Adapter
->PackInfo
[iQIndex
].uiDroppedCountPackets
++;
434 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "Dropped Bytes:%x Dropped Packets:%x",
435 Adapter
->PackInfo
[iQIndex
].uiDroppedCountBytes
,
436 Adapter
->PackInfo
[iQIndex
].uiDroppedCountPackets
);
437 atomic_dec(&Adapter
->TotalPacketCount
);
439 spin_unlock_bh(&Adapter
->PackInfo
[iQIndex
].SFQueueLock
);
441 // up(&Adapter->data_packet_queue_lock);
442 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "<=====");
445 USHORT
ClassifyPacket(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
)
448 S_CLASSIFIER_RULE
*pstClassifierRule
= NULL
;
449 S_ETHCS_PKT_INFO stEthCsPktInfo
;
450 PVOID pvEThPayload
= NULL
;
451 struct iphdr
*pIpHeader
= NULL
;
453 USHORT usIndex
=Adapter
->usBestEffortQueueIndex
;
454 BOOLEAN bFragmentedPkt
=FALSE
,bClassificationSucceed
=FALSE
;
455 USHORT usCurrFragment
=0;
457 PTCP_HEADER pTcpHeader
;
458 UCHAR IpHeaderLength
;
459 UCHAR TcpHeaderLength
;
461 pvEThPayload
= skb
->data
;
462 *((UINT32
*) (skb
->cb
) +SKB_CB_TCPACK_OFFSET
) = 0;
463 EThCSGetPktInfo(Adapter
,pvEThPayload
,&stEthCsPktInfo
);
465 switch(stEthCsPktInfo
.eNwpktEthFrameType
)
467 case eEth802LLCFrame
:
469 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802LLCFrame\n");
470 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_LLC_FRAME
);
474 case eEth802LLCSNAPFrame
:
476 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802LLC SNAP Frame\n");
477 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_LLC_SNAP_FRAME
);
480 case eEth802QVLANFrame
:
482 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802.1Q VLANFrame\n");
483 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_Q_FRAME
);
488 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : ETH Other Frame\n");
489 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_ETH2_FRAME
);
494 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : Unrecognized ETH Frame\n");
495 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_ETH2_FRAME
);
500 if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv4Packet
)
502 usCurrFragment
= (ntohs(pIpHeader
->frag_off
) & IP_OFFSET
);
503 if((ntohs(pIpHeader
->frag_off
) & IP_MF
) || usCurrFragment
)
504 bFragmentedPkt
= TRUE
;
508 //Fragmented Packet. Get Frag Classifier Entry.
509 pstClassifierRule
= GetFragIPClsEntry(Adapter
,pIpHeader
->id
, pIpHeader
->saddr
);
510 if(pstClassifierRule
)
512 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
,"It is next Fragmented pkt");
513 bClassificationSucceed
=TRUE
;
515 if(!(ntohs(pIpHeader
->frag_off
) & IP_MF
))
517 //Fragmented Last packet . Remove Frag Classifier Entry
518 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
,"This is the last fragmented Pkt");
519 DelFragIPClsEntry(Adapter
,pIpHeader
->id
, pIpHeader
->saddr
);
524 for(uiLoopIndex
= MAX_CLASSIFIERS
- 1; uiLoopIndex
>= 0; uiLoopIndex
--)
526 if(bClassificationSucceed
)
528 //Iterate through all classifiers which are already in order of priority
529 //to classify the packet until match found
532 if(FALSE
==Adapter
->astClassifierTable
[uiLoopIndex
].bUsed
)
534 bClassificationSucceed
=FALSE
;
537 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex
);
539 if(0 == Adapter
->astClassifierTable
[uiLoopIndex
].ucDirection
)
541 bClassificationSucceed
=FALSE
;//cannot be processed for classification.
542 break; // it is a down link connection
545 pstClassifierRule
= &Adapter
->astClassifierTable
[uiLoopIndex
];
547 uiSfIndex
= SearchSfid(Adapter
,pstClassifierRule
->ulSFID
);
548 if (uiSfIndex
>= NO_OF_QUEUES
) {
549 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Queue Not Valid. SearchSfid for this classifier Failed\n");
553 if(Adapter
->PackInfo
[uiSfIndex
].bEthCSSupport
)
556 if(eEthUnsupportedFrame
==stEthCsPktInfo
.eNwpktEthFrameType
)
558 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame \n");
559 bClassificationSucceed
= FALSE
;
565 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
);
566 bClassificationSucceed
= EThCSClassifyPkt(Adapter
,skb
,&stEthCsPktInfo
,pstClassifierRule
, Adapter
->PackInfo
[uiSfIndex
].bEthCSSupport
);
568 if(!bClassificationSucceed
)
570 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : Ethernet CS Classification Failed\n");
575 else // No ETH Supported on this SF
577 if(eEthOtherFrame
!= stEthCsPktInfo
.eNwpktEthFrameType
)
579 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");
580 bClassificationSucceed
= FALSE
;
585 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Proceeding to IP CS Clasification");
587 if(Adapter
->PackInfo
[uiSfIndex
].bIPCSSupport
)
590 if(stEthCsPktInfo
.eNwpktIPFrameType
== eNonIPPacket
)
592 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet is Not an IP Packet \n");
593 bClassificationSucceed
= FALSE
;
596 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Dump IP Header : \n");
597 DumpFullPacket((PUCHAR
)pIpHeader
,20);
599 if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv4Packet
)
600 bClassificationSucceed
= IpVersion4(Adapter
,pIpHeader
,pstClassifierRule
);
601 else if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv6Packet
)
602 bClassificationSucceed
= IpVersion6(Adapter
,pIpHeader
,pstClassifierRule
);
608 if(bClassificationSucceed
== TRUE
)
610 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "CF id : %d, SF ID is =%lu",pstClassifierRule
->uiClassifierRuleIndex
, pstClassifierRule
->ulSFID
);
612 //Store The matched Classifier in SKB
613 *((UINT32
*)(skb
->cb
)+SKB_CB_CLASSIFICATION_OFFSET
) = pstClassifierRule
->uiClassifierRuleIndex
;
614 if((TCP
== pIpHeader
->protocol
) && !bFragmentedPkt
&& (ETH_AND_IP_HEADER_LEN
+ TCP_HEADER_LEN
<= skb
->len
) )
616 IpHeaderLength
= pIpHeader
->ihl
;
617 pTcpHeader
= (PTCP_HEADER
)(((PUCHAR
)pIpHeader
)+(IpHeaderLength
*4));
618 TcpHeaderLength
= GET_TCP_HEADER_LEN(pTcpHeader
->HeaderLength
);
620 if((pTcpHeader
->ucFlags
& TCP_ACK
) &&
621 (ntohs(pIpHeader
->tot_len
) == (IpHeaderLength
*4)+(TcpHeaderLength
*4)))
623 *((UINT32
*) (skb
->cb
) +SKB_CB_TCPACK_OFFSET
) = TCP_ACK
;
627 usIndex
= SearchSfid(Adapter
, pstClassifierRule
->ulSFID
);
628 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "index is =%d", usIndex
);
630 //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.
631 if(bFragmentedPkt
&& (usCurrFragment
== 0))
633 //First Fragment of Fragmented Packet. Create Frag CLS Entry
634 S_FRAGMENTED_PACKET_INFO stFragPktInfo
;
635 stFragPktInfo
.bUsed
= TRUE
;
636 stFragPktInfo
.ulSrcIpAddress
= pIpHeader
->saddr
;
637 stFragPktInfo
.usIpIdentification
= pIpHeader
->id
;
638 stFragPktInfo
.pstMatchedClassifierEntry
= pstClassifierRule
;
639 stFragPktInfo
.bOutOfOrderFragment
= FALSE
;
640 AddFragIPClsEntry(Adapter
,&stFragPktInfo
);
646 if(bClassificationSucceed
)
649 return INVALID_QUEUE_INDEX
;
652 static BOOLEAN
EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,PUCHAR Mac
)
655 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
656 if(pstClassifierRule
->ucEthCSSrcMACLen
==0)
658 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s \n",__FUNCTION__
);
659 for(i
=0;i
<MAC_ADDRESS_SIZE
;i
++)
661 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
]);
662 if((pstClassifierRule
->au8EThCSSrcMAC
[i
] & pstClassifierRule
->au8EThCSSrcMACMask
[i
])!=
663 (Mac
[i
] & pstClassifierRule
->au8EThCSSrcMACMask
[i
]))
669 static BOOLEAN
EthCSMatchDestMACAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,PUCHAR Mac
)
672 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
673 if(pstClassifierRule
->ucEthCSDestMACLen
==0)
675 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s \n",__FUNCTION__
);
676 for(i
=0;i
<MAC_ADDRESS_SIZE
;i
++)
678 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
]);
679 if((pstClassifierRule
->au8EThCSDestMAC
[i
] & pstClassifierRule
->au8EThCSDestMACMask
[i
])!=
680 (Mac
[i
] & pstClassifierRule
->au8EThCSDestMACMask
[i
]))
686 static BOOLEAN
EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE
*pstClassifierRule
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
688 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
689 if((pstClassifierRule
->ucEtherTypeLen
==0)||
690 (pstClassifierRule
->au8EthCSEtherType
[0] == 0))
693 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]);
694 if(pstClassifierRule
->au8EthCSEtherType
[0] == 1)
696 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]);
698 if(memcmp(&pstEthCsPktInfo
->usEtherType
,&pstClassifierRule
->au8EthCSEtherType
[1],2)==0)
704 if(pstClassifierRule
->au8EthCSEtherType
[0] == 2)
706 if(eEth802LLCFrame
!= pstEthCsPktInfo
->eNwpktEthFrameType
)
709 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]);
710 if(pstEthCsPktInfo
->ucDSAP
== pstClassifierRule
->au8EthCSEtherType
[2])
721 static BOOLEAN
EthCSMatchVLANRules(S_CLASSIFIER_RULE
*pstClassifierRule
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
723 BOOLEAN bClassificationSucceed
= FALSE
;
725 B_UINT8 uPriority
= 0;
726 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
728 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
);
730 /* In case FW didn't receive the TLV, the priority field should be ignored */
731 if(pstClassifierRule
->usValidityBitMap
& (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID
))
733 if(pstEthCsPktInfo
->eNwpktEthFrameType
!=eEth802QVLANFrame
)
736 uPriority
= (ntohs(*(USHORT
*)(skb
->data
+ sizeof(ETH_HEADER_STRUC
))) & 0xF000) >> 13;
738 if((uPriority
>= pstClassifierRule
->usUserPriority
[0]) && (uPriority
<= pstClassifierRule
->usUserPriority
[1]))
739 bClassificationSucceed
= TRUE
;
741 if(!bClassificationSucceed
)
745 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 D User Priority Rule Matched\n");
747 bClassificationSucceed
= FALSE
;
749 if(pstClassifierRule
->usValidityBitMap
& (1<<PKT_CLASSIFICATION_VLANID_VALID
))
751 if(pstEthCsPktInfo
->eNwpktEthFrameType
!=eEth802QVLANFrame
)
754 usVLANID
= ntohs(*(USHORT
*)(skb
->data
+ sizeof(ETH_HEADER_STRUC
))) & 0xFFF;
756 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__
,usVLANID
, uPriority
);
758 if(usVLANID
== ((pstClassifierRule
->usVLANID
& 0xFFF0) >> 4))
759 bClassificationSucceed
= TRUE
;
761 if(!bClassificationSucceed
)
765 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 Q VLAN ID Rule Matched\n");
771 static BOOLEAN
EThCSClassifyPkt(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
,
772 PS_ETHCS_PKT_INFO pstEthCsPktInfo
,
773 S_CLASSIFIER_RULE
*pstClassifierRule
,
774 B_UINT8 EthCSCupport
)
776 BOOLEAN bClassificationSucceed
= FALSE
;
777 bClassificationSucceed
= EthCSMatchSrcMACAddress(pstClassifierRule
,((ETH_HEADER_STRUC
*)(skb
->data
))->au8SourceAddress
);
778 if(!bClassificationSucceed
)
780 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS SrcMAC Matched\n");
782 bClassificationSucceed
= EthCSMatchDestMACAddress(pstClassifierRule
,((ETH_HEADER_STRUC
*)(skb
->data
))->au8DestinationAddress
);
783 if(!bClassificationSucceed
)
785 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS DestMAC Matched\n");
787 //classify on ETHType/802.2SAP TLV
788 bClassificationSucceed
= EthCSMatchEThTypeSAP(pstClassifierRule
,skb
,pstEthCsPktInfo
);
789 if(!bClassificationSucceed
)
792 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS EthType/802.2SAP Matched\n");
794 //classify on 802.1VLAN Header Parameters
796 bClassificationSucceed
= EthCSMatchVLANRules(pstClassifierRule
,skb
,pstEthCsPktInfo
);
797 if(!bClassificationSucceed
)
799 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 VLAN Rules Matched\n");
801 return bClassificationSucceed
;
804 static void EThCSGetPktInfo(PMINI_ADAPTER Adapter
,PVOID pvEthPayload
,
805 PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
807 USHORT u16Etype
= ntohs(((ETH_HEADER_STRUC
*)pvEthPayload
)->u16Etype
);
809 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype
);
812 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCSGetPktInfo : ETH2 Frame \n");
814 if(u16Etype
== ETHERNET_FRAMETYPE_802QVLAN
)
817 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802QVLANFrame
;
818 u16Etype
= ((ETH_CS_802_Q_FRAME
*)pvEthPayload
)->EthType
;
819 //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority
823 pstEthCsPktInfo
->eNwpktEthFrameType
= eEthOtherFrame
;
824 u16Etype
= ntohs(u16Etype
);
831 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "802.2 LLC Frame \n");
832 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802LLCFrame
;
833 pstEthCsPktInfo
->ucDSAP
= ((ETH_CS_802_LLC_FRAME
*)pvEthPayload
)->DSAP
;
834 if(pstEthCsPktInfo
->ucDSAP
== 0xAA && ((ETH_CS_802_LLC_FRAME
*)pvEthPayload
)->SSAP
== 0xAA)
837 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802LLCSNAPFrame
;
838 u16Etype
= ((ETH_CS_802_LLC_SNAP_FRAME
*)pvEthPayload
)->usEtherType
;
841 if(u16Etype
== ETHERNET_FRAMETYPE_IPV4
)
842 pstEthCsPktInfo
->eNwpktIPFrameType
= eIPv4Packet
;
843 else if(u16Etype
== ETHERNET_FRAMETYPE_IPV6
)
844 pstEthCsPktInfo
->eNwpktIPFrameType
= eIPv6Packet
;
846 pstEthCsPktInfo
->eNwpktIPFrameType
= eNonIPPacket
;
848 pstEthCsPktInfo
->usEtherType
= ((ETH_HEADER_STRUC
*)pvEthPayload
)->u16Etype
;
849 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo
->eNwpktIPFrameType
);
850 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo
->eNwpktEthFrameType
);
851 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo
->usEtherType
);