2
* Copyright (C) 2015 Mellanox Technologies Ltd.
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.
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.
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
20
FILE_LICENCE ( GPL2_OR_LATER );
22
#include "../include/mlx_port.h"
23
#include "../include/mlx_cmd.h"
24
#include "../../mlx_utils/include/public/mlx_memory.h"
25
#include "../../mlx_utils/include/public/mlx_pci.h"
26
#include "../../mlx_utils/include/public/mlx_bail.h"
28
#define PortDataEntry( _option, _offset, _align, _mask) { \
35
#define QpDataEntry( _type, _send_offset, _recv_offset) { \
37
.send_offset = _send_offset, \
38
.recv_offset = _recv_offset, \
42
struct nodnic_port_data_entry nodnic_port_data_table[] = {
43
PortDataEntry(nodnic_port_option_link_type, 0x0, 4, 0x1),
44
PortDataEntry(nodnic_port_option_mac_low, 0xc, 0, 0xFFFFFFFF),
45
PortDataEntry(nodnic_port_option_mac_high, 0x8, 0, 0xFFFF),
46
PortDataEntry(nodnic_port_option_log_cq_size, 0x6c, 0, 0x3F),
47
PortDataEntry(nodnic_port_option_reset_needed, 0x0, 31, 0x1),
48
PortDataEntry(nodnic_port_option_mac_filters_en, 0x4, 0, 0x1F),
49
PortDataEntry(nodnic_port_option_port_state, 0x0, 0, 0xF),
50
PortDataEntry(nodnic_port_option_network_en, 0x4, 31, 0x1),
51
PortDataEntry(nodnic_port_option_dma_en, 0x4, 30, 0x1),
52
PortDataEntry(nodnic_port_option_eq_addr_low, 0x74, 0, 0xFFFFFFFF),
53
PortDataEntry(nodnic_port_option_eq_addr_high, 0x70, 0, 0xFFFFFFFF),
54
PortDataEntry(nodnic_port_option_cq_addr_low, 0x6c, 12, 0xFFFFF),
55
PortDataEntry(nodnic_port_option_cq_addr_high, 0x68, 0, 0xFFFFFFFF),
56
PortDataEntry(nodnic_port_option_port_management_change_event, 0x0, 30, 0x1),
57
PortDataEntry(nodnic_port_option_port_promisc_en, 0x4, 29, 0x1),
58
PortDataEntry(nodnic_port_option_arm_cq, 0x78, 8, 0xffff),
59
PortDataEntry(nodnic_port_option_port_promisc_multicast_en, 0x4, 28, 0x1),
61
PortDataEntry(nodnic_port_option_crspace_en, 0x4, 27, 0x1),
65
#define MAX_QP_DATA_ENTRIES 5
66
struct nodnic_qp_data_entry nodnic_qp_data_teable[MAX_QP_DATA_ENTRIES] = {
67
QpDataEntry(NODNIC_QPT_SMI, 0, 0),
68
QpDataEntry(NODNIC_QPT_GSI, 0, 0),
69
QpDataEntry(NODNIC_QPT_UD, 0, 0),
70
QpDataEntry(NODNIC_QPT_RC, 0, 0),
71
QpDataEntry(NODNIC_QPT_ETH, 0x80, 0xC0),
74
#define MAX_NODNIC_PORTS 2
75
int nodnic_port_offset_table[MAX_NODNIC_PORTS] = {
76
0x100, //port 1 offset
77
0x280, //port 1 offset
81
nodnic_port_get_state(
82
IN nodnic_port_priv *port_priv,
83
OUT nodnic_port_state *state
86
mlx_status status = MLX_SUCCESS;
89
status = nodnic_port_query(port_priv,
90
nodnic_port_option_port_state, &out);
91
MLX_CHECK_STATUS(port_priv->device, status, query_err,
92
"nodnic_port_query failed");
93
*state = (nodnic_port_state)out;
99
IN nodnic_port_priv *port_priv,
100
OUT nodnic_port_type *type
103
mlx_status status = MLX_SUCCESS;
106
if ( port_priv->port_type == NODNIC_PORT_TYPE_UNKNOWN){
107
status = nodnic_port_query(port_priv,
108
nodnic_port_option_link_type, &out);
109
MLX_FATAL_CHECK_STATUS(status, query_err,
110
"nodnic_port_query failed");
111
port_priv->port_type = (nodnic_port_type)out;
113
*type = port_priv->port_type;
120
IN nodnic_port_priv *port_priv,
121
IN nodnic_port_option option,
125
mlx_status status = MLX_SUCCESS;
126
nodnic_device_priv *device_priv = NULL;
127
struct nodnic_port_data_entry *data_entry;
128
mlx_uint32 buffer = 0;
129
if( port_priv == NULL || out == NULL){
130
status = MLX_INVALID_PARAMETER;
133
device_priv = port_priv->device;
135
data_entry = &nodnic_port_data_table[option];
137
status = nodnic_cmd_read(device_priv,
138
port_priv->port_offset + data_entry->offset , &buffer);
139
MLX_CHECK_STATUS(device_priv, status, read_err,
140
"nodnic_cmd_read failed");
141
*out = (buffer >> data_entry->align) & data_entry->mask;
149
IN nodnic_port_priv *port_priv,
150
IN nodnic_port_option option,
154
mlx_status status = MLX_SUCCESS;
155
nodnic_device_priv *device_priv = NULL;
156
struct nodnic_port_data_entry *data_entry;
157
mlx_uint32 buffer = 0;
159
if( port_priv == NULL ){
160
MLX_DEBUG_FATAL_ERROR("port_priv is NULL\n");
161
status = MLX_INVALID_PARAMETER;
164
device_priv = port_priv->device;
165
data_entry = &nodnic_port_data_table[option];
167
if( in > data_entry->mask ){
168
MLX_DEBUG_FATAL_ERROR("in > data_entry->mask (%d > %d)\n",
169
in, data_entry->mask);
170
status = MLX_INVALID_PARAMETER;
173
status = nodnic_cmd_read(device_priv,
174
port_priv->port_offset + data_entry->offset, &buffer);
175
MLX_FATAL_CHECK_STATUS(status, read_err,
176
"nodnic_cmd_read failed");
177
buffer = buffer & ~(data_entry->mask << data_entry->align);
178
buffer = buffer | (in << data_entry->align);
179
status = nodnic_cmd_write(device_priv,
180
port_priv->port_offset + data_entry->offset, buffer);
181
MLX_FATAL_CHECK_STATUS(status, write_err,
182
"nodnic_cmd_write failed");
190
nodnic_port_read_reset_needed(
191
IN nodnic_port_priv *port_priv,
192
OUT mlx_boolean *reset_needed
195
mlx_status status = MLX_SUCCESS;
197
status = nodnic_port_query(port_priv,
198
nodnic_port_option_reset_needed, &out);
199
MLX_CHECK_STATUS(port_priv->device, status, query_err,
200
"nodnic_port_query failed");
201
*reset_needed = (mlx_boolean)out;
207
nodnic_port_read_port_management_change_event(
208
IN nodnic_port_priv *port_priv,
209
OUT mlx_boolean *change_event
212
mlx_status status = MLX_SUCCESS;
214
status = nodnic_port_query(port_priv,
215
nodnic_port_option_port_management_change_event, &out);
216
MLX_CHECK_STATUS(port_priv->device, status, query_err,
217
"nodnic_port_query failed");
218
*change_event = (mlx_boolean)out;
224
nodnic_port_create_cq(
225
IN nodnic_port_priv *port_priv,
230
mlx_status status = MLX_SUCCESS;
231
nodnic_device_priv *device_priv = NULL;
232
mlx_uint64 address = 0;
233
if( port_priv == NULL || cq == NULL){
234
status = MLX_INVALID_PARAMETER;
238
device_priv = port_priv->device;
240
status = mlx_memory_zalloc(device_priv->utils,
241
sizeof(nodnic_cq),(mlx_void **)cq);
242
MLX_FATAL_CHECK_STATUS(status, alloc_err,
243
"cq priv allocation error");
245
(*cq)->cq_size = cq_size;
246
status = mlx_memory_alloc_dma(device_priv->utils,
247
(*cq)->cq_size, NODNIC_MEMORY_ALIGN,
249
MLX_FATAL_CHECK_STATUS(status, dma_alloc_err,
250
"cq allocation error");
252
status = mlx_memory_map_dma(device_priv->utils,
257
MLX_FATAL_CHECK_STATUS(status, cq_map_err,
260
/* update cq address */
261
#define NODIC_CQ_ADDR_HIGH 0x68
262
#define NODIC_CQ_ADDR_LOW 0x6c
263
address = (mlx_uint64)(*cq)->cq_physical;
264
nodnic_port_set(port_priv, nodnic_port_option_cq_addr_low,
265
(mlx_uint32)(address >> 12));
266
address = address >> 32;
267
nodnic_port_set(port_priv, nodnic_port_option_cq_addr_high,
268
(mlx_uint32)address);
271
mlx_memory_ummap_dma(device_priv->utils, (*cq)->map);
273
mlx_memory_free_dma(device_priv->utils, (*cq)->cq_size,
274
(void **)&((*cq)->cq_virt));
276
mlx_memory_free(device_priv->utils, (void **)cq);
283
nodnic_port_destroy_cq(
284
IN nodnic_port_priv *port_priv,
288
mlx_status status = MLX_SUCCESS;
289
nodnic_device_priv *device_priv = NULL;
291
if( port_priv == NULL || cq == NULL){
292
status = MLX_INVALID_PARAMETER;
295
device_priv = port_priv->device;
297
mlx_memory_ummap_dma(device_priv->utils, cq->map);
299
mlx_memory_free_dma(device_priv->utils, cq->cq_size,
300
(void **)&(cq->cq_virt));
302
mlx_memory_free(device_priv->utils, (void **)&cq);
307
nodnic_port_create_qp(
308
IN nodnic_port_priv *port_priv,
309
IN nodnic_queue_pair_type type,
310
IN mlx_size send_wq_size,
311
IN mlx_uint32 send_wqe_num,
312
IN mlx_size receive_wq_size,
313
IN mlx_uint32 recv_wqe_num,
317
mlx_status status = MLX_SUCCESS;
318
nodnic_device_priv *device_priv = NULL;
319
mlx_uint32 max_ring_size = 0;
320
mlx_uint64 address = 0;
321
mlx_uint32 log_size = 0;
322
if( port_priv == NULL || qp == NULL){
323
status = MLX_INVALID_PARAMETER;
327
device_priv = port_priv->device;
328
max_ring_size = (1 << device_priv->device_cap.log_max_ring_size);
329
if( send_wq_size > max_ring_size ||
330
receive_wq_size > max_ring_size ){
331
status = MLX_INVALID_PARAMETER;
335
status = mlx_memory_zalloc(device_priv->utils,
336
sizeof(nodnic_qp),(mlx_void **)qp);
337
MLX_FATAL_CHECK_STATUS(status, alloc_err,
338
"qp allocation error");
340
if( nodnic_qp_data_teable[type].send_offset == 0 ||
341
nodnic_qp_data_teable[type].recv_offset == 0){
342
status = MLX_INVALID_PARAMETER;
346
(*qp)->send.nodnic_ring.offset = port_priv->port_offset +
347
nodnic_qp_data_teable[type].send_offset;
348
(*qp)->receive.nodnic_ring.offset = port_priv->port_offset +
349
nodnic_qp_data_teable[type].recv_offset;
351
status = mlx_memory_alloc_dma(device_priv->utils,
352
send_wq_size, NODNIC_MEMORY_ALIGN,
353
(void*)&(*qp)->send.wqe_virt);
354
MLX_FATAL_CHECK_STATUS(status, send_alloc_err,
355
"send wq allocation error");
357
status = mlx_memory_alloc_dma(device_priv->utils,
358
receive_wq_size, NODNIC_MEMORY_ALIGN,
359
&(*qp)->receive.wqe_virt);
360
MLX_FATAL_CHECK_STATUS(status, receive_alloc_err,
361
"receive wq allocation error");
363
status = mlx_memory_map_dma(device_priv->utils,
364
(*qp)->send.wqe_virt,
366
&(*qp)->send.nodnic_ring.wqe_physical,
367
&(*qp)->send.nodnic_ring.map);
368
MLX_FATAL_CHECK_STATUS(status, send_map_err,
369
"send wq map error");
371
status = mlx_memory_map_dma(device_priv->utils,
372
(*qp)->receive.wqe_virt,
374
&(*qp)->receive.nodnic_ring.wqe_physical,
375
&(*qp)->receive.nodnic_ring.map);
376
MLX_FATAL_CHECK_STATUS(status, receive_map_err,
377
"receive wq map error");
379
(*qp)->send.nodnic_ring.wq_size = send_wq_size;
380
(*qp)->send.nodnic_ring.num_wqes = send_wqe_num;
381
(*qp)->receive.nodnic_ring.wq_size = receive_wq_size;
382
(*qp)->receive.nodnic_ring.num_wqes = recv_wqe_num;
384
/* Set Ownership bit in Send/receive queue (0 - recv ; 1 - send) */
385
mlx_memory_set(device_priv->utils, (*qp)->send.wqe_virt, 0xff, send_wq_size );
386
mlx_memory_set(device_priv->utils, (*qp)->receive.wqe_virt, 0, recv_wqe_num );
388
/* update send ring */
389
#define NODIC_RING_QP_ADDR_HIGH 0x0
390
#define NODIC_RING_QP_ADDR_LOW 0x4
391
address = (mlx_uint64)(*qp)->send.nodnic_ring.wqe_physical;
392
status = nodnic_cmd_write(device_priv, (*qp)->send.nodnic_ring.offset +
393
NODIC_RING_QP_ADDR_HIGH,
394
(mlx_uint32)(address >> 32));
395
MLX_FATAL_CHECK_STATUS(status, write_send_addr_err,
396
"send address write error 1");
397
mlx_utils_ilog2((*qp)->send.nodnic_ring.wq_size, &log_size);
398
address = address | log_size;
399
status = nodnic_cmd_write(device_priv, (*qp)->send.nodnic_ring.offset +
400
NODIC_RING_QP_ADDR_LOW,
401
(mlx_uint32)address);
402
MLX_FATAL_CHECK_STATUS(status, write_send_addr_err,
403
"send address write error 2");
404
/* update receive ring */
405
address = (mlx_uint64)(*qp)->receive.nodnic_ring.wqe_physical;
406
status = nodnic_cmd_write(device_priv, (*qp)->receive.nodnic_ring.offset +
407
NODIC_RING_QP_ADDR_HIGH,
408
(mlx_uint32)(address >> 32));
409
MLX_FATAL_CHECK_STATUS(status, write_recv_addr_err,
410
"receive address write error 1");
411
mlx_utils_ilog2((*qp)->receive.nodnic_ring.wq_size, &log_size);
412
address = address | log_size;
413
status = nodnic_cmd_write(device_priv, (*qp)->receive.nodnic_ring.offset +
414
NODIC_RING_QP_ADDR_LOW,
415
(mlx_uint32)address);
416
MLX_FATAL_CHECK_STATUS(status, write_recv_addr_err,
417
"receive address write error 2");
422
mlx_memory_ummap_dma(device_priv->utils, (*qp)->receive.nodnic_ring.map);
424
mlx_memory_ummap_dma(device_priv->utils, (*qp)->send.nodnic_ring.map);
426
mlx_memory_free_dma(device_priv->utils, receive_wq_size,
427
&((*qp)->receive.wqe_virt));
429
mlx_memory_free_dma(device_priv->utils, send_wq_size,
430
(void **)&((*qp)->send.wqe_virt));
433
mlx_memory_free(device_priv->utils, (void **)qp);
440
nodnic_port_destroy_qp(
441
IN nodnic_port_priv *port_priv,
442
IN nodnic_queue_pair_type type __attribute__((unused)),
446
mlx_status status = MLX_SUCCESS;
447
nodnic_device_priv *device_priv = port_priv->device;
449
status = mlx_memory_ummap_dma(device_priv->utils,
450
qp->receive.nodnic_ring.map);
451
if( status != MLX_SUCCESS){
452
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
455
status = mlx_memory_ummap_dma(device_priv->utils, qp->send.nodnic_ring.map);
456
if( status != MLX_SUCCESS){
457
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
460
status = mlx_memory_free_dma(device_priv->utils,
461
qp->receive.nodnic_ring.wq_size,
462
(void **)&(qp->receive.wqe_virt));
463
if( status != MLX_SUCCESS){
464
MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
466
status = mlx_memory_free_dma(device_priv->utils,
467
qp->send.nodnic_ring.wq_size,
468
(void **)&(qp->send.wqe_virt));
469
if( status != MLX_SUCCESS){
470
MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
472
status = mlx_memory_free(device_priv->utils, (void **)&qp);
473
if( status != MLX_SUCCESS){
474
MLX_DEBUG_ERROR(device_priv, "mlx_memory_free failed (Status = %d)\n", status);
481
IN nodnic_port_priv *port_priv,
482
IN struct nodnic_ring *ring,
486
mlx_status status = MLX_SUCCESS;
487
mlx_uint32 buffer = 0;
488
if( ring == NULL || qpn == NULL){
489
status = MLX_INVALID_PARAMETER;
492
if( ring->qpn != 0 ){
496
#define NODNIC_RING_QPN_OFFSET 0xc
497
#define NODNIC_RING_QPN_MASK 0xFFFFFF
498
status = nodnic_cmd_read(port_priv->device,
499
ring->offset + NODNIC_RING_QPN_OFFSET,
501
MLX_FATAL_CHECK_STATUS(status, read_err,
502
"nodnic_cmd_read failed");
503
ring->qpn = buffer & NODNIC_RING_QPN_MASK;
514
nodnic_port_send_db_connectx3(
515
IN nodnic_port_priv *port_priv,
516
IN struct nodnic_ring *ring __attribute__((unused)),
520
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
521
mlx_uint32 index32 = index;
522
mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
523
(mlx_uint64)&(ptr->send_doorbell), 1, &index32);
529
nodnic_port_recv_db_connectx3(
530
IN nodnic_port_priv *port_priv,
531
IN struct nodnic_ring *ring __attribute__((unused)),
535
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
536
mlx_uint32 index32 = index;
537
mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
538
(mlx_uint64)&(ptr->recv_doorbell), 1, &index32);
544
nodnic_port_update_ring_doorbell(
545
IN nodnic_port_priv *port_priv,
546
IN struct nodnic_ring *ring,
550
mlx_status status = MLX_SUCCESS;
551
mlx_uint32 buffer = 0;
553
status = MLX_INVALID_PARAMETER;
556
#define NODNIC_RING_RING_OFFSET 0x8
557
buffer = (mlx_uint32)((index & 0xFFFF)<< 8);
558
status = nodnic_cmd_write(port_priv->device,
559
ring->offset + NODNIC_RING_RING_OFFSET,
561
MLX_CHECK_STATUS(port_priv->device, status, write_err,
562
"nodnic_cmd_write failed");
569
nodnic_port_get_cq_size(
570
IN nodnic_port_priv *port_priv,
571
OUT mlx_uint64 *cq_size
574
mlx_status status = MLX_SUCCESS;
576
status = nodnic_port_query(port_priv, nodnic_port_option_log_cq_size, &out);
577
MLX_FATAL_CHECK_STATUS(status, query_err,
578
"nodnic_port_query failed");
585
nodnic_port_allocate_eq(
586
IN nodnic_port_priv *port_priv,
587
IN mlx_uint8 log_eq_size
590
mlx_status status = MLX_SUCCESS;
591
nodnic_device_priv *device_priv = NULL;
592
mlx_uint64 address = 0;
594
if( port_priv == NULL ){
595
status = MLX_INVALID_PARAMETER;
599
device_priv = port_priv->device;
600
port_priv->eq.eq_size = ( ( 1 << log_eq_size ) * 1024 ); /* Size is in KB */
601
status = mlx_memory_alloc_dma(device_priv->utils,
602
port_priv->eq.eq_size,
604
&port_priv->eq.eq_virt);
605
MLX_FATAL_CHECK_STATUS(status, alloc_err,
606
"eq allocation error");
608
status = mlx_memory_map_dma(device_priv->utils,
609
port_priv->eq.eq_virt,
610
port_priv->eq.eq_size,
611
&port_priv->eq.eq_physical,
613
MLX_FATAL_CHECK_STATUS(status, map_err,
616
address = port_priv->eq.eq_physical;
617
status = nodnic_port_set(port_priv, nodnic_port_option_eq_addr_low,
618
(mlx_uint32)address);
619
MLX_FATAL_CHECK_STATUS(status, set_err,
620
"failed to set eq addr low");
621
address = (address >> 32);
622
status = nodnic_port_set(port_priv, nodnic_port_option_eq_addr_high,
623
(mlx_uint32)address);
624
MLX_FATAL_CHECK_STATUS(status, set_err,
625
"failed to set eq addr high");
628
mlx_memory_ummap_dma(device_priv->utils, port_priv->eq.map);
630
mlx_memory_free_dma(device_priv->utils,
631
port_priv->eq.eq_size,
632
(void **)&(port_priv->eq.eq_virt));
639
IN nodnic_port_priv *port_priv
642
mlx_status status = MLX_SUCCESS;
643
nodnic_device_priv *device_priv = NULL;
645
if( port_priv == NULL ){
646
status = MLX_INVALID_PARAMETER;
650
device_priv = port_priv->device;
651
mlx_memory_ummap_dma(device_priv->utils, port_priv->eq.map);
653
mlx_memory_free_dma(device_priv->utils,
654
port_priv->eq.eq_size,
655
(void **)&(port_priv->eq.eq_virt));
662
nodnic_port_add_mac_filter(
663
IN nodnic_port_priv *port_priv,
664
IN mlx_mac_address mac
667
mlx_status status = MLX_SUCCESS;
668
nodnic_device_priv *device= NULL;;
671
mlx_uint32 mac_filters_en = 0;
672
mlx_uint32 address = 0;
673
mlx_mac_address zero_mac;
674
mlx_utils *utils = NULL;
676
if( port_priv == NULL){
677
status = MLX_INVALID_PARAMETER;
681
memset(&zero_mac, 0, sizeof(zero_mac));
683
device = port_priv->device;
684
utils = device->utils;
686
/* check if mac already exists */
687
for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
688
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
696
/* serch for available mac filter slot */
697
for (index = 0 ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
698
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &zero_mac,
699
sizeof(zero_mac), &out);
704
if ( index >= NODNIC_MAX_MAC_FILTERS ){
709
status = nodnic_port_query(port_priv, nodnic_port_option_mac_filters_en,
711
MLX_CHECK_STATUS(device, status , query_err,
712
"nodnic_port_query failed");
713
if(mac_filters_en & (1 << index)){
717
port_priv->mac_filters[index] = mac;
720
address = port_priv->port_offset + NODNIC_PORT_MAC_FILTERS_OFFSET +
723
status = nodnic_cmd_write(device, address, mac.high );
724
MLX_CHECK_STATUS(device, status, write_err, "set mac high failed");
725
status = nodnic_cmd_write(device, address + 0x4, mac.low );
726
MLX_CHECK_STATUS(device, status, write_err, "set mac low failed");
729
mac_filters_en = mac_filters_en | (1 << index);
730
status = nodnic_port_set(port_priv, nodnic_port_option_mac_filters_en,
732
MLX_CHECK_STATUS(device, status , set_err,
733
"nodnic_port_set failed");
744
nodnic_port_remove_mac_filter(
745
IN nodnic_port_priv *port_priv,
746
IN mlx_mac_address mac
749
mlx_status status = MLX_SUCCESS;
750
nodnic_device_priv *device= NULL;;
753
mlx_uint32 mac_filters_en = 0;
754
mlx_mac_address zero_mac;
755
mlx_utils *utils = NULL;
757
if( port_priv == NULL){
758
status = MLX_INVALID_PARAMETER;
762
memset(&zero_mac, 0, sizeof(zero_mac));
764
device = port_priv->device;
765
utils = device->utils;
767
/* serch for mac filter */
768
for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
769
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
775
if ( index == NODNIC_MAX_MAC_FILTERS ){
780
status = nodnic_port_query(port_priv, nodnic_port_option_mac_filters_en,
782
MLX_CHECK_STATUS(device, status , query_err,
783
"nodnic_port_query failed");
784
if((mac_filters_en & (1 << index)) == 0){
788
port_priv->mac_filters[index] = zero_mac;
790
// disable mac filter
791
mac_filters_en = mac_filters_en & ~(1 << index);
792
status = nodnic_port_set(port_priv, nodnic_port_option_mac_filters_en,
794
MLX_CHECK_STATUS(device, status , set_err,
795
"nodnic_port_set failed");
806
nodnic_port_set_network(
807
IN nodnic_port_priv *port_priv,
811
mlx_status status = MLX_SUCCESS;
812
/*mlx_uint32 network_valid = 0;
815
status = nodnic_port_set(port_priv, nodnic_port_option_network_en, value);
816
MLX_CHECK_STATUS(port_priv->device, status, set_err,
817
"nodnic_port_set failed");
818
port_priv->network_state = value;
826
nodnic_port_set_dma_connectx3(
827
IN nodnic_port_priv *port_priv,
831
mlx_utils *utils = port_priv->device->utils;
832
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
833
mlx_uint32 data = (value ? 0xffffffff : 0x0);
834
mlx_pci_mem_write(utils, MlxPciWidthUint32, 0,
835
(mlx_uint64)&(ptr->dma_en), 1, &data);
843
IN nodnic_port_priv *port_priv,
847
return nodnic_port_set(port_priv, nodnic_port_option_dma_en, value);
852
nodnic_port_check_and_set_dma(
853
IN nodnic_port_priv *port_priv,
857
mlx_status status = MLX_SUCCESS;
858
if ( port_priv->dma_state == value ) {
859
MLX_DEBUG_WARN(port_priv->device,
860
"nodnic_port_check_and_set_dma: already %s\n",
861
(value ? "enabled" : "disabled"));
862
status = MLX_SUCCESS;
866
status = port_priv->set_dma(port_priv, value);
867
MLX_CHECK_STATUS(port_priv->device, status, set_err,
868
"nodnic_port_set failed");
869
port_priv->dma_state = value;
877
nodnic_port_set_promisc(
878
IN nodnic_port_priv *port_priv,
881
mlx_status status = MLX_SUCCESS;
882
mlx_uint32 buffer = value;
884
status = nodnic_port_set(port_priv, nodnic_port_option_port_promisc_en, buffer);
885
MLX_CHECK_STATUS(port_priv->device, status, set_err,
886
"nodnic_port_set failed");
892
nodnic_port_set_promisc_multicast(
893
IN nodnic_port_priv *port_priv,
896
mlx_status status = MLX_SUCCESS;
897
mlx_uint32 buffer = value;
899
status = nodnic_port_set(port_priv, nodnic_port_option_port_promisc_multicast_en, buffer);
900
MLX_CHECK_STATUS(port_priv->device, status, set_err,
901
"nodnic_port_set failed");
908
IN nodnic_port_priv *port_priv
911
mlx_status status = MLX_SUCCESS;
913
if( port_priv == NULL ){
914
status = MLX_INVALID_PARAMETER;
918
status = nodnic_port_set_network(port_priv, TRUE);
919
MLX_FATAL_CHECK_STATUS(status, set_err,
920
"nodnic_port_set_network failed");
928
IN nodnic_port_priv *port_priv
931
mlx_status status = MLX_SUCCESS;
933
if( port_priv == NULL ){
934
status = MLX_INVALID_PARAMETER;
938
status = nodnic_port_set_network(port_priv, FALSE);
939
MLX_FATAL_CHECK_STATUS(status, set_err,
940
"nodnic_port_set_network failed");
947
nodnic_port_enable_dma(
948
IN nodnic_port_priv *port_priv
951
mlx_status status = MLX_SUCCESS;
953
if( port_priv == NULL ){
954
status = MLX_INVALID_PARAMETER;
958
status = nodnic_port_check_and_set_dma(port_priv, TRUE);
959
MLX_CHECK_STATUS(port_priv->device, status, set_err,
960
"nodnic_port_check_and_set_dma failed");
967
nodnic_port_disable_dma(
968
IN nodnic_port_priv *port_priv
971
mlx_status status = MLX_SUCCESS;
973
if( port_priv == NULL ){
974
status = MLX_INVALID_PARAMETER;
978
status = nodnic_port_check_and_set_dma(port_priv, FALSE);
979
MLX_CHECK_STATUS(port_priv->device, status, set_err,
980
"nodnic_port_check_and_set_dma failed");
987
nodnic_port_thin_init(
988
IN nodnic_device_priv *device_priv,
989
IN nodnic_port_priv *port_priv,
990
IN mlx_uint8 port_index
993
mlx_status status = MLX_SUCCESS;
994
mlx_boolean reset_needed = 0;
999
if( device_priv == NULL || port_priv == NULL || port_index > 1){
1000
status = MLX_INVALID_PARAMETER;
1004
port_priv->device = device_priv;
1006
port_priv->port_offset = device_priv->device_offset +
1007
nodnic_port_offset_table[port_index];
1009
port_priv->port_num = port_index + 1;
1011
port_priv->send_doorbell = nodnic_port_update_ring_doorbell;
1012
port_priv->recv_doorbell = nodnic_port_update_ring_doorbell;
1013
port_priv->set_dma = nodnic_port_set_dma;
1015
if (device_priv->device_cap.crspace_doorbells) {
1016
status = nodnic_cmd_read(device_priv, (port_priv->port_offset + 0x100),
1018
if (status != MLX_SUCCESS) {
1021
port_priv->data_flow_gw = (nodnic_port_data_flow_gw *)
1022
(device_priv->utils->config + offset);
1024
if ( nodnic_port_set ( port_priv, nodnic_port_option_crspace_en, 1 ) ) {
1027
port_priv->send_doorbell = nodnic_port_send_db_connectx3;
1028
port_priv->recv_doorbell = nodnic_port_recv_db_connectx3;
1029
port_priv->set_dma = nodnic_port_set_dma_connectx3;
1032
/* clear reset_needed */
1033
nodnic_port_read_reset_needed(port_priv, &reset_needed);
1035
port_priv->port_type = NODNIC_PORT_TYPE_UNKNOWN;