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.


4ef93df8b446f528f6d7948bffb623d8de457452
[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             uint8_t rx_ok     : 1;
175             uint8_t rx_bad_align     : 1;
176             uint8_t rx_crc_err     : 1;
177             uint8_t rx_too_long     : 1;        
178             uint8_t rx_runt     : 1;
179             uint8_t rx_bad_sym  : 1;
180             uint8_t reserved    : 7;
181             uint8_t rx_brdcast  : 1;
182             uint8_t rx_phys     : 1;
183             uint8_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             uint8_t rx_ok       :1;
274             uint8_t rx_err     : 1;
275             uint8_t tx_ok        : 1;
276             uint8_t tx_err          : 1;
277             uint8_t rx_ovw          : 1;
278             uint8_t pun_linkchg          : 1;
279             uint8_t rx_fifo_ovw  : 1;
280             uint8_t reservd:     6;
281             uint8_t lenchg  :1;
282             uint8_t timeout   :1;
283             uint8_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, 0, nic_state->pci_dev);
586         nic_state->statistic.interrupts ++;
587     }
588 }
589
590 static void prom9346_decode_command(struct EEprom9346 * eeprom, uint8_t command) {
591     PrintDebug("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("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("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("RTL8139: eeprom write enabled\n");
621                     break;
622                 case Chip9346_op_write_all:
623                     PrintDebug("RTL8139: eeprom begin write all\n");
624                     break;
625                 case Chip9346_op_write_disable:
626                     PrintDebug("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("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("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("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("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("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("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("=== eeprom: begin access, enter command mode\n");
750     }
751
752     if (eecs == 0) {
753         PrintDebug("=== 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("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("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("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     v3_gpa_to_hva(&(nic_state->vm->cores[0]), guestpa, &host_rxbuf);   
899
900     //wrap to the front of rx buffer
901     if (regs->cbr + size > nic_state->rx_bufsize){
902         wrap = MOD2(regs->cbr + size, nic_state->rx_bufsize);
903
904         if (wrap && !(nic_state->rx_bufsize < 64*1024 && rtl8139_rxwrap(nic_state))){
905             PrintDebug("RTL8139: rx packet wrapped in buffer at %d\n", size-wrap);
906
907             if (size > wrap){
908                 memcpy((void *)(host_rxbuf + regs->cbr), buf, size-wrap);
909             }
910
911             // reset buffer pointer
912             regs->cbr = 0;
913
914             memcpy((void *)(host_rxbuf + regs->cbr), buf + (size-wrap), wrap);
915
916             regs->cbr = wrap;
917
918             return;
919         }
920     }
921
922     memcpy((void *)(host_rxbuf + regs->cbr), buf, size);
923
924     regs->cbr += size;
925 }
926
927 #define POLYNOMIAL 0x04c11db6
928
929 /* From FreeBSD */
930 static inline int compute_mcast_idx(const uint8_t *ep) {
931     uint32_t crc;
932     int carry, i, j;
933     uint8_t b;
934
935     crc = 0xffffffff;
936     for (i = 0; i < 6; i++) {
937         b = *ep++;
938         for (j = 0; j < 8; j++) {
939             carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
940             crc <<= 1;
941             b >>= 1;
942             if (carry){
943                 crc = ((crc ^ POLYNOMIAL) | carry);
944             }
945         }
946     }
947     return (crc >> 26);
948 }
949
950
951 static int rx_one_pkt(struct rtl8139_state * nic_state, 
952                       uint8_t * pkt, 
953                       uint32_t len){
954     struct rtl8139_regs *regs = &(nic_state->regs);
955     uint_t rxbufsize = nic_state->rx_bufsize;
956     uint32_t header, val;
957     uint8_t bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
958
959     if (regs->rcr & AcceptAllPhys) {
960         PrintDebug("RTL8139: packet received in promiscuous mode\n");
961     } else {
962         if (!memcmp(pkt,  bcast_addr, 6)) {
963             if (!(regs->rcr & AcceptBroadcast)){
964                 PrintDebug("RTL8139: broadcast packet rejected\n");
965                 return -1;
966             }
967             header |= Rx_Broadcast;
968             PrintDebug("RTL8139: broadcast packet received\n");
969         } else if (pkt[0] & 0x01) {
970             // multicast
971             if (!(regs->rcr & AcceptMulticast)){
972                 PrintDebug("RTL8139: multicast packet rejected\n");
973                 return -1;
974             }
975
976             int mcast_idx = compute_mcast_idx(pkt);
977
978             if (!(regs->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))){
979                 PrintDebug("RTL8139: multicast address mismatch\n");
980                 return -1;
981             }
982             header |= Rx_Multicast;
983             PrintDebug("RTL8139: multicast packet received\n");
984         } else if (!compare_ethaddr(regs->id, pkt)){
985             if (!(regs->rcr & AcceptMyPhys)){
986                 PrintDebug("RTL8139: rejecting physical address matching packet\n");
987                 return -1;
988             }
989
990             header |= Rx_Physical;
991             PrintDebug("RTL8139: physical address matching packet received\n");
992         } else {
993             PrintDebug("RTL8139: unknown packet\n");
994             return -1;
995         }
996     }
997
998     if(1){
999         PrintDebug("RTL8139: in ring Rx mode\n");
1000
1001         int avail = MOD2(rxbufsize + regs->capr - regs->cbr, rxbufsize);
1002
1003         if (avail != 0 && len + 8 >= avail){
1004             PrintError("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",
1005                    rxbufsize, regs->cbr, regs->capr, avail, len + 8);
1006
1007             regs->isr |= ISR_Rxovw;
1008             ++ regs->mpc;
1009             rtl8139_update_irq(nic_state);
1010             return -1;
1011         }
1012
1013         header |= Rx_OK;
1014         header |= ((len << 16) & 0xffff0000);
1015
1016         rtl8139_rxbuf_write(nic_state, (uint8_t *)&header, 4);
1017
1018         rtl8139_rxbuf_write(nic_state, pkt, len);
1019
1020         /* CRC checksum */
1021         val = v3_crc32(0, pkt, len);
1022
1023         rtl8139_rxbuf_write(nic_state, (uint8_t *)&val, 4);
1024
1025         // correct buffer write pointer 
1026         regs->cbr = MOD2((regs->cbr + 3) & ~0x3, rxbufsize);
1027
1028         PrintDebug("RTL8139: received: rx buffer length %d CBR: 0x%04x CAPR: 0x%04x\n",
1029                         rxbufsize, regs->cbr, regs->capr);
1030     }
1031
1032     regs->isr |= ISR_Rok;
1033
1034     nic_state->statistic.rx_pkts ++;
1035     nic_state->statistic.rx_bytes += len;
1036         
1037     rtl8139_update_irq(nic_state);   
1038
1039     return 0;
1040 }
1041
1042 static int rtl8139_rx(uint8_t * pkt, uint32_t len, void * private_data) {
1043     struct rtl8139_state *nic_state = (struct rtl8139_state *)private_data;
1044
1045     if (!rtl8139_receiver_enabled(nic_state)){
1046         PrintDebug("RTL8139: receiver disabled\n");
1047         nic_state->statistic.rx_dropped ++;
1048                 
1049         return 0;
1050     }
1051         
1052     if(rx_one_pkt(nic_state, pkt, len) >= 0){
1053         nic_state->statistic.rx_pkts ++;
1054         nic_state->statistic.rx_bytes += len;
1055     }else {
1056         nic_state->statistic.rx_dropped ++;
1057     }
1058
1059     return 0;
1060 }
1061
1062 static void rtl8139_rcr_write(struct rtl8139_state * nic_state, uint32_t val) {
1063     PrintDebug("RTL8139: RCR write val=0x%08x\n", val);
1064
1065     val = SET_MASKED(val, 0xf0fc0040, nic_state->regs.rcr);
1066     nic_state->regs.rcr = val;
1067
1068 #if 0
1069     uchar_t rblen = (regs->rcr >> 11) & 0x3;
1070     switch(rblen) {
1071         case 0x0:
1072             rxbufsize = 1024 * 8 + 16;
1073             break;
1074         case 0x1:
1075             rxbufsize = 1024 * 16 + 16;
1076             break;
1077         case 0x2:
1078             rxbufsize = 1024 * 32 + 16;
1079             break;
1080         default:
1081             rxbufsize = 1024 * 64 + 16;
1082             break;
1083     }
1084 #endif
1085
1086     // reset buffer size and read/write pointers
1087     rtl8139_reset_rxbuf(nic_state, 8192 << ((nic_state->regs.rcr >> 11) & 0x3));
1088
1089     PrintDebug("RTL8139: RCR write reset buffer size to %d\n", nic_state->rx_bufsize);
1090 }
1091
1092
1093 #if 0
1094
1095 static int rtl8139_config_writeable(struct vm_device *dev)
1096 {
1097     struct nic_context *nic_state = (struct nic_context *)(dev->private_data);
1098         
1099     if (nic_state->regs.cmd9346 & CMD9346_Unlock)
1100     {
1101         return 1;
1102     }
1103
1104     PrintDebug("RTL8139: Configuration registers are unwriteable\n");
1105
1106     return 0;
1107 }
1108
1109 #endif
1110
1111 static inline int transmitter_enabled(struct rtl8139_state * nic_state){
1112     return nic_state->regs.cmd & CMD_Te;
1113 }
1114
1115 static int rxbufempty(struct rtl8139_state * nic_state){
1116     struct rtl8139_regs *regs = &(nic_state->regs);
1117     int unread;
1118
1119     unread = MOD2(regs->cbr + nic_state->rx_bufsize - regs->capr, nic_state->rx_bufsize);
1120    
1121     if (unread != 0){
1122         PrintDebug("RTL8139: receiver buffer data available 0x%04x\n", unread);
1123         return 0;
1124     }
1125
1126     PrintDebug("RTL8139: receiver buffer is empty\n");
1127
1128     return 1;
1129 }
1130
1131 static void rtl8139_cmd_write(struct rtl8139_state * nic_state, uint32_t val){
1132     val &= 0xff;
1133
1134     PrintDebug("RTL8139: Cmd write val=0x%08x\n", val);
1135
1136     if (val & CMD_Rst){
1137         PrintDebug("RTL8139: Cmd reset\n");
1138         rtl8139_reset(nic_state);
1139     }
1140     if (val & CMD_Re){
1141         PrintDebug("RTL8139: Cmd enable receiver\n");
1142     }
1143     if (val & CMD_Te){
1144         PrintDebug("RTL8139: Cmd enable transmitter\n");
1145     }
1146
1147     val = SET_MASKED(val, 0xe3, nic_state->regs.cmd);
1148     val &= ~CMD_Rst;
1149
1150     nic_state->regs.cmd = val;
1151 }
1152
1153 static int tx_one_packet(struct rtl8139_state * nic_state, int descriptor){
1154     struct rtl8139_regs *regs = &(nic_state->regs);
1155     int txsize;
1156     uint8_t *pkt;
1157     addr_t pkt_gpa = 0, hostva = 0;
1158
1159     if (!transmitter_enabled(nic_state)){
1160         PrintError("RTL8139: fail to send from descriptor %d: transmitter disabled\n", descriptor);
1161         return 0;
1162     }
1163
1164     if (regs->tsd[descriptor] & TSD_Own){
1165         PrintError("RTL8139: fail to send from descriptor %d: owned by host\n", descriptor);
1166         return 0;
1167     }
1168
1169     txsize = regs->tsd[descriptor] & 0x1fff;
1170     pkt_gpa = (addr_t) regs->tsad[descriptor];
1171
1172     PrintDebug("RTL8139: sending %d bytes from guest memory at 0x%08x\n", txsize, regs->tsad[descriptor]);
1173         
1174     v3_gpa_to_hva(&(nic_state->vm->cores[0]), (addr_t)pkt_gpa, &hostva);
1175     pkt = (uchar_t *)hostva;
1176
1177 #ifdef V3_CONFIG_DEBUG_RTL8139
1178     v3_hexdump(pkt, txsize, NULL, 0);
1179 #endif
1180
1181     if (TxLoopBack == (regs->tcr & TxLoopBack)){ /* loopback test */
1182         PrintDebug(("RTL8139: transmit loopback mode\n"));
1183         rx_one_pkt(nic_state, pkt, txsize);
1184     } else{       
1185         if (nic_state->net_ops->send(pkt, txsize, nic_state->backend_data) == 0){
1186             PrintDebug("RTL8139: Sent %d bytes from descriptor %d\n", txsize, descriptor);
1187             nic_state->statistic.tx_pkts ++;
1188             nic_state->statistic.tx_bytes += txsize;
1189         } else {
1190             PrintError("Rtl8139: Sending packet error: 0x%p\n", pkt);
1191             nic_state->statistic.tx_dropped ++;
1192         }
1193     }
1194
1195     regs->tsd[descriptor] |= TSD_Tok;
1196     regs->tsd[descriptor] |= TSD_Own;
1197
1198     nic_state->regs.isr |= ISR_Tok;
1199     rtl8139_update_irq(nic_state);
1200
1201     return 0;
1202 }
1203
1204 /*transmit status registers*/
1205 static void rtl8139_tsd_write(struct rtl8139_state * nic_state, 
1206                               uint8_t descriptor, 
1207                               uint32_t val){ 
1208     if (!transmitter_enabled(nic_state)){
1209         PrintDebug("RTL8139: TxStatus write val=0x%08x descriptor=%d, Transmitter not enabled\n", val, descriptor);
1210                 
1211         return;
1212     }
1213
1214     PrintDebug("RTL8139: TSD write val=0x%08x descriptor=%d\n", val, descriptor);
1215
1216     // mask read-only bits
1217     val &= ~0xff00c000;
1218     val = SET_MASKED(val, 0x00c00000,  nic_state->regs.tsd[descriptor]);
1219
1220     nic_state->regs.tsd[descriptor] = val;
1221
1222     tx_one_packet(nic_state, descriptor);
1223 }
1224
1225 /* transmit status of all descriptors */
1226 static uint16_t rtl8139_txsad_read(struct rtl8139_state * nic_state){
1227     uint16_t ret = 0;
1228     struct rtl8139_regs *regs = &(nic_state->regs);
1229
1230     ret = ((regs->tsd[3] & TSD_Tok)?TSAD_TOK3:0)
1231          |((regs->tsd[2] & TSD_Tok)?TSAD_TOK2:0)
1232          |((regs->tsd[1] & TSD_Tok)?TSAD_TOK1:0)
1233          |((regs->tsd[0] & TSD_Tok)?TSAD_TOK0:0)
1234
1235          |((regs->tsd[3] & TSD_Tun)?TSAD_TUN3:0)
1236          |((regs->tsd[2] & TSD_Tun)?TSAD_TUN2:0)
1237          |((regs->tsd[1] & TSD_Tun)?TSAD_TUN1:0)
1238          |((regs->tsd[0] & TSD_Tun)?TSAD_TUN0:0)
1239
1240          |((regs->tsd[3] & TSD_Tabt)?TSAD_TABT3:0)
1241          |((regs->tsd[2] & TSD_Tabt)?TSAD_TABT2:0)
1242          |((regs->tsd[1] & TSD_Tabt)?TSAD_TABT1:0)
1243          |((regs->tsd[0] & TSD_Tabt)?TSAD_TABT0:0)
1244
1245          |((regs->tsd[3] & TSD_Own)?TSAD_OWN3:0)
1246          |((regs->tsd[2] & TSD_Own)?TSAD_OWN2:0)
1247          |((regs->tsd[1] & TSD_Own)?TSAD_OWN1:0)
1248          |((regs->tsd[0] & TSD_Own)?TSAD_OWN0:0) ;
1249
1250     PrintDebug("RTL8139: txsad read val=0x%04x\n", (int)ret);
1251
1252     return ret;
1253 }
1254
1255 static inline void rtl8139_isr_write(struct rtl8139_state * nic_state, uint32_t val) {
1256     struct rtl8139_regs *regs = &(nic_state->regs);
1257
1258     PrintDebug("RTL8139: ISR write val=0x%04x\n", val);
1259
1260     uint16_t newisr = regs->isr & ~val;
1261
1262     /* mask unwriteable bits */
1263     newisr = SET_MASKED(newisr, 0x1e00, regs->isr);
1264
1265     /* writing 1 to interrupt status register bit clears it */
1266     regs->isr = 0;
1267     rtl8139_update_irq(nic_state);
1268
1269     regs->isr = newisr;
1270     rtl8139_update_irq(nic_state);
1271 }
1272
1273 static int rtl8139_mmio_write(struct guest_info * core, 
1274                               addr_t guest_addr, 
1275                               void * src,
1276                               uint_t length, 
1277                               void * priv_data) {
1278     int idx;
1279     uint32_t val;
1280     struct rtl8139_state *nic_state = (struct rtl8139_state *)(priv_data);
1281
1282     idx = guest_addr & 0xff;
1283
1284     memcpy(&val, src, length);
1285
1286     PrintDebug("rtl8139 mmio write: addr:0x%x (%u bytes): 0x%x\n", (int)guest_addr, length, val);
1287         
1288     switch(idx) {
1289         case RTL8139_IDR0 ... RTL8139_IDR0 + 5:
1290             nic_state->regs.id[idx - RTL8139_IDR0] = val & 0xff;
1291             break;
1292
1293         case RTL8139_MAR0 ... RTL8139_MAR0 + 7:
1294             nic_state->regs.mult[idx - RTL8139_MAR0] = val & 0xff;
1295             break;
1296
1297         case RTL8139_TSD0:
1298         case RTL8139_TSD1:
1299         case RTL8139_TSD2:
1300         case RTL8139_TSD3:
1301             rtl8139_tsd_write(nic_state, (idx - RTL8139_TSD0)/4, val);
1302             break;
1303                 
1304         case RTL8139_TSAD0:
1305         case RTL8139_TSAD1:
1306         case RTL8139_TSAD2:
1307         case RTL8139_TSAD3:
1308             nic_state->regs.tsad[(idx - RTL8139_TSAD0)/4] = val;
1309             break;
1310                 
1311         case RTL8139_RBSTART:
1312             nic_state->regs.rbstart = val;
1313             break;
1314         case RTL8139_ERBCR:
1315             nic_state->regs.erbcr = val & 0xffff;
1316             break;
1317         case RTL8139_ERSR:
1318             //nic_state->regs.ersr = val & 0xff;
1319             nic_state->regs.ersr &= (~val) & 0x0c;
1320             break;
1321         case RTL8139_CR:
1322             rtl8139_cmd_write(nic_state, val);
1323             break;
1324         case RTL8139_CAPR:
1325         {
1326             val &= 0xffff;
1327             /* this value is off by 16 */
1328             nic_state->regs.capr = MOD2(val + 0x10, nic_state->rx_bufsize);
1329
1330             PrintDebug("RTL 8139: CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
1331             nic_state->rx_bufsize, nic_state->regs.cbr, nic_state->regs.capr);  
1332         }
1333             break;
1334         case RTL8139_CBR: /* read only */
1335             //nic_state->regs.cbr = val & 0xffff;
1336             break;
1337         case RTL8139_IMR:
1338         {
1339             PrintDebug("RTL8139: IMR write val=0x%04x\n", val);
1340
1341             /* mask unwriteable bits */
1342             val = SET_MASKED(val, 0x1e00, nic_state->regs.imr);
1343             nic_state->regs.imr = val;
1344             rtl8139_update_irq(nic_state);
1345         }
1346             break;
1347         case RTL8139_ISR:
1348             rtl8139_isr_write(nic_state, val);
1349             break;
1350         case RTL8139_TCR:
1351             nic_state->regs.tcr = val;
1352             break;
1353         case RTL8139_RCR:
1354             rtl8139_rcr_write(nic_state, val);
1355             break;
1356         case RTL8139_TCTR:
1357             nic_state->regs.tctr = 0; /* write clear current tick */
1358             break;
1359         case RTL8139_MPC:
1360             nic_state->regs.mpc = 0; /* clear on write */
1361             break;
1362         case RTL8139_9346CR:
1363             rtl8139_9346cr_write(nic_state, val);
1364             break;
1365         case RTL8139_CONFIG0:
1366             nic_state->regs.config[0] = val & 0xff;
1367             break;
1368         case RTL8139_CONFIG1:
1369             nic_state->regs.config[1] = val & 0xff;
1370             break;
1371         case RTL8139_TimerInt:
1372             nic_state->regs.timer_int = val;
1373             break;
1374         case RTL8139_MSR:
1375             nic_state->regs.msr = val & 0xff;
1376             break;
1377         case RTL8139_CONFIG3:
1378             nic_state->regs.config3[0] = val & 0xff;
1379             break;
1380         case RTL8139_CONFIG4:
1381             nic_state->regs.config3[1] = val & 0xff;
1382             break;
1383                 
1384         case RTL8139_MULINT:
1385             nic_state->regs.mulint = val & 0xffff;
1386             break;
1387         case RTL8139_RERID:
1388             nic_state->regs.rerid = val & 0xffff;
1389             break;
1390         case RTL8139_TXSAD:
1391             nic_state->regs.txsad = val & 0xffff;
1392             break;
1393         case RTL8139_BMCR:
1394             nic_state->regs.bmcr = val & 0xffff;
1395             break;
1396         case RTL8139_BMSR:
1397             nic_state->regs.bmsr = val & 0xffff;
1398             break;
1399         case RTL8139_ANAR:
1400             nic_state->regs.anar = val & 0xffff;
1401             break;
1402         case RTL8139_ANLPAR:
1403             nic_state->regs.anlpar = val & 0xffff;
1404             break;
1405         case RTL8139_ANER:
1406             nic_state->regs.aner = val & 0xffff;
1407             break;
1408         case RTL8139_DIS:
1409             nic_state->regs.dis = val & 0xffff;
1410             break;
1411         case RTL8139_FCSC:
1412             nic_state->regs.fcsc = val & 0xffff;
1413             break;
1414         case RTL8139_NWAYTR:
1415             nic_state->regs.nwaytr = val & 0xffff;
1416             break;
1417         case RTL8139_REC:
1418             nic_state->regs.rec = val & 0xffff;
1419             break;
1420
1421         case RTL8139_CSCR:
1422             nic_state->regs.cscr = val;
1423             break;
1424         case RTL8139_PHY1_PARM:
1425             nic_state->regs.phy1_parm = val;
1426             break;
1427         case RTL8139_TW_PARM:
1428             nic_state->regs.tw_parm = val & 0xffff;
1429             break;
1430         case RTL8139_PHY2_PARM:
1431             nic_state->regs.phy2_parm = val;
1432             break;
1433         case RTL8139_CRC0 ... RTL8139_CRC0 + 7:
1434             nic_state->regs.crc[idx - RTL8139_CRC0] = val & 0xff;
1435             break;
1436
1437         case RTL8139_Config5:
1438             nic_state->regs.config5 = val & 0xff;
1439             break;
1440         default:
1441             PrintDebug("rtl8139 write error: invalid port: 0x%x\n", idx);
1442         }
1443         
1444     return length;
1445 }
1446
1447 static int rtl8139_mmio_read(struct guest_info * core, 
1448                              addr_t guest_addr, 
1449                              void * dst, 
1450                              uint_t length, 
1451                              void * priv_data) {
1452     uint16_t idx;
1453     uint32_t val;
1454     struct rtl8139_state *nic_state = (struct rtl8139_state *)priv_data;
1455
1456     idx = guest_addr & 0xff;
1457
1458     switch(idx) {
1459         case RTL8139_IDR0 ... RTL8139_IDR0 + 5:
1460             val = nic_state->regs.id[idx - RTL8139_IDR0];
1461             break;
1462                 
1463         case RTL8139_MAR0 ... RTL8139_MAR0 + 7:
1464             val = nic_state->regs.mult[idx - RTL8139_MAR0];
1465             break;
1466
1467         case RTL8139_TSD0:
1468         case RTL8139_TSD1:
1469         case RTL8139_TSD2:
1470         case RTL8139_TSD3:
1471             val = nic_state->regs.tsd[(idx - RTL8139_TSD0)/4];
1472             break;
1473
1474         case RTL8139_TSAD0:
1475         case RTL8139_TSAD1:
1476         case RTL8139_TSAD2:
1477         case RTL8139_TSAD3:
1478             val = nic_state->regs.tsad[(idx - RTL8139_TSAD0)/4];
1479             break;
1480
1481         case RTL8139_RBSTART:
1482             val = nic_state->regs.rbstart;
1483             break;
1484         case RTL8139_ERBCR:
1485             val = nic_state->regs.erbcr;
1486             break;
1487         case RTL8139_ERSR:
1488             val = nic_state->regs.ersr;
1489             break;
1490         case RTL8139_CR:
1491         {
1492             val = nic_state->regs.cmd;
1493             if (rxbufempty(nic_state)){
1494                 val |= CMD_Bufe;
1495             }
1496         }
1497             break;
1498         case RTL8139_CAPR:
1499             /* this value is off by 16 -- don't know why - Lei*/
1500             val = nic_state->regs.capr - 0x10;
1501             break;
1502         case RTL8139_CBR:
1503             val = nic_state->regs.cbr;
1504             break;
1505         case RTL8139_IMR:
1506             val = nic_state->regs.imr;
1507             break;
1508         case RTL8139_ISR:
1509             val = (uint32_t)nic_state->regs.isr;
1510             break;
1511         case RTL8139_TCR:
1512             val = nic_state->regs.tcr;
1513             break;
1514         case RTL8139_RCR:
1515             val = nic_state->regs.rcr;
1516             break;
1517         case RTL8139_TCTR:
1518             val = nic_state->regs.tctr;
1519             break;
1520         case RTL8139_MPC:
1521             val = nic_state->regs.mpc;
1522             break;
1523         case RTL8139_9346CR:
1524             val = rtl8139_9346cr_read(nic_state);
1525             break;
1526         case RTL8139_CONFIG0:
1527             val = nic_state->regs.config[0];
1528             break;
1529         case RTL8139_CONFIG1:
1530             val = nic_state->regs.config[1];
1531             break;
1532         case RTL8139_TimerInt:
1533             val = nic_state->regs.timer_int;
1534             break;
1535         case RTL8139_MSR:
1536             val = nic_state->regs.msr;
1537             break;
1538         case RTL8139_CONFIG3:
1539             val = nic_state->regs.config3[0];
1540             break;
1541         case RTL8139_CONFIG4:
1542             val = nic_state->regs.config3[1];
1543             break;
1544         case RTL8139_MULINT:
1545             val = nic_state->regs.mulint;
1546             break;
1547         case RTL8139_RERID:
1548             val = nic_state->regs.rerid;
1549             break;
1550         case RTL8139_TXSAD: 
1551             val = rtl8139_txsad_read(nic_state);
1552             break;
1553         case RTL8139_BMCR:
1554             val = nic_state->regs.bmcr;
1555             break;
1556         case RTL8139_BMSR:
1557             val = nic_state->regs.bmsr;
1558             break;
1559         case RTL8139_ANAR:
1560             val = nic_state->regs.anar;
1561             break;
1562         case RTL8139_ANLPAR:
1563             val = nic_state->regs.anlpar;
1564             break;
1565         case RTL8139_ANER:
1566             val = nic_state->regs.aner;
1567             break;
1568         case RTL8139_DIS:
1569             val = nic_state->regs.dis;
1570             break;
1571         case RTL8139_FCSC:
1572             val = nic_state->regs.fcsc;
1573             break;
1574         case RTL8139_NWAYTR:
1575             val = nic_state->regs.nwaytr;
1576             break;
1577         case RTL8139_REC:
1578             val = nic_state->regs.rec;
1579             break;
1580         case RTL8139_CSCR:
1581             val = nic_state->regs.cscr;
1582             break;
1583         case RTL8139_PHY1_PARM:
1584             val = nic_state->regs.phy1_parm;
1585             break;
1586         case RTL8139_TW_PARM:
1587             val = nic_state->regs.tw_parm;
1588             break;
1589         case RTL8139_PHY2_PARM:
1590             val = nic_state->regs.phy2_parm;
1591             break;
1592         case RTL8139_CRC0 ... RTL8139_CRC0 + 7:
1593             val = nic_state->regs.crc[idx - RTL8139_CRC0];
1594             break;
1595         case RTL8139_Config5:
1596             val = nic_state->regs.config5;
1597             break;
1598         default:
1599             val = 0x0;
1600             break;
1601     }
1602
1603     memcpy(dst, &val, length);
1604         
1605     PrintDebug("rtl8139 mmio read: port:0x%x (%u bytes): 0x%x\n", (int)guest_addr, length, val);
1606
1607     return length;
1608 }
1609
1610
1611 static int rtl8139_ioport_write(struct guest_info * core,
1612                                 uint16_t port, 
1613                                 void *src, 
1614                                 uint_t length, 
1615                                 void * private_data) {
1616     return rtl8139_mmio_write(core, (addr_t)port, 
1617                               src, length, private_data);
1618 }
1619
1620 static int rtl8139_ioport_read(struct guest_info * core, 
1621                                uint16_t port, 
1622                                void *dst, 
1623                                uint_t length, 
1624                                void * private_data) {
1625     return rtl8139_mmio_read(core, (addr_t)port, 
1626                              dst, length, private_data);
1627 }
1628
1629
1630 static int rtl8139_init_state(struct rtl8139_state *nic_state) {
1631     PrintDebug("rtl8139: init_state\n");
1632         
1633     nic_state->regs.tsd[0] = nic_state->regs.tsd[1] = nic_state->regs.tsd[2] = nic_state->regs.tsd[3] = TSD_Own;
1634
1635     nic_state->regs.rerid = RTL8139_PCI_REVID_8139;
1636     nic_state->regs.tcr |= ((0x1d << 26) | (0x1 << 22));
1637
1638     rtl8139_reset(nic_state);
1639
1640     return 0;
1641 }
1642
1643
1644 #if 0
1645 static inline int rtl8139_reset_device(struct rtl8139_state * nic_state) {
1646     nic_state->regs.cmd |= CMD_Rst;
1647     rtl8139_init_state(nic_state);
1648     nic_state->regs.cmd &= ~CMD_Rst;
1649         
1650     return 0;
1651 }
1652
1653 static inline int rtl8139_start_device(struct rtl8139_state * nic_state) {
1654     nic_state->regs.cmd |= CMD_Re | CMD_Te;
1655         
1656     return 0;
1657 }
1658
1659 static int rtl8139_stop_device(struct rtl8139_state * nic_state) {
1660     PrintDebug("rtl8139: stop device\n");
1661
1662     nic_state->regs.cmd &= ~(CMD_Re | CMD_Te);
1663         
1664     return 0;
1665 }
1666
1667 static int rtl8139_hook_iospace(struct rtl8139_state * nic_state, 
1668                                 addr_t base_addr, 
1669                                 int size, 
1670                                 int type, 
1671                                 void *data) {
1672     int i;
1673
1674     if (base_addr <= 0){
1675         PrintError("In RTL8139: Fail to Hook IO Space, base address 0x%x\n", (int) base_addr);
1676         return -1;
1677     }
1678
1679     if (type == PCI_BAR_IO){
1680         PrintDebug("In RTL8139: Hook IO ports starting from %x, size %d\n", (int) base_addr, size);
1681
1682         for (i = 0; i < 0xff; i++){     
1683             v3_dev_hook_io(nic_state->dev, base_addr + i, &rtl8139_ioport_read, &rtl8139_ioport_write);
1684         }
1685     } else if (type == PCI_BAR_MEM32) {
1686         PrintDebug("In RTL8139: Hook memory space starting from %x, size %d\n", (int) base_addr, size);
1687         
1688         //hook memory mapped I/O        
1689         v3_hook_full_mem(nic_state->vm, nic_state->vm->cores[0].cpu_id, base_addr, base_addr + 0xff,
1690                                      &rtl8139_mmio_read, &rtl8139_mmio_write, nic_state);
1691     } else {
1692        PrintError("In RTL8139: unknown memory type: start %x, size %d\n", (int) base_addr, size);
1693     }
1694         
1695     return 0;
1696 }
1697 #endif
1698
1699 static int register_dev(struct rtl8139_state * nic_state)  {
1700     int i;
1701
1702     if (nic_state->pci_bus == NULL) {
1703         PrintError("RTL8139: Not attached to any PCI bus\n");
1704
1705         return -1;
1706     }
1707
1708     struct v3_pci_bar bars[6];
1709     struct pci_device * pci_dev = NULL;
1710
1711     for (i = 0; i < 6; i++) {
1712         bars[i].type = PCI_BAR_NONE;
1713     }
1714
1715     bars[0].type = PCI_BAR_IO;
1716     bars[0].default_base_port = 0xc100;
1717     bars[0].num_ports = 0x100;
1718
1719     bars[0].io_read = rtl8139_ioport_read;
1720     bars[0].io_write = rtl8139_ioport_write;
1721     bars[0].private_data = nic_state;
1722
1723 /*
1724     bars[1].type = PCI_BAR_MEM32;
1725     bars[1].default_base_addr = -1;
1726     bars[1].num_pages = 1;
1727
1728     bars[1].mem_read = rtl8139_mmio_read;
1729     bars[1].mem_write = rtl8139_mmio_write;
1730     bars[1].private_data = nic_state;
1731 */
1732
1733     pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0, 
1734                                          "RTL8139", bars,
1735                                          NULL, NULL, NULL, nic_state);
1736
1737
1738     if (pci_dev == NULL) {
1739         PrintError("RTL8139: Could not register PCI Device\n");
1740         return -1;
1741     }
1742         
1743     pci_dev->config_header.vendor_id = 0x10ec;
1744     pci_dev->config_header.device_id = 0x8139;
1745     pci_dev->config_header.command = 0x05;
1746         
1747     pci_dev->config_header.revision = RTL8139_PCI_REVID_8139;
1748
1749     pci_dev->config_header.subclass = 0x00;
1750     pci_dev->config_header.class = 0x02;
1751     pci_dev->config_header.header_type = 0x00;
1752
1753     pci_dev->config_header.intr_line = 12;
1754     pci_dev->config_header.intr_pin = 1;
1755     pci_dev->config_space[0x34] = 0xdc;
1756
1757     nic_state->pci_dev = pci_dev;
1758         
1759     return 0;
1760 }
1761
1762 static int connect_fn(struct v3_vm_info * info, 
1763                       void * frontend_data, 
1764                       struct v3_dev_net_ops * ops, 
1765                       v3_cfg_tree_t * cfg, 
1766                       void * private_data) {
1767     struct rtl8139_state * nic_state = (struct rtl8139_state *)frontend_data;
1768
1769     rtl8139_init_state(nic_state);
1770     register_dev(nic_state);
1771
1772     nic_state->net_ops = ops;
1773     nic_state->backend_data = private_data;     
1774
1775     ops->recv = rtl8139_rx;
1776     ops->poll = NULL;
1777     ops->start_tx = NULL;
1778     ops->stop_tx = NULL;
1779     ops->frontend_data = nic_state;
1780     memcpy(ops->fnt_mac, nic_state->mac, ETH_ALEN);
1781
1782     return 0;
1783 }
1784
1785
1786 static int rtl8139_free(void * private_data) {
1787     struct rtl8139_state * nic_state = (struct rtl8139_state *)private_data;
1788
1789     /* dettached from backend */
1790
1791     /* unregistered from PCI? */
1792
1793     V3_Free(nic_state);
1794         
1795     return 0;
1796 }
1797
1798
1799 static struct v3_device_ops dev_ops = {
1800     .free = rtl8139_free,
1801 };
1802
1803
1804 static int rtl8139_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1805     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
1806     struct rtl8139_state * nic_state = NULL;
1807     char * dev_id = v3_cfg_val(cfg, "ID");
1808     char * macstr = v3_cfg_val(cfg, "mac");
1809
1810     nic_state  = (struct rtl8139_state *)V3_Malloc(sizeof(struct rtl8139_state));
1811     memset(nic_state, 0, sizeof(struct rtl8139_state));
1812
1813     nic_state->pci_bus = pci_bus;
1814     nic_state->vm = vm;
1815
1816     if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1817         PrintDebug("RTL8139: Mac specified %s\n", macstr);
1818     }else {
1819         PrintDebug("RTL8139: MAC not specified\n");
1820         random_ethaddr(nic_state->mac);
1821     }
1822
1823     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1824
1825     if (dev == NULL) {
1826         PrintError("RTL8139: Could not attach device %s\n", dev_id);
1827         V3_Free(nic_state);
1828         return -1;
1829     }
1830
1831     nic_state->dev = dev;
1832
1833     if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)nic_state) == -1) {
1834         PrintError("RTL8139: Could not register %s as net frontend\n", dev_id);
1835         v3_remove_device(dev);
1836         V3_Free(nic_state);
1837         return -1;
1838     }
1839             
1840     return 0;
1841 }
1842
1843 device_register("RTL8139", rtl8139_init)