iPXE
flexboot_nodnic.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Mellanox Technologies Ltd.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 */
19
20FILE_LICENCE ( GPL2_OR_LATER );
21
22#include <stdio.h>
23#include <string.h>
24#include <unistd.h>
25#include <errno.h>
26#include <ipxe/pci.h>
27#include <ipxe/malloc.h>
28#include <ipxe/umalloc.h>
29#include <ipxe/if_ether.h>
30#include <ipxe/ethernet.h>
31#include <ipxe/vlan.h>
32#include <ipxe/io.h>
33#include "flexboot_nodnic.h"
42#include <byteswap.h>
43#include <usr/ifmgmt.h>
49
50/***************************************************************************
51 *
52 * Completion queue operations
53 *
54 ***************************************************************************
55 */
57#ifndef DEVICE_CX3
58 mlx_uint32 val32 = 0;
59 union arm_cq_uar cq_uar;
60
61#define ARM_CQ_UAR_CQ_CI_MASK 0xffffff
62#define ARM_CQ_UAR_CMDSN_MASK 3
63#define ARM_CQ_UAR_CMDSN_OFFSET 28
64#define ARM_CQ_UAR_CQ_CI_OFFSET 0x20
65 if ( port->port_priv.device->device_cap.support_bar_cq_ctrl ) {
66 cq_uar.dword[0] = cpu_to_be32((port->eth_cq->next_idx & ARM_CQ_UAR_CQ_CI_MASK) |
68 cq_uar.dword[1] = cpu_to_be32(port->eth_cq->cqn);
69 wmb();
70 writeq(cq_uar.qword, port->port_priv.device->uar.virt + ARM_CQ_UAR_CQ_CI_OFFSET);
71 port->port_priv.arm_cq_doorbell_record->dword[0] = cq_uar.dword[1];
72 port->port_priv.arm_cq_doorbell_record->dword[1] = cq_uar.dword[0];
73 } else {
74 val32 = ( port->eth_cq->next_idx & 0xffffff );
75 if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val32 ) ) {
76 MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
77 return MLX_FAILED;
78 }
79 }
80#else
81 mlx_utils *utils = port->port_priv.device->utils;
82 nodnic_port_data_flow_gw *ptr = port->port_priv.data_flow_gw;
83 mlx_uint32 data = 0;
84 mlx_uint32 val = 0;
85
86 if ( port->port_priv.device->device_cap.crspace_doorbells == 0 ) {
87 val = ( port->eth_cq->next_idx & 0xffff );
88 if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val ) ) {
89 MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
90 return MLX_FAILED;
91 }
92 } else {
93 /* Arming the CQ with CQ CI should be with this format -
94 * 16 bit - CQ CI - same endianness as the FW (don't swap bytes)
95 * 15 bit - reserved
96 * 1 bit - arm CQ - must correct the endianness with the reserved above */
97 data = ( ( ( port->eth_cq->next_idx & 0xffff ) << 16 ) | 0x0080 );
98 /* Write the new index and update FW that new data was submitted */
100 ( mlx_uintn ) & ( ptr->armcq_cq_ci_dword ), 1, &data );
101 }
102#endif
103 return 0;
104}
105
106/**
107 * Create completion queue
108 *
109 * @v ibdev Infiniband device
110 * @v cq Completion queue
111 * @ret rc Return status code
112 */
113static int flexboot_nodnic_create_cq ( struct ib_device *ibdev ,
114 struct ib_completion_queue *cq ) {
117 struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq;
120
121 flexboot_nodnic_cq = (struct flexboot_nodnic_completion_queue *)
122 zalloc(sizeof(*flexboot_nodnic_cq));
123 if ( flexboot_nodnic_cq == NULL ) {
125 goto qp_alloc_err;
126 }
127
128 status = nodnic_port_create_cq(&port->port_priv,
129 cq->num_cqes *
131 &flexboot_nodnic_cq->nodnic_completion_queue
132 );
133 MLX_FATAL_CHECK_STATUS(status, create_err,
134 "nodnic_port_create_cq failed");
136 flexboot_nodnic_cq->nodnic_completion_queue->cq_virt,
137 cq->num_cqes);
139 status = nodnic_port_query(&port->port_priv,
141 (mlx_uint32 *)&cqn );
142 MLX_FATAL_CHECK_STATUS(status, read_cqn_err,
143 "failed to query cqn");
144 cq->cqn = cqn;
145 }
146
147 ib_cq_set_drvdata ( cq, flexboot_nodnic_cq );
148 return status;
149read_cqn_err:
150create_err:
151 free(flexboot_nodnic_cq);
152qp_alloc_err:
153 return status;
154}
155
156/**
157 * Destroy completion queue
158 *
159 * @v ibdev Infiniband device
160 * @v cq Completion queue
161 */
162static void flexboot_nodnic_destroy_cq ( struct ib_device *ibdev ,
163 struct ib_completion_queue *cq ) {
166 struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq = ib_cq_get_drvdata ( cq );
167
168 nodnic_port_destroy_cq(&port->port_priv,
169 flexboot_nodnic_cq->nodnic_completion_queue);
170
171 free(flexboot_nodnic_cq);
172}
173
174static
176 struct ib_completion_queue *cq,
177 unsigned long qpn, int is_send ) {
178 struct ib_work_queue *wq;
179 struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp;
182 struct nodnic_ring *ring;
183 mlx_uint32 out_qpn;
184 list_for_each_entry ( wq, &cq->work_queues, list ) {
185 flexboot_nodnic_qp = ib_qp_get_drvdata ( wq->qp );
186 if( wq->is_send == is_send && wq->is_send == TRUE ) {
187 ring = &flexboot_nodnic_qp->nodnic_queue_pair->send.nodnic_ring;
188 } else if( wq->is_send == is_send && wq->is_send == FALSE ) {
189 ring = &flexboot_nodnic_qp->nodnic_queue_pair->receive.nodnic_ring;
190 } else {
191 continue;
192 }
193 nodnic_port_get_qpn(&port->port_priv, ring, &out_qpn);
194 if ( out_qpn == qpn )
195 return wq;
196 }
197 return NULL;
198}
199
200/**
201 * Handle completion
202 *
203 * @v ibdev Infiniband device
204 * @v cq Completion queue
205 * @v cqe Hardware completion queue entry
206 * @ret rc Return status code
207 */
208static int flexboot_nodnic_complete ( struct ib_device *ibdev,
209 struct ib_completion_queue *cq,
210 struct cqe_data *cqe_data ) {
212 struct ib_work_queue *wq;
213 struct ib_queue_pair *qp;
214 struct io_buffer *iobuf;
215 struct ib_address_vector recv_dest;
216 struct ib_address_vector recv_source;
217 unsigned long qpn;
218 unsigned long wqe_idx;
219 unsigned long wqe_idx_mask;
220 size_t len;
221 int rc = 0;
222
223 /* Parse completion */
224 qpn = cqe_data->qpn;
225
226 if ( cqe_data->is_error == TRUE ) {
227 DBGC ( flexboot_nodnic, "flexboot_nodnic %p CQN %#lx syndrome %x vendor %x\n",
230 rc = -EIO;
231 /* Don't return immediately; propagate error to completer */
232 }
233
234 /* Identify work queue */
235 wq = flexboot_nodnic_find_wq( ibdev, cq, qpn, cqe_data->is_send );
236 if ( wq == NULL ) {
238 "flexboot_nodnic %p CQN %#lx unknown %s QPN %#lx\n",
239 flexboot_nodnic, cq->cqn,
240 ( cqe_data->is_send ? "send" : "recv" ), qpn );
241 return -EIO;
242 }
243 qp = wq->qp;
244
245 /* Identify work queue entry */
246 wqe_idx = cqe_data->wqe_counter;
247 wqe_idx_mask = ( wq->num_wqes - 1 );
249 "NODNIC %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
250 flexboot_nodnic, cq->cqn, qp->qpn,
251 ( cqe_data->is_send ? "send" : "recv" ),
252 wqe_idx );
253
254 /* Identify I/O buffer */
255 iobuf = wq->iobufs[wqe_idx & wqe_idx_mask];
256 if ( iobuf == NULL ) {
258 "NODNIC %p CQN %#lx QPN %#lx empty %s WQE %#lx\n",
259 flexboot_nodnic, cq->cqn, qp->qpn,
260 ( cqe_data->is_send ? "send" : "recv" ), wqe_idx );
261 return -EIO;
262 }
263 wq->iobufs[wqe_idx & wqe_idx_mask] = NULL;
264
265 if ( cqe_data->is_send == TRUE ) {
266 /* Hand off to completion handler */
267 ib_complete_send ( ibdev, qp, iobuf, rc );
268 } else if ( rc != 0 ) {
269 /* Propagate error to receive completion handler */
270 ib_complete_recv ( ibdev, qp, NULL, NULL, iobuf, rc );
271 } else {
272 /* Set received length */
274 assert ( len <= iob_tailroom ( iobuf ) );
275 iob_put ( iobuf, len );
276 memset ( &recv_dest, 0, sizeof ( recv_dest ) );
277 recv_dest.qpn = qpn;
278 memset ( &recv_source, 0, sizeof ( recv_source ) );
279 switch ( qp->type ) {
280 case IB_QPT_SMI:
281 case IB_QPT_GSI:
282 case IB_QPT_UD:
283 case IB_QPT_RC:
284 break;
285 case IB_QPT_ETH:
286 break;
287 default:
288 assert ( 0 );
289 return -EINVAL;
290 }
291 /* Hand off to completion handler */
292 ib_complete_recv ( ibdev, qp, &recv_dest,
293 &recv_source, iobuf, rc );
294 }
295
296 return rc;
297}
298/**
299 * Poll completion queue
300 *
301 * @v ibdev Infiniband device
302 * @v cq Completion queues
303 */
304static void flexboot_nodnic_poll_cq ( struct ib_device *ibdev,
305 struct ib_completion_queue *cq) {
307 struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq = ib_cq_get_drvdata ( cq );
308 void *cqe;
309 mlx_size cqe_size;
310 struct cqe_data cqe_data;
311 unsigned int cqe_idx_mask;
312 int rc;
313
315 while ( TRUE ) {
316 /* Look for completion entry */
317 cqe_idx_mask = ( cq->num_cqes - 1 );
318 cqe = ((uint8_t *)flexboot_nodnic_cq->nodnic_completion_queue->cq_virt) +
319 cqe_size * (cq->next_idx & cqe_idx_mask);
320
321 /* TODO: check fill_completion */
323 if ( cqe_data.owner ^
324 ( ( cq->next_idx & cq->num_cqes ) ? 1 : 0 ) ) {
325 /* Entry still owned by hardware; end of poll */
326 break;
327 }
328 /* Handle completion */
329 rc = flexboot_nodnic_complete ( ibdev, cq, &cqe_data );
330 if ( rc != 0 ) {
331 DBGC ( flexboot_nodnic, "flexboot_nodnic %p CQN %#lx failed to complete: %s\n",
332 flexboot_nodnic, cq->cqn, strerror ( rc ) );
333 DBGC_HDA ( flexboot_nodnic, virt_to_phys ( cqe ),
334 cqe, sizeof ( *cqe ) );
335 }
336
337 /* Update completion queue's index */
338 cq->next_idx++;
339 }
340}
341/***************************************************************************
342 *
343 * Queue pair operations
344 *
345 ***************************************************************************
346 */
347
348
349/**
350 * Create queue pair
351 *
352 * @v ibdev Infiniband device
353 * @v qp Queue pair
354 * @ret rc Return status code
355 */
356static int flexboot_nodnic_create_qp ( struct ib_device *ibdev,
357 struct ib_queue_pair *qp ) {
360 struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp;
362
363 flexboot_nodnic_qp = (struct flexboot_nodnic_queue_pair *)zalloc(sizeof(*flexboot_nodnic_qp));
364 if ( flexboot_nodnic_qp == NULL ) {
366 goto qp_alloc_err;
367 }
368
369 status = nodnic_port_create_qp(&port->port_priv,
371 qp->send.num_wqes * sizeof(struct nodnic_send_wqbb),
372 qp->send.num_wqes,
373 qp->recv.num_wqes * sizeof(struct nodnic_recv_wqe),
374 qp->recv.num_wqes,
375 &flexboot_nodnic_qp->nodnic_queue_pair);
376 MLX_FATAL_CHECK_STATUS(status, create_err,
377 "nodnic_port_create_qp failed");
378 ib_qp_set_drvdata ( qp, flexboot_nodnic_qp );
379 return status;
380create_err:
381 free(flexboot_nodnic_qp);
382qp_alloc_err:
383 return status;
384}
385
386/**
387 * Modify queue pair
388 *
389 * @v ibdev Infiniband device
390 * @v qp Queue pair
391 * @ret rc Return status code
392 */
394 struct ib_queue_pair *qp __unused) {
395 /*not needed*/
396 return 0;
397}
398
399/**
400 * Destroy queue pair
401 *
402 * @v ibdev Infiniband device
403 * @v qp Queue pair
404 */
405static void flexboot_nodnic_destroy_qp ( struct ib_device *ibdev,
406 struct ib_queue_pair *qp ) {
409 struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
410
411 nodnic_port_destroy_qp(&port->port_priv,
413 flexboot_nodnic_qp->nodnic_queue_pair);
414
415 free(flexboot_nodnic_qp);
416}
417
418/***************************************************************************
419 *
420 * Work request operations
421 *
422 ***************************************************************************
423 */
424
425/**
426 * Post send work queue entry
427 *
428 * @v ibdev Infiniband device
429 * @v qp Queue pair
430 * @v av Address vector
431 * @v iobuf I/O buffer
432 * @ret rc Return status code
433 */
434static int flexboot_nodnic_post_send ( struct ib_device *ibdev,
435 struct ib_queue_pair *qp,
436 struct ib_address_vector *av,
437 struct io_buffer *iobuf) {
438
440 struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
442 struct ib_work_queue *wq = &qp->send;
443 struct nodnic_send_wqbb *wqbb;
444 nodnic_qp *nodnic_qp = flexboot_nodnic_qp->nodnic_queue_pair;
445 struct nodnic_send_ring *send_ring = &nodnic_qp->send;
447 unsigned int wqe_idx_mask;
448 unsigned long wqe_idx;
449
450 if ( ( port->port_priv.dma_state == FALSE ) ||
451 ( port->port_priv.port_state & NODNIC_PORT_DISABLING_DMA ) ) {
452 DBGC ( flexboot_nodnic, "flexboot_nodnic DMA disabled\n");
453 status = -ENETDOWN;
454 goto post_send_done;
455 }
456
457 /* Allocate work queue entry */
458 wqe_idx = wq->next_idx;
459 wqe_idx_mask = ( wq->num_wqes - 1 );
460 if ( wq->iobufs[wqe_idx & wqe_idx_mask] ) {
461 DBGC ( flexboot_nodnic, "flexboot_nodnic %p QPN %#lx send queue full\n",
462 flexboot_nodnic, qp->qpn );
463 status = -ENOBUFS;
464 goto post_send_done;
465 }
466 wqbb = &send_ring->wqe_virt[wqe_idx & wqe_idx_mask];
467 wq->iobufs[wqe_idx & wqe_idx_mask] = iobuf;
468
470 fill_send_wqe[qp->type] != NULL );
472 fill_send_wqe[qp->type] ( ibdev, qp, av, iobuf,
473 wqbb, wqe_idx );
474 if ( status != 0 ) {
475 DBGC ( flexboot_nodnic, "flexboot_nodnic %p QPN %#lx fill send wqe failed\n",
476 flexboot_nodnic, qp->qpn );
477 goto post_send_done;
478 }
479
480 wq->next_idx++;
481
482 status = port->port_priv.send_doorbell ( &port->port_priv,
483 &send_ring->nodnic_ring, ( mlx_uint16 ) wq->next_idx );
486 }
487 if ( status != 0 ) {
488 DBGC ( flexboot_nodnic, "flexboot_nodnic %p ring send doorbell failed\n", flexboot_nodnic );
489 }
490
491post_send_done:
492 return status;
493}
494
495/**
496 * Post receive work queue entry
497 *
498 * @v ibdev Infiniband device
499 * @v qp Queue pair
500 * @v iobuf I/O buffer
501 * @ret rc Return status code
502 */
503static int flexboot_nodnic_post_recv ( struct ib_device *ibdev,
504 struct ib_queue_pair *qp,
505 struct io_buffer *iobuf ) {
507 struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
509 struct ib_work_queue *wq = &qp->recv;
510 nodnic_qp *nodnic_qp = flexboot_nodnic_qp->nodnic_queue_pair;
511 struct nodnic_recv_ring *recv_ring = &nodnic_qp->receive;
512 struct nodnic_recv_wqe *wqe;
513 unsigned int wqe_idx_mask;
515
516 /* Allocate work queue entry */
517 wqe_idx_mask = ( wq->num_wqes - 1 );
518 if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
520 "flexboot_nodnic %p QPN %#lx receive queue full\n",
521 flexboot_nodnic, qp->qpn );
522 status = -ENOBUFS;
523 goto post_recv_done;
524 }
525 wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
526 wqe = &((struct nodnic_recv_wqe*)recv_ring->wqe_virt)[wq->next_idx & wqe_idx_mask];
527
528 MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
529 MLX_FILL_1 ( &wqe->data[0], 1, l_key, flexboot_nodnic->device_priv.lkey );
530 MLX_FILL_H ( &wqe->data[0], 2,
531 local_address_h, virt_to_bus ( iobuf->data ) );
532 MLX_FILL_1 ( &wqe->data[0], 3,
533 local_address_l, virt_to_bus ( iobuf->data ) );
534
535 wq->next_idx++;
536
537 status = port->port_priv.recv_doorbell ( &port->port_priv,
538 &recv_ring->nodnic_ring, ( mlx_uint16 ) wq->next_idx );
539 if ( status != 0 ) {
540 DBGC ( flexboot_nodnic, "flexboot_nodnic %p ring receive doorbell failed\n", flexboot_nodnic );
541 }
542post_recv_done:
543 return status;
544}
545
546/***************************************************************************
547 *
548 * Event queues
549 *
550 ***************************************************************************
551 */
552
553static void flexboot_nodnic_poll_eq ( struct ib_device *ibdev ) {
556 struct net_device *netdev;
559
560 if ( ! ibdev ) {
561 DBG ( "%s: ibdev = NULL!!!\n", __FUNCTION__ );
562 return;
563 }
564
566 port = &flexboot_nodnic->port[ibdev->port - 1];
567 netdev = port->netdev;
568
569 if ( ! netdev_is_open ( netdev ) ) {
570 DBG2( "%s: port %d is closed\n", __FUNCTION__, port->ibdev->port );
571 return;
572 }
573
574 /* we don't poll EQ. Just poll link status if it's not active */
575 if ( ! netdev_link_ok ( netdev ) ) {
576 status = nodnic_port_get_state ( &port->port_priv, &state );
577 MLX_FATAL_CHECK_STATUS(status, state_err, "nodnic_port_get_state failed");
578
580 DBG( "%s: port %d physical link is up\n", __FUNCTION__,
581 port->ibdev->port );
582 port->type->state_change ( flexboot_nodnic, port, 1 );
583 }
584 }
585state_err:
586 return;
587}
588
589/***************************************************************************
590 *
591 * Multicast group operations
592 *
593 ***************************************************************************
594 */
595static int flexboot_nodnic_mcast_attach ( struct ib_device *ibdev,
596 struct ib_queue_pair *qp,
597 union ib_gid *gid) {
602
603 switch (qp->type) {
604 case IB_QPT_ETH:
605 memcpy(&mac, gid, sizeof(mac));
608 "nodnic_port_add_mac_filter failed");
609 break;
610 default:
611 break;
612 }
613mac_err:
614 return status;
615}
617 struct ib_queue_pair *qp,
618 union ib_gid *gid ) {
623
624 switch (qp->type) {
625 case IB_QPT_ETH:
626 memcpy(&mac, gid, sizeof(mac));
629 "nodnic_port_remove_mac_filter failed");
630 break;
631 default:
632 break;
633 }
634mac_err:
635 return;
636}
637/***************************************************************************
638 *
639 * Infiniband link-layer operations
640 *
641 ***************************************************************************
642 */
643
644/**
645 * Initialise Infiniband link
646 *
647 * @v ibdev Infiniband device
648 * @ret rc Return status code
649 */
651 int rc = 0;
652
653 /*TODO: add implementation*/
654 return rc;
655}
656
657/**
658 * Close Infiniband link
659 *
660 * @v ibdev Infiniband device
661 */
663 /*TODO: add implementation*/
664}
665
666/**
667 * Inform embedded subnet management agent of a received MAD
668 *
669 * @v ibdev Infiniband device
670 * @v mad MAD
671 * @ret rc Return status code
672 */
674 union ib_mad *mad __unused) {
675 /*TODO: add implementation*/
676 return 0;
677}
678
679/** flexboot_nodnic Infiniband operations */
681 .create_cq = flexboot_nodnic_create_cq,
682 .destroy_cq = flexboot_nodnic_destroy_cq,
683 .create_qp = flexboot_nodnic_create_qp,
684 .modify_qp = flexboot_nodnic_modify_qp,
685 .destroy_qp = flexboot_nodnic_destroy_qp,
686 .post_send = flexboot_nodnic_post_send,
687 .post_recv = flexboot_nodnic_post_recv,
688 .poll_cq = flexboot_nodnic_poll_cq,
689 .poll_eq = flexboot_nodnic_poll_eq,
692 .mcast_attach = flexboot_nodnic_mcast_attach,
693 .mcast_detach = flexboot_nodnic_mcast_detach,
694 .set_port_info = flexboot_nodnic_inform_sma,
695 .set_pkey_table = flexboot_nodnic_inform_sma,
696};
697/***************************************************************************
698 *
699 *
700 *
701 ***************************************************************************
702 */
703
704#define FLEX_NODNIC_TX_POLL_TOUT 500000
705#define FLEX_NODNIC_TX_POLL_USLEEP 10
706
708 struct ib_device *ibdev = port->ibdev;
709 struct ib_completion_queue *cq;
710 struct ib_work_queue *wq;
711 int keep_polling = 0;
713
714 list_for_each_entry ( cq, &ibdev->cqs, list ) {
715 do {
716 ib_poll_cq ( ibdev, cq );
717 keep_polling = 0;
719 if ( wq->is_send )
720 keep_polling += ( wq->fill > 0 );
721 }
723 } while ( keep_polling && ( timeout-- > 0 ) );
724 }
725}
726
728 nodnic_port_priv *port_priv = & ( port->port_priv );
730
731 if ( ! ( port_priv->port_state & NODNIC_PORT_OPENED ) )
732 return;
733
736 if ( ( status = nodnic_port_disable_dma ( port_priv ) ) ) {
737 MLX_DEBUG_WARN ( port, "Failed to disable DMA %d\n", status );
738 }
739
741}
742
743/***************************************************************************
744 *
745 * Ethernet operation
746 *
747 ***************************************************************************
748 */
749
750/** Number of flexboot_nodnic Ethernet send work queue entries */
751#define FLEXBOOT_NODNIC_ETH_NUM_SEND_WQES 64
752
753/** Number of flexboot_nodnic Ethernet receive work queue entries */
754#define FLEXBOOT_NODNIC_ETH_NUM_RECV_WQES 64
755/** flexboot nodnic Ethernet queue pair operations */
757 .alloc_iob = alloc_iob,
758};
759
760/**
761 * Transmit packet via flexboot_nodnic Ethernet device
762 *
763 * @v netdev Network device
764 * @v iobuf I/O buffer
765 * @ret rc Return status code
766 */
768 struct io_buffer *iobuf) {
769 struct flexboot_nodnic_port *port = netdev->priv;
770 struct ib_device *ibdev = port->ibdev;
772 int rc;
773
774 rc = ib_post_send ( ibdev, port->eth_qp, NULL, iobuf);
775 /* Transmit packet */
776 if ( rc != 0) {
777 DBGC ( flexboot_nodnic, "NODNIC %p port %d could not transmit: %s\n",
778 flexboot_nodnic, ibdev->port, strerror ( rc ) );
779 return rc;
780 }
781
782 return 0;
783}
784
785/**
786 * Handle flexboot_nodnic Ethernet device send completion
787 *
788 * @v ibdev Infiniband device
789 * @v qp Queue pair
790 * @v iobuf I/O buffer
791 * @v rc Completion status code
792 */
794 struct ib_queue_pair *qp,
795 struct io_buffer *iobuf,
796 int rc) {
798
799 netdev_tx_complete_err ( netdev, iobuf, rc );
800}
801
802/**
803 * Handle flexboot_nodnic Ethernet device receive completion
804 *
805 * @v ibdev Infiniband device
806 * @v qp Queue pair
807 * @v av Address vector, or NULL
808 * @v iobuf I/O buffer
809 * @v rc Completion status code
810 */
812 struct ib_queue_pair *qp,
814 struct ib_address_vector *source,
815 struct io_buffer *iobuf,
816 int rc) {
818
819 if ( rc != 0 ) {
820 DBG ( "Received packet with error\n" );
821 netdev_rx_err ( netdev, iobuf, rc );
822 return;
823 }
824
825 if ( source == NULL ) {
826 DBG ( "Received packet without address vector\n" );
827 netdev_rx_err ( netdev, iobuf, -ENOTTY );
828 return;
829 }
830
831 netdev_rx ( netdev, iobuf );
832}
833
834/** flexboot_nodnic Ethernet device completion operations */
839
840/**
841 * Poll flexboot_nodnic Ethernet device
842 *
843 * @v netdev Network device
844 */
846 struct flexboot_nodnic_port *port = netdev->priv;
847 struct ib_device *ibdev = port->ibdev;
848
849 ib_poll_eq ( ibdev );
850}
851
852/**
853 * Open flexboot_nodnic Ethernet device
854 *
855 * @v netdev Network device
856 * @ret rc Return status code
857 */
859 struct flexboot_nodnic_port *port = netdev->priv;
860 struct ib_device *ibdev = port->ibdev;
863 struct ib_completion_queue *dummy_cq = NULL;
864 struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = NULL;
865 mlx_uint64 cq_size = 0;
866 mlx_uint32 qpn = 0;
868 int rc;
869
870 if ( port->port_priv.port_state & NODNIC_PORT_OPENED ) {
871 DBGC ( flexboot_nodnic, "%s: port %d is already opened\n",
872 __FUNCTION__, port->ibdev->port );
873 return 0;
874 }
875
876 port->port_priv.port_state |= NODNIC_PORT_OPENED;
877
878 dummy_cq = zalloc ( sizeof ( struct ib_completion_queue ) );
879 if ( dummy_cq == NULL ) {
880 DBGC ( flexboot_nodnic, "%s: Failed to allocate dummy CQ\n", __FUNCTION__ );
882 goto err_create_dummy_cq;
883 }
884 INIT_LIST_HEAD ( &dummy_cq->work_queues );
885
886 if ( ( rc = ib_create_qp ( ibdev, IB_QPT_ETH,
890 &port->eth_qp ) ) != 0 ) {
891 DBGC ( flexboot_nodnic, "flexboot_nodnic %p port %d could not create queue pair\n",
892 flexboot_nodnic, ibdev->port );
894 goto err_create_qp;
895 }
896
897 ib_qp_set_ownerdata ( port->eth_qp, netdev );
898
899 status = nodnic_port_get_cq_size(&port->port_priv, &cq_size);
900 MLX_FATAL_CHECK_STATUS(status, get_cq_size_err,
901 "nodnic_port_get_cq_size failed");
902
903 if ( ( rc = ib_create_cq ( ibdev, cq_size, &flexboot_nodnic_eth_cq_op,
904 &port->eth_cq ) ) != 0 ) {
906 "flexboot_nodnic %p port %d could not create completion queue\n",
907 flexboot_nodnic, ibdev->port );
909 goto err_create_cq;
910 }
911 port->eth_qp->send.cq = port->eth_cq;
912 list_del(&port->eth_qp->send.list);
913 list_add ( &port->eth_qp->send.list, &port->eth_cq->work_queues );
914 port->eth_qp->recv.cq = port->eth_cq;
915 port->cmdsn = 0;
916 list_del(&port->eth_qp->recv.list);
917 list_add ( &port->eth_qp->recv.list, &port->eth_cq->work_queues );
918
919 status = nodnic_port_allocate_eq(&port->port_priv,
921 MLX_FATAL_CHECK_STATUS(status, eq_alloc_err,
922 "nodnic_port_allocate_eq failed");
923
924 status = nodnic_port_init(&port->port_priv);
926 "nodnic_port_init failed");
927
928 /* update qp - qpn */
929 flexboot_nodnic_qp = ib_qp_get_drvdata ( port->eth_qp );
930 status = nodnic_port_get_qpn(&port->port_priv,
931 &flexboot_nodnic_qp->nodnic_queue_pair->send.nodnic_ring,
932 &qpn);
934 "nodnic_port_get_qpn failed");
935 port->eth_qp->qpn = qpn;
936
937 /* Fill receive rings */
938 ib_refill_recv ( ibdev, port->eth_qp );
939
940 status = nodnic_port_enable_dma(&port->port_priv);
942 "nodnic_port_enable_dma failed");
943
945 status = nodnic_port_set_promisc(&port->port_priv, TRUE);
946 MLX_FATAL_CHECK_STATUS(status, promisc_err,
947 "nodnic_port_set_promisc failed");
948 }
949
950 status = nodnic_port_get_state(&port->port_priv, &state);
952 "nodnic_port_get_state failed");
953
954 port->type->state_change (
956
957 DBGC ( flexboot_nodnic, "%s: port %d opened (link is %s)\n",
958 __FUNCTION__, port->ibdev->port,
959 ( ( state == nodnic_port_state_active ) ? "Up" : "Down" ) );
960
961 free(dummy_cq);
962 return 0;
963state_err:
964promisc_err:
965dma_err:
966qpn_err:
967 nodnic_port_close(&port->port_priv);
968init_err:
969 nodnic_port_free_eq(&port->port_priv);
970eq_alloc_err:
971err_create_cq:
972get_cq_size_err:
973 ib_destroy_qp(ibdev, port->eth_qp );
974err_create_qp:
975 free(dummy_cq);
976err_create_dummy_cq:
977 port->port_priv.port_state &= ~NODNIC_PORT_OPENED;
978 return status;
979}
980
981/**
982 * Close flexboot_nodnic Ethernet device
983 *
984 * @v netdev Network device
985 */
987 struct flexboot_nodnic_port *port = netdev->priv;
988 struct ib_device *ibdev = port->ibdev;
991
992 if ( ! ( port->port_priv.port_state & NODNIC_PORT_OPENED ) ) {
993 DBGC ( flexboot_nodnic, "%s: port %d is already closed\n",
994 __FUNCTION__, port->ibdev->port );
995 return;
996 }
997
999 if ( ( status = nodnic_port_set_promisc( &port->port_priv, FALSE ) ) ) {
1001 "nodnic_port_set_promisc failed (status = %d)\n", status );
1002 }
1003 }
1004
1006
1007 port->port_priv.port_state &= ~NODNIC_PORT_OPENED;
1008
1009 port->type->state_change ( flexboot_nodnic, port, FALSE );
1010
1011 /* Close port */
1012 status = nodnic_port_close(&port->port_priv);
1013 if ( status != MLX_SUCCESS ) {
1014 DBGC ( flexboot_nodnic, "flexboot_nodnic %p port %d could not close port: %s\n",
1015 flexboot_nodnic, ibdev->port, strerror ( status ) );
1016 /* Nothing we can do about this */
1017 }
1018
1019 ib_destroy_qp ( ibdev, port->eth_qp );
1020 port->eth_qp = NULL;
1021 ib_destroy_cq ( ibdev, port->eth_cq );
1022 port->eth_cq = NULL;
1023
1024 nodnic_port_free_eq(&port->port_priv);
1025
1026 DBGC ( flexboot_nodnic, "%s: port %d closed\n", __FUNCTION__, port->ibdev->port );
1027}
1028
1029void flexboot_nodnic_eth_irq ( struct net_device *netdev, int enable ) {
1030 struct flexboot_nodnic_port *port = netdev->priv;
1031
1032 if ( enable ) {
1033 if ( ( port->port_priv.port_state & NODNIC_PORT_OPENED ) &&
1034 ! ( port->port_priv.port_state & NODNIC_PORT_DISABLING_DMA ) ) {
1036 } else {
1037 /* do nothing */
1038 }
1039 } else {
1040 nodnic_device_clear_int( port->port_priv.device );
1041 }
1042}
1043
1044/** flexboot_nodnic Ethernet network device operations */
1051
1052/**
1053 * Register flexboot_nodnic Ethernet device
1054 */
1056 struct flexboot_nodnic_port *port) {
1058 struct net_device *netdev;
1059 struct ib_device *ibdev = port->ibdev;
1060 union {
1061 uint8_t bytes[8];
1062 uint32_t dwords[2];
1063 } mac;
1064
1065 /* Allocate network devices */
1066 netdev = alloc_etherdev ( 0 );
1067 if ( netdev == NULL ) {
1068 DBGC ( flexboot_nodnic, "flexboot_nodnic %p port %d could not allocate net device\n",
1069 flexboot_nodnic, ibdev->port );
1071 goto alloc_err;
1072 }
1073 port->netdev = netdev;
1075 netdev->dev = ibdev->dev;
1076 netdev->priv = port;
1077
1078 status = nodnic_port_query(&port->port_priv,
1080 &mac.dwords[0]);
1082 "failed to query mac high");
1083 status = nodnic_port_query(&port->port_priv,
1085 &mac.dwords[1]);
1087 "failed to query mac low");
1088 mac.dwords[0] = htonl(mac.dwords[0]);
1089 mac.dwords[1] = htonl(mac.dwords[1]);
1090 memcpy ( netdev->hw_addr,
1091 &mac.bytes[2], ETH_ALEN);
1092 /* Register network device */
1094 if ( status != MLX_SUCCESS ) {
1096 "flexboot_nodnic %p port %d could not register network device: %s\n",
1097 flexboot_nodnic, ibdev->port, strerror ( status ) );
1098 goto reg_err;
1099 }
1100 return status;
1101reg_err:
1102mac_err:
1103 netdev_put ( netdev );
1104alloc_err:
1105 return status;
1106}
1107
1108/**
1109 * Handle flexboot_nodnic Ethernet device port state change
1110 */
1112 struct flexboot_nodnic_port *port,
1113 int link_up ) {
1114 struct net_device *netdev = port->netdev;
1115
1116 if ( link_up )
1118 else
1120
1121}
1122
1123/**
1124 * Unregister flexboot_nodnic Ethernet device
1125 */
1133
1134/** flexboot_nodnic Ethernet port type */
1140
1141/***************************************************************************
1142 *
1143 * PCI interface helper functions
1144 *
1145 ***************************************************************************
1146 */
1147static
1151 nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
1152 struct pci_device *pci = flexboot_nodnic_priv->pci;
1153 struct ib_device *ibdev = NULL;
1154 unsigned int i = 0;
1155
1156 /* Allocate Infiniband devices */
1157 for (; i < device_priv->device_cap.num_ports; i++) {
1158 if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
1159 continue;
1160 ibdev = alloc_ibdev(0);
1161 if (ibdev == NULL) {
1163 goto err_alloc_ibdev;
1164 }
1165 flexboot_nodnic_priv->port[i].ibdev = ibdev;
1167 ibdev->dev = &pci->dev;
1168 ibdev->port = ( FLEXBOOT_NODNIC_PORT_BASE + i);
1169 ibdev->ports = device_priv->device_cap.num_ports;
1170 ib_set_drvdata(ibdev, flexboot_nodnic_priv);
1171 }
1172 return status;
1173err_alloc_ibdev:
1174 for ( i-- ; ( signed int ) i >= 0 ; i-- )
1175 ibdev_put ( flexboot_nodnic_priv->port[i].ibdev );
1176 return status;
1177}
1178
1179static
1181flexboot_nodnic_thin_init_ports( struct flexboot_nodnic *flexboot_nodnic_priv ) {
1183 nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
1184 nodnic_port_priv *port_priv = NULL;
1185 unsigned int i = 0;
1186
1187 for ( i = 0; i < device_priv->device_cap.num_ports; i++ ) {
1188 if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
1189 continue;
1190 port_priv = &flexboot_nodnic_priv->port[i].port_priv;
1191 status = nodnic_port_thin_init( device_priv, port_priv, i );
1192 MLX_FATAL_CHECK_STATUS(status, thin_init_err,
1193 "flexboot_nodnic_thin_init_ports failed");
1194 }
1195thin_init_err:
1196 return status;
1197}
1198
1199
1200static
1202flexboot_nodnic_set_ports_type ( struct flexboot_nodnic *flexboot_nodnic_priv ) {
1204 nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
1205 nodnic_port_priv *port_priv = NULL;
1207 unsigned int i = 0;
1208
1209 for ( i = 0 ; i < device_priv->device_cap.num_ports ; i++ ) {
1210 if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
1211 continue;
1212 port_priv = &flexboot_nodnic_priv->port[i].port_priv;
1213 status = nodnic_port_get_type(port_priv, &type);
1215 "nodnic_port_get_type failed");
1216 switch ( type ) {
1218 DBGC ( flexboot_nodnic_priv, "Port %d type is Ethernet\n", i );
1219 flexboot_nodnic_priv->port[i].type = &flexboot_nodnic_port_type_eth;
1220 break;
1222 DBGC ( flexboot_nodnic_priv, "Port %d type is Infiniband\n", i );
1224 goto type_err;
1225 default:
1226 DBGC ( flexboot_nodnic_priv, "Port %d type is unknown\n", i );
1228 goto type_err;
1229 }
1230 }
1231type_err:
1232 return status;
1233}
1234
1235static
1239 nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
1240 struct flexboot_nodnic_port *port = NULL;
1241 unsigned int i = 0;
1242
1243 for (; i < device_priv->device_cap.num_ports; i++) {
1244 if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
1245 continue;
1246 port = &flexboot_nodnic_priv->port[i];
1247 status = port->type->register_dev ( flexboot_nodnic_priv, port );
1249 "port register_dev failed");
1250 }
1251reg_err:
1252 return status;
1253}
1254
1255static
1258 struct flexboot_nodnic_port *port;
1259 nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
1260 int i = (device_priv->device_cap.num_ports - 1);
1261
1262 for (; i >= 0; i--) {
1263 if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
1264 continue;
1265 port = &flexboot_nodnic_priv->port[i];
1266 port->type->unregister_dev(flexboot_nodnic_priv, port);
1267 ibdev_put(flexboot_nodnic_priv->port[i].ibdev);
1268 }
1269 return MLX_SUCCESS;
1270}
1271
1272/***************************************************************************
1273 *
1274 * flexboot nodnic interface
1275 *
1276 ***************************************************************************
1277 */
1281 int i;
1282
1283 for ( i = 0; i < nodnic->device_priv.device_cap.num_ports; i++ ) {
1284 if ( ! ( nodnic->port_mask & ( i + 1 ) ) )
1285 continue;
1286 port_priv = & ( nodnic->port[i].port_priv );
1288 continue;
1289
1290 if ( ( status = nodnic_port_enable_dma ( port_priv ) ) ) {
1291 MLX_DEBUG_WARN ( nodnic, "Failed to enable DMA %d\n", status );
1292 }
1293 }
1294}
1295
1297 int i;
1298
1299 for ( i = 0; i < nodnic->device_priv.device_cap.num_ports; i++ ) {
1300 if ( ! ( nodnic->port_mask & ( i + 1 ) ) )
1301 continue;
1302 flexboot_nodnic_port_disable_dma ( & ( nodnic->port[i] ) );
1303 }
1304}
1305
1307 mlx_utils utils;
1310 int is_supported = 0;
1311
1312 DBG ( "%s: start\n", __FUNCTION__ );
1313
1314 memset ( &utils, 0, sizeof ( utils ) );
1315
1316 status = mlx_utils_init ( &utils, pci );
1317 MLX_CHECK_STATUS ( pci, status, utils_init_err, "mlx_utils_init failed" );
1318
1319 status = mlx_pci_gw_init ( &utils );
1320 MLX_CHECK_STATUS ( pci, status, pci_gw_init_err, "mlx_pci_gw_init failed" );
1321
1324
1325 if ( status == MLX_SUCCESS ) {
1327 is_supported = ( buffer & 0x1 );
1328 }
1329
1330 mlx_pci_gw_teardown( &utils );
1331
1332pci_gw_init_err:
1333 mlx_utils_teardown(&utils);
1334utils_init_err:
1335 DBG ( "%s: NODNIC is %s supported (status = %d)\n",
1336 __FUNCTION__, ( is_supported ? "": "not" ), status );
1337 return is_supported;
1338}
1339
1340
1341void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
1342 uint16_t high_byte ) {
1343 union mac_addr {
1344 struct {
1345 uint32_t low_byte;
1346 uint16_t high_byte;
1347 };
1348 uint8_t mac_addr[ETH_ALEN];
1349 } mac_addr_aux;
1350
1351 mac_addr_aux.high_byte = high_byte;
1352 mac_addr_aux.low_byte = low_byte;
1353
1354 mac_addr[0] = mac_addr_aux.mac_addr[5];
1355 mac_addr[1] = mac_addr_aux.mac_addr[4];
1356 mac_addr[2] = mac_addr_aux.mac_addr[3];
1357 mac_addr[3] = mac_addr_aux.mac_addr[2];
1358 mac_addr[4] = mac_addr_aux.mac_addr[1];
1359 mac_addr[5] = mac_addr_aux.mac_addr[0];
1360}
1361
1363 struct flexboot_nodnic *flexboot_nodnic_priv, uint8_t port __unused ) {
1364 struct mlx_vmac_query_virt_mac virt_mac;
1366
1367 memset ( & virt_mac, 0, sizeof ( virt_mac ) );
1368 status = mlx_vmac_query_virt_mac ( flexboot_nodnic_priv->device_priv.utils,
1369 &virt_mac );
1370 if ( ! status ) {
1371 DBGC ( flexboot_nodnic_priv, "NODNIC %p Failed to set the virtual MAC\n"
1372 ,flexboot_nodnic_priv );
1373 }
1374
1375 return status;
1376}
1377
1378
1379/**
1380 * Set port masking
1381 *
1382 * @v flexboot_nodnic nodnic device
1383 * @ret rc Return status code
1384 */
1386 unsigned int i;
1388
1390 for ( i = 0; i < device_priv->device_cap.num_ports; i++ ) {
1391 flexboot_nodnic->port_mask |= (i + 1);
1392 }
1393
1394 if ( ! flexboot_nodnic->port_mask ) {
1395 /* No port was enabled */
1396 DBGC ( flexboot_nodnic, "NODNIC %p No port was enabled for "
1397 "booting\n", flexboot_nodnic );
1398 return -ENETUNREACH;
1399 }
1400
1401 return 0;
1402}
1403
1404int init_mlx_utils ( mlx_utils **utils, struct pci_device *pci ) {
1405 int rc = 0;
1406
1407 *utils = ( mlx_utils * ) zalloc ( sizeof ( mlx_utils ) );
1408 if ( *utils == NULL ) {
1409 DBGC ( utils, "%s: Failed to allocate utils\n", __FUNCTION__ );
1410 rc = -1;
1411 goto err_utils_alloc;
1412 }
1413 if ( mlx_utils_init ( *utils, pci ) ) {
1414 DBGC ( utils, "%s: mlx_utils_init failed\n", __FUNCTION__ );
1415 rc = -1;
1416 goto err_utils_init;
1417 }
1418 if ( mlx_pci_gw_init ( *utils ) ){
1419 DBGC ( utils, "%s: mlx_pci_gw_init failed\n", __FUNCTION__ );
1420 rc = -1;
1421 goto err_cmd_init;
1422 }
1423
1424 return 0;
1425
1426 mlx_pci_gw_teardown ( *utils );
1427err_cmd_init:
1428 mlx_utils_teardown ( *utils );
1429err_utils_init:
1430 free ( *utils );
1431err_utils_alloc:
1432 *utils = NULL;
1433
1434 return rc;
1435}
1436
1437void free_mlx_utils ( mlx_utils **utils ) {
1438
1439 mlx_pci_gw_teardown ( *utils );
1440 mlx_utils_teardown ( *utils );
1441 free ( *utils );
1442 *utils = NULL;
1443}
1444
1445/**
1446 * Initialise Nodnic PCI parameters
1447 *
1448 * @v hermon Nodnic device
1449 */
1452 struct pci_device *pci = flexboot_nodnic->pci;
1454
1456 DBGC ( flexboot_nodnic, "%s: tx db using uar is not supported \n", __FUNCTION__ );
1457 return -ENOTSUP;
1458 }
1459 /* read uar offset then allocate */
1461 DBGC ( flexboot_nodnic, "%s: nodnic_port_set_send_uar_offset failed,"
1462 "status = %d\n", __FUNCTION__, status );
1463 return -EINVAL;
1464 }
1465 uar->phys = ( pci_bar_start ( pci, FLEXBOOT_NODNIC_HCA_BAR ) + (mlx_uint32)uar->offset );
1466 uar->virt = ( void * )( pci_ioremap ( pci, uar->phys, FLEXBOOT_NODNIC_PAGE_SIZE ) );
1467
1468 return status;
1469}
1470
1473
1474 if ( uar->virt ) {
1475 iounmap( uar->virt );
1476 uar->virt = NULL;
1477 }
1478
1479 return MLX_SUCCESS;
1480}
1481
1482
1484 struct flexboot_nodnic_callbacks *callbacks,
1485 void *drv_priv __unused ) {
1487 struct flexboot_nodnic *flexboot_nodnic_priv = NULL;
1489 int i = 0;
1490
1491 if ( ( pci == NULL ) || ( callbacks == NULL ) ) {
1492 DBGC ( flexboot_nodnic_priv, "%s: Bad Parameter\n", __FUNCTION__ );
1493 return -EINVAL;
1494 }
1495
1496 flexboot_nodnic_priv = zalloc( sizeof ( *flexboot_nodnic_priv ) );
1497 if ( flexboot_nodnic_priv == NULL ) {
1498 DBGC ( flexboot_nodnic_priv, "%s: Failed to allocate priv data\n", __FUNCTION__ );
1500 goto device_err_alloc;
1501 }
1502
1503 /* Register settings
1504 * Note that pci->priv will be the device private data */
1505 flexboot_nodnic_priv->pci = pci;
1506 flexboot_nodnic_priv->callbacks = callbacks;
1507 pci_set_drvdata ( pci, flexboot_nodnic_priv );
1508
1509 device_priv = &flexboot_nodnic_priv->device_priv;
1510 /* init mlx utils */
1512 MLX_FATAL_CHECK_STATUS(status, err_utils_init,
1513 "init_mlx_utils failed");
1514
1515 /* init device */
1517 MLX_FATAL_CHECK_STATUS(status, device_init_err,
1518 "nodnic_device_init failed");
1519
1521 MLX_FATAL_CHECK_STATUS(status, get_cap_err,
1522 "nodnic_device_get_cap failed");
1523
1525 MLX_DEBUG_ERROR( device_priv->utils, "Failed to set admin mtu\n" );
1526 }
1527
1528 status = flexboot_nodnic_set_port_masking ( flexboot_nodnic_priv );
1529 MLX_FATAL_CHECK_STATUS(status, err_set_masking,
1530 "flexboot_nodnic_set_port_masking failed");
1531
1532 status = flexboot_nodnic_allocate_infiniband_devices( flexboot_nodnic_priv );
1533 MLX_FATAL_CHECK_STATUS(status, err_alloc_ibdev,
1534 "flexboot_nodnic_allocate_infiniband_devices failed");
1535
1536 /* port init */
1537 status = flexboot_nodnic_thin_init_ports( flexboot_nodnic_priv );
1538 MLX_FATAL_CHECK_STATUS(status, err_thin_init_ports,
1539 "flexboot_nodnic_thin_init_ports failed");
1540
1541 if ( ( status = flexboot_nodnic_alloc_uar ( flexboot_nodnic_priv ) ) ) {
1542 DBGC(flexboot_nodnic_priv, "%s: flexboot_nodnic_alloc_uar failed"
1543 " ( status = %d )\n",__FUNCTION__, status );
1544 }
1545
1546 /* device reg */
1547 status = flexboot_nodnic_set_ports_type( flexboot_nodnic_priv );
1548 MLX_CHECK_STATUS( flexboot_nodnic_priv, status, err_set_ports_types,
1549 "flexboot_nodnic_set_ports_type failed");
1550
1551 status = flexboot_nodnic_ports_register_dev( flexboot_nodnic_priv );
1553 "flexboot_nodnic_ports_register_dev failed");
1554
1555 for ( i = 0; i < device_priv->device_cap.num_ports; i++ ) {
1556 if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
1557 continue;
1558 flexboot_nodnic_get_factory_mac ( flexboot_nodnic_priv, i );
1559 }
1560
1561 /* Update ETH operations with IRQ function if supported */
1562 DBGC ( flexboot_nodnic_priv, "%s: %s IRQ function\n",
1563 __FUNCTION__, ( callbacks->irq ? "Valid" : "No" ) );
1565 return 0;
1566
1567 flexboot_nodnic_ports_unregister_dev ( flexboot_nodnic_priv );
1568reg_err:
1569err_set_ports_types:
1570 flexboot_nodnic_dealloc_uar ( flexboot_nodnic_priv );
1571err_thin_init_ports:
1572err_alloc_ibdev:
1573err_set_masking:
1574get_cap_err:
1576device_init_err:
1578err_utils_init:
1579 free ( flexboot_nodnic_priv );
1580device_err_alloc:
1581 return status;
1582}
1583
1585{
1586 struct flexboot_nodnic *flexboot_nodnic_priv = pci_get_drvdata ( pci );
1587 nodnic_device_priv *device_priv = & ( flexboot_nodnic_priv->device_priv );
1588
1589 flexboot_nodnic_dealloc_uar ( flexboot_nodnic_priv );
1590 flexboot_nodnic_ports_unregister_dev ( flexboot_nodnic_priv );
1593 free( flexboot_nodnic_priv );
1594}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
__be32 cqn
Definition CIB_PRM.h:1
u8 gid[16]
Definition CIB_PRM.h:3
__be32 qpn
Definition CIB_PRM.h:1
u8 port
Port number.
Definition CIB_PRM.h:3
__be32 byte_count
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
union ib_mad mad
Definition arbel.h:1
struct arbelprm_qp_db_record qp
Definition arbel.h:2
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
unsigned char uint8_t
Definition stdint.h:10
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void timeout(int)
ring len
Length.
Definition dwmac.h:226
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t status
Status.
Definition ena.h:5
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
Error codes.
uint8_t state
State.
Definition eth_slow.h:36
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
Ethernet protocol.
static int flexboot_nodnic_mcast_attach(struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid)
#define ARM_CQ_UAR_CQ_CI_MASK
static void flexboot_nodnic_eth_poll(struct net_device *netdev)
Poll flexboot_nodnic Ethernet device.
static struct flexboot_nodnic_port_type flexboot_nodnic_port_type_eth
flexboot_nodnic Ethernet port type
static void flexboot_nodnic_mcast_detach(struct ib_device *ibdev, struct ib_queue_pair *qp, union ib_gid *gid)
static int flexboot_nodnic_modify_qp(struct ib_device *ibdev, struct ib_queue_pair *qp)
Modify queue pair.
static mlx_status flexboot_nodnic_allocate_infiniband_devices(struct flexboot_nodnic *flexboot_nodnic_priv)
static void flexboot_nodnic_eth_complete_recv(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *dest, struct ib_address_vector *source, struct io_buffer *iobuf, int rc)
Handle flexboot_nodnic Ethernet device receive completion.
static int flexboot_nodnic_set_port_masking(struct flexboot_nodnic *flexboot_nodnic)
Set port masking.
static int flexboot_nodnic_alloc_uar(struct flexboot_nodnic *flexboot_nodnic)
Initialise Nodnic PCI parameters.
static int flexboot_nodnic_complete(struct ib_device *ibdev, struct ib_completion_queue *cq, struct cqe_data *cqe_data)
Handle completion.
static int flexboot_nodnic_post_send(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf)
Post send work queue entry.
static int flexboot_nodnic_post_recv(struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf)
Post receive work queue entry.
static int flexboot_nodnic_ib_open(struct ib_device *ibdev)
Initialise Infiniband link.
static void flexboot_nodnic_eth_close(struct net_device *netdev)
Close flexboot_nodnic Ethernet device.
static mlx_status flexboot_nodnic_get_factory_mac(struct flexboot_nodnic *flexboot_nodnic_priv, uint8_t port)
void flexboot_nodnic_eth_irq(struct net_device *netdev, int enable)
#define ARM_CQ_UAR_CQ_CI_OFFSET
static void flexboot_nodnic_disable_dma(struct flexboot_nodnic *nodnic)
static mlx_status flexboot_nodnic_ports_unregister_dev(struct flexboot_nodnic *flexboot_nodnic_priv)
static void flexboot_nodnic_poll_eq(struct ib_device *ibdev)
#define FLEXBOOT_NODNIC_ETH_NUM_RECV_WQES
Number of flexboot_nodnic Ethernet receive work queue entries.
int init_mlx_utils(mlx_utils **utils, struct pci_device *pci)
int flexboot_nodnic_is_supported(struct pci_device *pci)
int flexboot_nodnic_probe(struct pci_device *pci, struct flexboot_nodnic_callbacks *callbacks, void *drv_priv)
static struct ib_work_queue * flexboot_nodnic_find_wq(struct ib_device *ibdev, struct ib_completion_queue *cq, unsigned long qpn, int is_send)
static void flexboot_nodnic_destroy_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Destroy completion queue.
static int flexboot_nodnic_register_netdev(struct flexboot_nodnic *flexboot_nodnic, struct flexboot_nodnic_port *port)
Register flexboot_nodnic Ethernet device.
static int flexboot_nodnic_arm_cq(struct flexboot_nodnic_port *port)
static void flexboot_nodnic_complete_all_tx(struct flexboot_nodnic_port *port)
static mlx_status flexboot_nodnic_thin_init_ports(struct flexboot_nodnic *flexboot_nodnic_priv)
static mlx_status flexboot_nodnic_set_ports_type(struct flexboot_nodnic *flexboot_nodnic_priv)
#define ARM_CQ_UAR_CMDSN_OFFSET
#define ARM_CQ_UAR_CMDSN_MASK
static int flexboot_nodnic_eth_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet via flexboot_nodnic Ethernet device.
void flexboot_nodnic_remove(struct pci_device *pci)
static void flexboot_nodnic_ib_close(struct ib_device *ibdev)
Close Infiniband link.
static void flexboot_nodnic_port_disable_dma(struct flexboot_nodnic_port *port)
static void flexboot_nodnic_destroy_qp(struct ib_device *ibdev, struct ib_queue_pair *qp)
Destroy queue pair.
static struct net_device_operations flexboot_nodnic_eth_operations
flexboot_nodnic Ethernet network device operations
static struct ib_completion_queue_operations flexboot_nodnic_eth_cq_op
flexboot_nodnic Ethernet device completion operations
static int flexboot_nodnic_inform_sma(struct ib_device *ibdev, union ib_mad *mad)
Inform embedded subnet management agent of a received MAD.
static void flexboot_nodnic_eth_complete_send(struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc)
Handle flexboot_nodnic Ethernet device send completion.
static int flexboot_nodnic_create_qp(struct ib_device *ibdev, struct ib_queue_pair *qp)
Create queue pair.
static struct ib_device_operations flexboot_nodnic_ib_operations
flexboot_nodnic Infiniband operations
static void flexboot_nodnic_poll_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Poll completion queue.
static struct ib_queue_pair_operations flexboot_nodnic_eth_qp_op
flexboot nodnic Ethernet queue pair operations
static void flexboot_nodnic_enable_dma(struct flexboot_nodnic *nodnic)
void flexboot_nodnic_copy_mac(uint8_t mac_addr[], uint32_t low_byte, uint16_t high_byte)
static void flexboot_nodnic_state_change_netdev(struct flexboot_nodnic *flexboot_nodnic, struct flexboot_nodnic_port *port, int link_up)
Handle flexboot_nodnic Ethernet device port state change.
static void flexboot_nodnic_unregister_netdev(struct flexboot_nodnic *flexboot_nodnic, struct flexboot_nodnic_port *port)
Unregister flexboot_nodnic Ethernet device.
#define FLEXBOOT_NODNIC_ETH_NUM_SEND_WQES
Number of flexboot_nodnic Ethernet send work queue entries.
#define FLEX_NODNIC_TX_POLL_TOUT
#define FLEX_NODNIC_TX_POLL_USLEEP
static int flexboot_nodnic_dealloc_uar(struct flexboot_nodnic *flexboot_nodnic)
void free_mlx_utils(mlx_utils **utils)
static int flexboot_nodnic_eth_open(struct net_device *netdev)
Open flexboot_nodnic Ethernet device.
static int flexboot_nodnic_create_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Create completion queue.
static mlx_status flexboot_nodnic_ports_register_dev(struct flexboot_nodnic *flexboot_nodnic_priv)
#define FLEXBOOT_NODNIC_HCA_BAR
#define EN_DEFAULT_ADMIN_MTU
#define FLEXBOOT_NODNIC_PAGE_SIZE
#define FLEXBOOT_NODNIC_PORT_BASE
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG2(...)
Definition compiler.h:515
#define DBGCP(...)
Definition compiler.h:539
#define DBGC(...)
Definition compiler.h:505
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define DBGC_HDA(...)
Definition compiler.h:506
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENETUNREACH
Network unreachable.
Definition errno.h:489
#define EIO
Input/output error.
Definition errno.h:434
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENOBUFS
No buffer space available.
Definition errno.h:499
#define ENETDOWN
Network is down.
Definition errno.h:479
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
uint8_t bytes[64]
Definition ib_mad.h:5
#define ETH_ALEN
Definition if_ether.h:9
Network interface management.
#define htonl(value)
Definition byteswap.h:134
#define cpu_to_be32(value)
Definition byteswap.h:111
iPXE I/O API
#define wmb()
Definition io.h:546
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition io.h:184
#define writeq(data, io_addr)
Definition io.h:273
void iounmap(volatile const void *io_addr)
Unmap I/O address.
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
User memory allocation.
void __asmcall int val
Definition setjmp.h:12
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void ib_refill_recv(struct ib_device *ibdev, struct ib_queue_pair *qp)
Refill receive work queue.
Definition infiniband.c:556
void ib_destroy_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Destroy completion queue.
Definition infiniband.c:145
int ib_create_cq(struct ib_device *ibdev, unsigned int num_cqes, struct ib_completion_queue_operations *op, struct ib_completion_queue **new_cq)
Create completion queue.
Definition infiniband.c:98
void ib_complete_recv(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *dest, struct ib_address_vector *source, struct io_buffer *iobuf, int rc)
Complete receive work queue entry.
Definition infiniband.c:536
int ib_post_send(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *dest, struct io_buffer *iobuf)
Post send work queue entry.
Definition infiniband.c:416
void ib_poll_eq(struct ib_device *ibdev)
Poll event queue.
Definition infiniband.c:878
void ib_poll_cq(struct ib_device *ibdev, struct ib_completion_queue *cq)
Poll completion queue.
Definition infiniband.c:161
void ib_destroy_qp(struct ib_device *ibdev, struct ib_queue_pair *qp)
Destroy queue pair.
Definition infiniband.c:314
int ib_create_qp(struct ib_device *ibdev, enum ib_queue_pair_type type, unsigned int num_send_wqes, struct ib_completion_queue *send_cq, unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq, struct ib_queue_pair_operations *op, const char *name, struct ib_queue_pair **new_qp)
Create queue pair.
Definition infiniband.c:199
void ib_complete_send(struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc)
Complete send work queue entry.
Definition infiniband.c:515
struct ib_device * alloc_ibdev(size_t priv_size)
Allocate Infiniband device.
Definition infiniband.c:917
static __always_inline void * ib_get_drvdata(struct ib_device *ibdev)
Get Infiniband device driver-private data.
Definition infiniband.h:709
static __always_inline void * ib_cq_get_drvdata(struct ib_completion_queue *cq)
Get Infiniband completion queue driver-private data.
Definition infiniband.h:687
static __always_inline void * ib_qp_get_ownerdata(struct ib_queue_pair *qp)
Get Infiniband queue pair owner-private data.
Definition infiniband.h:665
static __always_inline void ib_qp_set_ownerdata(struct ib_queue_pair *qp, void *priv)
Set Infiniband queue pair owner-private data.
Definition infiniband.h:654
@ IB_QPT_ETH
Definition infiniband.h:144
@ IB_QPT_UD
Definition infiniband.h:142
@ IB_QPT_GSI
Definition infiniband.h:141
@ IB_QPT_RC
Definition infiniband.h:143
@ IB_QPT_SMI
Definition infiniband.h:140
static __always_inline void * ib_qp_get_drvdata(struct ib_queue_pair *qp)
Get Infiniband queue pair driver-private data.
Definition infiniband.h:643
static __always_inline void ib_cq_set_drvdata(struct ib_completion_queue *cq, void *priv)
Set Infiniband completion queue driver-private data.
Definition infiniband.h:676
static __always_inline void ib_qp_set_drvdata(struct ib_queue_pair *qp, void *priv)
Set Infiniband queue pair driver-private data.
Definition infiniband.h:632
static __always_inline void ib_set_drvdata(struct ib_device *ibdev, void *priv)
Set Infiniband device driver-private data.
Definition infiniband.h:698
static __always_inline void ibdev_put(struct ib_device *ibdev)
Drop reference to Infiniband device.
Definition infiniband.h:599
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition iobuf.h:180
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
Dynamic memory allocation.
#define MLX_CHECK_STATUS(id, status, label, message)
Definition mlx_bail.h:37
#define MLX_FATAL_CHECK_STATUS(status, label, message)
Definition mlx_bail.h:29
#define MLX_FILL_H(_structure_st, _index, _field, _address)
Definition mlx_bitops.h:240
#define MLX_FILL_1(_ptr, _index,...)
Definition mlx_bitops.h:167
mlx_status nodnic_device_init(IN nodnic_device_priv *device_priv)
Definition mlx_device.c:195
#define NODNIC_NIC_INTERFACE_SUPPORTED_BIT
Definition mlx_device.h:41
mlx_status nodnic_device_clear_int(IN nodnic_device_priv *device_priv)
Definition mlx_device.c:165
mlx_status nodnic_device_teardown(IN nodnic_device_priv *device_priv)
Definition mlx_device.c:218
#define NODNIC_NIC_INTERFACE_SUPPORTED_OFFSET
Definition mlx_device.h:33
mlx_status nodnic_device_get_cap(IN nodnic_device_priv *device_priv)
Definition mlx_device.c:230
#define MLX_DEBUG_ERROR(...)
Definition mlx_logging.h:29
#define MLX_DEBUG_WARN(...)
Definition mlx_logging.h:30
mlx_status mlx_set_admin_mtu(IN mlx_utils *utils, IN mlx_uint8 port_num, IN mlx_uint32 admin_mtu)
Definition mlx_mtu.c:63
struct _nodnic_device_priv nodnic_device_priv
struct _nodnic_port_priv nodnic_port_priv
struct _nodnic_qp nodnic_qp
struct _nodnic_uar_priv nodnic_uar
@ NODNIC_PORT_TYPE_UNKNOWN
#define NODNIC_PORT_OPENED
#define NODNIC_PORT_DISABLING_DMA
mlx_status mlx_pci_mem_write(IN mlx_utils *utils, IN mlx_pci_width width, IN mlx_uint8 bar_index, IN mlx_uint64 offset, IN mlx_uintn count, IN mlx_void *buffer)
Definition mlx_pci.c:116
@ MlxPciWidthUint32
Definition mlx_pci.h:30
mlx_status mlx_pci_gw_teardown(IN mlx_utils *utils)
Definition mlx_pci_gw.c:247
mlx_status mlx_pci_gw_read(IN mlx_utils *utils, IN mlx_pci_gw_space space, IN mlx_uint32 address, OUT mlx_pci_gw_buffer *buffer)
Definition mlx_pci_gw.c:258
mlx_status mlx_pci_gw_init(IN mlx_utils *utils)
Definition mlx_pci_gw.c:218
mlx_uint32 mlx_pci_gw_buffer
Definition mlx_pci_gw.h:52
#define PCI_GW_SPACE_NODNIC
Definition mlx_pci_gw.h:47
mlx_status nodnic_port_init(IN nodnic_port_priv *port_priv)
Definition mlx_port.c:1235
mlx_status nodnic_port_get_cq_size(IN nodnic_port_priv *port_priv, OUT mlx_uint64 *cq_size)
Definition mlx_port.c:899
mlx_status nodnic_port_set_send_uar_offset(IN nodnic_port_priv *port_priv)
Definition mlx_port.c:197
mlx_status nodnic_port_get_state(IN nodnic_port_priv *port_priv, OUT nodnic_port_state *state)
Definition mlx_port.c:88
mlx_status nodnic_port_enable_dma(IN nodnic_port_priv *port_priv)
Definition mlx_port.c:1275
mlx_status nodnic_port_get_type(IN nodnic_port_priv *port_priv, OUT nodnic_port_type *type)
Definition mlx_port.c:105
mlx_status nodnic_port_remove_mac_filter(IN nodnic_port_priv *port_priv, IN mlx_mac_address mac)
Definition mlx_port.c:1073
mlx_status nodnic_port_thin_init(IN nodnic_device_priv *device_priv, IN nodnic_port_priv *port_priv, IN mlx_uint8 port_index)
Definition mlx_port.c:1315
mlx_status nodnic_port_close(IN nodnic_port_priv *port_priv)
Definition mlx_port.c:1255
mlx_status nodnic_port_disable_dma(IN nodnic_port_priv *port_priv)
Definition mlx_port.c:1295
mlx_status nodnic_port_query(IN nodnic_port_priv *port_priv, IN nodnic_port_option option, OUT mlx_uint32 *out)
Definition mlx_port.c:126
mlx_status nodnic_port_get_qpn(IN nodnic_port_priv *port_priv, IN struct nodnic_ring *ring, OUT mlx_uint32 *qpn)
Definition mlx_port.c:796
mlx_status nodnic_port_allocate_eq(IN nodnic_port_priv *port_priv, IN mlx_uint8 log_eq_size)
Definition mlx_port.c:915
mlx_status nodnic_port_add_mac_filter(IN nodnic_port_priv *port_priv, IN mlx_mac_address mac)
Definition mlx_port.c:992
mlx_status nodnic_port_create_qp(IN nodnic_port_priv *port_priv, IN nodnic_queue_pair_type type, IN mlx_size send_wq_size, IN mlx_uint32 send_wqe_num, IN mlx_size receive_wq_size, IN mlx_uint32 recv_wqe_num, OUT nodnic_qp **qp)
Definition mlx_port.c:585
mlx_status nodnic_port_free_eq(IN nodnic_port_priv *port_priv)
Definition mlx_port.c:968
mlx_status nodnic_port_set(IN nodnic_port_priv *port_priv, IN nodnic_port_option option, IN mlx_uint32 in)
Definition mlx_port.c:155
nodnic_port_state
Definition mlx_port.h:69
@ nodnic_port_state_active
Definition mlx_port.h:73
@ nodnic_port_state_down
Definition mlx_port.h:70
mlx_status nodnic_port_destroy_qp(IN nodnic_port_priv *port_priv, IN nodnic_queue_pair_type type, IN nodnic_qp *qp)
Definition mlx_port.c:726
@ nodnic_port_option_mac_high
Definition mlx_port.h:32
@ nodnic_port_option_cq_n_index
Definition mlx_port.h:52
@ nodnic_port_option_mac_low
Definition mlx_port.h:31
@ nodnic_port_option_arm_cq
Definition mlx_port.h:45
mlx_status nodnic_port_set_promisc(IN nodnic_port_priv *port_priv, IN mlx_boolean value)
Definition mlx_port.c:1205
mlx_status nodnic_port_destroy_cq(IN nodnic_port_priv *port_priv, IN nodnic_cq *cq)
Definition mlx_port.c:426
mlx_status nodnic_port_create_cq(IN nodnic_port_priv *port_priv, IN mlx_size cq_size, OUT nodnic_cq **cq)
Definition mlx_port.c:360
uint16_t mlx_uint16
uint32_t mlx_uint32
size_t mlx_size
#define MLX_UNSUPPORTED
uint64_t mlx_uint64
#define MLX_FAILED
#define MLX_SUCCESS
int mlx_status
#define MLX_OUT_OF_RESOURCES
unsigned long mlx_uintn
mlx_status mlx_utils_init(IN mlx_utils *utils, IN mlx_pci *pci)
Definition mlx_utils.c:28
mlx_status mlx_utils_teardown(IN mlx_utils *utils)
Definition mlx_utils.c:46
mlx_status mlx_vmac_query_virt_mac(IN mlx_utils *utils, OUT struct mlx_vmac_query_virt_mac *virt_mac)
Definition mlx_vmac.c:27
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition netdevice.h:640
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition pci.c:97
PCI bus.
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:366
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:376
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
mlx_void * cq_virt
cq entries
nodnic_device_capabilites device_cap
nodnic_device_priv * device
struct nodnic_send_ring send
struct nodnic_recv_ring receive
mlx_uint32 vendor_err_syndrome
mlx_uint32 syndrome
mlx_uint32 byte_cnt
mlx_uint32 is_send
mlx_boolean owner
mlx_uint32 wqe_counter
mlx_uint32 is_error
mlx_uint32 qpn
mlx_status(* tx_uar_send_doorbell_fn)(struct ib_device *ibdev, struct nodnic_send_wqbb *wqbb)
mlx_status(* fill_completion)(void *cqe, struct cqe_data *cqe_data)
void(* irq)(struct net_device *netdev, int enable)
mlx_status(* cqe_set_owner)(void *cq, unsigned int num_cqes)
A flexboot_nodnic port type.
A flexboot nodnic port.
nodnic_port_priv port_priv
nodic port
struct flexboot_nodnic_port_type * type
Port type.
struct ib_device * ibdev
Infiniband device.
A flexboot nodnic queue pair.
A flexboot_nodnic device.
nodnic_device_priv device_priv
nodnic device
struct pci_device * pci
PCI device.
struct flexboot_nodnic_callbacks * callbacks
nic specific data
struct flexboot_nodnic_port port[FLEXBOOT_NODNIC_MAX_PORTS]
flexboot_nodnic ports
u16 port_mask
Port masking.
An Infiniband Address Vector.
Definition infiniband.h:73
unsigned long qpn
Queue Pair Number.
Definition infiniband.h:75
Infiniband completion queue operations.
Definition infiniband.h:195
An Infiniband Completion Queue.
Definition infiniband.h:225
unsigned long cqn
Completion queue number.
Definition infiniband.h:231
unsigned long next_idx
Next completion queue entry index.
Definition infiniband.h:241
struct list_head work_queues
List of work queues completing to this queue.
Definition infiniband.h:243
unsigned int num_cqes
Number of completion queue entries.
Definition infiniband.h:233
Infiniband device operations.
Definition infiniband.h:255
An Infiniband device.
Definition infiniband.h:399
unsigned int ports
Total ports on device.
Definition infiniband.h:421
struct ib_device_operations * op
Infiniband operations.
Definition infiniband.h:417
struct device * dev
Underlying device.
Definition infiniband.h:411
struct list_head cqs
List of completion queues.
Definition infiniband.h:413
unsigned int port
Port number.
Definition infiniband.h:419
Infiniband queue pair operations.
Definition infiniband.h:148
An Infiniband Queue Pair.
Definition infiniband.h:158
An Infiniband Work Queue.
Definition infiniband.h:101
unsigned int fill
Number of occupied work queue entries.
Definition infiniband.h:115
struct io_buffer ** iobufs
I/O buffers assigned to work queue.
Definition infiniband.h:125
struct ib_completion_queue * cq
Associated completion queue.
Definition infiniband.h:107
struct list_head list
List of work queues on this completion queue.
Definition infiniband.h:109
struct ib_queue_pair * qp
Containing queue pair.
Definition infiniband.h:103
int is_send
"Is a send queue" flag
Definition infiniband.h:105
unsigned long next_idx
Next work queue entry index.
Definition infiniband.h:123
unsigned int num_wqes
Number of work queue entries.
Definition infiniband.h:113
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
struct nodnic_ring nodnic_ring
struct nodnic_wqe_segment_data_ptr data[NODNIC_MAX_SCATTER]
Definition nodnic_prm.h:44
struct nodnic_ring nodnic_ring
struct nodnic_send_wqbb * wqe_virt
A PCI device.
Definition pci.h:211
struct device dev
Generic device.
Definition pci.h:213
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61
#define TRUE
Definition tlan.h:46
#define FALSE
Definition tlan.h:45
mlx_uint64 qword
mlx_uint32 dword[2]
An Infiniband Global Identifier.
Definition ib_packet.h:34
A management datagram.
Definition ib_mad.h:611
Virtual LANs.