⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at_ethtool.c

📁 Linux* Base Driver for the Attansic(R) L1 Gigabit Ethernet Adapter
💻 C
📖 第 1 页 / 共 2 页
字号:
		adapter->rfd_ring = rfd_old;
		adapter->rrd_ring = rrd_old;
		adapter->tpd_ring = tpd_old;
		at_free_ring_resources(adapter);
        adapter->rfd_ring = rfd_new;
		adapter->rrd_ring = rrd_new;
		adapter->tpd_ring = tpd_new;

		if((err = at_up(adapter)))
			return err;
	}
	return 0;

err_setup_ring:
	adapter->rfd_ring = rfd_old;
	adapter->rrd_ring = rrd_old;
	adapter->tpd_ring = tpd_old;
	at_up(adapter);
	return err;
}
#endif /* ETHTOOL_SRINGPARAM */
#ifdef	ETHTOOL_GPAUSEPARAM
static int
at_ethtool_gpause(struct at_adapter *adapter,
                     struct ethtool_pauseparam *epause)
{
	struct at_hw *hw = &adapter->hw;
	
	if (hw->MediaType == MEDIA_TYPE_AUTO_SENSOR ||
	    hw->MediaType == MEDIA_TYPE_1000M_FULL) {
		epause->autoneg = AUTONEG_ENABLE;
	} else {
		epause->autoneg = AUTONEG_DISABLE;
	}
	
	epause->rx_pause = 1;
	epause->tx_pause = 1;

	return 0;
}
#endif /* ETHTOOL_GPAUSEPARAM */
#ifdef	ETHTOOL_SPAUSEPARAM
static int
at_ethtool_spause(struct at_adapter *adapter,
                     struct ethtool_pauseparam *epause)
{
	struct at_hw *hw = &adapter->hw;
	
	if (hw->MediaType == MEDIA_TYPE_AUTO_SENSOR ||
	    hw->MediaType == MEDIA_TYPE_1000M_FULL) {
		epause->autoneg = AUTONEG_ENABLE;
	} else {
		epause->autoneg = AUTONEG_DISABLE;
	}
	
	epause->rx_pause = 1;
	epause->tx_pause = 1;
	return 0;
	
}
#endif /* ETHTOOL_SPAUSEPARAM */


