/* When a new command is implemented, the below table should be updated * with new command and it's version info.
*/ static u32 pfvf_cmd_versions[OCTEP_PFVF_MBOX_CMD_MAX] = {
[0 ... OCTEP_PFVF_MBOX_CMD_DEV_REMOVE] = OCTEP_PFVF_MBOX_VERSION_V1,
[OCTEP_PFVF_MBOX_CMD_GET_FW_INFO ... OCTEP_PFVF_MBOX_NOTIF_LINK_STATUS] =
OCTEP_PFVF_MBOX_VERSION_V2
};
int octep_vf_setup_mbox(struct octep_vf_device *oct)
{ int ring = 0;
oct->mbox = vzalloc(sizeof(*oct->mbox)); if (!oct->mbox) return -1;
int octep_vf_mbox_send_cmd(struct octep_vf_device *oct, union octep_pfvf_mbox_word cmd, union octep_pfvf_mbox_word *rsp)
{ struct octep_vf_mbox *mbox = oct->mbox; int ret;
if (!mbox) return OCTEP_PFVF_MBOX_CMD_STATUS_NOT_SETUP;
mutex_lock(&mbox->lock); if (pfvf_cmd_versions[cmd.s.opcode] > oct->mbox_neg_ver) {
dev_dbg(&oct->pdev->dev, "CMD:%d not supported in Version:%d\n",
cmd.s.opcode, oct->mbox_neg_ver);
mutex_unlock(&mbox->lock); return -EOPNOTSUPP;
}
ret = __octep_vf_mbox_send_cmd(oct, cmd, rsp);
mutex_unlock(&mbox->lock); return ret;
}
int octep_vf_mbox_bulk_read(struct octep_vf_device *oct, enum octep_pfvf_mbox_opcode opcode,
u8 *data, int *size)
{ struct octep_vf_mbox *mbox = oct->mbox; union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int data_len = 0, tmp_len = 0; int read_cnt, i = 0, ret;
if (!mbox) return OCTEP_PFVF_MBOX_CMD_STATUS_NOT_SETUP;
mutex_lock(&mbox->lock);
cmd.u64 = 0;
cmd.s_data.opcode = opcode;
cmd.s_data.frag = 0; /* Send cmd to read data from PF */
ret = __octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "send mbox cmd fail for data request\n");
mutex_unlock(&mbox->lock); return ret;
} /* PF sends the data length of requested CMD * in ACK
*/
data_len = *((int32_t *)rsp.s_data.data);
tmp_len = data_len;
cmd.u64 = 0;
rsp.u64 = 0;
cmd.s_data.opcode = opcode;
cmd.s_data.frag = 1; while (data_len) {
ret = __octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "send mbox cmd fail for data request\n");
mutex_unlock(&mbox->lock);
mbox->mbox_data.data_index = 0;
memset(mbox->mbox_data.recv_data, 0, OCTEP_PFVF_MBOX_MAX_DATA_BUF_SIZE); return ret;
} if (data_len > OCTEP_PFVF_MBOX_MAX_DATA_SIZE) {
data_len -= OCTEP_PFVF_MBOX_MAX_DATA_SIZE;
read_cnt = OCTEP_PFVF_MBOX_MAX_DATA_SIZE;
} else {
read_cnt = data_len;
data_len = 0;
} for (i = 0; i < read_cnt; i++) {
mbox->mbox_data.recv_data[mbox->mbox_data.data_index] =
rsp.s_data.data[i];
mbox->mbox_data.data_index++;
}
cmd.u64 = 0;
rsp.u64 = 0;
cmd.s_data.opcode = opcode;
cmd.s_data.frag = 1;
}
memcpy(data, mbox->mbox_data.recv_data, tmp_len);
*size = tmp_len;
mbox->mbox_data.data_index = 0;
memset(mbox->mbox_data.recv_data, 0, OCTEP_PFVF_MBOX_MAX_DATA_BUF_SIZE);
mutex_unlock(&mbox->lock); return 0;
}
int octep_vf_mbox_set_mtu(struct octep_vf_device *oct, int mtu)
{ int frame_size = mtu + ETH_HLEN + ETH_FCS_LEN; union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int ret = 0;
if (mtu < ETH_MIN_MTU || frame_size > ETH_MAX_MTU) {
dev_err(&oct->pdev->dev, "Failed to set MTU to %d MIN MTU:%d MAX MTU:%d\n",
mtu, ETH_MIN_MTU, ETH_MAX_MTU); return -EINVAL;
}
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Mbox send failed; err=%d\n", ret); return ret;
} if (rsp.s_set_mtu.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "Received Mbox NACK from PF for MTU:%d\n", mtu); return -EINVAL;
}
return 0;
}
int octep_vf_mbox_set_mac_addr(struct octep_vf_device *oct, char *mac_addr)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int i, ret;
cmd.u64 = 0;
cmd.s_set_mac.opcode = OCTEP_PFVF_MBOX_CMD_SET_MAC_ADDR; for (i = 0; i < ETH_ALEN; i++)
cmd.s_set_mac.mac_addr[i] = mac_addr[i];
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Mbox send failed; err = %d\n", ret); return ret;
} if (rsp.s_set_mac.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "received NACK\n"); return -EINVAL;
} return 0;
}
int octep_vf_mbox_get_mac_addr(struct octep_vf_device *oct, char *mac_addr)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int i, ret;
cmd.u64 = 0;
cmd.s_set_mac.opcode = OCTEP_PFVF_MBOX_CMD_GET_MAC_ADDR;
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "get_mac: mbox send failed; err = %d\n", ret); return ret;
} if (rsp.s_set_mac.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "get_mac: received NACK\n"); return -EINVAL;
} for (i = 0; i < ETH_ALEN; i++)
mac_addr[i] = rsp.s_set_mac.mac_addr[i]; return 0;
}
int octep_vf_mbox_set_rx_state(struct octep_vf_device *oct, bool state)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int ret;
cmd.u64 = 0;
cmd.s_link_state.opcode = OCTEP_PFVF_MBOX_CMD_SET_RX_STATE;
cmd.s_link_state.state = state;
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Set Rx state via VF Mbox send failed\n"); return ret;
} if (rsp.s_link_state.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "Set Rx state received NACK\n"); return -EINVAL;
} return 0;
}
int octep_vf_mbox_set_link_status(struct octep_vf_device *oct, bool status)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int ret;
cmd.u64 = 0;
cmd.s_link_status.opcode = OCTEP_PFVF_MBOX_CMD_SET_LINK_STATUS;
cmd.s_link_status.status = status;
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Set link status via VF Mbox send failed\n"); return ret;
} if (rsp.s_link_status.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "Set link status received NACK\n"); return -EINVAL;
} return 0;
}
int octep_vf_mbox_get_link_status(struct octep_vf_device *oct, u8 *oper_up)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int ret;
cmd.u64 = 0;
cmd.s_link_status.opcode = OCTEP_PFVF_MBOX_CMD_GET_LINK_STATUS;
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Get link status via VF Mbox send failed\n"); return ret;
} if (rsp.s_link_status.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "Get link status received NACK\n"); return -EINVAL;
}
*oper_up = rsp.s_link_status.status; return 0;
}
int octep_vf_mbox_dev_remove(struct octep_vf_device *oct)
{ union octep_pfvf_mbox_word cmd; int ret;
int octep_vf_mbox_get_fw_info(struct octep_vf_device *oct)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int ret;
cmd.u64 = 0;
cmd.s_fw_info.opcode = OCTEP_PFVF_MBOX_CMD_GET_FW_INFO;
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Get link status via VF Mbox send failed\n"); return ret;
} if (rsp.s_fw_info.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "Get link status received NACK\n"); return -EINVAL;
}
oct->fw_info.pkind = rsp.s_fw_info.pkind;
oct->fw_info.fsz = rsp.s_fw_info.fsz;
oct->fw_info.rx_ol_flags = rsp.s_fw_info.rx_ol_flags;
oct->fw_info.tx_ol_flags = rsp.s_fw_info.tx_ol_flags;
return 0;
}
int octep_vf_mbox_set_offloads(struct octep_vf_device *oct, u16 tx_offloads,
u16 rx_offloads)
{ union octep_pfvf_mbox_word cmd; union octep_pfvf_mbox_word rsp; int ret;
cmd.u64 = 0;
cmd.s_offloads.opcode = OCTEP_PFVF_MBOX_CMD_SET_OFFLOADS;
cmd.s_offloads.rx_ol_flags = rx_offloads;
cmd.s_offloads.tx_ol_flags = tx_offloads;
ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp); if (ret) {
dev_err(&oct->pdev->dev, "Set offloads via VF Mbox send failed\n"); return ret;
} if (rsp.s_link_state.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
dev_err(&oct->pdev->dev, "Set offloads received NACK\n"); return -EINVAL;
} return 0;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.