Skip to content

Commit 02feda1

Browse files
Rajesh Borundiadavem330
authored andcommitted
qlcnic: Support SR-IOV enable and disable
o Add QLCNIC_SRIOV to Kconfig. o Provide PCI sysfs hooks to enable and disable SR-IOV. o Allow enabling only when CONFIG_QLCNIC_SRIOV is defined. o qlcnic_sriov_pf.c has all the PF related SR-IOV functionality. o qlcnic_sriov_common.c has VF functionality and SR-IOV functionality which is common between VF and PF. o qlcnic_sriov.h is a common header file for SR-IOV defines. Signed-off-by: Manish Chopra <[email protected]> Signed-off-by: Sucheta Chakraborty <[email protected]> Signed-off-by: Rajesh Borundia <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c23343c commit 02feda1

File tree

12 files changed

+613
-7
lines changed

12 files changed

+613
-7
lines changed

drivers/net/ethernet/qlogic/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ config QLCNIC
3535
This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
3636
devices.
3737

38+
config QLCNIC_SRIOV
39+
bool "QLOGIC QLCNIC 83XX family SR-IOV Support"
40+
depends on QLCNIC && PCI_IOV
41+
default y
42+
---help---
43+
This configuration parameter enables Single Root Input Output
44+
Virtualization support for QLE83XX Converged Ethernet devices.
45+
This allows for virtual function acceleration in virtualized
46+
environments.
47+
3848
config QLGE
3949
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
4050
depends on PCI

drivers/net/ethernet/qlogic/qlcnic/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ qlcnic-y := qlcnic_hw.o qlcnic_main.o qlcnic_init.o \
88
qlcnic_ethtool.o qlcnic_ctx.o qlcnic_io.o \
99
qlcnic_sysfs.o qlcnic_minidump.o qlcnic_83xx_hw.o \
1010
qlcnic_83xx_init.o qlcnic_83xx_vnic.o \
11-
qlcnic_minidump.o
11+
qlcnic_minidump.o qlcnic_sriov_common.o
12+
13+
qlcnic-$(CONFIG_QLCNIC_SRIOV) += qlcnic_sriov_pf.o

