- case ETHTOOL_GREGS: {
- struct ethtool_regs edata;
- u8 *ptr;
- int len = cp->casreg_len < CAS_MAX_REGS ?
- cp->casreg_len: CAS_MAX_REGS;
-
- if (copy_from_user(&edata, ep_user, sizeof (edata)))
- return -EFAULT;
-
- if (edata.len > len)
- edata.len = len;
- edata.version = 0;
- if (copy_to_user (ep_user, &edata, sizeof(edata)))
- return -EFAULT;
-
- /* cas_get_regs handles locks (cp->lock). */
- ptr = cas_get_regs(cp);
- if (ptr == NULL)
- return -ENOMEM;
- if (copy_to_user(ep_user + sizeof (edata), ptr, edata.len))
- return -EFAULT;
-
- kfree(ptr);
- return (0);
- }
- case ETHTOOL_GSTRINGS: {
- struct ethtool_gstrings edata;
- int len;
-
- if (copy_from_user(&edata, ep_user, sizeof(edata)))
- return -EFAULT;
-
- len = edata.len;
- switch(edata.string_set) {
- case ETH_SS_STATS:
- edata.len = (len < CAS_NUM_STAT_KEYS) ?
- len : CAS_NUM_STAT_KEYS;
- if (copy_to_user(ep_user, &edata, sizeof(edata)))
- return -EFAULT;
-
- if (copy_to_user(ep_user + sizeof(edata),
- ðtool_cassini_statnames,
- (edata.len * ETH_GSTRING_LEN)))
- return -EFAULT;
- return 0;
- default:
- return -EINVAL;
- }
- }
- case ETHTOOL_GSTATS: {
- int i = 0;
- u64 *tmp;
- struct ethtool_stats edata;
- struct net_device_stats *stats;
- int len;
-
- if (copy_from_user(&edata, ep_user, sizeof(edata)))
- return -EFAULT;
-
- len = edata.n_stats;
- stats = cas_get_stats(cp->dev);
- edata.cmd = ETHTOOL_GSTATS;
- edata.n_stats = (len < CAS_NUM_STAT_KEYS) ?
- len : CAS_NUM_STAT_KEYS;
- if (copy_to_user(ep_user, &edata, sizeof (edata)))
- return -EFAULT;
-
- tmp = kmalloc(sizeof(u64)*CAS_NUM_STAT_KEYS, GFP_KERNEL);
- if (tmp) {
- tmp[i++] = stats->collisions;
- tmp[i++] = stats->rx_bytes;
- tmp[i++] = stats->rx_crc_errors;
- tmp[i++] = stats->rx_dropped;
- tmp[i++] = stats->rx_errors;
- tmp[i++] = stats->rx_fifo_errors;
- tmp[i++] = stats->rx_frame_errors;
- tmp[i++] = stats->rx_length_errors;
- tmp[i++] = stats->rx_over_errors;
- tmp[i++] = stats->rx_packets;
- tmp[i++] = stats->tx_aborted_errors;
- tmp[i++] = stats->tx_bytes;
- tmp[i++] = stats->tx_dropped;
- tmp[i++] = stats->tx_errors;
- tmp[i++] = stats->tx_fifo_errors;
- tmp[i++] = stats->tx_packets;
- BUG_ON(i != CAS_NUM_STAT_KEYS);
-
- i = copy_to_user(ep_user + sizeof(edata),
- tmp, sizeof(u64)*edata.n_stats);
- kfree(tmp);
- } else {
- return -ENOMEM;
- }
- if (i)
- return -EFAULT;
- return 0;
- }
- }