| .. | .. |
|---|
| 35 | 35 | #include "en/port.h" |
|---|
| 36 | 36 | #include "en/port_buffer.h" |
|---|
| 37 | 37 | |
|---|
| 38 | +#define MLX5E_MAX_BW_ALLOC 100 /* Max percentage of BW allocation */ |
|---|
| 39 | + |
|---|
| 38 | 40 | #define MLX5E_100MB (100000) |
|---|
| 39 | 41 | #define MLX5E_1GB (1000000) |
|---|
| 40 | 42 | |
|---|
| .. | .. |
|---|
| 47 | 49 | enum { |
|---|
| 48 | 50 | MLX5E_VENDOR_TC_GROUP_NUM = 7, |
|---|
| 49 | 51 | MLX5E_LOWEST_PRIO_GROUP = 0, |
|---|
| 52 | +}; |
|---|
| 53 | + |
|---|
| 54 | +enum { |
|---|
| 55 | + MLX5_DCB_CHG_RESET, |
|---|
| 56 | + MLX5_DCB_NO_CHG, |
|---|
| 57 | + MLX5_DCB_CHG_NO_RESET, |
|---|
| 50 | 58 | }; |
|---|
| 51 | 59 | |
|---|
| 52 | 60 | #define MLX5_DSCP_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, qcam_reg) && \ |
|---|
| .. | .. |
|---|
| 238 | 246 | * Report both group #0 and #1 as ETS type. |
|---|
| 239 | 247 | * All the tcs in group #0 will be reported with 0% BW. |
|---|
| 240 | 248 | */ |
|---|
| 241 | | -int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) |
|---|
| 249 | +static int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) |
|---|
| 242 | 250 | { |
|---|
| 243 | 251 | struct mlx5_core_dev *mdev = priv->mdev; |
|---|
| 244 | 252 | u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS]; |
|---|
| .. | .. |
|---|
| 680 | 688 | |
|---|
| 681 | 689 | memset(perm_addr, 0xff, MAX_ADDR_LEN); |
|---|
| 682 | 690 | |
|---|
| 683 | | - mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr); |
|---|
| 691 | + mlx5_query_mac_address(priv->mdev, perm_addr); |
|---|
| 684 | 692 | } |
|---|
| 685 | 693 | |
|---|
| 686 | 694 | static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev, |
|---|
| .. | .. |
|---|
| 977 | 985 | return err; |
|---|
| 978 | 986 | } |
|---|
| 979 | 987 | |
|---|
| 980 | | -const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = { |
|---|
| 988 | +static const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = { |
|---|
| 981 | 989 | .ieee_getets = mlx5e_dcbnl_ieee_getets, |
|---|
| 982 | 990 | .ieee_setets = mlx5e_dcbnl_ieee_setets, |
|---|
| 983 | 991 | .ieee_getmaxrate = mlx5e_dcbnl_ieee_getmaxrate, |
|---|
| .. | .. |
|---|
| 1008 | 1016 | .getpfcstate = mlx5e_dcbnl_getpfcstate, |
|---|
| 1009 | 1017 | .setpfcstate = mlx5e_dcbnl_setpfcstate, |
|---|
| 1010 | 1018 | }; |
|---|
| 1019 | + |
|---|
| 1020 | +void mlx5e_dcbnl_build_netdev(struct net_device *netdev) |
|---|
| 1021 | +{ |
|---|
| 1022 | + struct mlx5e_priv *priv = netdev_priv(netdev); |
|---|
| 1023 | + struct mlx5_core_dev *mdev = priv->mdev; |
|---|
| 1024 | + |
|---|
| 1025 | + if (MLX5_CAP_GEN(mdev, vport_group_manager) && MLX5_CAP_GEN(mdev, qos)) |
|---|
| 1026 | + netdev->dcbnl_ops = &mlx5e_dcbnl_ops; |
|---|
| 1027 | +} |
|---|
| 1028 | + |
|---|
| 1029 | +void mlx5e_dcbnl_build_rep_netdev(struct net_device *netdev) |
|---|
| 1030 | +{ |
|---|
| 1031 | + struct mlx5e_priv *priv = netdev_priv(netdev); |
|---|
| 1032 | + struct mlx5_core_dev *mdev = priv->mdev; |
|---|
| 1033 | + |
|---|
| 1034 | + if (MLX5_CAP_GEN(mdev, qos)) |
|---|
| 1035 | + netdev->dcbnl_ops = &mlx5e_dcbnl_ops; |
|---|
| 1036 | +} |
|---|
| 1011 | 1037 | |
|---|
| 1012 | 1038 | static void mlx5e_dcbnl_query_dcbx_mode(struct mlx5e_priv *priv, |
|---|
| 1013 | 1039 | enum mlx5_dcbx_oper_mode *mode) |
|---|
| .. | .. |
|---|
| 1098 | 1124 | mlx5e_dcbnl_dscp_app(priv, DELETE); |
|---|
| 1099 | 1125 | } |
|---|
| 1100 | 1126 | |
|---|
| 1101 | | -static void mlx5e_trust_update_tx_min_inline_mode(struct mlx5e_priv *priv, |
|---|
| 1102 | | - struct mlx5e_params *params) |
|---|
| 1127 | +static void mlx5e_params_calc_trust_tx_min_inline_mode(struct mlx5_core_dev *mdev, |
|---|
| 1128 | + struct mlx5e_params *params, |
|---|
| 1129 | + u8 trust_state) |
|---|
| 1103 | 1130 | { |
|---|
| 1104 | | - params->tx_min_inline_mode = mlx5e_params_calculate_tx_min_inline(priv->mdev); |
|---|
| 1105 | | - if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP && |
|---|
| 1131 | + mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode); |
|---|
| 1132 | + if (trust_state == MLX5_QPTS_TRUST_DSCP && |
|---|
| 1106 | 1133 | params->tx_min_inline_mode == MLX5_INLINE_MODE_L2) |
|---|
| 1107 | 1134 | params->tx_min_inline_mode = MLX5_INLINE_MODE_IP; |
|---|
| 1108 | 1135 | } |
|---|
| 1109 | 1136 | |
|---|
| 1110 | | -static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv) |
|---|
| 1137 | +static int mlx5e_update_trust_state_hw(struct mlx5e_priv *priv, void *context) |
|---|
| 1111 | 1138 | { |
|---|
| 1112 | | - struct mlx5e_channels new_channels = {}; |
|---|
| 1139 | + u8 *trust_state = context; |
|---|
| 1140 | + int err; |
|---|
| 1113 | 1141 | |
|---|
| 1114 | | - mutex_lock(&priv->state_lock); |
|---|
| 1142 | + err = mlx5_set_trust_state(priv->mdev, *trust_state); |
|---|
| 1143 | + if (err) |
|---|
| 1144 | + return err; |
|---|
| 1145 | + priv->dcbx_dp.trust_state = *trust_state; |
|---|
| 1115 | 1146 | |
|---|
| 1116 | | - new_channels.params = priv->channels.params; |
|---|
| 1117 | | - mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params); |
|---|
| 1118 | | - |
|---|
| 1119 | | - if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
|---|
| 1120 | | - priv->channels.params = new_channels.params; |
|---|
| 1121 | | - goto out; |
|---|
| 1122 | | - } |
|---|
| 1123 | | - |
|---|
| 1124 | | - /* Skip if tx_min_inline is the same */ |
|---|
| 1125 | | - if (new_channels.params.tx_min_inline_mode == |
|---|
| 1126 | | - priv->channels.params.tx_min_inline_mode) |
|---|
| 1127 | | - goto out; |
|---|
| 1128 | | - |
|---|
| 1129 | | - if (mlx5e_open_channels(priv, &new_channels)) |
|---|
| 1130 | | - goto out; |
|---|
| 1131 | | - mlx5e_switch_priv_channels(priv, &new_channels, NULL); |
|---|
| 1132 | | - |
|---|
| 1133 | | -out: |
|---|
| 1134 | | - mutex_unlock(&priv->state_lock); |
|---|
| 1147 | + return 0; |
|---|
| 1135 | 1148 | } |
|---|
| 1136 | 1149 | |
|---|
| 1137 | 1150 | static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state) |
|---|
| 1138 | 1151 | { |
|---|
| 1139 | | - int err; |
|---|
| 1152 | + struct mlx5e_channels new_channels = {}; |
|---|
| 1153 | + bool reset_channels = true; |
|---|
| 1154 | + bool opened; |
|---|
| 1155 | + int err = 0; |
|---|
| 1140 | 1156 | |
|---|
| 1141 | | - err = mlx5_set_trust_state(priv->mdev, trust_state); |
|---|
| 1142 | | - if (err) |
|---|
| 1143 | | - return err; |
|---|
| 1144 | | - priv->dcbx_dp.trust_state = trust_state; |
|---|
| 1145 | | - mlx5e_trust_update_sq_inline_mode(priv); |
|---|
| 1157 | + mutex_lock(&priv->state_lock); |
|---|
| 1158 | + |
|---|
| 1159 | + new_channels.params = priv->channels.params; |
|---|
| 1160 | + mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &new_channels.params, |
|---|
| 1161 | + trust_state); |
|---|
| 1162 | + |
|---|
| 1163 | + opened = test_bit(MLX5E_STATE_OPENED, &priv->state); |
|---|
| 1164 | + if (!opened) |
|---|
| 1165 | + reset_channels = false; |
|---|
| 1166 | + |
|---|
| 1167 | + /* Skip if tx_min_inline is the same */ |
|---|
| 1168 | + if (new_channels.params.tx_min_inline_mode == |
|---|
| 1169 | + priv->channels.params.tx_min_inline_mode) |
|---|
| 1170 | + reset_channels = false; |
|---|
| 1171 | + |
|---|
| 1172 | + if (reset_channels) { |
|---|
| 1173 | + err = mlx5e_safe_switch_channels(priv, &new_channels, |
|---|
| 1174 | + mlx5e_update_trust_state_hw, |
|---|
| 1175 | + &trust_state); |
|---|
| 1176 | + } else { |
|---|
| 1177 | + err = mlx5e_update_trust_state_hw(priv, &trust_state); |
|---|
| 1178 | + if (!err && !opened) |
|---|
| 1179 | + priv->channels.params = new_channels.params; |
|---|
| 1180 | + } |
|---|
| 1181 | + |
|---|
| 1182 | + mutex_unlock(&priv->state_lock); |
|---|
| 1146 | 1183 | |
|---|
| 1147 | 1184 | return err; |
|---|
| 1148 | 1185 | } |
|---|
| .. | .. |
|---|
| 1173 | 1210 | if (err) |
|---|
| 1174 | 1211 | return err; |
|---|
| 1175 | 1212 | |
|---|
| 1176 | | - mlx5e_trust_update_tx_min_inline_mode(priv, &priv->channels.params); |
|---|
| 1213 | + if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_PCP && priv->dcbx.dscp_app_cnt) { |
|---|
| 1214 | + /* |
|---|
| 1215 | + * Align the driver state with the register state. |
|---|
| 1216 | + * Temporary state change is required to enable the app list reset. |
|---|
| 1217 | + */ |
|---|
| 1218 | + priv->dcbx_dp.trust_state = MLX5_QPTS_TRUST_DSCP; |
|---|
| 1219 | + mlx5e_dcbnl_delete_app(priv); |
|---|
| 1220 | + priv->dcbx_dp.trust_state = MLX5_QPTS_TRUST_PCP; |
|---|
| 1221 | + } |
|---|
| 1222 | + |
|---|
| 1223 | + mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &priv->channels.params, |
|---|
| 1224 | + priv->dcbx_dp.trust_state); |
|---|
| 1177 | 1225 | |
|---|
| 1178 | 1226 | err = mlx5_query_dscp2prio(priv->mdev, priv->dcbx_dp.dscp2prio); |
|---|
| 1179 | 1227 | if (err) |
|---|
| 1180 | 1228 | return err; |
|---|
| 1181 | 1229 | |
|---|
| 1182 | 1230 | return 0; |
|---|
| 1231 | +} |
|---|
| 1232 | + |
|---|
| 1233 | +#define MLX5E_BUFFER_CELL_SHIFT 7 |
|---|
| 1234 | + |
|---|
| 1235 | +static u16 mlx5e_query_port_buffers_cell_size(struct mlx5e_priv *priv) |
|---|
| 1236 | +{ |
|---|
| 1237 | + struct mlx5_core_dev *mdev = priv->mdev; |
|---|
| 1238 | + u32 out[MLX5_ST_SZ_DW(sbcam_reg)] = {}; |
|---|
| 1239 | + u32 in[MLX5_ST_SZ_DW(sbcam_reg)] = {}; |
|---|
| 1240 | + |
|---|
| 1241 | + if (!MLX5_CAP_GEN(mdev, sbcam_reg)) |
|---|
| 1242 | + return (1 << MLX5E_BUFFER_CELL_SHIFT); |
|---|
| 1243 | + |
|---|
| 1244 | + if (mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), |
|---|
| 1245 | + MLX5_REG_SBCAM, 0, 0)) |
|---|
| 1246 | + return (1 << MLX5E_BUFFER_CELL_SHIFT); |
|---|
| 1247 | + |
|---|
| 1248 | + return MLX5_GET(sbcam_reg, out, cap_cell_size); |
|---|
| 1183 | 1249 | } |
|---|
| 1184 | 1250 | |
|---|
| 1185 | 1251 | void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv) |
|---|
| .. | .. |
|---|
| 1199 | 1265 | if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST) |
|---|
| 1200 | 1266 | priv->dcbx.cap |= DCB_CAP_DCBX_HOST; |
|---|
| 1201 | 1267 | |
|---|
| 1268 | + priv->dcbx.port_buff_cell_sz = mlx5e_query_port_buffers_cell_size(priv); |
|---|
| 1202 | 1269 | priv->dcbx.manual_buffer = false; |
|---|
| 1203 | 1270 | priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN; |
|---|
| 1204 | 1271 | |
|---|