cvmx-wqe.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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. * This header file defines the work queue entry (wqe) data structure.
  30. * Since this is a commonly used structure that depends on structures
  31. * from several hardware blocks, those definitions have been placed
  32. * in this file to create a single point of definition of the wqe
  33. * format.
  34. * Data structures are still named according to the block that they
  35. * relate to.
  36. *
  37. */
  38. #ifndef __CVMX_WQE_H__
  39. #define __CVMX_WQE_H__
  40. #include <asm/octeon/cvmx-packet.h>
  41. #define OCT_TAG_TYPE_STRING(x) \
  42. (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \
  43. (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \
  44. (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \
  45. "NULL_NULL")))
  46. /**
  47. * HW decode / err_code in work queue entry
  48. */
  49. typedef union {
  50. uint64_t u64;
  51. /* Use this struct if the hardware determines that the packet is IP */
  52. struct {
  53. #ifdef __BIG_ENDIAN_BITFIELD
  54. /* HW sets this to the number of buffers used by this packet */
  55. uint64_t bufs:8;
  56. /* HW sets to the number of L2 bytes prior to the IP */
  57. uint64_t ip_offset:8;
  58. /* set to 1 if we found DSA/VLAN in the L2 */
  59. uint64_t vlan_valid:1;
  60. /* Set to 1 if the DSA/VLAN tag is stacked */
  61. uint64_t vlan_stacked:1;
  62. uint64_t unassigned:1;
  63. /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
  64. uint64_t vlan_cfi:1;
  65. /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
  66. uint64_t vlan_id:12;
  67. /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
  68. uint64_t pr:4;
  69. uint64_t unassigned2:8;
  70. /* the packet needs to be decompressed */
  71. uint64_t dec_ipcomp:1;
  72. /* the packet is either TCP or UDP */
  73. uint64_t tcp_or_udp:1;
  74. /* the packet needs to be decrypted (ESP or AH) */
  75. uint64_t dec_ipsec:1;
  76. /* the packet is IPv6 */
  77. uint64_t is_v6:1;
  78. /*
  79. * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
  80. * software, etc.).
  81. */
  82. /*
  83. * reserved for software use, hardware will clear on
  84. * packet creation.
  85. */
  86. uint64_t software:1;
  87. /* exceptional conditions below */
  88. /* the receive interface hardware detected an L4 error
  89. * (only applies if !is_frag) (only applies if
  90. * !rcv_error && !not_IP && !IP_exc && !is_frag)
  91. * failure indicated in err_code below, decode:
  92. *
  93. * - 1 = Malformed L4
  94. * - 2 = L4 Checksum Error: the L4 checksum value is
  95. * - 3 = UDP Length Error: The UDP length field would
  96. * make the UDP data longer than what remains in
  97. * the IP packet (as defined by the IP header
  98. * length field).
  99. * - 4 = Bad L4 Port: either the source or destination
  100. * TCP/UDP port is 0.
  101. * - 8 = TCP FIN Only: the packet is TCP and only the
  102. * FIN flag set.
  103. * - 9 = TCP No Flags: the packet is TCP and no flags
  104. * are set.
  105. * - 10 = TCP FIN RST: the packet is TCP and both FIN
  106. * and RST are set.
  107. * - 11 = TCP SYN URG: the packet is TCP and both SYN
  108. * and URG are set.
  109. * - 12 = TCP SYN RST: the packet is TCP and both SYN
  110. * and RST are set.
  111. * - 13 = TCP SYN FIN: the packet is TCP and both SYN
  112. * and FIN are set.
  113. */
  114. uint64_t L4_error:1;
  115. /* set if the packet is a fragment */
  116. uint64_t is_frag:1;
  117. /* the receive interface hardware detected an IP error
  118. * / exception (only applies if !rcv_error && !not_IP)
  119. * failure indicated in err_code below, decode:
  120. *
  121. * - 1 = Not IP: the IP version field is neither 4 nor
  122. * 6.
  123. * - 2 = IPv4 Header Checksum Error: the IPv4 header
  124. * has a checksum violation.
  125. * - 3 = IP Malformed Header: the packet is not long
  126. * enough to contain the IP header.
  127. * - 4 = IP Malformed: the packet is not long enough
  128. * to contain the bytes indicated by the IP
  129. * header. Pad is allowed.
  130. * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
  131. * Hop Count field are zero.
  132. * - 6 = IP Options
  133. */
  134. uint64_t IP_exc:1;
  135. /*
  136. * Set if the hardware determined that the packet is a
  137. * broadcast.
  138. */
  139. uint64_t is_bcast:1;
  140. /*
  141. * St if the hardware determined that the packet is a
  142. * multi-cast.
  143. */
  144. uint64_t is_mcast:1;
  145. /*
  146. * Set if the packet may not be IP (must be zero in
  147. * this case).
  148. */
  149. uint64_t not_IP:1;
  150. /*
  151. * The receive interface hardware detected a receive
  152. * error (must be zero in this case).
  153. */
  154. uint64_t rcv_error:1;
  155. /* lower err_code = first-level descriptor of the
  156. * work */
  157. /* zero for packet submitted by hardware that isn't on
  158. * the slow path */
  159. /* type is cvmx_pip_err_t */
  160. uint64_t err_code:8;
  161. #else
  162. uint64_t err_code:8;
  163. uint64_t rcv_error:1;
  164. uint64_t not_IP:1;
  165. uint64_t is_mcast:1;
  166. uint64_t is_bcast:1;
  167. uint64_t IP_exc:1;
  168. uint64_t is_frag:1;
  169. uint64_t L4_error:1;
  170. uint64_t software:1;
  171. uint64_t is_v6:1;
  172. uint64_t dec_ipsec:1;
  173. uint64_t tcp_or_udp:1;
  174. uint64_t dec_ipcomp:1;
  175. uint64_t unassigned2:4;
  176. uint64_t unassigned2a:4;
  177. uint64_t pr:4;
  178. uint64_t vlan_id:12;
  179. uint64_t vlan_cfi:1;
  180. uint64_t unassigned:1;
  181. uint64_t vlan_stacked:1;
  182. uint64_t vlan_valid:1;
  183. uint64_t ip_offset:8;
  184. uint64_t bufs:8;
  185. #endif
  186. } s;
  187. struct {
  188. #ifdef __BIG_ENDIAN_BITFIELD
  189. uint64_t bufs:8;
  190. uint64_t ip_offset:8;
  191. uint64_t vlan_valid:1;
  192. uint64_t vlan_stacked:1;
  193. uint64_t unassigned:1;
  194. uint64_t vlan_cfi:1;
  195. uint64_t vlan_id:12;
  196. uint64_t port:12; /* MAC/PIP port number. */
  197. uint64_t dec_ipcomp:1;
  198. uint64_t tcp_or_udp:1;
  199. uint64_t dec_ipsec:1;
  200. uint64_t is_v6:1;
  201. uint64_t software:1;
  202. uint64_t L4_error:1;
  203. uint64_t is_frag:1;
  204. uint64_t IP_exc:1;
  205. uint64_t is_bcast:1;
  206. uint64_t is_mcast:1;
  207. uint64_t not_IP:1;
  208. uint64_t rcv_error:1;
  209. uint64_t err_code:8;
  210. #else
  211. uint64_t err_code:8;
  212. uint64_t rcv_error:1;
  213. uint64_t not_IP:1;
  214. uint64_t is_mcast:1;
  215. uint64_t is_bcast:1;
  216. uint64_t IP_exc:1;
  217. uint64_t is_frag:1;
  218. uint64_t L4_error:1;
  219. uint64_t software:1;
  220. uint64_t is_v6:1;
  221. uint64_t dec_ipsec:1;
  222. uint64_t tcp_or_udp:1;
  223. uint64_t dec_ipcomp:1;
  224. uint64_t port:12;
  225. uint64_t vlan_id:12;
  226. uint64_t vlan_cfi:1;
  227. uint64_t unassigned:1;
  228. uint64_t vlan_stacked:1;
  229. uint64_t vlan_valid:1;
  230. uint64_t ip_offset:8;
  231. uint64_t bufs:8;
  232. #endif
  233. } s_cn68xx;
  234. /* use this to get at the 16 vlan bits */
  235. struct {
  236. #ifdef __BIG_ENDIAN_BITFIELD
  237. uint64_t unused1:16;
  238. uint64_t vlan:16;
  239. uint64_t unused2:32;
  240. #else
  241. uint64_t unused2:32;
  242. uint64_t vlan:16;
  243. uint64_t unused1:16;
  244. #endif
  245. } svlan;
  246. /*
  247. * use this struct if the hardware could not determine that
  248. * the packet is ip.
  249. */
  250. struct {
  251. #ifdef __BIG_ENDIAN_BITFIELD
  252. /*
  253. * HW sets this to the number of buffers used by this
  254. * packet.
  255. */
  256. uint64_t bufs:8;
  257. uint64_t unused:8;
  258. /* set to 1 if we found DSA/VLAN in the L2 */
  259. uint64_t vlan_valid:1;
  260. /* Set to 1 if the DSA/VLAN tag is stacked */
  261. uint64_t vlan_stacked:1;
  262. uint64_t unassigned:1;
  263. /*
  264. * HW sets to the DSA/VLAN CFI flag (valid when
  265. * vlan_valid)
  266. */
  267. uint64_t vlan_cfi:1;
  268. /*
  269. * HW sets to the DSA/VLAN_ID field (valid when
  270. * vlan_valid).
  271. */
  272. uint64_t vlan_id:12;
  273. /*
  274. * Ring Identifier (if PCIe). Requires
  275. * PIP_GBL_CTL[RING_EN]=1
  276. */
  277. uint64_t pr:4;
  278. uint64_t unassigned2:12;
  279. /*
  280. * reserved for software use, hardware will clear on
  281. * packet creation.
  282. */
  283. uint64_t software:1;
  284. uint64_t unassigned3:1;
  285. /*
  286. * set if the hardware determined that the packet is
  287. * rarp.
  288. */
  289. uint64_t is_rarp:1;
  290. /*
  291. * set if the hardware determined that the packet is
  292. * arp
  293. */
  294. uint64_t is_arp:1;
  295. /*
  296. * set if the hardware determined that the packet is a
  297. * broadcast.
  298. */
  299. uint64_t is_bcast:1;
  300. /*
  301. * set if the hardware determined that the packet is a
  302. * multi-cast
  303. */
  304. uint64_t is_mcast:1;
  305. /*
  306. * set if the packet may not be IP (must be one in
  307. * this case)
  308. */
  309. uint64_t not_IP:1;
  310. /* The receive interface hardware detected a receive
  311. * error. Failure indicated in err_code below,
  312. * decode:
  313. *
  314. * - 1 = partial error: a packet was partially
  315. * received, but internal buffering / bandwidth
  316. * was not adequate to receive the entire
  317. * packet.
  318. * - 2 = jabber error: the RGMII packet was too large
  319. * and is truncated.
  320. * - 3 = overrun error: the RGMII packet is longer
  321. * than allowed and had an FCS error.
  322. * - 4 = oversize error: the RGMII packet is longer
  323. * than allowed.
  324. * - 5 = alignment error: the RGMII packet is not an
  325. * integer number of bytes
  326. * and had an FCS error (100M and 10M only).
  327. * - 6 = fragment error: the RGMII packet is shorter
  328. * than allowed and had an FCS error.
  329. * - 7 = GMX FCS error: the RGMII packet had an FCS
  330. * error.
  331. * - 8 = undersize error: the RGMII packet is shorter
  332. * than allowed.
  333. * - 9 = extend error: the RGMII packet had an extend
  334. * error.
  335. * - 10 = length mismatch error: the RGMII packet had
  336. * a length that did not match the length field
  337. * in the L2 HDR.
  338. * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
  339. * packet had one or more data reception errors
  340. * (RXERR) or the SPI4 packet had one or more
  341. * DIP4 errors.
  342. * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
  343. * packet was not large enough to cover the
  344. * skipped bytes or the SPI4 packet was
  345. * terminated with an About EOPS.
  346. * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
  347. * RGMII packet had a studder error (data not
  348. * repeated - 10/100M only) or the SPI4 packet
  349. * was sent to an NXA.
  350. * - 16 = FCS error: a SPI4.2 packet had an FCS error.
  351. * - 17 = Skip error: a packet was not large enough to
  352. * cover the skipped bytes.
  353. * - 18 = L2 header malformed: the packet is not long
  354. * enough to contain the L2.
  355. */
  356. uint64_t rcv_error:1;
  357. /*
  358. * lower err_code = first-level descriptor of the
  359. * work
  360. */
  361. /*
  362. * zero for packet submitted by hardware that isn't on
  363. * the slow path
  364. */
  365. /* type is cvmx_pip_err_t (union, so can't use directly */
  366. uint64_t err_code:8;
  367. #else
  368. uint64_t err_code:8;
  369. uint64_t rcv_error:1;
  370. uint64_t not_IP:1;
  371. uint64_t is_mcast:1;
  372. uint64_t is_bcast:1;
  373. uint64_t is_arp:1;
  374. uint64_t is_rarp:1;
  375. uint64_t unassigned3:1;
  376. uint64_t software:1;
  377. uint64_t unassigned2:4;
  378. uint64_t unassigned2a:8;
  379. uint64_t pr:4;
  380. uint64_t vlan_id:12;
  381. uint64_t vlan_cfi:1;
  382. uint64_t unassigned:1;
  383. uint64_t vlan_stacked:1;
  384. uint64_t vlan_valid:1;
  385. uint64_t unused:8;
  386. uint64_t bufs:8;
  387. #endif
  388. } snoip;
  389. } cvmx_pip_wqe_word2;
  390. union cvmx_pip_wqe_word0 {
  391. struct {
  392. #ifdef __BIG_ENDIAN_BITFIELD
  393. /**
  394. * raw chksum result generated by the HW
  395. */
  396. uint16_t hw_chksum;
  397. /**
  398. * Field unused by hardware - available for software
  399. */
  400. uint8_t unused;
  401. /**
  402. * Next pointer used by hardware for list maintenance.
  403. * May be written/read by HW before the work queue
  404. * entry is scheduled to a PP (Only 36 bits used in
  405. * Octeon 1)
  406. */
  407. uint64_t next_ptr:40;
  408. #else
  409. uint64_t next_ptr:40;
  410. uint8_t unused;
  411. uint16_t hw_chksum;
  412. #endif
  413. } cn38xx;
  414. struct {
  415. #ifdef __BIG_ENDIAN_BITFIELD
  416. uint64_t l4ptr:8; /* 56..63 */
  417. uint64_t unused0:8; /* 48..55 */
  418. uint64_t l3ptr:8; /* 40..47 */
  419. uint64_t l2ptr:8; /* 32..39 */
  420. uint64_t unused1:18; /* 14..31 */
  421. uint64_t bpid:6; /* 8..13 */
  422. uint64_t unused2:2; /* 6..7 */
  423. uint64_t pknd:6; /* 0..5 */
  424. #else
  425. uint64_t pknd:6; /* 0..5 */
  426. uint64_t unused2:2; /* 6..7 */
  427. uint64_t bpid:6; /* 8..13 */
  428. uint64_t unused1:18; /* 14..31 */
  429. uint64_t l2ptr:8; /* 32..39 */
  430. uint64_t l3ptr:8; /* 40..47 */
  431. uint64_t unused0:8; /* 48..55 */
  432. uint64_t l4ptr:8; /* 56..63 */
  433. #endif
  434. } cn68xx;
  435. };
  436. union cvmx_wqe_word0 {
  437. uint64_t u64;
  438. union cvmx_pip_wqe_word0 pip;
  439. };
  440. union cvmx_wqe_word1 {
  441. uint64_t u64;
  442. struct {
  443. #ifdef __BIG_ENDIAN_BITFIELD
  444. uint64_t len:16;
  445. uint64_t varies:14;
  446. /**
  447. * the type of the tag (ORDERED, ATOMIC, NULL)
  448. */
  449. uint64_t tag_type:2;
  450. uint64_t tag:32;
  451. #else
  452. uint64_t tag:32;
  453. uint64_t tag_type:2;
  454. uint64_t varies:14;
  455. uint64_t len:16;
  456. #endif
  457. };
  458. struct {
  459. #ifdef __BIG_ENDIAN_BITFIELD
  460. uint64_t len:16;
  461. uint64_t zero_0:1;
  462. /**
  463. * HW sets this to what it thought the priority of
  464. * the input packet was
  465. */
  466. uint64_t qos:3;
  467. uint64_t zero_1:1;
  468. /**
  469. * the group that the work queue entry will be scheduled to
  470. */
  471. uint64_t grp:6;
  472. uint64_t zero_2:3;
  473. uint64_t tag_type:2;
  474. uint64_t tag:32;
  475. #else
  476. uint64_t tag:32;
  477. uint64_t tag_type:2;
  478. uint64_t zero_2:3;
  479. uint64_t grp:6;
  480. uint64_t zero_1:1;
  481. uint64_t qos:3;
  482. uint64_t zero_0:1;
  483. uint64_t len:16;
  484. #endif
  485. } cn68xx;
  486. struct {
  487. #ifdef __BIG_ENDIAN_BITFIELD
  488. /**
  489. * HW sets to the total number of bytes in the packet
  490. */
  491. uint64_t len:16;
  492. /**
  493. * HW sets this to input physical port
  494. */
  495. uint64_t ipprt:6;
  496. /**
  497. * HW sets this to what it thought the priority of
  498. * the input packet was
  499. */
  500. uint64_t qos:3;
  501. /**
  502. * the group that the work queue entry will be scheduled to
  503. */
  504. uint64_t grp:4;
  505. /**
  506. * the type of the tag (ORDERED, ATOMIC, NULL)
  507. */
  508. uint64_t tag_type:3;
  509. /**
  510. * the synchronization/ordering tag
  511. */
  512. uint64_t tag:32;
  513. #else
  514. uint64_t tag:32;
  515. uint64_t tag_type:2;
  516. uint64_t zero_2:1;
  517. uint64_t grp:4;
  518. uint64_t qos:3;
  519. uint64_t ipprt:6;
  520. uint64_t len:16;
  521. #endif
  522. } cn38xx;
  523. };
  524. /**
  525. * Work queue entry format
  526. *
  527. * must be 8-byte aligned
  528. */
  529. struct cvmx_wqe {
  530. /*****************************************************************
  531. * WORD 0
  532. * HW WRITE: the following 64 bits are filled by HW when a packet arrives
  533. */
  534. union cvmx_wqe_word0 word0;
  535. /*****************************************************************
  536. * WORD 1
  537. * HW WRITE: the following 64 bits are filled by HW when a packet arrives
  538. */
  539. union cvmx_wqe_word1 word1;
  540. /**
  541. * WORD 2 HW WRITE: the following 64-bits are filled in by
  542. * hardware when a packet arrives This indicates a variety of
  543. * status and error conditions.
  544. */
  545. cvmx_pip_wqe_word2 word2;
  546. /**
  547. * Pointer to the first segment of the packet.
  548. */
  549. union cvmx_buf_ptr packet_ptr;
  550. /**
  551. * HW WRITE: octeon will fill in a programmable amount from the
  552. * packet, up to (at most, but perhaps less) the amount
  553. * needed to fill the work queue entry to 128 bytes
  554. *
  555. * If the packet is recognized to be IP, the hardware starts
  556. * (except that the IPv4 header is padded for appropriate
  557. * alignment) writing here where the IP header starts. If the
  558. * packet is not recognized to be IP, the hardware starts
  559. * writing the beginning of the packet here.
  560. */
  561. uint8_t packet_data[96];
  562. /**
  563. * If desired, SW can make the work Q entry any length. For the
  564. * purposes of discussion here, Assume 128B always, as this is all that
  565. * the hardware deals with.
  566. *
  567. */
  568. } CVMX_CACHE_LINE_ALIGNED;
  569. static inline int cvmx_wqe_get_port(struct cvmx_wqe *work)
  570. {
  571. int port;
  572. if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
  573. port = work->word2.s_cn68xx.port;
  574. else
  575. port = work->word1.cn38xx.ipprt;
  576. return port;
  577. }
  578. static inline void cvmx_wqe_set_port(struct cvmx_wqe *work, int port)
  579. {
  580. if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
  581. work->word2.s_cn68xx.port = port;
  582. else
  583. work->word1.cn38xx.ipprt = port;
  584. }
  585. static inline int cvmx_wqe_get_grp(struct cvmx_wqe *work)
  586. {
  587. int grp;
  588. if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
  589. grp = work->word1.cn68xx.grp;
  590. else
  591. grp = work->word1.cn38xx.grp;
  592. return grp;
  593. }
  594. static inline void cvmx_wqe_set_grp(struct cvmx_wqe *work, int grp)
  595. {
  596. if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
  597. work->word1.cn68xx.grp = grp;
  598. else
  599. work->word1.cn38xx.grp = grp;
  600. }
  601. static inline int cvmx_wqe_get_qos(struct cvmx_wqe *work)
  602. {
  603. int qos;
  604. if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
  605. qos = work->word1.cn68xx.qos;
  606. else
  607. qos = work->word1.cn38xx.qos;
  608. return qos;
  609. }
  610. static inline void cvmx_wqe_set_qos(struct cvmx_wqe *work, int qos)
  611. {
  612. if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
  613. work->word1.cn68xx.qos = qos;
  614. else
  615. work->word1.cn38xx.qos = qos;
  616. }
  617. #endif /* __CVMX_WQE_H__ */