use super::{IxgbeNic, get_ixgbe_nic, IxgbeRxQueueRegisters, IxgbeTxQueueRegisters};
use physical_nic::PhysicalNic;
use virtual_nic::VirtualNic;
use intel_ethernet::descriptors::{AdvancedRxDescriptor, AdvancedTxDescriptor};
use nic_queues::{RxQueue, TxQueue};
use alloc::vec::Vec;
use net::NetworkDevice;
use pci::PciLocation;
pub fn create_virtual_nic(
nic_id: PciLocation,
ip_addresses: Vec<[u8; 4]>,
default_rx_queue: usize,
default_tx_queue: usize
) -> Result<
VirtualNic<IxgbeRxQueueRegisters, AdvancedRxDescriptor, IxgbeTxQueueRegisters, AdvancedTxDescriptor>,
&'static str> {
let num_queues = ip_addresses.len();
if num_queues == 0 { return Err("need to request >0 number of queues"); }
if (default_rx_queue >= num_queues) || (default_tx_queue >= num_queues) {
return Err("default queue value is out of bounds");
}
let (rx_queues, tx_queues, mac_address) = {
let mut nic = get_ixgbe_nic(nic_id)?.lock();
let mut rx_queues = nic.take_rx_queues_from_physical_nic(num_queues)?;
let tx_queues = nic.take_tx_queues_from_physical_nic(num_queues)?;
for (queue, ip_address) in rx_queues.iter_mut().zip(ip_addresses.iter()) {
let filter_num = nic.set_5_tuple_filter(None, Some(*ip_address), None, None, None, 7 , queue.id)?;
queue.filter_num = Some(filter_num);
}
(rx_queues, tx_queues, nic.mac_address())
};
VirtualNic::new(
rx_queues,
default_rx_queue,
tx_queues,
default_tx_queue,
mac_address,
get_ixgbe_nic(nic_id)?
)
}
impl PhysicalNic<IxgbeRxQueueRegisters, AdvancedRxDescriptor, IxgbeTxQueueRegisters, AdvancedTxDescriptor> for IxgbeNic
{
fn return_rx_queues(&mut self, mut queues: Vec<RxQueue<IxgbeRxQueueRegisters, AdvancedRxDescriptor>>) {
for queue in &queues {
self.disable_5_tuple_filter(queue.filter_num.unwrap()); }
self.rx_queues.append(&mut queues);
}
fn return_tx_queues(&mut self, mut queues: Vec<TxQueue<IxgbeTxQueueRegisters, AdvancedTxDescriptor>>) {
self.tx_queues.append(&mut queues);
}
}