aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>2019-02-28 18:24:22 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-04-18 11:38:47 -0400
commit37b6f6469f75070e4fb2e32995eb858e79b8860a (patch)
treec382e12efce222342d5f55407007c7da332f7da7 /drivers/net/ethernet
parent802abbb44a251a753ad56fcda1e35daf0138ab29 (diff)
ice: Add code for DCB initialization part 1/4
This patch introduces a skeleton for ice_init_pf_dcb, the top level function for DCB initialization. Subsequent patches will add to this DCB init flow. In this patch, ice_init_pf_dcb checks if DCB is a supported capability. If so, an admin queue call to start the LLDP and DCBx in firmware is issued. If not, an error is reported. Note that we don't fail the driver init if DCB init fails. Reviewed-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/intel/ice/Makefile1
-rw-r--r--drivers/net/ethernet/intel/ice/ice.h3
-rw-r--r--drivers/net/ethernet/intel/ice/ice_adminq_cmd.h26
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.c85
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.h37
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb_lib.c42
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb_lib.h19
-rw-r--r--drivers/net/ethernet/intel/ice/ice_hw_autogen.h3
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c10
-rw-r--r--drivers/net/ethernet/intel/ice/ice_type.h4
10 files changed, 230 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile
index e5d6f684437e..2d140ba83781 100644
--- a/drivers/net/ethernet/intel/ice/Makefile
+++ b/drivers/net/ethernet/intel/ice/Makefile
@@ -17,3 +17,4 @@ ice-y := ice_main.o \
17 ice_txrx.o \ 17 ice_txrx.o \
18 ice_ethtool.o 18 ice_ethtool.o
19ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o 19ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o
20ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_lib.o
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index c04debc1a0ea..d76333c808a3 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -34,6 +34,7 @@
34#include "ice_devids.h" 34#include "ice_devids.h"
35#include "ice_type.h" 35#include "ice_type.h"
36#include "ice_txrx.h" 36#include "ice_txrx.h"
37#include "ice_dcb.h"
37#include "ice_switch.h" 38#include "ice_switch.h"
38#include "ice_common.h" 39#include "ice_common.h"
39#include "ice_sched.h" 40#include "ice_sched.h"
@@ -321,6 +322,8 @@ enum ice_pf_flags {
321 ICE_FLAG_RSS_ENA, 322 ICE_FLAG_RSS_ENA,
322 ICE_FLAG_SRIOV_ENA, 323 ICE_FLAG_SRIOV_ENA,
323 ICE_FLAG_SRIOV_CAPABLE, 324 ICE_FLAG_SRIOV_CAPABLE,
325 ICE_FLAG_DCB_CAPABLE,
326 ICE_FLAG_DCB_ENA,
324 ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, 327 ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
325 ICE_PF_FLAGS_NBITS /* must be last */ 328 ICE_PF_FLAGS_NBITS /* must be last */
326}; 329};
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 757848f85072..4809e5ac55f4 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -1132,6 +1132,27 @@ struct ice_aqc_pf_vf_msg {
1132 __le32 addr_low; 1132 __le32 addr_low;
1133}; 1133};
1134 1134
1135/* Start LLDP (direct 0x0A06) */
1136struct ice_aqc_lldp_start {
1137 u8 command;
1138#define ICE_AQ_LLDP_AGENT_START BIT(0)
1139#define ICE_AQ_LLDP_AGENT_PERSIST_ENA BIT(1)
1140 u8 reserved[15];
1141};
1142
1143/* Stop/Start LLDP Agent (direct 0x0A09)
1144 * Used for stopping/starting specific LLDP agent. e.g. DCBx.
1145 * The same structure is used for the response, with the command field
1146 * being used as the status field.
1147 */
1148struct ice_aqc_lldp_stop_start_specific_agent {
1149 u8 command;
1150#define ICE_AQC_START_STOP_AGENT_M BIT(0)
1151#define ICE_AQC_START_STOP_AGENT_STOP_DCBX 0
1152#define ICE_AQC_START_STOP_AGENT_START_DCBX ICE_AQC_START_STOP_AGENT_M
1153 u8 reserved[15];
1154};
1155
1135/* Get/Set RSS key (indirect 0x0B04/0x0B02) */ 1156/* Get/Set RSS key (indirect 0x0B04/0x0B02) */
1136struct ice_aqc_get_set_rss_key { 1157struct ice_aqc_get_set_rss_key {
1137#define ICE_AQC_GSET_RSS_KEY_VSI_VALID BIT(15) 1158#define ICE_AQC_GSET_RSS_KEY_VSI_VALID BIT(15)
@@ -1390,6 +1411,8 @@ struct ice_aq_desc {
1390 struct ice_aqc_query_txsched_res query_sched_res; 1411 struct ice_aqc_query_txsched_res query_sched_res;
1391 struct ice_aqc_nvm nvm; 1412 struct ice_aqc_nvm nvm;
1392 struct ice_aqc_pf_vf_msg virt; 1413 struct ice_aqc_pf_vf_msg virt;
1414 struct ice_aqc_lldp_start lldp_start;
1415 struct ice_aqc_lldp_stop_start_specific_agent lldp_agent_ctrl;
1393 struct ice_aqc_get_set_rss_lut get_set_rss_lut; 1416 struct ice_aqc_get_set_rss_lut get_set_rss_lut;
1394 struct ice_aqc_get_set_rss_key get_set_rss_key; 1417 struct ice_aqc_get_set_rss_key get_set_rss_key;
1395 struct ice_aqc_add_txqs add_txqs; 1418 struct ice_aqc_add_txqs add_txqs;
@@ -1491,6 +1514,9 @@ enum ice_adminq_opc {
1491 /* PF/VF mailbox commands */ 1514 /* PF/VF mailbox commands */
1492 ice_mbx_opc_send_msg_to_pf = 0x0801, 1515 ice_mbx_opc_send_msg_to_pf = 0x0801,
1493 ice_mbx_opc_send_msg_to_vf = 0x0802, 1516 ice_mbx_opc_send_msg_to_vf = 0x0802,
1517 /* LLDP commands */
1518 ice_aqc_opc_lldp_start = 0x0A06,
1519 ice_aqc_opc_lldp_stop_start_specific_agent = 0x0A09,
1494 1520
1495 /* RSS commands */ 1521 /* RSS commands */
1496 ice_aqc_opc_set_rss_key = 0x0B02, 1522 ice_aqc_opc_set_rss_key = 0x0B02,
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.c b/drivers/net/ethernet/intel/ice/ice_dcb.c
new file mode 100644
index 000000000000..39543e487ec1
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_dcb.c
@@ -0,0 +1,85 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019, Intel Corporation. */
3
4#include "ice_common.h"
5#include "ice_sched.h"
6#include "ice_dcb.h"
7
8/**
9 * ice_aq_start_lldp
10 * @hw: pointer to the HW struct
11 * @cd: pointer to command details structure or NULL
12 *
13 * Start the embedded LLDP Agent on all ports. (0x0A06)
14 */
15enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd)
16{
17 struct ice_aqc_lldp_start *cmd;
18 struct ice_aq_desc desc;
19
20 cmd = &desc.params.lldp_start;
21
22 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_start);
23
24 cmd->command = ICE_AQ_LLDP_AGENT_START;
25
26 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
27}
28
29/**
30 * ice_get_dcbx_status
31 * @hw: pointer to the HW struct
32 *
33 * Get the DCBX status from the Firmware
34 */
35u8 ice_get_dcbx_status(struct ice_hw *hw)
36{
37 u32 reg;
38
39 reg = rd32(hw, PRTDCB_GENS);
40 return (u8)((reg & PRTDCB_GENS_DCBX_STATUS_M) >>
41 PRTDCB_GENS_DCBX_STATUS_S);
42}
43
44/**
45 * ice_aq_start_stop_dcbx - Start/Stop DCBx service in FW
46 * @hw: pointer to the HW struct
47 * @start_dcbx_agent: True if DCBx Agent needs to be started
48 * False if DCBx Agent needs to be stopped
49 * @dcbx_agent_status: FW indicates back the DCBx agent status
50 * True if DCBx Agent is active
51 * False if DCBx Agent is stopped
52 * @cd: pointer to command details structure or NULL
53 *
54 * Start/Stop the embedded dcbx Agent. In case that this wrapper function
55 * returns ICE_SUCCESS, caller will need to check if FW returns back the same
56 * value as stated in dcbx_agent_status, and react accordingly. (0x0A09)
57 */
58enum ice_status
59ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,
60 bool *dcbx_agent_status, struct ice_sq_cd *cd)
61{
62 struct ice_aqc_lldp_stop_start_specific_agent *cmd;
63 enum ice_status status;
64 struct ice_aq_desc desc;
65 u16 opcode;
66
67 cmd = &desc.params.lldp_agent_ctrl;
68
69 opcode = ice_aqc_opc_lldp_stop_start_specific_agent;
70
71 ice_fill_dflt_direct_cmd_desc(&desc, opcode);
72
73 if (start_dcbx_agent)
74 cmd->command = ICE_AQC_START_STOP_AGENT_START_DCBX;
75
76 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
77
78 *dcbx_agent_status = false;
79
80 if (!status &&
81 cmd->command == ICE_AQC_START_STOP_AGENT_START_DCBX)
82 *dcbx_agent_status = true;
83
84 return status;
85}
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.h b/drivers/net/ethernet/intel/ice/ice_dcb.h
new file mode 100644
index 000000000000..071d205c983c
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_dcb.h
@@ -0,0 +1,37 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (c) 2019, Intel Corporation. */
3
4#ifndef _ICE_DCB_H_
5#define _ICE_DCB_H_
6
7#include "ice_type.h"
8
9#define ICE_DCBX_STATUS_IN_PROGRESS 1
10#define ICE_DCBX_STATUS_DONE 2
11
12u8 ice_get_dcbx_status(struct ice_hw *hw);
13#ifdef CONFIG_DCB
14enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd);
15enum ice_status
16ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,
17 bool *dcbx_agent_status, struct ice_sq_cd *cd);
18#else /* CONFIG_DCB */
19static inline enum ice_status
20ice_aq_start_lldp(struct ice_hw __always_unused *hw,
21 struct ice_sq_cd __always_unused *cd)
22{
23 return 0;
24}
25
26static inline enum ice_status
27ice_aq_start_stop_dcbx(struct ice_hw __always_unused *hw,
28 bool __always_unused start_dcbx_agent,
29 bool *dcbx_agent_status,
30 struct ice_sq_cd __always_unused *cd)
31{
32 *dcbx_agent_status = false;
33
34 return 0;
35}
36#endif /* CONFIG_DCB */
37#endif /* _ICE_DCB_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
new file mode 100644
index 000000000000..8ce358fbe9fb
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
@@ -0,0 +1,42 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019, Intel Corporation. */
3
4#include "ice_dcb_lib.h"
5
6/**
7 * ice_init_pf_dcb - initialize DCB for a PF
8 * @pf: pf to initiialize DCB for
9 */
10int ice_init_pf_dcb(struct ice_pf *pf)
11{
12 struct device *dev = &pf->pdev->dev;
13 struct ice_port_info *port_info;
14 struct ice_hw *hw = &pf->hw;
15
16 port_info = hw->port_info;
17
18 /* check if device is DCB capable */
19 if (!hw->func_caps.common_cap.dcb) {
20 dev_dbg(dev, "DCB not supported\n");
21 return -EOPNOTSUPP;
22 }
23
24 /* Best effort to put DCBx and LLDP into a good state */
25 port_info->dcbx_status = ice_get_dcbx_status(hw);
26 if (port_info->dcbx_status != ICE_DCBX_STATUS_DONE &&
27 port_info->dcbx_status != ICE_DCBX_STATUS_IN_PROGRESS) {
28 bool dcbx_status;
29
30 /* Attempt to start LLDP engine. Ignore errors
31 * as this will error if it is already started
32 */
33 ice_aq_start_lldp(hw, NULL);
34
35 /* Attempt to start DCBX. Ignore errors as this
36 * will error if it is already started
37 */
38 ice_aq_start_stop_dcbx(hw, true, &dcbx_status, NULL);
39 }
40
41 return 0;
42}
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.h b/drivers/net/ethernet/intel/ice/ice_dcb_lib.h
new file mode 100644
index 000000000000..d67c769a9fb5
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.h
@@ -0,0 +1,19 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (c) 2019, Intel Corporation. */
3
4#ifndef _ICE_DCB_LIB_H_
5#define _ICE_DCB_LIB_H_
6
7#include "ice.h"
8#include "ice_lib.h"
9
10#ifdef CONFIG_DCB
11int ice_init_pf_dcb(struct ice_pf *pf);
12#else
13static inline int ice_init_pf_dcb(struct ice_pf *pf)
14{
15 dev_dbg(&pf->pdev->dev, "DCB not supported\n");
16 return -EOPNOTSUPP;
17}
18#endif /* CONFIG_DCB */
19#endif /* _ICE_DCB_LIB_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
index af6f32358363..dfc180d2b282 100644
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
@@ -49,6 +49,9 @@
49#define PF_MBX_ATQLEN_ATQLEN_M ICE_M(0x3FF, 0) 49#define PF_MBX_ATQLEN_ATQLEN_M ICE_M(0x3FF, 0)
50#define PF_MBX_ATQLEN_ATQENABLE_M BIT(31) 50#define PF_MBX_ATQLEN_ATQENABLE_M BIT(31)
51#define PF_MBX_ATQT 0x0022E300 51#define PF_MBX_ATQT 0x0022E300
52#define PRTDCB_GENS 0x00083020
53#define PRTDCB_GENS_DCBX_STATUS_S 0
54#define PRTDCB_GENS_DCBX_STATUS_M ICE_M(0x7, 0)
52#define GLFLXP_RXDID_FLAGS(_i, _j) (0x0045D000 + ((_i) * 4 + (_j) * 256)) 55#define GLFLXP_RXDID_FLAGS(_i, _j) (0x0045D000 + ((_i) * 4 + (_j) * 256))
53#define GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S 0 56#define GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S 0
54#define GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M ICE_M(0x3F, 0) 57#define GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M ICE_M(0x3F, 0)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index d58887a1cc36..22fe0605aa9f 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -7,6 +7,7 @@
7 7
8#include "ice.h" 8#include "ice.h"
9#include "ice_lib.h" 9#include "ice_lib.h"
10#include "ice_dcb_lib.h"
10 11
11#define DRV_VERSION "0.7.3-k" 12#define DRV_VERSION "0.7.3-k"
12#define DRV_SUMMARY "Intel(R) Ethernet Connection E800 Series Linux Driver" 13#define DRV_SUMMARY "Intel(R) Ethernet Connection E800 Series Linux Driver"
@@ -2285,6 +2286,15 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
2285 2286
2286 ice_init_pf(pf); 2287 ice_init_pf(pf);
2287 2288
2289 err = ice_init_pf_dcb(pf);
2290 if (err) {
2291 clear_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);
2292 clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
2293
2294 /* do not fail overall init if DCB init fails */
2295 err = 0;
2296 }
2297
2288 ice_determine_q_usage(pf); 2298 ice_determine_q_usage(pf);
2289 2299
2290 pf->num_alloc_vsi = hw->func_caps.guar_num_vsi; 2300 pf->num_alloc_vsi = hw->func_caps.guar_num_vsi;
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index 119fda5674cc..e21ea271b48e 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -148,6 +148,8 @@ struct ice_hw_common_caps {
148 /* RSS related capabilities */ 148 /* RSS related capabilities */
149 u16 rss_table_size; /* 512 for PFs and 64 for VFs */ 149 u16 rss_table_size; /* 512 for PFs and 64 for VFs */
150 u8 rss_table_entry_width; /* RSS Entry width in bits */ 150 u8 rss_table_entry_width; /* RSS Entry width in bits */
151
152 u8 dcb;
151}; 153};
152 154
153/* Function specific capabilities */ 155/* Function specific capabilities */
@@ -277,6 +279,8 @@ struct ice_port_info {
277 struct ice_mac_info mac; 279 struct ice_mac_info mac;
278 struct ice_phy_info phy; 280 struct ice_phy_info phy;
279 struct mutex sched_lock; /* protect access to TXSched tree */ 281 struct mutex sched_lock; /* protect access to TXSched tree */
282 /* LLDP/DCBX Status */
283 u8 dcbx_status;
280 u8 lport; 284 u8 lport;
281#define ICE_LPORT_MASK 0xff 285#define ICE_LPORT_MASK 0xff
282 u8 is_vf; 286 u8 is_vf;