1 /** 2 * Copyright 2013 Cisco Systems, Inc. All rights reserved. 3 * 4 * This program is free software; you may redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; version 2 of the License. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15 * SOFTWARE. 16 * 17 */ 18 19 #include <linux/netdevice.h> 20 #include <linux/ethtool.h> 21 22 #include "enic_res.h" 23 #include "enic.h" 24 #include "enic_dev.h" 25 #include "enic_clsf.h" 26 #include "vnic_rss.h" 27 #include "vnic_stats.h" 28 29 struct enic_stat { 30 char name[ETH_GSTRING_LEN]; 31 unsigned int index; 32 }; 33 34 #define ENIC_TX_STAT(stat) { \ 35 .name = #stat, \ 36 .index = offsetof(struct vnic_tx_stats, stat) / sizeof(u64) \ 37 } 38 39 #define ENIC_RX_STAT(stat) { \ 40 .name = #stat, \ 41 .index = offsetof(struct vnic_rx_stats, stat) / sizeof(u64) \ 42 } 43 44 #define ENIC_GEN_STAT(stat) { \ 45 .name = #stat, \ 46 .index = offsetof(struct vnic_gen_stats, stat) / sizeof(u64)\ 47 } 48 49 static const struct enic_stat enic_tx_stats[] = { 50 ENIC_TX_STAT(tx_frames_ok), 51 ENIC_TX_STAT(tx_unicast_frames_ok), 52 ENIC_TX_STAT(tx_multicast_frames_ok), 53 ENIC_TX_STAT(tx_broadcast_frames_ok), 54 ENIC_TX_STAT(tx_bytes_ok), 55 ENIC_TX_STAT(tx_unicast_bytes_ok), 56 ENIC_TX_STAT(tx_multicast_bytes_ok), 57 ENIC_TX_STAT(tx_broadcast_bytes_ok), 58 ENIC_TX_STAT(tx_drops), 59 ENIC_TX_STAT(tx_errors), 60 ENIC_TX_STAT(tx_tso), 61 }; 62 63 static const struct enic_stat enic_rx_stats[] = { 64 ENIC_RX_STAT(rx_frames_ok), 65 ENIC_RX_STAT(rx_frames_total), 66 ENIC_RX_STAT(rx_unicast_frames_ok), 67 ENIC_RX_STAT(rx_multicast_frames_ok), 68 ENIC_RX_STAT(rx_broadcast_frames_ok), 69 ENIC_RX_STAT(rx_bytes_ok), 70 ENIC_RX_STAT(rx_unicast_bytes_ok), 71 ENIC_RX_STAT(rx_multicast_bytes_ok), 72 ENIC_RX_STAT(rx_broadcast_bytes_ok), 73 ENIC_RX_STAT(rx_drop), 74 ENIC_RX_STAT(rx_no_bufs), 75 ENIC_RX_STAT(rx_errors), 76 ENIC_RX_STAT(rx_rss), 77 ENIC_RX_STAT(rx_crc_errors), 78 ENIC_RX_STAT(rx_frames_64), 79 ENIC_RX_STAT(rx_frames_127), 80 ENIC_RX_STAT(rx_frames_255), 81 ENIC_RX_STAT(rx_frames_511), 82 ENIC_RX_STAT(rx_frames_1023), 83 ENIC_RX_STAT(rx_frames_1518), 84 ENIC_RX_STAT(rx_frames_to_max), 85 }; 86 87 static const struct enic_stat enic_gen_stats[] = { 88 ENIC_GEN_STAT(dma_map_error), 89 }; 90 91 static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats); 92 static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats); 93 static const unsigned int enic_n_gen_stats = ARRAY_SIZE(enic_gen_stats); 94 95 static void enic_intr_coal_set_rx(struct enic *enic, u32 timer) 96 { 97 int i; 98 int intr; 99 100 for (i = 0; i < enic->rq_count; i++) { 101 intr = enic_msix_rq_intr(enic, i); 102 vnic_intr_coalescing_timer_set(&enic->intr[intr], timer); 103 } 104 } 105 106 static int enic_get_settings(struct net_device *netdev, 107 struct ethtool_cmd *ecmd) 108 { 109 struct enic *enic = netdev_priv(netdev); 110 111 ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); 112 ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); 113 ecmd->port = PORT_FIBRE; 114 ecmd->transceiver = XCVR_EXTERNAL; 115 116 if (netif_carrier_ok(netdev)) { 117 ethtool_cmd_speed_set(ecmd, vnic_dev_port_speed(enic->vdev)); 118 ecmd->duplex = DUPLEX_FULL; 119 } else { 120 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); 121 ecmd->duplex = DUPLEX_UNKNOWN; 122 } 123 124 ecmd->autoneg = AUTONEG_DISABLE; 125 126 return 0; 127 } 128 129 static void enic_get_drvinfo(struct net_device *netdev, 130 struct ethtool_drvinfo *drvinfo) 131 { 132 struct enic *enic = netdev_priv(netdev); 133 struct vnic_devcmd_fw_info *fw_info; 134 135 enic_dev_fw_info(enic, &fw_info); 136 137 strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); 138 strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); 139 strlcpy(drvinfo->fw_version, fw_info->fw_version, 140 sizeof(drvinfo->fw_version)); 141 strlcpy(drvinfo->bus_info, pci_name(enic->pdev), 142 sizeof(drvinfo->bus_info)); 143 } 144 145 static void enic_get_strings(struct net_device *netdev, u32 stringset, 146 u8 *data) 147 { 148 unsigned int i; 149 150 switch (stringset) { 151 case ETH_SS_STATS: 152 for (i = 0; i < enic_n_tx_stats; i++) { 153 memcpy(data, enic_tx_stats[i].name, ETH_GSTRING_LEN); 154 data += ETH_GSTRING_LEN; 155 } 156 for (i = 0; i < enic_n_rx_stats; i++) { 157 memcpy(data, enic_rx_stats[i].name, ETH_GSTRING_LEN); 158 data += ETH_GSTRING_LEN; 159 } 160 for (i = 0; i < enic_n_gen_stats; i++) { 161 memcpy(data, enic_gen_stats[i].name, ETH_GSTRING_LEN); 162 data += ETH_GSTRING_LEN; 163 } 164 break; 165 } 166 } 167 168 static int enic_get_sset_count(struct net_device *netdev, int sset) 169 { 170 switch (sset) { 171 case ETH_SS_STATS: 172 return enic_n_tx_stats + enic_n_rx_stats + enic_n_gen_stats; 173 default: 174 return -EOPNOTSUPP; 175 } 176 } 177 178 static void enic_get_ethtool_stats(struct net_device *netdev, 179 struct ethtool_stats *stats, u64 *data) 180 { 181 struct enic *enic = netdev_priv(netdev); 182 struct vnic_stats *vstats; 183 unsigned int i; 184 185 enic_dev_stats_dump(enic, &vstats); 186 187 for (i = 0; i < enic_n_tx_stats; i++) 188 *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].index]; 189 for (i = 0; i < enic_n_rx_stats; i++) 190 *(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].index]; 191 for (i = 0; i < enic_n_gen_stats; i++) 192 *(data++) = ((u64 *)&enic->gen_stats)[enic_gen_stats[i].index]; 193 } 194 195 static u32 enic_get_msglevel(struct net_device *netdev) 196 { 197 struct enic *enic = netdev_priv(netdev); 198 return enic->msg_enable; 199 } 200 201 static void enic_set_msglevel(struct net_device *netdev, u32 value) 202 { 203 struct enic *enic = netdev_priv(netdev); 204 enic->msg_enable = value; 205 } 206 207 static int enic_get_coalesce(struct net_device *netdev, 208 struct ethtool_coalesce *ecmd) 209 { 210 struct enic *enic = netdev_priv(netdev); 211 struct enic_rx_coal *rxcoal = &enic->rx_coalesce_setting; 212 213 ecmd->tx_coalesce_usecs = enic->tx_coalesce_usecs; 214 ecmd->rx_coalesce_usecs = enic->rx_coalesce_usecs; 215 if (rxcoal->use_adaptive_rx_coalesce) 216 ecmd->use_adaptive_rx_coalesce = 1; 217 ecmd->rx_coalesce_usecs_low = rxcoal->small_pkt_range_start; 218 ecmd->rx_coalesce_usecs_high = rxcoal->range_end; 219 220 return 0; 221 } 222 223 static int enic_set_coalesce(struct net_device *netdev, 224 struct ethtool_coalesce *ecmd) 225 { 226 struct enic *enic = netdev_priv(netdev); 227 u32 tx_coalesce_usecs; 228 u32 rx_coalesce_usecs; 229 u32 rx_coalesce_usecs_low; 230 u32 rx_coalesce_usecs_high; 231 u32 coalesce_usecs_max; 232 unsigned int i, intr; 233 struct enic_rx_coal *rxcoal = &enic->rx_coalesce_setting; 234 235 coalesce_usecs_max = vnic_dev_get_intr_coal_timer_max(enic->vdev); 236 tx_coalesce_usecs = min_t(u32, ecmd->tx_coalesce_usecs, 237 coalesce_usecs_max); 238 rx_coalesce_usecs = min_t(u32, ecmd->rx_coalesce_usecs, 239 coalesce_usecs_max); 240 241 rx_coalesce_usecs_low = min_t(u32, ecmd->rx_coalesce_usecs_low, 242 coalesce_usecs_max); 243 rx_coalesce_usecs_high = min_t(u32, ecmd->rx_coalesce_usecs_high, 244 coalesce_usecs_max); 245 246 switch (vnic_dev_get_intr_mode(enic->vdev)) { 247 case VNIC_DEV_INTR_MODE_INTX: 248 if (tx_coalesce_usecs != rx_coalesce_usecs) 249 return -EINVAL; 250 if (ecmd->use_adaptive_rx_coalesce || 251 ecmd->rx_coalesce_usecs_low || 252 ecmd->rx_coalesce_usecs_high) 253 return -EINVAL; 254 255 intr = enic_legacy_io_intr(); 256 vnic_intr_coalescing_timer_set(&enic->intr[intr], 257 tx_coalesce_usecs); 258 break; 259 case VNIC_DEV_INTR_MODE_MSI: 260 if (tx_coalesce_usecs != rx_coalesce_usecs) 261 return -EINVAL; 262 if (ecmd->use_adaptive_rx_coalesce || 263 ecmd->rx_coalesce_usecs_low || 264 ecmd->rx_coalesce_usecs_high) 265 return -EINVAL; 266 267 vnic_intr_coalescing_timer_set(&enic->intr[0], 268 tx_coalesce_usecs); 269 break; 270 case VNIC_DEV_INTR_MODE_MSIX: 271 if (ecmd->rx_coalesce_usecs_high && 272 (rx_coalesce_usecs_high < 273 rx_coalesce_usecs_low + ENIC_AIC_LARGE_PKT_DIFF)) 274 return -EINVAL; 275 276 for (i = 0; i < enic->wq_count; i++) { 277 intr = enic_msix_wq_intr(enic, i); 278 vnic_intr_coalescing_timer_set(&enic->intr[intr], 279 tx_coalesce_usecs); 280 } 281 282 rxcoal->use_adaptive_rx_coalesce = 283 !!ecmd->use_adaptive_rx_coalesce; 284 if (!rxcoal->use_adaptive_rx_coalesce) 285 enic_intr_coal_set_rx(enic, rx_coalesce_usecs); 286 287 if (ecmd->rx_coalesce_usecs_high) { 288 rxcoal->range_end = rx_coalesce_usecs_high; 289 rxcoal->small_pkt_range_start = rx_coalesce_usecs_low; 290 rxcoal->large_pkt_range_start = rx_coalesce_usecs_low + 291 ENIC_AIC_LARGE_PKT_DIFF; 292 } 293 break; 294 default: 295 break; 296 } 297 298 enic->tx_coalesce_usecs = tx_coalesce_usecs; 299 enic->rx_coalesce_usecs = rx_coalesce_usecs; 300 301 return 0; 302 } 303 304 static int enic_grxclsrlall(struct enic *enic, struct ethtool_rxnfc *cmd, 305 u32 *rule_locs) 306 { 307 int j, ret = 0, cnt = 0; 308 309 cmd->data = enic->rfs_h.max - enic->rfs_h.free; 310 for (j = 0; j < (1 << ENIC_RFS_FLW_BITSHIFT); j++) { 311 struct hlist_head *hhead; 312 struct hlist_node *tmp; 313 struct enic_rfs_fltr_node *n; 314 315 hhead = &enic->rfs_h.ht_head[j]; 316 hlist_for_each_entry_safe(n, tmp, hhead, node) { 317 if (cnt == cmd->rule_cnt) 318 return -EMSGSIZE; 319 rule_locs[cnt] = n->fltr_id; 320 cnt++; 321 } 322 } 323 cmd->rule_cnt = cnt; 324 325 return ret; 326 } 327 328 static int enic_grxclsrule(struct enic *enic, struct ethtool_rxnfc *cmd) 329 { 330 struct ethtool_rx_flow_spec *fsp = 331 (struct ethtool_rx_flow_spec *)&cmd->fs; 332 struct enic_rfs_fltr_node *n; 333 334 n = htbl_fltr_search(enic, (u16)fsp->location); 335 if (!n) 336 return -EINVAL; 337 switch (n->keys.ip_proto) { 338 case IPPROTO_TCP: 339 fsp->flow_type = TCP_V4_FLOW; 340 break; 341 case IPPROTO_UDP: 342 fsp->flow_type = UDP_V4_FLOW; 343 break; 344 default: 345 return -EINVAL; 346 break; 347 } 348 349 fsp->h_u.tcp_ip4_spec.ip4src = n->keys.src; 350 fsp->m_u.tcp_ip4_spec.ip4src = (__u32)~0; 351 352 fsp->h_u.tcp_ip4_spec.ip4dst = n->keys.dst; 353 fsp->m_u.tcp_ip4_spec.ip4dst = (__u32)~0; 354 355 fsp->h_u.tcp_ip4_spec.psrc = n->keys.port16[0]; 356 fsp->m_u.tcp_ip4_spec.psrc = (__u16)~0; 357 358 fsp->h_u.tcp_ip4_spec.pdst = n->keys.port16[1]; 359 fsp->m_u.tcp_ip4_spec.pdst = (__u16)~0; 360 361 fsp->ring_cookie = n->rq_id; 362 363 return 0; 364 } 365 366 static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, 367 u32 *rule_locs) 368 { 369 struct enic *enic = netdev_priv(dev); 370 int ret = 0; 371 372 switch (cmd->cmd) { 373 case ETHTOOL_GRXRINGS: 374 cmd->data = enic->rq_count; 375 break; 376 case ETHTOOL_GRXCLSRLCNT: 377 spin_lock_bh(&enic->rfs_h.lock); 378 cmd->rule_cnt = enic->rfs_h.max - enic->rfs_h.free; 379 cmd->data = enic->rfs_h.max; 380 spin_unlock_bh(&enic->rfs_h.lock); 381 break; 382 case ETHTOOL_GRXCLSRLALL: 383 spin_lock_bh(&enic->rfs_h.lock); 384 ret = enic_grxclsrlall(enic, cmd, rule_locs); 385 spin_unlock_bh(&enic->rfs_h.lock); 386 break; 387 case ETHTOOL_GRXCLSRULE: 388 spin_lock_bh(&enic->rfs_h.lock); 389 ret = enic_grxclsrule(enic, cmd); 390 spin_unlock_bh(&enic->rfs_h.lock); 391 break; 392 default: 393 ret = -EOPNOTSUPP; 394 break; 395 } 396 397 return ret; 398 } 399 400 static int enic_get_tunable(struct net_device *dev, 401 const struct ethtool_tunable *tuna, void *data) 402 { 403 struct enic *enic = netdev_priv(dev); 404 int ret = 0; 405 406 switch (tuna->id) { 407 case ETHTOOL_RX_COPYBREAK: 408 *(u32 *)data = enic->rx_copybreak; 409 break; 410 default: 411 ret = -EINVAL; 412 break; 413 } 414 415 return ret; 416 } 417 418 static int enic_set_tunable(struct net_device *dev, 419 const struct ethtool_tunable *tuna, 420 const void *data) 421 { 422 struct enic *enic = netdev_priv(dev); 423 int ret = 0; 424 425 switch (tuna->id) { 426 case ETHTOOL_RX_COPYBREAK: 427 enic->rx_copybreak = *(u32 *)data; 428 break; 429 default: 430 ret = -EINVAL; 431 break; 432 } 433 434 return ret; 435 } 436 437 static u32 enic_get_rxfh_key_size(struct net_device *netdev) 438 { 439 return ENIC_RSS_LEN; 440 } 441 442 static int enic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey, 443 u8 *hfunc) 444 { 445 struct enic *enic = netdev_priv(netdev); 446 447 if (hkey) 448 memcpy(hkey, enic->rss_key, ENIC_RSS_LEN); 449 450 if (hfunc) 451 *hfunc = ETH_RSS_HASH_TOP; 452 453 return 0; 454 } 455 456 static int enic_set_rxfh(struct net_device *netdev, const u32 *indir, 457 const u8 *hkey, const u8 hfunc) 458 { 459 struct enic *enic = netdev_priv(netdev); 460 461 if ((hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) || 462 indir) 463 return -EINVAL; 464 465 if (hkey) 466 memcpy(enic->rss_key, hkey, ENIC_RSS_LEN); 467 468 return __enic_set_rsskey(enic); 469 } 470 471 static const struct ethtool_ops enic_ethtool_ops = { 472 .get_settings = enic_get_settings, 473 .get_drvinfo = enic_get_drvinfo, 474 .get_msglevel = enic_get_msglevel, 475 .set_msglevel = enic_set_msglevel, 476 .get_link = ethtool_op_get_link, 477 .get_strings = enic_get_strings, 478 .get_sset_count = enic_get_sset_count, 479 .get_ethtool_stats = enic_get_ethtool_stats, 480 .get_coalesce = enic_get_coalesce, 481 .set_coalesce = enic_set_coalesce, 482 .get_rxnfc = enic_get_rxnfc, 483 .get_tunable = enic_get_tunable, 484 .set_tunable = enic_set_tunable, 485 .get_rxfh_key_size = enic_get_rxfh_key_size, 486 .get_rxfh = enic_get_rxfh, 487 .set_rxfh = enic_set_rxfh, 488 }; 489 490 void enic_set_ethtool_ops(struct net_device *netdev) 491 { 492 netdev->ethtool_ops = &enic_ethtool_ops; 493 } 494