.. | .. |
---|
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) && \ |
---|
.. | .. |
---|
109 | 117 | if (!MLX5_CAP_GEN(priv->mdev, ets)) |
---|
110 | 118 | return -EOPNOTSUPP; |
---|
111 | 119 | |
---|
112 | | - ets->ets_cap = mlx5_max_tc(priv->mdev) + 1; |
---|
113 | | - for (i = 0; i < ets->ets_cap; i++) { |
---|
| 120 | + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { |
---|
114 | 121 | err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]); |
---|
115 | 122 | if (err) |
---|
116 | 123 | return err; |
---|
| 124 | + } |
---|
117 | 125 | |
---|
| 126 | + ets->ets_cap = mlx5_max_tc(priv->mdev) + 1; |
---|
| 127 | + for (i = 0; i < ets->ets_cap; i++) { |
---|
118 | 128 | err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]); |
---|
119 | 129 | if (err) |
---|
120 | 130 | return err; |
---|
.. | .. |
---|
238 | 248 | * Report both group #0 and #1 as ETS type. |
---|
239 | 249 | * All the tcs in group #0 will be reported with 0% BW. |
---|
240 | 250 | */ |
---|
241 | | -int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) |
---|
| 251 | +static int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) |
---|
242 | 252 | { |
---|
243 | 253 | struct mlx5_core_dev *mdev = priv->mdev; |
---|
244 | 254 | u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS]; |
---|
.. | .. |
---|
680 | 690 | |
---|
681 | 691 | memset(perm_addr, 0xff, MAX_ADDR_LEN); |
---|
682 | 692 | |
---|
683 | | - mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr); |
---|
| 693 | + mlx5_query_mac_address(priv->mdev, perm_addr); |
---|
684 | 694 | } |
---|
685 | 695 | |
---|
686 | 696 | static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev, |
---|
.. | .. |
---|
977 | 987 | return err; |
---|
978 | 988 | } |
---|
979 | 989 | |
---|
980 | | -const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = { |
---|
| 990 | +static const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = { |
---|
981 | 991 | .ieee_getets = mlx5e_dcbnl_ieee_getets, |
---|
982 | 992 | .ieee_setets = mlx5e_dcbnl_ieee_setets, |
---|
983 | 993 | .ieee_getmaxrate = mlx5e_dcbnl_ieee_getmaxrate, |
---|
.. | .. |
---|
1008 | 1018 | .getpfcstate = mlx5e_dcbnl_getpfcstate, |
---|
1009 | 1019 | .setpfcstate = mlx5e_dcbnl_setpfcstate, |
---|
1010 | 1020 | }; |
---|
| 1021 | + |
---|
| 1022 | +void mlx5e_dcbnl_build_netdev(struct net_device *netdev) |
---|
| 1023 | +{ |
---|
| 1024 | + struct mlx5e_priv *priv = netdev_priv(netdev); |
---|
| 1025 | + struct mlx5_core_dev *mdev = priv->mdev; |
---|
| 1026 | + |
---|
| 1027 | + if (MLX5_CAP_GEN(mdev, vport_group_manager) && MLX5_CAP_GEN(mdev, qos)) |
---|
| 1028 | + netdev->dcbnl_ops = &mlx5e_dcbnl_ops; |
---|
| 1029 | +} |
---|
| 1030 | + |
---|
| 1031 | +void mlx5e_dcbnl_build_rep_netdev(struct net_device *netdev) |
---|
| 1032 | +{ |
---|
| 1033 | + struct mlx5e_priv *priv = netdev_priv(netdev); |
---|
| 1034 | + struct mlx5_core_dev *mdev = priv->mdev; |
---|
| 1035 | + |
---|
| 1036 | + if (MLX5_CAP_GEN(mdev, qos)) |
---|
| 1037 | + netdev->dcbnl_ops = &mlx5e_dcbnl_ops; |
---|
| 1038 | +} |
---|
1011 | 1039 | |
---|
1012 | 1040 | static void mlx5e_dcbnl_query_dcbx_mode(struct mlx5e_priv *priv, |
---|
1013 | 1041 | enum mlx5_dcbx_oper_mode *mode) |
---|
.. | .. |
---|
1098 | 1126 | mlx5e_dcbnl_dscp_app(priv, DELETE); |
---|
1099 | 1127 | } |
---|
1100 | 1128 | |
---|
1101 | | -static void mlx5e_trust_update_tx_min_inline_mode(struct mlx5e_priv *priv, |
---|
1102 | | - struct mlx5e_params *params) |
---|
| 1129 | +static void mlx5e_params_calc_trust_tx_min_inline_mode(struct mlx5_core_dev *mdev, |
---|
| 1130 | + struct mlx5e_params *params, |
---|
| 1131 | + u8 trust_state) |
---|
1103 | 1132 | { |
---|
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 && |
---|
| 1133 | + mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode); |
---|
| 1134 | + if (trust_state == MLX5_QPTS_TRUST_DSCP && |
---|
1106 | 1135 | params->tx_min_inline_mode == MLX5_INLINE_MODE_L2) |
---|
1107 | 1136 | params->tx_min_inline_mode = MLX5_INLINE_MODE_IP; |
---|
1108 | 1137 | } |
---|
1109 | 1138 | |
---|
1110 | | -static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv) |
---|
| 1139 | +static int mlx5e_update_trust_state_hw(struct mlx5e_priv *priv, void *context) |
---|
1111 | 1140 | { |
---|
1112 | | - struct mlx5e_channels new_channels = {}; |
---|
| 1141 | + u8 *trust_state = context; |
---|
| 1142 | + int err; |
---|
1113 | 1143 | |
---|
1114 | | - mutex_lock(&priv->state_lock); |
---|
| 1144 | + err = mlx5_set_trust_state(priv->mdev, *trust_state); |
---|
| 1145 | + if (err) |
---|
| 1146 | + return err; |
---|
| 1147 | + priv->dcbx_dp.trust_state = *trust_state; |
---|
1115 | 1148 | |
---|
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); |
---|
| 1149 | + return 0; |
---|
1135 | 1150 | } |
---|
1136 | 1151 | |
---|
1137 | 1152 | static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state) |
---|
1138 | 1153 | { |
---|
1139 | | - int err; |
---|
| 1154 | + struct mlx5e_channels new_channels = {}; |
---|
| 1155 | + bool reset_channels = true; |
---|
| 1156 | + bool opened; |
---|
| 1157 | + int err = 0; |
---|
1140 | 1158 | |
---|
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); |
---|
| 1159 | + mutex_lock(&priv->state_lock); |
---|
| 1160 | + |
---|
| 1161 | + new_channels.params = priv->channels.params; |
---|
| 1162 | + mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &new_channels.params, |
---|
| 1163 | + trust_state); |
---|
| 1164 | + |
---|
| 1165 | + opened = test_bit(MLX5E_STATE_OPENED, &priv->state); |
---|
| 1166 | + if (!opened) |
---|
| 1167 | + reset_channels = false; |
---|
| 1168 | + |
---|
| 1169 | + /* Skip if tx_min_inline is the same */ |
---|
| 1170 | + if (new_channels.params.tx_min_inline_mode == |
---|
| 1171 | + priv->channels.params.tx_min_inline_mode) |
---|
| 1172 | + reset_channels = false; |
---|
| 1173 | + |
---|
| 1174 | + if (reset_channels) { |
---|
| 1175 | + err = mlx5e_safe_switch_channels(priv, &new_channels, |
---|
| 1176 | + mlx5e_update_trust_state_hw, |
---|
| 1177 | + &trust_state); |
---|
| 1178 | + } else { |
---|
| 1179 | + err = mlx5e_update_trust_state_hw(priv, &trust_state); |
---|
| 1180 | + if (!err && !opened) |
---|
| 1181 | + priv->channels.params = new_channels.params; |
---|
| 1182 | + } |
---|
| 1183 | + |
---|
| 1184 | + mutex_unlock(&priv->state_lock); |
---|
1146 | 1185 | |
---|
1147 | 1186 | return err; |
---|
1148 | 1187 | } |
---|
.. | .. |
---|
1173 | 1212 | if (err) |
---|
1174 | 1213 | return err; |
---|
1175 | 1214 | |
---|
1176 | | - mlx5e_trust_update_tx_min_inline_mode(priv, &priv->channels.params); |
---|
| 1215 | + if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_PCP && priv->dcbx.dscp_app_cnt) { |
---|
| 1216 | + /* |
---|
| 1217 | + * Align the driver state with the register state. |
---|
| 1218 | + * Temporary state change is required to enable the app list reset. |
---|
| 1219 | + */ |
---|
| 1220 | + priv->dcbx_dp.trust_state = MLX5_QPTS_TRUST_DSCP; |
---|
| 1221 | + mlx5e_dcbnl_delete_app(priv); |
---|
| 1222 | + priv->dcbx_dp.trust_state = MLX5_QPTS_TRUST_PCP; |
---|
| 1223 | + } |
---|
| 1224 | + |
---|
| 1225 | + mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &priv->channels.params, |
---|
| 1226 | + priv->dcbx_dp.trust_state); |
---|
1177 | 1227 | |
---|
1178 | 1228 | err = mlx5_query_dscp2prio(priv->mdev, priv->dcbx_dp.dscp2prio); |
---|
1179 | 1229 | if (err) |
---|
1180 | 1230 | return err; |
---|
1181 | 1231 | |
---|
1182 | 1232 | return 0; |
---|
| 1233 | +} |
---|
| 1234 | + |
---|
| 1235 | +#define MLX5E_BUFFER_CELL_SHIFT 7 |
---|
| 1236 | + |
---|
| 1237 | +static u16 mlx5e_query_port_buffers_cell_size(struct mlx5e_priv *priv) |
---|
| 1238 | +{ |
---|
| 1239 | + struct mlx5_core_dev *mdev = priv->mdev; |
---|
| 1240 | + u32 out[MLX5_ST_SZ_DW(sbcam_reg)] = {}; |
---|
| 1241 | + u32 in[MLX5_ST_SZ_DW(sbcam_reg)] = {}; |
---|
| 1242 | + |
---|
| 1243 | + if (!MLX5_CAP_GEN(mdev, sbcam_reg)) |
---|
| 1244 | + return (1 << MLX5E_BUFFER_CELL_SHIFT); |
---|
| 1245 | + |
---|
| 1246 | + if (mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), |
---|
| 1247 | + MLX5_REG_SBCAM, 0, 0)) |
---|
| 1248 | + return (1 << MLX5E_BUFFER_CELL_SHIFT); |
---|
| 1249 | + |
---|
| 1250 | + return MLX5_GET(sbcam_reg, out, cap_cell_size); |
---|
1183 | 1251 | } |
---|
1184 | 1252 | |
---|
1185 | 1253 | void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv) |
---|
.. | .. |
---|
1199 | 1267 | if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST) |
---|
1200 | 1268 | priv->dcbx.cap |= DCB_CAP_DCBX_HOST; |
---|
1201 | 1269 | |
---|
| 1270 | + priv->dcbx.port_buff_cell_sz = mlx5e_query_port_buffers_cell_size(priv); |
---|
1202 | 1271 | priv->dcbx.manual_buffer = false; |
---|
1203 | 1272 | priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN; |
---|
1204 | 1273 | |
---|