3
3
#![ allow( dead_code) ]
4
4
5
5
use alloc:: boxed:: Box ;
6
- use alloc:: collections :: { btree_map , BTreeMap } ;
6
+ use alloc:: vec :: Vec ;
7
7
use core:: mem;
8
8
9
9
use x86:: io:: * ;
@@ -209,7 +209,7 @@ pub struct RTL8139Driver {
209
209
rxbuffer : Box < [ u8 ] > ,
210
210
rxpos : usize ,
211
211
txbuffer : Box < [ u8 ] > ,
212
- box_map : BTreeMap < usize , Box < [ u8 ] > > ,
212
+ polling_mode_counter : u32 ,
213
213
}
214
214
215
215
impl NetworkInterface for RTL8139Driver {
@@ -270,7 +270,7 @@ impl NetworkInterface for RTL8139Driver {
270
270
false
271
271
}
272
272
273
- fn receive_rx_buffer ( & mut self ) -> Result < ( & ' static mut [ u8 ] , usize ) , ( ) > {
273
+ fn receive_rx_buffer ( & mut self ) -> Result < Vec < u8 > , ( ) > {
274
274
let cmd = unsafe { inb ( self . iobase + CR ) } ;
275
275
276
276
if ( cmd & CR_BUFE ) != CR_BUFE {
@@ -282,25 +282,18 @@ impl NetworkInterface for RTL8139Driver {
282
282
let pos = ( self . rxpos + mem:: size_of :: < u16 > ( ) ) % RX_BUF_LEN ;
283
283
284
284
// do we reach the end of the receive buffers?
285
- // in this case, we have to copy the data in boxed slice
285
+ // in this case, we conact the two slices to one vec
286
286
let buf = if pos + length as usize > RX_BUF_LEN {
287
287
let first = & self . rxbuffer [ pos..RX_BUF_LEN ] ;
288
288
let second = & self . rxbuffer [ ..length as usize - first. len ( ) ] ;
289
- let msg = [ first, second] . concat ( ) . into_boxed_slice ( ) ;
290
-
291
- // buffer address to release box in `rx_buffer_consumed`
292
- match self . box_map . entry ( self . rxpos ) {
293
- btree_map:: Entry :: Vacant ( entry) => entry. insert ( msg) ,
294
- btree_map:: Entry :: Occupied ( _) => unreachable ! ( ) ,
295
- }
289
+ [ first, second] . concat ( )
296
290
} else {
297
- & mut self . rxbuffer [ pos..] [ ..length. into ( ) ]
291
+ ( self . rxbuffer [ pos..] [ ..length. into ( ) ] ) . to_vec ( )
298
292
} ;
299
- // SAFETY: This is a blatant lie and very unsound.
300
- // The API must be fixed or the buffer may never touched again.
301
- let buf = unsafe { mem:: transmute ( buf) } ;
302
293
303
- Ok ( ( buf, self . rxpos ) )
294
+ self . consume_current_buffer ( ) ;
295
+
296
+ Ok ( buf)
304
297
} else {
305
298
error ! (
306
299
"RTL8192: invalid header {:#x}, rx_pos {}\n " ,
@@ -314,43 +307,22 @@ impl NetworkInterface for RTL8139Driver {
314
307
}
315
308
}
316
309
317
- // Tells driver, that buffer is consumed and can be deallocated
318
- fn rx_buffer_consumed ( & mut self , handle : usize ) {
319
- if self . rxpos != handle {
320
- warn ! ( "Invalid handle {} != {}" , self . rxpos, handle)
321
- }
322
-
323
- drop ( self . box_map . remove ( & self . rxpos ) ) ;
324
-
325
- let length = self . rx_peek_u16 ( ) ;
326
- self . advance_rxpos ( usize:: from ( length) + mem:: size_of :: < u16 > ( ) ) ;
327
-
328
- // packets are dword aligned
329
- self . rxpos = ( ( self . rxpos + 3 ) & !0x3 ) % RX_BUF_LEN ;
330
- if self . rxpos >= 0x10 {
331
- unsafe {
332
- outw ( self . iobase + CAPR , ( self . rxpos - 0x10 ) . try_into ( ) . unwrap ( ) ) ;
333
- }
334
- } else {
335
- unsafe {
336
- outw (
337
- self . iobase + CAPR ,
338
- ( RX_BUF_LEN - ( 0x10 - self . rxpos ) ) . try_into ( ) . unwrap ( ) ,
339
- ) ;
340
- }
341
- }
342
- }
343
-
344
310
fn set_polling_mode ( & mut self , value : bool ) {
345
311
if value {
346
- // disable interrupts from the NIC
347
- unsafe {
348
- outw ( self . iobase + IMR , INT_MASK_NO_ROK ) ;
312
+ if self . polling_mode_counter == 0 {
313
+ // disable interrupts from the NIC
314
+ unsafe {
315
+ outw ( self . iobase + IMR , INT_MASK_NO_ROK ) ;
316
+ }
349
317
}
318
+ self . polling_mode_counter += 1 ;
350
319
} else {
351
- // Enable all known interrupts by setting the interrupt mask.
352
- unsafe {
353
- outw ( self . iobase + IMR , INT_MASK ) ;
320
+ self . polling_mode_counter -= 1 ;
321
+ if self . polling_mode_counter == 0 {
322
+ // Enable all known interrupts by setting the interrupt mask.
323
+ unsafe {
324
+ outw ( self . iobase + IMR , INT_MASK ) ;
325
+ }
354
326
}
355
327
}
356
328
}
@@ -390,6 +362,27 @@ impl NetworkInterface for RTL8139Driver {
390
362
}
391
363
392
364
impl RTL8139Driver {
365
+ // Tells driver, that buffer is consumed and can be deallocated
366
+ fn consume_current_buffer ( & mut self ) {
367
+ let length = self . rx_peek_u16 ( ) ;
368
+ self . advance_rxpos ( usize:: from ( length) + mem:: size_of :: < u16 > ( ) ) ;
369
+
370
+ // packets are dword aligned
371
+ self . rxpos = ( ( self . rxpos + 3 ) & !0x3 ) % RX_BUF_LEN ;
372
+ if self . rxpos >= 0x10 {
373
+ unsafe {
374
+ outw ( self . iobase + CAPR , ( self . rxpos - 0x10 ) . try_into ( ) . unwrap ( ) ) ;
375
+ }
376
+ } else {
377
+ unsafe {
378
+ outw (
379
+ self . iobase + CAPR ,
380
+ ( RX_BUF_LEN - ( 0x10 - self . rxpos ) ) . try_into ( ) . unwrap ( ) ,
381
+ ) ;
382
+ }
383
+ }
384
+ }
385
+
393
386
fn rx_peek_u16 ( & self ) -> u16 {
394
387
u16:: from_ne_bytes (
395
388
self . rxbuffer [ self . rxpos ..] [ ..mem:: size_of :: < u16 > ( ) ]
@@ -611,6 +604,6 @@ pub fn init_device(adapter: &pci::PciAdapter) -> Result<RTL8139Driver, DriverErr
611
604
rxbuffer,
612
605
rxpos : 0 ,
613
606
txbuffer,
614
- box_map : BTreeMap :: new ( ) ,
607
+ polling_mode_counter : 0 ,
615
608
} )
616
609
}
0 commit comments