IxEthAccCommon.c 29 KB

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