Qos.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200
  1. /**
  2. * @file Qos.C
  3. * This file contains the routines related to Quality of Service.
  4. */
  5. #include "headers.h"
  6. static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
  7. PVOID pvEthPayload,
  8. struct bcm_eth_packet_info *pstEthCsPktInfo);
  9. static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
  10. struct sk_buff *skb,
  11. struct bcm_eth_packet_info *pstEthCsPktInfo,
  12. struct bcm_classifier_rule *pstClassifierRule,
  13. B_UINT8 EthCSCupport);
  14. static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd,
  15. struct bcm_classifier_rule *pstClassifierRule);
  16. static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex);
  17. /*******************************************************************
  18. * Function - MatchSrcIpAddress()
  19. *
  20. * Description - Checks whether the Source IP address from the packet
  21. * matches with that of Queue.
  22. *
  23. * Parameters - pstClassifierRule: Pointer to the packet info structure.
  24. * - ulSrcIP : Source IP address from the packet.
  25. *
  26. * Returns - TRUE(If address matches) else FAIL .
  27. *********************************************************************/
  28. static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule,
  29. ULONG ulSrcIP)
  30. {
  31. UCHAR ucLoopIndex = 0;
  32. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  33. union u_ip_address *src_addr;
  34. ulSrcIP = ntohl(ulSrcIP);
  35. if (0 == pstClassifierRule->ucIPSourceAddressLength)
  36. return TRUE;
  37. for (ucLoopIndex = 0;
  38. ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);
  39. ucLoopIndex++) {
  40. src_addr = &pstClassifierRule->stSrcIpAddress;
  41. BCM_DEBUG_PRINT(Adapter,
  42. DBG_TYPE_TX,
  43. IPV4_DBG,
  44. DBG_LVL_ALL,
  45. "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x",
  46. (UINT)src_addr->ulIpv4Mask[ucLoopIndex],
  47. (UINT)ulSrcIP,
  48. (UINT)src_addr->ulIpv6Addr[ucLoopIndex]);
  49. if ((src_addr->ulIpv4Mask[ucLoopIndex] & ulSrcIP) ==
  50. (src_addr->ulIpv4Addr[ucLoopIndex] &
  51. src_addr->ulIpv4Mask[ucLoopIndex]))
  52. return TRUE;
  53. }
  54. BCM_DEBUG_PRINT(Adapter,
  55. DBG_TYPE_TX,
  56. IPV4_DBG,
  57. DBG_LVL_ALL,
  58. "Src Ip Address Not Matched");
  59. return false;
  60. }
  61. /*******************************************************************
  62. * Function - MatchDestIpAddress()
  63. *
  64. * Description - Checks whether the Destination IP address from the packet
  65. * matches with that of Queue.
  66. *
  67. * Parameters - pstClassifierRule: Pointer to the packet info structure.
  68. * - ulDestIP : Destination IP address from the packet.
  69. *
  70. * Returns - TRUE(If address matches) else FAIL .
  71. *********************************************************************/
  72. static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP)
  73. {
  74. UCHAR ucLoopIndex = 0;
  75. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  76. union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress;
  77. ulDestIP = ntohl(ulDestIP);
  78. if (0 == pstClassifierRule->ucIPDestinationAddressLength)
  79. return TRUE;
  80. BCM_DEBUG_PRINT(Adapter,
  81. DBG_TYPE_TX,
  82. IPV4_DBG,
  83. DBG_LVL_ALL,
  84. "Destination Ip Address 0x%x 0x%x 0x%x ",
  85. (UINT)ulDestIP,
  86. (UINT)dest_addr->ulIpv4Mask[ucLoopIndex],
  87. (UINT)dest_addr->ulIpv4Addr[ucLoopIndex]);
  88. for (ucLoopIndex = 0;
  89. ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength);
  90. ucLoopIndex++) {
  91. if ((dest_addr->ulIpv4Mask[ucLoopIndex] & ulDestIP) ==
  92. (dest_addr->ulIpv4Addr[ucLoopIndex] &
  93. dest_addr->ulIpv4Mask[ucLoopIndex]))
  94. return TRUE;
  95. }
  96. BCM_DEBUG_PRINT(Adapter,
  97. DBG_TYPE_TX,
  98. IPV4_DBG,
  99. DBG_LVL_ALL,
  100. "Destination Ip Address Not Matched");
  101. return false;
  102. }
  103. /************************************************************************
  104. * Function - MatchTos()
  105. *
  106. * Description - Checks the TOS from the packet matches with that of queue.
  107. *
  108. * Parameters - pstClassifierRule : Pointer to the packet info structure.
  109. * - ucTypeOfService: TOS from the packet.
  110. *
  111. * Returns - TRUE(If address matches) else FAIL.
  112. **************************************************************************/
  113. static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule,
  114. UCHAR ucTypeOfService)
  115. {
  116. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  117. if (3 != pstClassifierRule->ucIPTypeOfServiceLength)
  118. return TRUE;
  119. if (((pstClassifierRule->ucTosMask & ucTypeOfService) <=
  120. pstClassifierRule->ucTosHigh) &&
  121. ((pstClassifierRule->ucTosMask & ucTypeOfService) >=
  122. pstClassifierRule->ucTosLow))
  123. return TRUE;
  124. BCM_DEBUG_PRINT(Adapter,
  125. DBG_TYPE_TX,
  126. IPV4_DBG,
  127. DBG_LVL_ALL,
  128. "Type Of Service Not Matched");
  129. return false;
  130. }
  131. /***************************************************************************
  132. * Function - MatchProtocol()
  133. *
  134. * Description - Checks the protocol from the packet matches with that of queue.
  135. *
  136. * Parameters - pstClassifierRule: Pointer to the packet info structure.
  137. * - ucProtocol : Protocol from the packet.
  138. *
  139. * Returns - TRUE(If address matches) else FAIL.
  140. ****************************************************************************/
  141. bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,
  142. UCHAR ucProtocol)
  143. {
  144. UCHAR ucLoopIndex = 0;
  145. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  146. if (0 == pstClassifierRule->ucProtocolLength)
  147. return TRUE;
  148. for (ucLoopIndex = 0;
  149. ucLoopIndex < pstClassifierRule->ucProtocolLength;
  150. ucLoopIndex++) {
  151. BCM_DEBUG_PRINT(Adapter,
  152. DBG_TYPE_TX,
  153. IPV4_DBG,
  154. DBG_LVL_ALL,
  155. "Protocol:0x%X Classification Protocol:0x%X",
  156. ucProtocol,
  157. pstClassifierRule->ucProtocol[ucLoopIndex]);
  158. if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol)
  159. return TRUE;
  160. }
  161. BCM_DEBUG_PRINT(Adapter,
  162. DBG_TYPE_TX,
  163. IPV4_DBG,
  164. DBG_LVL_ALL,
  165. "Protocol Not Matched");
  166. return false;
  167. }
  168. /***********************************************************************
  169. * Function - MatchSrcPort()
  170. *
  171. * Description - Checks, Source port from the packet matches with that of queue.
  172. *
  173. * Parameters - pstClassifierRule: Pointer to the packet info structure.
  174. * - ushSrcPort : Source port from the packet.
  175. *
  176. * Returns - TRUE(If address matches) else FAIL.
  177. ***************************************************************************/
  178. bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,
  179. USHORT ushSrcPort)
  180. {
  181. UCHAR ucLoopIndex = 0;
  182. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  183. if (0 == pstClassifierRule->ucSrcPortRangeLength)
  184. return TRUE;
  185. for (ucLoopIndex = 0;
  186. ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength;
  187. ucLoopIndex++) {
  188. if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] &&
  189. ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex])
  190. return TRUE;
  191. }
  192. BCM_DEBUG_PRINT(Adapter,
  193. DBG_TYPE_TX,
  194. IPV4_DBG,
  195. DBG_LVL_ALL,
  196. "Src Port: %x Not Matched ",
  197. ushSrcPort);
  198. return false;
  199. }
  200. /***********************************************************************
  201. * Function - MatchDestPort()
  202. *
  203. * Description - Checks, Destination port from packet matches with that of queue.
  204. *
  205. * Parameters - pstClassifierRule: Pointer to the packet info structure.
  206. * - ushDestPort : Destination port from the packet.
  207. *
  208. * Returns - TRUE(If address matches) else FAIL.
  209. ***************************************************************************/
  210. bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,
  211. USHORT ushDestPort)
  212. {
  213. UCHAR ucLoopIndex = 0;
  214. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  215. if (0 == pstClassifierRule->ucDestPortRangeLength)
  216. return TRUE;
  217. for (ucLoopIndex = 0;
  218. ucLoopIndex < pstClassifierRule->ucDestPortRangeLength;
  219. ucLoopIndex++) {
  220. BCM_DEBUG_PRINT(Adapter,
  221. DBG_TYPE_TX,
  222. IPV4_DBG,
  223. DBG_LVL_ALL,
  224. "Matching Port:0x%X 0x%X 0x%X",
  225. ushDestPort,
  226. pstClassifierRule->usDestPortRangeLo[ucLoopIndex],
  227. pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
  228. if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] &&
  229. ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex])
  230. return TRUE;
  231. }
  232. BCM_DEBUG_PRINT(Adapter,
  233. DBG_TYPE_TX,
  234. IPV4_DBG,
  235. DBG_LVL_ALL,
  236. "Dest Port: %x Not Matched",
  237. ushDestPort);
  238. return false;
  239. }
  240. /**
  241. * @ingroup tx_functions
  242. * Compares IPV4 Ip address and port number
  243. * @return Queue Index.
  244. */
  245. static USHORT IpVersion4(struct bcm_mini_adapter *Adapter,
  246. struct iphdr *iphd,
  247. struct bcm_classifier_rule *pstClassifierRule)
  248. {
  249. struct bcm_transport_header *xprt_hdr = NULL;
  250. bool bClassificationSucceed = false;
  251. BCM_DEBUG_PRINT(Adapter,
  252. DBG_TYPE_TX,
  253. IPV4_DBG,
  254. DBG_LVL_ALL,
  255. "========>");
  256. xprt_hdr = (struct bcm_transport_header *)((PUCHAR)iphd + sizeof(struct iphdr));
  257. BCM_DEBUG_PRINT(Adapter,
  258. DBG_TYPE_TX,
  259. IPV4_DBG,
  260. DBG_LVL_ALL,
  261. "Trying to see Direction = %d %d",
  262. pstClassifierRule->ucDirection,
  263. pstClassifierRule->usVCID_Value);
  264. /* Checking classifier validity */
  265. if (!pstClassifierRule->bUsed ||
  266. pstClassifierRule->ucDirection == DOWNLINK_DIR)
  267. goto out;
  268. BCM_DEBUG_PRINT(Adapter,
  269. DBG_TYPE_TX,
  270. IPV4_DBG,
  271. DBG_LVL_ALL,
  272. "is IPv6 check!");
  273. if (pstClassifierRule->bIpv6Protocol)
  274. goto out;
  275. /* Checking IP header parameter */
  276. BCM_DEBUG_PRINT(Adapter,
  277. DBG_TYPE_TX,
  278. IPV4_DBG,
  279. DBG_LVL_ALL,
  280. "Trying to match Source IP Address");
  281. if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr))
  282. goto out;
  283. BCM_DEBUG_PRINT(Adapter,
  284. DBG_TYPE_TX,
  285. IPV4_DBG,
  286. DBG_LVL_ALL,
  287. "Source IP Address Matched");
  288. if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr))
  289. goto out;
  290. BCM_DEBUG_PRINT(Adapter,
  291. DBG_TYPE_TX,
  292. IPV4_DBG,
  293. DBG_LVL_ALL,
  294. "Destination IP Address Matched");
  295. if (!MatchTos(pstClassifierRule, iphd->tos)) {
  296. BCM_DEBUG_PRINT(Adapter,
  297. DBG_TYPE_TX,
  298. IPV4_DBG,
  299. DBG_LVL_ALL,
  300. "TOS Match failed\n");
  301. goto out;
  302. }
  303. BCM_DEBUG_PRINT(Adapter,
  304. DBG_TYPE_TX,
  305. IPV4_DBG,
  306. DBG_LVL_ALL,
  307. "TOS Matched");
  308. if (!MatchProtocol(pstClassifierRule, iphd->protocol))
  309. goto out;
  310. BCM_DEBUG_PRINT(Adapter,
  311. DBG_TYPE_TX,
  312. IPV4_DBG,
  313. DBG_LVL_ALL,
  314. "Protocol Matched");
  315. /*
  316. * if protocol is not TCP or UDP then no
  317. * need of comparing source port and destination port
  318. */
  319. if (iphd->protocol != TCP && iphd->protocol != UDP) {
  320. bClassificationSucceed = TRUE;
  321. goto out;
  322. }
  323. /* Checking Transport Layer Header field if present */
  324. BCM_DEBUG_PRINT(Adapter,
  325. DBG_TYPE_TX,
  326. IPV4_DBG,
  327. DBG_LVL_ALL,
  328. "Source Port %04x",
  329. (iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source);
  330. if (!MatchSrcPort(pstClassifierRule,
  331. ntohs((iphd->protocol == UDP) ?
  332. xprt_hdr->uhdr.source : xprt_hdr->thdr.source)))
  333. goto out;
  334. BCM_DEBUG_PRINT(Adapter,
  335. DBG_TYPE_TX,
  336. IPV4_DBG,
  337. DBG_LVL_ALL,
  338. "Src Port Matched");
  339. BCM_DEBUG_PRINT(Adapter,
  340. DBG_TYPE_TX,
  341. IPV4_DBG,
  342. DBG_LVL_ALL,
  343. "Destination Port %04x",
  344. (iphd->protocol == UDP) ? xprt_hdr->uhdr.dest :
  345. xprt_hdr->thdr.dest);
  346. if (!MatchDestPort(pstClassifierRule,
  347. ntohs((iphd->protocol == UDP) ?
  348. xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest)))
  349. goto out;
  350. bClassificationSucceed = TRUE;
  351. out:
  352. if (TRUE == bClassificationSucceed) {
  353. INT iMatchedSFQueueIndex = 0;
  354. iMatchedSFQueueIndex =
  355. SearchSfid(Adapter, pstClassifierRule->ulSFID);
  356. if (iMatchedSFQueueIndex >= NO_OF_QUEUES)
  357. bClassificationSucceed = false;
  358. else if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
  359. bClassificationSucceed = false;
  360. }
  361. BCM_DEBUG_PRINT(Adapter,
  362. DBG_TYPE_TX,
  363. IPV4_DBG,
  364. DBG_LVL_ALL,
  365. "IpVersion4 <==========");
  366. return bClassificationSucceed;
  367. }
  368. VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter)
  369. {
  370. UINT iIndex = 0;
  371. for (iIndex = 0; iIndex < HiPriority; iIndex++) {
  372. if (!Adapter->PackInfo[iIndex].bValid)
  373. continue;
  374. PruneQueue(Adapter, iIndex);
  375. }
  376. }
  377. /**
  378. * @ingroup tx_functions
  379. * This function checks if the max queue size for a queue
  380. * is less than number of bytes in the queue. If so -
  381. * drops packets from the Head till the number of bytes is
  382. * less than or equal to max queue size for the queue.
  383. */
  384. static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex)
  385. {
  386. struct sk_buff *PacketToDrop = NULL;
  387. struct net_device_stats *netstats;
  388. struct bcm_packet_info *curr_pack_info = &Adapter->PackInfo[iIndex];
  389. BCM_DEBUG_PRINT(Adapter,
  390. DBG_TYPE_TX,
  391. PRUNE_QUEUE,
  392. DBG_LVL_ALL,
  393. "=====> Index %d",
  394. iIndex);
  395. if (iIndex == HiPriority)
  396. return;
  397. if (!Adapter || (iIndex < 0) || (iIndex > HiPriority))
  398. return;
  399. /* To Store the netdevice statistic */
  400. netstats = &Adapter->dev->stats;
  401. spin_lock_bh(&curr_pack_info->SFQueueLock);
  402. while (1) {
  403. /* while((UINT)curr_pack_info->uiCurrentPacketsOnHost >
  404. SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { */
  405. BCM_DEBUG_PRINT(Adapter,
  406. DBG_TYPE_TX,
  407. PRUNE_QUEUE,
  408. DBG_LVL_ALL,
  409. "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
  410. curr_pack_info->uiCurrentBytesOnHost,
  411. curr_pack_info->uiMaxBucketSize);
  412. PacketToDrop = curr_pack_info->FirstTxQueue;
  413. if (PacketToDrop == NULL)
  414. break;
  415. if ((curr_pack_info->uiCurrentPacketsOnHost <
  416. SF_MAX_ALLOWED_PACKETS_TO_BACKUP) &&
  417. ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb) +
  418. SKB_CB_LATENCY_OFFSET))/HZ) <=
  419. curr_pack_info->uiMaxLatency))
  420. break;
  421. if (PacketToDrop) {
  422. if (netif_msg_tx_err(Adapter))
  423. pr_info(PFX "%s: tx queue %d overlimit\n",
  424. Adapter->dev->name, iIndex);
  425. netstats->tx_dropped++;
  426. DEQUEUEPACKET(curr_pack_info->FirstTxQueue,
  427. curr_pack_info->LastTxQueue);
  428. /* update current bytes and packets count */
  429. curr_pack_info->uiCurrentBytesOnHost -=
  430. PacketToDrop->len;
  431. curr_pack_info->uiCurrentPacketsOnHost--;
  432. /* update dropped bytes and packets counts */
  433. curr_pack_info->uiDroppedCountBytes += PacketToDrop->len;
  434. curr_pack_info->uiDroppedCountPackets++;
  435. dev_kfree_skb(PacketToDrop);
  436. }
  437. BCM_DEBUG_PRINT(Adapter,
  438. DBG_TYPE_TX,
  439. PRUNE_QUEUE,
  440. DBG_LVL_ALL,
  441. "Dropped Bytes:%x Dropped Packets:%x",
  442. curr_pack_info->uiDroppedCountBytes,
  443. curr_pack_info->uiDroppedCountPackets);
  444. atomic_dec(&Adapter->TotalPacketCount);
  445. }
  446. spin_unlock_bh(&curr_pack_info->SFQueueLock);
  447. BCM_DEBUG_PRINT(Adapter,
  448. DBG_TYPE_TX,
  449. PRUNE_QUEUE,
  450. DBG_LVL_ALL,
  451. "TotalPacketCount:%x",
  452. atomic_read(&Adapter->TotalPacketCount));
  453. BCM_DEBUG_PRINT(Adapter,
  454. DBG_TYPE_TX,
  455. PRUNE_QUEUE,
  456. DBG_LVL_ALL,
  457. "<=====");
  458. }
  459. VOID flush_all_queues(struct bcm_mini_adapter *Adapter)
  460. {
  461. INT iQIndex;
  462. UINT uiTotalPacketLength;
  463. struct sk_buff *PacketToDrop = NULL;
  464. struct bcm_packet_info *curr_packet_info;
  465. BCM_DEBUG_PRINT(Adapter,
  466. DBG_TYPE_OTHERS,
  467. DUMP_INFO,
  468. DBG_LVL_ALL,
  469. "=====>");
  470. /* down(&Adapter->data_packet_queue_lock); */
  471. for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) {
  472. struct net_device_stats *netstats = &Adapter->dev->stats;
  473. curr_packet_info = &Adapter->PackInfo[iQIndex];
  474. spin_lock_bh(&curr_packet_info->SFQueueLock);
  475. while (curr_packet_info->FirstTxQueue) {
  476. PacketToDrop = curr_packet_info->FirstTxQueue;
  477. if (PacketToDrop) {
  478. uiTotalPacketLength = PacketToDrop->len;
  479. netstats->tx_dropped++;
  480. } else
  481. uiTotalPacketLength = 0;
  482. DEQUEUEPACKET(curr_packet_info->FirstTxQueue,
  483. curr_packet_info->LastTxQueue);
  484. /* Free the skb */
  485. dev_kfree_skb(PacketToDrop);
  486. /* update current bytes and packets count */
  487. curr_packet_info->uiCurrentBytesOnHost -= uiTotalPacketLength;
  488. curr_packet_info->uiCurrentPacketsOnHost--;
  489. /* update dropped bytes and packets counts */
  490. curr_packet_info->uiDroppedCountBytes += uiTotalPacketLength;
  491. curr_packet_info->uiDroppedCountPackets++;
  492. BCM_DEBUG_PRINT(Adapter,
  493. DBG_TYPE_OTHERS,
  494. DUMP_INFO,
  495. DBG_LVL_ALL,
  496. "Dropped Bytes:%x Dropped Packets:%x",
  497. curr_packet_info->uiDroppedCountBytes,
  498. curr_packet_info->uiDroppedCountPackets);
  499. atomic_dec(&Adapter->TotalPacketCount);
  500. }
  501. spin_unlock_bh(&curr_packet_info->SFQueueLock);
  502. }
  503. /* up(&Adapter->data_packet_queue_lock); */
  504. BCM_DEBUG_PRINT(Adapter,
  505. DBG_TYPE_OTHERS,
  506. DUMP_INFO,
  507. DBG_LVL_ALL,
  508. "<=====");
  509. }
  510. USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
  511. {
  512. INT uiLoopIndex = 0;
  513. struct bcm_classifier_rule *pstClassifierRule = NULL;
  514. struct bcm_eth_packet_info stEthCsPktInfo;
  515. PVOID pvEThPayload = NULL;
  516. struct iphdr *pIpHeader = NULL;
  517. INT uiSfIndex = 0;
  518. USHORT usIndex = Adapter->usBestEffortQueueIndex;
  519. bool bFragmentedPkt = false, bClassificationSucceed = false;
  520. USHORT usCurrFragment = 0;
  521. struct bcm_tcp_header *pTcpHeader;
  522. UCHAR IpHeaderLength;
  523. UCHAR TcpHeaderLength;
  524. pvEThPayload = skb->data;
  525. *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = 0;
  526. EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo);
  527. switch (stEthCsPktInfo.eNwpktEthFrameType) {
  528. case eEth802LLCFrame:
  529. BCM_DEBUG_PRINT(Adapter,
  530. DBG_TYPE_TX,
  531. IPV4_DBG,
  532. DBG_LVL_ALL,
  533. "ClassifyPacket : 802LLCFrame\n");
  534. pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame);
  535. break;
  536. case eEth802LLCSNAPFrame:
  537. BCM_DEBUG_PRINT(Adapter,
  538. DBG_TYPE_TX,
  539. IPV4_DBG,
  540. DBG_LVL_ALL,
  541. "ClassifyPacket : 802LLC SNAP Frame\n");
  542. pIpHeader = pvEThPayload +
  543. sizeof(struct bcm_eth_llc_snap_frame);
  544. break;
  545. case eEth802QVLANFrame:
  546. BCM_DEBUG_PRINT(Adapter,
  547. DBG_TYPE_TX,
  548. IPV4_DBG,
  549. DBG_LVL_ALL,
  550. "ClassifyPacket : 802.1Q VLANFrame\n");
  551. pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame);
  552. break;
  553. case eEthOtherFrame:
  554. BCM_DEBUG_PRINT(Adapter,
  555. DBG_TYPE_TX,
  556. IPV4_DBG,
  557. DBG_LVL_ALL,
  558. "ClassifyPacket : ETH Other Frame\n");
  559. pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
  560. break;
  561. default:
  562. BCM_DEBUG_PRINT(Adapter,
  563. DBG_TYPE_TX,
  564. IPV4_DBG,
  565. DBG_LVL_ALL,
  566. "ClassifyPacket : Unrecognized ETH Frame\n");
  567. pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
  568. break;
  569. }
  570. if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) {
  571. usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET);
  572. if ((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment)
  573. bFragmentedPkt = TRUE;
  574. if (bFragmentedPkt) {
  575. /* Fragmented Packet. Get Frag Classifier Entry. */
  576. pstClassifierRule = GetFragIPClsEntry(Adapter,
  577. pIpHeader->id,
  578. pIpHeader->saddr);
  579. if (pstClassifierRule) {
  580. BCM_DEBUG_PRINT(Adapter,
  581. DBG_TYPE_TX,
  582. IPV4_DBG,
  583. DBG_LVL_ALL,
  584. "It is next Fragmented pkt");
  585. bClassificationSucceed = TRUE;
  586. }
  587. if (!(ntohs(pIpHeader->frag_off) & IP_MF)) {
  588. /* Fragmented Last packet . Remove Frag Classifier Entry */
  589. BCM_DEBUG_PRINT(Adapter,
  590. DBG_TYPE_TX,
  591. IPV4_DBG,
  592. DBG_LVL_ALL,
  593. "This is the last fragmented Pkt");
  594. DelFragIPClsEntry(Adapter,
  595. pIpHeader->id,
  596. pIpHeader->saddr);
  597. }
  598. }
  599. }
  600. for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) {
  601. if (bClassificationSucceed)
  602. break;
  603. /*
  604. * Iterate through all classifiers which are already in order of priority
  605. * to classify the packet until match found
  606. */
  607. if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) {
  608. bClassificationSucceed = false;
  609. continue;
  610. }
  611. BCM_DEBUG_PRINT(Adapter,
  612. DBG_TYPE_TX,
  613. IPV4_DBG,
  614. DBG_LVL_ALL,
  615. "Adapter->PackInfo[%d].bvalid=True\n",
  616. uiLoopIndex);
  617. if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) {
  618. bClassificationSucceed = false; /* cannot be processed for classification. */
  619. continue; /* it is a down link connection */
  620. }
  621. pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex];
  622. uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
  623. if (uiSfIndex >= NO_OF_QUEUES) {
  624. BCM_DEBUG_PRINT(Adapter,
  625. DBG_TYPE_TX,
  626. IPV4_DBG,
  627. DBG_LVL_ALL,
  628. "Queue Not Valid. SearchSfid for this classifier Failed\n");
  629. continue;
  630. }
  631. if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) {
  632. if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) {
  633. BCM_DEBUG_PRINT(Adapter,
  634. DBG_TYPE_TX,
  635. IPV4_DBG,
  636. DBG_LVL_ALL,
  637. " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
  638. bClassificationSucceed = false;
  639. continue;
  640. }
  641. BCM_DEBUG_PRINT(Adapter,
  642. DBG_TYPE_TX,
  643. IPV4_DBG,
  644. DBG_LVL_ALL,
  645. "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",
  646. pstClassifierRule->uiClassifierRuleIndex,
  647. Adapter->PackInfo[uiSfIndex].ulSFID);
  648. bClassificationSucceed = EThCSClassifyPkt(Adapter,
  649. skb,
  650. &stEthCsPktInfo,
  651. pstClassifierRule,
  652. Adapter->PackInfo[uiSfIndex].bEthCSSupport);
  653. if (!bClassificationSucceed) {
  654. BCM_DEBUG_PRINT(Adapter,
  655. DBG_TYPE_TX,
  656. IPV4_DBG,
  657. DBG_LVL_ALL,
  658. "ClassifyPacket : Ethernet CS Classification Failed\n");
  659. continue;
  660. }
  661. } else { /* No ETH Supported on this SF */
  662. if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) {
  663. BCM_DEBUG_PRINT(Adapter,
  664. DBG_TYPE_TX,
  665. IPV4_DBG,
  666. DBG_LVL_ALL,
  667. " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
  668. bClassificationSucceed = false;
  669. continue;
  670. }
  671. }
  672. BCM_DEBUG_PRINT(Adapter,
  673. DBG_TYPE_TX,
  674. IPV4_DBG,
  675. DBG_LVL_ALL,
  676. "Proceeding to IP CS Clasification");
  677. if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) {
  678. if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) {
  679. BCM_DEBUG_PRINT(Adapter,
  680. DBG_TYPE_TX,
  681. IPV4_DBG,
  682. DBG_LVL_ALL,
  683. " ClassifyPacket : Packet is Not an IP Packet\n");
  684. bClassificationSucceed = false;
  685. continue;
  686. }
  687. BCM_DEBUG_PRINT(Adapter,
  688. DBG_TYPE_TX,
  689. IPV4_DBG,
  690. DBG_LVL_ALL,
  691. "Dump IP Header :\n");
  692. DumpFullPacket((PUCHAR)pIpHeader, 20);
  693. if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
  694. bClassificationSucceed = IpVersion4(Adapter,
  695. pIpHeader,
  696. pstClassifierRule);
  697. else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet)
  698. bClassificationSucceed = IpVersion6(Adapter,
  699. pIpHeader,
  700. pstClassifierRule);
  701. }
  702. }
  703. if (bClassificationSucceed == TRUE) {
  704. BCM_DEBUG_PRINT(Adapter,
  705. DBG_TYPE_TX,
  706. IPV4_DBG,
  707. DBG_LVL_ALL,
  708. "CF id : %d, SF ID is =%lu",
  709. pstClassifierRule->uiClassifierRuleIndex,
  710. pstClassifierRule->ulSFID);
  711. /* Store The matched Classifier in SKB */
  712. *((UINT32 *)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) =
  713. pstClassifierRule->uiClassifierRuleIndex;
  714. if ((TCP == pIpHeader->protocol) && !bFragmentedPkt &&
  715. (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <=
  716. skb->len)) {
  717. IpHeaderLength = pIpHeader->ihl;
  718. pTcpHeader =
  719. (struct bcm_tcp_header *)(((PUCHAR)pIpHeader) +
  720. (IpHeaderLength*4));
  721. TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
  722. if ((pTcpHeader->ucFlags & TCP_ACK) &&
  723. (ntohs(pIpHeader->tot_len) ==
  724. (IpHeaderLength*4)+(TcpHeaderLength*4)))
  725. *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) =
  726. TCP_ACK;
  727. }
  728. usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
  729. BCM_DEBUG_PRINT(Adapter,
  730. DBG_TYPE_TX,
  731. IPV4_DBG,
  732. DBG_LVL_ALL,
  733. "index is =%d",
  734. usIndex);
  735. /*
  736. * If this is the first fragment of a Fragmented pkt,
  737. * add this CF. Only This CF should be used for all other
  738. * fragment of this Pkt.
  739. */
  740. if (bFragmentedPkt && (usCurrFragment == 0)) {
  741. /*
  742. * First Fragment of Fragmented Packet.
  743. * Create Frag CLS Entry
  744. */
  745. struct bcm_fragmented_packet_info stFragPktInfo;
  746. stFragPktInfo.bUsed = TRUE;
  747. stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr;
  748. stFragPktInfo.usIpIdentification = pIpHeader->id;
  749. stFragPktInfo.pstMatchedClassifierEntry =
  750. pstClassifierRule;
  751. stFragPktInfo.bOutOfOrderFragment = false;
  752. AddFragIPClsEntry(Adapter, &stFragPktInfo);
  753. }
  754. }
  755. return bClassificationSucceed ? usIndex : INVALID_QUEUE_INDEX;
  756. }
  757. static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule,
  758. PUCHAR Mac)
  759. {
  760. UINT i = 0;
  761. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  762. if (pstClassifierRule->ucEthCSSrcMACLen == 0)
  763. return TRUE;
  764. BCM_DEBUG_PRINT(Adapter,
  765. DBG_TYPE_TX,
  766. IPV4_DBG,
  767. DBG_LVL_ALL,
  768. "%s\n", __func__);
  769. for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
  770. BCM_DEBUG_PRINT(Adapter,
  771. DBG_TYPE_TX,
  772. IPV4_DBG,
  773. DBG_LVL_ALL,
  774. "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
  775. i,
  776. Mac[i],
  777. pstClassifierRule->au8EThCSSrcMAC[i],
  778. pstClassifierRule->au8EThCSSrcMACMask[i]);
  779. if ((pstClassifierRule->au8EThCSSrcMAC[i] &
  780. pstClassifierRule->au8EThCSSrcMACMask[i]) !=
  781. (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
  782. return false;
  783. }
  784. return TRUE;
  785. }
  786. static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule,
  787. PUCHAR Mac)
  788. {
  789. UINT i = 0;
  790. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  791. if (pstClassifierRule->ucEthCSDestMACLen == 0)
  792. return TRUE;
  793. BCM_DEBUG_PRINT(Adapter,
  794. DBG_TYPE_TX,
  795. IPV4_DBG,
  796. DBG_LVL_ALL,
  797. "%s\n",
  798. __func__);
  799. for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
  800. BCM_DEBUG_PRINT(Adapter,
  801. DBG_TYPE_TX,
  802. IPV4_DBG,
  803. DBG_LVL_ALL,
  804. "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
  805. i,
  806. Mac[i],
  807. pstClassifierRule->au8EThCSDestMAC[i],
  808. pstClassifierRule->au8EThCSDestMACMask[i]);
  809. if ((pstClassifierRule->au8EThCSDestMAC[i] &
  810. pstClassifierRule->au8EThCSDestMACMask[i]) !=
  811. (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
  812. return false;
  813. }
  814. return TRUE;
  815. }
  816. static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,
  817. struct sk_buff *skb,
  818. struct bcm_eth_packet_info *pstEthCsPktInfo)
  819. {
  820. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  821. if ((pstClassifierRule->ucEtherTypeLen == 0) ||
  822. (pstClassifierRule->au8EthCSEtherType[0] == 0))
  823. return TRUE;
  824. BCM_DEBUG_PRINT(Adapter,
  825. DBG_TYPE_TX,
  826. IPV4_DBG,
  827. DBG_LVL_ALL,
  828. "%s SrcEtherType:%x CLS EtherType[0]:%x\n",
  829. __func__,
  830. pstEthCsPktInfo->usEtherType,
  831. pstClassifierRule->au8EthCSEtherType[0]);
  832. if (pstClassifierRule->au8EthCSEtherType[0] == 1) {
  833. BCM_DEBUG_PRINT(Adapter,
  834. DBG_TYPE_TX,
  835. IPV4_DBG,
  836. DBG_LVL_ALL,
  837. "%s CLS EtherType[1]:%x EtherType[2]:%x\n",
  838. __func__,
  839. pstClassifierRule->au8EthCSEtherType[1],
  840. pstClassifierRule->au8EthCSEtherType[2]);
  841. if (memcmp(&pstEthCsPktInfo->usEtherType,
  842. &pstClassifierRule->au8EthCSEtherType[1],
  843. 2) == 0)
  844. return TRUE;
  845. else
  846. return false;
  847. }
  848. if (pstClassifierRule->au8EthCSEtherType[0] == 2) {
  849. if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
  850. return false;
  851. BCM_DEBUG_PRINT(Adapter,
  852. DBG_TYPE_TX,
  853. IPV4_DBG,
  854. DBG_LVL_ALL,
  855. "%s EthCS DSAP:%x EtherType[2]:%x\n",
  856. __func__,
  857. pstEthCsPktInfo->ucDSAP,
  858. pstClassifierRule->au8EthCSEtherType[2]);
  859. if (pstEthCsPktInfo->ucDSAP ==
  860. pstClassifierRule->au8EthCSEtherType[2])
  861. return TRUE;
  862. else
  863. return false;
  864. }
  865. return false;
  866. }
  867. static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule,
  868. struct sk_buff *skb,
  869. struct bcm_eth_packet_info *pstEthCsPktInfo)
  870. {
  871. bool bClassificationSucceed = false;
  872. USHORT usVLANID;
  873. B_UINT8 uPriority = 0;
  874. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  875. BCM_DEBUG_PRINT(Adapter,
  876. DBG_TYPE_TX,
  877. IPV4_DBG,
  878. DBG_LVL_ALL,
  879. "%s CLS UserPrio:%x CLS VLANID:%x\n",
  880. __func__,
  881. ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),
  882. pstClassifierRule->usVLANID);
  883. /*
  884. * In case FW didn't receive the TLV,
  885. * the priority field should be ignored
  886. */
  887. if (pstClassifierRule->usValidityBitMap &
  888. (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) {
  889. if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
  890. return false;
  891. uPriority = (ntohs(*(USHORT *)(skb->data +
  892. sizeof(struct bcm_eth_header))) &
  893. 0xF000) >> 13;
  894. if ((uPriority >= pstClassifierRule->usUserPriority[0]) &&
  895. (uPriority <=
  896. pstClassifierRule->usUserPriority[1]))
  897. bClassificationSucceed = TRUE;
  898. if (!bClassificationSucceed)
  899. return false;
  900. }
  901. BCM_DEBUG_PRINT(Adapter,
  902. DBG_TYPE_TX,
  903. IPV4_DBG,
  904. DBG_LVL_ALL,
  905. "ETH CS 802.1 D User Priority Rule Matched\n");
  906. bClassificationSucceed = false;
  907. if (pstClassifierRule->usValidityBitMap &
  908. (1<<PKT_CLASSIFICATION_VLANID_VALID)) {
  909. if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
  910. return false;
  911. usVLANID = ntohs(*(USHORT *)(skb->data +
  912. sizeof(struct bcm_eth_header))) & 0xFFF;
  913. BCM_DEBUG_PRINT(Adapter,
  914. DBG_TYPE_TX,
  915. IPV4_DBG,
  916. DBG_LVL_ALL,
  917. "%s Pkt VLANID %x Priority: %d\n",
  918. __func__,
  919. usVLANID,
  920. uPriority);
  921. if (usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4))
  922. bClassificationSucceed = TRUE;
  923. if (!bClassificationSucceed)
  924. return false;
  925. }
  926. BCM_DEBUG_PRINT(Adapter,
  927. DBG_TYPE_TX,
  928. IPV4_DBG,
  929. DBG_LVL_ALL,
  930. "ETH CS 802.1 Q VLAN ID Rule Matched\n");
  931. return TRUE;
  932. }
  933. static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
  934. struct sk_buff *skb,
  935. struct bcm_eth_packet_info *pstEthCsPktInfo,
  936. struct bcm_classifier_rule *pstClassifierRule,
  937. B_UINT8 EthCSCupport)
  938. {
  939. bool bClassificationSucceed = false;
  940. bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,
  941. ((struct bcm_eth_header *)(skb->data))->au8SourceAddress);
  942. if (!bClassificationSucceed)
  943. return false;
  944. BCM_DEBUG_PRINT(Adapter,
  945. DBG_TYPE_TX,
  946. IPV4_DBG,
  947. DBG_LVL_ALL,
  948. "ETH CS SrcMAC Matched\n");
  949. bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,
  950. ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress);
  951. if (!bClassificationSucceed)
  952. return false;
  953. BCM_DEBUG_PRINT(Adapter,
  954. DBG_TYPE_TX,
  955. IPV4_DBG,
  956. DBG_LVL_ALL,
  957. "ETH CS DestMAC Matched\n");
  958. /* classify on ETHType/802.2SAP TLV */
  959. bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,
  960. skb,
  961. pstEthCsPktInfo);
  962. if (!bClassificationSucceed)
  963. return false;
  964. BCM_DEBUG_PRINT(Adapter,
  965. DBG_TYPE_TX,
  966. IPV4_DBG,
  967. DBG_LVL_ALL,
  968. "ETH CS EthType/802.2SAP Matched\n");
  969. /* classify on 802.1VLAN Header Parameters */
  970. bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,
  971. skb,
  972. pstEthCsPktInfo);
  973. if (!bClassificationSucceed)
  974. return false;
  975. BCM_DEBUG_PRINT(Adapter,
  976. DBG_TYPE_TX,
  977. IPV4_DBG,
  978. DBG_LVL_ALL,
  979. "ETH CS 802.1 VLAN Rules Matched\n");
  980. return bClassificationSucceed;
  981. }
  982. static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
  983. PVOID pvEthPayload,
  984. struct bcm_eth_packet_info *pstEthCsPktInfo)
  985. {
  986. USHORT u16Etype = ntohs(
  987. ((struct bcm_eth_header *)pvEthPayload)->u16Etype);
  988. BCM_DEBUG_PRINT(Adapter,
  989. DBG_TYPE_TX,
  990. IPV4_DBG,
  991. DBG_LVL_ALL,
  992. "EthCSGetPktInfo : Eth Hdr Type : %X\n",
  993. u16Etype);
  994. if (u16Etype > 0x5dc) {
  995. BCM_DEBUG_PRINT(Adapter,
  996. DBG_TYPE_TX,
  997. IPV4_DBG,
  998. DBG_LVL_ALL,
  999. "EthCSGetPktInfo : ETH2 Frame\n");
  1000. /* ETH2 Frame */
  1001. if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN) {
  1002. /* 802.1Q VLAN Header */
  1003. pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame;
  1004. u16Etype = ((struct bcm_eth_q_frame *)pvEthPayload)->EthType;
  1005. /* ((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority */
  1006. } else {
  1007. pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame;
  1008. u16Etype = ntohs(u16Etype);
  1009. }
  1010. } else {
  1011. /* 802.2 LLC */
  1012. BCM_DEBUG_PRINT(Adapter,
  1013. DBG_TYPE_TX,
  1014. IPV4_DBG,
  1015. DBG_LVL_ALL,
  1016. "802.2 LLC Frame\n");
  1017. pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame;
  1018. pstEthCsPktInfo->ucDSAP =
  1019. ((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP;
  1020. if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA) {
  1021. /* SNAP Frame */
  1022. pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame;
  1023. u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType;
  1024. }
  1025. }
  1026. if (u16Etype == ETHERNET_FRAMETYPE_IPV4)
  1027. pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet;
  1028. else if (u16Etype == ETHERNET_FRAMETYPE_IPV6)
  1029. pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet;
  1030. else
  1031. pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket;
  1032. pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype;
  1033. BCM_DEBUG_PRINT(Adapter,
  1034. DBG_TYPE_TX,
  1035. IPV4_DBG,
  1036. DBG_LVL_ALL,
  1037. "EthCsPktInfo->eNwpktIPFrameType : %x\n",
  1038. pstEthCsPktInfo->eNwpktIPFrameType);
  1039. BCM_DEBUG_PRINT(Adapter,
  1040. DBG_TYPE_TX,
  1041. IPV4_DBG,
  1042. DBG_LVL_ALL,
  1043. "EthCsPktInfo->eNwpktEthFrameType : %x\n",
  1044. pstEthCsPktInfo->eNwpktEthFrameType);
  1045. BCM_DEBUG_PRINT(Adapter,
  1046. DBG_TYPE_TX,
  1047. IPV4_DBG,
  1048. DBG_LVL_ALL,
  1049. "EthCsPktInfo->usEtherType : %x\n",
  1050. pstEthCsPktInfo->usEtherType);
  1051. }