FreeBSD/sys/dev/vxge/vxge.c
/*
 * vxge_ioctl
 * Callback to control the device
 */
vxge_ioctl
Callback to control the device
vxge_ioctl Callback to control the device
int
vxge_ioctl(ifnet_t ifp, u_long command, caddr_t data)
{
	int mask, err = 0;
	vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc;
	struct ifreq *ifr = (struct ifreq *) data;
	if (!vdev->is_active)
		return (EBUSY);
	switch (command) {
	case SIOCSIFADDR:
	case SIOCGIFADDR:
		ether_ioctl(ifp, command, data);
		break;
	case SIOCSIFMTU:
		err = vxge_change_mtu(vdev, (unsigned long)ifr->ifr_mtu);
		break;
	case SIOCSIFFLAGS:
		VXGE_DRV_LOCK(vdev);
		if (ifp->if_flags & IFF_UP) {
			if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
				if ((ifp->if_flags ^ vdev->if_flags) &
				    (IFF_PROMISC | IFF_ALLMULTI))
					vxge_promisc_set(vdev);
			} else {
				vxge_init_locked(vdev);
			}
		} else {
			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
				vxge_stop_locked(vdev);
		}
		vdev->if_flags = ifp->if_flags;
		VXGE_DRV_UNLOCK(vdev);
		break;
	case SIOCADDMULTI:
	case SIOCDELMULTI:
		break;
	case SIOCSIFMEDIA:
	case SIOCGIFMEDIA:
		err = ifmedia_ioctl(ifp, ifr, &vdev->media, command);
		break;
	case SIOCSIFCAP:
		VXGE_DRV_LOCK(vdev);
		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
		if (mask & IFCAP_TXCSUM) {
			ifp->if_capenable ^= IFCAP_TXCSUM;
			ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
			if ((ifp->if_capenable & IFCAP_TSO) &&
			    !(ifp->if_capenable & IFCAP_TXCSUM)) {
				ifp->if_capenable &= ~IFCAP_TSO;
				ifp->if_hwassist &= ~CSUM_TSO;
				if_printf(ifp, "TSO Disabled\n");
			}
		}
		if (mask & IFCAP_RXCSUM)
			ifp->if_capenable ^= IFCAP_RXCSUM;
		if (mask & IFCAP_TSO4) {
			ifp->if_capenable ^= IFCAP_TSO4;
			if (ifp->if_capenable & IFCAP_TSO) {
				if (ifp->if_capenable & IFCAP_TXCSUM) {
					ifp->if_hwassist |= CSUM_TSO;
					if_printf(ifp, "TSO Enabled\n");
				} else {
					ifp->if_capenable &= ~IFCAP_TSO;
					ifp->if_hwassist &= ~CSUM_TSO;
					if_printf(ifp,
					    "Enable tx checksum offload \
					     first.\n");
					err = EAGAIN;
				}
			} else {
				ifp->if_hwassist &= ~CSUM_TSO;
				if_printf(ifp, "TSO Disabled\n");
			}
		}
		if (mask & IFCAP_LRO)
			ifp->if_capenable ^= IFCAP_LRO;
		if (mask & IFCAP_VLAN_HWTAGGING)
			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
		if (mask & IFCAP_VLAN_MTU)
			ifp->if_capenable ^= IFCAP_VLAN_MTU;
		if (mask & IFCAP_VLAN_HWCSUM)
			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
#if __FreeBSD_version >= 800000
		if (mask & IFCAP_VLAN_HWTSO)
			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
#endif
#if defined(VLAN_CAPABILITIES)
		VLAN_CAPABILITIES(ifp);
#endif
		VXGE_DRV_UNLOCK(vdev);
		break;
	case SIOCGPRIVATE_0:
		VXGE_DRV_LOCK(vdev);
		err = vxge_ioctl_stats(vdev, ifr);
		VXGE_DRV_UNLOCK(vdev);
		break;
	case SIOCGPRIVATE_1:
		VXGE_DRV_LOCK(vdev);
		err = vxge_ioctl_regs(vdev, ifr);
		VXGE_DRV_UNLOCK(vdev);
		break;
	default:
		err = ether_ioctl(ifp, command, data);
		break;
	}
	return (err);
}
int vxge_ioctl ( ifnet_t ifp , u_long command , caddr_t data ) { int mask , err = 0 ; vxge_dev_t * vdev = ( vxge_dev_t * ) ifp -> if_softc ; struct ifreq * ifr = ( struct ifreq * ) data ; if ( ! vdev -> is_active ) return ( EBUSY ) ; switch ( command ) { case SIOCSIFADDR : case SIOCGIFADDR : ether_ioctl ( ifp , command , data ) ; break ; case SIOCSIFMTU : err = vxge_change_mtu ( vdev , ( unsigned long ) ifr -> ifr_mtu ) ; break ; case SIOCSIFFLAGS : VXGE_DRV_LOCK ( vdev ) ; if ( ifp -> if_flags & IFF_UP ) { if ( ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) ) { if ( ( ifp -> if_flags ^ vdev -> if_flags ) & ( IFF_PROMISC | IFF_ALLMULTI ) ) vxge_promisc_set ( vdev ) ; } else { vxge_init_locked ( vdev ) ; } } else { if ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) vxge_stop_locked ( vdev ) ; } vdev -> if_flags = ifp -> if_flags ; VXGE_DRV_UNLOCK ( vdev ) ; break ; case SIOCADDMULTI : case SIOCDELMULTI : break ; case SIOCSIFMEDIA : case SIOCGIFMEDIA : err = ifmedia_ioctl ( ifp , ifr , & vdev -> media , command ) ; break ; case SIOCSIFCAP : VXGE_DRV_LOCK ( vdev ) ; mask = ifr -> ifr_reqcap ^ ifp -> if_capenable ; if ( mask & IFCAP_TXCSUM ) { ifp -> if_capenable ^= IFCAP_TXCSUM ; ifp -> if_hwassist ^= ( CSUM_TCP | CSUM_UDP | CSUM_IP ) ; if ( ( ifp -> if_capenable & IFCAP_TSO ) && ! ( ifp -> if_capenable & IFCAP_TXCSUM ) ) { ifp -> if_capenable &= ~ IFCAP_TSO ; ifp -> if_hwassist &= ~ CSUM_TSO ; if_printf ( ifp , " \n " ) ; } } if ( mask & IFCAP_RXCSUM ) ifp -> if_capenable ^= IFCAP_RXCSUM ; if ( mask & IFCAP_TSO4 ) { ifp -> if_capenable ^= IFCAP_TSO4 ; if ( ifp -> if_capenable & IFCAP_TSO ) { if ( ifp -> if_capenable & IFCAP_TXCSUM ) { ifp -> if_hwassist |= CSUM_TSO ; if_printf ( ifp , " \n " ) ; } else { ifp -> if_capenable &= ~ IFCAP_TSO ; ifp -> if_hwassist &= ~ CSUM_TSO ; if_printf ( ifp , " \
 \n " ) ; err = EAGAIN ; } } else { ifp -> if_hwassist &= ~ CSUM_TSO ; if_printf ( ifp , " \n " ) ; } } if ( mask & IFCAP_LRO ) ifp -> if_capenable ^= IFCAP_LRO ; if ( mask & IFCAP_VLAN_HWTAGGING ) ifp -> if_capenable ^= IFCAP_VLAN_HWTAGGING ; if ( mask & IFCAP_VLAN_MTU ) ifp -> if_capenable ^= IFCAP_VLAN_MTU ; if ( mask & IFCAP_VLAN_HWCSUM ) ifp -> if_capenable ^= IFCAP_VLAN_HWCSUM ; #if __FreeBSD_version >= 800000 if ( mask & IFCAP_VLAN_HWTSO ) ifp -> if_capenable ^= IFCAP_VLAN_HWTSO ; #endif #if defined ( VLAN_CAPABILITIES ) VLAN_CAPABILITIES ( ifp ) ; #endif VXGE_DRV_UNLOCK ( vdev ) ; break ; case SIOCGPRIVATE_0 : VXGE_DRV_LOCK ( vdev ) ; err = vxge_ioctl_stats ( vdev , ifr ) ; VXGE_DRV_UNLOCK ( vdev ) ; break ; case SIOCGPRIVATE_1 : VXGE_DRV_LOCK ( vdev ) ; err = vxge_ioctl_regs ( vdev , ifr ) ; VXGE_DRV_UNLOCK ( vdev ) ; break ; default : err = ether_ioctl ( ifp , command , data ) ; break ; } return ( err ) ; }
vxge_ioctl
 Callback to control the device
vxge_ioctl Callback to control the device
/* Set/Get ifnet address */ /* Set Interface MTU */ /* Set Interface Flags */ /* Add/delete multicast address */ /* Get/Set Interface Media */ /* Set Capabilities */