struct ethtool_value edata = { cmd: ETHTOOL_GMSGLVL }; 
struct ethtool_value edata = { .cmd = ETHTOOL_GMSGLVL }; 
static int cas_ethtool_ioctl(struct net_device *dev, void *ep_user){	struct cas *cp = netdev_priv(dev);	u16 bmcr;	int full_duplex, speed, pause;	struct ethtool_cmd ecmd;	unsigned long flags;	enum link_state linkstate = link_up;	if (copy_from_user(&ecmd, ep_user, sizeof(ecmd)))		return -EFAULT;			switch(ecmd.cmd) {        case ETHTOOL_GDRVINFO: {		struct ethtool_drvinfo info = { cmd: ETHTOOL_GDRVINFO };		strncpy(info.driver, DRV_MODULE_NAME,			ETHTOOL_BUSINFO_LEN);		strncpy(info.version, DRV_MODULE_VERSION,			ETHTOOL_BUSINFO_LEN);		info.fw_version[0] = '\0';		strncpy(info.bus_info, pci_name(cp->pdev),			ETHTOOL_BUSINFO_LEN);		info.regdump_len = cp->casreg_len < CAS_MAX_REGS ?			cp->casreg_len : CAS_MAX_REGS;		info.n_stats = CAS_NUM_STAT_KEYS;		if (copy_to_user(ep_user, &info, sizeof(info)))			return -EFAULT;		return 0;	}	case ETHTOOL_GSET:		ecmd.advertising = 0;		ecmd.supported = SUPPORTED_Autoneg;		if (cp->cas_flags & CAS_FLAG_1000MB_CAP) {			ecmd.supported |= SUPPORTED_1000baseT_Full;			ecmd.advertising |= ADVERTISED_1000baseT_Full;		}		/* Record PHY settings if HW is on. */		spin_lock_irqsave(&cp->lock, flags);		bmcr = 0;		linkstate = cp->lstate;		if (CAS_PHY_MII(cp->phy_type)) {			ecmd.port = PORT_MII;			ecmd.transceiver = (cp->cas_flags & CAS_FLAG_SATURN) ?				XCVR_INTERNAL : XCVR_EXTERNAL;			ecmd.phy_address = cp->phy_addr;			ecmd.advertising |= ADVERTISED_TP | ADVERTISED_MII |				ADVERTISED_10baseT_Half | 				ADVERTISED_10baseT_Full | 				ADVERTISED_100baseT_Half | 				ADVERTISED_100baseT_Full;			ecmd.supported |=				(SUPPORTED_10baseT_Half | 				 SUPPORTED_10baseT_Full |				 SUPPORTED_100baseT_Half | 				 SUPPORTED_100baseT_Full |				 SUPPORTED_TP | SUPPORTED_MII);			if (cp->hw_running) {				cas_mif_poll(cp, 0);				bmcr = cas_phy_read(cp, MII_BMCR);				cas_read_mii_link_mode(cp, &full_duplex, 						       &speed, &pause);				cas_mif_poll(cp, 1);			}		} else {			ecmd.port = PORT_FIBRE;			ecmd.transceiver = XCVR_INTERNAL;			ecmd.phy_address = 0;			ecmd.supported   |= SUPPORTED_FIBRE;			ecmd.advertising |= ADVERTISED_FIBRE;			if (cp->hw_running) {				/* pcs uses the same bits as mii */ 				bmcr = readl(cp->regs + REG_PCS_MII_CTRL);				cas_read_pcs_link_mode(cp, &full_duplex, 						       &speed, &pause);			}		}		spin_unlock_irqrestore(&cp->lock, flags);		if (bmcr & BMCR_ANENABLE) {			ecmd.advertising |= ADVERTISED_Autoneg;			ecmd.autoneg = AUTONEG_ENABLE;			ecmd.speed = ((speed == 10) ?				      SPEED_10 :				      ((speed == 1000) ?				       SPEED_1000 : SPEED_100));			ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;		} else {			ecmd.autoneg = AUTONEG_DISABLE;			ecmd.speed =				(bmcr & CAS_BMCR_SPEED1000) ?				SPEED_1000 : 				((bmcr & BMCR_SPEED100) ? SPEED_100: 				 SPEED_10);			ecmd.duplex =				(bmcr & BMCR_FULLDPLX) ?				DUPLEX_FULL : DUPLEX_HALF;		}		if (linkstate != link_up) {			/* Force these to "unknown" if the link is not up and			 * autonogotiation in enabled. We can set the link 			 * speed to 0, but not ecmd.duplex,			 * because its legal values are 0 and 1.  Ethtool will			 * print the value reported in parentheses after the			 * word "Unknown" for unrecognized values.			 *			 * If in forced mode, we report the speed and duplex			 * settings that we configured.			 */			if (cp->link_cntl & BMCR_ANENABLE) {				ecmd.speed = 0;				ecmd.duplex = 0xff;			} else {				ecmd.speed = SPEED_10;				if (cp->link_cntl & BMCR_SPEED100) {					ecmd.speed = SPEED_100;				} else if (cp->link_cntl & CAS_BMCR_SPEED1000) {					ecmd.speed = SPEED_1000;				}				ecmd.duplex = (cp->link_cntl & BMCR_FULLDPLX)?					DUPLEX_FULL : DUPLEX_HALF;			}		}		if (copy_to_user(ep_user, &ecmd, sizeof(ecmd)))			return -EFAULT;		return 0;	case ETHTOOL_SSET:		if (!capable(CAP_NET_ADMIN))			return -EPERM;		/* Verify the settings we care about. */		if (ecmd.autoneg != AUTONEG_ENABLE &&		    ecmd.autoneg != AUTONEG_DISABLE)			return -EINVAL;		if (ecmd.autoneg == AUTONEG_DISABLE &&		    ((ecmd.speed != SPEED_1000 &&		      ecmd.speed != SPEED_100 &&		      ecmd.speed != SPEED_10) ||		     (ecmd.duplex != DUPLEX_HALF &&		      ecmd.duplex != DUPLEX_FULL)))			return -EINVAL;		/* Apply settings and restart link process. */		spin_lock_irqsave(&cp->lock, flags);		cas_begin_auto_negotiation(cp, &ecmd);		spin_unlock_irqrestore(&cp->lock, flags);		return 0;	case ETHTOOL_NWAY_RST:		if ((cp->link_cntl & BMCR_ANENABLE) == 0)			return -EINVAL;		/* Restart link process. */		spin_lock_irqsave(&cp->lock, flags);		cas_begin_auto_negotiation(cp, NULL);		spin_unlock_irqrestore(&cp->lock, flags);		return 0;	case ETHTOOL_GWOL:	case ETHTOOL_SWOL:		break; /* doesn't exist */	/* get link status */	case ETHTOOL_GLINK: {		struct ethtool_value edata = { cmd: ETHTOOL_GLINK };		edata.data = (cp->lstate == link_up);		if (copy_to_user(ep_user, &edata, sizeof(edata)))			return -EFAULT;		return 0;	}	/* get message-level */	case ETHTOOL_GMSGLVL: {		struct ethtool_value edata = { cmd: ETHTOOL_GMSGLVL };		edata.data = cp->msg_enable;		if (copy_to_user(ep_user, &edata, sizeof(edata)))			return -EFAULT;		return 0;	}	/* set message-level */	case ETHTOOL_SMSGLVL: {		struct ethtool_value edata;		if (!capable(CAP_NET_ADMIN)) {			return (-EPERM);		}		if (copy_from_user(&edata, ep_user, sizeof(edata)))			return -EFAULT;		cp->msg_enable = edata.data;		return 0;	}	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),					 &ethtool_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;	}	}	return -EOPNOTSUPP;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/46d7031ecb8a8360b0022abd8014f38cc1197166/cassini.c/buggy/drivers/net/cassini.c