static int qlcnic_irq_test(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); int max_sds_rings = adapter->max_sds_rings; int ret; if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); if (ret) goto clear_it; adapter->diag_cnt = 0; ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, adapter->portnum, 0, 0, 0x00000011); if (ret) goto done; msleep(10); ret = !adapter->diag_cnt; done: qlcnic_diag_free_res(netdev, max_sds_rings); clear_it: adapter->max_sds_rings = max_sds_rings; clear_bit(__QLCNIC_RESETTING, &adapter->state); return ret; }
static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter) { struct qlcnic_sriov *sriov = adapter->ahw->sriov; struct qlcnic_cmd_args cmd; int ret = 0; memset(&cmd, 0, sizeof(cmd)); ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd, QLCNIC_BC_CMD_GET_ACL); if (ret) return ret; ret = qlcnic_issue_cmd(adapter, &cmd); if (ret) { dev_err(&adapter->pdev->dev, "Failed to get ACL, err=%d\n", ret); } else { sriov->vlan_mode = cmd.rsp.arg[1] & 0x3; switch (sriov->vlan_mode) { case QLC_GUEST_VLAN_MODE: ret = qlcnic_sriov_set_guest_vlan_mode(adapter, &cmd); break; case QLC_PVID_MODE: ret = qlcnic_sriov_set_pvid_mode(adapter, &cmd); break; } } qlcnic_free_mbx_args(&cmd); return ret; }
/* Get MAC address of a NIC partition */ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) { int err; u32 arg1; arg1 = adapter->ahw.pci_func | BIT_8; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, 0, 0, QLCNIC_CDRP_CMD_MAC_ADDRESS); if (err == QLCNIC_RCODE_SUCCESS) qlcnic_fetch_mac(adapter, QLCNIC_ARG1_CRB_OFFSET, QLCNIC_ARG2_CRB_OFFSET, 0, mac); else { dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n", err); err = -EIO; } return err; }
/* Configure eSwitch for port mirroring */ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, u8 enable_mirroring, u8 pci_func) { int err = -EIO; u32 arg1; if (adapter->op_mode != QLCNIC_MGMT_FUNC || !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) return err; arg1 = id | (enable_mirroring ? BIT_4 : 0); arg1 |= pci_func << 8; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, 0, 0, QLCNIC_CDRP_CMD_SET_PORTMIRRORING); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, "Failed to configure port mirroring%d on eswitch:%d\n", pci_func, id); } else { dev_info(&adapter->pdev->dev, "Configured eSwitch %d for port mirroring:%d\n", id, pci_func); } return err; }
/* Set MAC address of a NIC partition */ int qlcnic_set_mac_address(struct qlcnic_adapter *adapter, u8* mac) { int err = 0; u32 arg1, arg2, arg3; arg1 = adapter->ahw.pci_func | BIT_9; arg2 = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24); arg3 = mac[4] | (mac[5] << 16); err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, arg2, arg3, QLCNIC_CDRP_CMD_MAC_ADDRESS); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, "Failed to set mac address%d\n", err); err = -EIO; } return err; }
int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val) { return qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, reg, val, 0, QLCNIC_CDRP_CMD_WRITE_PHY); }
/* Get info of a NIC partition */ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *npar_info, u8 func_id) { int err; dma_addr_t nic_dma_t; struct qlcnic_info *nic_info; void *nic_info_addr; size_t nic_size = sizeof(struct qlcnic_info); nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size, &nic_dma_t); if (!nic_info_addr) return -ENOMEM; memset(nic_info_addr, 0, nic_size); nic_info = (struct qlcnic_info *) nic_info_addr; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, MSD(nic_dma_t), LSD(nic_dma_t), (func_id << 16 | nic_size), QLCNIC_CDRP_CMD_GET_NIC_INFO); if (err == QLCNIC_RCODE_SUCCESS) { npar_info->pci_func = le16_to_cpu(nic_info->pci_func); npar_info->op_mode = le16_to_cpu(nic_info->op_mode); npar_info->phys_port = le16_to_cpu(nic_info->phys_port); npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode); npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques); npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw); npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw); npar_info->capabilities = le32_to_cpu(nic_info->capabilities); npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); dev_info(&adapter->pdev->dev, "phy port: %d switch_mode: %d,\n" "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n" "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n", npar_info->phys_port, npar_info->switch_mode, npar_info->max_tx_ques, npar_info->max_rx_ques, npar_info->min_tx_bw, npar_info->max_tx_bw, npar_info->max_mtu, npar_info->capabilities); } else { dev_err(&adapter->pdev->dev, "Failed to get nic info%d\n", err); err = -EIO; } pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t); return err; }
static void qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter) { if (qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, adapter->tx_context_id, QLCNIC_DESTROY_CTX_RESET, 0, QLCNIC_CDRP_CMD_DESTROY_TX_CTX)) { dev_err(&adapter->pdev->dev, "Failed to destroy tx ctx in firmware\n"); } }
/* Get PCI Info of a partition */ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, struct qlcnic_pci_info *pci_info) { int err = 0, i; dma_addr_t pci_info_dma_t; struct qlcnic_pci_info *npar; void *pci_info_addr; size_t npar_size = sizeof(struct qlcnic_pci_info); size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC; pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size, &pci_info_dma_t); if (!pci_info_addr) return -ENOMEM; memset(pci_info_addr, 0, pci_size); npar = (struct qlcnic_pci_info *) pci_info_addr; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, MSD(pci_info_dma_t), LSD(pci_info_dma_t), pci_size, QLCNIC_CDRP_CMD_GET_PCI_INFO); if (err == QLCNIC_RCODE_SUCCESS) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { pci_info->id = le32_to_cpu(npar->id); pci_info->active = le32_to_cpu(npar->active); pci_info->type = le32_to_cpu(npar->type); pci_info->default_port = le32_to_cpu(npar->default_port); pci_info->tx_min_bw = le32_to_cpu(npar->tx_min_bw); pci_info->tx_max_bw = le32_to_cpu(npar->tx_max_bw); memcpy(pci_info->mac, npar->mac, ETH_ALEN); } } else { dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n", err); err = -EIO; } pci_free_consistent(adapter->pdev, pci_size, pci_info_addr, pci_info_dma_t); return err; }
/* Configure a NIC partition */ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) { int err = -EIO; dma_addr_t nic_dma_t; void *nic_info_addr; struct qlcnic_info *nic_info; size_t nic_size = sizeof(struct qlcnic_info); if (adapter->op_mode != QLCNIC_MGMT_FUNC) return err; nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size, &nic_dma_t); if (!nic_info_addr) return -ENOMEM; memset(nic_info_addr, 0, nic_size); nic_info = (struct qlcnic_info *)nic_info_addr; nic_info->pci_func = cpu_to_le16(nic->pci_func); nic_info->op_mode = cpu_to_le16(nic->op_mode); nic_info->phys_port = cpu_to_le16(nic->phys_port); nic_info->switch_mode = cpu_to_le16(nic->switch_mode); nic_info->capabilities = cpu_to_le32(nic->capabilities); nic_info->max_mac_filters = nic->max_mac_filters; nic_info->max_tx_ques = cpu_to_le16(nic->max_tx_ques); nic_info->max_rx_ques = cpu_to_le16(nic->max_rx_ques); nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw); nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw); err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, MSD(nic_dma_t), LSD(nic_dma_t), ((nic->pci_func << 16) | nic_size), QLCNIC_CDRP_CMD_SET_NIC_INFO); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n", err); err = -EIO; } pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t); return err; }
int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val) { if (qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, reg, 0, 0, QLCNIC_CDRP_CMD_READ_PHY)) { return -EIO; } return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); }
static void qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter) { struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; if (qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, recv_ctx->context_id, QLCNIC_DESTROY_CTX_RESET, 0, QLCNIC_CDRP_CMD_DESTROY_RX_CTX)) { dev_err(&adapter->pdev->dev, "Failed to destroy rx ctx in firmware\n"); } recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED; }
static int qlcnic_irq_test(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_cmd_args cmd; int ret, max_sds_rings = adapter->max_sds_rings; if (qlcnic_83xx_check(adapter)) return qlcnic_83xx_interrupt_test(netdev); if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); if (ret) goto clear_diag_irq; ahw->diag_cnt = 0; ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST); if (ret) goto free_diag_res; cmd.req.arg[1] = ahw->pci_func; ret = qlcnic_issue_cmd(adapter, &cmd); if (ret) goto done; usleep_range(1000, 12000); ret = !ahw->diag_cnt; done: qlcnic_free_mbx_args(&cmd); free_diag_res: qlcnic_diag_free_res(netdev, max_sds_rings); clear_diag_irq: adapter->max_sds_rings = max_sds_rings; clear_bit(__QLCNIC_RESETTING, &adapter->state); return ret; }
int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu) { struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) { if (qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, recv_ctx->context_id, mtu, 0, QLCNIC_CDRP_CMD_SET_MTU)) { dev_err(&adapter->pdev->dev, "Failed to set mtu\n"); return -EIO; } } return 0; }
/* Configure eSwitch port */ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id, int vlan_tagging, u8 discard_tagged, u8 promsc_mode, u8 mac_learn, u8 pci_func, u16 vlan_id) { int err = -EIO; u32 arg1; struct qlcnic_eswitch *eswitch; if (adapter->op_mode != QLCNIC_MGMT_FUNC) return err; eswitch = &adapter->eswitch[id]; if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE)) return err; arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0); arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0); arg1 |= pci_func << 8; if (vlan_tagging) arg1 |= BIT_5 | (vlan_id << 16); err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, 0, 0, QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, "Failed to configure eswitch port%d\n", eswitch->port); } else { dev_info(&adapter->pdev->dev, "Configured eSwitch for port %d\n", eswitch->port); } return err; }
/* Get eSwitch Capabilities */ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, struct qlcnic_eswitch *eswitch) { int err = -EIO; u32 arg1, arg2; if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) return err; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, port, 0, 0, QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY); if (err == QLCNIC_RCODE_SUCCESS) { arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); eswitch->port = arg1 & 0xf; eswitch->active_vports = LSB(arg2); eswitch->max_ucast_filters = MSB(arg2); eswitch->max_active_vlans = LSB(MSW(arg2)); if (arg1 & BIT_6) eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; if (arg1 & BIT_7) eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE; if (arg1 & BIT_8) eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; } else { dev_err(&adapter->pdev->dev, "Failed to get eswitch capabilities%d\n", err); } return err; }
int qlcnic_reset_partition(struct qlcnic_adapter *adapter, u8 func_no) { int err = -EIO; if (adapter->op_mode != QLCNIC_MGMT_FUNC) return err; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, func_no, 0, 0, QLCNIC_CDRP_CMD_RESET_NPAR); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, "Failed to issue reset partition%d\n", err); err = -EIO; } return err; }
/* Enable/Disable eSwitch */ int qlcnic_toggle_eswitch(struct qlcnic_adapter *adapter, u8 id, u8 enable) { int err = -EIO; u32 arg1, arg2; struct qlcnic_eswitch *eswitch; if (adapter->op_mode != QLCNIC_MGMT_FUNC) return err; eswitch = &adapter->eswitch[id]; if (!eswitch) return err; arg1 = eswitch->port | (enable ? BIT_4 : 0); arg2 = eswitch->active_vports | (eswitch->max_ucast_filters << 8) | (eswitch->max_active_vlans << 16); err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, arg2, 0, QLCNIC_CDRP_CMD_TOGGLE_ESWITCH); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, "Failed to enable eswitch%d\n", eswitch->port); eswitch->flags &= ~QLCNIC_SWITCH_ENABLE; err = -EIO; } else { eswitch->flags |= QLCNIC_SWITCH_ENABLE; dev_info(&adapter->pdev->dev, "Enabled eSwitch for port %d\n", eswitch->port); } return err; }
static int qlcnic_irq_test(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); int max_sds_rings = adapter->max_sds_rings; int ret; struct qlcnic_cmd_args cmd; if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); if (ret) goto clear_it; adapter->diag_cnt = 0; memset(&cmd, 0, sizeof(cmd)); cmd.req.cmd = QLCNIC_CDRP_CMD_INTRPT_TEST; cmd.req.arg1 = adapter->ahw->pci_func; qlcnic_issue_cmd(adapter, &cmd); ret = cmd.rsp.cmd; if (ret) goto done; msleep(10); ret = !adapter->diag_cnt; done: qlcnic_diag_free_res(netdev, max_sds_rings); clear_it: adapter->max_sds_rings = max_sds_rings; clear_bit(__QLCNIC_RESETTING, &adapter->state); return ret; }
int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *adapter, struct qlcnic_info *npar_info, u16 vport_id) { struct device *dev = &adapter->pdev->dev; struct qlcnic_cmd_args cmd; int err; u32 status; err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO); if (err) return err; cmd.req.arg[1] = vport_id << 16 | 0x1; err = qlcnic_issue_cmd(adapter, &cmd); if (err) { dev_err(&adapter->pdev->dev, "Failed to get vport info, err=%d\n", err); qlcnic_free_mbx_args(&cmd); return err; } status = cmd.rsp.arg[2] & 0xffff; if (status & BIT_0) npar_info->min_tx_bw = MSW(cmd.rsp.arg[2]); if (status & BIT_1) npar_info->max_tx_bw = LSW(cmd.rsp.arg[3]); if (status & BIT_2) npar_info->max_tx_ques = MSW(cmd.rsp.arg[3]); if (status & BIT_3) npar_info->max_tx_mac_filters = LSW(cmd.rsp.arg[4]); if (status & BIT_4) npar_info->max_rx_mcast_mac_filters = MSW(cmd.rsp.arg[4]); if (status & BIT_5) npar_info->max_rx_ucast_mac_filters = LSW(cmd.rsp.arg[5]); if (status & BIT_6) npar_info->max_rx_ip_addr = MSW(cmd.rsp.arg[5]); if (status & BIT_7) npar_info->max_rx_lro_flow = LSW(cmd.rsp.arg[6]); if (status & BIT_8) npar_info->max_rx_status_rings = MSW(cmd.rsp.arg[6]); if (status & BIT_9) npar_info->max_rx_buf_rings = LSW(cmd.rsp.arg[7]); npar_info->max_rx_ques = MSW(cmd.rsp.arg[7]); npar_info->max_tx_vlan_keys = LSW(cmd.rsp.arg[8]); npar_info->max_local_ipv6_addrs = MSW(cmd.rsp.arg[8]); npar_info->max_remote_ipv6_addrs = LSW(cmd.rsp.arg[9]); dev_info(dev, "\n\tmin_tx_bw: %d, max_tx_bw: %d max_tx_ques: %d,\n" "\tmax_tx_mac_filters: %d max_rx_mcast_mac_filters: %d,\n" "\tmax_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d,\n" "\tmax_rx_lro_flow: %d max_rx_status_rings: %d,\n" "\tmax_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d\n" "\tlocal_ipv6_addr: %d, remote_ipv6_addr: %d\n", npar_info->min_tx_bw, npar_info->max_tx_bw, npar_info->max_tx_ques, npar_info->max_tx_mac_filters, npar_info->max_rx_mcast_mac_filters, npar_info->max_rx_ucast_mac_filters, npar_info->max_rx_ip_addr, npar_info->max_rx_lro_flow, npar_info->max_rx_status_rings, npar_info->max_rx_buf_rings, npar_info->max_rx_ques, npar_info->max_tx_vlan_keys, npar_info->max_local_ipv6_addrs, npar_info->max_remote_ipv6_addrs); qlcnic_free_mbx_args(&cmd); return err; }