Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Cleanup and sanity-checking of endianness, dead code, unchecked returns (Coverity...
[palacios.git] / palacios / src / devices / rtl8139.c
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2011, Lei Xia <lxia@northwestern.edu> 
11  * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author:  Lei Xia <lxia@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <devices/pci.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_types.h>
23 #include <palacios/vmm_io.h>
24 #include <palacios/vmm_debug.h>
25 #include <palacios/vm_guest_mem.h>
26 #include <palacios/vmm_ethernet.h>
27 #include <palacios/vmm_sprintf.h>
28
29
30
31 #ifndef V3_CONFIG_DEBUG_RTL8139
32 #undef PrintDebug
33 #define PrintDebug(fmts, args...)
34 #endif
35
36 #define RTL8139_IDR0    (0x00)  /* ID Registers start, len 6*1bytes */
37 #define RTL8139_MAR0    (0x08)  /* Mulicast Registers start, len 8*1bytes */
38
39 #define RTL8139_TSD0    (0x10)  /* Tx Status of Descriptors */
40 #define RTL8139_TSD1    (0x14)
41 #define RTL8139_TSD2    (0x18)
42 #define RTL8139_TSD3    (0x1c)
43
44 #define RTL8139_TSAD0   (0x20)  /* Tx Start Address of Descriptors */
45 #define RTL8139_TSAD1   (0x24)
46 #define RTL8139_TSAD2   (0x28)
47 #define RTL8139_TSAD3   (0x2c)
48
49 #define RTL8139_RBSTART (0x30)  /* Rx Buffer Start Address */
50 #define RTL8139_ERBCR   (0x34)  /* Early Rx Byte Count Register */
51 #define RTL8139_ERSR    (0x36)  /* Early Rx Status Register */
52 #define RTL8139_CR      (0x37)  /* Command Register */
53 #define RTL8139_CAPR    (0x38)  /* Current Address of Pkt Read */
54 #define RTL8139_CBR     (0x3a)  /* Current Buffer Address */
55 #define RTL8139_IMR     (0x3c)  /* Intrpt Mask Reg */
56 #define RTL8139_ISR     (0x3e)  /* Intrpt Status Reg */
57 #define RTL8139_TCR     (0x40)  /* Tx Config Reg */
58 #define RTL8139_RCR     (0x44)  /* Rx Config Reg */
59 #define RTL8139_TCTR    (0x48)  /* Timer Count Reg */
60 #define RTL8139_MPC     (0x4c)  /* Missed Pkt Counter */
61 #define RTL8139_9346CR  (0x50)  /* 9346 Command Reg */
62 #define RTL8139_CONFIG0 (0x51)  /* Config Reg */
63 #define RTL8139_CONFIG1 (0x52)
64 #define RTL8139_TimerInt    (0x54)      /* Timer Intrpt Reg */
65 #define RTL8139_MSR     (0x58)  /* Media Status Reg */
66 #define RTL8139_CONFIG3 (0x59)  
67 #define RTL8139_CONFIG4 (0x5a)
68 #define RTL8139_MULINT  (0x5c)  /* Multiple Intrpt Select */
69 #define RTL8139_RERID   (0x5e)  
70 #define RTL8139_TXSAD    (0x60) /* Tx Status of All Descriptors */
71 #define RTL8139_BMCR    (0x62)  /* Basic Mode Control Register */
72 #define RTL8139_BMSR    (0x64)  /* Basic Mode Status Register */
73 #define RTL8139_ANAR    (0x66)  /* Auto-Negotiation Advertisement Register */
74 #define RTL8139_ANLPAR  (0x68)  /* Auto-Negotiation Link Partner Register */
75 #define RTL8139_ANER    (0x6a)  /* Auto-Negotiation Expansion Register */
76 #define RTL8139_DIS     (0x6c)  /* Disconnect Counter */
77 #define RTL8139_FCSC    (0x6e)  /* False Carrier Sense Counter */
78 #define RTL8139_NWAYTR  (0x70)  /* N-way Test Register */
79 #define RTL8139_REC     (0x72)  /* RX ER Counter */
80 #define RTL8139_CSCR    (0x74)  /* CS Config Register */
81 #define RTL8139_PHY1_PARM   (0x78)      /* PHY parameter */
82 #define RTL8139_TW_PARM (0x7c)  /* Twister parameter */
83 #define RTL8139_PHY2_PARM   (0x80)
84
85 #define RTL8139_CRC0    (0x84)  /* Power Management CRC Reg for wakeup frame 8*1bytes */
86
87 #define RTL8139_Wakeup0 (0x8c)  /* Power Management wakeup frame */
88 #define RTL8139_Wakeup1 (0x94)
89 #define RTL8139_Wakeup2 (0x9c)
90 #define RTL8139_Wakeup3 (0xa4)
91 #define RTL8139_Wakeup4 (0xac)
92 #define RTL8139_Wakeup5 (0xb4)
93 #define RTL8139_Wakeup6 (0xbc)
94 #define RTL8139_Wakeup7 (0xc4)
95
96 #define RTL8139_LSBCRO0 (0xcc)  /* LSB of the mask byte of wakeup frame */
97 #define RTL8139_LSBCRO1 (0xcd)
98 #define RTL8139_LSBCRO2 (0xce)
99 #define RTL8139_LSBCRO3 (0xcf)
100 #define RTL8139_LSBCRO4 (0xd0)
101 #define RTL8139_LSBCRO5 (0xd1)
102 #define RTL8139_LSBCRO6 (0xd2)
103 #define RTL8139_LSBCRO7 (0xd3)
104
105 #define RTL8139_Config5 (0xd8)
106
107 /* Interrupts */
108 #define PKT_RX      0x0001
109 #define RX_ERR      0x0002
110 #define TX_OK       0x0004
111 #define TX_ERR      0x0008
112 #define RX_BUFF_OF  0x0010
113 #define RX_UNDERRUN 0x0020
114 #define RX_FIFO_OF  0x0040
115 #define CABLE_LEN_CHNG  0x2000
116 #define TIME_OUT    0x4000
117 #define SERR        0x8000
118
119 #define DESC_SIZE 2048
120 #define TX_FIFO_SIZE (DESC_SIZE * 4)
121 #define RX_FIFO_SIZE (DESC_SIZE * 4)
122
123 typedef enum {NIC_READY, NIC_REG_POSTED} nic_state_t;
124
125 enum TxStatusBits {
126     TSD_Own = 1<<13,
127     TSD_Tun = 1<<14,
128     TSD_Tok = 1<<15,
129     TSD_Cdh = 1<<28,
130     TSD_Owc = 1<<29,
131     TSD_Tabt = 1<<30,
132     TSD_Crs = 1<<31,
133 };
134
135 /* Transmit Status Register (TSD0-3) Offset: 0x10-0x1F */
136 struct tx_status_reg {
137     union {
138         uint16_t val;
139         struct {
140             uint16_t size     : 13;
141             uint8_t own     : 1;
142             uint8_t tun     : 1;
143             uint8_t tok     : 1;        
144             uint8_t er_tx_th   : 6;
145             uint8_t reserved    : 2;
146             uint8_t ncc            : 4;
147             uint8_t cdh : 1;
148             uint8_t owc : 1;
149             uint8_t tabt        : 1;
150             uint8_t crs : 1;
151         } __attribute__((packed));
152     } __attribute__((packed));
153 } __attribute__((packed));
154
155
156 enum RxStatusBits {
157     Rx_Multicast = 1<<15,
158     Rx_Physical = 1<<14,
159     Rx_Broadcast = 1<<13,
160     Rx_BadSymbol = 1<<5,
161     Rx_Runt = 1<<4,
162     Rx_TooLong = 1<<3,
163     Rx_CRCErr = 1<<2,
164     Rx_BadAlign = 1<<1,
165     Rx_OK = 1<<0,
166 };
167
168
169 /* Receive Status Register in RX Packet Header */
170 struct rx_status_reg {
171     union {
172         uint16_t val;
173         struct {
174             uint16_t rx_ok     : 1;
175             uint16_t rx_bad_align     : 1;
176             uint16_t rx_crc_err     : 1;
177             uint16_t rx_too_long     : 1;       
178             uint16_t rx_runt    : 1;
179             uint16_t rx_bad_sym : 1;
180             uint16_t reserved   : 7;
181             uint16_t rx_brdcast : 1;
182             uint16_t rx_phys    : 1;
183             uint16_t rx_multi   : 1;
184         } __attribute__((packed));
185     } __attribute__((packed));
186 } __attribute__((packed));
187
188
189 /* ERSR - Early Rx Status Register Offset: 0x36*/
190 struct errx_status_reg{
191     union {
192         uint8_t val;
193         struct {
194             uint8_t er_rx_ok     : 1;
195             uint8_t er_rx_ovw     : 1;
196             uint8_t er_rx_bad_pkt     : 1;
197             uint8_t er_rx_good     : 1; 
198             uint8_t reserved    : 4;
199         } __attribute__((packed));
200     } __attribute__((packed));
201 } __attribute__((packed));
202
203
204 /* Transmit Status of All Descriptors (TSAD) Register */
205 enum TSAD_bits {
206     TSAD_TOK3 = 1<<15, /* TOK bits of Descriptors*/
207     TSAD_TOK2 = 1<<14, 
208     TSAD_TOK1 = 1<<13, 
209     TSAD_TOK0 = 1<<12, 
210     TSAD_TUN3 = 1<<11, /* TUN bits of Descriptors */
211     TSAD_TUN2 = 1<<10, 
212     TSAD_TUN1 = 1<<9, 
213     TSAD_TUN0 = 1<<8,
214     TSAD_TABT3 = 1<<7, /* TABT bits of Descriptors */
215     TSAD_TABT2 = 1<<6,
216     TSAD_TABT1 = 1<<5,
217     TSAD_TABT0 = 1<<4,
218     TSAD_OWN3 = 1<<3, /* OWN bits of Descriptors */
219     TSAD_OWN2 = 1<<2,
220     TSAD_OWN1 = 1<<1, 
221     TSAD_OWN0 = 1<<0,
222 };
223
224
225 /* Transmit Status of All Descriptors (TSAD) Register Offset: 0x60-0x61*/
226 struct txsad_reg {
227     union {
228         uint16_t val;
229         struct {
230             uint8_t own0     : 1;
231             uint8_t own1     : 1;
232             uint8_t own2     : 1;
233             uint8_t own3     : 1;       
234             uint8_t tabt0       : 1;
235             uint8_t tabt1       : 1;
236             uint8_t tabt2       : 1;
237             uint8_t tabt3       : 1;
238             uint8_t tun0        : 1;
239             uint8_t tun1        : 1;
240             uint8_t tun2        : 1;
241             uint8_t tun3        : 1;
242             uint8_t tok0        : 1;
243             uint8_t tok1        : 1;
244             uint8_t tok2        : 1;
245             uint8_t tok3        : 1;
246         } __attribute__((packed));
247     } __attribute__((packed));
248 } __attribute__((packed));
249
250
251
252 enum ISRBits {
253     ISR_Rok = 1<<0,
254     ISR_Rer = 1<<1,
255     ISR_Tok = 1<<2,
256     ISR_Ter = 1<<3,
257     ISR_Rxovw = 1<<4,
258     ISR_Pun = 1<<5,
259     ISR_Fovw = 1<<6,
260     ISR_Lenchg = 1<<13,
261     ISR_Timeout = 1<<14,
262     ISR_Serr = 1<<15,
263 };
264
265 /* 
266  * Interrupt Status Register (ISR) Offset: ox3e-0x3f
267  * Interrupt Mask Register (IMR 0x3c-0x3d) shares the same structure
268  */
269 struct isr_imr_reg {
270     union {
271         uint16_t val;
272         struct {
273             uint16_t rx_ok      :1;
274             uint16_t rx_err     : 1;
275             uint16_t tx_ok        : 1;
276             uint16_t tx_err          : 1;
277             uint16_t rx_ovw          : 1;
278             uint16_t pun_linkchg          : 1;
279             uint16_t rx_fifo_ovw  : 1;
280             uint16_t reservd:     6;
281             uint16_t lenchg  :1;
282             uint16_t timeout   :1;
283             uint16_t syserr  :1;
284         } __attribute__((packed));
285     } __attribute__((packed));
286 } __attribute__((packed));
287
288 enum CMDBits {
289     CMD_Bufe = 1<<0,
290     CMD_Te = 1<<2,
291     CMD_Re = 1<<3,
292     CMD_Rst = 1<<4,
293 };
294
295
296 /* Commmand Register Offset: 0x37 */
297 struct cmd_reg {
298     union {
299         uint8_t val;
300         struct {
301             uint8_t cmd_bufe      : 1;
302             uint8_t reservd_1        : 1;
303             uint8_t cmd_te          : 1;
304             uint8_t cmd_re          : 1;
305             uint8_t cmd_rst          : 1;
306             uint8_t reservd_2  : 3;
307         } __attribute__((packed));
308     } __attribute__((packed));
309 } __attribute__((packed));
310
311
312
313
314 enum CMD9346Bits {
315     CMD9346_Lock = 0x00,
316     CMD9346_Unlock = 0xC0,
317 };
318
319
320
321 /* 93C46 Commmand Register Offset: 0x50 */
322 struct cmd9346_reg {
323     union {
324         uint8_t val;
325         struct {
326             uint8_t eedo      : 1;
327             uint8_t eedi        : 1;
328             uint8_t eesk          : 1;
329             uint8_t eecs          : 1;
330             uint8_t reserved    : 2;
331             uint8_t eem  : 2;
332         } __attribute__((packed));
333     } __attribute__((packed));
334 } __attribute__((packed));
335
336
337
338 // Bits in TxConfig.
339 enum TXConfig_bits{
340
341         /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
342     TxIFGShift = 24,
343     TxIFG84 = (0 << TxIFGShift),    /* 8.4us / 840ns (10 / 100Mbps) */
344     TxIFG88 = (1 << TxIFGShift),    /* 8.8us / 880ns (10 / 100Mbps) */
345     TxIFG92 = (2 << TxIFGShift),    /* 9.2us / 920ns (10 / 100Mbps) */
346     TxIFG96 = (3 << TxIFGShift),    /* 9.6us / 960ns (10 / 100Mbps) */
347
348     TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
349     TxCRC = (1 << 16),  /* DISABLE appending CRC to end of Tx packets */
350     TxClearAbt = (1 << 0),      /* Clear abort (WO) */
351     TxDMAShift = 8,             /* DMA burst value (0-7) is shifted this many bits */
352     TxRetryShift = 4,   /* TXRR value (0-15) is shifted this many bits */
353
354     TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
355 };
356
357
358 /* Transmit Configuration Register (TCR) Offset: 0x40-0x43 */
359 struct tx_config_reg {
360     union {
361         uint32_t val;
362         struct {
363             uint8_t clr_abort   :1;
364             uint8_t reserved_1     : 3;
365             uint8_t tx_retry_cnt        : 4;
366             uint8_t max_dma          : 3;
367             uint8_t reserved_2          : 5;
368             uint8_t tx_crc          : 1;
369             uint8_t loop_test  : 2;
370             uint8_t reservd_3:     3;
371             uint8_t hw_verid_b  :2;
372             uint8_t ifg   :2;
373             uint8_t hw_verid_a  :5;
374             uint8_t reservd_4  :1;
375         } __attribute__((packed));
376     } __attribute__((packed));
377 } __attribute__((packed));
378
379
380
381
382 enum CSCRBits {
383     CSCR_Testfun = 1<<15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */
384     CSCR_LD  = 1<<9,  /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/
385     CSCR_HEART_BIT = 1<<8,  /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/
386     CSCR_JBEN = 1<<7,  /* 1 = enable jabber function. 0 = disable jabber function, def 1*/
387     CSCR_F_LINK_100 = 1<<6, /* Used to login force good link in 100Mbps for diagnostic purposes. 1 = DISABLE, 0 = ENABLE. def 1*/
388     CSCR_F_Connect  = 1<<5,  /* Assertion of this bit forces the disconnect function to be bypassed. def 0*/
389     CSCR_Con_status = 1<<3, /* This bit indicates the status of the connection. 1 = valid connected link detected; 0 = disconnected link detected. RO def 0*/
390     CSCR_Con_status_En = 1<<2, /* Assertion of this bit configures LED1 pin to indicate connection status. def 0*/
391     CSCR_PASS_SCR = 1<<0, /* Bypass Scramble, def 0*/
392 };
393
394
395 /* CS Configuration Register (CSCR) Offset: 0x74-0x75 */
396 struct cscr_reg {
397     union {
398         uint16_t val;
399         struct {
400             uint8_t pass_scr    :1;
401             uint8_t reserved_1     : 1;
402             uint8_t con_status_en        : 1;
403             uint8_t con_status          : 1;
404             uint8_t reserved_2          : 1;
405             uint8_t f_connect          : 1;
406             uint8_t f_link_100  : 1;
407             uint8_t jben:     1;
408             uint8_t heart_beat  :1;
409             uint8_t ld   :1;
410             uint8_t reservd_3  :5;
411             uint8_t test_fun  :1;
412         } __attribute__((packed));
413     } __attribute__((packed));
414 } __attribute__((packed));
415
416
417 /* Bits in RxConfig. */
418 enum rx_mode_bits {
419     AcceptErr = 0x20,
420     AcceptRunt = 0x10,
421     AcceptBroadcast = 0x08,
422     AcceptMulticast = 0x04,
423     AcceptMyPhys = 0x02,
424     AcceptAllPhys = 0x01,
425 };
426
427
428 /* Receive Configuration Register (RCR) Offset: 0x44-0x47 */
429 struct rx_config_reg {
430     union {
431         uint32_t val;
432         struct {
433             uint8_t all_phy   : 1;
434             uint8_t my_phy      : 1;
435             uint8_t all_multi     : 1;
436             uint8_t all_brdcast        : 1;
437             uint8_t acpt_runt          : 1;
438             uint8_t acpt_err          : 1;
439             uint8_t reserved_1          : 1;
440             uint8_t wrap  : 1;
441             uint8_t max_dma:     3;
442             uint8_t rx_buf_len  :2;
443             uint8_t rx_fifo_thresd   :3;
444             uint8_t rer8  :1;
445             uint8_t mul_er_intr  :1;
446             uint8_t reserved_2          : 6;
447             uint8_t eraly_rx_thresd   :4;
448             uint8_t reserved_3          : 4;
449         } __attribute__((packed));
450     } __attribute__((packed));
451 } __attribute__((packed));
452
453
454
455
456 #define RTL8139_PCI_REVID_8139      0x10
457
458 #define SET_MASKED(input, mask, curr) \
459     (((input) & ~(mask)) | ((curr) & (mask)))
460
461 /* arg % size for size which is a power of 2 */
462 #define MOD2(input, size) \
463     ((input) & (size - 1))
464
465
466 /* Size is 64 * 16bit words */
467 #define EEPROM_9346_ADDR_BITS 6
468 #define EEPROM_9346_SIZE  (1 << EEPROM_9346_ADDR_BITS)
469 #define EEPROM_9346_ADDR_MASK (EEPROM_9346_SIZE - 1)
470
471 enum Chip9346Operation
472 {
473     Chip9346_op_mask = 0xc0,          /* 10 zzzzzz */
474     Chip9346_op_read = 0x80,          /* 10 AAAAAA */
475     Chip9346_op_write = 0x40,         /* 01 AAAAAA D(15)..D(0) */
476     Chip9346_op_ext_mask = 0xf0,      /* 11 zzzzzz */
477     Chip9346_op_write_enable = 0x30,  /* 00 11zzzz */
478     Chip9346_op_write_all = 0x10,     /* 00 01zzzz */
479     Chip9346_op_write_disable = 0x00, /* 00 00zzzz */
480 };
481
482 enum Chip9346Mode {
483     Chip9346_none = 0,
484     Chip9346_enter_command_mode,
485     Chip9346_read_command,
486     Chip9346_data_read,      /* from output register */
487     Chip9346_data_write,     /* to input register, then to contents at specified address */
488     Chip9346_data_write_all, /* to input register, then filling contents */
489 };
490
491 struct EEprom9346 {
492     uint16_t contents[EEPROM_9346_SIZE];
493     int      mode;
494     uint32_t tick;
495     uint8_t  address;
496     uint16_t input;
497     uint16_t output;
498
499     uint8_t eecs;
500     uint8_t eesk;
501     uint8_t eedi;
502     uint8_t eedo;
503 };
504
505 struct rtl8139_regs {
506   union{
507         uint8_t mem[256];
508         
509         struct {
510             uint8_t id[6];
511             uint8_t reserved;
512             uint8_t mult[8];
513             uint32_t tsd[4];
514             uint32_t tsad[4];
515             uint32_t rbstart;
516             uint16_t erbcr;
517             uint8_t ersr;
518             uint8_t cmd;
519             uint16_t capr;
520             uint16_t cbr;
521             uint16_t imr;
522             uint16_t isr;
523             uint32_t tcr;
524             uint32_t rcr;
525             uint32_t tctr;
526             uint16_t mpc;
527             uint8_t cmd9346;
528             uint8_t config[2];
529             uint32_t timer_int;
530             uint8_t msr;
531             uint8_t config3[2];
532             uint16_t mulint;
533             uint16_t rerid;
534             uint16_t txsad;
535             uint16_t bmcr;
536             uint16_t bmsr;
537             uint16_t anar;
538             uint16_t anlpar;
539             uint16_t aner;
540             uint16_t dis;
541             uint16_t fcsc;
542             uint16_t nwaytr;
543             uint16_t rec;
544             uint32_t cscr;
545             uint32_t phy1_parm;
546             uint16_t tw_parm;
547             uint32_t  phy2_parm;
548             uint8_t crc[8];
549             uint32_t wakeup[16];
550             uint8_t isbcr[8];
551             uint8_t config5;
552         }__attribute__((packed));
553    }__attribute__((packed));
554 };
555
556
557
558 struct rtl8139_state {  
559     nic_state_t dev_state;
560
561     struct v3_vm_info * vm;
562     struct pci_device * pci_dev;
563     struct vm_device * pci_bus;
564     struct vm_device * dev;
565
566     struct nic_statistics statistic;
567
568     struct rtl8139_regs regs;
569     struct EEprom9346 eeprom; 
570
571     uint8_t tx_fifo[TX_FIFO_SIZE];
572     uint8_t rx_fifo[RX_FIFO_SIZE];
573     uint32_t rx_bufsize;
574
575     uint8_t mac[ETH_ALEN];
576
577     struct v3_dev_net_ops *net_ops;
578     void * backend_data;
579 };
580
581 static inline void rtl8139_update_irq(struct rtl8139_state * nic_state) {
582     int isr = ((nic_state->regs.isr & nic_state->regs.imr) & 0xffff);
583
584     if(isr & 0xffff){
585         v3_pci_raise_irq(nic_state->pci_bus, nic_state->pci_dev, 0);
586         nic_state->statistic.tx_interrupts ++;
587     }
588 }
589
590 static void prom9346_decode_command(struct EEprom9346 * eeprom, uint8_t command) {
591     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom command 0x%02x\n", command);
592
593     switch (command & Chip9346_op_mask) {
594         case Chip9346_op_read:
595         {
596             eeprom->address = command & EEPROM_9346_ADDR_MASK;
597             eeprom->output = eeprom->contents[eeprom->address];
598             eeprom->eedo = 0;
599             eeprom->tick = 0;
600             eeprom->mode = Chip9346_data_read;
601             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom read from address 0x%02x data=0x%04x\n",
602                    eeprom->address, eeprom->output);
603         }
604         break;
605
606         case Chip9346_op_write:
607         {
608             eeprom->address = command & EEPROM_9346_ADDR_MASK;
609             eeprom->input = 0;
610             eeprom->tick = 0;
611             eeprom->mode = Chip9346_none; /* Chip9346_data_write */
612             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom begin write to address 0x%02x\n",
613                    eeprom->address);
614         }
615         break;
616         default:
617             eeprom->mode = Chip9346_none;
618             switch (command & Chip9346_op_ext_mask) {
619                 case Chip9346_op_write_enable:
620                     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom write enabled\n");
621                     break;
622                 case Chip9346_op_write_all:
623                     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom begin write all\n");
624                     break;
625                 case Chip9346_op_write_disable:
626                     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom write disabled\n");
627                     break;
628             }
629         break;
630     }
631 }
632
633 static void prom9346_shift_clock(struct EEprom9346 * eeprom) {
634     int bit = eeprom->eedi?1:0;
635
636     ++ eeprom->tick;
637
638     PrintDebug(VM_NONE, VCORE_NONE, "eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, eeprom->eedo);
639
640     switch (eeprom->mode) {
641         case Chip9346_enter_command_mode:
642             if (bit) {
643                 eeprom->mode = Chip9346_read_command;
644                 eeprom->tick = 0;
645                 eeprom->input = 0;
646                 PrintDebug(VM_NONE, VCORE_NONE, "eeprom: +++ synchronized, begin command read\n");
647             }
648             break;
649
650         case Chip9346_read_command:
651             eeprom->input = (eeprom->input << 1) | (bit & 1);
652             if (eeprom->tick == 8) {
653                 prom9346_decode_command(eeprom, eeprom->input & 0xff);
654             }
655             break;
656
657         case Chip9346_data_read:
658             eeprom->eedo = (eeprom->output & 0x8000)?1:0;
659             eeprom->output <<= 1;
660             if (eeprom->tick == 16){
661 #if 1
662         // the FreeBSD drivers (rl and re) don't explicitly toggle
663         // CS between reads (or does setting Cfg9346 to 0 count too?),
664         // so we need to enter wait-for-command state here
665                 eeprom->mode = Chip9346_enter_command_mode;
666                 eeprom->input = 0;
667                 eeprom->tick = 0;
668
669                 PrintDebug(VM_NONE, VCORE_NONE, "eeprom: +++ end of read, awaiting next command\n");
670 #else
671         // original behaviour
672                 ++eeprom->address;
673                 eeprom->address &= EEPROM_9346_ADDR_MASK;
674                 eeprom->output = eeprom->contents[eeprom->address];
675                 eeprom->tick = 0;
676
677                 DEBUG_PRINT(("eeprom: +++ read next address 0x%02x data=0x%04x\n",
678                        eeprom->address, eeprom->output));
679 #endif
680             }
681             break;
682
683         case Chip9346_data_write:
684             eeprom->input = (eeprom->input << 1) | (bit & 1);
685             if (eeprom->tick == 16) {
686                 PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom write to address 0x%02x data=0x%04x\n",
687                        eeprom->address, eeprom->input);
688
689                 eeprom->contents[eeprom->address] = eeprom->input;
690                 eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */
691                 eeprom->tick = 0;
692                 eeprom->input = 0;
693             }
694             break;
695
696         case Chip9346_data_write_all:
697             eeprom->input = (eeprom->input << 1) | (bit & 1);
698             if (eeprom->tick == 16) {
699                 int i;
700                 for (i = 0; i < EEPROM_9346_SIZE; i++)
701                 {
702                     eeprom->contents[i] = eeprom->input;
703                 }
704                 PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: eeprom filled with data=0x%04x\n",
705                        eeprom->input);
706
707                 eeprom->mode = Chip9346_enter_command_mode;
708                 eeprom->tick = 0;
709                 eeprom->input = 0;
710             }
711             break;
712
713         default:
714             break;
715     }
716 }
717
718 static int prom9346_get_wire(struct rtl8139_state * nic_state) {
719     struct EEprom9346 *eeprom = &(nic_state->eeprom);
720
721     if (eeprom->eecs == 0)
722         return 0;
723
724     return eeprom->eedo;
725 }
726
727 static void prom9346_set_wire(struct rtl8139_state * nic_state, 
728                               int eecs, 
729                               int eesk, 
730                               int eedi) {
731     struct EEprom9346 *eeprom = &(nic_state->eeprom);
732     uint8_t old_eecs = eeprom->eecs;
733     uint8_t old_eesk = eeprom->eesk;
734
735     eeprom->eecs = eecs;
736     eeprom->eesk = eesk;
737     eeprom->eedi = eedi;
738
739     PrintDebug(VM_NONE, VCORE_NONE, "eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n",
740                  eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo);
741
742     if (old_eecs == 0 && eecs) {
743         /* Synchronize start */
744         eeprom->tick = 0;
745         eeprom->input = 0;
746         eeprom->output = 0;
747         eeprom->mode = Chip9346_enter_command_mode;
748
749         PrintDebug(VM_NONE, VCORE_NONE, "=== eeprom: begin access, enter command mode\n");
750     }
751
752     if (eecs == 0) {
753         PrintDebug(VM_NONE, VCORE_NONE, "=== eeprom: end access\n");
754         return;
755     }
756
757     if (!old_eesk && eesk) {
758         /* SK front rules */
759         prom9346_shift_clock(eeprom);
760     }
761 }
762
763
764 static inline void rtl8139_reset_rxbuf(struct rtl8139_state * nic_state, uint32_t bufsize) {
765     nic_state->rx_bufsize = bufsize;
766     nic_state->regs.capr = 0;
767     nic_state->regs.cbr = 0;
768 }
769
770
771 static void rtl8139_reset(struct rtl8139_state *nic_state) {
772     struct rtl8139_regs *regs = &(nic_state->regs);
773     int i;
774
775     PrintDebug(VM_NONE, VCORE_NONE, "Rtl8139: Reset\n");
776
777     /* restore MAC address */
778     memcpy(regs->id, nic_state->mac, ETH_ALEN);
779     memset(regs->mult, 0xff, 8);
780
781     rtl8139_update_irq(nic_state);
782
783     // prepare eeprom
784     nic_state->eeprom.contents[0] = 0x8129;
785         
786     // PCI vendor and device ID
787     nic_state->eeprom.contents[1] = 0x10ec;
788     nic_state->eeprom.contents[2] = 0x8139;
789     //Mac address
790     nic_state->eeprom.contents[7] = nic_state->mac[0] | nic_state->mac[1] << 8;
791     nic_state->eeprom.contents[8] = nic_state->mac[2] | nic_state->mac[3] << 8;
792     nic_state->eeprom.contents[9] = nic_state->mac[4] | nic_state->mac[5] << 8;
793
794     for (i = 0; i < 4; ++i) {
795         regs->tsd[i] = TSD_Own;
796     }
797
798     rtl8139_reset_rxbuf(nic_state, 1024*8);
799
800     /* ACK the reset */
801     regs->tcr = 0;
802
803     regs->tcr |= ((0x1d << 26) | (0x1 << 22)); // RTL-8139D
804     regs->rerid = RTL8139_PCI_REVID_8139;
805
806     regs->cmd = CMD_Rst; //RxBufEmpty bit is calculated on read from ChipCmd 
807
808     regs->config[0] = 0x0 | (1 << 4); // No boot ROM 
809     regs->config[1] = 0xC; //IO mapped and MEM mapped registers available
810     //regs->config[1] = 0x4; //Only IO mapped registers available
811     regs->config3[0] = 0x1; // fast back-to-back compatible
812     regs->config3[1] = 0x0;
813     regs->config5 = 0x0;
814         
815     regs->cscr = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD;
816
817     //0x3100 : 100Mbps, full duplex, autonegotiation.  0x2100 : 100Mbps, full duplex
818     regs->bmcr = 0x1000; // autonegotiation
819
820     regs->bmsr  = 0x7809;
821     regs->bmsr |= 0x0020; // autonegotiation completed
822     regs->bmsr |= 0x0004; // link is up
823
824     regs->anar = 0x05e1;     // all modes, full duplex
825     regs->anlpar = 0x05e1;   // all modes, full duplex
826     regs->aner = 0x0001;     // autonegotiation supported
827
828     // reset timer and disable timer interrupt
829     regs->tctr = 0;
830     regs->timer_int = 0;
831 }
832
833
834
835 static void rtl8139_9346cr_write(struct rtl8139_state * nic_state, uint32_t val) {
836     val &= 0xff;
837
838     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: 9346CR write val=0x%02x\n", val);
839
840     /* mask unwriteable bits */
841     val = SET_MASKED(val, 0x31, nic_state->regs.cmd9346);
842
843     uint32_t opmode = val & 0xc0;
844     uint32_t eeprom_val = val & 0xf;
845
846     if (opmode == 0x80) {
847         /* eeprom access */
848         int eecs = (eeprom_val & 0x08)?1:0;
849         int eesk = (eeprom_val & 0x04)?1:0;
850         int eedi = (eeprom_val & 0x02)?1:0;
851         prom9346_set_wire(nic_state, eecs, eesk, eedi);
852     } else if (opmode == 0x40) {
853         /* Reset.  */
854         val = 0;
855         rtl8139_reset(nic_state);
856     }
857
858     nic_state->regs.cmd9346 = val;
859 }
860
861 static uint32_t rtl8139_9346cr_read(struct rtl8139_state * nic_state) {
862     uint32_t ret = nic_state->regs.cmd9346;
863     uint32_t opmode = ret & 0xc0;
864
865     if (opmode == 0x80) {
866         /* eeprom access */
867         int eedo = prom9346_get_wire(nic_state);
868         if (eedo){
869             ret |=  0x01;
870         } else {
871             ret &= ~0x01;
872         }
873     }
874
875     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: 9346CR read val=0x%02x\n", ret);
876
877     return ret;
878 }
879
880
881 static inline int rtl8139_receiver_enabled(struct rtl8139_state * nic_state) {
882     return nic_state->regs.cmd & CMD_Re;
883 }
884
885 static inline int rtl8139_rxwrap(struct rtl8139_state * nic_state) {
886     // wrapping enabled; assume 1.5k more buffer space if size < 64K
887     return (nic_state->regs.rcr & (1 << 7));
888 }
889
890 static void rtl8139_rxbuf_write(struct rtl8139_state * nic_state, 
891                                 const void * buf, 
892                                 int size) {
893     struct rtl8139_regs *regs = &(nic_state->regs);
894     int wrap;
895     addr_t guestpa, host_rxbuf;
896
897     guestpa = (addr_t)regs->rbstart;
898     if (v3_gpa_to_hva(&(nic_state->vm->cores[0]), guestpa, &host_rxbuf)) { 
899         PrintError(VM_NONE, VCORE_NONE, "RTL8139: cannot translate address\n");
900         return;
901     }
902
903     //wrap to the front of rx buffer
904     if (regs->cbr + size > nic_state->rx_bufsize){
905         wrap = MOD2(regs->cbr + size, nic_state->rx_bufsize);
906
907         if (wrap && !(nic_state->rx_bufsize < 64*1024 && rtl8139_rxwrap(nic_state))){
908             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: rx packet wrapped in buffer at %d\n", size-wrap);
909
910             if (size > wrap){
911                 memcpy((void *)(host_rxbuf + regs->cbr), buf, size-wrap);
912             }
913
914             // reset buffer pointer
915             regs->cbr = 0;
916
917             memcpy((void *)(host_rxbuf + regs->cbr), buf + (size-wrap), wrap);
918
919             regs->cbr = wrap;
920
921             return;
922         }
923     }
924
925     memcpy((void *)(host_rxbuf + regs->cbr), buf, size);
926
927     regs->cbr += size;
928 }
929
930 #define POLYNOMIAL 0x04c11db6
931
932 /* From FreeBSD */
933 static inline int compute_mcast_idx(const uint8_t *ep) {
934     uint32_t crc;
935     int carry, i, j;
936     uint8_t b;
937
938     crc = 0xffffffff;
939     for (i = 0; i < 6; i++) {
940         b = *ep++;
941         for (j = 0; j < 8; j++) {
942             carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
943             crc <<= 1;
944             b >>= 1;
945             if (carry){
946                 crc = ((crc ^ POLYNOMIAL) | carry);
947             }
948         }
949     }
950     return (crc >> 26);
951 }
952
953
954 static int rx_one_pkt(struct rtl8139_state * nic_state, 
955                       uint8_t * pkt, 
956                       uint32_t len){
957     struct rtl8139_regs *regs = &(nic_state->regs);
958     uint_t rxbufsize = nic_state->rx_bufsize;
959     uint32_t header, val;
960     uint8_t bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
961
962     header = 0;
963
964     if (regs->rcr & AcceptAllPhys) {
965         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: packet received in promiscuous mode\n");
966     } else {
967         if (!memcmp(pkt,  bcast_addr, 6)) {
968             if (!(regs->rcr & AcceptBroadcast)){
969                 PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: broadcast packet rejected\n");
970                 return -1;
971             }
972             header |= Rx_Broadcast;
973             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: broadcast packet received\n");
974         } else if (pkt[0] & 0x01) {
975             // multicast
976             if (!(regs->rcr & AcceptMulticast)){
977                 PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: multicast packet rejected\n");
978                 return -1;
979             }
980
981             int mcast_idx = compute_mcast_idx(pkt);
982
983             if (!(regs->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))){
984                 PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: multicast address mismatch\n");
985                 return -1;
986             }
987             header |= Rx_Multicast;
988             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: multicast packet received\n");
989         } else if (!compare_ethaddr(regs->id, pkt)){
990             if (!(regs->rcr & AcceptMyPhys)){
991                 PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: rejecting physical address matching packet\n");
992                 return -1;
993             }
994
995             header |= Rx_Physical;
996             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: physical address matching packet received\n");
997         } else {
998             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: unknown packet\n");
999             return -1;
1000         }
1001     }
1002
1003     if(1){
1004         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: in ring Rx mode\n");
1005
1006         int avail = MOD2(rxbufsize + regs->capr - regs->cbr, rxbufsize);
1007
1008         if (avail != 0 && len + 8 >= avail){
1009             PrintError(VM_NONE, VCORE_NONE, "rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",
1010                    rxbufsize, regs->cbr, regs->capr, avail, len + 8);
1011
1012             regs->isr |= ISR_Rxovw;
1013             ++ regs->mpc;
1014             rtl8139_update_irq(nic_state);
1015             return -1;
1016         }
1017
1018         header |= Rx_OK;
1019         header |= ((len << 16) & 0xffff0000);
1020
1021         rtl8139_rxbuf_write(nic_state, (uint8_t *)&header, 4);
1022
1023         rtl8139_rxbuf_write(nic_state, pkt, len);
1024
1025         /* CRC checksum */
1026         val = v3_crc32(0, pkt, len);
1027
1028         rtl8139_rxbuf_write(nic_state, (uint8_t *)&val, 4);
1029
1030         // correct buffer write pointer 
1031         regs->cbr = MOD2((regs->cbr + 3) & ~0x3, rxbufsize);
1032
1033         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: received: rx buffer length %d CBR: 0x%04x CAPR: 0x%04x\n",
1034                         rxbufsize, regs->cbr, regs->capr);
1035     }
1036
1037     regs->isr |= ISR_Rok;
1038
1039     nic_state->statistic.rx_pkts ++;
1040     nic_state->statistic.rx_bytes += len;
1041         
1042     rtl8139_update_irq(nic_state);   
1043
1044     return 0;
1045 }
1046
1047 static int rtl8139_rx(uint8_t * pkt, uint32_t len, void * private_data) {
1048     struct rtl8139_state *nic_state = (struct rtl8139_state *)private_data;
1049
1050     if (!rtl8139_receiver_enabled(nic_state)){
1051         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: receiver disabled\n");
1052         nic_state->statistic.rx_dropped ++;
1053                 
1054         return 0;
1055     }
1056         
1057     if(rx_one_pkt(nic_state, pkt, len) >= 0){
1058         nic_state->statistic.rx_pkts ++;
1059         nic_state->statistic.rx_bytes += len;
1060     }else {
1061         nic_state->statistic.rx_dropped ++;
1062     }
1063
1064     return 0;
1065 }
1066
1067 static void rtl8139_rcr_write(struct rtl8139_state * nic_state, uint32_t val) {
1068     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: RCR write val=0x%08x\n", val);
1069
1070     val = SET_MASKED(val, 0xf0fc0040, nic_state->regs.rcr);
1071     nic_state->regs.rcr = val;
1072
1073 #if 0
1074     uchar_t rblen = (regs->rcr >> 11) & 0x3;
1075     switch(rblen) {
1076         case 0x0:
1077             rxbufsize = 1024 * 8 + 16;
1078             break;
1079         case 0x1:
1080             rxbufsize = 1024 * 16 + 16;
1081             break;
1082         case 0x2:
1083             rxbufsize = 1024 * 32 + 16;
1084             break;
1085         default:
1086             rxbufsize = 1024 * 64 + 16;
1087             break;
1088     }
1089 #endif
1090
1091     // reset buffer size and read/write pointers
1092     rtl8139_reset_rxbuf(nic_state, 8192 << ((nic_state->regs.rcr >> 11) & 0x3));
1093
1094     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: RCR write reset buffer size to %d\n", nic_state->rx_bufsize);
1095 }
1096
1097
1098 #if 0
1099
1100 static int rtl8139_config_writeable(struct vm_device *dev)
1101 {
1102     struct nic_context *nic_state = (struct nic_context *)(dev->private_data);
1103         
1104     if (nic_state->regs.cmd9346 & CMD9346_Unlock)
1105     {
1106         return 1;
1107     }
1108
1109     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: Configuration registers are unwriteable\n");
1110
1111     return 0;
1112 }
1113
1114 #endif
1115
1116 static inline int transmitter_enabled(struct rtl8139_state * nic_state){
1117     return nic_state->regs.cmd & CMD_Te;
1118 }
1119
1120 static int rxbufempty(struct rtl8139_state * nic_state){
1121     struct rtl8139_regs *regs = &(nic_state->regs);
1122     int unread;
1123
1124     unread = MOD2(regs->cbr + nic_state->rx_bufsize - regs->capr, nic_state->rx_bufsize);
1125    
1126     if (unread != 0){
1127         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: receiver buffer data available 0x%04x\n", unread);
1128         return 0;
1129     }
1130
1131     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: receiver buffer is empty\n");
1132
1133     return 1;
1134 }
1135
1136 static void rtl8139_cmd_write(struct rtl8139_state * nic_state, uint32_t val){
1137     val &= 0xff;
1138
1139     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: Cmd write val=0x%08x\n", val);
1140
1141     if (val & CMD_Rst){
1142         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: Cmd reset\n");
1143         rtl8139_reset(nic_state);
1144     }
1145     if (val & CMD_Re){
1146         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: Cmd enable receiver\n");
1147     }
1148     if (val & CMD_Te){
1149         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: Cmd enable transmitter\n");
1150     }
1151
1152     val = SET_MASKED(val, 0xe3, nic_state->regs.cmd);
1153     val &= ~CMD_Rst;
1154
1155     nic_state->regs.cmd = val;
1156 }
1157
1158 static int tx_one_packet(struct rtl8139_state * nic_state, int descriptor){
1159     struct rtl8139_regs *regs = &(nic_state->regs);
1160     int txsize;
1161     uint8_t *pkt;
1162     addr_t pkt_gpa = 0, hostva = 0;
1163
1164     if (!transmitter_enabled(nic_state)){
1165         PrintError(VM_NONE, VCORE_NONE, "RTL8139: fail to send from descriptor %d: transmitter disabled\n", descriptor);
1166         return 0;
1167     }
1168
1169     if (regs->tsd[descriptor] & TSD_Own){
1170         PrintError(VM_NONE, VCORE_NONE, "RTL8139: fail to send from descriptor %d: owned by host\n", descriptor);
1171         return 0;
1172     }
1173
1174     txsize = regs->tsd[descriptor] & 0x1fff;
1175     pkt_gpa = (addr_t) regs->tsad[descriptor];
1176
1177     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: sending %d bytes from guest memory at 0x%08x\n", txsize, regs->tsad[descriptor]);
1178         
1179     if (v3_gpa_to_hva(&(nic_state->vm->cores[0]), (addr_t)pkt_gpa, &hostva)) {      
1180         PrintError(VM_NONE, VCORE_NONE, "RTL8139: Cannot translate address\n");
1181         return -1;
1182     }
1183
1184     pkt = (uchar_t *)hostva;
1185
1186 #ifdef V3_CONFIG_DEBUG_RTL8139
1187     v3_hexdump(pkt, txsize, NULL, 0);
1188 #endif
1189
1190     if (TxLoopBack == (regs->tcr & TxLoopBack)){ /* loopback test */
1191         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: transmit loopback mode\n");
1192         rx_one_pkt(nic_state, pkt, txsize);
1193     } else{       
1194         if (nic_state->net_ops->send(pkt, txsize, nic_state->backend_data) == 0){
1195             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: Sent %d bytes from descriptor %d\n", txsize, descriptor);
1196             nic_state->statistic.tx_pkts ++;
1197             nic_state->statistic.tx_bytes += txsize;
1198         } else {
1199             PrintError(VM_NONE, VCORE_NONE, "Rtl8139: Sending packet error: 0x%p\n", pkt);
1200             nic_state->statistic.tx_dropped ++;
1201         }
1202     }
1203
1204     regs->tsd[descriptor] |= TSD_Tok;
1205     regs->tsd[descriptor] |= TSD_Own;
1206
1207     nic_state->regs.isr |= ISR_Tok;
1208     rtl8139_update_irq(nic_state);
1209
1210     return 0;
1211 }
1212
1213 /*transmit status registers*/
1214 static void rtl8139_tsd_write(struct rtl8139_state * nic_state, 
1215                               uint8_t descriptor, 
1216                               uint32_t val){ 
1217     if (!transmitter_enabled(nic_state)){
1218         PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: TxStatus write val=0x%08x descriptor=%d, Transmitter not enabled\n", val, descriptor);
1219                 
1220         return;
1221     }
1222
1223     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: TSD write val=0x%08x descriptor=%d\n", val, descriptor);
1224
1225     // mask read-only bits
1226     val &= ~0xff00c000;
1227     val = SET_MASKED(val, 0x00c00000,  nic_state->regs.tsd[descriptor]);
1228
1229     nic_state->regs.tsd[descriptor] = val;
1230
1231     tx_one_packet(nic_state, descriptor);
1232 }
1233
1234 /* transmit status of all descriptors */
1235 static uint16_t rtl8139_txsad_read(struct rtl8139_state * nic_state){
1236     uint16_t ret = 0;
1237     struct rtl8139_regs *regs = &(nic_state->regs);
1238
1239     ret = ((regs->tsd[3] & TSD_Tok)?TSAD_TOK3:0)
1240          |((regs->tsd[2] & TSD_Tok)?TSAD_TOK2:0)
1241          |((regs->tsd[1] & TSD_Tok)?TSAD_TOK1:0)
1242          |((regs->tsd[0] & TSD_Tok)?TSAD_TOK0:0)
1243
1244          |((regs->tsd[3] & TSD_Tun)?TSAD_TUN3:0)
1245          |((regs->tsd[2] & TSD_Tun)?TSAD_TUN2:0)
1246          |((regs->tsd[1] & TSD_Tun)?TSAD_TUN1:0)
1247          |((regs->tsd[0] & TSD_Tun)?TSAD_TUN0:0)
1248
1249          |((regs->tsd[3] & TSD_Tabt)?TSAD_TABT3:0)
1250          |((regs->tsd[2] & TSD_Tabt)?TSAD_TABT2:0)
1251          |((regs->tsd[1] & TSD_Tabt)?TSAD_TABT1:0)
1252          |((regs->tsd[0] & TSD_Tabt)?TSAD_TABT0:0)
1253
1254          |((regs->tsd[3] & TSD_Own)?TSAD_OWN3:0)
1255          |((regs->tsd[2] & TSD_Own)?TSAD_OWN2:0)
1256          |((regs->tsd[1] & TSD_Own)?TSAD_OWN1:0)
1257          |((regs->tsd[0] & TSD_Own)?TSAD_OWN0:0) ;
1258
1259     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: txsad read val=0x%04x\n", (int)ret);
1260
1261     return ret;
1262 }
1263
1264 static inline void rtl8139_isr_write(struct rtl8139_state * nic_state, uint32_t val) {
1265     struct rtl8139_regs *regs = &(nic_state->regs);
1266
1267     PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: ISR write val=0x%04x\n", val);
1268
1269     uint16_t newisr = regs->isr & ~val;
1270
1271     /* mask unwriteable bits */
1272     newisr = SET_MASKED(newisr, 0x1e00, regs->isr);
1273
1274     /* writing 1 to interrupt status register bit clears it */
1275     regs->isr = 0;
1276     rtl8139_update_irq(nic_state);
1277
1278     regs->isr = newisr;
1279     rtl8139_update_irq(nic_state);
1280 }
1281
1282 static int rtl8139_mmio_write(struct guest_info * core, 
1283                               addr_t guest_addr, 
1284                               void * src,
1285                               uint_t length, 
1286                               void * priv_data) {
1287     int idx;
1288     uint32_t val;
1289     struct rtl8139_state *nic_state = (struct rtl8139_state *)(priv_data);
1290
1291     idx = guest_addr & 0xff;
1292
1293     memcpy(&val, src, length);
1294
1295     PrintDebug(VM_NONE, VCORE_NONE, "rtl8139 mmio write: addr:0x%x (%u bytes): 0x%x\n", (int)guest_addr, length, val);
1296         
1297     switch(idx) {
1298         case RTL8139_IDR0 ... RTL8139_IDR0 + 5:
1299             nic_state->regs.id[idx - RTL8139_IDR0] = val & 0xff;
1300             break;
1301
1302         case RTL8139_MAR0 ... RTL8139_MAR0 + 7:
1303             nic_state->regs.mult[idx - RTL8139_MAR0] = val & 0xff;
1304             break;
1305
1306         case RTL8139_TSD0:
1307         case RTL8139_TSD1:
1308         case RTL8139_TSD2:
1309         case RTL8139_TSD3:
1310             rtl8139_tsd_write(nic_state, (idx - RTL8139_TSD0)/4, val);
1311             break;
1312                 
1313         case RTL8139_TSAD0:
1314         case RTL8139_TSAD1:
1315         case RTL8139_TSAD2:
1316         case RTL8139_TSAD3:
1317             nic_state->regs.tsad[(idx - RTL8139_TSAD0)/4] = val;
1318             break;
1319                 
1320         case RTL8139_RBSTART:
1321             nic_state->regs.rbstart = val;
1322             break;
1323         case RTL8139_ERBCR:
1324             nic_state->regs.erbcr = val & 0xffff;
1325             break;
1326         case RTL8139_ERSR:
1327             //nic_state->regs.ersr = val & 0xff;
1328             nic_state->regs.ersr &= (~val) & 0x0c;
1329             break;
1330         case RTL8139_CR:
1331             rtl8139_cmd_write(nic_state, val);
1332             break;
1333         case RTL8139_CAPR:
1334         {
1335             val &= 0xffff;
1336             /* this value is off by 16 */
1337             nic_state->regs.capr = MOD2(val + 0x10, nic_state->rx_bufsize);
1338
1339             PrintDebug(VM_NONE, VCORE_NONE, "RTL 8139: CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
1340             nic_state->rx_bufsize, nic_state->regs.cbr, nic_state->regs.capr);  
1341         }
1342             break;
1343         case RTL8139_CBR: /* read only */
1344             //nic_state->regs.cbr = val & 0xffff;
1345             break;
1346         case RTL8139_IMR:
1347         {
1348             PrintDebug(VM_NONE, VCORE_NONE, "RTL8139: IMR write val=0x%04x\n", val);
1349
1350             /* mask unwriteable bits */
1351             val = SET_MASKED(val, 0x1e00, nic_state->regs.imr);
1352             nic_state->regs.imr = val;
1353             rtl8139_update_irq(nic_state);
1354         }
1355             break;
1356         case RTL8139_ISR:
1357             rtl8139_isr_write(nic_state, val);
1358             break;
1359         case RTL8139_TCR:
1360             nic_state->regs.tcr = val;
1361             break;
1362         case RTL8139_RCR:
1363             rtl8139_rcr_write(nic_state, val);
1364             break;
1365         case RTL8139_TCTR:
1366             nic_state->regs.tctr = 0; /* write clear current tick */
1367             break;
1368         case RTL8139_MPC:
1369             nic_state->regs.mpc = 0; /* clear on write */
1370             break;
1371         case RTL8139_9346CR:
1372             rtl8139_9346cr_write(nic_state, val);
1373             break;
1374         case RTL8139_CONFIG0:
1375             nic_state->regs.config[0] = val & 0xff;
1376             break;
1377         case RTL8139_CONFIG1:
1378             nic_state->regs.config[1] = val & 0xff;
1379             break;
1380         case RTL8139_TimerInt:
1381             nic_state->regs.timer_int = val;
1382             break;
1383         case RTL8139_MSR:
1384             nic_state->regs.msr = val & 0xff;
1385             break;
1386         case RTL8139_CONFIG3:
1387             nic_state->regs.config3[0] = val & 0xff;
1388             break;
1389         case RTL8139_CONFIG4:
1390             nic_state->regs.config3[1] = val & 0xff;
1391             break;
1392                 
1393         case RTL8139_MULINT:
1394             nic_state->regs.mulint = val & 0xffff;
1395             break;
1396         case RTL8139_RERID:
1397             nic_state->regs.rerid = val & 0xffff;
1398             break;
1399         case RTL8139_TXSAD:
1400             nic_state->regs.txsad = val & 0xffff;
1401             break;
1402         case RTL8139_BMCR:
1403             nic_state->regs.bmcr = val & 0xffff;
1404             break;
1405         case RTL8139_BMSR:
1406             nic_state->regs.bmsr = val & 0xffff;
1407             break;
1408         case RTL8139_ANAR:
1409             nic_state->regs.anar = val & 0xffff;
1410             break;
1411         case RTL8139_ANLPAR:
1412             nic_state->regs.anlpar = val & 0xffff;
1413             break;
1414         case RTL8139_ANER:
1415             nic_state->regs.aner = val & 0xffff;
1416             break;
1417         case RTL8139_DIS:
1418             nic_state->regs.dis = val & 0xffff;
1419             break;
1420         case RTL8139_FCSC:
1421             nic_state->regs.fcsc = val & 0xffff;
1422             break;
1423         case RTL8139_NWAYTR:
1424             nic_state->regs.nwaytr = val & 0xffff;
1425             break;
1426         case RTL8139_REC:
1427             nic_state->regs.rec = val & 0xffff;
1428             break;
1429
1430         case RTL8139_CSCR:
1431             nic_state->regs.cscr = val;
1432             break;
1433         case RTL8139_PHY1_PARM:
1434             nic_state->regs.phy1_parm = val;
1435             break;
1436         case RTL8139_TW_PARM:
1437             nic_state->regs.tw_parm = val & 0xffff;
1438             break;
1439         case RTL8139_PHY2_PARM:
1440             nic_state->regs.phy2_parm = val;
1441             break;
1442         case RTL8139_CRC0 ... RTL8139_CRC0 + 7:
1443             nic_state->regs.crc[idx - RTL8139_CRC0] = val & 0xff;
1444             break;
1445
1446         case RTL8139_Config5:
1447             nic_state->regs.config5 = val & 0xff;
1448             break;
1449         default:
1450             PrintDebug(VM_NONE, VCORE_NONE, "rtl8139 write error: invalid port: 0x%x\n", idx);
1451         }
1452         
1453     return length;
1454 }
1455
1456 static int rtl8139_mmio_read(struct guest_info * core, 
1457                              addr_t guest_addr, 
1458                              void * dst, 
1459                              uint_t length, 
1460                              void * priv_data) {
1461     uint16_t idx;
1462     uint32_t val;
1463     struct rtl8139_state *nic_state = (struct rtl8139_state *)priv_data;
1464
1465     idx = guest_addr & 0xff;
1466
1467     switch(idx) {
1468         case RTL8139_IDR0 ... RTL8139_IDR0 + 5:
1469             val = nic_state->regs.id[idx - RTL8139_IDR0];
1470             break;
1471                 
1472         case RTL8139_MAR0 ... RTL8139_MAR0 + 7:
1473             val = nic_state->regs.mult[idx - RTL8139_MAR0];
1474             break;
1475
1476         case RTL8139_TSD0:
1477         case RTL8139_TSD1:
1478         case RTL8139_TSD2:
1479         case RTL8139_TSD3:
1480             val = nic_state->regs.tsd[(idx - RTL8139_TSD0)/4];
1481             break;
1482
1483         case RTL8139_TSAD0:
1484         case RTL8139_TSAD1:
1485         case RTL8139_TSAD2:
1486         case RTL8139_TSAD3:
1487             val = nic_state->regs.tsad[(idx - RTL8139_TSAD0)/4];
1488             break;
1489
1490         case RTL8139_RBSTART:
1491             val = nic_state->regs.rbstart;
1492             break;
1493         case RTL8139_ERBCR:
1494             val = nic_state->regs.erbcr;
1495             break;
1496         case RTL8139_ERSR:
1497             val = nic_state->regs.ersr;
1498             break;
1499         case RTL8139_CR:
1500         {
1501             val = nic_state->regs.cmd;
1502             if (rxbufempty(nic_state)){
1503                 val |= CMD_Bufe;
1504             }
1505         }
1506             break;
1507         case RTL8139_CAPR:
1508             /* this value is off by 16 -- don't know why - Lei*/
1509             val = nic_state->regs.capr - 0x10;
1510             break;
1511         case RTL8139_CBR:
1512             val = nic_state->regs.cbr;
1513             break;
1514         case RTL8139_IMR:
1515             val = nic_state->regs.imr;
1516             break;
1517         case RTL8139_ISR:
1518             val = (uint32_t)nic_state->regs.isr;
1519             break;
1520         case RTL8139_TCR:
1521             val = nic_state->regs.tcr;
1522             break;
1523         case RTL8139_RCR:
1524             val = nic_state->regs.rcr;
1525             break;
1526         case RTL8139_TCTR:
1527             val = nic_state->regs.tctr;
1528             break;
1529         case RTL8139_MPC:
1530             val = nic_state->regs.mpc;
1531             break;
1532         case RTL8139_9346CR:
1533             val = rtl8139_9346cr_read(nic_state);
1534             break;
1535         case RTL8139_CONFIG0:
1536             val = nic_state->regs.config[0];
1537             break;
1538         case RTL8139_CONFIG1:
1539             val = nic_state->regs.config[1];
1540             break;
1541         case RTL8139_TimerInt:
1542             val = nic_state->regs.timer_int;
1543             break;
1544         case RTL8139_MSR:
1545             val = nic_state->regs.msr;
1546             break;
1547         case RTL8139_CONFIG3:
1548             val = nic_state->regs.config3[0];
1549             break;
1550         case RTL8139_CONFIG4:
1551             val = nic_state->regs.config3[1];
1552             break;
1553         case RTL8139_MULINT:
1554             val = nic_state->regs.mulint;
1555             break;
1556         case RTL8139_RERID:
1557             val = nic_state->regs.rerid;
1558             break;
1559         case RTL8139_TXSAD: 
1560             val = rtl8139_txsad_read(nic_state);
1561             break;
1562         case RTL8139_BMCR:
1563             val = nic_state->regs.bmcr;
1564             break;
1565         case RTL8139_BMSR:
1566             val = nic_state->regs.bmsr;
1567             break;
1568         case RTL8139_ANAR:
1569             val = nic_state->regs.anar;
1570             break;
1571         case RTL8139_ANLPAR:
1572             val = nic_state->regs.anlpar;
1573             break;
1574         case RTL8139_ANER:
1575             val = nic_state->regs.aner;
1576             break;
1577         case RTL8139_DIS:
1578             val = nic_state->regs.dis;
1579             break;
1580         case RTL8139_FCSC:
1581             val = nic_state->regs.fcsc;
1582             break;
1583         case RTL8139_NWAYTR:
1584             val = nic_state->regs.nwaytr;
1585             break;
1586         case RTL8139_REC:
1587             val = nic_state->regs.rec;
1588             break;
1589         case RTL8139_CSCR:
1590             val = nic_state->regs.cscr;
1591             break;
1592         case RTL8139_PHY1_PARM:
1593             val = nic_state->regs.phy1_parm;
1594             break;
1595         case RTL8139_TW_PARM:
1596             val = nic_state->regs.tw_parm;
1597             break;
1598         case RTL8139_PHY2_PARM:
1599             val = nic_state->regs.phy2_parm;
1600             break;
1601         case RTL8139_CRC0 ... RTL8139_CRC0 + 7:
1602             val = nic_state->regs.crc[idx - RTL8139_CRC0];
1603             break;
1604         case RTL8139_Config5:
1605             val = nic_state->regs.config5;
1606             break;
1607         default:
1608             val = 0x0;
1609             break;
1610     }
1611
1612     memcpy(dst, &val, length);
1613         
1614     PrintDebug(VM_NONE, VCORE_NONE, "rtl8139 mmio read: port:0x%x (%u bytes): 0x%x\n", (int)guest_addr, length, val);
1615
1616     return length;
1617 }
1618
1619
1620 static int rtl8139_ioport_write(struct guest_info * core,
1621                                 uint16_t port, 
1622                                 void *src, 
1623                                 uint_t length, 
1624                                 void * private_data) {
1625     return rtl8139_mmio_write(core, (addr_t)port, 
1626                               src, length, private_data);
1627 }
1628
1629 static int rtl8139_ioport_read(struct guest_info * core, 
1630                                uint16_t port, 
1631                                void *dst, 
1632                                uint_t length, 
1633                                void * private_data) {
1634     return rtl8139_mmio_read(core, (addr_t)port, 
1635                              dst, length, private_data);
1636 }
1637
1638
1639 static int rtl8139_init_state(struct rtl8139_state *nic_state) {
1640     PrintDebug(VM_NONE, VCORE_NONE, "rtl8139: init_state\n");
1641         
1642     nic_state->regs.tsd[0] = nic_state->regs.tsd[1] = nic_state->regs.tsd[2] = nic_state->regs.tsd[3] = TSD_Own;
1643
1644     nic_state->regs.rerid = RTL8139_PCI_REVID_8139;
1645     nic_state->regs.tcr |= ((0x1d << 26) | (0x1 << 22));
1646
1647     rtl8139_reset(nic_state);
1648
1649     return 0;
1650 }
1651
1652
1653 #if 0
1654 static inline int rtl8139_reset_device(struct rtl8139_state * nic_state) {
1655     nic_state->regs.cmd |= CMD_Rst;
1656     rtl8139_init_state(nic_state);
1657     nic_state->regs.cmd &= ~CMD_Rst;
1658         
1659     return 0;
1660 }
1661
1662 static inline int rtl8139_start_device(struct rtl8139_state * nic_state) {
1663     nic_state->regs.cmd |= CMD_Re | CMD_Te;
1664         
1665     return 0;
1666 }
1667
1668 static int rtl8139_stop_device(struct rtl8139_state * nic_state) {
1669     PrintDebug(VM_NONE, VCORE_NONE, "rtl8139: stop device\n");
1670
1671     nic_state->regs.cmd &= ~(CMD_Re | CMD_Te);
1672         
1673     return 0;
1674 }
1675
1676 static int rtl8139_hook_iospace(struct rtl8139_state * nic_state, 
1677                                 addr_t base_addr, 
1678                                 int size, 
1679                                 int type, 
1680                                 void *data) {
1681     int i;
1682
1683     if (base_addr <= 0){
1684         PrintError(VM_NONE, VCORE_NONE, "In RTL8139: Fail to Hook IO Space, base address 0x%x\n", (int) base_addr);
1685         return -1;
1686     }
1687
1688     if (type == PCI_BAR_IO){
1689         PrintDebug(VM_NONE, VCORE_NONE, "In RTL8139: Hook IO ports starting from %x, size %d\n", (int) base_addr, size);
1690
1691         for (i = 0; i < 0xff; i++){     
1692             v3_dev_hook_io(nic_state->dev, base_addr + i, &rtl8139_ioport_read, &rtl8139_ioport_write);
1693         }
1694     } else if (type == PCI_BAR_MEM32) {
1695         PrintDebug(VM_NONE, VCORE_NONE, "In RTL8139: Hook memory space starting from %x, size %d\n", (int) base_addr, size);
1696         
1697         //hook memory mapped I/O        
1698         v3_hook_full_mem(nic_state->vm, nic_state->vm->cores[0].cpu_id, base_addr, base_addr + 0xff,
1699                                      &rtl8139_mmio_read, &rtl8139_mmio_write, nic_state);
1700     } else {
1701        PrintError(VM_NONE, VCORE_NONE, "In RTL8139: unknown memory type: start %x, size %d\n", (int) base_addr, size);
1702     }
1703         
1704     return 0;
1705 }
1706 #endif
1707
1708 static int register_dev(struct rtl8139_state * nic_state)  {
1709     int i;
1710
1711     if (nic_state->pci_bus == NULL) {
1712         PrintError(VM_NONE, VCORE_NONE, "RTL8139: Not attached to any PCI bus\n");
1713
1714         return -1;
1715     }
1716
1717     struct v3_pci_bar bars[6];
1718     struct pci_device * pci_dev = NULL;
1719
1720     for (i = 0; i < 6; i++) {
1721         bars[i].type = PCI_BAR_NONE;
1722     }
1723
1724     bars[0].type = PCI_BAR_IO;
1725     bars[0].default_base_port = -1;
1726     bars[0].num_ports = 0x100;
1727
1728     bars[0].io_read = rtl8139_ioport_read;
1729     bars[0].io_write = rtl8139_ioport_write;
1730     bars[0].private_data = nic_state;
1731
1732 /*
1733     bars[1].type = PCI_BAR_MEM32;
1734     bars[1].default_base_addr = -1;
1735     bars[1].num_pages = 1;
1736
1737     bars[1].mem_read = rtl8139_mmio_read;
1738     bars[1].mem_write = rtl8139_mmio_write;
1739     bars[1].private_data = nic_state;
1740 */
1741
1742     pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0, 
1743                                          "RTL8139", bars,
1744                                      NULL, NULL, NULL, NULL, nic_state);
1745
1746
1747     if (pci_dev == NULL) {
1748         PrintError(VM_NONE, VCORE_NONE, "RTL8139: Could not register PCI Device\n");
1749         return -1;
1750     }
1751         
1752     pci_dev->config_header.vendor_id = 0x10ec;
1753     pci_dev->config_header.device_id = 0x8139;
1754     pci_dev->config_header.command = 0x05;
1755         
1756     pci_dev->config_header.revision = RTL8139_PCI_REVID_8139;
1757
1758     pci_dev->config_header.subclass = 0x00;
1759     pci_dev->config_header.class = 0x02;
1760     pci_dev->config_header.header_type = 0x00;
1761
1762     pci_dev->config_header.intr_line = 12;
1763     pci_dev->config_header.intr_pin = 1;
1764     pci_dev->config_space[0x34] = 0xdc;
1765
1766     nic_state->pci_dev = pci_dev;
1767         
1768     return 0;
1769 }
1770
1771 static int connect_fn(struct v3_vm_info * info, 
1772                       void * frontend_data, 
1773                       struct v3_dev_net_ops * ops, 
1774                       v3_cfg_tree_t * cfg, 
1775                       void * private_data) {
1776     struct rtl8139_state * nic_state = (struct rtl8139_state *)frontend_data;
1777
1778     rtl8139_init_state(nic_state);
1779     register_dev(nic_state);
1780
1781     nic_state->net_ops = ops;
1782     nic_state->backend_data = private_data;     
1783
1784     ops->recv = rtl8139_rx;
1785     ops->poll = NULL;
1786     ops->config.frontend_data = nic_state;
1787     ops->config.fnt_mac = nic_state->mac;
1788
1789     return 0;
1790 }
1791
1792
1793 static int rtl8139_free(void * private_data) {
1794     struct rtl8139_state * nic_state = (struct rtl8139_state *)private_data;
1795
1796     /* dettached from backend */
1797
1798     /* unregistered from PCI? */
1799
1800     V3_Free(nic_state);
1801         
1802     return 0;
1803 }
1804
1805
1806 static struct v3_device_ops dev_ops = {
1807     .free = rtl8139_free,
1808 };
1809
1810
1811 static int rtl8139_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1812     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
1813     struct rtl8139_state * nic_state = NULL;
1814     char * dev_id = v3_cfg_val(cfg, "ID");
1815     char * macstr = v3_cfg_val(cfg, "mac");
1816
1817     nic_state  = (struct rtl8139_state *)V3_Malloc(sizeof(struct rtl8139_state));
1818
1819     if (!nic_state) {
1820         PrintError(vm, VCORE_NONE, "Cannot allocate in init\n");
1821         return -1;
1822     }
1823
1824     memset(nic_state, 0, sizeof(struct rtl8139_state));
1825
1826     nic_state->pci_bus = pci_bus;
1827     nic_state->vm = vm;
1828
1829     if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1830         PrintDebug(vm, VCORE_NONE, "RTL8139: Mac specified %s\n", macstr);
1831     }else {
1832         PrintDebug(vm, VCORE_NONE, "RTL8139: MAC not specified\n");
1833         random_ethaddr(nic_state->mac);
1834     }
1835
1836     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1837
1838     if (dev == NULL) {
1839         PrintError(vm, VCORE_NONE, "RTL8139: Could not attach device %s\n", dev_id);
1840         V3_Free(nic_state);
1841         return -1;
1842     }
1843
1844     nic_state->dev = dev;
1845
1846     if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)nic_state) == -1) {
1847         PrintError(vm, VCORE_NONE, "RTL8139: Could not register %s as net frontend\n", dev_id);
1848         v3_remove_device(dev);
1849         V3_Free(nic_state);
1850         return -1;
1851     }
1852             
1853     return 0;
1854 }
1855
1856 device_register("RTL8139", rtl8139_init)