IxEthAccCommon.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. /**
  2. * @file IxEthAccCommon.c
  3. *
  4. * @author Intel Corporation
  5. * @date 12-Feb-2002
  6. *
  7. * @brief This file contains the implementation common support routines for the component
  8. *
  9. * Design Notes:
  10. *
  11. * @par
  12. * IXP400 SW Release version 2.0
  13. *
  14. * -- Copyright Notice --
  15. *
  16. * @par
  17. * Copyright 2001-2005, Intel Corporation.
  18. * All rights reserved.
  19. *
  20. * @par
  21. * SPDX-License-Identifier: BSD-3-Clause
  22. * @par
  23. * -- End of Copyright Notice --
  24. */
  25. /*
  26. * Component header files
  27. */
  28. #include "IxOsal.h"
  29. #include "IxEthAcc.h"
  30. #include "IxEthDB.h"
  31. #include "IxNpeMh.h"
  32. #include "IxEthDBPortDefs.h"
  33. #include "IxFeatureCtrl.h"
  34. #include "IxEthAcc_p.h"
  35. #include "IxEthAccQueueAssign_p.h"
  36. #include "IxEthAccDataPlane_p.h"
  37. #include "IxEthAccMii_p.h"
  38. /**
  39. * @addtogroup IxEthAccPri
  40. *@{
  41. */
  42. extern IxEthAccInfo ixEthAccDataInfo;
  43. /**
  44. *
  45. * @brief Maximum number of RX queues set to be the maximum number
  46. * of traffic calsses.
  47. *
  48. */
  49. #define IX_ETHACC_MAX_RX_QUEUES \
  50. (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \
  51. - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \
  52. + 1)
  53. /**
  54. *
  55. * @brief Maximum number of 128 entry RX queues
  56. *
  57. */
  58. #define IX_ETHACC_MAX_LARGE_RX_QUEUES 4
  59. /**
  60. *
  61. * @brief Data structure template for Default RX Queues
  62. *
  63. */
  64. IX_ETH_ACC_PRIVATE
  65. IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate =
  66. {
  67. IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */
  68. "Eth Rx Q",
  69. ixEthRxFrameQMCallback, /**< Functional callback */
  70. (IxQMgrCallbackId) 0, /**< Callback tag */
  71. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  72. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  73. true, /**< Enable Q notification at startup */
  74. IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */
  75. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  76. IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */
  77. };
  78. /**
  79. *
  80. * @brief Data structure template for Small RX Queues
  81. *
  82. */
  83. IX_ETH_ACC_PRIVATE
  84. IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate =
  85. {
  86. IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */
  87. "Eth Rx Q",
  88. ixEthRxFrameQMCallback, /**< Functional callback */
  89. (IxQMgrCallbackId) 0, /**< Callback tag */
  90. IX_QMGR_Q_SIZE64, /**< Allocate Smaller Q */
  91. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  92. true, /**< Enable Q notification at startup */
  93. IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */
  94. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  95. IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */
  96. };
  97. /**
  98. *
  99. * @brief Data structure used to register & initialize the Queues
  100. *
  101. */
  102. IX_ETH_ACC_PRIVATE
  103. IxEthAccQregInfo ixEthAccQmgrStaticInfo[]=
  104. {
  105. {
  106. IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q,
  107. "Eth Rx Fr Q 1",
  108. ixEthRxFreeQMCallback,
  109. (IxQMgrCallbackId) IX_ETH_PORT_1,
  110. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  111. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  112. false, /**< Disable Q notification at startup */
  113. IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback */
  114. IX_QMGR_Q_WM_LEVEL0, /***< Q Low water mark */
  115. IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
  116. },
  117. {
  118. IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q,
  119. "Eth Rx Fr Q 2",
  120. ixEthRxFreeQMCallback,
  121. (IxQMgrCallbackId) IX_ETH_PORT_2,
  122. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  123. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  124. false, /**< Disable Q notification at startup */
  125. IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE, /**< Q Condition to drive callback */
  126. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  127. IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
  128. },
  129. #ifdef __ixp46X
  130. {
  131. IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q,
  132. "Eth Rx Fr Q 3",
  133. ixEthRxFreeQMCallback,
  134. (IxQMgrCallbackId) IX_ETH_PORT_3,
  135. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  136. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  137. false, /**< Disable Q notification at startup */
  138. IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE, /**< Q Condition to drive callback */
  139. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  140. IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
  141. },
  142. #endif
  143. {
  144. IX_ETH_ACC_TX_FRAME_ENET0_Q,
  145. "Eth Tx Q 1",
  146. ixEthTxFrameQMCallback,
  147. (IxQMgrCallbackId) IX_ETH_PORT_1,
  148. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  149. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  150. false, /**< Disable Q notification at startup */
  151. IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE, /**< Q Condition to drive callback */
  152. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  153. IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
  154. },
  155. {
  156. IX_ETH_ACC_TX_FRAME_ENET1_Q,
  157. "Eth Tx Q 2",
  158. ixEthTxFrameQMCallback,
  159. (IxQMgrCallbackId) IX_ETH_PORT_2,
  160. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  161. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  162. false, /**< Disable Q notification at startup */
  163. IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE, /**< Q Condition to drive callback */
  164. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  165. IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
  166. },
  167. #ifdef __ixp46X
  168. {
  169. IX_ETH_ACC_TX_FRAME_ENET2_Q,
  170. "Eth Tx Q 3",
  171. ixEthTxFrameQMCallback,
  172. (IxQMgrCallbackId) IX_ETH_PORT_3,
  173. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  174. IX_QMGR_Q_ENTRY_SIZE1, /** Queue Entry Sizes - all Q entries are single ord entries */
  175. false, /** Disable Q notification at startup */
  176. IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE, /** Q Condition to drive callback */
  177. IX_QMGR_Q_WM_LEVEL0, /* No queues use almost empty */
  178. IX_QMGR_Q_WM_LEVEL64, /** Q High water mark - needed used */
  179. },
  180. #endif
  181. {
  182. IX_ETH_ACC_TX_FRAME_DONE_ETH_Q,
  183. "Eth Tx Done Q",
  184. ixEthTxFrameDoneQMCallback,
  185. (IxQMgrCallbackId) 0,
  186. IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
  187. IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
  188. true, /**< Enable Q notification at startup */
  189. IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback */
  190. IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
  191. IX_QMGR_Q_WM_LEVEL2, /**< Q High water mark - needed by NPE */
  192. },
  193. { /* Null Termination entry
  194. */
  195. (IxQMgrQId)0,
  196. (char *) NULL,
  197. (IxQMgrCallback) NULL,
  198. (IxQMgrCallbackId) 0,
  199. 0,
  200. 0,
  201. 0,
  202. 0,
  203. 0,
  204. 0
  205. }
  206. };
  207. /**
  208. *
  209. * @brief Data structure used to register & initialize the Queues
  210. *
  211. * The structure will be filled at run time depending on the NPE
  212. * image already loaded and the QoS configured in ethDB.
  213. *
  214. */
  215. IX_ETH_ACC_PRIVATE
  216. IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]=
  217. {
  218. { /* PlaceHolder for rx queues
  219. * depending on the QoS configured
  220. */
  221. (IxQMgrQId)0,
  222. (char *) NULL,
  223. (IxQMgrCallback) NULL,
  224. (IxQMgrCallbackId) 0,
  225. 0,
  226. 0,
  227. 0,
  228. 0,
  229. 0,
  230. 0
  231. },
  232. { /* PlaceHolder for rx queues
  233. * depending on the QoS configured
  234. */
  235. (IxQMgrQId)0,
  236. (char *) NULL,
  237. (IxQMgrCallback) NULL,
  238. (IxQMgrCallbackId) 0,
  239. 0,
  240. 0,
  241. 0,
  242. 0,
  243. 0,
  244. 0
  245. },
  246. { /* PlaceHolder for rx queues
  247. * depending on the QoS configured
  248. */
  249. (IxQMgrQId)0,
  250. (char *) NULL,
  251. (IxQMgrCallback) NULL,
  252. (IxQMgrCallbackId) 0,
  253. 0,
  254. 0,
  255. 0,
  256. 0,
  257. 0,
  258. 0
  259. },
  260. { /* PlaceHolder for rx queues
  261. * depending on the QoS configured
  262. */
  263. (IxQMgrQId)0,
  264. (char *) NULL,
  265. (IxQMgrCallback) NULL,
  266. (IxQMgrCallbackId) 0,
  267. 0,
  268. 0,
  269. 0,
  270. 0,
  271. 0,
  272. 0
  273. },
  274. { /* PlaceHolder for rx queues
  275. * depending on the QoS configured
  276. */
  277. (IxQMgrQId)0,
  278. (char *) NULL,
  279. (IxQMgrCallback) NULL,
  280. (IxQMgrCallbackId) 0,
  281. 0,
  282. 0,
  283. 0,
  284. 0,
  285. 0,
  286. 0
  287. },
  288. { /* PlaceHolder for rx queues
  289. * depending on the QoS configured
  290. */
  291. (IxQMgrQId)0,
  292. (char *) NULL,
  293. (IxQMgrCallback) NULL,
  294. (IxQMgrCallbackId) 0,
  295. 0,
  296. 0,
  297. 0,
  298. 0,
  299. 0,
  300. 0
  301. },
  302. { /* PlaceHolder for rx queues
  303. * depending on the QoS configured
  304. */
  305. (IxQMgrQId)0,
  306. (char *) NULL,
  307. (IxQMgrCallback) NULL,
  308. (IxQMgrCallbackId) 0,
  309. 0,
  310. 0,
  311. 0,
  312. 0,
  313. 0,
  314. 0
  315. },
  316. { /* PlaceHolder for rx queues
  317. * depending on the QoS configured
  318. */
  319. (IxQMgrQId)0,
  320. (char *) NULL,
  321. (IxQMgrCallback) NULL,
  322. (IxQMgrCallbackId) 0,
  323. 0,
  324. 0,
  325. 0,
  326. 0,
  327. 0,
  328. 0
  329. },
  330. { /* Null Termination entry
  331. */
  332. (IxQMgrQId)0,
  333. (char *) NULL,
  334. (IxQMgrCallback) NULL,
  335. (IxQMgrCallbackId) 0,
  336. 0,
  337. 0,
  338. 0,
  339. 0,
  340. 0,
  341. 0
  342. }
  343. };
  344. /* forward declarations */
  345. IX_ETH_ACC_PRIVATE IxEthAccStatus
  346. ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes);
  347. /**
  348. * @fn ixEthAccQMgrQueueSetup(void)
  349. *
  350. * @brief Setup one queue and its event, and register the callback required
  351. * by this component to the QMgr
  352. *
  353. * @internal
  354. */
  355. IX_ETH_ACC_PRIVATE IxEthAccStatus
  356. ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes)
  357. {
  358. /*
  359. * Configure each Q.
  360. */
  361. if ( ixQMgrQConfig( qInfoDes->qName,
  362. qInfoDes->qId,
  363. qInfoDes->qSize,
  364. qInfoDes->qWords) != IX_SUCCESS)
  365. {
  366. return IX_ETH_ACC_FAIL;
  367. }
  368. if ( ixQMgrWatermarkSet( qInfoDes->qId,
  369. qInfoDes->AlmostEmptyThreshold,
  370. qInfoDes->AlmostFullThreshold
  371. ) != IX_SUCCESS)
  372. {
  373. return IX_ETH_ACC_FAIL;
  374. }
  375. /*
  376. * Set dispatcher priority.
  377. */
  378. if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId,
  379. IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY)
  380. != IX_SUCCESS)
  381. {
  382. return IX_ETH_ACC_FAIL;
  383. }
  384. /*
  385. * Register callbacks for each Q.
  386. */
  387. if ( ixQMgrNotificationCallbackSet(qInfoDes->qId,
  388. qInfoDes->qCallback,
  389. qInfoDes->callbackTag)
  390. != IX_SUCCESS )
  391. {
  392. return IX_ETH_ACC_FAIL;
  393. }
  394. /*
  395. * Set notification condition for Q
  396. */
  397. if (qInfoDes->qNotificationEnableAtStartup == true)
  398. {
  399. if ( ixQMgrNotificationEnable(qInfoDes->qId,
  400. qInfoDes->qConditionSource)
  401. != IX_SUCCESS )
  402. {
  403. return IX_ETH_ACC_FAIL;
  404. }
  405. }
  406. return(IX_ETH_ACC_SUCCESS);
  407. }
  408. /**
  409. * @fn ixEthAccQMgrQueuesConfig(void)
  410. *
  411. * @brief Setup all the queues and register all callbacks required
  412. * by this component to the QMgr
  413. *
  414. * The RxFree queues, tx queues, rx queues are configured statically
  415. *
  416. * Rx queues configuration is driven by QoS setup.
  417. * Many Rx queues may be required when QoS is enabled (this depends
  418. * on IxEthDB setup and the images being downloaded). The configuration
  419. * of the rxQueues is done in many steps as follows:
  420. *
  421. * @li select all Rx queues as configured by ethDB for all ports
  422. * @li sort the queues by traffic class
  423. * @li build the priority dependency for all queues
  424. * @li fill the configuration for all rx queues
  425. * @li configure all statically configured queues
  426. * @li configure all dynamically configured queues
  427. *
  428. * @param none
  429. *
  430. * @return IxEthAccStatus
  431. *
  432. * @internal
  433. */
  434. IX_ETH_ACC_PUBLIC
  435. IxEthAccStatus ixEthAccQMgrQueuesConfig(void)
  436. {
  437. struct
  438. {
  439. int npeCount;
  440. UINT32 npeId;
  441. IxQMgrQId qId;
  442. IxEthDBProperty trafficClass;
  443. } rxQueues[IX_ETHACC_MAX_RX_QUEUES];
  444. UINT32 rxQueue = 0;
  445. UINT32 rxQueueCount = 0;
  446. IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES;
  447. IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS;
  448. IxEthDBPortId ixEthDbPortId = 0;
  449. IxEthAccPortId ixEthAccPortId = 0;
  450. UINT32 ixNpeId = 0;
  451. UINT32 ixHighestNpeId = 0;
  452. UINT32 sortIterations = 0;
  453. IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
  454. IxEthAccQregInfo *qInfoDes = NULL;
  455. IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
  456. IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY;
  457. UINT32 ixEthDBParameter = 0;
  458. BOOL completelySorted = false;
  459. /* Fill the corspondance between ports and queues
  460. * This defines the mapping from port to queue Ids.
  461. */
  462. ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue
  463. = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q;
  464. ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue
  465. = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q;
  466. #ifdef __ixp46X
  467. ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue
  468. = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q;
  469. #endif
  470. ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue
  471. = IX_ETH_ACC_TX_FRAME_ENET0_Q;
  472. ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue
  473. = IX_ETH_ACC_TX_FRAME_ENET1_Q;
  474. #ifdef __ixp46X
  475. ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue
  476. = IX_ETH_ACC_TX_FRAME_ENET2_Q;
  477. #endif
  478. /* Fill the corspondance between ports and NPEs
  479. * This defines the mapping from port to npeIds.
  480. */
  481. ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB;
  482. ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC;
  483. #ifdef __ixp46X
  484. ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA;
  485. #endif
  486. /* set the default rx scheduling discipline */
  487. ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY;
  488. /*
  489. * Queue Selection step:
  490. *
  491. * The following code selects all the queues and build
  492. * a temporary array which contains for each queue
  493. * - the queue Id,
  494. * - the highest traffic class (in case of many
  495. * priorities configured for the same queue on different
  496. * ports)
  497. * - the number of different Npes which are
  498. * configured to write to this queue.
  499. *
  500. * The output of this loop is a temporary array of RX queues
  501. * in any order.
  502. *
  503. */
  504. #ifdef CONFIG_IXP425_COMPONENT_ETHDB
  505. for (ixEthAccPortId = 0;
  506. (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS)
  507. && (ret == IX_ETH_ACC_SUCCESS);
  508. ixEthAccPortId++)
  509. {
  510. /* map between ethDb and ethAcc port Ids */
  511. ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId;
  512. /* map between npeId and ethAcc port Ids */
  513. ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId);
  514. /* Iterate thru the different priorities */
  515. for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
  516. ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY;
  517. ixEthDBTrafficClass++)
  518. {
  519. ixEthDBStatus = ixEthDBFeaturePropertyGet(
  520. ixEthDbPortId,
  521. IX_ETH_DB_VLAN_QOS,
  522. ixEthDBTrafficClass,
  523. &ixEthDBPropertyType,
  524. (void *)&ixEthDBParameter);
  525. if (ixEthDBStatus == IX_ETH_DB_SUCCESS)
  526. {
  527. /* This port and QoS class are mapped to
  528. * a RX queue.
  529. */
  530. if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY)
  531. {
  532. /* remember the highest npe Id supporting ethernet */
  533. if (ixNpeId > ixHighestNpeId)
  534. {
  535. ixHighestNpeId = ixNpeId;
  536. }
  537. /* search the queue in the list of queues
  538. * already used by an other port or QoS
  539. */
  540. for (rxQueue = 0;
  541. rxQueue < rxQueueCount;
  542. rxQueue++)
  543. {
  544. if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter)
  545. {
  546. /* found an existing setup, update the number of ports
  547. * for this queue if the port maps to
  548. * a different NPE.
  549. */
  550. if (rxQueues[rxQueue].npeId != ixNpeId)
  551. {
  552. rxQueues[rxQueue].npeCount++;
  553. rxQueues[rxQueue].npeId = ixNpeId;
  554. }
  555. /* get the highest traffic class for this queue */
  556. if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass)
  557. {
  558. rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;
  559. }
  560. break;
  561. }
  562. }
  563. if (rxQueue == rxQueueCount)
  564. {
  565. /* new queue not found in the current list,
  566. * add a new entry.
  567. */
  568. IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES);
  569. rxQueues[rxQueueCount].qId = ixEthDBParameter;
  570. rxQueues[rxQueueCount].npeCount = 1;
  571. rxQueues[rxQueueCount].npeId = ixNpeId;
  572. rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass;
  573. rxQueueCount++;
  574. }
  575. }
  576. else
  577. {
  578. /* unexpected property type (not Integer) */
  579. ret = IX_ETH_ACC_FAIL;
  580. IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0);
  581. /* no point to continue to iterate */
  582. break;
  583. }
  584. }
  585. else
  586. {
  587. /* No Rx queue configured for this port
  588. * and this traffic class. Do nothing.
  589. */
  590. }
  591. }
  592. /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */
  593. ixEthDBFeaturePropertySet(ixEthDbPortId,
  594. IX_ETH_DB_VLAN_QOS,
  595. IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE,
  596. NULL /* ignored */);
  597. }
  598. #else
  599. ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId);
  600. rxQueues[0].qId = 4;
  601. rxQueues[0].npeCount = 1;
  602. rxQueues[0].npeId = ixNpeId;
  603. rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
  604. rxQueueCount++;
  605. #endif
  606. /* check there is at least 1 rx queue : there is no point
  607. * to continue if there is no rx queue configured
  608. */
  609. if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL))
  610. {
  611. IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0);
  612. return (IX_ETH_ACC_FAIL);
  613. }
  614. /* Queue sort step:
  615. *
  616. * Re-order the array of queues by decreasing traffic class
  617. * using a bubble sort. (trafficClass 0 is the lowest
  618. * priority traffic, trafficClass 7 is the highest priority traffic)
  619. *
  620. * Primary sort order is traffic class
  621. * Secondary sort order is npeId
  622. *
  623. * Note that a bubble sort algorithm is not very efficient when
  624. * the number of queues grows . However, this is not a very bad choice
  625. * considering the very small number of entries to sort. Also, bubble
  626. * sort is extremely fast when the list is already sorted.
  627. *
  628. * The output of this loop is a sorted array of queues.
  629. *
  630. */
  631. sortIterations = 0;
  632. do
  633. {
  634. sortIterations++;
  635. completelySorted = true;
  636. for (rxQueue = 0;
  637. rxQueue < rxQueueCount - sortIterations;
  638. rxQueue++)
  639. {
  640. /* compare adjacent elements */
  641. if ((rxQueues[rxQueue].trafficClass <
  642. rxQueues[rxQueue+1].trafficClass)
  643. || ((rxQueues[rxQueue].trafficClass ==
  644. rxQueues[rxQueue+1].trafficClass)
  645. &&(rxQueues[rxQueue].npeId <
  646. rxQueues[rxQueue+1].npeId)))
  647. {
  648. /* swap adjacent elements */
  649. int npeCount = rxQueues[rxQueue].npeCount;
  650. UINT32 npeId = rxQueues[rxQueue].npeId;
  651. IxQMgrQId qId = rxQueues[rxQueue].qId;
  652. IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass;
  653. rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount;
  654. rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId;
  655. rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId;
  656. rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass;
  657. rxQueues[rxQueue+1].npeCount = npeCount;
  658. rxQueues[rxQueue+1].npeId = npeId;
  659. rxQueues[rxQueue+1].qId = qId;
  660. rxQueues[rxQueue+1].trafficClass = trafficClass;
  661. completelySorted = false;
  662. }
  663. }
  664. }
  665. while (!completelySorted);
  666. /* Queue traffic class list:
  667. *
  668. * Fill an array of rx queues linked by ascending traffic classes.
  669. *
  670. * If the queues are configured as follows
  671. * qId 6 -> traffic class 0 (lowest)
  672. * qId 7 -> traffic class 0
  673. * qId 8 -> traffic class 6
  674. * qId 12 -> traffic class 7 (highest)
  675. *
  676. * Then the output of this loop will be
  677. *
  678. * higherPriorityQueue[6] = 8
  679. * higherPriorityQueue[7] = 8
  680. * higherPriorityQueue[8] = 12
  681. * higherPriorityQueue[12] = Invalid queueId
  682. * higherPriorityQueue[...] = Invalid queueId
  683. *
  684. * Note that this queue ordering does not handle all possibilities
  685. * that could result from different rules associated with different
  686. * ports, and inconsistencies in the rules. In all cases, the
  687. * output of this algorithm is a simple linked list of queues,
  688. * without closed circuit.
  689. * This list is implemented as an array with invalid values initialized
  690. * with an "invalid" queue id which is the maximum number of queues.
  691. *
  692. */
  693. /*
  694. * Initialise the rx queue list.
  695. */
  696. for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++)
  697. {
  698. ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES;
  699. }
  700. /* build the linked list for this NPE.
  701. */
  702. for (ixNpeId = 0;
  703. ixNpeId <= ixHighestNpeId;
  704. ixNpeId++)
  705. {
  706. /* iterate thru the sorted list of queues
  707. */
  708. ixQId = IX_QMGR_MAX_NUM_QUEUES;
  709. for (rxQueue = 0;
  710. rxQueue < rxQueueCount;
  711. rxQueue++)
  712. {
  713. if (rxQueues[rxQueue].npeId == ixNpeId)
  714. {
  715. ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId;
  716. /* iterate thru queues with the same traffic class
  717. * than the current queue. (queues are ordered by descending
  718. * traffic classes and npeIds).
  719. */
  720. while ((rxQueue < rxQueueCount - 1)
  721. && (rxQueues[rxQueue].trafficClass
  722. == rxQueues[rxQueue+1].trafficClass)
  723. && (ixNpeId == rxQueues[rxQueue].npeId))
  724. {
  725. rxQueue++;
  726. ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId;
  727. }
  728. ixQId = rxQueues[rxQueue].qId;
  729. }
  730. }
  731. }
  732. /* point on the first dynamic queue description */
  733. qInfoDes = ixEthAccQmgrRxQueuesInfo;
  734. /* update the list of queues with the rx queues */
  735. for (rxQueue = 0;
  736. (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS);
  737. rxQueue++)
  738. {
  739. /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues
  740. * with the full 128 entries. For the lower priority queues, use
  741. * a smaller number of entries. This ensures queue resources
  742. * remain available for other components.
  743. */
  744. if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) &&
  745. (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) )
  746. {
  747. /* add the small RX Queue setup template to the list of queues */
  748. memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes));
  749. } else {
  750. /* add the default RX Queue setup template to the list of queues */
  751. memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes));
  752. }
  753. /* setup the RxQueue ID */
  754. qInfoDes->qId = rxQueues[rxQueue].qId;
  755. /* setup the RxQueue watermark level
  756. *
  757. * Each queue can be filled by many NPEs. To avoid the
  758. * NPEs to write to a full queue, need to set the
  759. * high watermark level for nearly full condition.
  760. * (the high watermark level are a power of 2
  761. * starting from the top of the queue)
  762. *
  763. * Number of watermark
  764. * ports level
  765. * 1 0
  766. * 2 1
  767. * 3 2
  768. * 4 4
  769. * 5 4
  770. * 6 8
  771. * n approx. 2**ceil(log2(n))
  772. */
  773. if (rxQueues[rxQueue].npeCount == 1)
  774. {
  775. qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0;
  776. }
  777. else if (rxQueues[rxQueue].npeCount == 2)
  778. {
  779. qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1;
  780. }
  781. else if (rxQueues[rxQueue].npeCount == 3)
  782. {
  783. qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2;
  784. }
  785. else
  786. {
  787. /* reach the maximum number for CSR 2.0 */
  788. IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0);
  789. ret = IX_ETH_ACC_FAIL;
  790. break;
  791. }
  792. /* move to next queue entry */
  793. ++qInfoDes;
  794. }
  795. /* configure the static list (RxFree, Tx and TxDone queues) */
  796. for (qInfoDes = ixEthAccQmgrStaticInfo;
  797. (qInfoDes->qCallback != (IxQMgrCallback) NULL )
  798. && (ret == IX_ETH_ACC_SUCCESS);
  799. ++qInfoDes)
  800. {
  801. ret = ixEthAccQMgrQueueSetup(qInfoDes);
  802. }
  803. /* configure the dynamic list (Rx queues) */
  804. for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
  805. (qInfoDes->qCallback != (IxQMgrCallback) NULL )
  806. && (ret == IX_ETH_ACC_SUCCESS);
  807. ++qInfoDes)
  808. {
  809. ret = ixEthAccQMgrQueueSetup(qInfoDes);
  810. }
  811. return(ret);
  812. }
  813. /**
  814. * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries)
  815. *
  816. * @brief Add and return the total number of entries in all Rx queues
  817. *
  818. * @param UINT32 rxQueueEntries[in] number of entries in all queues
  819. *
  820. * @return void
  821. *
  822. * @note Rx queues configuration is driven by Qos Setup. There is a
  823. * variable number of rx queues which are set at initialisation.
  824. *
  825. * @internal
  826. */
  827. IX_ETH_ACC_PUBLIC
  828. void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries)
  829. {
  830. UINT32 rxQueueLevel;
  831. IxEthAccQregInfo *qInfoDes;;
  832. *numRxQueueEntries = 0;
  833. /* iterate thru rx queues */
  834. for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
  835. qInfoDes->qCallback != (IxQMgrCallback)NULL;
  836. ++qInfoDes)
  837. {
  838. /* retrieve the rx queue level */
  839. rxQueueLevel = 0;
  840. ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel);
  841. (*numRxQueueEntries) += rxQueueLevel;
  842. }
  843. }
  844. /**
  845. * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
  846. *
  847. * @brief Change the callback registered to all rx queues.
  848. *
  849. * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register
  850. *
  851. * @return IxEthAccStatus
  852. *
  853. * @note The user may decide to use different Rx mechanisms
  854. * (e.g. receive many frames at the same time , or receive
  855. * one frame at a time, depending on the overall application
  856. * performances). A different QMgr callback is registered. This
  857. * way, there is no excessive pointer checks in the datapath.
  858. *
  859. * @internal
  860. */
  861. IX_ETH_ACC_PUBLIC
  862. IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
  863. {
  864. IxEthAccQregInfo *qInfoDes;
  865. IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
  866. /* parameter check */
  867. if (NULL == ixQMgrCallback)
  868. {
  869. ret = IX_ETH_ACC_FAIL;
  870. }
  871. /* iterate thru rx queues */
  872. for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
  873. (qInfoDes->qCallback != (IxQMgrCallback) NULL )
  874. && (ret == IX_ETH_ACC_SUCCESS);
  875. ++qInfoDes)
  876. {
  877. /* register the rx callback for all queues */
  878. if (ixQMgrNotificationCallbackSet(qInfoDes->qId,
  879. ixQMgrCallback,
  880. qInfoDes->callbackTag
  881. ) != IX_SUCCESS)
  882. {
  883. ret = IX_ETH_ACC_FAIL;
  884. }
  885. }
  886. return(ret);
  887. }
  888. /**
  889. * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
  890. *
  891. * @brief Check the npe exists for this port
  892. *
  893. * @param IxEthAccPortId portId[in] port
  894. *
  895. * @return IxEthAccStatus
  896. *
  897. * @internal
  898. */
  899. IX_ETH_ACC_PUBLIC
  900. IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
  901. {
  902. /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
  903. if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
  904. (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
  905. || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
  906. {
  907. if ((IX_ETH_PORT_1 == portId) &&
  908. (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
  909. IX_FEATURE_CTRL_COMPONENT_ENABLED))
  910. {
  911. return IX_ETH_ACC_SUCCESS;
  912. }
  913. if ((IX_ETH_PORT_2 == portId) &&
  914. (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
  915. IX_FEATURE_CTRL_COMPONENT_ENABLED))
  916. {
  917. return IX_ETH_ACC_SUCCESS;
  918. }
  919. if ((IX_ETH_PORT_3 == portId) &&
  920. (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
  921. IX_FEATURE_CTRL_COMPONENT_ENABLED))
  922. {
  923. return IX_ETH_ACC_SUCCESS;
  924. }
  925. return IX_ETH_ACC_FAIL;
  926. }
  927. return IX_ETH_ACC_SUCCESS;
  928. }
  929. /**
  930. * @fn ixEthAccStatsShow(void)
  931. *
  932. * @brief Displays all EthAcc stats
  933. *
  934. * @return void
  935. *
  936. */
  937. void ixEthAccStatsShow(IxEthAccPortId portId)
  938. {
  939. ixEthAccMdioShow();
  940. printf("\nPort %u\nUnicast MAC : ", portId);
  941. ixEthAccPortUnicastAddressShow(portId);
  942. ixEthAccPortMulticastAddressShow(portId);
  943. printf("\n");
  944. ixEthAccDataPlaneShow();
  945. }