int
at_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
{
	struct at_adapter *adapter = netdev->priv;
	void *addr = ifr->ifr_data;
	uint32_t cmd;

	if(get_user(cmd, (uint32_t *) addr))
		return -EFAULT;

	//michael add 2005-11-17/	
	DEBUGOUT("enter at_ethtool_ioctl\n");
	switch(cmd) {
	case ETHTOOL_GSET: {
		struct ethtool_cmd ecmd = {ETHTOOL_GSET};
		at_ethtool_gset(adapter, &ecmd);
		if(copy_to_user(addr, &ecmd, sizeof(ecmd)))
			return -EFAULT;
		return 0;
	}
	case ETHTOOL_SSET: {
		struct ethtool_cmd ecmd;
		if(copy_from_user(&ecmd, addr, sizeof(ecmd)))
			return -EFAULT;
		return at_ethtool_sset(adapter, &ecmd);
	}
#ifdef	ETHTOOL_GDRVINFO
	case ETHTOOL_GDRVINFO: {
		struct ethtool_drvinfo drvinfo = {ETHTOOL_GDRVINFO};
		at_ethtool_gdrvinfo(adapter, &drvinfo);
		if(copy_to_user(addr, &drvinfo, sizeof(drvinfo)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GDRVINFO */
#ifdef	ETHTOOL_GSTRINGS
	case ETHTOOL_GSTRINGS: {
		struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
		char *strings = NULL;
		int err = 0;

		if(copy_from_user(&gstrings, addr, sizeof(gstrings)))
			return -EFAULT;
		switch(gstrings.string_set) 
		{
#ifdef	ETHTOOL_GSTATS
		case ETH_SS_STATS: 
		{
            int i;
            gstrings.len = AT_STATS_LEN;
            strings = kmalloc(AT_STATS_LEN * ETH_GSTRING_LEN,
            		  GFP_KERNEL);
            if(!strings)
            	return -ENOMEM;
            for(i=0; i < AT_STATS_LEN; i++) {
            	memcpy(&strings[i * ETH_GSTRING_LEN],
            	       at_gstrings_stats[i].stat_string,
            	       ETH_GSTRING_LEN);
            }
		break;
        }
#endif	/* ETHTOOL_GSTATS */
		default:
			return -EOPNOTSUPP;
		}
		if(copy_to_user(addr, &gstrings, sizeof(gstrings)))
			err = -EFAULT;
		addr += offsetof(struct ethtool_gstrings, data);
		if(!err && copy_to_user(addr, strings, gstrings.len * ETH_GSTRING_LEN))
			err = -EFAULT;

		kfree(strings);
		return err;
	}
#endif	/* ETHTOOL_GSTRINGS */
#ifdef	ETHTOOL_NWAY_RST
	case ETHTOOL_NWAY_RST: {
		struct at_hw* hw = &adapter->hw;
		if(netif_running(netdev)) {
			uint16_t phy_data;
			at_down(adapter);
			
			if (hw->MediaType == MEDIA_TYPE_AUTO_SENSOR ||
    			hw->MediaType == MEDIA_TYPE_1000M_FULL) {
    			phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
    		} else {
	        	switch (hw->MediaType)
	    		{
	    		case MEDIA_TYPE_100M_FULL:
	    			phy_data = MII_CR_FULL_DUPLEX|MII_CR_SPEED_100|MII_CR_RESET;
	    			break;
	    		case MEDIA_TYPE_100M_HALF:
	    			phy_data = MII_CR_SPEED_100|MII_CR_RESET;
	    			break;
	    		case MEDIA_TYPE_10M_FULL:
	    			phy_data = MII_CR_FULL_DUPLEX|MII_CR_SPEED_10|MII_CR_RESET;
	    			break;
	    		default: // MEDIA_TYPE_10M_HALF:
	    			phy_data = MII_CR_SPEED_10|MII_CR_RESET;
	    			break;
	    		}
    		}
    		at_write_phy_reg(hw, MII_BMCR, phy_data);
			at_up(adapter);
		}
		return 0;
	}
#endif	/* ETHTOOL_NWAY_RST */
#ifdef	ETHTOOL_GLINK
	case ETHTOOL_GLINK: {
		struct ethtool_value link = {ETHTOOL_GLINK};
		link.data = netif_carrier_ok(netdev);
		if(copy_to_user(addr, &link, sizeof(link)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GLINK */
#ifdef	ETHTOOL_GWOL
	case ETHTOOL_GWOL: {
		struct ethtool_wolinfo wol = {ETHTOOL_GWOL};
		at_ethtool_gwol(adapter, &wol);
		if(copy_to_user(addr, &wol, sizeof(wol)) != 0)
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GWOL */
#ifdef	ETHTOOL_SWOL
	case ETHTOOL_SWOL: {
		struct ethtool_wolinfo wol;
		if(copy_from_user(&wol, addr, sizeof(wol)) != 0)
			return -EFAULT;
		return at_ethtool_swol(adapter, &wol);
	}
#endif	/* ETHTOOL_SWOL */

#ifdef	ETHTOOL_GRINGPARAM
	case ETHTOOL_GRINGPARAM: {
		struct ethtool_ringparam ering = {ETHTOOL_GRINGPARAM};
		at_ethtool_gring(adapter, &ering);
		if(copy_to_user(addr, &ering, sizeof(ering)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GRINGPARAM */
#ifdef	ETHTOOL_SRINGPARAM
	case ETHTOOL_SRINGPARAM: {
		struct ethtool_ringparam ering;
		if(copy_from_user(&ering, addr, sizeof(ering)))
			return -EFAULT;
		return at_ethtool_sring(adapter, &ering);
	}
#endif	/* ETHTOOL_SRINGPARAM */
#ifdef	ETHTOOL_GPAUSEPARAM
	case ETHTOOL_GPAUSEPARAM: {
		struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM};
		at_ethtool_gpause(adapter, &epause);
		if(copy_to_user(addr, &epause, sizeof(epause)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GPAUSEPARAM */
#ifdef	ETHTOOL_SPAUSEPARAM
	case ETHTOOL_SPAUSEPARAM: {
		struct ethtool_pauseparam epause;
		if(copy_from_user(&epause, addr, sizeof(epause)))
			return -EFAULT;
		return at_ethtool_spause(adapter, &epause);
	}
#endif	/* ETHTOOL_SPAUSEPARAM */
#ifdef	ETHTOOL_GSTATS
	case ETHTOOL_GSTATS: {
		struct {
			struct ethtool_stats eth_stats;
			uint64_t data[AT_STATS_LEN];
		} stats = { {ETHTOOL_GSTATS, AT_STATS_LEN} };
		int i;

		for(i = 0; i < AT_STATS_LEN; i++)
			stats.data[i] = (at_gstrings_stats[i].sizeof_stat ==
					sizeof(uint64_t)) ?
				*(uint64_t *)((char *)adapter +
					at_gstrings_stats[i].stat_offset) :
				*(uint32_t *)((char *)adapter +
					at_gstrings_stats[i].stat_offset);
		if(copy_to_user(addr, &stats, sizeof(stats)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GSTATS */
#ifdef	ETHTOOL_GRXCSUM
	case ETHTOOL_GRXCSUM: {
		struct ethtool_value edata = { ETHTOOL_GRXCSUM };

		edata.data = 1;
		if (copy_to_user(addr, &edata, sizeof(edata)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GRXCSUM */
#ifdef	ETHTOOL_GTXCSUM
	case ETHTOOL_GTXCSUM: {
		struct ethtool_value edata = { ETHTOOL_GTXCSUM };

		edata.data =
			(netdev->features & NETIF_F_HW_CSUM) != 0;
		if (copy_to_user(addr, &edata, sizeof(edata)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GTXCSUM */
#ifdef	ETHTOOL_STXCSUM
	case ETHTOOL_STXCSUM: {
		struct ethtool_value edata;

		if (copy_from_user(&edata, addr, sizeof(edata)))
			return -EFAULT;

		if (edata.data)
			netdev->features |= NETIF_F_HW_CSUM;
		else
			netdev->features &= ~NETIF_F_HW_CSUM;

		return 0;
	}
#endif	/* ETHTOOL_STXCSUM */
#ifdef	ETHTOOL_GSG
	case ETHTOOL_GSG: {
		struct ethtool_value edata = { ETHTOOL_GSG };

		edata.data =
			(netdev->features & NETIF_F_SG) != 0;
		if (copy_to_user(addr, &edata, sizeof(edata)))
			return -EFAULT;
		return 0;
	}
#endif	/* ETHTOOL_GSG */
#ifdef	ETHTOOL_SSG
	case ETHTOOL_SSG: {
		struct ethtool_value edata;

		if (copy_from_user(&edata, addr, sizeof(edata)))
			return -EFAULT;

		if (edata.data)
			netdev->features |= NETIF_F_SG;
		else
			netdev->features &= ~NETIF_F_SG;

		return 0;
	}
#endif	/* ETHTOOL_SSG */
#ifdef NETIF_F_TSO
#ifdef ETHTOOL_GTSO
	case ETHTOOL_GTSO: {
		struct ethtool_value edata = { ETHTOOL_GTSO };

		edata.data = (netdev->features & NETIF_F_TSO) != 0;
		if (copy_to_user(addr, &edata, sizeof(edata)))
			return -EFAULT;
		return 0;
	}
#endif /* ETHTOOL_GTSO */
#ifdef ETHTOOL_STSO
	case ETHTOOL_STSO: {
		struct ethtool_value edata;

		if (copy_from_user(&edata, addr, sizeof(edata)))
			return -EFAULT;

		if (edata.data)
			netdev->features |= NETIF_F_TSO;
		else
			netdev->features &= ~NETIF_F_TSO;

		return 0;
	}
#endif /* ETHTOOL_STSO */
#endif
	default:
		return -EOPNOTSUPP;
	}
}

#endif//SIOCETHTOOL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -