/** * Get station addresses * * @v nii NII NIC * @v netdev Network device to fill in * @ret rc Return status code */ static int nii_get_station_address ( struct nii_nic *nii, struct net_device *netdev ) { PXE_DB_STATION_ADDRESS db; int stat; int rc; /* Initialise UNDI */ if ( ( rc = nii_initialise ( nii ) ) != 0 ) goto err_initialise; /* Issue command */ if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_STATION_ADDRESS, &db, sizeof ( db ) ) ) < 0 ) { rc = -EIO_STAT ( stat ); DBGC ( nii, "NII %s could not get station address: %s\n", nii->dev.name, strerror ( rc ) ); goto err_station_address; } /* Copy MAC addresses */ memcpy ( netdev->ll_addr, db.StationAddr, netdev->ll_protocol->ll_addr_len ); memcpy ( netdev->hw_addr, db.PermanentAddr, netdev->ll_protocol->hw_addr_len ); memcpy ( nii->broadcast, db.BroadcastAddr, sizeof ( nii->broadcast ) ); err_station_address: nii_shutdown ( nii ); err_initialise: return rc; }
/** * Open network device * * @v netdev Network device * @ret rc Return status code */ static int nii_open ( struct net_device *netdev ) { struct nii_nic *nii = netdev->priv; int rc; /* Initialise NIC */ if ( ( rc = nii_initialise ( nii ) ) != 0 ) goto err_initialise; /* Attempt to set station address */ if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) { DBGC ( nii, "NII %s could not set station address: %s\n", nii->dev.name, strerror ( rc ) ); /* Treat as non-fatal */ } /* Set receive filters */ if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 ) goto err_set_rx_filters; return 0; err_set_rx_filters: nii_shutdown ( nii ); err_initialise: return rc; }
/** * Close network device * * @v netdev Network device */ static void nii_close ( struct net_device *netdev ) { struct nii_nic *nii = netdev->priv; /* Shut down NIC */ nii_shutdown ( nii ); /* Discard transmit buffer, if applicable */ if ( nii->txbuf ) { netdev_tx_complete_err ( netdev, nii->txbuf, -ECANCELED ); nii->txbuf = NULL; } /* Discard receive buffer, if applicable */ if ( nii->rxbuf ) { free_iob ( nii->rxbuf ); nii->rxbuf = NULL; } }
/** * Open network device * * @v netdev Network device * @ret rc Return status code */ static int nii_open ( struct net_device *netdev ) { struct nii_nic *nii = netdev->priv; int rc; /* Initialise NIC * * Some Emulex NII drivers have a bug which prevents packets * from being sent or received unless we specifically ask it * to detect cable presence during initialisation. Work * around these buggy drivers by requesting cable detection at * this point, even though we don't care about link state here * (and would prefer to have the NIC initialise even if no * cable is present, to match the behaviour of all other iPXE * drivers). */ if ( ( rc = nii_initialise_and_detect ( nii ) ) != 0 ) goto err_initialise; /* Attempt to set station address */ if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) { DBGC ( nii, "NII %s could not set station address: %s\n", nii->dev.name, strerror ( rc ) ); /* Treat as non-fatal */ } /* Set receive filters */ if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 ) goto err_set_rx_filters; return 0; err_set_rx_filters: nii_shutdown ( nii ); err_initialise: return rc; }