int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) { struct mlx4_cmd_mailbox *inmailbox, *outmailbox; u8 *inbuf, *outbuf; int err; inmailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(inmailbox)) return PTR_ERR(inmailbox); outmailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(outmailbox)) { mlx4_free_cmd_mailbox(dev, inmailbox); return PTR_ERR(outmailbox); } inbuf = inmailbox->buf; outbuf = outmailbox->buf; memset(inbuf, 0, 256); memset(outbuf, 0, 256); inbuf[0] = 1; inbuf[1] = 1; inbuf[2] = 1; inbuf[3] = 1; *(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015); *(__be32 *) (&inbuf[20]) = cpu_to_be32(port); err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3, MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); if (!err) *caps = *(__be32 *) (outbuf + 84); mlx4_free_cmd_mailbox(dev, inmailbox); mlx4_free_cmd_mailbox(dev, outmailbox); return err; }
int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv) { panic("Disabled"); #if 0 // AKAROS_PORT struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_vlan_fltr_mbox *filter; int i; int j; int index = 0; uint32_t entry; int err = 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); filter = mailbox->buf; for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { entry = 0; for (j = 0; j < 32; j++) if (test_bit(index++, priv->active_vlans)) entry |= 1 << j; filter->entry[i] = cpu_to_be32(entry); } err = mlx4_cmd(dev, mailbox->dma, priv->port, 0, MLX4_CMD_SET_VLAN_FLTR, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); mlx4_free_cmd_mailbox(dev, mailbox); return err; #endif }
static int mlx4_SET_PORT(struct mlx4_ib_dev *dev, u8 port, int reset_qkey_viols, u32 cap_mask) { struct mlx4_cmd_mailbox *mailbox; int err; mailbox = mlx4_alloc_cmd_mailbox(dev->dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memset(mailbox->buf, 0, 256); if (dev->dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { *(u8 *) mailbox->buf = !!reset_qkey_viols << 6; ((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask); } else { ((u8 *) mailbox->buf)[3] = !!reset_qkey_viols; ((__be32 *) mailbox->buf)[1] = cpu_to_be32(cap_mask); } err = mlx4_cmd(dev->dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev->dev, mailbox); return err; }
int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, u32 cqn, u16 xrcd, struct mlx4_mtt *mtt, u64 db_rec, struct mlx4_srq *srq) { struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table; struct mlx4_cmd_mailbox *mailbox; struct mlx4_srq_context *srq_context; u64 mtt_addr; int err; err = mlx4_srq_alloc_icm(dev, &srq->srqn); if (err) return err; spin_lock_irq(&srq_table->lock); err = radix_tree_insert(&srq_table->tree, srq->srqn, srq); spin_unlock_irq(&srq_table->lock); if (err) goto err_icm; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) { err = PTR_ERR(mailbox); goto err_radix; } srq_context = mailbox->buf; memset(srq_context, 0, sizeof *srq_context); srq_context->state_logsize_srqn = cpu_to_be32((ilog2(srq->max) << 24) | srq->srqn); srq_context->logstride = srq->wqe_shift - 4; srq_context->xrcd = cpu_to_be16(xrcd); srq_context->pg_offset_cqn = cpu_to_be32(cqn & 0xffffff); srq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; mtt_addr = mlx4_mtt_addr(dev, mtt); srq_context->mtt_base_addr_h = mtt_addr >> 32; srq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff); srq_context->pd = cpu_to_be32(pdn); srq_context->db_rec_addr = cpu_to_be64(db_rec); err = mlx4_SW2HW_SRQ(dev, mailbox, srq->srqn); mlx4_free_cmd_mailbox(dev, mailbox); if (err) goto err_radix; atomic_set(&srq->refcount, 1); init_completion(&srq->free); return 0; err_radix: spin_lock_irq(&srq_table->lock); radix_tree_delete(&srq_table->tree, srq->srqn); spin_unlock_irq(&srq_table->lock); err_icm: mlx4_srq_free_icm(dev, srq->srqn); return err; }
int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, u8 promisc) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_port_rqp_calc_context *context; int err; u32 in_mod; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); context = mailbox->buf; memset(context, 0, sizeof *context); context->base_qpn = cpu_to_be32(base_qpn); context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | base_qpn); context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_SHIFT | base_qpn); context->intra_no_vlan = 0; context->no_vlan = MLX4_NO_VLAN_IDX; context->intra_vlan_miss = 0; context->vlan_miss = MLX4_VLAN_MISS_IDX; in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port; err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) { struct mlx4_en_query_port_context *qport_context; struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); struct mlx4_en_port_state *state = &priv->port_state; struct mlx4_cmd_mailbox *mailbox; int err; mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memset(mailbox->buf, 0, sizeof(*qport_context)); err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0, MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B); if (err) goto out; qport_context = mailbox->buf; /* This command is always accessed from Ethtool context * already synchronized, no need in locking */ state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) == MLX4_EN_1G_SPEED) state->link_speed = 1000; else state->link_speed = 10000; state->transciver = qport_context->transceiver; out: mlx4_free_cmd_mailbox(mdev->dev, mailbox); return err; }
int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_vlan_fltr_mbox *filter; int i; int j; int index = 0; u32 entry; int err = 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); filter = mailbox->buf; memset(filter, 0, sizeof(*filter)); for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { entry = 0; for (j = 0; j < 32; j++) if (test_bit(index++, priv->active_vlans)) entry |= 1 << j; filter->entry[i] = cpu_to_be32(entry); } err = mlx4_cmd(dev, mailbox->dma, priv->port, 0, MLX4_CMD_SET_VLAN_FLTR, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_vlan_fltr_mbox *filter; int i; int j; int index = 0; u32 entry; int err = 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); filter = mailbox->buf; if (grp) { memset(filter, 0, sizeof *filter); for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { entry = 0; for (j = 0; j < 32; j++) if (vlan_group_get_device(grp, index++)) entry |= 1 << j; filter->entry[i] = cpu_to_be32(entry); } } else { /* When no vlans are configured we block all vlans */ memset(filter, 0, sizeof(*filter)); } err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_VLAN_FLTR, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_port_general_context *context; int err; u32 in_mod; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); context = mailbox->buf; memset(context, 0, sizeof *context); context->flags = SET_PORT_GEN_ALL_VALID; context->mtu = cpu_to_be16(mtu); context->pptx = (pptx * (!pfctx)) << 7; context->pfctx = pfctx; context->pprx = (pprx * (!pfcrx)) << 7; context->pfcrx = pfcrx; in_mod = MLX4_SET_PORT_GENERAL << 8 | port; err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_disable_32_14_4_e_read(struct mlx4_dev *dev, u8 *config, int port) { struct mlx4_congestion_control_mb_prio_802_1_qau_params *hw_qcn; struct mlx4_cmd_mailbox *mailbox_out = NULL; u64 mailbox_in_dma = 0; u32 inmod = 0; int err = 0; if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QCN)) return -EOPNOTSUPP; mailbox_out = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox_out)) return -ENOMEM; hw_qcn = (struct mlx4_congestion_control_mb_prio_802_1_qau_params *) mailbox_out->buf; inmod = port | 1 << 8 | (MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT << 16); err = mlx4_cmd_box(dev, mailbox_in_dma, mailbox_out->dma, inmod, MLX4_CONGESTION_CONTROL_GET_PARAMS, MLX4_CMD_CONGESTION_CTRL_OPCODE, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); if (!err) *config = be32_to_cpu(hw_qcn->extended_enable) >> 22; mlx4_free_cmd_mailbox(dev, mailbox_out); return err; }
int mlx4_cq_resize(struct mlx4_dev *dev, struct mlx4_cq *cq, int entries, struct mlx4_mtt *mtt) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_cq_context *cq_context; u64 mtt_addr; int err; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); cq_context = mailbox->buf; memset(cq_context, 0, sizeof *cq_context); cq_context->logsize_usrpage = cpu_to_be32(ilog2(entries) << 24); cq_context->log_page_size = mtt->page_shift - 12; mtt_addr = mlx4_mtt_addr(dev, mtt); cq_context->mtt_base_addr_h = mtt_addr >> 32; cq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff); err = mlx4_MODIFY_CQ(dev, mailbox, cq->cqn, 0); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, uint8_t port) { struct mlx4_en_query_port_context *qport_context; struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); struct mlx4_en_port_state *state = &priv->port_state; struct mlx4_cmd_mailbox *mailbox; int err; mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0, MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); if (err) goto out; qport_context = mailbox->buf; /* This command is always accessed from Ethtool context * already synchronized, no need in locking */ state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); switch (qport_context->link_speed & MLX4_EN_SPEED_MASK) { case MLX4_EN_100M_SPEED: state->link_speed = SPEED_100; break; case MLX4_EN_1G_SPEED: state->link_speed = SPEED_1000; break; case MLX4_EN_10G_SPEED_XAUI: case MLX4_EN_10G_SPEED_XFI: state->link_speed = SPEED_10000; break; case MLX4_EN_20G_SPEED: state->link_speed = SPEED_20000; break; case MLX4_EN_40G_SPEED: state->link_speed = SPEED_40000; break; case MLX4_EN_56G_SPEED: state->link_speed = SPEED_56000; break; default: state->link_speed = -1; break; } state->transceiver = qport_context->transceiver; state->flags = 0; /* Reset and recalculate the port flags */ state->flags |= (qport_context->link_up & MLX4_EN_ANC_MASK) ? MLX4_EN_PORT_ANC : 0; state->flags |= (qport_context->autoneg & MLX4_EN_AUTONEG_MASK) ? MLX4_EN_PORT_ANE : 0; out: mlx4_free_cmd_mailbox(mdev->dev, mailbox); return err; }
static #endif int mlx4_en_dcbnl_ieee_getqcnstats(struct net_device *dev, struct ieee_qcn_stats *qcn_stats) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_congestion_control_mb_prio_802_1_qau_statistics *hw_qcn_stats; struct mlx4_cmd_mailbox *mailbox_out = NULL; u64 mailbox_in_dma = 0; u32 inmod = 0; int i, err; if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QCN)) return -EOPNOTSUPP; mailbox_out = mlx4_alloc_cmd_mailbox(priv->mdev->dev); if (IS_ERR(mailbox_out)) return -ENOMEM; hw_qcn_stats = (struct mlx4_congestion_control_mb_prio_802_1_qau_statistics *) mailbox_out->buf; for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { inmod = priv->port | ((1<<i) << 8) | (MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT << 16); err = mlx4_cmd_box(priv->mdev->dev, mailbox_in_dma, mailbox_out->dma, inmod, MLX4_CONGESTION_CONTROL_GET_STATISTICS, MLX4_CMD_CONGESTION_CTRL_OPCODE, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); if (err) { mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_out); return err; } qcn_stats->rppp_rp_centiseconds[i] = be64_to_cpu(hw_qcn_stats->rppp_rp_centiseconds); qcn_stats->rppp_created_rps[i] = be32_to_cpu(hw_qcn_stats->rppp_created_rps); } mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_out); return 0; }
int mlx4_check_ext_port_caps(struct mlx4_dev *dev, u8 port) { struct mlx4_cmd_mailbox *inmailbox, *outmailbox; u8 *inbuf, *outbuf; int err, packet_error; inmailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(inmailbox)) return PTR_ERR(inmailbox); outmailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(outmailbox)) { mlx4_free_cmd_mailbox(dev, inmailbox); return PTR_ERR(outmailbox); } inbuf = inmailbox->buf; outbuf = outmailbox->buf; memset(inbuf, 0, 256); memset(outbuf, 0, 256); inbuf[0] = 1; inbuf[1] = 1; inbuf[2] = 1; inbuf[3] = 1; *(__be16 *) (&inbuf[16]) = MLX4_ATTR_EXTENDED_PORT_INFO; *(__be32 *) (&inbuf[20]) = cpu_to_be32(port); err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3, MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); packet_error = be16_to_cpu(*(__be16 *) (outbuf + 4)); dev->caps.ext_port_cap[port] = (!err && !packet_error) ? MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO : 0; mlx4_free_cmd_mailbox(dev, inmailbox); mlx4_free_cmd_mailbox(dev, outmailbox); return err; }
int cmd_test (struct mlx4_dev *dev, char* log) { signed long int expected_rc = 0; int ret_val = FAIL; struct mlx4_cmd_mailbox* mailbox; mailbox = mlx4_alloc_cmd_mailbox(dev); VL_CHECK_LONG_INT_VALUE(IS_ERR(mailbox), expected_rc, goto mailbox_return , log, "Mailbox allocation failed"); uprintf( "Mailbox was allocated successfuly\n"); mlx4_free_cmd_mailbox(dev, mailbox); uprintf( "Mailbox was freed successfuly\n"); ret_val = SUCCESS; mailbox_return: return ret_val; }
static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port, __be32 *entries) { struct mlx4_cmd_mailbox *mailbox; u32 in_mod; int err; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE); in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port; err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_cq_ignore_overrun(struct mlx4_dev *dev, struct mlx4_cq *cq) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_cq_context *cq_context; int err; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); cq_context = mailbox->buf; memset(cq_context, 0, sizeof *cq_context); cq_context->flags |= cpu_to_be32(MLX4_CQ_FLAG_OI); err = mlx4_MODIFY_CQ(dev, mailbox, cq->cqn, 3); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
static int rdmaoe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, struct ib_wc *in_wc, struct ib_grh *in_grh, struct ib_mad *in_mad, struct ib_mad *out_mad) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_ib_dev *dev = to_mdev(ibdev); int err; u32 inmod = dev->counters[port_num - 1] & 0xffff; int mode; if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT) return -EINVAL; mailbox = mlx4_alloc_cmd_mailbox(dev->dev); if (IS_ERR(mailbox)) return IB_MAD_RESULT_FAILURE; err = mlx4_cmd_box(dev->dev, 0, mailbox->dma, inmod, 0, MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C); if (err) err = IB_MAD_RESULT_FAILURE; else { mode = be32_to_cpu(((struct mlx4_counters *)mailbox->buf)->counter_mode) & 0xf; switch (mode) { case 0: edit_counters(mailbox->buf, out_mad->data); err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; break; case 1: edit_ext_counters(mailbox->buf, out_mad->data); err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; break; default: err = IB_MAD_RESULT_FAILURE; } } mlx4_free_cmd_mailbox(dev->dev, mailbox); return err; }
static int read_iboe_counters(struct mlx4_dev *dev, int index, u64 counters[]) { struct mlx4_cmd_mailbox *mailbox; int err; int mode; struct mlx4_counters_ext *ext; struct mlx4_counters *reg; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return -ENOMEM; err = mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C); if (err) goto out; mode = be32_to_cpu(((struct mlx4_counters *)mailbox->buf)->counter_mode) & 0xf; switch (mode) { case 0: reg = mailbox->buf; counters[0] = be64_to_cpu(reg->rx_frames); counters[1] = be64_to_cpu(reg->tx_frames); counters[2] = be64_to_cpu(reg->rx_bytes); counters[3] = be64_to_cpu(reg->tx_bytes); break; case 1: ext = mailbox->buf; counters[0] = be64_to_cpu(ext->rx_uni_frames); counters[1] = be64_to_cpu(ext->tx_uni_frames); counters[2] = be64_to_cpu(ext->rx_uni_bytes); counters[3] = be64_to_cpu(ext->tx_uni_bytes); break; default: err = -EINVAL; } out: mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_watermark) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_srq_context *srq_context; int err; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); srq_context = mailbox->buf; err = mlx4_QUERY_SRQ(dev, mailbox, srq->srqn); if (err) goto err_out; *limit_watermark = be16_to_cpu(srq_context->limit_watermark); err_out: mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) { struct mlx4_cmd_mailbox *mailbox; int err; if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) return 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memset(mailbox->buf, 0, 256); ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_disable_32_14_4_e_write(struct mlx4_dev *dev, u8 config, int port) { struct mlx4_congestion_control_mb_prio_802_1_qau_params *hw_qcn; struct mlx4_cmd_mailbox *mailbox_in = NULL; u64 mailbox_in_dma = 0; u32 inmod = 0; int err; if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QCN)) return -EOPNOTSUPP; mailbox_in = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox_in)) return -ENOMEM; mailbox_in_dma = mailbox_in->dma; hw_qcn = (struct mlx4_congestion_control_mb_prio_802_1_qau_params *)mailbox_in->buf; inmod = port | 0xff << 8 | (MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT << 16); /* Before updating QCN parameter, *need to set it's modify enable bit to 1 */ hw_qcn->modify_enable_high = cpu_to_be32(1 << 22); hw_qcn->extended_enable = cpu_to_be32(config << 22); err = mlx4_cmd(dev, mailbox_in_dma, inmod, MLX4_CONGESTION_CONTROL_SET_PARAMS, MLX4_CMD_CONGESTION_CTRL_OPCODE, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); mlx4_free_cmd_mailbox(dev, mailbox_in); return err; }
int mlx4_cq_modify(struct mlx4_dev *dev, struct mlx4_cq *cq, u16 count, u16 period) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_cq_context *cq_context; int err; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); cq_context = mailbox->buf; memset(cq_context, 0, sizeof *cq_context); cq_context->cq_max_count = cpu_to_be16(count); cq_context->cq_period = cpu_to_be16(period); err = mlx4_MODIFY_CQ(dev, mailbox, cq->cqn, 1); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, u8 promisc) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_port_rqp_calc_context *context; int err; u32 in_mod; u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ? MCAST_DIRECT : MCAST_DEFAULT; if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER && dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) return 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); context = mailbox->buf; memset(context, 0, sizeof *context); context->base_qpn = cpu_to_be32(base_qpn); context->n_mac = 0x2; context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | base_qpn); context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT | base_qpn); context->intra_no_vlan = 0; context->no_vlan = MLX4_NO_VLAN_IDX; context->intra_vlan_miss = 0; context->vlan_miss = MLX4_VLAN_MISS_IDX; in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port; err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) { struct mlx4_cmd_mailbox *mailbox; int err; u8 is_eth = dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memset(mailbox->buf, 0, 256); if (is_eth) { ((u8 *) mailbox->buf)[3] = 6; ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15); ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15); } else ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) { struct mlx4_cmd_mailbox *mailbox; int err; if (dev->caps.port_type[port] != MLX4_PORT_TYPE_IB) return 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memset(mailbox->buf, 0, 256); if (mlx4_ib_set_4k_mtu) ((__be32 *) mailbox->buf)[0] |= cpu_to_be32((1 << 22) | (1 << 21) | (5 << 12) | (2 << 4)); ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; }
int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, int port, struct ib_wc *in_wc, struct ib_grh *in_grh, void *in_mad, void *response_mad) { struct mlx4_cmd_mailbox *inmailbox, *outmailbox; void *inbox; int err; u32 in_modifier = port; u8 op_modifier = 0; inmailbox = mlx4_alloc_cmd_mailbox(dev->dev); if (IS_ERR(inmailbox)) return PTR_ERR(inmailbox); inbox = inmailbox->buf; outmailbox = mlx4_alloc_cmd_mailbox(dev->dev); if (IS_ERR(outmailbox)) { mlx4_free_cmd_mailbox(dev->dev, inmailbox); return PTR_ERR(outmailbox); } memcpy(inbox, in_mad, 256); /* * Key check traps can't be generated unless we have in_wc to * tell us where to send the trap. */ if (ignore_mkey || !in_wc) op_modifier |= 0x1; if (ignore_bkey || !in_wc) op_modifier |= 0x2; if (in_wc) { struct { __be32 my_qpn; u32 reserved1; __be32 rqpn; u8 sl; u8 g_path; u16 reserved2[2]; __be16 pkey; u32 reserved3[11]; u8 grh[40]; } *ext_info; memset(inbox + 256, 0, 256); ext_info = inbox + 256; ext_info->my_qpn = cpu_to_be32(in_wc->qp->qp_num); ext_info->rqpn = cpu_to_be32(in_wc->src_qp); ext_info->sl = in_wc->sl << 4; ext_info->g_path = in_wc->dlid_path_bits | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); ext_info->pkey = cpu_to_be16(in_wc->pkey_index); if (in_grh) memcpy(ext_info->grh, in_grh, 40); op_modifier |= 0x4; in_modifier |= in_wc->slid << 16; } err = mlx4_cmd_box(dev->dev, inmailbox->dma, outmailbox->dma, in_modifier, op_modifier, MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); if (!err) memcpy(response_mad, outmailbox->buf, 256); mlx4_free_cmd_mailbox(dev->dev, inmailbox); mlx4_free_cmd_mailbox(dev->dev, outmailbox); return err; }
int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) { struct mlx4_en_stat_out_mbox *mlx4_en_stats; struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); struct net_device_stats *stats = &priv->stats; struct mlx4_cmd_mailbox *mailbox; u64 in_mod = reset << 8 | port; int err; int i; mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); memset(mailbox->buf, 0, sizeof(*mlx4_en_stats)); err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0, MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B); if (err) goto out; mlx4_en_stats = mailbox->buf; spin_lock_bh(&priv->stats_lock); stats->rx_packets = 0; stats->rx_bytes = 0; for (i = 0; i < priv->rx_ring_num; i++) { stats->rx_packets += priv->rx_ring[i].packets; stats->rx_bytes += priv->rx_ring[i].bytes; } stats->tx_packets = 0; stats->tx_bytes = 0; for (i = 0; i < priv->tx_ring_num; i++) { stats->tx_packets += priv->tx_ring[i].packets; stats->tx_bytes += priv->tx_ring[i].bytes; } stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) + be32_to_cpu(mlx4_en_stats->RdropLength) + be32_to_cpu(mlx4_en_stats->RJBBR) + be32_to_cpu(mlx4_en_stats->RCRC) + be32_to_cpu(mlx4_en_stats->RRUNT); stats->tx_errors = be32_to_cpu(mlx4_en_stats->TDROP); stats->multicast = be64_to_cpu(mlx4_en_stats->MCAST_prio_0) + be64_to_cpu(mlx4_en_stats->MCAST_prio_1) + be64_to_cpu(mlx4_en_stats->MCAST_prio_2) + be64_to_cpu(mlx4_en_stats->MCAST_prio_3) + be64_to_cpu(mlx4_en_stats->MCAST_prio_4) + be64_to_cpu(mlx4_en_stats->MCAST_prio_5) + be64_to_cpu(mlx4_en_stats->MCAST_prio_6) + be64_to_cpu(mlx4_en_stats->MCAST_prio_7) + be64_to_cpu(mlx4_en_stats->MCAST_novlan); stats->collisions = 0; stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength); stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw); stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC); stats->rx_frame_errors = 0; stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw); stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw); stats->tx_aborted_errors = 0; stats->tx_carrier_errors = 0; stats->tx_fifo_errors = 0; stats->tx_heartbeat_errors = 0; stats->tx_window_errors = 0; priv->pkstats.broadcast = be64_to_cpu(mlx4_en_stats->RBCAST_prio_0) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_1) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_2) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_3) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_4) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_5) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_6) + be64_to_cpu(mlx4_en_stats->RBCAST_prio_7) + be64_to_cpu(mlx4_en_stats->RBCAST_novlan); priv->pkstats.rx_prio[0] = be64_to_cpu(mlx4_en_stats->RTOT_prio_0); priv->pkstats.rx_prio[1] = be64_to_cpu(mlx4_en_stats->RTOT_prio_1); priv->pkstats.rx_prio[2] = be64_to_cpu(mlx4_en_stats->RTOT_prio_2); priv->pkstats.rx_prio[3] = be64_to_cpu(mlx4_en_stats->RTOT_prio_3); priv->pkstats.rx_prio[4] = be64_to_cpu(mlx4_en_stats->RTOT_prio_4); priv->pkstats.rx_prio[5] = be64_to_cpu(mlx4_en_stats->RTOT_prio_5); priv->pkstats.rx_prio[6] = be64_to_cpu(mlx4_en_stats->RTOT_prio_6); priv->pkstats.rx_prio[7] = be64_to_cpu(mlx4_en_stats->RTOT_prio_7); priv->pkstats.tx_prio[0] = be64_to_cpu(mlx4_en_stats->TTOT_prio_0); priv->pkstats.tx_prio[1] = be64_to_cpu(mlx4_en_stats->TTOT_prio_1); priv->pkstats.tx_prio[2] = be64_to_cpu(mlx4_en_stats->TTOT_prio_2); priv->pkstats.tx_prio[3] = be64_to_cpu(mlx4_en_stats->TTOT_prio_3); priv->pkstats.tx_prio[4] = be64_to_cpu(mlx4_en_stats->TTOT_prio_4); priv->pkstats.tx_prio[5] = be64_to_cpu(mlx4_en_stats->TTOT_prio_5); priv->pkstats.tx_prio[6] = be64_to_cpu(mlx4_en_stats->TTOT_prio_6); priv->pkstats.tx_prio[7] = be64_to_cpu(mlx4_en_stats->TTOT_prio_7); spin_unlock_bh(&priv->stats_lock); out: mlx4_free_cmd_mailbox(mdev->dev, mailbox); return err; }
int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq, int collapsed) { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_cq_table *cq_table = &priv->cq_table; struct mlx4_cmd_mailbox *mailbox; struct mlx4_cq_context *cq_context; u64 mtt_addr; int err; cq->cqn = mlx4_bitmap_alloc(&cq_table->bitmap); if (cq->cqn == -1) return -ENOMEM; err = mlx4_table_get(dev, &cq_table->table, cq->cqn); if (err) goto err_out; err = mlx4_table_get(dev, &cq_table->cmpt_table, cq->cqn); if (err) goto err_put; spin_lock_irq(&cq_table->lock); err = radix_tree_insert(&cq_table->tree, cq->cqn, cq); spin_unlock_irq(&cq_table->lock); if (err) goto err_cmpt_put; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) { err = PTR_ERR(mailbox); goto err_radix; } cq_context = mailbox->buf; memset(cq_context, 0, sizeof *cq_context); cq_context->flags = cpu_to_be32(!!collapsed << 18); cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index); cq_context->comp_eqn = priv->eq_table.eq[MLX4_EQ_COMP].eqn; cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; mtt_addr = mlx4_mtt_addr(dev, mtt); cq_context->mtt_base_addr_h = mtt_addr >> 32; cq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff); cq_context->db_rec_addr = cpu_to_be64(db_rec); err = mlx4_SW2HW_CQ(dev, mailbox, cq->cqn); mlx4_free_cmd_mailbox(dev, mailbox); if (err) goto err_radix; cq->cons_index = 0; cq->arm_sn = 1; cq->uar = uar; atomic_set(&cq->refcount, 1); init_completion(&cq->free); return 0; err_radix: spin_lock_irq(&cq_table->lock); radix_tree_delete(&cq_table->tree, cq->cqn); spin_unlock_irq(&cq_table->lock); err_cmpt_put: mlx4_table_put(dev, &cq_table->cmpt_table, cq->cqn); err_put: mlx4_table_put(dev, &cq_table->table, cq->cqn); err_out: mlx4_bitmap_free(&cq_table->bitmap, cq->cqn); return err; }
int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq, unsigned vector, int collapsed, int timestamp_en) { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_cq_table *cq_table = &priv->cq_table; struct mlx4_cmd_mailbox *mailbox; struct mlx4_cq_context *cq_context; u64 mtt_addr; int err; if (vector > dev->caps.num_comp_vectors + dev->caps.comp_pool) return -EINVAL; cq->vector = vector; err = mlx4_cq_alloc_icm(dev, &cq->cqn); if (err) return err; spin_lock_irq(&cq_table->lock); err = radix_tree_insert(&cq_table->tree, cq->cqn, cq); spin_unlock_irq(&cq_table->lock); if (err) goto err_icm; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) { err = PTR_ERR(mailbox); goto err_radix; } cq_context = mailbox->buf; memset(cq_context, 0, sizeof *cq_context); cq_context->flags = cpu_to_be32(!!collapsed << 18); if (timestamp_en) cq_context->flags |= cpu_to_be32(1 << 19); cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index); cq_context->comp_eqn = priv->eq_table.eq[vector].eqn; cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; mtt_addr = mlx4_mtt_addr(dev, mtt); cq_context->mtt_base_addr_h = mtt_addr >> 32; cq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff); cq_context->db_rec_addr = cpu_to_be64(db_rec); err = mlx4_SW2HW_CQ(dev, mailbox, cq->cqn); mlx4_free_cmd_mailbox(dev, mailbox); if (err) goto err_radix; cq->cons_index = 0; cq->arm_sn = 1; cq->uar = uar; cq->eqn = priv->eq_table.eq[cq->vector].eqn; cq->irq = priv->eq_table.eq[cq->vector].irq; return 0; err_radix: spin_lock_irq(&cq_table->lock); radix_tree_delete(&cq_table->tree, cq->cqn); spin_unlock_irq(&cq_table->lock); err_icm: mlx4_cq_free_icm(dev, cq->cqn); return err; }