예제 #1
0
파일: nii.c 프로젝트: baloo/ipxe
/**
 * Check for link state changes
 *
 * @v netdev		Network device
 * @v stat		Status flags
 */
static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
	int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );

	if ( no_media && netdev_link_ok ( netdev ) ) {
		netdev_link_down ( netdev );
	} else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
		netdev_link_up ( netdev );
	}
}
예제 #2
0
파일: dm96xx.c 프로젝트: dell-asm-ci/ipxe
/**
 * Update link status based on network status register
 *
 * @v dm96xx		DM96xx device
 * @v nsr		Network status register
 */
static void dm96xx_link_nsr ( struct dm96xx_device *dm96xx, unsigned int nsr ) {
	struct net_device *netdev = dm96xx->netdev;

	if ( nsr & DM96XX_NSR_LINKST ) {
		if ( ! netdev_link_ok ( netdev ) )
			netdev_link_up ( netdev );
	} else {
		if ( netdev_link_ok ( netdev ) )
			netdev_link_down ( netdev );
	}
}
예제 #3
0
파일: mii.c 프로젝트: 7perl/akaros
/**
 * mii_check_link - check MII link status
 * @mii: MII interface
 *
 * If the link status changed (previous != current), call
 * netif_carrier_on() if current link status is Up or call
 * netif_carrier_off() if current link status is Down.
 */
void mii_check_link(struct mii_if_info *mii)
{
#warning "figure out what to do about etherboot netdev; does ours work?"
#if 0
	int cur_link = mii_link_ok(mii);
	int prev_link = netdev_link_ok(mii->dev);

	if (cur_link && !prev_link)
		netdev_link_up(mii->dev);
	else if (prev_link && !cur_link)
		netdev_link_down(mii->dev);
#endif
}
예제 #4
0
파일: intelxlvf.c 프로젝트: eworm-de/ipxe
/**
 * Handle link status event
 *
 * @v netdev		Network device
 * @v link		Link status
 */
static void intelxlvf_admin_link ( struct net_device *netdev,
				   struct intelxl_admin_vf_status_link *link ) {
	struct intelxl_nic *intelxl = netdev->priv;

	DBGC ( intelxl, "INTELXL %p link %#02x speed %#02x\n", intelxl,
	       link->status, link->speed );

	/* Update network device */
	if ( link->status ) {
		netdev_link_up ( netdev );
	} else {
		netdev_link_down ( netdev );
	}
}
예제 #5
0
파일: snpnet.c 프로젝트: eatnumber1/ipxe
/**
 * Check link state
 *
 * @v netdev		Network device
 */
static void snpnet_check_link ( struct net_device *netdev ) {
    struct snp_nic *snp = netdev_priv ( netdev );
    EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;

    /* Do nothing unless media presence detection is supported */
    if ( ! mode->MediaPresentSupported )
        return;

    /* Report any link status change */
    if ( mode->MediaPresent && ( ! netdev_link_ok ( netdev ) ) ) {
        netdev_link_up ( netdev );
    } else if ( ( ! mode->MediaPresent ) && netdev_link_ok ( netdev ) ) {
        netdev_link_down ( netdev );
    }
}
예제 #6
0
/**
 * Check link state
 *
 * @v netdev		Network device
 */
static void intelxvf_check_link ( struct net_device *netdev ) {
	struct intel_nic *intel = netdev->priv;
	uint32_t links;

	/* Read link status */
	links = readl ( intel->regs + INTELXVF_LINKS );
	DBGC ( intel, "INTEL %p link status is %08x\n", intel, links );

	/* Update network device */
	if ( links & INTELXVF_LINKS_UP ) {
		netdev_link_up ( netdev );
	} else {
		netdev_link_down ( netdev );
	}
}
예제 #7
0
파일: rhine.c 프로젝트: 42wim/ipxe
/**
 * Check link state
 *
 * @v netdev		Network device
 */
