2
2
//!
3
3
//! The module contains ...
4
4
5
+ cfg_if:: cfg_if! {
6
+ if #[ cfg( feature = "pci" ) ] {
7
+ mod pci;
8
+ } else {
9
+ mod mmio;
10
+ }
11
+ }
12
+
5
13
use alloc:: boxed:: Box ;
6
14
use alloc:: rc:: Rc ;
7
15
use alloc:: vec:: Vec ;
@@ -12,18 +20,16 @@ use align_address::Align;
12
20
use pci_types:: InterruptLine ;
13
21
use smoltcp:: phy:: { Checksum , ChecksumCapabilities } ;
14
22
use smoltcp:: wire:: { EthernetFrame , Ipv4Packet , Ipv6Packet , ETHERNET_HEADER_LEN } ;
15
- use virtio_spec:: net:: { Hdr , HdrF } ;
23
+ use virtio_spec:: net:: { ConfigVolatileFieldAccess , Hdr , HdrF } ;
16
24
use virtio_spec:: FeatureBits ;
25
+ use volatile:: access:: ReadOnly ;
26
+ use volatile:: VolatileRef ;
17
27
18
- use self :: constants:: { Status , MAX_NUM_VQ } ;
28
+ use self :: constants:: MAX_NUM_VQ ;
19
29
use self :: error:: VirtioNetError ;
20
30
#[ cfg( not( target_arch = "riscv64" ) ) ]
21
31
use crate :: arch:: kernel:: core_local:: increment_irq_counter;
22
32
use crate :: config:: VIRTIO_MAX_QUEUE_SIZE ;
23
- #[ cfg( not( feature = "pci" ) ) ]
24
- use crate :: drivers:: net:: virtio_mmio:: NetDevCfgRaw ;
25
- #[ cfg( feature = "pci" ) ]
26
- use crate :: drivers:: net:: virtio_pci:: NetDevCfgRaw ;
27
33
use crate :: drivers:: net:: NetworkDriver ;
28
34
#[ cfg( not( feature = "pci" ) ) ]
29
35
use crate :: drivers:: virtio:: transport:: mmio:: { ComCfg , IsrStatus , NotifCfg } ;
@@ -38,7 +44,7 @@ use crate::executor::device::{RxToken, TxToken};
38
44
/// Handling the right access to fields, as some are read-only
39
45
/// for the driver.
40
46
pub ( crate ) struct NetDevCfg {
41
- pub raw : & ' static NetDevCfgRaw ,
47
+ pub raw : VolatileRef < ' static , virtio_spec :: net :: Config , ReadOnly > ,
42
48
pub dev_id : u16 ,
43
49
pub features : virtio_spec:: net:: F ,
44
50
}
@@ -154,7 +160,7 @@ impl RxQueues {
154
160
( 1514 + mem:: size_of :: < Hdr > ( ) )
155
161
. align_up ( core:: mem:: size_of :: < crossbeam_utils:: CachePadded < u8 > > ( ) )
156
162
} else {
157
- dev_cfg. raw . get_mtu ( ) as usize + mem:: size_of :: < Hdr > ( )
163
+ dev_cfg. raw . as_ptr ( ) . mtu ( ) . read ( ) . to_ne ( ) as usize + mem:: size_of :: < Hdr > ( )
158
164
} ;
159
165
160
166
// See Virtio specification v1.1 - 5.1.6.3.1
@@ -318,8 +324,10 @@ impl TxQueues {
318
324
// Header and data are added as ONE output descriptor to the transmitvq.
319
325
// Hence we are interpreting this, as the fact, that send packets must be inside a single descriptor.
320
326
// As usize is currently safe as the minimal usize is defined as 16bit in rust.
321
- let buff_def =
322
- Bytes :: new ( mem:: size_of :: < Hdr > ( ) + dev_cfg. raw . get_mtu ( ) as usize ) . unwrap ( ) ;
327
+ let buff_def = Bytes :: new (
328
+ mem:: size_of :: < Hdr > ( ) + dev_cfg. raw . as_ptr ( ) . mtu ( ) . read ( ) . to_ne ( ) as usize ,
329
+ )
330
+ . unwrap ( ) ;
323
331
let spec = BuffSpec :: Single ( buff_def) ;
324
332
325
333
let num_buff: u16 = vq. size ( ) . into ( ) ;
@@ -421,7 +429,14 @@ impl NetworkDriver for VirtioNetDriver {
421
429
/// If VIRTIO_NET_F_MAC is not set, the function panics currently!
422
430
fn get_mac_address ( & self ) -> [ u8 ; 6 ] {
423
431
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: MAC ) {
424
- self . dev_cfg . raw . get_mac ( )
432
+ loop {
433
+ let before = self . com_cfg . config_generation ( ) ;
434
+ let mac = self . dev_cfg . raw . as_ptr ( ) . mac ( ) . read ( ) ;
435
+ let after = self . com_cfg . config_generation ( ) ;
436
+ if before == after {
437
+ break mac;
438
+ }
439
+ }
425
440
} else {
426
441
unreachable ! ( "Currently VIRTIO_NET_F_MAC must be negotiated!" )
427
442
}
@@ -637,11 +652,11 @@ impl VirtioNetDriver {
637
652
/// Returns the current status of the device, if VIRTIO_NET_F_STATUS
638
653
/// has been negotiated. Otherwise assumes an active device.
639
654
#[ cfg( not( feature = "pci" ) ) ]
640
- pub fn dev_status ( & self ) -> u16 {
655
+ pub fn dev_status ( & self ) -> virtio_spec :: net :: S {
641
656
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: STATUS ) {
642
- self . dev_cfg . raw . get_status ( )
657
+ self . dev_cfg . raw . as_ptr ( ) . status ( ) . read ( )
643
658
} else {
644
- u16 :: from ( Status :: VIRTIO_NET_S_LINK_UP )
659
+ virtio_spec :: net :: S :: LINK_UP
645
660
}
646
661
}
647
662
@@ -650,8 +665,12 @@ impl VirtioNetDriver {
650
665
#[ cfg( feature = "pci" ) ]
651
666
pub fn is_link_up ( & self ) -> bool {
652
667
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: STATUS ) {
653
- self . dev_cfg . raw . get_status ( ) & u16:: from ( Status :: VIRTIO_NET_S_LINK_UP )
654
- == u16:: from ( Status :: VIRTIO_NET_S_LINK_UP )
668
+ self . dev_cfg
669
+ . raw
670
+ . as_ptr ( )
671
+ . status ( )
672
+ . read ( )
673
+ . contains ( virtio_spec:: net:: S :: LINK_UP )
655
674
} else {
656
675
true
657
676
}
@@ -660,8 +679,12 @@ impl VirtioNetDriver {
660
679
#[ allow( dead_code) ]
661
680
pub fn is_announce ( & self ) -> bool {
662
681
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: STATUS ) {
663
- self . dev_cfg . raw . get_status ( ) & u16:: from ( Status :: VIRTIO_NET_S_ANNOUNCE )
664
- == u16:: from ( Status :: VIRTIO_NET_S_ANNOUNCE )
682
+ self . dev_cfg
683
+ . raw
684
+ . as_ptr ( )
685
+ . status ( )
686
+ . read ( )
687
+ . contains ( virtio_spec:: net:: S :: ANNOUNCE )
665
688
} else {
666
689
false
667
690
}
@@ -675,7 +698,12 @@ impl VirtioNetDriver {
675
698
#[ allow( dead_code) ]
676
699
pub fn get_max_vq_pairs ( & self ) -> u16 {
677
700
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: MQ ) {
678
- self . dev_cfg . raw . get_max_virtqueue_pairs ( )
701
+ self . dev_cfg
702
+ . raw
703
+ . as_ptr ( )
704
+ . max_virtqueue_pairs ( )
705
+ . read ( )
706
+ . to_ne ( )
679
707
} else {
680
708
1
681
709
}
@@ -838,7 +866,7 @@ impl VirtioNetDriver {
838
866
debug ! ( "{:?}" , self . checksums) ;
839
867
840
868
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: MTU ) {
841
- self . mtu = self . dev_cfg . raw . get_mtu ( ) ;
869
+ self . mtu = self . dev_cfg . raw . as_ptr ( ) . mtu ( ) . read ( ) . to_ne ( ) ;
842
870
}
843
871
844
872
Ok ( ( ) )
@@ -924,10 +952,23 @@ impl VirtioNetDriver {
924
952
// - the num_queues is found in the ComCfg struct of the device and defines the maximal number
925
953
// of supported queues.
926
954
if self . dev_cfg . features . contains ( virtio_spec:: net:: F :: MQ ) {
927
- if self . dev_cfg . raw . get_max_virtqueue_pairs ( ) * 2 >= MAX_NUM_VQ {
955
+ if self
956
+ . dev_cfg
957
+ . raw
958
+ . as_ptr ( )
959
+ . max_virtqueue_pairs ( )
960
+ . read ( )
961
+ . to_ne ( ) * 2 >= MAX_NUM_VQ
962
+ {
928
963
self . num_vqs = MAX_NUM_VQ ;
929
964
} else {
930
- self . num_vqs = self . dev_cfg . raw . get_max_virtqueue_pairs ( ) * 2 ;
965
+ self . num_vqs = self
966
+ . dev_cfg
967
+ . raw
968
+ . as_ptr ( )
969
+ . max_virtqueue_pairs ( )
970
+ . read ( )
971
+ . to_ne ( ) * 2 ;
931
972
}
932
973
} else {
933
974
// Minimal number of virtqueues defined in the standard v1.1. - 5.1.5 Step 1
@@ -1012,28 +1053,6 @@ impl VirtioNetDriver {
1012
1053
pub mod constants {
1013
1054
// Configuration constants
1014
1055
pub const MAX_NUM_VQ : u16 = 2 ;
1015
-
1016
- /// Enum contains virtio's network device status
1017
- /// indiacted in the status field of the device's
1018
- /// configuration structure.
1019
- ///
1020
- /// See Virtio specification v1.1. - 5.1.4
1021
- #[ allow( dead_code, non_camel_case_types) ]
1022
- #[ derive( Copy , Clone , Debug ) ]
1023
- #[ repr( u16 ) ]
1024
- pub enum Status {
1025
- VIRTIO_NET_S_LINK_UP = 1 << 0 ,
1026
- VIRTIO_NET_S_ANNOUNCE = 1 << 1 ,
1027
- }
1028
-
1029
- impl From < Status > for u16 {
1030
- fn from ( stat : Status ) -> Self {
1031
- match stat {
1032
- Status :: VIRTIO_NET_S_LINK_UP => 1 ,
1033
- Status :: VIRTIO_NET_S_ANNOUNCE => 2 ,
1034
- }
1035
- }
1036
- }
1037
1056
}
1038
1057
1039
1058
/// Error module of virtios network driver. Containing the (VirtioNetError)[VirtioNetError]
0 commit comments