Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ice: Add code for DCB initialization part 2/4

This patch introduces a new top level function ice_init_dcb (and
related lower level helper functions) which continues the DCB init
flow.

This function uses ice_get_dcb_cfg to get, parse and store the DCB
configuration. Once this is done, it sets itself up to be notified
by the firmware on LLDP MIB change events.

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>

authored by

Anirudh Venkataramanan and committed by
Jeff Kirsher
0ebd3ff1 37b6f646

+1057 -1
+79
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
··· 1132 1132 __le32 addr_low; 1133 1133 }; 1134 1134 1135 + /* Get LLDP MIB (indirect 0x0A00) 1136 + * Note: This is also used by the LLDP MIB Change Event (0x0A01) 1137 + * as the format is the same. 1138 + */ 1139 + struct ice_aqc_lldp_get_mib { 1140 + u8 type; 1141 + #define ICE_AQ_LLDP_MIB_TYPE_S 0 1142 + #define ICE_AQ_LLDP_MIB_TYPE_M (0x3 << ICE_AQ_LLDP_MIB_TYPE_S) 1143 + #define ICE_AQ_LLDP_MIB_LOCAL 0 1144 + #define ICE_AQ_LLDP_MIB_REMOTE 1 1145 + #define ICE_AQ_LLDP_MIB_LOCAL_AND_REMOTE 2 1146 + #define ICE_AQ_LLDP_BRID_TYPE_S 2 1147 + #define ICE_AQ_LLDP_BRID_TYPE_M (0x3 << ICE_AQ_LLDP_BRID_TYPE_S) 1148 + #define ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID 0 1149 + #define ICE_AQ_LLDP_BRID_TYPE_NON_TPMR 1 1150 + /* Tx pause flags in the 0xA01 event use ICE_AQ_LLDP_TX_* */ 1151 + #define ICE_AQ_LLDP_TX_S 0x4 1152 + #define ICE_AQ_LLDP_TX_M (0x03 << ICE_AQ_LLDP_TX_S) 1153 + #define ICE_AQ_LLDP_TX_ACTIVE 0 1154 + #define ICE_AQ_LLDP_TX_SUSPENDED 1 1155 + #define ICE_AQ_LLDP_TX_FLUSHED 3 1156 + /* The following bytes are reserved for the Get LLDP MIB command (0x0A00) 1157 + * and in the LLDP MIB Change Event (0x0A01). They are valid for the 1158 + * Get LLDP MIB (0x0A00) response only. 1159 + */ 1160 + u8 reserved1; 1161 + __le16 local_len; 1162 + __le16 remote_len; 1163 + u8 reserved2[2]; 1164 + __le32 addr_high; 1165 + __le32 addr_low; 1166 + }; 1167 + 1168 + /* Configure LLDP MIB Change Event (direct 0x0A01) */ 1169 + /* For MIB Change Event use ice_aqc_lldp_get_mib structure above */ 1170 + struct ice_aqc_lldp_set_mib_change { 1171 + u8 command; 1172 + #define ICE_AQ_LLDP_MIB_UPDATE_ENABLE 0x0 1173 + #define ICE_AQ_LLDP_MIB_UPDATE_DIS 0x1 1174 + u8 reserved[15]; 1175 + }; 1176 + 1135 1177 /* Start LLDP (direct 0x0A06) */ 1136 1178 struct ice_aqc_lldp_start { 1137 1179 u8 command; 1138 1180 #define ICE_AQ_LLDP_AGENT_START BIT(0) 1139 1181 #define ICE_AQ_LLDP_AGENT_PERSIST_ENA BIT(1) 1140 1182 u8 reserved[15]; 1183 + }; 1184 + 1185 + /* Get CEE DCBX Oper Config (0x0A07) 1186 + * The command uses the generic descriptor struct and 1187 + * returns the struct below as an indirect response. 1188 + */ 1189 + struct ice_aqc_get_cee_dcb_cfg_resp { 1190 + u8 oper_num_tc; 1191 + u8 oper_prio_tc[4]; 1192 + u8 oper_tc_bw[8]; 1193 + u8 oper_pfc_en; 1194 + __le16 oper_app_prio; 1195 + #define ICE_AQC_CEE_APP_FCOE_S 0 1196 + #define ICE_AQC_CEE_APP_FCOE_M (0x7 << ICE_AQC_CEE_APP_FCOE_S) 1197 + #define ICE_AQC_CEE_APP_ISCSI_S 3 1198 + #define ICE_AQC_CEE_APP_ISCSI_M (0x7 << ICE_AQC_CEE_APP_ISCSI_S) 1199 + #define ICE_AQC_CEE_APP_FIP_S 8 1200 + #define ICE_AQC_CEE_APP_FIP_M (0x7 << ICE_AQC_CEE_APP_FIP_S) 1201 + __le32 tlv_status; 1202 + #define ICE_AQC_CEE_PG_STATUS_S 0 1203 + #define ICE_AQC_CEE_PG_STATUS_M (0x7 << ICE_AQC_CEE_PG_STATUS_S) 1204 + #define ICE_AQC_CEE_PFC_STATUS_S 3 1205 + #define ICE_AQC_CEE_PFC_STATUS_M (0x7 << ICE_AQC_CEE_PFC_STATUS_S) 1206 + #define ICE_AQC_CEE_FCOE_STATUS_S 8 1207 + #define ICE_AQC_CEE_FCOE_STATUS_M (0x7 << ICE_AQC_CEE_FCOE_STATUS_S) 1208 + #define ICE_AQC_CEE_ISCSI_STATUS_S 11 1209 + #define ICE_AQC_CEE_ISCSI_STATUS_M (0x7 << ICE_AQC_CEE_ISCSI_STATUS_S) 1210 + #define ICE_AQC_CEE_FIP_STATUS_S 16 1211 + #define ICE_AQC_CEE_FIP_STATUS_M (0x7 << ICE_AQC_CEE_FIP_STATUS_S) 1212 + u8 reserved[12]; 1141 1213 }; 1142 1214 1143 1215 /* Stop/Start LLDP Agent (direct 0x0A09) ··· 1483 1411 struct ice_aqc_query_txsched_res query_sched_res; 1484 1412 struct ice_aqc_nvm nvm; 1485 1413 struct ice_aqc_pf_vf_msg virt; 1414 + struct ice_aqc_lldp_get_mib lldp_get_mib; 1415 + struct ice_aqc_lldp_set_mib_change lldp_set_event; 1486 1416 struct ice_aqc_lldp_start lldp_start; 1487 1417 struct ice_aqc_lldp_stop_start_specific_agent lldp_agent_ctrl; 1488 1418 struct ice_aqc_get_set_rss_lut get_set_rss_lut; ··· 1519 1445 /* error codes */ 1520 1446 enum ice_aq_err { 1521 1447 ICE_AQ_RC_OK = 0, /* Success */ 1448 + ICE_AQ_RC_EPERM = 1, /* Operation not permitted */ 1449 + ICE_AQ_RC_ENOENT = 2, /* No such element */ 1522 1450 ICE_AQ_RC_ENOMEM = 9, /* Out of memory */ 1523 1451 ICE_AQ_RC_EBUSY = 12, /* Device or resource busy */ 1524 1452 ICE_AQ_RC_EEXIST = 13, /* Object already exists */ ··· 1591 1515 ice_mbx_opc_send_msg_to_pf = 0x0801, 1592 1516 ice_mbx_opc_send_msg_to_vf = 0x0802, 1593 1517 /* LLDP commands */ 1518 + ice_aqc_opc_lldp_get_mib = 0x0A00, 1519 + ice_aqc_opc_lldp_set_mib_change = 0x0A01, 1594 1520 ice_aqc_opc_lldp_start = 0x0A06, 1521 + ice_aqc_opc_get_cee_dcb_cfg = 0x0A07, 1595 1522 ice_aqc_opc_lldp_stop_start_specific_agent = 0x0A09, 1596 1523 1597 1524 /* RSS commands */
+819
drivers/net/ethernet/intel/ice/ice_dcb.c
··· 6 6 #include "ice_dcb.h" 7 7 8 8 /** 9 + * ice_aq_get_lldp_mib 10 + * @hw: pointer to the HW struct 11 + * @bridge_type: type of bridge requested 12 + * @mib_type: Local, Remote or both Local and Remote MIBs 13 + * @buf: pointer to the caller-supplied buffer to store the MIB block 14 + * @buf_size: size of the buffer (in bytes) 15 + * @local_len: length of the returned Local LLDP MIB 16 + * @remote_len: length of the returned Remote LLDP MIB 17 + * @cd: pointer to command details structure or NULL 18 + * 19 + * Requests the complete LLDP MIB (entire packet). (0x0A00) 20 + */ 21 + static enum ice_status 22 + ice_aq_get_lldp_mib(struct ice_hw *hw, u8 bridge_type, u8 mib_type, void *buf, 23 + u16 buf_size, u16 *local_len, u16 *remote_len, 24 + struct ice_sq_cd *cd) 25 + { 26 + struct ice_aqc_lldp_get_mib *cmd; 27 + struct ice_aq_desc desc; 28 + enum ice_status status; 29 + 30 + cmd = &desc.params.lldp_get_mib; 31 + 32 + if (buf_size == 0 || !buf) 33 + return ICE_ERR_PARAM; 34 + 35 + ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_get_mib); 36 + 37 + cmd->type = mib_type & ICE_AQ_LLDP_MIB_TYPE_M; 38 + cmd->type |= (bridge_type << ICE_AQ_LLDP_BRID_TYPE_S) & 39 + ICE_AQ_LLDP_BRID_TYPE_M; 40 + 41 + desc.datalen = cpu_to_le16(buf_size); 42 + 43 + status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 44 + if (!status) { 45 + if (local_len) 46 + *local_len = le16_to_cpu(cmd->local_len); 47 + if (remote_len) 48 + *remote_len = le16_to_cpu(cmd->remote_len); 49 + } 50 + 51 + return status; 52 + } 53 + 54 + /** 55 + * ice_aq_cfg_lldp_mib_change 56 + * @hw: pointer to the HW struct 57 + * @ena_update: Enable or Disable event posting 58 + * @cd: pointer to command details structure or NULL 59 + * 60 + * Enable or Disable posting of an event on ARQ when LLDP MIB 61 + * associated with the interface changes (0x0A01) 62 + */ 63 + static enum ice_status 64 + ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update, 65 + struct ice_sq_cd *cd) 66 + { 67 + struct ice_aqc_lldp_set_mib_change *cmd; 68 + struct ice_aq_desc desc; 69 + 70 + cmd = &desc.params.lldp_set_event; 71 + 72 + ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_mib_change); 73 + 74 + if (!ena_update) 75 + cmd->command |= ICE_AQ_LLDP_MIB_UPDATE_DIS; 76 + 77 + return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 78 + } 79 + 80 + /** 9 81 * ice_aq_start_lldp 10 82 * @hw: pointer to the HW struct 11 83 * @cd: pointer to command details structure or NULL ··· 111 39 reg = rd32(hw, PRTDCB_GENS); 112 40 return (u8)((reg & PRTDCB_GENS_DCBX_STATUS_M) >> 113 41 PRTDCB_GENS_DCBX_STATUS_S); 42 + } 43 + 44 + /** 45 + * ice_parse_ieee_ets_common_tlv 46 + * @buf: Data buffer to be parsed for ETS CFG/REC data 47 + * @ets_cfg: Container to store parsed data 48 + * 49 + * Parses the common data of IEEE 802.1Qaz ETS CFG/REC TLV 50 + */ 51 + static void 52 + ice_parse_ieee_ets_common_tlv(u8 *buf, struct ice_dcb_ets_cfg *ets_cfg) 53 + { 54 + u8 offset = 0; 55 + int i; 56 + 57 + /* Priority Assignment Table (4 octets) 58 + * Octets:| 1 | 2 | 3 | 4 | 59 + * ----------------------------------------- 60 + * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7| 61 + * ----------------------------------------- 62 + * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0| 63 + * ----------------------------------------- 64 + */ 65 + for (i = 0; i < 4; i++) { 66 + ets_cfg->prio_table[i * 2] = 67 + ((buf[offset] & ICE_IEEE_ETS_PRIO_1_M) >> 68 + ICE_IEEE_ETS_PRIO_1_S); 69 + ets_cfg->prio_table[i * 2 + 1] = 70 + ((buf[offset] & ICE_IEEE_ETS_PRIO_0_M) >> 71 + ICE_IEEE_ETS_PRIO_0_S); 72 + offset++; 73 + } 74 + 75 + /* TC Bandwidth Table (8 octets) 76 + * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 77 + * --------------------------------- 78 + * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7| 79 + * --------------------------------- 80 + * 81 + * TSA Assignment Table (8 octets) 82 + * Octets:| 9 | 10| 11| 12| 13| 14| 15| 16| 83 + * --------------------------------- 84 + * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7| 85 + * --------------------------------- 86 + */ 87 + ice_for_each_traffic_class(i) { 88 + ets_cfg->tcbwtable[i] = buf[offset]; 89 + ets_cfg->tsatable[i] = buf[ICE_MAX_TRAFFIC_CLASS + offset++]; 90 + } 91 + } 92 + 93 + /** 94 + * ice_parse_ieee_etscfg_tlv 95 + * @tlv: IEEE 802.1Qaz ETS CFG TLV 96 + * @dcbcfg: Local store to update ETS CFG data 97 + * 98 + * Parses IEEE 802.1Qaz ETS CFG TLV 99 + */ 100 + static void 101 + ice_parse_ieee_etscfg_tlv(struct ice_lldp_org_tlv *tlv, 102 + struct ice_dcbx_cfg *dcbcfg) 103 + { 104 + struct ice_dcb_ets_cfg *etscfg; 105 + u8 *buf = tlv->tlvinfo; 106 + 107 + /* First Octet post subtype 108 + * -------------------------- 109 + * |will-|CBS | Re- | Max | 110 + * |ing | |served| TCs | 111 + * -------------------------- 112 + * |1bit | 1bit|3 bits|3bits| 113 + */ 114 + etscfg = &dcbcfg->etscfg; 115 + etscfg->willing = ((buf[0] & ICE_IEEE_ETS_WILLING_M) >> 116 + ICE_IEEE_ETS_WILLING_S); 117 + etscfg->cbs = ((buf[0] & ICE_IEEE_ETS_CBS_M) >> ICE_IEEE_ETS_CBS_S); 118 + etscfg->maxtcs = ((buf[0] & ICE_IEEE_ETS_MAXTC_M) >> 119 + ICE_IEEE_ETS_MAXTC_S); 120 + 121 + /* Begin parsing at Priority Assignment Table (offset 1 in buf) */ 122 + ice_parse_ieee_ets_common_tlv(&buf[1], etscfg); 123 + } 124 + 125 + /** 126 + * ice_parse_ieee_etsrec_tlv 127 + * @tlv: IEEE 802.1Qaz ETS REC TLV 128 + * @dcbcfg: Local store to update ETS REC data 129 + * 130 + * Parses IEEE 802.1Qaz ETS REC TLV 131 + */ 132 + static void 133 + ice_parse_ieee_etsrec_tlv(struct ice_lldp_org_tlv *tlv, 134 + struct ice_dcbx_cfg *dcbcfg) 135 + { 136 + u8 *buf = tlv->tlvinfo; 137 + 138 + /* Begin parsing at Priority Assignment Table (offset 1 in buf) */ 139 + ice_parse_ieee_ets_common_tlv(&buf[1], &dcbcfg->etsrec); 140 + } 141 + 142 + /** 143 + * ice_parse_ieee_pfccfg_tlv 144 + * @tlv: IEEE 802.1Qaz PFC CFG TLV 145 + * @dcbcfg: Local store to update PFC CFG data 146 + * 147 + * Parses IEEE 802.1Qaz PFC CFG TLV 148 + */ 149 + static void 150 + ice_parse_ieee_pfccfg_tlv(struct ice_lldp_org_tlv *tlv, 151 + struct ice_dcbx_cfg *dcbcfg) 152 + { 153 + u8 *buf = tlv->tlvinfo; 154 + 155 + /* ---------------------------------------- 156 + * |will-|MBC | Re- | PFC | PFC Enable | 157 + * |ing | |served| cap | | 158 + * ----------------------------------------- 159 + * |1bit | 1bit|2 bits|4bits| 1 octet | 160 + */ 161 + dcbcfg->pfc.willing = ((buf[0] & ICE_IEEE_PFC_WILLING_M) >> 162 + ICE_IEEE_PFC_WILLING_S); 163 + dcbcfg->pfc.mbc = ((buf[0] & ICE_IEEE_PFC_MBC_M) >> ICE_IEEE_PFC_MBC_S); 164 + dcbcfg->pfc.pfccap = ((buf[0] & ICE_IEEE_PFC_CAP_M) >> 165 + ICE_IEEE_PFC_CAP_S); 166 + dcbcfg->pfc.pfcena = buf[1]; 167 + } 168 + 169 + /** 170 + * ice_parse_ieee_app_tlv 171 + * @tlv: IEEE 802.1Qaz APP TLV 172 + * @dcbcfg: Local store to update APP PRIO data 173 + * 174 + * Parses IEEE 802.1Qaz APP PRIO TLV 175 + */ 176 + static void 177 + ice_parse_ieee_app_tlv(struct ice_lldp_org_tlv *tlv, 178 + struct ice_dcbx_cfg *dcbcfg) 179 + { 180 + u16 offset = 0; 181 + u16 typelen; 182 + int i = 0; 183 + u16 len; 184 + u8 *buf; 185 + 186 + typelen = ntohs(tlv->typelen); 187 + len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S); 188 + buf = tlv->tlvinfo; 189 + 190 + /* Removing sizeof(ouisubtype) and reserved byte from len. 191 + * Remaining len div 3 is number of APP TLVs. 192 + */ 193 + len -= (sizeof(tlv->ouisubtype) + 1); 194 + 195 + /* Move offset to App Priority Table */ 196 + offset++; 197 + 198 + /* Application Priority Table (3 octets) 199 + * Octets:| 1 | 2 | 3 | 200 + * ----------------------------------------- 201 + * |Priority|Rsrvd| Sel | Protocol ID | 202 + * ----------------------------------------- 203 + * Bits:|23 21|20 19|18 16|15 0| 204 + * ----------------------------------------- 205 + */ 206 + while (offset < len) { 207 + dcbcfg->app[i].priority = ((buf[offset] & 208 + ICE_IEEE_APP_PRIO_M) >> 209 + ICE_IEEE_APP_PRIO_S); 210 + dcbcfg->app[i].selector = ((buf[offset] & 211 + ICE_IEEE_APP_SEL_M) >> 212 + ICE_IEEE_APP_SEL_S); 213 + dcbcfg->app[i].prot_id = (buf[offset + 1] << 0x8) | 214 + buf[offset + 2]; 215 + /* Move to next app */ 216 + offset += 3; 217 + i++; 218 + if (i >= ICE_DCBX_MAX_APPS) 219 + break; 220 + } 221 + 222 + dcbcfg->numapps = i; 223 + } 224 + 225 + /** 226 + * ice_parse_ieee_tlv 227 + * @tlv: IEEE 802.1Qaz TLV 228 + * @dcbcfg: Local store to update ETS REC data 229 + * 230 + * Get the TLV subtype and send it to parsing function 231 + * based on the subtype value 232 + */ 233 + static void 234 + ice_parse_ieee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg) 235 + { 236 + u32 ouisubtype; 237 + u8 subtype; 238 + 239 + ouisubtype = ntohl(tlv->ouisubtype); 240 + subtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >> 241 + ICE_LLDP_TLV_SUBTYPE_S); 242 + switch (subtype) { 243 + case ICE_IEEE_SUBTYPE_ETS_CFG: 244 + ice_parse_ieee_etscfg_tlv(tlv, dcbcfg); 245 + break; 246 + case ICE_IEEE_SUBTYPE_ETS_REC: 247 + ice_parse_ieee_etsrec_tlv(tlv, dcbcfg); 248 + break; 249 + case ICE_IEEE_SUBTYPE_PFC_CFG: 250 + ice_parse_ieee_pfccfg_tlv(tlv, dcbcfg); 251 + break; 252 + case ICE_IEEE_SUBTYPE_APP_PRI: 253 + ice_parse_ieee_app_tlv(tlv, dcbcfg); 254 + break; 255 + default: 256 + break; 257 + } 258 + } 259 + 260 + /** 261 + * ice_parse_cee_pgcfg_tlv 262 + * @tlv: CEE DCBX PG CFG TLV 263 + * @dcbcfg: Local store to update ETS CFG data 264 + * 265 + * Parses CEE DCBX PG CFG TLV 266 + */ 267 + static void 268 + ice_parse_cee_pgcfg_tlv(struct ice_cee_feat_tlv *tlv, 269 + struct ice_dcbx_cfg *dcbcfg) 270 + { 271 + struct ice_dcb_ets_cfg *etscfg; 272 + u8 *buf = tlv->tlvinfo; 273 + u16 offset = 0; 274 + int i; 275 + 276 + etscfg = &dcbcfg->etscfg; 277 + 278 + if (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M) 279 + etscfg->willing = 1; 280 + 281 + etscfg->cbs = 0; 282 + /* Priority Group Table (4 octets) 283 + * Octets:| 1 | 2 | 3 | 4 | 284 + * ----------------------------------------- 285 + * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7| 286 + * ----------------------------------------- 287 + * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0| 288 + * ----------------------------------------- 289 + */ 290 + for (i = 0; i < 4; i++) { 291 + etscfg->prio_table[i * 2] = 292 + ((buf[offset] & ICE_CEE_PGID_PRIO_1_M) >> 293 + ICE_CEE_PGID_PRIO_1_S); 294 + etscfg->prio_table[i * 2 + 1] = 295 + ((buf[offset] & ICE_CEE_PGID_PRIO_0_M) >> 296 + ICE_CEE_PGID_PRIO_0_S); 297 + offset++; 298 + } 299 + 300 + /* PG Percentage Table (8 octets) 301 + * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 302 + * --------------------------------- 303 + * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7| 304 + * --------------------------------- 305 + */ 306 + ice_for_each_traffic_class(i) 307 + etscfg->tcbwtable[i] = buf[offset++]; 308 + 309 + /* Number of TCs supported (1 octet) */ 310 + etscfg->maxtcs = buf[offset]; 311 + } 312 + 313 + /** 314 + * ice_parse_cee_pfccfg_tlv 315 + * @tlv: CEE DCBX PFC CFG TLV 316 + * @dcbcfg: Local store to update PFC CFG data 317 + * 318 + * Parses CEE DCBX PFC CFG TLV 319 + */ 320 + static void 321 + ice_parse_cee_pfccfg_tlv(struct ice_cee_feat_tlv *tlv, 322 + struct ice_dcbx_cfg *dcbcfg) 323 + { 324 + u8 *buf = tlv->tlvinfo; 325 + 326 + if (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M) 327 + dcbcfg->pfc.willing = 1; 328 + 329 + /* ------------------------ 330 + * | PFC Enable | PFC TCs | 331 + * ------------------------ 332 + * | 1 octet | 1 octet | 333 + */ 334 + dcbcfg->pfc.pfcena = buf[0]; 335 + dcbcfg->pfc.pfccap = buf[1]; 336 + } 337 + 338 + /** 339 + * ice_parse_cee_app_tlv 340 + * @tlv: CEE DCBX APP TLV 341 + * @dcbcfg: Local store to update APP PRIO data 342 + * 343 + * Parses CEE DCBX APP PRIO TLV 344 + */ 345 + static void 346 + ice_parse_cee_app_tlv(struct ice_cee_feat_tlv *tlv, struct ice_dcbx_cfg *dcbcfg) 347 + { 348 + u16 len, typelen, offset = 0; 349 + struct ice_cee_app_prio *app; 350 + u8 i; 351 + 352 + typelen = ntohs(tlv->hdr.typelen); 353 + len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S); 354 + 355 + dcbcfg->numapps = len / sizeof(*app); 356 + if (!dcbcfg->numapps) 357 + return; 358 + if (dcbcfg->numapps > ICE_DCBX_MAX_APPS) 359 + dcbcfg->numapps = ICE_DCBX_MAX_APPS; 360 + 361 + for (i = 0; i < dcbcfg->numapps; i++) { 362 + u8 up, selector; 363 + 364 + app = (struct ice_cee_app_prio *)(tlv->tlvinfo + offset); 365 + for (up = 0; up < ICE_MAX_USER_PRIORITY; up++) 366 + if (app->prio_map & BIT(up)) 367 + break; 368 + 369 + dcbcfg->app[i].priority = up; 370 + 371 + /* Get Selector from lower 2 bits, and convert to IEEE */ 372 + selector = (app->upper_oui_sel & ICE_CEE_APP_SELECTOR_M); 373 + switch (selector) { 374 + case ICE_CEE_APP_SEL_ETHTYPE: 375 + dcbcfg->app[i].selector = ICE_APP_SEL_ETHTYPE; 376 + break; 377 + case ICE_CEE_APP_SEL_TCPIP: 378 + dcbcfg->app[i].selector = ICE_APP_SEL_TCPIP; 379 + break; 380 + default: 381 + /* Keep selector as it is for unknown types */ 382 + dcbcfg->app[i].selector = selector; 383 + } 384 + 385 + dcbcfg->app[i].prot_id = ntohs(app->protocol); 386 + /* Move to next app */ 387 + offset += sizeof(*app); 388 + } 389 + } 390 + 391 + /** 392 + * ice_parse_cee_tlv 393 + * @tlv: CEE DCBX TLV 394 + * @dcbcfg: Local store to update DCBX config data 395 + * 396 + * Get the TLV subtype and send it to parsing function 397 + * based on the subtype value 398 + */ 399 + static void 400 + ice_parse_cee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg) 401 + { 402 + struct ice_cee_feat_tlv *sub_tlv; 403 + u8 subtype, feat_tlv_count = 0; 404 + u16 len, tlvlen, typelen; 405 + u32 ouisubtype; 406 + 407 + ouisubtype = ntohl(tlv->ouisubtype); 408 + subtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >> 409 + ICE_LLDP_TLV_SUBTYPE_S); 410 + /* Return if not CEE DCBX */ 411 + if (subtype != ICE_CEE_DCBX_TYPE) 412 + return; 413 + 414 + typelen = ntohs(tlv->typelen); 415 + tlvlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S); 416 + len = sizeof(tlv->typelen) + sizeof(ouisubtype) + 417 + sizeof(struct ice_cee_ctrl_tlv); 418 + /* Return if no CEE DCBX Feature TLVs */ 419 + if (tlvlen <= len) 420 + return; 421 + 422 + sub_tlv = (struct ice_cee_feat_tlv *)((char *)tlv + len); 423 + while (feat_tlv_count < ICE_CEE_MAX_FEAT_TYPE) { 424 + u16 sublen; 425 + 426 + typelen = ntohs(sub_tlv->hdr.typelen); 427 + sublen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S); 428 + subtype = (u8)((typelen & ICE_LLDP_TLV_TYPE_M) >> 429 + ICE_LLDP_TLV_TYPE_S); 430 + switch (subtype) { 431 + case ICE_CEE_SUBTYPE_PG_CFG: 432 + ice_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg); 433 + break; 434 + case ICE_CEE_SUBTYPE_PFC_CFG: 435 + ice_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg); 436 + break; 437 + case ICE_CEE_SUBTYPE_APP_PRI: 438 + ice_parse_cee_app_tlv(sub_tlv, dcbcfg); 439 + break; 440 + default: 441 + return; /* Invalid Sub-type return */ 442 + } 443 + feat_tlv_count++; 444 + /* Move to next sub TLV */ 445 + sub_tlv = (struct ice_cee_feat_tlv *) 446 + ((char *)sub_tlv + sizeof(sub_tlv->hdr.typelen) + 447 + sublen); 448 + } 449 + } 450 + 451 + /** 452 + * ice_parse_org_tlv 453 + * @tlv: Organization specific TLV 454 + * @dcbcfg: Local store to update ETS REC data 455 + * 456 + * Currently only IEEE 802.1Qaz TLV is supported, all others 457 + * will be returned 458 + */ 459 + static void 460 + ice_parse_org_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg) 461 + { 462 + u32 ouisubtype; 463 + u32 oui; 464 + 465 + ouisubtype = ntohl(tlv->ouisubtype); 466 + oui = ((ouisubtype & ICE_LLDP_TLV_OUI_M) >> ICE_LLDP_TLV_OUI_S); 467 + switch (oui) { 468 + case ICE_IEEE_8021QAZ_OUI: 469 + ice_parse_ieee_tlv(tlv, dcbcfg); 470 + break; 471 + case ICE_CEE_DCBX_OUI: 472 + ice_parse_cee_tlv(tlv, dcbcfg); 473 + break; 474 + default: 475 + break; 476 + } 477 + } 478 + 479 + /** 480 + * ice_lldp_to_dcb_cfg 481 + * @lldpmib: LLDPDU to be parsed 482 + * @dcbcfg: store for LLDPDU data 483 + * 484 + * Parse DCB configuration from the LLDPDU 485 + */ 486 + static enum ice_status 487 + ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg) 488 + { 489 + struct ice_lldp_org_tlv *tlv; 490 + enum ice_status ret = 0; 491 + u16 offset = 0; 492 + u16 typelen; 493 + u16 type; 494 + u16 len; 495 + 496 + if (!lldpmib || !dcbcfg) 497 + return ICE_ERR_PARAM; 498 + 499 + /* set to the start of LLDPDU */ 500 + lldpmib += ETH_HLEN; 501 + tlv = (struct ice_lldp_org_tlv *)lldpmib; 502 + while (1) { 503 + typelen = ntohs(tlv->typelen); 504 + type = ((typelen & ICE_LLDP_TLV_TYPE_M) >> ICE_LLDP_TLV_TYPE_S); 505 + len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S); 506 + offset += sizeof(typelen) + len; 507 + 508 + /* END TLV or beyond LLDPDU size */ 509 + if (type == ICE_TLV_TYPE_END || offset > ICE_LLDPDU_SIZE) 510 + break; 511 + 512 + switch (type) { 513 + case ICE_TLV_TYPE_ORG: 514 + ice_parse_org_tlv(tlv, dcbcfg); 515 + break; 516 + default: 517 + break; 518 + } 519 + 520 + /* Move to next TLV */ 521 + tlv = (struct ice_lldp_org_tlv *) 522 + ((char *)tlv + sizeof(tlv->typelen) + len); 523 + } 524 + 525 + return ret; 526 + } 527 + 528 + /** 529 + * ice_aq_get_dcb_cfg 530 + * @hw: pointer to the HW struct 531 + * @mib_type: mib type for the query 532 + * @bridgetype: bridge type for the query (remote) 533 + * @dcbcfg: store for LLDPDU data 534 + * 535 + * Query DCB configuration from the firmware 536 + */ 537 + static enum ice_status 538 + ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype, 539 + struct ice_dcbx_cfg *dcbcfg) 540 + { 541 + enum ice_status ret; 542 + u8 *lldpmib; 543 + 544 + /* Allocate the LLDPDU */ 545 + lldpmib = devm_kzalloc(ice_hw_to_dev(hw), ICE_LLDPDU_SIZE, GFP_KERNEL); 546 + if (!lldpmib) 547 + return ICE_ERR_NO_MEMORY; 548 + 549 + ret = ice_aq_get_lldp_mib(hw, bridgetype, mib_type, (void *)lldpmib, 550 + ICE_LLDPDU_SIZE, NULL, NULL, NULL); 551 + 552 + if (!ret) 553 + /* Parse LLDP MIB to get DCB configuration */ 554 + ret = ice_lldp_to_dcb_cfg(lldpmib, dcbcfg); 555 + 556 + devm_kfree(ice_hw_to_dev(hw), lldpmib); 557 + 558 + return ret; 114 559 } 115 560 116 561 /** ··· 671 82 *dcbx_agent_status = true; 672 83 673 84 return status; 85 + } 86 + 87 + /** 88 + * ice_aq_get_cee_dcb_cfg 89 + * @hw: pointer to the HW struct 90 + * @buff: response buffer that stores CEE operational configuration 91 + * @cd: pointer to command details structure or NULL 92 + * 93 + * Get CEE DCBX mode operational configuration from firmware (0x0A07) 94 + */ 95 + static enum ice_status 96 + ice_aq_get_cee_dcb_cfg(struct ice_hw *hw, 97 + struct ice_aqc_get_cee_dcb_cfg_resp *buff, 98 + struct ice_sq_cd *cd) 99 + { 100 + struct ice_aq_desc desc; 101 + 102 + ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_cee_dcb_cfg); 103 + 104 + return ice_aq_send_cmd(hw, &desc, (void *)buff, sizeof(*buff), cd); 105 + } 106 + 107 + /** 108 + * ice_cee_to_dcb_cfg 109 + * @cee_cfg: pointer to CEE configuration struct 110 + * @dcbcfg: DCB configuration struct 111 + * 112 + * Convert CEE configuration from firmware to DCB configuration 113 + */ 114 + static void 115 + ice_cee_to_dcb_cfg(struct ice_aqc_get_cee_dcb_cfg_resp *cee_cfg, 116 + struct ice_dcbx_cfg *dcbcfg) 117 + { 118 + u32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status); 119 + u32 ice_aqc_cee_status_mask, ice_aqc_cee_status_shift; 120 + u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio); 121 + u8 i, err, sync, oper, app_index, ice_app_sel_type; 122 + u16 ice_aqc_cee_app_mask, ice_aqc_cee_app_shift; 123 + u16 ice_app_prot_id_type; 124 + 125 + /* CEE PG data to ETS config */ 126 + dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc; 127 + 128 + /* Note that the FW creates the oper_prio_tc nibbles reversed 129 + * from those in the CEE Priority Group sub-TLV. 130 + */ 131 + for (i = 0; i < ICE_MAX_TRAFFIC_CLASS / 2; i++) { 132 + dcbcfg->etscfg.prio_table[i * 2] = 133 + ((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_0_M) >> 134 + ICE_CEE_PGID_PRIO_0_S); 135 + dcbcfg->etscfg.prio_table[i * 2 + 1] = 136 + ((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_1_M) >> 137 + ICE_CEE_PGID_PRIO_1_S); 138 + } 139 + 140 + ice_for_each_traffic_class(i) { 141 + dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i]; 142 + 143 + if (dcbcfg->etscfg.prio_table[i] == ICE_CEE_PGID_STRICT) { 144 + /* Map it to next empty TC */ 145 + dcbcfg->etscfg.prio_table[i] = cee_cfg->oper_num_tc - 1; 146 + dcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_STRICT; 147 + } else { 148 + dcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS; 149 + } 150 + } 151 + 152 + /* CEE PFC data to ETS config */ 153 + dcbcfg->pfc.pfcena = cee_cfg->oper_pfc_en; 154 + dcbcfg->pfc.pfccap = ICE_MAX_TRAFFIC_CLASS; 155 + 156 + app_index = 0; 157 + for (i = 0; i < 3; i++) { 158 + if (i == 0) { 159 + /* FCoE APP */ 160 + ice_aqc_cee_status_mask = ICE_AQC_CEE_FCOE_STATUS_M; 161 + ice_aqc_cee_status_shift = ICE_AQC_CEE_FCOE_STATUS_S; 162 + ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FCOE_M; 163 + ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FCOE_S; 164 + ice_app_sel_type = ICE_APP_SEL_ETHTYPE; 165 + ice_app_prot_id_type = ICE_APP_PROT_ID_FCOE; 166 + } else if (i == 1) { 167 + /* iSCSI APP */ 168 + ice_aqc_cee_status_mask = ICE_AQC_CEE_ISCSI_STATUS_M; 169 + ice_aqc_cee_status_shift = ICE_AQC_CEE_ISCSI_STATUS_S; 170 + ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_ISCSI_M; 171 + ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_ISCSI_S; 172 + ice_app_sel_type = ICE_APP_SEL_TCPIP; 173 + ice_app_prot_id_type = ICE_APP_PROT_ID_ISCSI; 174 + } else { 175 + /* FIP APP */ 176 + ice_aqc_cee_status_mask = ICE_AQC_CEE_FIP_STATUS_M; 177 + ice_aqc_cee_status_shift = ICE_AQC_CEE_FIP_STATUS_S; 178 + ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FIP_M; 179 + ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FIP_S; 180 + ice_app_sel_type = ICE_APP_SEL_ETHTYPE; 181 + ice_app_prot_id_type = ICE_APP_PROT_ID_FIP; 182 + } 183 + 184 + status = (tlv_status & ice_aqc_cee_status_mask) >> 185 + ice_aqc_cee_status_shift; 186 + err = (status & ICE_TLV_STATUS_ERR) ? 1 : 0; 187 + sync = (status & ICE_TLV_STATUS_SYNC) ? 1 : 0; 188 + oper = (status & ICE_TLV_STATUS_OPER) ? 1 : 0; 189 + /* Add FCoE/iSCSI/FIP APP if Error is False and 190 + * Oper/Sync is True 191 + */ 192 + if (!err && sync && oper) { 193 + dcbcfg->app[app_index].priority = 194 + (app_prio & ice_aqc_cee_app_mask) >> 195 + ice_aqc_cee_app_shift; 196 + dcbcfg->app[app_index].selector = ice_app_sel_type; 197 + dcbcfg->app[app_index].prot_id = ice_app_prot_id_type; 198 + app_index++; 199 + } 200 + } 201 + 202 + dcbcfg->numapps = app_index; 203 + } 204 + 205 + /** 206 + * ice_get_ieee_dcb_cfg 207 + * @pi: port information structure 208 + * @dcbx_mode: mode of DCBX (IEEE or CEE) 209 + * 210 + * Get IEEE or CEE mode DCB configuration from the Firmware 211 + */ 212 + static enum ice_status 213 + ice_get_ieee_or_cee_dcb_cfg(struct ice_port_info *pi, u8 dcbx_mode) 214 + { 215 + struct ice_dcbx_cfg *dcbx_cfg = NULL; 216 + enum ice_status ret; 217 + 218 + if (!pi) 219 + return ICE_ERR_PARAM; 220 + 221 + if (dcbx_mode == ICE_DCBX_MODE_IEEE) 222 + dcbx_cfg = &pi->local_dcbx_cfg; 223 + else if (dcbx_mode == ICE_DCBX_MODE_CEE) 224 + dcbx_cfg = &pi->desired_dcbx_cfg; 225 + 226 + /* Get Local DCB Config in case of ICE_DCBX_MODE_IEEE 227 + * or get CEE DCB Desired Config in case of ICE_DCBX_MODE_CEE 228 + */ 229 + ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_LOCAL, 230 + ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg); 231 + if (ret) 232 + goto out; 233 + 234 + /* Get Remote DCB Config */ 235 + dcbx_cfg = &pi->remote_dcbx_cfg; 236 + ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE, 237 + ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg); 238 + /* Don't treat ENOENT as an error for Remote MIBs */ 239 + if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) 240 + ret = 0; 241 + 242 + out: 243 + return ret; 244 + } 245 + 246 + /** 247 + * ice_get_dcb_cfg 248 + * @pi: port information structure 249 + * 250 + * Get DCB configuration from the Firmware 251 + */ 252 + static enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi) 253 + { 254 + struct ice_aqc_get_cee_dcb_cfg_resp cee_cfg; 255 + struct ice_dcbx_cfg *dcbx_cfg; 256 + enum ice_status ret; 257 + 258 + if (!pi) 259 + return ICE_ERR_PARAM; 260 + 261 + ret = ice_aq_get_cee_dcb_cfg(pi->hw, &cee_cfg, NULL); 262 + if (!ret) { 263 + /* CEE mode */ 264 + dcbx_cfg = &pi->local_dcbx_cfg; 265 + dcbx_cfg->dcbx_mode = ICE_DCBX_MODE_CEE; 266 + dcbx_cfg->tlv_status = le32_to_cpu(cee_cfg.tlv_status); 267 + ice_cee_to_dcb_cfg(&cee_cfg, dcbx_cfg); 268 + ret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_CEE); 269 + } else if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) { 270 + /* CEE mode not enabled try querying IEEE data */ 271 + dcbx_cfg = &pi->local_dcbx_cfg; 272 + dcbx_cfg->dcbx_mode = ICE_DCBX_MODE_IEEE; 273 + ret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_IEEE); 274 + } 275 + 276 + return ret; 277 + } 278 + 279 + /** 280 + * ice_init_dcb 281 + * @hw: pointer to the HW struct 282 + * 283 + * Update DCB configuration from the Firmware 284 + */ 285 + enum ice_status ice_init_dcb(struct ice_hw *hw) 286 + { 287 + struct ice_port_info *pi = hw->port_info; 288 + enum ice_status ret = 0; 289 + 290 + if (!hw->func_caps.common_cap.dcb) 291 + return ICE_ERR_NOT_SUPPORTED; 292 + 293 + pi->is_sw_lldp = true; 294 + 295 + /* Get DCBX status */ 296 + pi->dcbx_status = ice_get_dcbx_status(hw); 297 + 298 + if (pi->dcbx_status == ICE_DCBX_STATUS_DONE || 299 + pi->dcbx_status == ICE_DCBX_STATUS_IN_PROGRESS) { 300 + /* Get current DCBX configuration */ 301 + ret = ice_get_dcb_cfg(pi); 302 + pi->is_sw_lldp = (hw->adminq.sq_last_status == ICE_AQ_RC_EPERM); 303 + if (ret) 304 + return ret; 305 + } else if (pi->dcbx_status == ICE_DCBX_STATUS_DIS) { 306 + return ICE_ERR_NOT_READY; 307 + } 308 + 309 + /* Configure the LLDP MIB change event */ 310 + ret = ice_aq_cfg_lldp_mib_change(hw, true, NULL); 311 + if (!ret) 312 + pi->is_sw_lldp = false; 313 + 314 + return ret; 674 315 }
+99
drivers/net/ethernet/intel/ice/ice_dcb.h
··· 8 8 9 9 #define ICE_DCBX_STATUS_IN_PROGRESS 1 10 10 #define ICE_DCBX_STATUS_DONE 2 11 + #define ICE_DCBX_STATUS_DIS 7 12 + 13 + #define ICE_TLV_TYPE_END 0 14 + #define ICE_TLV_TYPE_ORG 127 15 + 16 + #define ICE_IEEE_8021QAZ_OUI 0x0080C2 17 + #define ICE_IEEE_SUBTYPE_ETS_CFG 9 18 + #define ICE_IEEE_SUBTYPE_ETS_REC 10 19 + #define ICE_IEEE_SUBTYPE_PFC_CFG 11 20 + #define ICE_IEEE_SUBTYPE_APP_PRI 12 21 + 22 + #define ICE_CEE_DCBX_OUI 0x001B21 23 + #define ICE_CEE_DCBX_TYPE 2 24 + #define ICE_CEE_SUBTYPE_PG_CFG 2 25 + #define ICE_CEE_SUBTYPE_PFC_CFG 3 26 + #define ICE_CEE_SUBTYPE_APP_PRI 4 27 + #define ICE_CEE_MAX_FEAT_TYPE 3 28 + /* Defines for LLDP TLV header */ 29 + #define ICE_LLDP_TLV_LEN_S 0 30 + #define ICE_LLDP_TLV_LEN_M (0x01FF << ICE_LLDP_TLV_LEN_S) 31 + #define ICE_LLDP_TLV_TYPE_S 9 32 + #define ICE_LLDP_TLV_TYPE_M (0x7F << ICE_LLDP_TLV_TYPE_S) 33 + #define ICE_LLDP_TLV_SUBTYPE_S 0 34 + #define ICE_LLDP_TLV_SUBTYPE_M (0xFF << ICE_LLDP_TLV_SUBTYPE_S) 35 + #define ICE_LLDP_TLV_OUI_S 8 36 + #define ICE_LLDP_TLV_OUI_M (0xFFFFFFUL << ICE_LLDP_TLV_OUI_S) 37 + 38 + /* Defines for IEEE ETS TLV */ 39 + #define ICE_IEEE_ETS_MAXTC_S 0 40 + #define ICE_IEEE_ETS_MAXTC_M (0x7 << ICE_IEEE_ETS_MAXTC_S) 41 + #define ICE_IEEE_ETS_CBS_S 6 42 + #define ICE_IEEE_ETS_CBS_M BIT(ICE_IEEE_ETS_CBS_S) 43 + #define ICE_IEEE_ETS_WILLING_S 7 44 + #define ICE_IEEE_ETS_WILLING_M BIT(ICE_IEEE_ETS_WILLING_S) 45 + #define ICE_IEEE_ETS_PRIO_0_S 0 46 + #define ICE_IEEE_ETS_PRIO_0_M (0x7 << ICE_IEEE_ETS_PRIO_0_S) 47 + #define ICE_IEEE_ETS_PRIO_1_S 4 48 + #define ICE_IEEE_ETS_PRIO_1_M (0x7 << ICE_IEEE_ETS_PRIO_1_S) 49 + #define ICE_CEE_PGID_PRIO_0_S 0 50 + #define ICE_CEE_PGID_PRIO_0_M (0xF << ICE_CEE_PGID_PRIO_0_S) 51 + #define ICE_CEE_PGID_PRIO_1_S 4 52 + #define ICE_CEE_PGID_PRIO_1_M (0xF << ICE_CEE_PGID_PRIO_1_S) 53 + #define ICE_CEE_PGID_STRICT 15 54 + 55 + /* Defines for IEEE TSA types */ 56 + #define ICE_IEEE_TSA_STRICT 0 57 + #define ICE_IEEE_TSA_ETS 2 58 + 59 + /* Defines for IEEE PFC TLV */ 60 + #define ICE_IEEE_PFC_CAP_S 0 61 + #define ICE_IEEE_PFC_CAP_M (0xF << ICE_IEEE_PFC_CAP_S) 62 + #define ICE_IEEE_PFC_MBC_S 6 63 + #define ICE_IEEE_PFC_MBC_M BIT(ICE_IEEE_PFC_MBC_S) 64 + #define ICE_IEEE_PFC_WILLING_S 7 65 + #define ICE_IEEE_PFC_WILLING_M BIT(ICE_IEEE_PFC_WILLING_S) 66 + 67 + /* Defines for IEEE APP TLV */ 68 + #define ICE_IEEE_APP_SEL_S 0 69 + #define ICE_IEEE_APP_SEL_M (0x7 << ICE_IEEE_APP_SEL_S) 70 + #define ICE_IEEE_APP_PRIO_S 5 71 + #define ICE_IEEE_APP_PRIO_M (0x7 << ICE_IEEE_APP_PRIO_S) 72 + 73 + /* IEEE 802.1AB LLDP Organization specific TLV */ 74 + struct ice_lldp_org_tlv { 75 + __be16 typelen; 76 + __be32 ouisubtype; 77 + u8 tlvinfo[1]; 78 + } __packed; 79 + 80 + struct ice_cee_tlv_hdr { 81 + __be16 typelen; 82 + u8 operver; 83 + u8 maxver; 84 + }; 85 + 86 + struct ice_cee_ctrl_tlv { 87 + struct ice_cee_tlv_hdr hdr; 88 + __be32 seqno; 89 + __be32 ackno; 90 + }; 91 + 92 + struct ice_cee_feat_tlv { 93 + struct ice_cee_tlv_hdr hdr; 94 + u8 en_will_err; /* Bits: |En|Will|Err|Reserved(5)| */ 95 + #define ICE_CEE_FEAT_TLV_ENA_M 0x80 96 + #define ICE_CEE_FEAT_TLV_WILLING_M 0x40 97 + #define ICE_CEE_FEAT_TLV_ERR_M 0x20 98 + u8 subtype; 99 + u8 tlvinfo[1]; 100 + }; 101 + 102 + struct ice_cee_app_prio { 103 + __be16 protocol; 104 + u8 upper_oui_sel; /* Bits: |Upper OUI(6)|Selector(2)| */ 105 + #define ICE_CEE_APP_SELECTOR_M 0x03 106 + __be16 lower_oui; 107 + u8 prio_map; 108 + } __packed; 11 109 12 110 u8 ice_get_dcbx_status(struct ice_hw *hw); 111 + enum ice_status ice_init_dcb(struct ice_hw *hw); 13 112 #ifdef CONFIG_DCB 14 113 enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd); 15 114 enum ice_status
+1 -1
drivers/net/ethernet/intel/ice/ice_dcb_lib.c
··· 38 38 ice_aq_start_stop_dcbx(hw, true, &dcbx_status, NULL); 39 39 } 40 40 41 - return 0; 41 + return ice_init_dcb(hw); 42 42 }
+1
drivers/net/ethernet/intel/ice/ice_status.h
··· 12 12 ICE_ERR_PARAM = -1, 13 13 ICE_ERR_NOT_IMPL = -2, 14 14 ICE_ERR_NOT_READY = -3, 15 + ICE_ERR_NOT_SUPPORTED = -4, 15 16 ICE_ERR_BAD_PTR = -5, 16 17 ICE_ERR_INVAL_SIZE = -6, 17 18 ICE_ERR_DEVICE_NOT_SUPPORTED = -8,
+58
drivers/net/ethernet/intel/ice/ice_type.h
··· 262 262 u8 rdma_ena; 263 263 }; 264 264 265 + /* CEE or IEEE 802.1Qaz ETS Configuration data */ 266 + struct ice_dcb_ets_cfg { 267 + u8 willing; 268 + u8 cbs; 269 + u8 maxtcs; 270 + u8 prio_table[ICE_MAX_TRAFFIC_CLASS]; 271 + u8 tcbwtable[ICE_MAX_TRAFFIC_CLASS]; 272 + u8 tsatable[ICE_MAX_TRAFFIC_CLASS]; 273 + }; 274 + 275 + /* CEE or IEEE 802.1Qaz PFC Configuration data */ 276 + struct ice_dcb_pfc_cfg { 277 + u8 willing; 278 + u8 mbc; 279 + u8 pfccap; 280 + u8 pfcena; 281 + }; 282 + 283 + /* CEE or IEEE 802.1Qaz Application Priority data */ 284 + struct ice_dcb_app_priority_table { 285 + u16 prot_id; 286 + u8 priority; 287 + u8 selector; 288 + }; 289 + 290 + #define ICE_MAX_USER_PRIORITY 8 291 + #define ICE_DCBX_MAX_APPS 32 292 + #define ICE_LLDPDU_SIZE 1500 293 + #define ICE_TLV_STATUS_OPER 0x1 294 + #define ICE_TLV_STATUS_SYNC 0x2 295 + #define ICE_TLV_STATUS_ERR 0x4 296 + #define ICE_APP_PROT_ID_FCOE 0x8906 297 + #define ICE_APP_PROT_ID_ISCSI 0x0cbc 298 + #define ICE_APP_PROT_ID_FIP 0x8914 299 + #define ICE_APP_SEL_ETHTYPE 0x1 300 + #define ICE_APP_SEL_TCPIP 0x2 301 + #define ICE_CEE_APP_SEL_ETHTYPE 0x0 302 + #define ICE_CEE_APP_SEL_TCPIP 0x1 303 + 304 + struct ice_dcbx_cfg { 305 + u32 numapps; 306 + u32 tlv_status; /* CEE mode TLV status */ 307 + struct ice_dcb_ets_cfg etscfg; 308 + struct ice_dcb_ets_cfg etsrec; 309 + struct ice_dcb_pfc_cfg pfc; 310 + struct ice_dcb_app_priority_table app[ICE_DCBX_MAX_APPS]; 311 + u8 dcbx_mode; 312 + #define ICE_DCBX_MODE_CEE 0x1 313 + #define ICE_DCBX_MODE_IEEE 0x2 314 + u8 app_mode; 315 + #define ICE_DCBX_APPS_NON_WILLING 0x1 316 + }; 317 + 265 318 struct ice_port_info { 266 319 struct ice_sched_node *root; /* Root Node per Port */ 267 320 struct ice_hw *hw; /* back pointer to HW instance */ ··· 332 279 struct ice_mac_info mac; 333 280 struct ice_phy_info phy; 334 281 struct mutex sched_lock; /* protect access to TXSched tree */ 282 + struct ice_dcbx_cfg local_dcbx_cfg; /* Oper/Local Cfg */ 283 + /* DCBX info */ 284 + struct ice_dcbx_cfg remote_dcbx_cfg; /* Peer Cfg */ 285 + struct ice_dcbx_cfg desired_dcbx_cfg; /* CEE Desired Cfg */ 335 286 /* LLDP/DCBX Status */ 336 287 u8 dcbx_status; 288 + u8 is_sw_lldp; 337 289 u8 lport; 338 290 #define ICE_LPORT_MASK 0xff 339 291 u8 is_vf;