static void rhine_check_link ( struct net_device *netdev ) {
	struct rhine_nic *rhn = netdev->priv;
	uint8_t mii_sr;

	/* Read MII status register */
	mii_sr = readb ( rhn->regs + RHINE_MII_SR );
	DBGC ( rhn, "RHINE %p link status %02x\n", rhn, mii_sr );

	/* Report link state */
	if ( ! ( mii_sr & RHINE_MII_SR_LINKPOLL ) ) {
		netdev_link_up ( netdev );
	} else if ( mii_sr & RHINE_MII_SR_PHYERR ) {
		netdev_link_err ( netdev, -EIO );
	} else {
		netdev_link_down ( netdev );
	}
}
예제 #8
0
파일: netfront.c 프로젝트: pipcet/ipxe
/**
 * Close network device
 *
 * @v netdev		Network device
 */
static void netfront_close ( struct net_device *netdev ) {
	struct netfront_nic *netfront = netdev->priv;
	struct xen_device *xendev = netfront->xendev;
	int rc;

	/* Reset devic, thereby ensuring that grant references are no
	 * longer in use, etc.
	 */
	if ( ( rc = netfront_reset ( netfront ) ) != 0 ) {
		DBGC ( netfront, "NETFRONT %s could not disconnect from "
		       "backend: %s\n", xendev->key, strerror ( rc ) );
		/* Things will probably go _very_ badly wrong if this
		 * happens, since it means the backend may still write
		 * to the outstanding RX buffers that we are about to
		 * free.  The best we can do is report the error via
		 * the link status, but there's a good chance the
		 * machine will crash soon.
		 */
		netdev_link_err ( netdev, rc );
	} else {
		netdev_link_down ( netdev );
	}

	/* Delete flags */
	netfront_rm ( netfront, "feature-rx-notify" );
	netfront_rm ( netfront, "feature-no-csum-offload" );
	netfront_rm ( netfront, "request-rx-copy" );

	/* Destroy event channel */
	netfront_destroy_event ( netfront );

	/* Destroy receive descriptor ring, freeing any outstanding
	 * I/O buffers.
	 */
	netfront_destroy_ring ( netfront, &netfront->rx, free_iob );

	/* Destroy transmit descriptor ring.  Leave any outstanding
	 * I/O buffers to be freed by netdev_tx_flush().
	 */
	netfront_destroy_ring ( netfront, &netfront->tx, NULL );
}
예제 #9
0
파일: netfront.c 프로젝트: pipcet/ipxe
/**
 * Probe Xen device
 *
 * @v xendev		Xen device
 * @ret rc		Return status code
 */
static int netfront_probe ( struct xen_device *xendev ) {
	struct xen_hypervisor *xen = xendev->xen;
	struct net_device *netdev;
	struct netfront_nic *netfront;
	int rc;

	/* Allocate and initialise structure */
	netdev = alloc_etherdev ( sizeof ( *netfront ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &netfront_operations );
	netdev->dev = &xendev->dev;
	netfront = netdev->priv;
	netfront->xendev = xendev;
	DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
	       xendev->key, xendev->backend, xendev->backend_id );

	/* Allocate grant references and initialise descriptor rings */
	if ( ( rc = xengrant_alloc ( xen, netfront->refs,
				     NETFRONT_REF_COUNT ) ) != 0 ) {
		DBGC ( netfront, "NETFRONT %s could not allocate grant "
		       "references: %s\n", xendev->key, strerror ( rc ) );
		goto err_grant_alloc;
	}
	netfront_init_ring ( &netfront->tx, "tx-ring-ref",
			     netfront->refs[NETFRONT_REF_TX_RING],
			     NETFRONT_NUM_TX_DESC, netfront->tx_iobufs,
			     &netfront->refs[NETFRONT_REF_TX_BASE],
			     netfront->tx_ids );
	netfront_init_ring ( &netfront->rx, "rx-ring-ref",
			     netfront->refs[NETFRONT_REF_RX_RING],
			     NETFRONT_NUM_RX_DESC, netfront->rx_iobufs,
			     &netfront->refs[NETFRONT_REF_RX_BASE],
			     netfront->rx_ids );

	/* Fetch MAC address */
	if ( ( rc = netfront_read_mac ( netfront, netdev->hw_addr ) ) != 0 )
		goto err_read_mac;

	/* Reset device.  Ignore failures; allow the device to be
	 * registered so that reset errors can be observed by the user
	 * when attempting to open the device.
	 */
	netfront_reset ( netfront );

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Set initial link state */
	netdev_link_down ( netdev );

	xen_set_drvdata ( xendev, netdev );
	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_read_mac:
	xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );
 err_grant_alloc:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}