You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

infiniband.h 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. #ifndef _GPXE_INFINIBAND_H
  2. #define _GPXE_INFINIBAND_H
  3. /** @file
  4. *
  5. * Infiniband protocol
  6. *
  7. */
  8. #include <stdint.h>
  9. #include <gpxe/refcnt.h>
  10. #include <gpxe/device.h>
  11. #include <gpxe/ib_packet.h>
  12. #include <gpxe/ib_mad.h>
  13. /** Subnet administrator QPN */
  14. #define IB_SA_QPN 1
  15. /** Broadcast QPN */
  16. #define IB_BROADCAST_QPN 0xffffffUL
  17. /** Subnet administrator queue key */
  18. #define IB_GLOBAL_QKEY 0x80010000UL
  19. struct ib_device;
  20. struct ib_queue_pair;
  21. struct ib_address_vector;
  22. struct ib_completion_queue;
  23. /** An Infiniband Work Queue */
  24. struct ib_work_queue {
  25. /** Containing queue pair */
  26. struct ib_queue_pair *qp;
  27. /** "Is a send queue" flag */
  28. int is_send;
  29. /** Associated completion queue */
  30. struct ib_completion_queue *cq;
  31. /** List of work queues on this completion queue */
  32. struct list_head list;
  33. /** Number of work queue entries */
  34. unsigned int num_wqes;
  35. /** Number of occupied work queue entries */
  36. unsigned int fill;
  37. /** Next work queue entry index
  38. *
  39. * This is the index of the next entry to be filled (i.e. the
  40. * first empty entry). This value is not bounded by num_wqes;
  41. * users must logical-AND with (num_wqes-1) to generate an
  42. * array index.
  43. */
  44. unsigned long next_idx;
  45. /** I/O buffers assigned to work queue */
  46. struct io_buffer **iobufs;
  47. /** Driver private data */
  48. void *drv_priv;
  49. };
  50. /** An Infiniband multicast GID */
  51. struct ib_multicast_gid {
  52. /** List of multicast GIDs on this QP */
  53. struct list_head list;
  54. /** Multicast GID */
  55. struct ib_gid gid;
  56. };
  57. /** An Infiniband Queue Pair */
  58. struct ib_queue_pair {
  59. /** Containing Infiniband device */
  60. struct ib_device *ibdev;
  61. /** List of queue pairs on this Infiniband device */
  62. struct list_head list;
  63. /** Queue Pair Number */
  64. unsigned long qpn;
  65. /** Queue key */
  66. unsigned long qkey;
  67. /** Send queue */
  68. struct ib_work_queue send;
  69. /** Receive queue */
  70. struct ib_work_queue recv;
  71. /** List of multicast GIDs */
  72. struct list_head mgids;
  73. /** Driver private data */
  74. void *drv_priv;
  75. /** Queue owner private data */
  76. void *owner_priv;
  77. };
  78. /** Infiniband queue pair modification flags */
  79. enum ib_queue_pair_mods {
  80. IB_MODIFY_QKEY = 0x0001,
  81. };
  82. /** An Infiniband Address Vector */
  83. struct ib_address_vector {
  84. /** Queue Pair Number */
  85. unsigned long qpn;
  86. /** Queue key
  87. *
  88. * Not specified for received packets.
  89. */
  90. unsigned long qkey;
  91. /** Local ID */
  92. unsigned int lid;
  93. /** Rate
  94. *
  95. * Not specified for received packets.
  96. */
  97. unsigned int rate;
  98. /** Service level */
  99. unsigned int sl;
  100. /** GID is present */
  101. unsigned int gid_present;
  102. /** GID, if present */
  103. struct ib_gid gid;
  104. };
  105. /** Infiniband completion queue operations */
  106. struct ib_completion_queue_operations {
  107. /**
  108. * Complete Send WQE
  109. *
  110. * @v ibdev Infiniband device
  111. * @v qp Queue pair
  112. * @v iobuf I/O buffer
  113. * @v rc Completion status code
  114. */
  115. void ( * complete_send ) ( struct ib_device *ibdev,
  116. struct ib_queue_pair *qp,
  117. struct io_buffer *iobuf, int rc );
  118. /**
  119. * Complete Receive WQE
  120. *
  121. * @v ibdev Infiniband device
  122. * @v qp Queue pair
  123. * @v av Address vector, or NULL
  124. * @v iobuf I/O buffer
  125. * @v rc Completion status code
  126. */
  127. void ( * complete_recv ) ( struct ib_device *ibdev,
  128. struct ib_queue_pair *qp,
  129. struct ib_address_vector *av,
  130. struct io_buffer *iobuf, int rc );
  131. };
  132. /** An Infiniband Completion Queue */
  133. struct ib_completion_queue {
  134. /** Completion queue number */
  135. unsigned long cqn;
  136. /** Number of completion queue entries */
  137. unsigned int num_cqes;
  138. /** Next completion queue entry index
  139. *
  140. * This is the index of the next entry to be filled (i.e. the
  141. * first empty entry). This value is not bounded by num_wqes;
  142. * users must logical-AND with (num_wqes-1) to generate an
  143. * array index.
  144. */
  145. unsigned long next_idx;
  146. /** List of work queues completing to this queue */
  147. struct list_head work_queues;
  148. /** Completion queue operations */
  149. struct ib_completion_queue_operations *op;
  150. /** Driver private data */
  151. void *drv_priv;
  152. };
  153. /**
  154. * Infiniband device operations
  155. *
  156. * These represent a subset of the Infiniband Verbs.
  157. */
  158. struct ib_device_operations {
  159. /** Create completion queue
  160. *
  161. * @v ibdev Infiniband device
  162. * @v cq Completion queue
  163. * @ret rc Return status code
  164. */
  165. int ( * create_cq ) ( struct ib_device *ibdev,
  166. struct ib_completion_queue *cq );
  167. /** Destroy completion queue
  168. *
  169. * @v ibdev Infiniband device
  170. * @v cq Completion queue
  171. */
  172. void ( * destroy_cq ) ( struct ib_device *ibdev,
  173. struct ib_completion_queue *cq );
  174. /** Create queue pair
  175. *
  176. * @v ibdev Infiniband device
  177. * @v qp Queue pair
  178. * @ret rc Return status code
  179. */
  180. int ( * create_qp ) ( struct ib_device *ibdev,
  181. struct ib_queue_pair *qp );
  182. /** Modify queue pair
  183. *
  184. * @v ibdev Infiniband device
  185. * @v qp Queue pair
  186. * @v mod_list Modification list
  187. * @ret rc Return status code
  188. */
  189. int ( * modify_qp ) ( struct ib_device *ibdev,
  190. struct ib_queue_pair *qp,
  191. unsigned long mod_list );
  192. /** Destroy queue pair
  193. *
  194. * @v ibdev Infiniband device
  195. * @v qp Queue pair
  196. */
  197. void ( * destroy_qp ) ( struct ib_device *ibdev,
  198. struct ib_queue_pair *qp );
  199. /** Post send work queue entry
  200. *
  201. * @v ibdev Infiniband device
  202. * @v qp Queue pair
  203. * @v av Address vector
  204. * @v iobuf I/O buffer
  205. * @ret rc Return status code
  206. *
  207. * If this method returns success, the I/O buffer remains
  208. * owned by the queue pair. If this method returns failure,
  209. * the I/O buffer is immediately released; the failure is
  210. * interpreted as "failure to enqueue buffer".
  211. */
  212. int ( * post_send ) ( struct ib_device *ibdev,
  213. struct ib_queue_pair *qp,
  214. struct ib_address_vector *av,
  215. struct io_buffer *iobuf );
  216. /** Post receive work queue entry
  217. *
  218. * @v ibdev Infiniband device
  219. * @v qp Queue pair
  220. * @v iobuf I/O buffer
  221. * @ret rc Return status code
  222. *
  223. * If this method returns success, the I/O buffer remains
  224. * owned by the queue pair. If this method returns failure,
  225. * the I/O buffer is immediately released; the failure is
  226. * interpreted as "failure to enqueue buffer".
  227. */
  228. int ( * post_recv ) ( struct ib_device *ibdev,
  229. struct ib_queue_pair *qp,
  230. struct io_buffer *iobuf );
  231. /** Poll completion queue
  232. *
  233. * @v ibdev Infiniband device
  234. * @v cq Completion queue
  235. *
  236. * The relevant completion handler (specified at completion
  237. * queue creation time) takes ownership of the I/O buffer.
  238. */
  239. void ( * poll_cq ) ( struct ib_device *ibdev,
  240. struct ib_completion_queue *cq );
  241. /**
  242. * Poll event queue
  243. *
  244. * @v ibdev Infiniband device
  245. */
  246. void ( * poll_eq ) ( struct ib_device *ibdev );
  247. /**
  248. * Open port
  249. *
  250. * @v ibdev Infiniband device
  251. * @ret rc Return status code
  252. */
  253. int ( * open ) ( struct ib_device *ibdev );
  254. /**
  255. * Close port
  256. *
  257. * @v ibdev Infiniband device
  258. */
  259. void ( * close ) ( struct ib_device *ibdev );
  260. /** Attach to multicast group
  261. *
  262. * @v ibdev Infiniband device
  263. * @v qp Queue pair
  264. * @v gid Multicast GID
  265. * @ret rc Return status code
  266. */
  267. int ( * mcast_attach ) ( struct ib_device *ibdev,
  268. struct ib_queue_pair *qp,
  269. struct ib_gid *gid );
  270. /** Detach from multicast group
  271. *
  272. * @v ibdev Infiniband device
  273. * @v qp Queue pair
  274. * @v gid Multicast GID
  275. */
  276. void ( * mcast_detach ) ( struct ib_device *ibdev,
  277. struct ib_queue_pair *qp,
  278. struct ib_gid *gid );
  279. };
  280. /** An Infiniband device */
  281. struct ib_device {
  282. /** Reference counter */
  283. struct refcnt refcnt;
  284. /** List of Infiniband devices */
  285. struct list_head list;
  286. /** Underlying device */
  287. struct device *dev;
  288. /** List of queue pairs */
  289. struct list_head qps;
  290. /** Infiniband operations */
  291. struct ib_device_operations *op;
  292. /** Port number */
  293. unsigned int port;
  294. /** Port state */
  295. uint8_t port_state;
  296. /** Link width */
  297. uint8_t link_width;
  298. /** Link speed */
  299. uint8_t link_speed;
  300. /** Port GID */
  301. struct ib_gid gid;
  302. /** Port LID */
  303. uint16_t lid;
  304. /** Subnet manager LID */
  305. uint16_t sm_lid;
  306. /** Subnet manager SL */
  307. uint8_t sm_sl;
  308. /** Partition key */
  309. uint16_t pkey;
  310. /** Outbound packet sequence number */
  311. uint32_t psn;
  312. /** Driver private data */
  313. void *drv_priv;
  314. /** Owner private data */
  315. void *owner_priv;
  316. };
  317. extern struct ib_completion_queue *
  318. ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
  319. struct ib_completion_queue_operations *op );
  320. extern void ib_destroy_cq ( struct ib_device *ibdev,
  321. struct ib_completion_queue *cq );
  322. extern struct ib_queue_pair *
  323. ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
  324. struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
  325. struct ib_completion_queue *recv_cq, unsigned long qkey );
  326. extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
  327. unsigned long mod_list, unsigned long qkey );
  328. extern void ib_destroy_qp ( struct ib_device *ibdev,
  329. struct ib_queue_pair *qp );
  330. extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
  331. unsigned long qpn );
  332. extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
  333. struct ib_gid *gid );
  334. extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
  335. unsigned long qpn, int is_send );
  336. extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
  337. struct ib_address_vector *av,
  338. struct io_buffer *iobuf );
  339. extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
  340. struct io_buffer *iobuf );
  341. extern void ib_complete_send ( struct ib_device *ibdev,
  342. struct ib_queue_pair *qp,
  343. struct io_buffer *iobuf, int rc );
  344. extern void ib_complete_recv ( struct ib_device *ibdev,
  345. struct ib_queue_pair *qp,
  346. struct ib_address_vector *av,
  347. struct io_buffer *iobuf, int rc );
  348. extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
  349. struct ib_gid *gid );
  350. extern void ib_mcast_detach ( struct ib_device *ibdev,
  351. struct ib_queue_pair *qp, struct ib_gid *gid );
  352. extern struct ib_device * alloc_ibdev ( size_t priv_size );
  353. extern int register_ibdev ( struct ib_device *ibdev );
  354. extern void unregister_ibdev ( struct ib_device *ibdev );
  355. extern void ib_link_state_changed ( struct ib_device *ibdev );
  356. extern struct list_head ib_devices;
  357. /** Iterate over all network devices */
  358. #define for_each_ibdev( ibdev ) \
  359. list_for_each_entry ( (ibdev), &ib_devices, list )
  360. /**
  361. * Poll completion queue
  362. *
  363. * @v ibdev Infiniband device
  364. * @v cq Completion queue
  365. */
  366. static inline __always_inline void
  367. ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) {
  368. ibdev->op->poll_cq ( ibdev, cq );
  369. }
  370. /**
  371. * Open port
  372. *
  373. * @v ibdev Infiniband device
  374. * @ret rc Return status code
  375. */
  376. static inline __always_inline int
  377. ib_open ( struct ib_device *ibdev ) {
  378. return ibdev->op->open ( ibdev );
  379. }
  380. /**
  381. * Close port
  382. *
  383. * @v ibdev Infiniband device
  384. */
  385. static inline __always_inline void
  386. ib_close ( struct ib_device *ibdev ) {
  387. ibdev->op->close ( ibdev );
  388. }
  389. /**
  390. * Check link state
  391. *
  392. * @v ibdev Infiniband device
  393. * @ret link_up Link is up
  394. */
  395. static inline __always_inline int
  396. ib_link_ok ( struct ib_device *ibdev ) {
  397. return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
  398. }
  399. /**
  400. * Get reference to Infiniband device
  401. *
  402. * @v ibdev Infiniband device
  403. * @ret ibdev Infiniband device
  404. */
  405. static inline __always_inline struct ib_device *
  406. ibdev_get ( struct ib_device *ibdev ) {
  407. ref_get ( &ibdev->refcnt );
  408. return ibdev;
  409. }
  410. /**
  411. * Drop reference to Infiniband device
  412. *
  413. * @v ibdev Infiniband device
  414. */
  415. static inline __always_inline void
  416. ibdev_put ( struct ib_device *ibdev ) {
  417. ref_put ( &ibdev->refcnt );
  418. }
  419. /**
  420. * Set Infiniband work queue driver-private data
  421. *
  422. * @v wq Work queue
  423. * @v priv Private data
  424. */
  425. static inline __always_inline void
  426. ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
  427. wq->drv_priv = priv;
  428. }
  429. /**
  430. * Get Infiniband work queue driver-private data
  431. *
  432. * @v wq Work queue
  433. * @ret priv Private data
  434. */
  435. static inline __always_inline void *
  436. ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
  437. return wq->drv_priv;
  438. }
  439. /**
  440. * Set Infiniband queue pair driver-private data
  441. *
  442. * @v qp Queue pair
  443. * @v priv Private data
  444. */
  445. static inline __always_inline void
  446. ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
  447. qp->drv_priv = priv;
  448. }
  449. /**
  450. * Get Infiniband queue pair driver-private data
  451. *
  452. * @v qp Queue pair
  453. * @ret priv Private data
  454. */
  455. static inline __always_inline void *
  456. ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
  457. return qp->drv_priv;
  458. }
  459. /**
  460. * Set Infiniband queue pair owner-private data
  461. *
  462. * @v qp Queue pair
  463. * @v priv Private data
  464. */
  465. static inline __always_inline void
  466. ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
  467. qp->owner_priv = priv;
  468. }
  469. /**
  470. * Get Infiniband queue pair owner-private data
  471. *
  472. * @v qp Queue pair
  473. * @ret priv Private data
  474. */
  475. static inline __always_inline void *
  476. ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
  477. return qp->owner_priv;
  478. }
  479. /**
  480. * Set Infiniband completion queue driver-private data
  481. *
  482. * @v cq Completion queue
  483. * @v priv Private data
  484. */
  485. static inline __always_inline void
  486. ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
  487. cq->drv_priv = priv;
  488. }
  489. /**
  490. * Get Infiniband completion queue driver-private data
  491. *
  492. * @v cq Completion queue
  493. * @ret priv Private data
  494. */
  495. static inline __always_inline void *
  496. ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
  497. return cq->drv_priv;
  498. }
  499. /**
  500. * Set Infiniband device driver-private data
  501. *
  502. * @v ibdev Infiniband device
  503. * @v priv Private data
  504. */
  505. static inline __always_inline void
  506. ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
  507. ibdev->drv_priv = priv;
  508. }
  509. /**
  510. * Get Infiniband device driver-private data
  511. *
  512. * @v ibdev Infiniband device
  513. * @ret priv Private data
  514. */
  515. static inline __always_inline void *
  516. ib_get_drvdata ( struct ib_device *ibdev ) {
  517. return ibdev->drv_priv;
  518. }
  519. /**
  520. * Set Infiniband device owner-private data
  521. *
  522. * @v ibdev Infiniband device
  523. * @v priv Private data
  524. */
  525. static inline __always_inline void
  526. ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
  527. ibdev->owner_priv = priv;
  528. }
  529. /**
  530. * Get Infiniband device owner-private data
  531. *
  532. * @v ibdev Infiniband device
  533. * @ret priv Private data
  534. */
  535. static inline __always_inline void *
  536. ib_get_ownerdata ( struct ib_device *ibdev ) {
  537. return ibdev->owner_priv;
  538. }
  539. #endif /* _GPXE_INFINIBAND_H */