3 This file contains the routines related to Quality of Service.
7 BOOLEAN
MatchSrcIpAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,ULONG ulSrcIP
);
8 BOOLEAN
MatchTos(S_CLASSIFIER_RULE
*pstClassifierRule
,UCHAR ucTypeOfService
);
9 BOOLEAN
MatchSrcPort(S_CLASSIFIER_RULE
*pstClassifierRule
,USHORT ushSrcPort
);
10 BOOLEAN
MatchDestPort(S_CLASSIFIER_RULE
*pstClassifierRule
,USHORT ushDestPort
);
11 BOOLEAN
MatchProtocol(S_CLASSIFIER_RULE
*pstClassifierRule
,UCHAR ucProtocol
);
12 BOOLEAN
MatchDestIpAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,ULONG ulDestIP
);
13 USHORT
ClassifyPacket(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
);
14 void EThCSGetPktInfo(PMINI_ADAPTER Adapter
,PVOID pvEthPayload
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
);
15 BOOLEAN
EThCSClassifyPkt(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
,S_CLASSIFIER_RULE
*pstClassifierRule
, B_UINT8 EthCSCupport
);
17 /*******************************************************************
18 * Function - MatchSrcIpAddress()
20 * Description - Checks whether the Source IP address from the packet
21 * matches with that of Queue.
23 * Parameters - pstClassifierRule: Pointer to the packet info structure.
24 * - ulSrcIP : Source IP address from the packet.
26 * Returns - TRUE(If address matches) else FAIL .
27 *********************************************************************/
28 BOOLEAN
MatchSrcIpAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,ULONG ulSrcIP
)
32 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
34 ulSrcIP
=ntohl(ulSrcIP
);
35 if(0 == pstClassifierRule
->ucIPSourceAddressLength
)
37 for(ucLoopIndex
=0; ucLoopIndex
< (pstClassifierRule
->ucIPSourceAddressLength
);ucLoopIndex
++)
39 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
]);
40 if((pstClassifierRule
->stSrcIpAddress
.ulIpv4Mask
[ucLoopIndex
] & ulSrcIP
)==
41 (pstClassifierRule
->stSrcIpAddress
.ulIpv4Addr
[ucLoopIndex
] & pstClassifierRule
->stSrcIpAddress
.ulIpv4Mask
[ucLoopIndex
] ))
46 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Ip Address Not Matched");
51 /*******************************************************************
52 * Function - MatchDestIpAddress()
54 * Description - Checks whether the Destination IP address from the packet
55 * matches with that of Queue.
57 * Parameters - pstClassifierRule: Pointer to the packet info structure.
58 * - ulDestIP : Destination IP address from the packet.
60 * Returns - TRUE(If address matches) else FAIL .
61 *********************************************************************/
62 BOOLEAN
MatchDestIpAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,ULONG ulDestIP
)
65 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
67 ulDestIP
=ntohl(ulDestIP
);
68 if(0 == pstClassifierRule
->ucIPDestinationAddressLength
)
70 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
]);
72 for(ucLoopIndex
=0;ucLoopIndex
<(pstClassifierRule
->ucIPDestinationAddressLength
);ucLoopIndex
++)
74 if((pstClassifierRule
->stDestIpAddress
.ulIpv4Mask
[ucLoopIndex
] & ulDestIP
)==
75 (pstClassifierRule
->stDestIpAddress
.ulIpv4Addr
[ucLoopIndex
] & pstClassifierRule
->stDestIpAddress
.ulIpv4Mask
[ucLoopIndex
]))
80 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination Ip Address Not Matched");
85 /************************************************************************
86 * Function - MatchTos()
88 * Description - Checks the TOS from the packet matches with that of queue.
90 * Parameters - pstClassifierRule : Pointer to the packet info structure.
91 * - ucTypeOfService: TOS from the packet.
93 * Returns - TRUE(If address matches) else FAIL.
94 **************************************************************************/
95 BOOLEAN
MatchTos(S_CLASSIFIER_RULE
*pstClassifierRule
,UCHAR ucTypeOfService
)
98 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
99 if( 3 != pstClassifierRule
->ucIPTypeOfServiceLength
)
102 if(((pstClassifierRule
->ucTosMask
& ucTypeOfService
)<=pstClassifierRule
->ucTosHigh
) && ((pstClassifierRule
->ucTosMask
& ucTypeOfService
)>=pstClassifierRule
->ucTosLow
))
106 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Type Of Service Not Matched");
111 /***************************************************************************
112 * Function - MatchProtocol()
114 * Description - Checks the protocol from the packet matches with that of queue.
116 * Parameters - pstClassifierRule: Pointer to the packet info structure.
117 * - ucProtocol : Protocol from the packet.
119 * Returns - TRUE(If address matches) else FAIL.
120 ****************************************************************************/
121 BOOLEAN
MatchProtocol(S_CLASSIFIER_RULE
*pstClassifierRule
,UCHAR ucProtocol
)
124 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
125 if(0 == pstClassifierRule
->ucProtocolLength
)
127 for(ucLoopIndex
=0;ucLoopIndex
<pstClassifierRule
->ucProtocolLength
;ucLoopIndex
++)
129 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Protocol:0x%X Classification Protocol:0x%X",ucProtocol
,pstClassifierRule
->ucProtocol
[ucLoopIndex
]);
130 if(pstClassifierRule
->ucProtocol
[ucLoopIndex
]==ucProtocol
)
135 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Protocol Not Matched");
140 /***********************************************************************
141 * Function - MatchSrcPort()
143 * Description - Checks, Source port from the packet matches with that of queue.
145 * Parameters - pstClassifierRule: Pointer to the packet info structure.
146 * - ushSrcPort : Source port from the packet.
148 * Returns - TRUE(If address matches) else FAIL.
149 ***************************************************************************/
150 BOOLEAN
MatchSrcPort(S_CLASSIFIER_RULE
*pstClassifierRule
,USHORT ushSrcPort
)
154 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
157 if(0 == pstClassifierRule
->ucSrcPortRangeLength
)
159 for(ucLoopIndex
=0;ucLoopIndex
<pstClassifierRule
->ucSrcPortRangeLength
;ucLoopIndex
++)
161 if(ushSrcPort
<= pstClassifierRule
->usSrcPortRangeHi
[ucLoopIndex
] &&
162 ushSrcPort
>= pstClassifierRule
->usSrcPortRangeLo
[ucLoopIndex
])
167 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Port: %x Not Matched ",ushSrcPort
);
172 /***********************************************************************
173 * Function - MatchDestPort()
175 * Description - Checks, Destination port from packet matches with that of queue.
177 * Parameters - pstClassifierRule: Pointer to the packet info structure.
178 * - ushDestPort : Destination port from the packet.
180 * Returns - TRUE(If address matches) else FAIL.
181 ***************************************************************************/
182 BOOLEAN
MatchDestPort(S_CLASSIFIER_RULE
*pstClassifierRule
,USHORT ushDestPort
)
185 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
187 if(0 == pstClassifierRule
->ucDestPortRangeLength
)
190 for(ucLoopIndex
=0;ucLoopIndex
<pstClassifierRule
->ucDestPortRangeLength
;ucLoopIndex
++)
192 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
]);
194 if(ushDestPort
<= pstClassifierRule
->usDestPortRangeHi
[ucLoopIndex
] &&
195 ushDestPort
>= pstClassifierRule
->usDestPortRangeLo
[ucLoopIndex
])
200 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Dest Port: %x Not Matched",ushDestPort
);
204 @ingroup tx_functions
205 Compares IPV4 Ip address and port number
208 USHORT
IpVersion4(PMINI_ADAPTER Adapter
, /**< Pointer to the driver control structure */
209 struct iphdr
*iphd
, /**<Pointer to the IP Hdr of the packet*/
210 S_CLASSIFIER_RULE
*pstClassifierRule
)
212 //IPHeaderFormat *pIpHeader=NULL;
213 xporthdr
*xprt_hdr
=NULL
;
214 BOOLEAN bClassificationSucceed
=FALSE
;
216 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "========>");
218 xprt_hdr
=(xporthdr
*)((PUCHAR
)iphd
+ sizeof(struct iphdr
));
221 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Trying to see Direction = %d %d",
222 pstClassifierRule
->ucDirection
,
223 pstClassifierRule
->usVCID_Value
);
225 //Checking classifier validity
226 if(!pstClassifierRule
->bUsed
|| pstClassifierRule
->ucDirection
== DOWNLINK_DIR
)
228 bClassificationSucceed
= FALSE
;
232 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "is IPv6 check!");
233 if(pstClassifierRule
->bIpv6Protocol
)
236 //**************Checking IP header parameter**************************//
237 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Trying to match Source IP Address");
238 if(FALSE
== (bClassificationSucceed
=
239 MatchSrcIpAddress(pstClassifierRule
, iphd
->saddr
)))
241 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Source IP Address Matched");
243 if(FALSE
== (bClassificationSucceed
=
244 MatchDestIpAddress(pstClassifierRule
, iphd
->daddr
)))
246 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination IP Address Matched");
248 if(FALSE
== (bClassificationSucceed
=
249 MatchTos(pstClassifierRule
, iphd
->tos
)))
251 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "TOS Match failed\n");
254 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "TOS Matched");
256 if(FALSE
== (bClassificationSucceed
=
257 MatchProtocol(pstClassifierRule
,iphd
->protocol
)))
259 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Protocol Matched");
261 //if protocol is not TCP or UDP then no need of comparing source port and destination port
262 if(iphd
->protocol
!=TCP
&& iphd
->protocol
!=UDP
)
265 //check if memory is available of src and Dest port
266 if(ETH_AND_IP_HEADER_LEN
+ L4_SRC_PORT_LEN
+ L4_DEST_PORT_LEN
> Packet
->len
)
268 //This is not an erroneous condition and pkt will be checked for next classification.
269 bClassificationSucceed
= FALSE
;
273 //******************Checking Transport Layer Header field if present *****************//
274 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Source Port %04x",
275 (iphd
->protocol
==UDP
)?xprt_hdr
->uhdr
.source
:xprt_hdr
->thdr
.source
);
277 if(FALSE
== (bClassificationSucceed
=
278 MatchSrcPort(pstClassifierRule
,
279 ntohs((iphd
->protocol
== UDP
)?
280 xprt_hdr
->uhdr
.source
:xprt_hdr
->thdr
.source
))))
282 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Src Port Matched");
284 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Destination Port %04x",
285 (iphd
->protocol
==UDP
)?xprt_hdr
->uhdr
.dest
:
286 xprt_hdr
->thdr
.dest
);
287 if(FALSE
== (bClassificationSucceed
=
288 MatchDestPort(pstClassifierRule
,
289 ntohs((iphd
->protocol
== UDP
)?
290 xprt_hdr
->uhdr
.dest
:xprt_hdr
->thdr
.dest
))))
294 if(TRUE
==bClassificationSucceed
)
296 INT iMatchedSFQueueIndex
= 0;
297 iMatchedSFQueueIndex
= SearchSfid(Adapter
,pstClassifierRule
->ulSFID
);
298 if(iMatchedSFQueueIndex
>= NO_OF_QUEUES
)
300 bClassificationSucceed
= FALSE
;
304 if(FALSE
== Adapter
->PackInfo
[iMatchedSFQueueIndex
].bActive
)
306 bClassificationSucceed
= FALSE
;
311 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "IpVersion4 <==========");
313 return bClassificationSucceed
;
316 @ingroup tx_functions
317 @return Queue Index based on priority.
319 USHORT
GetPacketQueueIndex(PMINI_ADAPTER Adapter
, /**<Pointer to the driver control structure */
320 struct sk_buff
* Packet
/**< Pointer to the Packet to be sent*/
324 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, QUEUE_INDEX
, DBG_LVL_ALL
, "=====>");
326 if(NULL
==Adapter
|| NULL
==Packet
)
328 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, QUEUE_INDEX
, DBG_LVL_ALL
, "Got NULL Values<======");
332 usIndex
= ClassifyPacket(Adapter
,Packet
);
334 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, QUEUE_INDEX
, DBG_LVL_ALL
, "Got Queue Index %x",usIndex
);
335 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, QUEUE_INDEX
, DBG_LVL_ALL
, "GetPacketQueueIndex <==============");
339 VOID
PruneQueueAllSF(PMINI_ADAPTER Adapter
)
343 for(iIndex
= 0; iIndex
< HiPriority
; iIndex
++)
345 if(!Adapter
->PackInfo
[iIndex
].bValid
)
348 PruneQueue(Adapter
, iIndex
);
354 @ingroup tx_functions
355 This function checks if the max queue size for a queue
356 is less than number of bytes in the queue. If so -
357 drops packets from the Head till the number of bytes is
358 less than or equal to max queue size for the queue.
360 VOID
PruneQueue(PMINI_ADAPTER Adapter
,/**<Pointer to the driver control structure*/
361 INT iIndex
/**<Queue Index*/
364 struct sk_buff
* PacketToDrop
=NULL
;
365 struct net_device_stats
* netstats
=NULL
;
367 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "=====> Index %d",iIndex
);
369 if(iIndex
== HiPriority
)
372 if(!Adapter
|| (iIndex
< 0) || (iIndex
> HiPriority
))
375 /* To Store the netdevice statistic */
376 netstats
= &((PLINUX_DEP_DATA
)Adapter
->pvOsDepData
)->netstats
;
378 spin_lock_bh(&Adapter
->PackInfo
[iIndex
].SFQueueLock
);
381 // while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost >
382 // SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
384 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
385 Adapter
->PackInfo
[iIndex
].uiCurrentBytesOnHost
,
386 Adapter
->PackInfo
[iIndex
].uiMaxBucketSize
);
388 PacketToDrop
= Adapter
->PackInfo
[iIndex
].FirstTxQueue
;
390 if(PacketToDrop
== NULL
)
392 if((Adapter
->PackInfo
[iIndex
].uiCurrentPacketsOnHost
< SF_MAX_ALLOWED_PACKETS_TO_BACKUP
) &&
393 ((1000*(jiffies
- *((B_UINT32
*)(PacketToDrop
->cb
)+SKB_CB_LATENCY_OFFSET
))/HZ
) <= Adapter
->PackInfo
[iIndex
].uiMaxLatency
))
399 netstats
->tx_dropped
++;
400 atomic_inc(&Adapter
->TxDroppedPacketCount
);
401 DEQUEUEPACKET(Adapter
->PackInfo
[iIndex
].FirstTxQueue
,
402 Adapter
->PackInfo
[iIndex
].LastTxQueue
);
403 /// update current bytes and packets count
404 Adapter
->PackInfo
[iIndex
].uiCurrentBytesOnHost
-=
406 Adapter
->PackInfo
[iIndex
].uiCurrentPacketsOnHost
--;
407 /// update dropped bytes and packets counts
408 Adapter
->PackInfo
[iIndex
].uiDroppedCountBytes
+= PacketToDrop
->len
;
409 Adapter
->PackInfo
[iIndex
].uiDroppedCountPackets
++;
410 bcm_kfree_skb(PacketToDrop
);
414 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "Dropped Bytes:%x Dropped Packets:%x",
415 Adapter
->PackInfo
[iIndex
].uiDroppedCountBytes
,
416 Adapter
->PackInfo
[iIndex
].uiDroppedCountPackets
);
418 atomic_dec(&Adapter
->TotalPacketCount
);
419 Adapter
->bcm_jiffies
= jiffies
;
422 spin_unlock_bh(&Adapter
->PackInfo
[iIndex
].SFQueueLock
);
424 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "TotalPacketCount:%x",
425 atomic_read(&Adapter
->TotalPacketCount
));
426 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, PRUNE_QUEUE
, DBG_LVL_ALL
, "<=====");
429 VOID
flush_all_queues(PMINI_ADAPTER Adapter
)
432 UINT uiTotalPacketLength
;
433 struct sk_buff
* PacketToDrop
=NULL
;
434 struct net_device_stats
* netstats
=NULL
;
436 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "=====>");
437 /* To Store the netdevice statistic */
438 netstats
= &((PLINUX_DEP_DATA
)Adapter
->pvOsDepData
)->netstats
;
440 // down(&Adapter->data_packet_queue_lock);
441 for(iQIndex
=LowPriority
; iQIndex
<HiPriority
; iQIndex
++)
443 spin_lock_bh(&Adapter
->PackInfo
[iQIndex
].SFQueueLock
);
444 while(Adapter
->PackInfo
[iQIndex
].FirstTxQueue
)
446 PacketToDrop
= Adapter
->PackInfo
[iQIndex
].FirstTxQueue
;
449 uiTotalPacketLength
= PacketToDrop
->len
;
450 netstats
->tx_dropped
++;
451 atomic_inc(&Adapter
->TxDroppedPacketCount
);
454 uiTotalPacketLength
= 0;
456 DEQUEUEPACKET(Adapter
->PackInfo
[iQIndex
].FirstTxQueue
,
457 Adapter
->PackInfo
[iQIndex
].LastTxQueue
);
460 bcm_kfree_skb(PacketToDrop
);
462 /// update current bytes and packets count
463 Adapter
->PackInfo
[iQIndex
].uiCurrentBytesOnHost
-= uiTotalPacketLength
;
464 Adapter
->PackInfo
[iQIndex
].uiCurrentPacketsOnHost
--;
466 /// update dropped bytes and packets counts
467 Adapter
->PackInfo
[iQIndex
].uiDroppedCountBytes
+= uiTotalPacketLength
;
468 Adapter
->PackInfo
[iQIndex
].uiDroppedCountPackets
++;
470 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "Dropped Bytes:%x Dropped Packets:%x",
471 Adapter
->PackInfo
[iQIndex
].uiDroppedCountBytes
,
472 Adapter
->PackInfo
[iQIndex
].uiDroppedCountPackets
);
473 atomic_dec(&Adapter
->TotalPacketCount
);
475 spin_unlock_bh(&Adapter
->PackInfo
[iQIndex
].SFQueueLock
);
477 // up(&Adapter->data_packet_queue_lock);
478 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, DBG_LVL_ALL
, "<=====");
481 USHORT
ClassifyPacket(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
)
484 S_CLASSIFIER_RULE
*pstClassifierRule
= NULL
;
485 S_ETHCS_PKT_INFO stEthCsPktInfo
;
486 PVOID pvEThPayload
= NULL
;
487 struct iphdr
*pIpHeader
= NULL
;
489 USHORT usIndex
=Adapter
->usBestEffortQueueIndex
;
490 BOOLEAN bFragmentedPkt
=FALSE
,bClassificationSucceed
=FALSE
;
491 USHORT usCurrFragment
=0;
493 PTCP_HEADER pTcpHeader
;
494 UCHAR IpHeaderLength
;
495 UCHAR TcpHeaderLength
;
497 pvEThPayload
= skb
->data
;
498 *((UINT32
*) (skb
->cb
) +SKB_CB_TCPACK_OFFSET
) = 0;
499 EThCSGetPktInfo(Adapter
,pvEThPayload
,&stEthCsPktInfo
);
501 switch(stEthCsPktInfo
.eNwpktEthFrameType
)
503 case eEth802LLCFrame
:
505 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802LLCFrame\n");
506 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_LLC_FRAME
);
510 case eEth802LLCSNAPFrame
:
512 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802LLC SNAP Frame\n");
513 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_LLC_SNAP_FRAME
);
516 case eEth802QVLANFrame
:
518 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : 802.1Q VLANFrame\n");
519 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_802_Q_FRAME
);
524 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : ETH Other Frame\n");
525 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_ETH2_FRAME
);
530 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : Unrecognized ETH Frame\n");
531 pIpHeader
= pvEThPayload
+ sizeof(ETH_CS_ETH2_FRAME
);
536 if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv4Packet
)
538 usCurrFragment
= (ntohs(pIpHeader
->frag_off
) & IP_OFFSET
);
539 if((ntohs(pIpHeader
->frag_off
) & IP_MF
) || usCurrFragment
)
540 bFragmentedPkt
= TRUE
;
544 //Fragmented Packet. Get Frag Classifier Entry.
545 pstClassifierRule
= GetFragIPClsEntry(Adapter
,pIpHeader
->id
, pIpHeader
->saddr
);
546 if(pstClassifierRule
)
548 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
,"It is next Fragmented pkt");
549 bClassificationSucceed
=TRUE
;
551 if(!(ntohs(pIpHeader
->frag_off
) & IP_MF
))
553 //Fragmented Last packet . Remove Frag Classifier Entry
554 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
,"This is the last fragmented Pkt");
555 DelFragIPClsEntry(Adapter
,pIpHeader
->id
, pIpHeader
->saddr
);
560 for(uiLoopIndex
= MAX_CLASSIFIERS
- 1; uiLoopIndex
>= 0; uiLoopIndex
--)
562 if (Adapter
->device_removed
)
564 bClassificationSucceed
= FALSE
;
568 if(bClassificationSucceed
)
570 //Iterate through all classifiers which are already in order of priority
571 //to classify the packet until match found
574 if(FALSE
==Adapter
->astClassifierTable
[uiLoopIndex
].bUsed
)
576 bClassificationSucceed
=FALSE
;
579 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex
);
581 if(0 == Adapter
->astClassifierTable
[uiLoopIndex
].ucDirection
)
583 bClassificationSucceed
=FALSE
;//cannot be processed for classification.
584 break; // it is a down link connection
587 pstClassifierRule
= &Adapter
->astClassifierTable
[uiLoopIndex
];
589 uiSfIndex
= SearchSfid(Adapter
,pstClassifierRule
->ulSFID
);
590 if (uiSfIndex
>= NO_OF_QUEUES
) {
591 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Queue Not Valid. SearchSfid for this classifier Failed\n");
595 if(Adapter
->PackInfo
[uiSfIndex
].bEthCSSupport
)
598 if(eEthUnsupportedFrame
==stEthCsPktInfo
.eNwpktEthFrameType
)
600 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame \n");
601 bClassificationSucceed
= FALSE
;
607 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
);
608 bClassificationSucceed
= EThCSClassifyPkt(Adapter
,skb
,&stEthCsPktInfo
,pstClassifierRule
, Adapter
->PackInfo
[uiSfIndex
].bEthCSSupport
);
610 if(!bClassificationSucceed
)
612 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ClassifyPacket : Ethernet CS Classification Failed\n");
617 else // No ETH Supported on this SF
619 if(eEthOtherFrame
!= stEthCsPktInfo
.eNwpktEthFrameType
)
621 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");
622 bClassificationSucceed
= FALSE
;
627 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Proceeding to IP CS Clasification");
629 if(Adapter
->PackInfo
[uiSfIndex
].bIPCSSupport
)
632 if(stEthCsPktInfo
.eNwpktIPFrameType
== eNonIPPacket
)
634 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, " ClassifyPacket : Packet is Not an IP Packet \n");
635 bClassificationSucceed
= FALSE
;
638 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "Dump IP Header : \n");
639 DumpFullPacket((PUCHAR
)pIpHeader
,20);
641 if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv4Packet
)
642 bClassificationSucceed
= IpVersion4(Adapter
,pIpHeader
,pstClassifierRule
);
643 else if(stEthCsPktInfo
.eNwpktIPFrameType
== eIPv6Packet
)
644 bClassificationSucceed
= IpVersion6(Adapter
,pIpHeader
,pstClassifierRule
);
650 if(bClassificationSucceed
== TRUE
)
652 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "CF id : %d, SF ID is =%lu",pstClassifierRule
->uiClassifierRuleIndex
, pstClassifierRule
->ulSFID
);
654 //Store The matched Classifier in SKB
655 *((UINT32
*)(skb
->cb
)+SKB_CB_CLASSIFICATION_OFFSET
) = pstClassifierRule
->uiClassifierRuleIndex
;
656 if((TCP
== pIpHeader
->protocol
) && !bFragmentedPkt
&& (ETH_AND_IP_HEADER_LEN
+ TCP_HEADER_LEN
<= skb
->len
) )
658 IpHeaderLength
= pIpHeader
->ihl
;
659 pTcpHeader
= (PTCP_HEADER
)(((PUCHAR
)pIpHeader
)+(IpHeaderLength
*4));
660 TcpHeaderLength
= GET_TCP_HEADER_LEN(pTcpHeader
->HeaderLength
);
662 if((pTcpHeader
->ucFlags
& TCP_ACK
) &&
663 (ntohs(pIpHeader
->tot_len
) == (IpHeaderLength
*4)+(TcpHeaderLength
*4)))
665 *((UINT32
*) (skb
->cb
) +SKB_CB_TCPACK_OFFSET
) = TCP_ACK
;
669 usIndex
= SearchSfid(Adapter
, pstClassifierRule
->ulSFID
);
670 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "index is =%d", usIndex
);
672 //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.
673 if(bFragmentedPkt
&& (usCurrFragment
== 0))
675 //First Fragment of Fragmented Packet. Create Frag CLS Entry
676 S_FRAGMENTED_PACKET_INFO stFragPktInfo
;
677 stFragPktInfo
.bUsed
= TRUE
;
678 stFragPktInfo
.ulSrcIpAddress
= pIpHeader
->saddr
;
679 stFragPktInfo
.usIpIdentification
= pIpHeader
->id
;
680 stFragPktInfo
.pstMatchedClassifierEntry
= pstClassifierRule
;
681 stFragPktInfo
.bOutOfOrderFragment
= FALSE
;
682 AddFragIPClsEntry(Adapter
,&stFragPktInfo
);
688 if(bClassificationSucceed
)
691 return INVALID_QUEUE_INDEX
;
694 static BOOLEAN
EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,PUCHAR Mac
)
697 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
698 if(pstClassifierRule
->ucEthCSSrcMACLen
==0)
700 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s \n",__FUNCTION__
);
701 for(i
=0;i
<MAC_ADDRESS_SIZE
;i
++)
703 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
]);
704 if((pstClassifierRule
->au8EThCSSrcMAC
[i
] & pstClassifierRule
->au8EThCSSrcMACMask
[i
])!=
705 (Mac
[i
] & pstClassifierRule
->au8EThCSSrcMACMask
[i
]))
711 static BOOLEAN
EthCSMatchDestMACAddress(S_CLASSIFIER_RULE
*pstClassifierRule
,PUCHAR Mac
)
714 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
715 if(pstClassifierRule
->ucEthCSDestMACLen
==0)
717 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s \n",__FUNCTION__
);
718 for(i
=0;i
<MAC_ADDRESS_SIZE
;i
++)
720 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
]);
721 if((pstClassifierRule
->au8EThCSDestMAC
[i
] & pstClassifierRule
->au8EThCSDestMACMask
[i
])!=
722 (Mac
[i
] & pstClassifierRule
->au8EThCSDestMACMask
[i
]))
728 static BOOLEAN
EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE
*pstClassifierRule
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
730 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
731 if((pstClassifierRule
->ucEtherTypeLen
==0)||
732 (pstClassifierRule
->au8EthCSEtherType
[0] == 0))
735 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]);
736 if(pstClassifierRule
->au8EthCSEtherType
[0] == 1)
738 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]);
740 if(memcmp(&pstEthCsPktInfo
->usEtherType
,&pstClassifierRule
->au8EthCSEtherType
[1],2)==0)
746 if(pstClassifierRule
->au8EthCSEtherType
[0] == 2)
748 if(eEth802LLCFrame
!= pstEthCsPktInfo
->eNwpktEthFrameType
)
751 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]);
752 if(pstEthCsPktInfo
->ucDSAP
== pstClassifierRule
->au8EthCSEtherType
[2])
763 static BOOLEAN
EthCSMatchVLANRules(S_CLASSIFIER_RULE
*pstClassifierRule
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
765 BOOLEAN bClassificationSucceed
= FALSE
;
767 B_UINT8 uPriority
= 0;
768 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
770 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
);
772 /* In case FW didn't recieve the TLV, the priority field should be ignored */
773 if(pstClassifierRule
->usValidityBitMap
& (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID
))
775 if(pstEthCsPktInfo
->eNwpktEthFrameType
!=eEth802QVLANFrame
)
778 uPriority
= (ntohs(*(USHORT
*)(skb
->data
+ sizeof(ETH_HEADER_STRUC
))) & 0xF000) >> 13;
780 if((uPriority
>= pstClassifierRule
->usUserPriority
[0]) && (uPriority
<= pstClassifierRule
->usUserPriority
[1]))
781 bClassificationSucceed
= TRUE
;
783 if(!bClassificationSucceed
)
787 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 D User Priority Rule Matched\n");
789 bClassificationSucceed
= FALSE
;
791 if(pstClassifierRule
->usValidityBitMap
& (1<<PKT_CLASSIFICATION_VLANID_VALID
))
793 if(pstEthCsPktInfo
->eNwpktEthFrameType
!=eEth802QVLANFrame
)
796 usVLANID
= ntohs(*(USHORT
*)(skb
->data
+ sizeof(ETH_HEADER_STRUC
))) & 0xFFF;
798 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__
,usVLANID
, uPriority
);
800 if(usVLANID
== ((pstClassifierRule
->usVLANID
& 0xFFF0) >> 4))
801 bClassificationSucceed
= TRUE
;
803 if(!bClassificationSucceed
)
807 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 Q VLAN ID Rule Matched\n");
813 BOOLEAN
EThCSClassifyPkt(PMINI_ADAPTER Adapter
,struct sk_buff
* skb
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
,S_CLASSIFIER_RULE
*pstClassifierRule
, B_UINT8 EthCSCupport
)
815 BOOLEAN bClassificationSucceed
= FALSE
;
816 bClassificationSucceed
= EthCSMatchSrcMACAddress(pstClassifierRule
,((ETH_HEADER_STRUC
*)(skb
->data
))->au8SourceAddress
);
817 if(!bClassificationSucceed
)
819 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS SrcMAC Matched\n");
821 bClassificationSucceed
= EthCSMatchDestMACAddress(pstClassifierRule
,((ETH_HEADER_STRUC
*)(skb
->data
))->au8DestinationAddress
);
822 if(!bClassificationSucceed
)
824 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS DestMAC Matched\n");
826 //classify on ETHType/802.2SAP TLV
827 bClassificationSucceed
= EthCSMatchEThTypeSAP(pstClassifierRule
,skb
,pstEthCsPktInfo
);
828 if(!bClassificationSucceed
)
831 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS EthType/802.2SAP Matched\n");
833 //classify on 802.1VLAN Header Parameters
835 bClassificationSucceed
= EthCSMatchVLANRules(pstClassifierRule
,skb
,pstEthCsPktInfo
);
836 if(!bClassificationSucceed
)
838 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "ETH CS 802.1 VLAN Rules Matched\n");
840 return bClassificationSucceed
;
843 void EThCSGetPktInfo(PMINI_ADAPTER Adapter
,PVOID pvEthPayload
,PS_ETHCS_PKT_INFO pstEthCsPktInfo
)
845 USHORT u16Etype
= ntohs(((ETH_HEADER_STRUC
*)pvEthPayload
)->u16Etype
);
846 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype
);
849 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCSGetPktInfo : ETH2 Frame \n");
851 if(u16Etype
== ETHERNET_FRAMETYPE_802QVLAN
)
854 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802QVLANFrame
;
855 u16Etype
= ((ETH_CS_802_Q_FRAME
*)pvEthPayload
)->EthType
;
856 //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority
860 pstEthCsPktInfo
->eNwpktEthFrameType
= eEthOtherFrame
;
861 u16Etype
= ntohs(u16Etype
);
868 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "802.2 LLC Frame \n");
869 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802LLCFrame
;
870 pstEthCsPktInfo
->ucDSAP
= ((ETH_CS_802_LLC_FRAME
*)pvEthPayload
)->DSAP
;
871 if(pstEthCsPktInfo
->ucDSAP
== 0xAA && ((ETH_CS_802_LLC_FRAME
*)pvEthPayload
)->SSAP
== 0xAA)
874 pstEthCsPktInfo
->eNwpktEthFrameType
= eEth802LLCSNAPFrame
;
875 u16Etype
= ((ETH_CS_802_LLC_SNAP_FRAME
*)pvEthPayload
)->usEtherType
;
878 if(u16Etype
== ETHERNET_FRAMETYPE_IPV4
)
879 pstEthCsPktInfo
->eNwpktIPFrameType
= eIPv4Packet
;
880 else if(u16Etype
== ETHERNET_FRAMETYPE_IPV6
)
881 pstEthCsPktInfo
->eNwpktIPFrameType
= eIPv6Packet
;
883 pstEthCsPktInfo
->eNwpktIPFrameType
= eNonIPPacket
;
885 pstEthCsPktInfo
->usEtherType
= ((ETH_HEADER_STRUC
*)pvEthPayload
)->u16Etype
;
886 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo
->eNwpktIPFrameType
);
887 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo
->eNwpktEthFrameType
);
888 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV4_DBG
, DBG_LVL_ALL
, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo
->usEtherType
);