/** * 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 ); } }
/** * 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 ); } }
/** * 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 }
/** * 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 ); } }
/** * 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 ); } }
/** * 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 ); } }
/** * 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 ); } }
/** * 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 ); }
/** * 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; }