.. | .. |
---|
47 | 47 | "tx S/G", |
---|
48 | 48 | "tx error", |
---|
49 | 49 | "rx error", |
---|
| 50 | + "rx dropped", |
---|
| 51 | + "tx dropped", |
---|
50 | 52 | }; |
---|
51 | 53 | |
---|
52 | 54 | static char dpaa_stats_global[][ETH_GSTRING_LEN] = { |
---|
.. | .. |
---|
78 | 80 | static int dpaa_get_link_ksettings(struct net_device *net_dev, |
---|
79 | 81 | struct ethtool_link_ksettings *cmd) |
---|
80 | 82 | { |
---|
81 | | - if (!net_dev->phydev) { |
---|
82 | | - netdev_dbg(net_dev, "phy device not initialized\n"); |
---|
| 83 | + if (!net_dev->phydev) |
---|
83 | 84 | return 0; |
---|
84 | | - } |
---|
85 | 85 | |
---|
86 | 86 | phy_ethtool_ksettings_get(net_dev->phydev, cmd); |
---|
87 | 87 | |
---|
.. | .. |
---|
93 | 93 | { |
---|
94 | 94 | int err; |
---|
95 | 95 | |
---|
96 | | - if (!net_dev->phydev) { |
---|
97 | | - netdev_err(net_dev, "phy device not initialized\n"); |
---|
| 96 | + if (!net_dev->phydev) |
---|
98 | 97 | return -ENODEV; |
---|
99 | | - } |
---|
100 | 98 | |
---|
101 | 99 | err = phy_ethtool_ksettings_set(net_dev->phydev, cmd); |
---|
102 | 100 | if (err < 0) |
---|
.. | .. |
---|
108 | 106 | static void dpaa_get_drvinfo(struct net_device *net_dev, |
---|
109 | 107 | struct ethtool_drvinfo *drvinfo) |
---|
110 | 108 | { |
---|
111 | | - int len; |
---|
112 | | - |
---|
113 | 109 | strlcpy(drvinfo->driver, KBUILD_MODNAME, |
---|
114 | 110 | sizeof(drvinfo->driver)); |
---|
115 | | - len = snprintf(drvinfo->version, sizeof(drvinfo->version), |
---|
116 | | - "%X", 0); |
---|
117 | | - len = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
---|
118 | | - "%X", 0); |
---|
119 | | - |
---|
120 | | - if (len >= sizeof(drvinfo->fw_version)) { |
---|
121 | | - /* Truncated output */ |
---|
122 | | - netdev_notice(net_dev, "snprintf() = %d\n", len); |
---|
123 | | - } |
---|
124 | 111 | strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent), |
---|
125 | 112 | sizeof(drvinfo->bus_info)); |
---|
126 | 113 | } |
---|
.. | .. |
---|
140 | 127 | { |
---|
141 | 128 | int err; |
---|
142 | 129 | |
---|
143 | | - if (!net_dev->phydev) { |
---|
144 | | - netdev_err(net_dev, "phy device not initialized\n"); |
---|
| 130 | + if (!net_dev->phydev) |
---|
145 | 131 | return -ENODEV; |
---|
146 | | - } |
---|
147 | 132 | |
---|
148 | 133 | err = 0; |
---|
149 | 134 | if (net_dev->phydev->autoneg) { |
---|
.. | .. |
---|
165 | 150 | priv = netdev_priv(net_dev); |
---|
166 | 151 | mac_dev = priv->mac_dev; |
---|
167 | 152 | |
---|
168 | | - if (!net_dev->phydev) { |
---|
169 | | - netdev_err(net_dev, "phy device not initialized\n"); |
---|
| 153 | + if (!net_dev->phydev) |
---|
170 | 154 | return; |
---|
171 | | - } |
---|
172 | 155 | |
---|
173 | 156 | epause->autoneg = mac_dev->autoneg_pause; |
---|
174 | 157 | epause->rx_pause = mac_dev->rx_pause_active; |
---|
.. | .. |
---|
182 | 165 | struct phy_device *phydev; |
---|
183 | 166 | bool rx_pause, tx_pause; |
---|
184 | 167 | struct dpaa_priv *priv; |
---|
185 | | - u32 newadv, oldadv; |
---|
186 | 168 | int err; |
---|
187 | 169 | |
---|
188 | 170 | priv = netdev_priv(net_dev); |
---|
.. | .. |
---|
194 | 176 | return -ENODEV; |
---|
195 | 177 | } |
---|
196 | 178 | |
---|
197 | | - if (!(phydev->supported & SUPPORTED_Pause) || |
---|
198 | | - (!(phydev->supported & SUPPORTED_Asym_Pause) && |
---|
199 | | - (epause->rx_pause != epause->tx_pause))) |
---|
| 179 | + if (!phy_validate_pause(phydev, epause)) |
---|
200 | 180 | return -EINVAL; |
---|
201 | 181 | |
---|
202 | 182 | /* The MAC should know how to handle PAUSE frame autonegotiation before |
---|
.. | .. |
---|
210 | 190 | /* Determine the sym/asym advertised PAUSE capabilities from the desired |
---|
211 | 191 | * rx/tx pause settings. |
---|
212 | 192 | */ |
---|
213 | | - newadv = 0; |
---|
214 | | - if (epause->rx_pause) |
---|
215 | | - newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause; |
---|
216 | | - if (epause->tx_pause) |
---|
217 | | - newadv ^= ADVERTISED_Asym_Pause; |
---|
218 | 193 | |
---|
219 | | - oldadv = phydev->advertising & |
---|
220 | | - (ADVERTISED_Pause | ADVERTISED_Asym_Pause); |
---|
221 | | - |
---|
222 | | - /* If there are differences between the old and the new advertised |
---|
223 | | - * values, restart PHY autonegotiation and advertise the new values. |
---|
224 | | - */ |
---|
225 | | - if (oldadv != newadv) { |
---|
226 | | - phydev->advertising &= ~(ADVERTISED_Pause |
---|
227 | | - | ADVERTISED_Asym_Pause); |
---|
228 | | - phydev->advertising |= newadv; |
---|
229 | | - if (phydev->autoneg) { |
---|
230 | | - err = phy_start_aneg(phydev); |
---|
231 | | - if (err < 0) |
---|
232 | | - netdev_err(net_dev, "phy_start_aneg() = %d\n", |
---|
233 | | - err); |
---|
234 | | - } |
---|
235 | | - } |
---|
| 194 | + phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause); |
---|
236 | 195 | |
---|
237 | 196 | fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); |
---|
238 | 197 | err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); |
---|
.. | .. |
---|
247 | 206 | unsigned int total_stats, num_stats; |
---|
248 | 207 | |
---|
249 | 208 | num_stats = num_online_cpus() + 1; |
---|
250 | | - total_stats = num_stats * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM) + |
---|
| 209 | + total_stats = num_stats * (DPAA_STATS_PERCPU_LEN + 1) + |
---|
251 | 210 | DPAA_STATS_GLOBAL_LEN; |
---|
252 | 211 | |
---|
253 | 212 | switch (type) { |
---|
.. | .. |
---|
259 | 218 | } |
---|
260 | 219 | |
---|
261 | 220 | static void copy_stats(struct dpaa_percpu_priv *percpu_priv, int num_cpus, |
---|
262 | | - int crr_cpu, u64 *bp_count, u64 *data) |
---|
| 221 | + int crr_cpu, u64 bp_count, u64 *data) |
---|
263 | 222 | { |
---|
264 | 223 | int num_values = num_cpus + 1; |
---|
265 | | - int crr = 0, j; |
---|
| 224 | + int crr = 0; |
---|
266 | 225 | |
---|
267 | 226 | /* update current CPU's stats and also add them to the total values */ |
---|
268 | 227 | data[crr * num_values + crr_cpu] = percpu_priv->in_interrupt; |
---|
.. | .. |
---|
286 | 245 | data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_errors; |
---|
287 | 246 | data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_errors; |
---|
288 | 247 | |
---|
289 | | - for (j = 0; j < DPAA_BPS_NUM; j++) { |
---|
290 | | - data[crr * num_values + crr_cpu] = bp_count[j]; |
---|
291 | | - data[crr++ * num_values + num_cpus] += bp_count[j]; |
---|
292 | | - } |
---|
| 248 | + data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_dropped; |
---|
| 249 | + data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_dropped; |
---|
| 250 | + |
---|
| 251 | + data[crr * num_values + crr_cpu] = percpu_priv->stats.tx_dropped; |
---|
| 252 | + data[crr++ * num_values + num_cpus] += percpu_priv->stats.tx_dropped; |
---|
| 253 | + |
---|
| 254 | + data[crr * num_values + crr_cpu] = bp_count; |
---|
| 255 | + data[crr++ * num_values + num_cpus] += bp_count; |
---|
293 | 256 | } |
---|
294 | 257 | |
---|
295 | 258 | static void dpaa_get_ethtool_stats(struct net_device *net_dev, |
---|
296 | 259 | struct ethtool_stats *stats, u64 *data) |
---|
297 | 260 | { |
---|
298 | | - u64 bp_count[DPAA_BPS_NUM], cg_time, cg_num; |
---|
299 | 261 | struct dpaa_percpu_priv *percpu_priv; |
---|
300 | 262 | struct dpaa_rx_errors rx_errors; |
---|
301 | 263 | unsigned int num_cpus, offset; |
---|
| 264 | + u64 bp_count, cg_time, cg_num; |
---|
302 | 265 | struct dpaa_ern_cnt ern_cnt; |
---|
303 | 266 | struct dpaa_bp *dpaa_bp; |
---|
304 | 267 | struct dpaa_priv *priv; |
---|
305 | | - int total_stats, i, j; |
---|
| 268 | + int total_stats, i; |
---|
306 | 269 | bool cg_status; |
---|
307 | 270 | |
---|
308 | 271 | total_stats = dpaa_get_sset_count(net_dev, ETH_SS_STATS); |
---|
.. | .. |
---|
316 | 279 | |
---|
317 | 280 | for_each_online_cpu(i) { |
---|
318 | 281 | percpu_priv = per_cpu_ptr(priv->percpu_priv, i); |
---|
319 | | - for (j = 0; j < DPAA_BPS_NUM; j++) { |
---|
320 | | - dpaa_bp = priv->dpaa_bps[j]; |
---|
321 | | - if (!dpaa_bp->percpu_count) |
---|
322 | | - continue; |
---|
323 | | - bp_count[j] = *(per_cpu_ptr(dpaa_bp->percpu_count, i)); |
---|
324 | | - } |
---|
| 282 | + dpaa_bp = priv->dpaa_bp; |
---|
| 283 | + if (!dpaa_bp->percpu_count) |
---|
| 284 | + continue; |
---|
| 285 | + bp_count = *(per_cpu_ptr(dpaa_bp->percpu_count, i)); |
---|
325 | 286 | rx_errors.dme += percpu_priv->rx_errors.dme; |
---|
326 | 287 | rx_errors.fpe += percpu_priv->rx_errors.fpe; |
---|
327 | 288 | rx_errors.fse += percpu_priv->rx_errors.fse; |
---|
.. | .. |
---|
339 | 300 | copy_stats(percpu_priv, num_cpus, i, bp_count, data); |
---|
340 | 301 | } |
---|
341 | 302 | |
---|
342 | | - offset = (num_cpus + 1) * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM); |
---|
| 303 | + offset = (num_cpus + 1) * (DPAA_STATS_PERCPU_LEN + 1); |
---|
343 | 304 | memcpy(data + offset, &rx_errors, sizeof(struct dpaa_rx_errors)); |
---|
344 | 305 | |
---|
345 | 306 | offset += sizeof(struct dpaa_rx_errors) / sizeof(u64); |
---|
.. | .. |
---|
387 | 348 | memcpy(strings, string_cpu, ETH_GSTRING_LEN); |
---|
388 | 349 | strings += ETH_GSTRING_LEN; |
---|
389 | 350 | } |
---|
390 | | - for (i = 0; i < DPAA_BPS_NUM; i++) { |
---|
391 | | - for (j = 0; j < num_cpus; j++) { |
---|
392 | | - snprintf(string_cpu, ETH_GSTRING_LEN, |
---|
393 | | - "bpool %c [CPU %d]", 'a' + i, j); |
---|
394 | | - memcpy(strings, string_cpu, ETH_GSTRING_LEN); |
---|
395 | | - strings += ETH_GSTRING_LEN; |
---|
396 | | - } |
---|
397 | | - snprintf(string_cpu, ETH_GSTRING_LEN, "bpool %c [TOTAL]", |
---|
398 | | - 'a' + i); |
---|
| 351 | + for (j = 0; j < num_cpus; j++) { |
---|
| 352 | + snprintf(string_cpu, ETH_GSTRING_LEN, |
---|
| 353 | + "bpool [CPU %d]", j); |
---|
399 | 354 | memcpy(strings, string_cpu, ETH_GSTRING_LEN); |
---|
400 | 355 | strings += ETH_GSTRING_LEN; |
---|
401 | 356 | } |
---|
| 357 | + snprintf(string_cpu, ETH_GSTRING_LEN, "bpool [TOTAL]"); |
---|
| 358 | + memcpy(strings, string_cpu, ETH_GSTRING_LEN); |
---|
| 359 | + strings += ETH_GSTRING_LEN; |
---|
| 360 | + |
---|
402 | 361 | memcpy(strings, dpaa_stats_global, size); |
---|
403 | 362 | } |
---|
404 | 363 | |
---|
.. | .. |
---|
416 | 375 | case UDP_V6_FLOW: |
---|
417 | 376 | if (priv->keygen_in_use) |
---|
418 | 377 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; |
---|
419 | | - /* Fall through */ |
---|
| 378 | + fallthrough; |
---|
420 | 379 | case IPV4_FLOW: |
---|
421 | 380 | case IPV6_FLOW: |
---|
422 | 381 | case SCTP_V4_FLOW: |
---|
.. | .. |
---|
525 | 484 | struct device_node *mac_node = dev->of_node; |
---|
526 | 485 | struct device_node *fman_node = NULL, *ptp_node = NULL; |
---|
527 | 486 | struct platform_device *ptp_dev = NULL; |
---|
528 | | - struct qoriq_ptp *ptp = NULL; |
---|
| 487 | + struct ptp_qoriq *ptp = NULL; |
---|
529 | 488 | |
---|
530 | 489 | info->phc_index = -1; |
---|
531 | 490 | |
---|
532 | 491 | fman_node = of_get_parent(mac_node); |
---|
533 | | - if (fman_node) |
---|
| 492 | + if (fman_node) { |
---|
534 | 493 | ptp_node = of_parse_phandle(fman_node, "ptimer-handle", 0); |
---|
| 494 | + of_node_put(fman_node); |
---|
| 495 | + } |
---|
535 | 496 | |
---|
536 | | - if (ptp_node) |
---|
| 497 | + if (ptp_node) { |
---|
537 | 498 | ptp_dev = of_find_device_by_node(ptp_node); |
---|
| 499 | + of_node_put(ptp_node); |
---|
| 500 | + } |
---|
538 | 501 | |
---|
539 | 502 | if (ptp_dev) |
---|
540 | 503 | ptp = platform_get_drvdata(ptp_dev); |
---|
.. | .. |
---|
553 | 516 | return 0; |
---|
554 | 517 | } |
---|
555 | 518 | |
---|
| 519 | +static int dpaa_get_coalesce(struct net_device *dev, |
---|
| 520 | + struct ethtool_coalesce *c) |
---|
| 521 | +{ |
---|
| 522 | + struct qman_portal *portal; |
---|
| 523 | + u32 period; |
---|
| 524 | + u8 thresh; |
---|
| 525 | + |
---|
| 526 | + portal = qman_get_affine_portal(smp_processor_id()); |
---|
| 527 | + qman_portal_get_iperiod(portal, &period); |
---|
| 528 | + qman_dqrr_get_ithresh(portal, &thresh); |
---|
| 529 | + |
---|
| 530 | + c->rx_coalesce_usecs = period; |
---|
| 531 | + c->rx_max_coalesced_frames = thresh; |
---|
| 532 | + |
---|
| 533 | + return 0; |
---|
| 534 | +} |
---|
| 535 | + |
---|
| 536 | +static int dpaa_set_coalesce(struct net_device *dev, |
---|
| 537 | + struct ethtool_coalesce *c) |
---|
| 538 | +{ |
---|
| 539 | + const cpumask_t *cpus = qman_affine_cpus(); |
---|
| 540 | + bool needs_revert[NR_CPUS] = {false}; |
---|
| 541 | + struct qman_portal *portal; |
---|
| 542 | + u32 period, prev_period; |
---|
| 543 | + u8 thresh, prev_thresh; |
---|
| 544 | + int cpu, res; |
---|
| 545 | + |
---|
| 546 | + period = c->rx_coalesce_usecs; |
---|
| 547 | + thresh = c->rx_max_coalesced_frames; |
---|
| 548 | + |
---|
| 549 | + /* save previous values */ |
---|
| 550 | + portal = qman_get_affine_portal(smp_processor_id()); |
---|
| 551 | + qman_portal_get_iperiod(portal, &prev_period); |
---|
| 552 | + qman_dqrr_get_ithresh(portal, &prev_thresh); |
---|
| 553 | + |
---|
| 554 | + /* set new values */ |
---|
| 555 | + for_each_cpu_and(cpu, cpus, cpu_online_mask) { |
---|
| 556 | + portal = qman_get_affine_portal(cpu); |
---|
| 557 | + res = qman_portal_set_iperiod(portal, period); |
---|
| 558 | + if (res) |
---|
| 559 | + goto revert_values; |
---|
| 560 | + res = qman_dqrr_set_ithresh(portal, thresh); |
---|
| 561 | + if (res) { |
---|
| 562 | + qman_portal_set_iperiod(portal, prev_period); |
---|
| 563 | + goto revert_values; |
---|
| 564 | + } |
---|
| 565 | + needs_revert[cpu] = true; |
---|
| 566 | + } |
---|
| 567 | + |
---|
| 568 | + return 0; |
---|
| 569 | + |
---|
| 570 | +revert_values: |
---|
| 571 | + /* restore previous values */ |
---|
| 572 | + for_each_cpu_and(cpu, cpus, cpu_online_mask) { |
---|
| 573 | + if (!needs_revert[cpu]) |
---|
| 574 | + continue; |
---|
| 575 | + portal = qman_get_affine_portal(cpu); |
---|
| 576 | + /* previous values will not fail, ignore return value */ |
---|
| 577 | + qman_portal_set_iperiod(portal, prev_period); |
---|
| 578 | + qman_dqrr_set_ithresh(portal, prev_thresh); |
---|
| 579 | + } |
---|
| 580 | + |
---|
| 581 | + return res; |
---|
| 582 | +} |
---|
| 583 | + |
---|
556 | 584 | const struct ethtool_ops dpaa_ethtool_ops = { |
---|
| 585 | + .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS | |
---|
| 586 | + ETHTOOL_COALESCE_RX_MAX_FRAMES, |
---|
557 | 587 | .get_drvinfo = dpaa_get_drvinfo, |
---|
558 | 588 | .get_msglevel = dpaa_get_msglevel, |
---|
559 | 589 | .set_msglevel = dpaa_set_msglevel, |
---|
.. | .. |
---|
569 | 599 | .get_rxnfc = dpaa_get_rxnfc, |
---|
570 | 600 | .set_rxnfc = dpaa_set_rxnfc, |
---|
571 | 601 | .get_ts_info = dpaa_get_ts_info, |
---|
| 602 | + .get_coalesce = dpaa_get_coalesce, |
---|
| 603 | + .set_coalesce = dpaa_set_coalesce, |
---|
572 | 604 | }; |
---|