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, \ 72 #define MAX_QP_DATA_ENTRIES 5 81 #define MAX_NODNIC_PORTS 2 99 "nodnic_port_query failed");
117 "nodnic_port_query failed");
120 *
type = port_priv->port_type;
140 device_priv = port_priv->device;
147 "nodnic_cmd_read failed");
166 if( port_priv ==
NULL ){
171 device_priv = port_priv->device;
174 if(
in > data_entry->
mask ){
183 "nodnic_cmd_read failed");
189 "nodnic_cmd_write failed");
204 if ( ! port_priv->device->device_cap.support_uar_tx_db ) {
205 MLX_DEBUG_INFO1 ( port_priv,
"nodnic_port_set_send_uar_offset: tx db using uar is not supported \n");
207 goto uar_not_supported;
213 "nodnic_port_query failed");
214 port_priv->device->uar.offset =
out << port_priv->device->device_cap.log_uar_page_size;
231 "nodnic_port_query failed");
248 "nodnic_port_query failed");
270 if( port_priv ==
NULL || nodnic_db ==
NULL ){
275 device_priv = port_priv->device;
282 "doorbell record dma allocation error");
287 &nodnic_db->doorbell_physical,
291 "doorbell record map dma error");
298 "failed to set doorbell addr low");
305 "failed to set doorbell addr high");
329 if( port_priv ==
NULL ){
334 device_priv = port_priv->device;
337 goto uar_arm_cq_db_unsupported;
340 #define NODNIC_PORT_ARM_CQ_DBR_ADDR_LOW_OFFSET 0x114 341 #define NODNIC_PORT_ARM_CQ_DBR_ADDR_HIGH_OFFSET 0x110 346 (
void **)&port_priv->arm_cq_doorbell_record ,
348 (
void **)&((*cq)->arm_cq_doorbell.map));
350 "failed to allocate doorbell record dma");
354 uar_arm_cq_db_unsupported:
369 if( port_priv ==
NULL || cq ==
NULL){
374 device_priv = port_priv->device;
379 "cq priv allocation error");
381 (*cq)->cq_size = cq_size;
386 "cq allocation error");
399 #define NODIC_CQ_ADDR_HIGH 0x68 400 #define NODIC_CQ_ADDR_LOW 0x6c 405 "cq set addr low error");
410 "cq set addr high error");
412 dma_set_addr_high_err:
413 dma_set_addr_low_err:
417 (
void **)&((*cq)->cq_virt));
434 if( port_priv ==
NULL || cq ==
NULL){
438 device_priv = port_priv->device;
442 cq->arm_cq_doorbell.map);
449 (
void **)&(port_priv->arm_cq_doorbell_record));
458 (
void **)&(cq->cq_virt));
479 #define NODNIC_RING_DBR_ADDR_LOW_OFFSET 0x1C 480 #define NODNIC_RING_DBR_ADDR_HIGH_OFFSET 0x18 484 (
void **)&nodnic_db->qp_doorbell_record,
488 "failed to allocate doorbell record dma");
511 device_priv = port_priv->device;
514 goto rx_pi_dma_unsupported;
519 &(*qp)->receive.nodnic_ring,&(*qp)->receive.nodnic_ring.recv_doorbell);
521 "rx doorbell dma allocation error");
527 rx_pi_dma_unsupported:
543 ring->send_doorbell.qp_doorbell_record->send_db = swapped;
563 device_priv = port_priv->device;
567 goto uar_tx_db_unsupported;
570 &(*qp)->send.nodnic_ring,&(*qp)->send.nodnic_ring.send_doorbell);
572 "tx doorbell dma allocation error");
578 uar_tx_db_unsupported:
605 device_priv = port_priv->device;
607 if( send_wq_size > max_ring_size ||
608 receive_wq_size > max_ring_size ){
616 "qp allocation error");
624 (*qp)->send.nodnic_ring.offset = port_priv->port_offset +
626 (*qp)->receive.nodnic_ring.offset = port_priv->port_offset +
631 (
void*)&(*qp)->send.wqe_virt);
633 "send wq allocation error");
637 &(*qp)->receive.wqe_virt);
639 "receive wq allocation error");
642 (*qp)->send.wqe_virt,
644 &(*qp)->send.nodnic_ring.wqe_physical,
645 &(*qp)->send.nodnic_ring.map);
647 "send wq map error");
650 (*qp)->receive.wqe_virt,
652 &(*qp)->receive.nodnic_ring.wqe_physical,
653 &(*qp)->receive.nodnic_ring.map);
655 "receive wq map error");
659 "receive db dma error");
664 (*qp)->send.nodnic_ring.wq_size = send_wq_size;
665 (*qp)->send.nodnic_ring.num_wqes = send_wqe_num;
666 (*qp)->receive.nodnic_ring.wq_size = receive_wq_size;
667 (*qp)->receive.nodnic_ring.num_wqes = recv_wqe_num;
674 #define NODIC_RING_QP_ADDR_HIGH 0x0 675 #define NODIC_RING_QP_ADDR_LOW 0x4 681 "send address write error 1");
688 "send address write error 2");
695 "receive address write error 1");
702 "receive address write error 2");
713 &((*qp)->receive.wqe_virt));
716 (
void **)&((*qp)->send.wqe_virt));
736 qp->receive.nodnic_ring.map);
748 qp->receive.nodnic_ring.recv_doorbell.map);
755 (
void **)&(
qp->receive.nodnic_ring.recv_doorbell.qp_doorbell_record));
763 qp->send.nodnic_ring.send_doorbell.map);
770 (
void **)&(
qp->send.nodnic_ring.send_doorbell.qp_doorbell_record));
777 qp->receive.nodnic_ring.wq_size,
778 (
void **)&(
qp->receive.wqe_virt));
783 qp->send.nodnic_ring.wq_size,
784 (
void **)&(
qp->send.wqe_virt));
808 if( ring->qpn != 0 ){
812 #define NODNIC_RING_QPN_OFFSET 0xc 813 #define NODNIC_RING_QPN_MASK 0xFFFFFF 818 "nodnic_cmd_read failed");
830 nodnic_port_send_db_connectx3(
836 nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
839 (
mlx_uintn)&(ptr->send_doorbell), 1, &index32);
845 nodnic_port_recv_db_connectx3(
851 nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
854 (
mlx_uintn)&(ptr->recv_doorbell), 1, &index32);
869 ring->recv_doorbell.qp_doorbell_record->recv_db = swapped;
886 #define NODNIC_RING_RING_OFFSET 0x8 892 "nodnic_cmd_write failed");
908 "nodnic_port_query failed");
924 if( port_priv ==
NULL ){
929 device_priv = port_priv->device;
930 port_priv->eq.eq_size = ( ( 1 << log_eq_size ) * 1024 );
932 port_priv->eq.eq_size,
934 &port_priv->eq.eq_virt);
936 "eq allocation error");
939 port_priv->eq.eq_virt,
940 port_priv->eq.eq_size,
941 &port_priv->eq.eq_physical,
946 address = port_priv->eq.eq_physical;
950 "failed to set eq addr low");
955 "failed to set eq addr high");
961 port_priv->eq.eq_size,
962 (
void **)&(port_priv->eq.eq_virt));
975 if( port_priv ==
NULL ){
980 device_priv = port_priv->device;
984 port_priv->eq.eq_size,
985 (
void **)&(port_priv->eq.eq_virt));
1006 if( port_priv ==
NULL){
1011 device = port_priv->device;
1021 goto already_exists;
1028 sizeof(zero_mac), &
out);
1041 "nodnic_port_query failed");
1042 if(mac_filters_en & (1 <<
index)){
1046 port_priv->mac_filters[
index] =
mac;
1058 mac_filters_en = mac_filters_en | (1 <<
index);
1062 "nodnic_port_set failed");
1086 if( port_priv ==
NULL){
1091 device = port_priv->device;
1111 "nodnic_port_query failed");
1112 if((mac_filters_en & (1 <<
index)) == 0){
1116 port_priv->mac_filters[
index] = zero_mac;
1119 mac_filters_en = mac_filters_en & ~(1 <<
index);
1123 "nodnic_port_set failed");
1145 "nodnic_port_set failed");
1146 port_priv->network_state =
value;
1154 nodnic_port_set_dma_connectx3(
1159 mlx_utils *utils = port_priv->device->utils;
1160 nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
1186 if ( port_priv->dma_state ==
value ) {
1188 "nodnic_port_check_and_set_dma: already %s\n",
1189 (
value ?
"enabled" :
"disabled"));
1196 "nodnic_port_set failed");
1197 port_priv->dma_state =
value;
1214 "nodnic_port_set failed");
1229 "nodnic_port_set failed");
1241 if( port_priv ==
NULL ){
1248 "nodnic_port_set_network failed");
1261 if( port_priv ==
NULL ){
1268 "nodnic_port_set_network failed");
1281 if( port_priv ==
NULL ){
1288 "nodnic_port_check_and_set_dma failed");
1301 if( port_priv ==
NULL ){
1308 "nodnic_port_check_and_set_dma failed");
1327 if( device_priv ==
NULL || port_priv ==
NULL || port_index > 1){
1332 port_priv->device = device_priv;
1334 port_priv->port_offset = device_priv->device_offset +
1337 port_priv->port_num = port_index + 1;
1343 if (device_priv->device_cap.crspace_doorbells) {
1349 port_priv->data_flow_gw = (nodnic_port_data_flow_gw *)
1350 (device_priv->utils->config +
offset);
1352 if (
nodnic_port_set ( port_priv, nodnic_port_option_crspace_en, 1 ) ) {
1355 port_priv->send_doorbell = nodnic_port_send_db_connectx3;
1356 port_priv->recv_doorbell = nodnic_port_recv_db_connectx3;
1357 port_priv->set_dma = nodnic_port_set_dma_connectx3;
1360 if ( device_priv->device_cap.support_rx_pi_dma ) {
#define NODNIC_RING_QPN_MASK
mlx_status nodnic_port_set(IN nodnic_port_priv *port_priv, IN nodnic_port_option option, IN mlx_uint32 in)
mlx_status nodnic_port_remove_mac_filter(IN nodnic_port_priv *port_priv, IN mlx_mac_address mac)
static mlx_status nodnic_port_check_and_set_dma(IN nodnic_port_priv *port_priv, IN mlx_boolean value)
#define NODNIC_RING_RING_OFFSET
mlx_status mlx_memory_cpu_to_be32(IN mlx_utils *utils, IN mlx_uint32 source, IN mlx_uint32 *destination)
static mlx_status nodnic_port_tx_dbr_dma_init(IN nodnic_port_priv *port_priv, OUT nodnic_qp **qp)
#define QpDataEntry(_type, _send_offset, _recv_offset)
mlx_status nodnic_port_get_qpn(IN nodnic_port_priv *port_priv, IN struct nodnic_ring *ring, OUT mlx_uint32 *qpn)
#define MLX_INVALID_PARAMETER
#define NODNIC_RING_DBR_ADDR_LOW_OFFSET
mlx_status nodnic_port_create_cq(IN nodnic_port_priv *port_priv, IN mlx_size cq_size, OUT nodnic_cq **cq)
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)
mlx_status nodnic_port_update_ring_doorbell(IN nodnic_port_priv *port_priv, IN struct nodnic_ring *ring, IN mlx_uint16 index)
#define MAX_QP_DATA_ENTRIES
mlx_status nodnic_port_set_send_uar_offset(IN nodnic_port_priv *port_priv)
mlx_status nodnic_port_destroy_cq(IN nodnic_port_priv *port_priv, IN nodnic_cq *cq)
uint64_t address
Base address.
uint32_t type
Operating system type.
mlx_status nodnic_port_set_promisc(IN nodnic_port_priv *port_priv, IN mlx_boolean value)
#define NODNIC_PORT_ARM_CQ_DBR_ADDR_LOW_OFFSET
mlx_status nodnic_port_destroy_qp(IN nodnic_port_priv *port_priv, IN nodnic_queue_pair_type type, IN nodnic_qp *qp)
mlx_status nodnic_port_init(IN nodnic_port_priv *port_priv)
mlx_status nodnic_port_set_promisc_multicast(IN nodnic_port_priv *port_priv, IN mlx_boolean value)
mlx_status nodnic_port_close(IN nodnic_port_priv *port_priv)
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
uint8_t mac[ETH_ALEN]
MAC address.
static mlx_status nodnic_port_allocate_dbr_dma(IN nodnic_port_priv *port_priv, IN struct nodnic_doorbell *nodnic_db, IN mlx_uint32 dbr_addr_low_ofst, IN mlx_uint32 dbr_addr_high_ofst, IN void **dbr_addr, IN mlx_size size, IN void **map)
mlx_uint8 support_rx_pi_dma
mlx_status nodnic_cmd_write(IN nodnic_device_priv *device_priv, IN mlx_uint32 address, IN mlx_pci_gw_buffer buffer)
mlx_status nodnic_port_read_port_management_change_event(IN nodnic_port_priv *port_priv, OUT mlx_boolean *change_event)
#define MLX_DEBUG_WARN(...)
static mlx_status nodnic_port_recv_db_dma(IN nodnic_port_priv *port_priv, IN struct nodnic_ring *ring, IN mlx_uint16 index)
#define NODIC_RING_QP_ADDR_HIGH
#define NODNIC_RING_DBR_ADDR_HIGH_OFFSET
mlx_status mlx_memory_map_dma(IN mlx_utils *utils, IN mlx_void *Addr, IN mlx_size NumberOfBytes, OUT mlx_physical_address *PhysAddr, OUT mlx_void **Mapping)
mlx_status mlx_utils_ilog2(IN mlx_uint32 i, OUT mlx_uint32 *log)
mlx_status mlx_memory_free(IN mlx_utils *utils, IN mlx_void **ptr)
#define NODNIC_PORT_ARM_CQ_DBR_ADDR_HIGH_OFFSET
mlx_status mlx_memory_set(IN mlx_utils *utils, IN mlx_void *block, IN mlx_int32 value, IN mlx_size size)
#define NODNIC_PORT_MAC_FILTERS_OFFSET
static mlx_status nodnic_port_set_network(IN nodnic_port_priv *port_priv, IN mlx_boolean value)
#define NODIC_RING_QP_ADDR_LOW
mlx_status mlx_memory_ummap_dma(IN mlx_utils *utils, IN mlx_void *Mapping)
A long option, as used for getopt_long()
mlx_status mlx_memory_cmp(IN mlx_utils *utils, IN mlx_void *first_block, IN mlx_void *second_block, IN mlx_size size, OUT mlx_uint32 *out)
pseudo_bit_t value[0x00020]
mlx_status nodnic_port_disable_dma(IN nodnic_port_priv *port_priv)
nodnic_device_capabilites device_cap
mlx_status mlx_memory_free_dma(IN mlx_utils *utils, IN mlx_size size, IN mlx_void **ptr)
mlx_status nodnic_port_add_mac_filter(IN nodnic_port_priv *port_priv, IN mlx_mac_address mac)
#define NODNIC_RING_QPN_OFFSET
static mlx_status nodnic_port_send_db_dma(IN nodnic_port_priv *port_priv, IN struct nodnic_ring *ring, IN mlx_uint16 index)
mlx_status nodnic_port_thin_init(IN nodnic_device_priv *device_priv, IN nodnic_port_priv *port_priv, IN mlx_uint8 port_index)
mlx_uint8 support_bar_cq_ctrl
static mlx_status nodnic_port_rx_pi_dma_alloc(IN nodnic_port_priv *port_priv, OUT nodnic_qp **qp)
struct nodnic_qp_data_entry nodnic_qp_data_teable[MAX_QP_DATA_ENTRIES]
#define MLX_FATAL_CHECK_STATUS(status, label, message)
mlx_status nodnic_port_get_type(IN nodnic_port_priv *port_priv, OUT nodnic_port_type *type)
mlx_status nodnic_port_allocate_eq(IN nodnic_port_priv *port_priv, IN mlx_uint8 log_eq_size)
static __always_inline int struct dma_mapping * map
mlx_uint8 support_uar_tx_db
nodnic_port_option option
struct arbelprm_qp_db_record qp
mlx_status nodnic_port_enable_dma(IN nodnic_port_priv *port_priv)
#define MLX_DEBUG_FATAL_ERROR(...)
static mlx_status nodnic_port_cq_dbr_dma_init(IN nodnic_port_priv *port_priv, OUT nodnic_cq **cq)
mlx_status nodnic_port_get_state(IN nodnic_port_priv *port_priv, OUT nodnic_port_state *state)
mlx_status mlx_memory_zalloc(IN mlx_utils *utils, IN mlx_size size, OUT mlx_void **ptr)
int nodnic_port_offset_table[MAX_NODNIC_PORTS]
#define MLX_DEBUG_ERROR(...)
mlx_uint8 log_max_ring_size
#define NODNIC_MEMORY_ALIGN
uint8_t size
Entry size (in 32-bit words)
uint8_t data[48]
Additional event data.
static mlx_status nodnic_port_allocate_ring_db_dma(IN nodnic_port_priv *port_priv, IN struct nodnic_ring *nodnic_ring, IN struct nodnic_doorbell *nodnic_db)
#define MLX_DEBUG_INFO1(...)
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)
#define PortDataEntry(_option, _offset, _align, _mask)
struct nodnic_port_data_entry nodnic_port_data_table[]
mlx_status nodnic_port_read_reset_needed(IN nodnic_port_priv *port_priv, OUT mlx_boolean *reset_needed)
uint16_t offset
Offset to command line.
#define NODNIC_MAX_MAC_FILTERS
mlx_status mlx_memory_alloc_dma(IN mlx_utils *utils, IN mlx_size size, IN mlx_size align, OUT mlx_void **ptr)
mlx_status nodnic_port_query(IN nodnic_port_priv *port_priv, IN nodnic_port_option option, OUT mlx_uint32 *out)
FILE_LICENCE(GPL2_OR_LATER)
static mlx_status nodnic_port_set_dma(IN nodnic_port_priv *port_priv, IN mlx_boolean value)
#define MLX_CHECK_STATUS(id, status, label, message)
mlx_status nodnic_cmd_read(IN nodnic_device_priv *device_priv, IN mlx_uint32 address, OUT mlx_pci_gw_buffer *buffer)
#define NULL
NULL pointer (VOID *)
mlx_status nodnic_port_free_eq(IN nodnic_port_priv *port_priv)
mlx_status nodnic_port_get_cq_size(IN nodnic_port_priv *port_priv, OUT mlx_uint64 *cq_size)