drivers/net/ethernet/qlogic/qlcnic/qlcnic.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ struct qlcnic_hardware_context {
449449
struct qlc_83xx_idc idc;
450450
struct qlc_83xx_fw_info fw_info;
451451
struct qlcnic_intrpt_config *intr_tbl;
452+
struct qlcnic_sriov *sriov;
452453
u32 *reg_tbl;
453454
u32 *ext_reg_tbl;
454455
u32 mbox_aen[QLC_83XX_MBX_AEN_CNT];
@@ -914,7 +915,9 @@ struct qlcnic_ipaddr {
914915
#define __QLCNIC_AER 5
915916
#define __QLCNIC_DIAG_RES_ALLOC 6
916917
#define __QLCNIC_LED_ENABLE 7
917-
#define __QLCNIC_ELB_INPROGRESS 8
918+
#define __QLCNIC_ELB_INPROGRESS 8
919+
#define __QLCNIC_SRIOV_ENABLE 10
920+
#define __QLCNIC_SRIOV_CAPABLE 11
918921

919922
#define QLCNIC_INTERRUPT_TEST 1
920923
#define QLCNIC_LOOPBACK_TEST 2
@@ -1051,7 +1054,11 @@ struct qlcnic_info_le {
10511054
u8 total_pf;
10521055
u8 total_rss_engines;
10531056
__le16 max_vports;
1054-
u8 reserved2[64];
1057+
__le16 linkstate_reg_offset;
1058+
__le16 bit_offsets;
1059+
__le16 max_local_ipv6_addrs;
1060+
__le16 max_remote_ipv6_addrs;
1061+
u8 reserved2[56];
10551062
} __packed;
10561063

10571064
struct qlcnic_info {
@@ -1083,6 +1090,10 @@ struct qlcnic_info {
10831090
u8 total_pf;
10841091
u8 total_rss_engines;
10851092
u16 max_vports;
1093+
u16 linkstate_reg_offset;
1094+
u16 bit_offsets;
1095+
u16 max_local_ipv6_addrs;
1096+
u16 max_remote_ipv6_addrs;
10861097
};
10871098

10881099
struct qlcnic_pci_info_le {
@@ -1511,6 +1522,7 @@ int qlcnic_reset_npar_config(struct qlcnic_adapter *);
15111522
int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *);
15121523
void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int,
15131524
__le16);
1525+
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
15141526
/*
15151527
* QLOGIC Board information
15161528
*/
@@ -1843,5 +1855,9 @@ static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter)
18431855
return (device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? true : false;
18441856
}
18451857

1858+
static inline bool qlcnic_sriov_pf_check(struct qlcnic_adapter *adapter)
1859+
{
1860+
return (adapter->ahw->op_mode == QLCNIC_SRIOV_PF_FUNC) ? true : false;
1861+
}
18461862

18471863
#endif /* __QLCNIC_H_ */

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
209209
{QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
210210
{QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
211211
{QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
212+
{QLCNIC_CMD_CONFIG_VPORT, 4, 4},
212213
};
213214

214215
static const u32 qlcnic_83xx_ext_reg_tbl[] = {
@@ -775,6 +776,9 @@ void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
775776
ahw->fw_hal_version);
776777
adapter->nic_ops = &qlcnic_vf_ops;
777778
} else {
779+
if (pci_find_ext_capability(adapter->pdev,
780+
PCI_EXT_CAP_ID_SRIOV))
781+
set_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state);
778782
adapter->nic_ops = &qlcnic_83xx_ops;
779783
}
780784
}

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ struct qlc_83xx_idc {
243243
#define QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(val) (val & 0x20000)
244244
#define QLC_83XX_VIRTUAL_NIC_MODE 0xFF
245245
#define QLC_83XX_DEFAULT_MODE 0x0
246+
#define QLC_83XX_SRIOV_MODE 0x1
246247
#define QLCNIC_BRDTYPE_83XX_10G 0x0083
247248

248249
#define QLC_83XX_FLASH_SPI_STATUS 0x2808E010

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#define QLC_83XX_OPCODE_POLL_READ_LIST 0x0100
2626

2727
static int qlcnic_83xx_init_default_driver(struct qlcnic_adapter *adapter);
28-
static int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
2928
static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev);
3029
static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter);
3130

@@ -1918,6 +1917,9 @@ int qlcnic_83xx_config_default_opmode(struct qlcnic_adapter *adapter)
19181917
qlcnic_get_func_no(adapter);
19191918
op_mode = QLCRDX(ahw, QLC_83XX_DRV_OP_MODE);
19201919

1920+
if (test_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state))
1921+
op_mode = QLC_83XX_DEFAULT_OPMODE;
1922+
19211923
if (op_mode == QLC_83XX_DEFAULT_OPMODE) {
19221924
adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
19231925
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
@@ -1947,6 +1949,16 @@ int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter)
19471949
ahw->max_mac_filters = nic_info.max_mac_filters;
19481950
ahw->max_mtu = nic_info.max_mtu;
19491951

1952+
/* VNIC mode is detected by BIT_23 in capabilities. This bit is also
1953+
* set in case device is SRIOV capable. VNIC and SRIOV are mutually
1954+
* exclusive. So in case of sriov capable device load driver in
1955+
* default mode
1956+
*/
1957+
if (test_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state)) {
1958+
ahw->nic_mode = QLC_83XX_DEFAULT_MODE;
1959+
return ahw->nic_mode;
1960+
}
1961+
19501962
if (ahw->capabilities & BIT_23)
19511963
ahw->nic_mode = QLC_83XX_VIRTUAL_NIC_MODE;
19521964
else
@@ -1955,7 +1967,7 @@ int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter)
19551967
return ahw->nic_mode;
19561968
}
19571969

