cvmx-pko.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /***********************license start***************
  2. * Author: Cavium Networks
  3. *
  4. * Contact: [email protected]
  5. * This file is part of the OCTEON SDK
  6. *
  7. * Copyright (c) 2003-2008 Cavium Networks
  8. *
  9. * This file is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License, Version 2, as
  11. * published by the Free Software Foundation.
  12. *
  13. * This file is distributed in the hope that it will be useful, but
  14. * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
  15. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16. * NONINFRINGEMENT. See the GNU General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this file; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22. * or visit http://www.gnu.org/licenses/.
  23. *
  24. * This file may also be available under a different license from Cavium.
  25. * Contact Cavium Networks for more information
  26. ***********************license end**************************************/
  27. /**
  28. *
  29. * Interface to the hardware Packet Output unit.
  30. *
  31. * Starting with SDK 1.7.0, the PKO output functions now support
  32. * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to
  33. * function similarly to previous SDKs by using POW atomic tags
  34. * to preserve ordering and exclusivity. As a new option, you
  35. * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc
  36. * memory based locking instead. This locking has the advantage
  37. * of not affecting the tag state but doesn't preserve packet
  38. * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most
  39. * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used
  40. * with hand tuned fast path code.
  41. *
  42. * Some of other SDK differences visible to the command queuing:
  43. * - PKO indexes are no longer stored in the FAU. A large
  44. * percentage of the FAU register block used to be tied up
  45. * maintaining PKO queue pointers. These are now stored in a
  46. * global named block.
  47. * - The PKO <b>use_locking</b> parameter can now have a global
  48. * effect. Since all application use the same named block,
  49. * queue locking correctly applies across all operating
  50. * systems when using CVMX_PKO_LOCK_CMD_QUEUE.
  51. * - PKO 3 word commands are now supported. Use
  52. * cvmx_pko_send_packet_finish3().
  53. *
  54. */
  55. #ifndef __CVMX_PKO_H__
  56. #define __CVMX_PKO_H__
  57. #include <asm/octeon/cvmx-fpa.h>
  58. #include <asm/octeon/cvmx-pow.h>
  59. #include <asm/octeon/cvmx-cmd-queue.h>
  60. #include <asm/octeon/cvmx-pko-defs.h>
  61. /* Adjust the command buffer size by 1 word so that in the case of using only
  62. * two word PKO commands no command words stradle buffers. The useful values
  63. * for this are 0 and 1. */
  64. #define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
  65. #define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
  66. #define CVMX_PKO_MAX_OUTPUT_QUEUES ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
  67. OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
  68. OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
  69. (OCTEON_IS_MODEL(OCTEON_CN58XX) || \
  70. OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
  71. #define CVMX_PKO_NUM_OUTPUT_PORTS 40
  72. /* use this for queues that are not used */
  73. #define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
  74. #define CVMX_PKO_QUEUE_STATIC_PRIORITY 9
  75. #define CVMX_PKO_ILLEGAL_QUEUE 0xFFFF
  76. #define CVMX_PKO_MAX_QUEUE_DEPTH 0
  77. typedef enum {
  78. CVMX_PKO_SUCCESS,
  79. CVMX_PKO_INVALID_PORT,
  80. CVMX_PKO_INVALID_QUEUE,
  81. CVMX_PKO_INVALID_PRIORITY,
  82. CVMX_PKO_NO_MEMORY,
  83. CVMX_PKO_PORT_ALREADY_SETUP,
  84. CVMX_PKO_CMD_QUEUE_INIT_ERROR
  85. } cvmx_pko_status_t;
  86. /**
  87. * This enumeration represents the differnet locking modes supported by PKO.
  88. */
  89. typedef enum {
  90. /*
  91. * PKO doesn't do any locking. It is the responsibility of the
  92. * application to make sure that no other core is accessing
  93. * the same queue at the same time
  94. */
  95. CVMX_PKO_LOCK_NONE = 0,
  96. /*
  97. * PKO performs an atomic tagswitch to insure exclusive access
  98. * to the output queue. This will maintain packet ordering on
  99. * output.
  100. */
  101. CVMX_PKO_LOCK_ATOMIC_TAG = 1,
  102. /*
  103. * PKO uses the common command queue locks to insure exclusive
  104. * access to the output queue. This is a memory based
  105. * ll/sc. This is the most portable locking mechanism.
  106. */
  107. CVMX_PKO_LOCK_CMD_QUEUE = 2,
  108. } cvmx_pko_lock_t;
  109. typedef struct {
  110. uint32_t packets;
  111. uint64_t octets;
  112. uint64_t doorbell;
  113. } cvmx_pko_port_status_t;
  114. /**
  115. * This structure defines the address to use on a packet enqueue
  116. */
  117. typedef union {
  118. uint64_t u64;
  119. struct {
  120. #ifdef __BIG_ENDIAN_BITFIELD
  121. /* Must CVMX_IO_SEG */
  122. uint64_t mem_space:2;
  123. /* Must be zero */
  124. uint64_t reserved:13;
  125. /* Must be one */
  126. uint64_t is_io:1;
  127. /* The ID of the device on the non-coherent bus */
  128. uint64_t did:8;
  129. /* Must be zero */
  130. uint64_t reserved2:4;
  131. /* Must be zero */
  132. uint64_t reserved3:18;
  133. /*
  134. * The hardware likes to have the output port in
  135. * addition to the output queue,
  136. */
  137. uint64_t port:6;
  138. /*
  139. * The output queue to send the packet to (0-127 are
  140. * legal)
  141. */
  142. uint64_t queue:9;
  143. /* Must be zero */
  144. uint64_t reserved4:3;
  145. #else
  146. uint64_t reserved4:3;
  147. uint64_t queue:9;
  148. uint64_t port:9;
  149. uint64_t reserved3:15;
  150. uint64_t reserved2:4;
  151. uint64_t did:8;
  152. uint64_t is_io:1;
  153. uint64_t reserved:13;
  154. uint64_t mem_space:2;
  155. #endif
  156. } s;
  157. } cvmx_pko_doorbell_address_t;
  158. /**
  159. * Structure of the first packet output command word.
  160. */
  161. union cvmx_pko_command_word0 {
  162. uint64_t u64;
  163. struct {
  164. #ifdef __BIG_ENDIAN_BITFIELD
  165. /*
  166. * The size of the reg1 operation - could be 8, 16,
  167. * 32, or 64 bits.
  168. */
  169. uint64_t size1:2;
  170. /*
  171. * The size of the reg0 operation - could be 8, 16,
  172. * 32, or 64 bits.
  173. */
  174. uint64_t size0:2;
  175. /*
  176. * If set, subtract 1, if clear, subtract packet
  177. * size.
  178. */
  179. uint64_t subone1:1;
  180. /*
  181. * The register, subtract will be done if reg1 is
  182. * non-zero.
  183. */
  184. uint64_t reg1:11;
  185. /* If set, subtract 1, if clear, subtract packet size */
  186. uint64_t subone0:1;
  187. /* The register, subtract will be done if reg0 is non-zero */
  188. uint64_t reg0:11;
  189. /*
  190. * When set, interpret segment pointer and segment
  191. * bytes in little endian order.
  192. */
  193. uint64_t le:1;
  194. /*
  195. * When set, packet data not allocated in L2 cache by
  196. * PKO.
  197. */
  198. uint64_t n2:1;
  199. /*
  200. * If set and rsp is set, word3 contains a pointer to
  201. * a work queue entry.
  202. */
  203. uint64_t wqp:1;
  204. /* If set, the hardware will send a response when done */
  205. uint64_t rsp:1;
  206. /*
  207. * If set, the supplied pkt_ptr is really a pointer to
  208. * a list of pkt_ptr's.
  209. */
  210. uint64_t gather:1;
  211. /*
  212. * If ipoffp1 is non zero, (ipoffp1-1) is the number
  213. * of bytes to IP header, and the hardware will
  214. * calculate and insert the UDP/TCP checksum.
  215. */
  216. uint64_t ipoffp1:7;
  217. /*
  218. * If set, ignore the I bit (force to zero) from all
  219. * pointer structures.
  220. */
  221. uint64_t ignore_i:1;
  222. /*
  223. * If clear, the hardware will attempt to free the
  224. * buffers containing the packet.
  225. */
  226. uint64_t dontfree:1;
  227. /*
  228. * The total number of segs in the packet, if gather
  229. * set, also gather list length.
  230. */
  231. uint64_t segs:6;
  232. /* Including L2, but no trailing CRC */
  233. uint64_t total_bytes:16;
  234. #else
  235. uint64_t total_bytes:16;
  236. uint64_t segs:6;
  237. uint64_t dontfree:1;
  238. uint64_t ignore_i:1;
  239. uint64_t ipoffp1:7;
  240. uint64_t gather:1;
  241. uint64_t rsp:1;
  242. uint64_t wqp:1;
  243. uint64_t n2:1;
  244. uint64_t le:1;
  245. uint64_t reg0:11;
  246. uint64_t subone0:1;
  247. uint64_t reg1:11;
  248. uint64_t subone1:1;
  249. uint64_t size0:2;
  250. uint64_t size1:2;
  251. #endif
  252. } s;
  253. };
  254. /* CSR typedefs have been moved to cvmx-csr-*.h */
  255. /**
  256. * Definition of internal state for Packet output processing
  257. */
  258. typedef struct {
  259. /* ptr to start of buffer, offset kept in FAU reg */
  260. uint64_t *start_ptr;
  261. } cvmx_pko_state_elem_t;
  262. /**
  263. * Call before any other calls to initialize the packet
  264. * output system.
  265. */
  266. extern void cvmx_pko_initialize_global(void);
  267. /**
  268. * Enables the packet output hardware. It must already be
  269. * configured.
  270. */
  271. extern void cvmx_pko_enable(void);
  272. /**
  273. * Disables the packet output. Does not affect any configuration.
  274. */
  275. extern void cvmx_pko_disable(void);
  276. /**
  277. * Shutdown and free resources required by packet output.
  278. */
  279. extern void cvmx_pko_shutdown(void);
  280. /**
  281. * Configure a output port and the associated queues for use.
  282. *
  283. * @port: Port to configure.
  284. * @base_queue: First queue number to associate with this port.
  285. * @num_queues: Number of queues t oassociate with this port
  286. * @priority: Array of priority levels for each queue. Values are
  287. * allowed to be 1-8. A value of 8 get 8 times the traffic
  288. * of a value of 1. There must be num_queues elements in the
  289. * array.
  290. */
  291. extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
  292. uint64_t base_queue,
  293. uint64_t num_queues,
  294. const uint64_t priority[]);
  295. /**
  296. * Ring the packet output doorbell. This tells the packet
  297. * output hardware that "len" command words have been added
  298. * to its pending list. This command includes the required
  299. * CVMX_SYNCWS before the doorbell ring.
  300. *
  301. * @port: Port the packet is for
  302. * @queue: Queue the packet is for
  303. * @len: Length of the command in 64 bit words
  304. */
  305. static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
  306. uint64_t len)
  307. {
  308. cvmx_pko_doorbell_address_t ptr;
  309. ptr.u64 = 0;
  310. ptr.s.mem_space = CVMX_IO_SEG;
  311. ptr.s.did = CVMX_OCT_DID_PKT_SEND;
  312. ptr.s.is_io = 1;
  313. ptr.s.port = port;
  314. ptr.s.queue = queue;
  315. /*
  316. * Need to make sure output queue data is in DRAM before
  317. * doorbell write.
  318. */
  319. CVMX_SYNCWS;
  320. cvmx_write_io(ptr.u64, len);
  321. }
  322. /**
  323. * Prepare to send a packet. This may initiate a tag switch to
  324. * get exclusive access to the output queue structure, and
  325. * performs other prep work for the packet send operation.
  326. *
  327. * cvmx_pko_send_packet_finish() MUST be called after this function is called,
  328. * and must be called with the same port/queue/use_locking arguments.
  329. *
  330. * The use_locking parameter allows the caller to use three
  331. * possible locking modes.
  332. * - CVMX_PKO_LOCK_NONE
  333. * - PKO doesn't do any locking. It is the responsibility
  334. * of the application to make sure that no other core
  335. * is accessing the same queue at the same time.
  336. * - CVMX_PKO_LOCK_ATOMIC_TAG
  337. * - PKO performs an atomic tagswitch to insure exclusive
  338. * access to the output queue. This will maintain
  339. * packet ordering on output.
  340. * - CVMX_PKO_LOCK_CMD_QUEUE
  341. * - PKO uses the common command queue locks to insure
  342. * exclusive access to the output queue. This is a
  343. * memory based ll/sc. This is the most portable
  344. * locking mechanism.
  345. *
  346. * NOTE: If atomic locking is used, the POW entry CANNOT be
  347. * descheduled, as it does not contain a valid WQE pointer.
  348. *
  349. * @port: Port to send it on
  350. * @queue: Queue to use
  351. * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
  352. * CVMX_PKO_LOCK_CMD_QUEUE
  353. */
  354. static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
  355. cvmx_pko_lock_t use_locking)
  356. {
  357. if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
  358. /*
  359. * Must do a full switch here to handle all cases. We
  360. * use a fake WQE pointer, as the POW does not access
  361. * this memory. The WQE pointer and group are only
  362. * used if this work is descheduled, which is not
  363. * supported by the
  364. * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish
  365. * combination. Note that this is a special case in
  366. * which these fake values can be used - this is not a
  367. * general technique.
  368. */
  369. uint32_t tag =
  370. CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
  371. CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
  372. (CVMX_TAG_SUBGROUP_MASK & queue);
  373. cvmx_pow_tag_sw_full((struct cvmx_wqe *) cvmx_phys_to_ptr(0x80), tag,
  374. CVMX_POW_TAG_TYPE_ATOMIC, 0);
  375. }
  376. }
  377. /**
  378. * Complete packet output. cvmx_pko_send_packet_prepare() must be
  379. * called exactly once before this, and the same parameters must be
  380. * passed to both cvmx_pko_send_packet_prepare() and
  381. * cvmx_pko_send_packet_finish().
  382. *
  383. * @port: Port to send it on
  384. * @queue: Queue to use
  385. * @pko_command:
  386. * PKO HW command word
  387. * @packet: Packet to send
  388. * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
  389. * CVMX_PKO_LOCK_CMD_QUEUE
  390. *
  391. * Returns: CVMX_PKO_SUCCESS on success, or error code on
  392. * failure of output
  393. */
  394. static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
  395. uint64_t port,
  396. uint64_t queue,
  397. union cvmx_pko_command_word0 pko_command,
  398. union cvmx_buf_ptr packet,
  399. cvmx_pko_lock_t use_locking)
  400. {
  401. cvmx_cmd_queue_result_t result;
  402. if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
  403. cvmx_pow_tag_sw_wait();
  404. result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
  405. (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
  406. pko_command.u64, packet.u64);
  407. if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
  408. cvmx_pko_doorbell(port, queue, 2);
  409. return CVMX_PKO_SUCCESS;
  410. } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
  411. || (result == CVMX_CMD_QUEUE_FULL)) {
  412. return CVMX_PKO_NO_MEMORY;
  413. } else {
  414. return CVMX_PKO_INVALID_QUEUE;
  415. }
  416. }
  417. /**
  418. * Complete packet output. cvmx_pko_send_packet_prepare() must be
  419. * called exactly once before this, and the same parameters must be
  420. * passed to both cvmx_pko_send_packet_prepare() and
  421. * cvmx_pko_send_packet_finish().
  422. *
  423. * @port: Port to send it on
  424. * @queue: Queue to use
  425. * @pko_command:
  426. * PKO HW command word
  427. * @packet: Packet to send
  428. * @addr: Plysical address of a work queue entry or physical address
  429. * to zero on complete.
  430. * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
  431. * CVMX_PKO_LOCK_CMD_QUEUE
  432. *
  433. * Returns: CVMX_PKO_SUCCESS on success, or error code on
  434. * failure of output
  435. */
  436. static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
  437. uint64_t port,
  438. uint64_t queue,
  439. union cvmx_pko_command_word0 pko_command,
  440. union cvmx_buf_ptr packet,
  441. uint64_t addr,
  442. cvmx_pko_lock_t use_locking)
  443. {
  444. cvmx_cmd_queue_result_t result;
  445. if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
  446. cvmx_pow_tag_sw_wait();
  447. result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
  448. (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
  449. pko_command.u64, packet.u64, addr);
  450. if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
  451. cvmx_pko_doorbell(port, queue, 3);
  452. return CVMX_PKO_SUCCESS;
  453. } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
  454. || (result == CVMX_CMD_QUEUE_FULL)) {
  455. return CVMX_PKO_NO_MEMORY;
  456. } else {
  457. return CVMX_PKO_INVALID_QUEUE;
  458. }
  459. }
  460. /**
  461. * Return the pko output queue associated with a port and a specific core.
  462. * In normal mode (PKO lockless operation is disabled), the value returned
  463. * is the base queue.
  464. *
  465. * @port: Port number
  466. * @core: Core to get queue for
  467. *
  468. * Returns Core-specific output queue
  469. */
  470. static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
  471. {
  472. #ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
  473. #define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
  474. #endif
  475. #ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
  476. #define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
  477. #endif
  478. if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
  479. return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
  480. else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
  481. return CVMX_PKO_MAX_PORTS_INTERFACE0 *
  482. CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
  483. 16) *
  484. CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
  485. else if ((port >= 32) && (port < 36))
  486. return CVMX_PKO_MAX_PORTS_INTERFACE0 *
  487. CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
  488. CVMX_PKO_MAX_PORTS_INTERFACE1 *
  489. CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
  490. 32) *
  491. CVMX_PKO_QUEUES_PER_PORT_PCI;
  492. else if ((port >= 36) && (port < 40))
  493. return CVMX_PKO_MAX_PORTS_INTERFACE0 *
  494. CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
  495. CVMX_PKO_MAX_PORTS_INTERFACE1 *
  496. CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
  497. 4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
  498. 36) *
  499. CVMX_PKO_QUEUES_PER_PORT_LOOP;
  500. else
  501. /* Given the limit on the number of ports we can map to
  502. * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256,
  503. * divided among all cores), the remaining unmapped ports
  504. * are assigned an illegal queue number */
  505. return CVMX_PKO_ILLEGAL_QUEUE;
  506. }
  507. /**
  508. * For a given port number, return the base pko output queue
  509. * for the port.
  510. *
  511. * @port: Port number
  512. * Returns Base output queue
  513. */
  514. static inline int cvmx_pko_get_base_queue(int port)
  515. {
  516. if (OCTEON_IS_MODEL(OCTEON_CN68XX))
  517. return port;
  518. return cvmx_pko_get_base_queue_per_core(port, 0);
  519. }
  520. /**
  521. * For a given port number, return the number of pko output queues.
  522. *
  523. * @port: Port number
  524. * Returns Number of output queues
  525. */
  526. static inline int cvmx_pko_get_num_queues(int port)
  527. {
  528. if (port < 16)
  529. return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
  530. else if (port < 32)
  531. return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
  532. else if (port < 36)
  533. return CVMX_PKO_QUEUES_PER_PORT_PCI;
  534. else if (port < 40)
  535. return CVMX_PKO_QUEUES_PER_PORT_LOOP;
  536. else
  537. return 0;
  538. }
  539. /**
  540. * Get the status counters for a port.
  541. *
  542. * @port_num: Port number to get statistics for.
  543. * @clear: Set to 1 to clear the counters after they are read
  544. * @status: Where to put the results.
  545. */
  546. static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
  547. cvmx_pko_port_status_t *status)
  548. {
  549. union cvmx_pko_reg_read_idx pko_reg_read_idx;
  550. union cvmx_pko_mem_count0 pko_mem_count0;
  551. union cvmx_pko_mem_count1 pko_mem_count1;
  552. pko_reg_read_idx.u64 = 0;
  553. pko_reg_read_idx.s.index = port_num;
  554. cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
  555. pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
  556. status->packets = pko_mem_count0.s.count;
  557. if (clear) {
  558. pko_mem_count0.s.count = port_num;
  559. cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
  560. }
  561. pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
  562. status->octets = pko_mem_count1.s.count;
  563. if (clear) {
  564. pko_mem_count1.s.count = port_num;
  565. cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
  566. }
  567. if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
  568. union cvmx_pko_mem_debug9 debug9;
  569. pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
  570. cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
  571. debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
  572. status->doorbell = debug9.cn38xx.doorbell;
  573. } else {
  574. union cvmx_pko_mem_debug8 debug8;
  575. pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
  576. cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
  577. debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
  578. status->doorbell = debug8.cn50xx.doorbell;
  579. }
  580. }
  581. /**
  582. * Rate limit a PKO port to a max packets/sec. This function is only
  583. * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
  584. *
  585. * @port: Port to rate limit
  586. * @packets_s: Maximum packet/sec
  587. * @burst: Maximum number of packets to burst in a row before rate
  588. * limiting cuts in.
  589. *
  590. * Returns Zero on success, negative on failure
  591. */
  592. extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
  593. /**
  594. * Rate limit a PKO port to a max bits/sec. This function is only
  595. * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
  596. *
  597. * @port: Port to rate limit
  598. * @bits_s: PKO rate limit in bits/sec
  599. * @burst: Maximum number of bits to burst before rate
  600. * limiting cuts in.
  601. *
  602. * Returns Zero on success, negative on failure
  603. */
  604. extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
  605. #endif /* __CVMX_PKO_H__ */