/* PXENV_UNDI_SET_STATION_ADDRESS * * Status: working */ PXENV_EXIT_t pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS *undi_set_station_address ) { struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol; DBG ( "PXENV_UNDI_SET_STATION_ADDRESS %s", ll_protocol->ntoa ( undi_set_station_address->StationAddress ) ); /* If adapter is open, the change will have no effect; return * an error */ if ( netdev_is_open ( pxe_netdev ) ) { DBG ( " failed: netdev is open\n" ); undi_set_station_address->Status = PXENV_STATUS_UNDI_INVALID_STATE; return PXENV_EXIT_FAILURE; } /* Update MAC address */ memcpy ( pxe_netdev->ll_addr, &undi_set_station_address->StationAddress, ll_protocol->ll_addr_len ); DBG ( "\n" ); undi_set_station_address->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; }
/** * Attempt to transmit PeerDist discovery requests on all sockets * * @v uuid Message UUID string * @v id Segment identifier string */ static void peerdisc_socket_tx ( const char *uuid, const char *id ) { struct peerdisc_socket *socket; struct net_device *netdev; struct xfer_metadata meta; union { struct sockaddr sa; struct sockaddr_tcpip st; } address; char *request; size_t len; int rc; /* Construct discovery request */ request = peerdist_discovery_request ( uuid, id ); if ( ! request ) goto err_request; len = strlen ( request ); /* Initialise data transfer metadata */ memset ( &meta, 0, sizeof ( meta ) ); meta.dest = &address.sa; /* Send message on each socket */ for_each_table_entry ( socket, PEERDISC_SOCKETS ) { /* Initialise socket address */ memcpy ( &address.sa, &socket->address.sa, sizeof ( address.sa ) ); /* Send message on each open network device */ for_each_netdev ( netdev ) { /* Skip unopened network devices */ if ( ! netdev_is_open ( netdev ) ) continue; address.st.st_scope_id = netdev->index; /* Discard request (for test purposes) if applicable */ if ( inject_fault ( PEERDISC_DISCARD_RATE ) ) continue; /* Transmit request */ if ( ( rc = xfer_deliver_raw_meta ( &socket->xfer, request, len, &meta ) ) != 0 ) { DBGC ( socket, "PEERDISC %s could not transmit " "via %s: %s\n", socket->name, netdev->name, strerror ( rc ) ); /* Contine to try other net devices/sockets */ continue; } } }
/** * Print status of network device * * @v netdev Network device */ void ifstat ( struct net_device *netdev ) { printf ( "%s: %s on %s (%s)\n" " [Link:%s, TX:%d TXE:%d RX:%d RXE:%d]\n", netdev->name, netdev_addr ( netdev ), netdev->dev->name, ( netdev_is_open ( netdev ) ? "open" : "closed" ), ( netdev_link_ok ( netdev ) ? "up" : "down" ), netdev->tx_stats.good, netdev->tx_stats.bad, netdev->rx_stats.good, netdev->rx_stats.bad ); if ( ! netdev_link_ok ( netdev ) ) { printf ( " [Link status: %s]\n", strerror ( netdev->link_rc ) ); } ifstat_errors ( &netdev->tx_stats, "TXE" ); ifstat_errors ( &netdev->rx_stats, "RXE" ); }
/** * Set EFI SNP mode state * * @v snp SNP interface */ static void efi_snp_set_state ( struct efi_snp_device *snpdev ) { struct net_device *netdev = snpdev->netdev; EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode; /* Calculate state */ if ( ! snpdev->started ) { /* Start() method not called; report as Stopped */ mode->State = EfiSimpleNetworkStopped; } else if ( ! netdev_is_open ( netdev ) ) { /* Network device not opened; report as Started */ mode->State = EfiSimpleNetworkStarted; } else if ( efi_snp_claimed ) { /* Network device opened but claimed for use by iPXE; report * as Started to inhibit receive polling. */ mode->State = EfiSimpleNetworkStarted; } else { /* Network device opened and available for use via SNP; report * as Initialized. */ mode->State = EfiSimpleNetworkInitialized; } }
static int startpxe_payload ( struct net_device *netdev ) { if ( netdev_is_open ( netdev ) ) pxe_activate ( netdev ); return 0; }