1958-
static int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
1970+
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
19591971
{
19601972
int ret;
19611973

drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,8 @@ enum {
714714
QLCNIC_MGMT_FUNC = 0,
715715
QLCNIC_PRIV_FUNC = 1,
716716
QLCNIC_NON_PRIV_FUNC = 2,
717-
QLCNIC_UNKNOWN_FUNC_MODE = 3
717+
QLCNIC_SRIOV_PF_FUNC = 3,
718+
QLCNIC_UNKNOWN_FUNC_MODE = 4
718719
};
719720

720721
enum {

drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum qlcnic_regs {
8383
#define QLCNIC_CMD_CONFIG_PORT 0x2e
8484
#define QLCNIC_CMD_TEMP_SIZE 0x2f
8585
#define QLCNIC_CMD_GET_TEMP_HDR 0x30
86+
#define QLCNIC_CMD_CONFIG_VPORT 0x32
8687
#define QLCNIC_CMD_GET_MAC_STATS 0x37
8788
#define QLCNIC_CMD_SET_DRV_VER 0x38
8889
#define QLCNIC_CMD_CONFIGURE_RSS 0x41

drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/interrupt.h>
1010

1111
#include "qlcnic.h"
12+
#include "qlcnic_sriov.h"
1213
#include "qlcnic_hw.h"
1314

1415
#include <linux/swab.h>
@@ -2022,11 +2023,13 @@ static void qlcnic_remove(struct pci_dev *pdev)
20222023
return;
20232024

20242025
netdev = adapter->netdev;
2026+
qlcnic_sriov_pf_disable(adapter);
20252027

20262028
qlcnic_cancel_idc_work(adapter);
20272029
ahw = adapter->ahw;
20282030

20292031
unregister_netdev(netdev);
2032+
qlcnic_sriov_cleanup(adapter);
20302033

20312034
if (qlcnic_83xx_check(adapter)) {
20322035
qlcnic_83xx_free_mbx_intr(adapter);
@@ -3430,7 +3433,10 @@ static struct pci_driver qlcnic_driver = {
34303433
.resume = qlcnic_resume,
34313434
#endif
34323435
.shutdown = qlcnic_shutdown,
3433-
.err_handler = &qlcnic_err_handler
3436+
.err_handler = &qlcnic_err_handler,
3437+
#ifdef CONFIG_QLCNIC_SRIOV
3438+
.sriov_configure = qlcnic_pci_sriov_configure,
3439+
#endif
34343440

34353441
};
34363442

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* QLogic qlcnic NIC Driver
3+
* Copyright (c) 2009-2013 QLogic Corporation
4+
*
5+
* See LICENSE.qlcnic for copyright and licensing details.
6+
*/
7+
8+
#ifndef _QLCNIC_83XX_SRIOV_H_
9+
#define _QLCNIC_83XX_SRIOV_H_
10+
11+
#include "qlcnic.h"
12+
#include <linux/types.h>
13+
#include <linux/pci.h>
14+
15+
struct qlcnic_resources {
16+
u16 num_tx_mac_filters;
17+
u16 num_rx_ucast_mac_filters;
18+
u16 num_rx_mcast_mac_filters;
19+
20+
u16 num_txvlan_keys;
21+
22+
u16 num_rx_queues;
23+
u16 num_tx_queues;
24+
25+
u16 num_rx_buf_rings;
26+
u16 num_rx_status_rings;
27+
28+
u16 num_destip;
29+
u32 num_lro_flows_supported;
30+
u16 max_local_ipv6_addrs;
31+
u16 max_remote_ipv6_addrs;
32+
};
33+
34+
struct qlcnic_sriov {
35+
u16 vp_handle;
36+
u8 num_vfs;
37+
struct qlcnic_resources ff_max;
38+
};
39+
40+
int qlcnic_sriov_init(struct qlcnic_adapter *, int);
41+
void qlcnic_sriov_cleanup(struct qlcnic_adapter *);
42+
void __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
43+
44+
static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
45+
{
46+
return test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state) ? true : false;
47+
}
48+
49+
#ifdef CONFIG_QLCNIC_SRIOV
50+
void qlcnic_sriov_pf_disable(struct qlcnic_adapter *);
51+
void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *);
52+
int qlcnic_pci_sriov_configure(struct pci_dev *, int);
53+
#else
54+
static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
55+
static inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
56+
#endif
57+
58+
#endif

0 commit comments

Comments
 (0)