FreeBSD/sys/dev/ixl/ixl_pf_main.c
/*********************************************************************
 *  Ioctl entry point
 *
 *  ixl_ioctl is called when the user wants to configure the
 *  interface.
 *
 *  return 0 on success, positive on failure
 **********************************************************************/
Ioctl entry point
ixl_ioctl is called when the user wants to configure the
interface.

return 0 on success, positive on failure
Ioctl entry point ixl_ioctl is called when the user wants to configure the interface . return 0 on success positive on failure
int
ixl_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
{
	struct ixl_vsi	*vsi = ifp->if_softc;
	struct ixl_pf	*pf = vsi->back;
	struct ifreq	*ifr = (struct ifreq *)data;
	struct ifdrv	*ifd = (struct ifdrv *)data;
#if defined(INET) || defined(INET6)
	struct ifaddr *ifa = (struct ifaddr *)data;
	bool		avoid_reset = FALSE;
#endif
	int             error = 0;
	switch (command) {
        case SIOCSIFADDR:
#ifdef INET
		if (ifa->ifa_addr->sa_family == AF_INET)
			avoid_reset = TRUE;
#endif
#ifdef INET6
		if (ifa->ifa_addr->sa_family == AF_INET6)
			avoid_reset = TRUE;
#endif
#if defined(INET) || defined(INET6)
		if (avoid_reset) {
			ifp->if_flags |= IFF_UP;
			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
				ixl_init(pf);
#ifdef INET
			if (!(ifp->if_flags & IFF_NOARP))
				arp_ifinit(ifp, ifa);
#endif
		} else
			error = ether_ioctl(ifp, command, data);
		break;
#endif
	case SIOCSIFMTU:
		IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
		if (ifr->ifr_mtu > IXL_MAX_FRAME -
		   ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN) {
			error = EINVAL;
		} else {
			IXL_PF_LOCK(pf);
			ifp->if_mtu = ifr->ifr_mtu;
			vsi->max_frame_size =
				ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN
			    + ETHER_VLAN_ENCAP_LEN;
			ixl_init_locked(pf);
			IXL_PF_UNLOCK(pf);
		}
		break;
	case SIOCSIFFLAGS:
		IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
		IXL_PF_LOCK(pf);
		if (ifp->if_flags & IFF_UP) {
			if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
				if ((ifp->if_flags ^ pf->if_flags) &
				    (IFF_PROMISC | IFF_ALLMULTI)) {
					ixl_set_promisc(vsi);
				}
			} else {
				IXL_PF_UNLOCK(pf);
				ixl_init(pf);
				IXL_PF_LOCK(pf);
			}
		} else {
			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
				IXL_PF_UNLOCK(pf);
				ixl_stop(pf);
				IXL_PF_LOCK(pf);
			}
		}
		pf->if_flags = ifp->if_flags;
		IXL_PF_UNLOCK(pf);
		break;
	case SIOCSDRVSPEC:
	case SIOCGDRVSPEC:
		IOCTL_DEBUGOUT("ioctl: SIOCxDRVSPEC (Get/Set Driver-specific "
		    "Info)\n");
		if (ifd->ifd_cmd == I40E_NVM_ACCESS)
			error = ixl_handle_nvmupd_cmd(pf, ifd);
		else
			error = EINVAL;
		break;
	case SIOCADDMULTI:
		IOCTL_DEBUGOUT("ioctl: SIOCADDMULTI");
		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
			IXL_PF_LOCK(pf);
			ixl_disable_intr(vsi);
			ixl_add_multi(vsi);
			ixl_enable_intr(vsi);
			IXL_PF_UNLOCK(pf);
		}
		break;
	case SIOCDELMULTI:
		IOCTL_DEBUGOUT("ioctl: SIOCDELMULTI");
		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
			IXL_PF_LOCK(pf);
			ixl_disable_intr(vsi);
			ixl_del_multi(vsi);
			ixl_enable_intr(vsi);
			IXL_PF_UNLOCK(pf);
		}
		break;
	case SIOCSIFMEDIA:
	case SIOCGIFMEDIA:
	case SIOCGIFXMEDIA:
		IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
		error = ifmedia_ioctl(ifp, ifr, &vsi->media, command);
		break;
	case SIOCSIFCAP:
	{
		int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
		IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
		ixl_cap_txcsum_tso(vsi, ifp, mask);
		if (mask & IFCAP_RXCSUM)
			ifp->if_capenable ^= IFCAP_RXCSUM;
		if (mask & IFCAP_RXCSUM_IPV6)
			ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
		if (mask & IFCAP_LRO)
			ifp->if_capenable ^= IFCAP_LRO;
		if (mask & IFCAP_VLAN_HWTAGGING)
			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
		if (mask & IFCAP_VLAN_HWFILTER)
			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
		if (mask & IFCAP_VLAN_HWTSO)
			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
			IXL_PF_LOCK(pf);
			ixl_init_locked(pf);
			IXL_PF_UNLOCK(pf);
		}
		VLAN_CAPABILITIES(ifp);
		break;
	}
	default:
		IOCTL_DEBUGOUT("ioctl: UNKNOWN (0x%X)\n", (int)command);
		error = ether_ioctl(ifp, command, data);
		break;
	}
	return (error);
}
int ixl_ioctl ( struct ifnet * ifp , u_long command , caddr_t data ) { struct ixl_vsi * vsi = ifp -> if_softc ; struct ixl_pf * pf = vsi -> back ; struct ifreq * ifr = ( struct ifreq * ) data ; struct ifdrv * ifd = ( struct ifdrv * ) data ; #if defined ( INET ) || defined ( INET6 ) struct ifaddr * ifa = ( struct ifaddr * ) data ; bool avoid_reset = FALSE ; #endif int error = 0 ; switch ( command ) { case SIOCSIFADDR : #ifdef INET if ( ifa -> ifa_addr -> sa_family == AF_INET ) avoid_reset = TRUE ; #endif #ifdef INET6 if ( ifa -> ifa_addr -> sa_family == AF_INET6 ) avoid_reset = TRUE ; #endif #if defined ( INET ) || defined ( INET6 ) if ( avoid_reset ) { ifp -> if_flags |= IFF_UP ; if ( ! ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) ) ixl_init ( pf ) ; #ifdef INET if ( ! ( ifp -> if_flags & IFF_NOARP ) ) arp_ifinit ( ifp , ifa ) ; #endif } else error = ether_ioctl ( ifp , command , data ) ; break ; #endif case SIOCSIFMTU : IOCTL_DEBUGOUT ( " " ) ; if ( ifr -> ifr_mtu > IXL_MAX_FRAME - ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN ) { error = EINVAL ; } else { IXL_PF_LOCK ( pf ) ; ifp -> if_mtu = ifr -> ifr_mtu ; vsi -> max_frame_size = ifp -> if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN ; ixl_init_locked ( pf ) ; IXL_PF_UNLOCK ( pf ) ; } break ; case SIOCSIFFLAGS : IOCTL_DEBUGOUT ( " " ) ; IXL_PF_LOCK ( pf ) ; if ( ifp -> if_flags & IFF_UP ) { if ( ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) ) { if ( ( ifp -> if_flags ^ pf -> if_flags ) & ( IFF_PROMISC | IFF_ALLMULTI ) ) { ixl_set_promisc ( vsi ) ; } } else { IXL_PF_UNLOCK ( pf ) ; ixl_init ( pf ) ; IXL_PF_LOCK ( pf ) ; } } else { if ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) { IXL_PF_UNLOCK ( pf ) ; ixl_stop ( pf ) ; IXL_PF_LOCK ( pf ) ; } } pf -> if_flags = ifp -> if_flags ; IXL_PF_UNLOCK ( pf ) ; break ; case SIOCSDRVSPEC : case SIOCGDRVSPEC : IOCTL_DEBUGOUT ( " " " \n " ) ; if ( ifd -> ifd_cmd == I40E_NVM_ACCESS ) error = ixl_handle_nvmupd_cmd ( pf , ifd ) ; else error = EINVAL ; break ; case SIOCADDMULTI : IOCTL_DEBUGOUT ( " " ) ; if ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) { IXL_PF_LOCK ( pf ) ; ixl_disable_intr ( vsi ) ; ixl_add_multi ( vsi ) ; ixl_enable_intr ( vsi ) ; IXL_PF_UNLOCK ( pf ) ; } break ; case SIOCDELMULTI : IOCTL_DEBUGOUT ( " " ) ; if ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) { IXL_PF_LOCK ( pf ) ; ixl_disable_intr ( vsi ) ; ixl_del_multi ( vsi ) ; ixl_enable_intr ( vsi ) ; IXL_PF_UNLOCK ( pf ) ; } break ; case SIOCSIFMEDIA : case SIOCGIFMEDIA : case SIOCGIFXMEDIA : IOCTL_DEBUGOUT ( " " ) ; error = ifmedia_ioctl ( ifp , ifr , & vsi -> media , command ) ; break ; case SIOCSIFCAP : { int mask = ifr -> ifr_reqcap ^ ifp -> if_capenable ; IOCTL_DEBUGOUT ( " " ) ; ixl_cap_txcsum_tso ( vsi , ifp , mask ) ; if ( mask & IFCAP_RXCSUM ) ifp -> if_capenable ^= IFCAP_RXCSUM ; if ( mask & IFCAP_RXCSUM_IPV6 ) ifp -> if_capenable ^= IFCAP_RXCSUM_IPV6 ; if ( mask & IFCAP_LRO ) ifp -> if_capenable ^= IFCAP_LRO ; if ( mask & IFCAP_VLAN_HWTAGGING ) ifp -> if_capenable ^= IFCAP_VLAN_HWTAGGING ; if ( mask & IFCAP_VLAN_HWFILTER ) ifp -> if_capenable ^= IFCAP_VLAN_HWFILTER ; if ( mask & IFCAP_VLAN_HWTSO ) ifp -> if_capenable ^= IFCAP_VLAN_HWTSO ; if ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) { IXL_PF_LOCK ( pf ) ; ixl_init_locked ( pf ) ; IXL_PF_UNLOCK ( pf ) ; } VLAN_CAPABILITIES ( ifp ) ; break ; } default : IOCTL_DEBUGOUT ( " \n " , ( int ) command ) ; error = ether_ioctl ( ifp , command , data ) ; break ; } return ( error ) ; }
Ioctl entry point
  ixl_ioctl is called when the user wants to configure the
  interface.
Ioctl entry point ixl_ioctl is called when the user wants to configure the interface .
/*
		** Calling init results in link renegotiation,
		** so we avoid doing it when possible.
		*/ /* NVM update command */