Commit | Line | Data |
---|---|---|
f8942e07 SH |
1 | /** |
2 | @file Qos.C | |
3 | This file contains the routines related to Quality of Service. | |
4 | */ | |
5 | #include "headers.h" | |
6 | ||
9dd47ee7 SH |
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); | |
9 | ||
10 | static USHORT IpVersion4(PMINI_ADAPTER Adapter, struct iphdr *iphd, | |
11 | S_CLASSIFIER_RULE *pstClassifierRule ); | |
12 | ||
13 | static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex); | |
14 | ||
f8942e07 SH |
15 | |
16 | /******************************************************************* | |
17 | * Function - MatchSrcIpAddress() | |
18 | * | |
19 | * Description - Checks whether the Source IP address from the packet | |
20 | * matches with that of Queue. | |
21 | * | |
22 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
23 | * - ulSrcIP : Source IP address from the packet. | |
24 | * | |
25 | * Returns - TRUE(If address matches) else FAIL . | |
26 | *********************************************************************/ | |
27 | BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP) | |
28 | { | |
29 | UCHAR ucLoopIndex=0; | |
30 | ||
31 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
32 | ||
33 | ulSrcIP=ntohl(ulSrcIP); | |
34 | if(0 == pstClassifierRule->ucIPSourceAddressLength) | |
35 | return TRUE; | |
36 | for(ucLoopIndex=0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);ucLoopIndex++) | |
37 | { | |
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] )) | |
41 | { | |
42 | return TRUE; | |
43 | } | |
44 | } | |
45 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched"); | |
46 | return FALSE; | |
47 | } | |
48 | ||
49 | ||
50 | /******************************************************************* | |
51 | * Function - MatchDestIpAddress() | |
52 | * | |
53 | * Description - Checks whether the Destination IP address from the packet | |
54 | * matches with that of Queue. | |
55 | * | |
56 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
57 | * - ulDestIP : Destination IP address from the packet. | |
58 | * | |
59 | * Returns - TRUE(If address matches) else FAIL . | |
60 | *********************************************************************/ | |
61 | BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP) | |
62 | { | |
63 | UCHAR ucLoopIndex=0; | |
64 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
65 | ||
66 | ulDestIP=ntohl(ulDestIP); | |
67 | if(0 == pstClassifierRule->ucIPDestinationAddressLength) | |
68 | return TRUE; | |
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]); | |
70 | ||
71 | for(ucLoopIndex=0;ucLoopIndex<(pstClassifierRule->ucIPDestinationAddressLength);ucLoopIndex++) | |
72 | { | |
73 | if((pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex] & ulDestIP)== | |
74 | (pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex])) | |
75 | { | |
76 | return TRUE; | |
77 | } | |
78 | } | |
79 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched"); | |
80 | return FALSE; | |
81 | } | |
82 | ||
83 | ||
84 | /************************************************************************ | |
85 | * Function - MatchTos() | |
86 | * | |
87 | * Description - Checks the TOS from the packet matches with that of queue. | |
88 | * | |
89 | * Parameters - pstClassifierRule : Pointer to the packet info structure. | |
90 | * - ucTypeOfService: TOS from the packet. | |
91 | * | |
92 | * Returns - TRUE(If address matches) else FAIL. | |
93 | **************************************************************************/ | |
94 | BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService) | |
95 | { | |
96 | ||
97 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
98 | if( 3 != pstClassifierRule->ucIPTypeOfServiceLength ) | |
99 | return TRUE; | |
100 | ||
101 | if(((pstClassifierRule->ucTosMask & ucTypeOfService)<=pstClassifierRule->ucTosHigh) && ((pstClassifierRule->ucTosMask & ucTypeOfService)>=pstClassifierRule->ucTosLow)) | |
102 | { | |
103 | return TRUE; | |
104 | } | |
105 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched"); | |
106 | return FALSE; | |
107 | } | |
108 | ||
109 | ||
110 | /*************************************************************************** | |
111 | * Function - MatchProtocol() | |
112 | * | |
113 | * Description - Checks the protocol from the packet matches with that of queue. | |
114 | * | |
115 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
116 | * - ucProtocol : Protocol from the packet. | |
117 | * | |
118 | * Returns - TRUE(If address matches) else FAIL. | |
119 | ****************************************************************************/ | |
120 | BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol) | |
121 | { | |
122 | UCHAR ucLoopIndex=0; | |
123 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
124 | if(0 == pstClassifierRule->ucProtocolLength) | |
125 | return TRUE; | |
126 | for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucProtocolLength;ucLoopIndex++) | |
127 | { | |
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) | |
130 | { | |
131 | return TRUE; | |
132 | } | |
133 | } | |
134 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched"); | |
135 | return FALSE; | |
136 | } | |
137 | ||
138 | ||
139 | /*********************************************************************** | |
140 | * Function - MatchSrcPort() | |
141 | * | |
142 | * Description - Checks, Source port from the packet matches with that of queue. | |
143 | * | |
144 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
145 | * - ushSrcPort : Source port from the packet. | |
146 | * | |
147 | * Returns - TRUE(If address matches) else FAIL. | |
148 | ***************************************************************************/ | |
149 | BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort) | |
150 | { | |
151 | UCHAR ucLoopIndex=0; | |
152 | ||
153 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
154 | ||
155 | ||
156 | if(0 == pstClassifierRule->ucSrcPortRangeLength) | |
157 | return TRUE; | |
158 | for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucSrcPortRangeLength;ucLoopIndex++) | |
159 | { | |
160 | if(ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] && | |
161 | ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex]) | |
162 | { | |
163 | return TRUE; | |
164 | } | |
165 | } | |
166 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ",ushSrcPort); | |
167 | return FALSE; | |
168 | } | |
169 | ||
170 | ||
171 | /*********************************************************************** | |
172 | * Function - MatchDestPort() | |
173 | * | |
174 | * Description - Checks, Destination port from packet matches with that of queue. | |
175 | * | |
176 | * Parameters - pstClassifierRule: Pointer to the packet info structure. | |
177 | * - ushDestPort : Destination port from the packet. | |
178 | * | |
179 | * Returns - TRUE(If address matches) else FAIL. | |
180 | ***************************************************************************/ | |
181 | BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort) | |
182 | { | |
183 | UCHAR ucLoopIndex=0; | |
184 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
185 | ||
186 | if(0 == pstClassifierRule->ucDestPortRangeLength) | |
187 | return TRUE; | |
188 | ||
189 | for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucDestPortRangeLength;ucLoopIndex++) | |
190 | { | |
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]); | |
192 | ||
193 | if(ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] && | |
194 | ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex]) | |
195 | { | |
196 | return TRUE; | |
197 | } | |
198 | } | |
199 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched",ushDestPort); | |
200 | return FALSE; | |
201 | } | |
202 | /** | |
203 | @ingroup tx_functions | |
204 | Compares IPV4 Ip address and port number | |
205 | @return Queue Index. | |
206 | */ | |
9dd47ee7 SH |
207 | static USHORT IpVersion4(PMINI_ADAPTER Adapter, |
208 | struct iphdr *iphd, | |
209 | S_CLASSIFIER_RULE *pstClassifierRule ) | |
f8942e07 | 210 | { |
f8942e07 SH |
211 | xporthdr *xprt_hdr=NULL; |
212 | BOOLEAN bClassificationSucceed=FALSE; | |
213 | ||
214 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "========>"); | |
215 | ||
216 | xprt_hdr=(xporthdr *)((PUCHAR)iphd + sizeof(struct iphdr)); | |
217 | ||
218 | do { | |
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); | |
222 | ||
223 | //Checking classifier validity | |
224 | if(!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR) | |
225 | { | |
226 | bClassificationSucceed = FALSE; | |
227 | break; | |
228 | } | |
229 | ||
230 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "is IPv6 check!"); | |
231 | if(pstClassifierRule->bIpv6Protocol) | |
232 | break; | |
233 | ||
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))) | |
238 | break; | |
239 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched"); | |
240 | ||
241 | if(FALSE == (bClassificationSucceed = | |
242 | MatchDestIpAddress(pstClassifierRule, iphd->daddr))) | |
243 | break; | |
244 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched"); | |
245 | ||
246 | if(FALSE == (bClassificationSucceed = | |
247 | MatchTos(pstClassifierRule, iphd->tos))) | |
248 | { | |
249 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n"); | |
250 | break; | |
251 | } | |
252 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched"); | |
253 | ||
254 | if(FALSE == (bClassificationSucceed = | |
255 | MatchProtocol(pstClassifierRule,iphd->protocol))) | |
256 | break; | |
257 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched"); | |
258 | ||
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) | |
261 | break; | |
f8942e07 SH |
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); | |
265 | ||
266 | if(FALSE == (bClassificationSucceed = | |
267 | MatchSrcPort(pstClassifierRule, | |
268 | ntohs((iphd->protocol == UDP)? | |
269 | xprt_hdr->uhdr.source:xprt_hdr->thdr.source)))) | |
270 | break; | |
271 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port Matched"); | |
272 | ||
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)))) | |
280 | break; | |
281 | } while(0); | |
282 | ||
283 | if(TRUE==bClassificationSucceed) | |
284 | { | |
285 | INT iMatchedSFQueueIndex = 0; | |
286 | iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); | |
287 | if(iMatchedSFQueueIndex >= NO_OF_QUEUES) | |
288 | { | |
289 | bClassificationSucceed = FALSE; | |
290 | } | |
291 | else | |
292 | { | |
293 | if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) | |
294 | { | |
295 | bClassificationSucceed = FALSE; | |
296 | } | |
297 | } | |
298 | } | |
299 | ||
300 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "IpVersion4 <=========="); | |
301 | ||
302 | return bClassificationSucceed; | |
303 | } | |
f8942e07 SH |
304 | |
305 | VOID PruneQueueAllSF(PMINI_ADAPTER Adapter) | |
306 | { | |
307 | UINT iIndex = 0; | |
308 | ||
309 | for(iIndex = 0; iIndex < HiPriority; iIndex++) | |
310 | { | |
311 | if(!Adapter->PackInfo[iIndex].bValid) | |
312 | continue; | |
313 | ||
314 | PruneQueue(Adapter, iIndex); | |
315 | } | |
316 | } | |
317 | ||
318 | ||
319 | /** | |
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. | |
325 | */ | |
9dd47ee7 | 326 | static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex) |
f8942e07 SH |
327 | { |
328 | struct sk_buff* PacketToDrop=NULL; | |
92bc6058 | 329 | struct net_device_stats *netstats; |
f8942e07 SH |
330 | |
331 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d",iIndex); | |
332 | ||
333 | if(iIndex == HiPriority) | |
92bc6058 | 334 | return; |
f8942e07 SH |
335 | |
336 | if(!Adapter || (iIndex < 0) || (iIndex > HiPriority)) | |
337 | return; | |
338 | ||
339 | /* To Store the netdevice statistic */ | |
92bc6058 | 340 | netstats = &Adapter->dev->stats; |
f8942e07 SH |
341 | |
342 | spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); | |
343 | ||
344 | while(1) | |
345 | // while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost > | |
346 | // SF_MAX_ALLOWED_PACKETS_TO_BACKUP) | |
347 | { | |
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); | |
351 | ||
352 | PacketToDrop = Adapter->PackInfo[iIndex].FirstTxQueue; | |
353 | ||
354 | if(PacketToDrop == NULL) | |
355 | break; | |
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)) | |
358 | break; | |
359 | ||
360 | if(PacketToDrop) | |
361 | { | |
9ec4475b SH |
362 | if (netif_msg_tx_err(Adapter)) |
363 | pr_info(PFX "%s: tx queue %d overlimit\n", | |
364 | Adapter->dev->name, iIndex); | |
365 | ||
e6f597a1 | 366 | netstats->tx_dropped++; |
cacd9222 | 367 | |
f8942e07 SH |
368 | DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue, |
369 | Adapter->PackInfo[iIndex].LastTxQueue); | |
370 | /// update current bytes and packets count | |
371 | Adapter->PackInfo[iIndex].uiCurrentBytesOnHost -= | |
372 | PacketToDrop->len; | |
373 | Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost--; | |
374 | /// update dropped bytes and packets counts | |
375 | Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len; | |
376 | Adapter->PackInfo[iIndex].uiDroppedCountPackets++; | |
082e889b | 377 | dev_kfree_skb(PacketToDrop); |
f8942e07 SH |
378 | |
379 | } | |
380 | ||
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); | |
384 | ||
385 | atomic_dec(&Adapter->TotalPacketCount); | |
f8942e07 SH |
386 | } |
387 | ||
388 | spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); | |
389 | ||
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, "<====="); | |
393 | } | |
394 | ||
395 | VOID flush_all_queues(PMINI_ADAPTER Adapter) | |
396 | { | |
397 | INT iQIndex; | |
398 | UINT uiTotalPacketLength; | |
cacd9222 | 399 | struct sk_buff* PacketToDrop=NULL; |
f8942e07 SH |
400 | |
401 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>"); | |
f8942e07 SH |
402 | |
403 | // down(&Adapter->data_packet_queue_lock); | |
404 | for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++) | |
405 | { | |
e6f597a1 | 406 | struct net_device_stats *netstats = &Adapter->dev->stats; |
cacd9222 | 407 | |
f8942e07 SH |
408 | spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); |
409 | while(Adapter->PackInfo[iQIndex].FirstTxQueue) | |
410 | { | |
411 | PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; | |
412 | if(PacketToDrop) | |
413 | { | |
414 | uiTotalPacketLength = PacketToDrop->len; | |
e6f597a1 | 415 | netstats->tx_dropped++; |
f8942e07 SH |
416 | } |
417 | else | |
418 | uiTotalPacketLength = 0; | |
419 | ||
420 | DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, | |
421 | Adapter->PackInfo[iQIndex].LastTxQueue); | |
422 | ||
423 | /* Free the skb */ | |
082e889b | 424 | dev_kfree_skb(PacketToDrop); |
f8942e07 SH |
425 | |
426 | /// update current bytes and packets count | |
427 | Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength; | |
428 | Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; | |
429 | ||
430 | /// update dropped bytes and packets counts | |
431 | Adapter->PackInfo[iQIndex].uiDroppedCountBytes += uiTotalPacketLength; | |
432 | Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; | |
433 | ||
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); | |
438 | } | |
439 | spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); | |
440 | } | |
441 | // up(&Adapter->data_packet_queue_lock); | |
442 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "<====="); | |
443 | } | |
444 | ||
445 | USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) | |
446 | { | |
447 | INT uiLoopIndex=0; | |
448 | S_CLASSIFIER_RULE *pstClassifierRule = NULL; | |
449 | S_ETHCS_PKT_INFO stEthCsPktInfo; | |
450 | PVOID pvEThPayload = NULL; | |
451 | struct iphdr *pIpHeader = NULL; | |
452 | INT uiSfIndex=0; | |
453 | USHORT usIndex=Adapter->usBestEffortQueueIndex; | |
454 | BOOLEAN bFragmentedPkt=FALSE,bClassificationSucceed=FALSE; | |
455 | USHORT usCurrFragment =0; | |
456 | ||
457 | PTCP_HEADER pTcpHeader; | |
458 | UCHAR IpHeaderLength; | |
459 | UCHAR TcpHeaderLength; | |
460 | ||
461 | pvEThPayload = skb->data; | |
462 | *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = 0; | |
463 | EThCSGetPktInfo(Adapter,pvEThPayload,&stEthCsPktInfo); | |
464 | ||
465 | switch(stEthCsPktInfo.eNwpktEthFrameType) | |
466 | { | |
467 | case eEth802LLCFrame: | |
468 | { | |
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); | |
471 | break; | |
472 | } | |
473 | ||
474 | case eEth802LLCSNAPFrame: | |
475 | { | |
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); | |
478 | break; | |
479 | } | |
480 | case eEth802QVLANFrame: | |
481 | { | |
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); | |
484 | break; | |
485 | } | |
486 | case eEthOtherFrame: | |
487 | { | |
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); | |
490 | break; | |
491 | } | |
492 | default: | |
493 | { | |
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); | |
496 | break; | |
497 | } | |
498 | } | |
499 | ||
500 | if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) | |
501 | { | |
502 | usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET); | |
503 | if((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment) | |
504 | bFragmentedPkt = TRUE; | |
505 | ||
506 | if(bFragmentedPkt) | |
507 | { | |
508 | //Fragmented Packet. Get Frag Classifier Entry. | |
509 | pstClassifierRule = GetFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr); | |
510 | if(pstClassifierRule) | |
511 | { | |
512 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"It is next Fragmented pkt"); | |
513 | bClassificationSucceed=TRUE; | |
514 | } | |
515 | if(!(ntohs(pIpHeader->frag_off) & IP_MF)) | |
516 | { | |
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); | |
520 | } | |
521 | } | |
522 | } | |
523 | ||
524 | for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) | |
525 | { | |
f8942e07 SH |
526 | if(bClassificationSucceed) |
527 | break; | |
528 | //Iterate through all classifiers which are already in order of priority | |
529 | //to classify the packet until match found | |
530 | do | |
531 | { | |
532 | if(FALSE==Adapter->astClassifierTable[uiLoopIndex].bUsed) | |
533 | { | |
534 | bClassificationSucceed=FALSE; | |
535 | break; | |
536 | } | |
537 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex); | |
538 | ||
539 | if(0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) | |
540 | { | |
541 | bClassificationSucceed=FALSE;//cannot be processed for classification. | |
542 | break; // it is a down link connection | |
543 | } | |
544 | ||
545 | pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex]; | |
546 | ||
547 | uiSfIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); | |
370adc7c | 548 | if (uiSfIndex >= NO_OF_QUEUES) { |
f8942e07 SH |
549 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Queue Not Valid. SearchSfid for this classifier Failed\n"); |
550 | break; | |
551 | } | |
552 | ||
553 | if(Adapter->PackInfo[uiSfIndex].bEthCSSupport) | |
554 | { | |
555 | ||
556 | if(eEthUnsupportedFrame==stEthCsPktInfo.eNwpktEthFrameType) | |
557 | { | |
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; | |
560 | break; | |
561 | } | |
562 | ||
563 | ||
564 | ||
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); | |
567 | ||
568 | if(!bClassificationSucceed) | |
569 | { | |
570 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Ethernet CS Classification Failed\n"); | |
571 | break; | |
572 | } | |
573 | } | |
574 | ||
575 | else // No ETH Supported on this SF | |
576 | { | |
577 | if(eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) | |
578 | { | |
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; | |
581 | break; | |
582 | } | |
583 | } | |
584 | ||
585 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Proceeding to IP CS Clasification"); | |
586 | ||
587 | if(Adapter->PackInfo[uiSfIndex].bIPCSSupport) | |
588 | { | |
589 | ||
590 | if(stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) | |
591 | { | |
592 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet \n"); | |
593 | bClassificationSucceed = FALSE; | |
594 | break; | |
595 | } | |
596 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dump IP Header : \n"); | |
597 | DumpFullPacket((PUCHAR)pIpHeader,20); | |
598 | ||
599 | if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) | |
600 | bClassificationSucceed = IpVersion4(Adapter,pIpHeader,pstClassifierRule); | |
601 | else if(stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet) | |
602 | bClassificationSucceed = IpVersion6(Adapter,pIpHeader,pstClassifierRule); | |
603 | } | |
604 | ||
605 | }while(0); | |
606 | } | |
607 | ||
608 | if(bClassificationSucceed == TRUE) | |
609 | { | |
610 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "CF id : %d, SF ID is =%lu",pstClassifierRule->uiClassifierRuleIndex, pstClassifierRule->ulSFID); | |
611 | ||
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) ) | |
615 | { | |
616 | IpHeaderLength = pIpHeader->ihl; | |
617 | pTcpHeader = (PTCP_HEADER)(((PUCHAR)pIpHeader)+(IpHeaderLength*4)); | |
618 | TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength); | |
619 | ||
620 | if((pTcpHeader->ucFlags & TCP_ACK) && | |
621 | (ntohs(pIpHeader->tot_len) == (IpHeaderLength*4)+(TcpHeaderLength*4))) | |
622 | { | |
623 | *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = TCP_ACK; | |
624 | } | |
625 | } | |
626 | ||
627 | usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); | |
628 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "index is =%d", usIndex); | |
629 | ||
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)) | |
632 | { | |
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); | |
641 | } | |
642 | ||
643 | ||
644 | } | |
645 | ||
646 | if(bClassificationSucceed) | |
647 | return usIndex; | |
648 | else | |
649 | return INVALID_QUEUE_INDEX; | |
650 | } | |
651 | ||
44a17eff | 652 | static BOOLEAN EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac) |
f8942e07 SH |
653 | { |
654 | UINT i=0; | |
655 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
656 | if(pstClassifierRule->ucEthCSSrcMACLen==0) | |
657 | return TRUE; | |
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++) | |
660 | { | |
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])) | |
664 | return FALSE; | |
665 | } | |
666 | return TRUE; | |
667 | } | |
668 | ||
44a17eff | 669 | static BOOLEAN EthCSMatchDestMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac) |
f8942e07 SH |
670 | { |
671 | UINT i=0; | |
672 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
673 | if(pstClassifierRule->ucEthCSDestMACLen==0) | |
674 | return TRUE; | |
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++) | |
677 | { | |
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])) | |
681 | return FALSE; | |
682 | } | |
683 | return TRUE; | |
684 | } | |
685 | ||
44a17eff | 686 | static BOOLEAN EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) |
f8942e07 SH |
687 | { |
688 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
689 | if((pstClassifierRule->ucEtherTypeLen==0)|| | |
690 | (pstClassifierRule->au8EthCSEtherType[0] == 0)) | |
691 | return TRUE; | |
692 | ||
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) | |
695 | { | |
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]); | |
697 | ||
698 | if(memcmp(&pstEthCsPktInfo->usEtherType,&pstClassifierRule->au8EthCSEtherType[1],2)==0) | |
699 | return TRUE; | |
700 | else | |
701 | return FALSE; | |
702 | } | |
703 | ||
704 | if(pstClassifierRule->au8EthCSEtherType[0] == 2) | |
705 | { | |
706 | if(eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType) | |
707 | return FALSE; | |
708 | ||
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]) | |
711 | return TRUE; | |
712 | else | |
713 | return FALSE; | |
714 | ||
715 | } | |
716 | ||
717 | return FALSE; | |
718 | ||
719 | } | |
720 | ||
44a17eff | 721 | static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) |
f8942e07 SH |
722 | { |
723 | BOOLEAN bClassificationSucceed = FALSE; | |
724 | USHORT usVLANID; | |
725 | B_UINT8 uPriority = 0; | |
726 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
727 | ||
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); | |
729 | ||
730 | /* In case FW didn't recieve the TLV, the priority field should be ignored */ | |
731 | if(pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) | |
732 | { | |
733 | if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame) | |
734 | return FALSE; | |
735 | ||
736 | uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xF000) >> 13; | |
737 | ||
738 | if((uPriority >= pstClassifierRule->usUserPriority[0]) && (uPriority <= pstClassifierRule->usUserPriority[1])) | |
739 | bClassificationSucceed = TRUE; | |
740 | ||
741 | if(!bClassificationSucceed) | |
742 | return FALSE; | |
743 | } | |
744 | ||
745 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 D User Priority Rule Matched\n"); | |
746 | ||
747 | bClassificationSucceed = FALSE; | |
748 | ||
749 | if(pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID)) | |
750 | { | |
751 | if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame) | |
752 | return FALSE; | |
753 | ||
754 | usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xFFF; | |
755 | ||
756 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__,usVLANID, uPriority); | |
757 | ||
758 | if(usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4)) | |
759 | bClassificationSucceed = TRUE; | |
760 | ||
761 | if(!bClassificationSucceed) | |
762 | return FALSE; | |
763 | } | |
764 | ||
765 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 Q VLAN ID Rule Matched\n"); | |
766 | ||
767 | return TRUE; | |
768 | } | |
769 | ||
770 | ||
9dd47ee7 SH |
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) | |
f8942e07 SH |
775 | { |
776 | BOOLEAN bClassificationSucceed = FALSE; | |
777 | bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress); | |
778 | if(!bClassificationSucceed) | |
779 | return FALSE; | |
780 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS SrcMAC Matched\n"); | |
781 | ||
782 | bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,((ETH_HEADER_STRUC*)(skb->data))->au8DestinationAddress); | |
783 | if(!bClassificationSucceed) | |
784 | return FALSE; | |
785 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS DestMAC Matched\n"); | |
786 | ||
787 | //classify on ETHType/802.2SAP TLV | |
788 | bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,skb,pstEthCsPktInfo); | |
789 | if(!bClassificationSucceed) | |
790 | return FALSE; | |
791 | ||
792 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS EthType/802.2SAP Matched\n"); | |
793 | ||
794 | //classify on 802.1VLAN Header Parameters | |
795 | ||
796 | bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,skb,pstEthCsPktInfo); | |
797 | if(!bClassificationSucceed) | |
798 | return FALSE; | |
799 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 VLAN Rules Matched\n"); | |
800 | ||
801 | return bClassificationSucceed; | |
802 | } | |
803 | ||
9dd47ee7 SH |
804 | static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload, |
805 | PS_ETHCS_PKT_INFO pstEthCsPktInfo) | |
f8942e07 SH |
806 | { |
807 | USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype); | |
9dd47ee7 | 808 | |
f8942e07 SH |
809 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype); |
810 | if(u16Etype > 0x5dc) | |
811 | { | |
812 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : ETH2 Frame \n"); | |
813 | //ETH2 Frame | |
814 | if(u16Etype == ETHERNET_FRAMETYPE_802QVLAN) | |
815 | { | |
816 | //802.1Q VLAN Header | |
817 | pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame; | |
818 | u16Etype = ((ETH_CS_802_Q_FRAME*)pvEthPayload)->EthType; | |
819 | //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority | |
820 | } | |
821 | else | |
822 | { | |
823 | pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame; | |
824 | u16Etype = ntohs(u16Etype); | |
825 | } | |
826 | ||
827 | } | |
828 | else | |
829 | { | |
830 | //802.2 LLC | |
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) | |
835 | { | |
836 | //SNAP Frame | |
837 | pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame; | |
838 | u16Etype = ((ETH_CS_802_LLC_SNAP_FRAME*)pvEthPayload)->usEtherType; | |
839 | } | |
840 | } | |
841 | if(u16Etype == ETHERNET_FRAMETYPE_IPV4) | |
842 | pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet; | |
843 | else if(u16Etype == ETHERNET_FRAMETYPE_IPV6) | |
844 | pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet; | |
845 | else | |
846 | pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket; | |
847 | ||
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); | |
852 | } | |
853 | ||
854 | ||
855 |