1 /*
2  * Cisco router simulation platform.
3  * Copyright (C) 2007 Christophe Fillot.  All rights reserved.
4  *
5  * Intel i8254x (Wiseman/Livengood) Ethernet chip emulation.
6  */
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdarg.h>
12 #include <unistd.h>
13 #include <time.h>
14 #include <errno.h>
15 #include <assert.h>
16 
17 #include "utils.h"
18 #include "cpu.h"
19 #include "vm.h"
20 #include "dynamips.h"
21 #include "memory.h"
22 #include "device.h"
23 #include "net.h"
24 #include "net_io.h"
25 #include "ptask.h"
26 #include "dev_i8254x.h"
27 
28 /* Debugging flags */
29 #define DEBUG_MII_REGS   0
30 #define DEBUG_ACCESS     0
31 #define DEBUG_TRANSMIT   0
32 #define DEBUG_RECEIVE    0
33 #define DEBUG_UNKNOWN    0
34 
35 /* Intel i8254x PCI vendor/product codes */
36 #define I8254X_PCI_VENDOR_ID    0x8086
37 #define I8254X_PCI_PRODUCT_ID   0x1001
38 
39 /* Maximum packet size */
40 #define I8254X_MAX_PKT_SIZE  16384
41 
42 /* Send up to 16 packets in a TX ring scan pass */
43 #define I8254X_TXRING_PASS_COUNT  16
44 
45 /* Register list */
46 #define I8254X_REG_CTRL      0x0000  /* Control Register */
47 #define I8254X_REG_STATUS    0x0008  /* Device Status Register */
48 #define I8254X_REG_CTRLEXT   0x0018  /* Extended Control Register */
49 #define I8254X_REG_MDIC      0x0020  /* MDI Control Register */
50 #define I8254X_REG_FCAL      0x0028  /* Flow Control Address Low */
51 #define I8254X_REG_FCAH      0x002c  /* Flow Control Address High */
52 #define I8254X_REG_FCT       0x0030  /* Flow Control Type */
53 #define I8254X_REG_VET       0x0038  /* VLAN Ether Type */
54 #define I8254X_REG_ICR       0x00c0  /* Interrupt Cause Read */
55 #define I8254X_REG_ITR       0x00c4  /* Interrupt Throttling Register */
56 #define I8254X_REG_ICS       0x00c8  /* Interrupt Cause Set Register */
57 #define I8254X_REG_IMS       0x00d0  /* Interrupt Mask Set/Read Register */
58 #define I8254X_REG_IMC       0x00d8  /* Interrupt Mask Clear Register */
59 #define I8254X_REG_RCTL      0x0100  /* Receive Control Register */
60 #define I8254X_REG_FCTTV     0x0170  /* Flow Control Transmit Timer Value */
61 #define I8254X_REG_TXCW      0x0178  /* Transmit Configuration Word */
62 #define I8254X_REG_RXCW      0x0180  /* Receive Configuration Word */
63 #define I8254X_REG_TCTL      0x0400  /* Transmit Control Register */
64 #define I8254X_REG_TIPG      0x0410  /* Transmit Inter Packet Gap  */
65 
66 #define I8254X_REG_LEDCTL    0x0E00  /* LED Control */
67 #define I8254X_REG_PBA       0x1000  /* Packet Buffer Allocation */
68 
69 #define I8254X_REG_RDBAL     0x2800  /* RX Descriptor Base Address Low */
70 #define I8254X_REG_RDBAH     0x2804  /* RX Descriptor Base Address High */
71 #define I8254X_REG_RDLEN     0x2808  /* RX Descriptor Length */
72 #define I8254X_REG_RDH       0x2810  /* RX Descriptor Head */
73 #define I8254X_REG_RDT       0x2818  /* RX Descriptor Tail */
74 #define I8254X_REG_RDTR      0x2820  /* RX Delay Timer Register */
75 #define I8254X_REG_RXDCTL    0x3828  /* RX Descriptor Control */
76 #define I8254X_REG_RADV      0x282c  /* RX Int. Absolute Delay Timer */
77 #define I8254X_REG_RSRPD     0x2c00  /* RX Small Packet Detect Interrupt */
78 
79 #define I8254X_REG_TXDMAC    0x3000  /* TX DMA Control */
80 #define I8254X_REG_TDBAL     0x3800  /* TX Descriptor Base Address Low */
81 #define I8254X_REG_TDBAH     0x3804  /* TX Descriptor Base Address Low */
82 #define I8254X_REG_TDLEN     0x3808  /* TX Descriptor Length */
83 #define I8254X_REG_TDH       0x3810  /* TX Descriptor Head */
84 #define I8254X_REG_TDT       0x3818  /* TX Descriptor Tail */
85 #define I8254X_REG_TIDV      0x3820  /* TX Interrupt Delay Value */
86 #define I8254X_REG_TXDCTL    0x3828  /* TX Descriptor Control */
87 #define I8254X_REG_TADV      0x382c  /* TX Absolute Interrupt Delay Value */
88 #define I8254X_REG_TSPMT     0x3830  /* TCP Segmentation Pad & Min Threshold */
89 
90 #define I8254X_REG_RXCSUM    0x5000  /* RX Checksum Control */
91 
92 /* Register list for i8254x */
93 #define I82542_REG_RDTR      0x0108  /* RX Delay Timer Register */
94 #define I82542_REG_RDBAL     0x0110  /* RX Descriptor Base Address Low */
95 #define I82542_REG_RDBAH     0x0114  /* RX Descriptor Base Address High */
96 #define I82542_REG_RDLEN     0x0118  /* RX Descriptor Length */
97 #define I82542_REG_RDH       0x0120  /* RDH for i82542 */
98 #define I82542_REG_RDT       0x0128  /* RDT for i82542 */
99 #define I82542_REG_TDBAL     0x0420  /* TX Descriptor Base Address Low */
100 #define I82542_REG_TDBAH     0x0424  /* TX Descriptor Base Address Low */
101 #define I82542_REG_TDLEN     0x0428  /* TX Descriptor Length */
102 #define I82542_REG_TDH       0x0430  /* TDH for i82542 */
103 #define I82542_REG_TDT       0x0438  /* TDT for i82542 */
104 
105 /* CTRL - Control Register (0x0000) */
106 #define I8254X_CTRL_FD               0x00000001  /* Full Duplex */
107 #define I8254X_CTRL_LRST             0x00000008  /* Link Reset */
108 #define I8254X_CTRL_ASDE             0x00000020  /* Auto-speed detection */
109 #define I8254X_CTRL_SLU              0x00000040  /* Set Link Up */
110 #define I8254X_CTRL_ILOS             0x00000080  /* Invert Loss of Signal */
111 #define I8254X_CTRL_SPEED_MASK       0x00000300  /* Speed selection */
112 #define I8254X_CTRL_SPEED_SHIFT      8
113 #define I8254X_CTRL_FRCSPD           0x00000800  /* Force Speed */
114 #define I8254X_CTRL_FRCDPLX          0x00001000  /* Force Duplex */
115 #define I8254X_CTRL_SDP0_DATA        0x00040000  /* SDP0 data */
116 #define I8254X_CTRL_SDP1_DATA        0x00080000  /* SDP1 data */
117 #define I8254X_CTRL_SDP0_IODIR       0x00400000  /* SDP0 direction */
118 #define I8254X_CTRL_SDP1_IODIR       0x00800000  /* SDP1 direction */
119 #define I8254X_CTRL_RST              0x04000000  /* Device Reset */
120 #define I8254X_CTRL_RFCE             0x08000000  /* RX Flow Ctrl Enable */
121 #define I8254X_CTRL_TFCE             0x10000000  /* TX Flow Ctrl Enable */
122 #define I8254X_CTRL_VME              0x40000000  /* VLAN Mode Enable */
123 #define I8254X_CTRL_PHY_RST          0x80000000  /* PHY reset */
124 
125 /* STATUS - Device Status Register (0x0008) */
126 #define I8254X_STATUS_FD             0x00000001  /* Full Duplex */
127 #define I8254X_STATUS_LU             0x00000002  /* Link Up */
128 #define I8254X_STATUS_TXOFF          0x00000010  /* Transmit paused */
129 #define I8254X_STATUS_TBIMODE        0x00000020  /* TBI Mode */
130 #define I8254X_STATUS_SPEED_MASK     0x000000C0  /* Link Speed setting */
131 #define I8254X_STATUS_SPEED_SHIFT    6
132 #define I8254X_STATUS_ASDV_MASK      0x00000300  /* Auto Speed Detection */
133 #define I8254X_STATUS_ASDV_SHIFT     8
134 #define I8254X_STATUS_PCI66          0x00000800  /* PCI bus speed */
135 #define I8254X_STATUS_BUS64          0x00001000  /* PCI bus width */
136 #define I8254X_STATUS_PCIX_MODE      0x00002000  /* PCI-X mode */
137 #define I8254X_STATUS_PCIXSPD_MASK   0x0000C000  /* PCI-X speed */
138 #define I8254X_STATUS_PCIXSPD_SHIFT  14
139 
140 /* CTRL_EXT - Extended Device Control Register (0x0018) */
141 #define I8254X_CTRLEXT_PHY_INT       0x00000020  /* PHY interrupt */
142 #define I8254X_CTRLEXT_SDP6_DATA     0x00000040  /* SDP6 data */
143 #define I8254X_CTRLEXT_SDP7_DATA     0x00000080  /* SDP7 data */
144 #define I8254X_CTRLEXT_SDP6_IODIR    0x00000400  /* SDP6 direction */
145 #define I8254X_CTRLEXT_SDP7_IODIR    0x00000800  /* SDP7 direction */
146 #define I8254X_CTRLEXT_ASDCHK        0x00001000  /* Auto-Speed Detect Chk */
147 #define I8254X_CTRLEXT_EE_RST        0x00002000  /* EEPROM reset */
148 #define I8254X_CTRLEXT_SPD_BYPS      0x00008000  /* Speed Select Bypass */
149 #define I8254X_CTRLEXT_RO_DIS        0x00020000  /* Relaxed Ordering Dis. */
150 #define I8254X_CTRLEXT_LNKMOD_MASK   0x00C00000  /* Link Mode */
151 #define I8254X_CTRLEXT_LNKMOD_SHIFT  22
152 
153 /* MDIC - MDI Control Register (0x0020) */
154 #define I8254X_MDIC_DATA_MASK        0x0000FFFF  /* Data */
155 #define I8254X_MDIC_REG_MASK         0x001F0000  /* PHY Register */
156 #define I8254X_MDIC_REG_SHIFT        16
157 #define I8254X_MDIC_PHY_MASK         0x03E00000  /* PHY Address */
158 #define I8254X_MDIC_PHY_SHIFT        21
159 #define I8254X_MDIC_OP_MASK          0x0C000000  /* Opcode */
160 #define I8254X_MDIC_OP_SHIFT         26
161 #define I8254X_MDIC_R                0x10000000  /* Ready */
162 #define I8254X_MDIC_I                0x20000000  /* Interrupt Enable */
163 #define I8254X_MDIC_E                0x40000000  /* Error */
164 
165 /* ICR - Interrupt Cause Read (0x00c0) */
166 #define I8254X_ICR_TXDW         0x00000001  /* TX Desc Written back */
167 #define I8254X_ICR_TXQE         0x00000002  /* TX Queue Empty */
168 #define I8254X_ICR_LSC          0x00000004  /* Link Status Change */
169 #define I8254X_ICR_RXSEQ        0x00000008  /* RX Sequence Error */
170 #define I8254X_ICR_RXDMT0       0x00000010  /* RX Desc min threshold reached */
171 #define I8254X_ICR_RXO          0x00000040  /* RX Overrun */
172 #define I8254X_ICR_RXT0         0x00000080  /* RX Timer Interrupt */
173 #define I8254X_ICR_MDAC         0x00000200  /* MDIO Access Complete */
174 #define I8254X_ICR_RXCFG        0x00000400
175 #define I8254X_ICR_PHY_INT      0x00001000  /* PHY Interrupt */
176 #define I8254X_ICR_GPI_SDP6     0x00002000  /* GPI on SDP6 */
177 #define I8254X_ICR_GPI_SDP7     0x00004000  /* GPI on SDP7 */
178 #define I8254X_ICR_TXD_LOW      0x00008000  /* TX Desc low threshold hit */
179 #define I8254X_ICR_SRPD         0x00010000  /* Small RX packet detected */
180 
181 /* RCTL - Receive Control Register (0x0100) */
182 #define I8254X_RCTL_EN          0x00000002  /* Receiver Enable */
183 #define I8254X_RCTL_SBP         0x00000004  /* Store Bad Packets */
184 #define I8254X_RCTL_UPE         0x00000008  /* Unicast Promiscuous Enabled */
185 #define I8254X_RCTL_MPE         0x00000010  /* Xcast Promiscuous Enabled */
186 #define I8254X_RCTL_LPE         0x00000020  /* Long Packet Reception Enable */
187 #define I8254X_RCTL_LBM_MASK    0x000000C0  /* Loopback Mode */
188 #define I8254X_RCTL_LBM_SHIFT   6
189 #define I8254X_RCTL_RDMTS_MASK  0x00000300  /* RX Desc Min Threshold Size */
190 #define I8254X_RCTL_RDMTS_SHIFT 8
191 #define I8254X_RCTL_MO_MASK     0x00003000  /* Multicast Offset */
192 #define I8254X_RCTL_MO_SHIFT    12
193 #define I8254X_RCTL_BAM         0x00008000  /* Broadcast Accept Mode */
194 #define I8254X_RCTL_BSIZE_MASK  0x00030000  /* RX Buffer Size */
195 #define I8254X_RCTL_BSIZE_SHIFT 16
196 #define I8254X_RCTL_VFE         0x00040000  /* VLAN Filter Enable */
197 #define I8254X_RCTL_CFIEN       0x00080000  /* CFI Enable */
198 #define I8254X_RCTL_CFI         0x00100000  /* Canonical Form Indicator Bit */
199 #define I8254X_RCTL_DPF         0x00400000  /* Discard Pause Frames */
200 #define I8254X_RCTL_PMCF        0x00800000  /* Pass MAC Control Frames */
201 #define I8254X_RCTL_BSEX        0x02000000  /* Buffer Size Extension */
202 #define I8254X_RCTL_SECRC       0x04000000  /* Strip Ethernet CRC */
203 
204 /* TCTL - Transmit Control Register (0x0400) */
205 #define I8254X_TCTL_EN          0x00000002  /* Transmit Enable */
206 #define I8254X_TCTL_PSP         0x00000008  /* Pad short packets */
207 #define I8254X_TCTL_SWXOFF      0x00400000  /* Software XOFF Transmission */
208 
209 /* PBA - Packet Buffer Allocation (0x1000) */
210 #define I8254X_PBA_RXA_MASK     0x0000FFFF  /* RX Packet Buffer */
211 #define I8254X_PBA_RXA_SHIFT    0
212 #define I8254X_PBA_TXA_MASK     0xFFFF0000  /* TX Packet Buffer */
213 #define I8254X_PBA_TXA_SHIFT    16
214 
215 /* Flow Control Type */
216 #define I8254X_FCT_TYPE_DEFAULT  0x8808
217 
218 /* === TX Descriptor fields === */
219 
220 /* TX Packet Length (word 2) */
221 #define I8254X_TXDESC_LEN_MASK  0x0000ffff
222 
223 /* TX Descriptor CMD field (word 2) */
224 #define I8254X_TXDESC_IDE       0x80000000  /* Interrupt Delay Enable */
225 #define I8254X_TXDESC_VLE       0x40000000  /* VLAN Packet Enable */
226 #define I8254X_TXDESC_DEXT      0x20000000  /* Extension */
227 #define I8254X_TXDESC_RPS       0x10000000  /* Report Packet Sent */
228 #define I8254X_TXDESC_RS        0x08000000  /* Report Status */
229 #define I8254X_TXDESC_IC        0x04000000  /* Insert Checksum */
230 #define I8254X_TXDESC_IFCS      0x02000000  /* Insert FCS */
231 #define I8254X_TXDESC_EOP       0x01000000  /* End Of Packet */
232 
233 /* TX Descriptor STA field (word 3) */
234 #define I8254X_TXDESC_TU        0x00000008  /* Transmit Underrun */
235 #define I8254X_TXDESC_LC        0x00000004  /* Late Collision */
236 #define I8254X_TXDESC_EC        0x00000002  /* Excess Collisions */
237 #define I8254X_TXDESC_DD        0x00000001  /* Descriptor Done */
238 
239 /* === RX Descriptor fields === */
240 
241 /* RX Packet Length (word 2) */
242 #define I8254X_RXDESC_LEN_MASK  0x0000ffff
243 
244 /* RX Descriptor STA field (word 3) */
245 #define I8254X_RXDESC_PIF       0x00000080  /* Passed In-exact Filter */
246 #define I8254X_RXDESC_IPCS      0x00000040  /* IP cksum calculated */
247 #define I8254X_RXDESC_TCPCS     0x00000020  /* TCP cksum calculated */
248 #define I8254X_RXDESC_VP        0x00000008  /* Packet is 802.1Q */
249 #define I8254X_RXDESC_IXSM      0x00000004  /* Ignore cksum indication */
250 #define I8254X_RXDESC_EOP       0x00000002  /* End Of Packet */
251 #define I8254X_RXDESC_DD        0x00000001  /* Descriptor Done */
252 
253 /* Intel i8254x private data */
254 struct i8254x_data {
255    char *name;
256 
257    /* Lock test */
258    pthread_mutex_t lock;
259 
260    /* Physical (MAC) address */
261    n_eth_addr_t mac_addr;
262 
263    /* Device information */
264    struct vdevice *dev;
265 
266    /* PCI device information */
267    struct pci_device *pci_dev;
268 
269    /* Virtual machine */
270    vm_instance_t *vm;
271 
272    /* NetIO descriptor */
273    netio_desc_t *nio;
274 
275    /* TX ring scanner task id */
276    ptask_id_t tx_tid;
277 
278    /* Interrupt registers */
279    m_uint32_t icr,imr;
280 
281    /* Device Control Register */
282    m_uint32_t ctrl;
283 
284    /* Extended Control Register */
285    m_uint32_t ctrl_ext;
286 
287    /* Flow Control registers */
288    m_uint32_t fcal,fcah,fct;
289 
290    /* RX Delay Timer */
291    m_uint32_t rdtr;
292 
293    /* RX/TX Control Registers */
294    m_uint32_t rctl,tctl;
295 
296    /* RX buffer size (computed from RX control register */
297    m_uint32_t rx_buf_size;
298 
299    /* RX/TX ring base addresses */
300    m_uint64_t rx_addr,tx_addr;
301 
302    /* RX/TX descriptor length */
303    m_uint32_t rdlen,tdlen;
304 
305    /* RX/TX descriptor head and tail */
306    m_uint32_t rdh,rdt,tdh,tdt;
307 
308    /* TX packet buffer */
309    m_uint8_t tx_buffer[I8254X_MAX_PKT_SIZE];
310 
311    /* RX IRQ count */
312    m_uint32_t rx_irq_cnt;
313 
314    /* MII/PHY handling */
315    u_int mii_state;
316    u_int mii_bit;
317    u_int mii_opcode;
318    u_int mii_phy;
319    u_int mii_reg;
320    u_int mii_data_pos;
321    u_int mii_data;
322    u_int mii_regs[32][32];
323 };
324 
325 /* TX descriptor */
326 struct tx_desc {
327    m_uint32_t tdes[4];
328 };
329 
330 /* RX descriptor */
331 struct rx_desc {
332    m_uint32_t rdes[4];
333 };
334 
335 #define LVG_LOCK(d)   pthread_mutex_lock(&(d)->lock)
336 #define LVG_UNLOCK(d) pthread_mutex_unlock(&(d)->lock)
337 
338 /* Log an message */
339 #define LVG_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
340 
341 /* Read a MII register */
mii_reg_read(struct i8254x_data * d)342 static m_uint16_t mii_reg_read(struct i8254x_data *d)
343 {
344 #if DEBUG_MII_REGS
345    LVG_LOG(d,"MII PHY read %d reg %d\n",d->mii_phy,d->mii_reg);
346 #endif
347 
348    switch(d->mii_reg) {
349       case 0x00:
350          return((d->mii_regs[d->mii_phy][d->mii_reg] & ~0x8200) | 0x2000);
351       case 0x01:
352          return(0x782c);
353       case 0x02:
354          return(0x0013);
355       case 0x03:
356          return(0x61d4);
357       case 0x05:
358          return(0x41e1);
359       case 0x06:
360          return(0x0001);
361       case 0x11:
362          return(0x4700);
363       default:
364          return(d->mii_regs[d->mii_phy][d->mii_reg]);
365    }
366 }
367 
368 /* Write a MII register */
mii_reg_write(struct i8254x_data * d)369 static void mii_reg_write(struct i8254x_data *d)
370 {
371 #if DEBUG_MII_REGS
372    LVG_LOG(d,"MII PHY write %d reg %d value %04x\n",
373              d->mii_phy,d->mii_reg,d->mii_data);
374 #endif
375    assert(d->mii_phy < 32);
376    assert(d->mii_reg < 32);
377    d->mii_regs[d->mii_phy][d->mii_reg] = d->mii_data;
378 }
379 
380 enum {
381    MII_OPCODE_READ = 1,
382    MII_OPCODE_WRITE,
383 };
384 
385 /* MII Finite State Machine */
mii_access(struct i8254x_data * d)386 static void mii_access(struct i8254x_data *d)
387 {
388    switch(d->mii_state) {
389       case 0:   /* reset */
390          d->mii_phy = 0;
391          d->mii_reg = 0;
392          d->mii_data_pos = 15;
393          d->mii_data = 0;
394 
395       case 1:   /* idle */
396          if (!d->mii_bit)
397             d->mii_state = 2;
398          else
399             d->mii_state = 1;
400          break;
401 
402       case 2:   /* start */
403          d->mii_state = d->mii_bit ? 3 : 0;
404          break;
405 
406       case 3:   /* opcode */
407          d->mii_state = d->mii_bit ? 4 : 5;
408          break;
409 
410       case 4:   /* read: opcode "10" */
411          if (!d->mii_bit) {
412             d->mii_opcode = MII_OPCODE_READ;
413             d->mii_state = 6;
414          } else {
415             d->mii_state = 0;
416          }
417          break;
418 
419       case 5:   /* write: opcode "01" */
420          if (d->mii_bit) {
421             d->mii_opcode = MII_OPCODE_WRITE;
422             d->mii_state = 6;
423          } else {
424             d->mii_state = 0;
425          }
426          break;
427 
428       case 6 ... 10:   /* phy */
429          d->mii_phy <<= 1;
430          d->mii_phy |= d->mii_bit;
431          d->mii_state++;
432          break;
433 
434       case 11 ... 15:  /* reg */
435          d->mii_reg <<= 1;
436          d->mii_reg |= d->mii_bit;
437          d->mii_state++;
438          break;
439 
440       case 16 ... 17:  /* ta */
441          if (d->mii_opcode == MII_OPCODE_READ)
442             d->mii_state = 18;
443          else
444             d->mii_state++;
445          break;
446 
447       case 18:
448          if (d->mii_opcode == MII_OPCODE_READ) {
449             d->mii_data = mii_reg_read(d);
450             d->mii_state++;
451          }
452 
453       case 19 ... 35:
454          if (d->mii_opcode == MII_OPCODE_READ) {
455             d->mii_bit = (d->mii_data >> d->mii_data_pos) & 0x1;
456          } else {
457             d->mii_data |= d->mii_bit << d->mii_data_pos;
458          }
459 
460          if (!d->mii_data_pos) {
461             if (d->mii_opcode == MII_OPCODE_WRITE)
462                mii_reg_write(d);
463             d->mii_state = 0;
464          } else {
465             d->mii_state++;
466          }
467 
468          d->mii_data_pos--;
469          break;
470 
471       default:
472          printf("MII: impossible state %u!\n",d->mii_state);
473    }
474 }
475 
476 /* Update the interrupt status */
dev_i8254x_update_irq_status(struct i8254x_data * d)477 static inline void dev_i8254x_update_irq_status(struct i8254x_data *d)
478 {
479    if (d->icr & d->imr)
480       pci_dev_trigger_irq(d->vm,d->pci_dev);
481    else
482       pci_dev_clear_irq(d->vm,d->pci_dev);
483 }
484 
485 /* Compute RX buffer size */
dev_i8254x_set_rx_buf_size(struct i8254x_data * d)486 static inline void dev_i8254x_set_rx_buf_size(struct i8254x_data *d)
487 {
488    m_uint32_t bsize;
489 
490    bsize = (d->rctl & I8254X_RCTL_BSIZE_MASK) >> I8254X_RCTL_BSIZE_SHIFT;
491 
492    if (!(d->rctl & I8254X_RCTL_BSEX)) {
493       /* Standard buffer sizes */
494       switch(bsize) {
495          case 0:
496             d->rx_buf_size = 2048;
497             break;
498          case 1:
499             d->rx_buf_size = 1024;
500             break;
501          case 2:
502             d->rx_buf_size = 512;
503             break;
504          case 3:
505             d->rx_buf_size = 256;
506             break;
507       }
508    } else {
509       /* Extended buffer sizes */
510       switch(bsize) {
511          case 0:
512             d->rx_buf_size = 0;  /* invalid */
513             break;
514          case 1:
515             d->rx_buf_size = 16384;
516             break;
517          case 2:
518             d->rx_buf_size = 8192;
519             break;
520          case 3:
521             d->rx_buf_size = 4096;
522             break;
523       }
524    }
525 }
526 
527 /*
528  * dev_i8254x_access()
529  */
dev_i8254x_access(cpu_gen_t * cpu,struct vdevice * dev,m_uint32_t offset,u_int op_size,u_int op_type,m_uint64_t * data)530 void *dev_i8254x_access(cpu_gen_t *cpu,struct vdevice *dev,
531                         m_uint32_t offset,u_int op_size,u_int op_type,
532                         m_uint64_t *data)
533 {
534    struct i8254x_data *d = dev->priv_data;
535 
536    if (op_type == MTS_READ)
537       *data = 0x0;
538 
539 #if DEBUG_ACCESS
540    if (op_type == MTS_READ) {
541       cpu_log(cpu,d->name,"read  access to offset=0x%x, pc=0x%llx, size=%u\n",
542               offset,cpu_get_pc(cpu),op_size);
543    } else {
544       cpu_log(cpu,d->name,"write access to offset=0x%x, pc=0x%llx, "
545               "val=0x%llx, size=%u\n",offset,cpu_get_pc(cpu),*data,op_size);
546    }
547 #endif
548 
549    LVG_LOCK(d);
550 
551    switch(offset) {
552 #if 0 /* TODO */
553       case 0x180:
554          if (op_type == MTS_READ)
555             *data = 0xFFFFFFFF; //0xDC004020; //1 << 31;
556          break;
557 #endif
558 
559       /* Link is Up and Full Duplex */
560       case I8254X_REG_STATUS:
561          if (op_type == MTS_READ)
562             *data = I8254X_STATUS_LU | I8254X_STATUS_FD;
563          break;
564 
565       /* Device Control Register */
566       case I8254X_REG_CTRL:
567          if (op_type == MTS_WRITE)
568             d->ctrl = *data;
569          else
570             *data = d->ctrl;
571          break;
572 
573       /* Extended Device Control Register */
574       case I8254X_REG_CTRLEXT:
575          if (op_type == MTS_WRITE) {
576             /* MDIO clock set ? */
577             if (!(d->ctrl_ext & I8254X_CTRLEXT_SDP6_DATA) &&
578                 (*data & I8254X_CTRLEXT_SDP6_DATA))
579              {
580                if (*data & I8254X_CTRLEXT_SDP7_IODIR)
581                   d->mii_bit = (*data & I8254X_CTRLEXT_SDP7_DATA) ? 1 : 0;
582 
583                mii_access(d);
584             }
585 
586             d->ctrl_ext = *data;
587          } else {
588             *data = d->ctrl_ext;
589 
590             if (!(d->ctrl_ext & I8254X_CTRLEXT_SDP7_IODIR)) {
591                if (d->mii_bit)
592                   *data |= I8254X_CTRLEXT_SDP7_DATA;
593                else
594                   *data &= ~I8254X_CTRLEXT_SDP7_DATA;
595             }
596          }
597          break;
598 
599       /* XXX */
600       case I8254X_REG_MDIC:
601          if (op_type == MTS_READ)
602             *data = 1 << 28;
603          break;
604 
605       /*
606        * Interrupt Cause Read Register.
607        *
608        * Notice: a read clears all interrupt bits.
609        */
610       case I8254X_REG_ICR:
611          if (op_type == MTS_READ) {
612             *data = d->icr;
613             d->icr = 0;
614 
615             if (d->rx_irq_cnt > 0) {
616                d->icr |= I8254X_ICR_RXT0;
617                d->rx_irq_cnt--;
618             }
619 
620             dev_i8254x_update_irq_status(d);
621          }
622          break;
623 
624       /* Interrupt Cause Set Register */
625       case I8254X_REG_ICS:
626          if (op_type == MTS_WRITE) {
627             d->icr |= *data;
628             dev_i8254x_update_irq_status(d);
629          }
630          break;
631 
632       /* Interrupt Mask Set/Read Register */
633       case I8254X_REG_IMS:
634          if (op_type == MTS_WRITE) {
635             d->imr |= *data;
636             dev_i8254x_update_irq_status(d);
637          } else {
638             *data = d->imr;
639          }
640          break;
641 
642       /* Interrupt Mask Clear Register */
643       case I8254X_REG_IMC:
644          if (op_type == MTS_WRITE) {
645             d->imr &= ~(*data);
646             dev_i8254x_update_irq_status(d);
647          }
648          break;
649 
650       /* Receive Control Register */
651       case I8254X_REG_RCTL:
652          if (op_type == MTS_READ) {
653             *data = d->rctl;
654          } else {
655             d->rctl = *data;
656             dev_i8254x_set_rx_buf_size(d);
657          }
658          break;
659 
660       /* Transmit Control Register */
661       case I8254X_REG_TCTL:
662          if (op_type == MTS_READ)
663             *data = d->tctl;
664          else
665             d->tctl = *data;
666          break;
667 
668       /* RX Descriptor Base Address Low */
669       case I8254X_REG_RDBAL:
670       case I82542_REG_RDBAL:
671          if (op_type == MTS_WRITE) {
672             d->rx_addr &= 0xFFFFFFFF00000000ULL;
673             d->rx_addr |= (m_uint32_t)(*data);
674          } else {
675             *data = (m_uint32_t)d->rx_addr;
676          }
677          break;
678 
679       /* RX Descriptor Base Address High */
680       case I8254X_REG_RDBAH:
681       case I82542_REG_RDBAH:
682          if (op_type == MTS_WRITE) {
683             d->rx_addr &= 0x00000000FFFFFFFFULL;
684             d->rx_addr |= *data << 32;
685          } else {
686             *data = d->rx_addr >> 32;
687          }
688          break;
689 
690       /* TX Descriptor Base Address Low */
691       case I8254X_REG_TDBAL:
692       case I82542_REG_TDBAL:
693          if (op_type == MTS_WRITE) {
694             d->tx_addr &= 0xFFFFFFFF00000000ULL;
695             d->tx_addr |= (m_uint32_t)(*data);
696          } else {
697             *data = (m_uint32_t)d->tx_addr;
698          }
699          break;
700 
701       /* TX Descriptor Base Address High */
702       case I8254X_REG_TDBAH:
703       case I82542_REG_TDBAH:
704          if (op_type == MTS_WRITE) {
705             d->tx_addr &= 0x00000000FFFFFFFFULL;
706             d->tx_addr |= *data << 32;
707          } else {
708             *data = d->tx_addr >> 32;
709          }
710          break;
711 
712       /* RX Descriptor Length */
713       case I8254X_REG_RDLEN:
714       case I82542_REG_RDLEN:
715          if (op_type == MTS_WRITE)
716             d->rdlen = *data & 0xFFF80;
717          else
718             *data = d->rdlen;
719          break;
720 
721       /* TX Descriptor Length */
722       case I8254X_REG_TDLEN:
723       case I82542_REG_TDLEN:
724          if (op_type == MTS_WRITE)
725             d->tdlen = *data & 0xFFF80;
726          else
727             *data = d->tdlen;
728          break;
729 
730       /* RX Descriptor Head */
731       case I82542_REG_RDH:
732       case I8254X_REG_RDH:
733          if (op_type == MTS_WRITE)
734             d->rdh = *data & 0xFFFF;
735          else
736             *data = d->rdh;
737          break;
738 
739       /* RX Descriptor Tail */
740       case I8254X_REG_RDT:
741       case I82542_REG_RDT:
742          if (op_type == MTS_WRITE)
743             d->rdt = *data & 0xFFFF;
744          else
745             *data = d->rdt;
746          break;
747 
748       /* TX Descriptor Head */
749       case I82542_REG_TDH:
750       case I8254X_REG_TDH:
751          if (op_type == MTS_WRITE)
752             d->tdh = *data & 0xFFFF;
753          else
754             *data = d->tdh;
755          break;
756 
757       /* TX Descriptor Tail */
758       case I82542_REG_TDT:
759       case I8254X_REG_TDT:
760          if (op_type == MTS_WRITE)
761             d->tdt = *data & 0xFFFF;
762          else
763             *data = d->tdt;
764          break;
765 
766       /* Flow Control Address Low */
767       case I8254X_REG_FCAL:
768          if (op_type == MTS_WRITE)
769             d->fcal = *data;
770          else
771             *data = d->fcal;
772          break;
773 
774       /* Flow Control Address High */
775       case I8254X_REG_FCAH:
776          if (op_type == MTS_WRITE)
777             d->fcah = *data & 0xFFFF;
778          else
779             *data = d->fcah;
780          break;
781 
782       /* Flow Control Type */
783       case I8254X_REG_FCT:
784          if (op_type == MTS_WRITE)
785             d->fct = *data & 0xFFFF;
786          else
787             *data = d->fct;
788          break;
789 
790       /* RX Delay Timer */
791       case I8254X_REG_RDTR:
792       case I82542_REG_RDTR:
793          if (op_type == MTS_WRITE)
794             d->rdtr = *data & 0xFFFF;
795          else
796             *data = d->rdtr;
797          break;
798 
799 #if DEBUG_UNKNOWN
800       default:
801          if (op_type == MTS_READ) {
802             cpu_log(cpu,d->name,
803                     "read access to unknown offset=0x%x, "
804                     "pc=0x%llx (size=%u)\n",
805                     offset,cpu_get_pc(cpu),op_size);
806          } else {
807             cpu_log(cpu,d->name,
808                     "write access to unknown offset=0x%x, pc=0x%llx, "
809                     "val=0x%llx (size=%u)\n",
810                     offset,cpu_get_pc(cpu),*data,op_size);
811          }
812 #endif
813    }
814 
815    LVG_UNLOCK(d);
816    return NULL;
817 }
818 
819 /* Read a TX descriptor */
txdesc_read(struct i8254x_data * d,m_uint64_t txd_addr,struct tx_desc * txd)820 static void txdesc_read(struct i8254x_data *d,m_uint64_t txd_addr,
821                         struct tx_desc *txd)
822 {
823    /* Get the descriptor from VM physical RAM */
824    physmem_copy_from_vm(d->vm,txd,txd_addr,sizeof(struct tx_desc));
825 
826    /* byte-swapping */
827    txd->tdes[0] = vmtoh32(txd->tdes[0]);
828    txd->tdes[1] = vmtoh32(txd->tdes[1]);
829    txd->tdes[2] = vmtoh32(txd->tdes[2]);
830    txd->tdes[3] = vmtoh32(txd->tdes[3]);
831 }
832 
833 /* Handle the TX ring (single packet) */
dev_i8254x_handle_txring_single(struct i8254x_data * d)834 static int dev_i8254x_handle_txring_single(struct i8254x_data *d)
835 {
836    m_uint64_t txd_addr,buf_addr;
837    m_uint32_t buf_len,tot_len;
838    m_uint32_t norm_len,icr;
839    struct tx_desc txd;
840    m_uint8_t *pkt_ptr;
841 
842    /* If Head is at same position than Tail, the ring is empty */
843    if (d->tdh == d->tdt)
844       return(FALSE);
845 
846    /* Check if the NIO can transmit */
847    if (!netio_can_transmit(d->nio))
848       return(FALSE);
849 
850    /* Empty packet for now */
851    pkt_ptr = d->tx_buffer;
852    tot_len = 0;
853    icr = 0;
854 
855    while(d->tdh != d->tdt) {
856       txd_addr = d->tx_addr + (d->tdh * sizeof(struct tx_desc));
857       txdesc_read(d,txd_addr,&txd);
858 
859       /* Copy the packet buffer */
860       buf_addr = ((m_uint64_t)txd.tdes[1] << 32) | txd.tdes[0];
861       buf_len  = txd.tdes[2] & I8254X_TXDESC_LEN_MASK;
862 
863 #if DEBUG_TRANSMIT
864       LVG_LOG(d,"copying data from 0x%8.8llx (buf_len=%u)\n",buf_addr,buf_len);
865 #endif
866       norm_len = normalize_size(buf_len,4,0);
867       physmem_copy_from_vm(d->vm,pkt_ptr,buf_addr,norm_len);
868       mem_bswap32(pkt_ptr,norm_len);
869 
870       pkt_ptr += buf_len;
871       tot_len += buf_len;
872 
873       /* Write the descriptor done bit if required */
874       if (txd.tdes[2] & I8254X_TXDESC_RS) {
875          txd.tdes[3] |= I8254X_TXDESC_DD;
876          icr |= I8254X_ICR_TXDW;
877          physmem_copy_u32_to_vm(d->vm,txd_addr+0x0c,txd.tdes[3]);
878       }
879 
880       /* Go to the next descriptor. Wrap ring if we are at end */
881       if (++d->tdh == (d->tdlen / sizeof(struct tx_desc)))
882          d->tdh = 0;
883 
884       /* End of packet ? */
885       if (txd.tdes[2] & I8254X_TXDESC_EOP) {
886 #if DEBUG_TRANSMIT
887          LVG_LOG(d,"sending packet of %u bytes\n",tot_len);
888          mem_dump(log_file,d->tx_buffer,tot_len);
889 #endif
890          netio_send(d->nio,d->tx_buffer,tot_len);
891          break;
892       }
893    }
894 
895    if (d->tdh == d->tdt)
896       icr |= I8254X_ICR_TXQE;
897 
898    /* Update the interrupt cause register and trigger IRQ if needed */
899    d->icr |= icr;
900    dev_i8254x_update_irq_status(d);
901    return(TRUE);
902 }
903 
904 /* Handle the TX ring */
dev_i8254x_handle_txring(struct i8254x_data * d)905 static int dev_i8254x_handle_txring(struct i8254x_data *d)
906 {
907    int res,i;
908 
909    /* Transmit Enabled ? */
910    if (!(d->tctl & I8254X_TCTL_EN))
911       return(FALSE);
912 
913    for(i=0;i<I8254X_TXRING_PASS_COUNT;i++) {
914       LVG_LOCK(d);
915       res = dev_i8254x_handle_txring_single(d);
916       LVG_UNLOCK(d);
917 
918       if (!res)
919          break;
920    }
921 
922    netio_clear_bw_stat(d->nio);
923    return(TRUE);
924 }
925 
926 /* Read a RX descriptor */
rxdesc_read(struct i8254x_data * d,m_uint64_t rxd_addr,struct rx_desc * rxd)927 static void rxdesc_read(struct i8254x_data *d,m_uint64_t rxd_addr,
928                         struct rx_desc *rxd)
929 {
930    /* Get the descriptor from VM physical RAM */
931    physmem_copy_from_vm(d->vm,rxd,rxd_addr,sizeof(struct rx_desc));
932 
933    /* byte-swapping */
934    rxd->rdes[0] = vmtoh32(rxd->rdes[0]);
935    rxd->rdes[1] = vmtoh32(rxd->rdes[1]);
936    rxd->rdes[2] = vmtoh32(rxd->rdes[2]);
937    rxd->rdes[3] = vmtoh32(rxd->rdes[3]);
938 }
939 
940 /*
941  * Put a packet in the RX ring.
942  */
dev_i8254x_receive_pkt(struct i8254x_data * d,u_char * pkt,ssize_t pkt_len)943 static int dev_i8254x_receive_pkt(struct i8254x_data *d,
944                                   u_char *pkt,ssize_t pkt_len)
945 {
946    m_uint64_t rxd_addr,buf_addr;
947    m_uint32_t cur_len,norm_len,tot_len;
948    struct rx_desc rxd;
949    m_uint32_t icr;
950    u_char *pkt_ptr;
951 
952    if (!d->rx_buf_size)
953       return(FALSE);
954 
955    LVG_LOCK(d);
956    pkt_ptr = pkt;
957    tot_len = pkt_len;
958    icr = 0;
959 
960    while(tot_len > 0) {
961       /* No descriptor available: RX overrun condition */
962       if (d->rdh == d->rdt) {
963          icr |= I8254X_ICR_RXO;
964          break;
965       }
966 
967       rxd_addr = d->rx_addr + (d->rdh * sizeof(struct rx_desc));
968       rxdesc_read(d,rxd_addr,&rxd);
969 
970       cur_len = (tot_len > d->rx_buf_size) ? d->rx_buf_size : tot_len;
971 
972       /* Copy the packet data into the RX buffer */
973       buf_addr = ((m_uint64_t)rxd.rdes[1] << 32) | rxd.rdes[0];
974 
975       norm_len = normalize_size(cur_len,4,0);
976       mem_bswap32(pkt_ptr,norm_len);
977       physmem_copy_to_vm(d->vm,pkt_ptr,buf_addr,norm_len);
978       tot_len -= cur_len;
979       pkt_ptr += cur_len;
980 
981       /* Set length field */
982       rxd.rdes[2] = cur_len;
983 
984       /* Set the status */
985       rxd.rdes[3] = I8254X_RXDESC_IXSM|I8254X_RXDESC_DD;
986 
987       if (!tot_len) {
988          rxd.rdes[3] |= I8254X_RXDESC_EOP;
989          icr |= I8254X_ICR_RXT0;
990          d->rx_irq_cnt++;
991          rxd.rdes[2] += 4;   /* FCS */
992       }
993 
994       /* Write back updated descriptor */
995       physmem_copy_u32_to_vm(d->vm,rxd_addr+0x08,rxd.rdes[2]);
996       physmem_copy_u32_to_vm(d->vm,rxd_addr+0x0c,rxd.rdes[3]);
997 
998       /* Goto to the next descriptor, and wrap if necessary */
999       if (++d->rdh == (d->rdlen / sizeof(struct rx_desc)))
1000          d->rdh = 0;
1001    }
1002 
1003    /* Update the interrupt cause register and trigger IRQ if needed */
1004    d->icr |= icr;
1005    dev_i8254x_update_irq_status(d);
1006    LVG_UNLOCK(d);
1007    return(TRUE);
1008 }
1009 
1010 /* Handle the RX ring */
dev_i8254x_handle_rxring(netio_desc_t * nio,u_char * pkt,ssize_t pkt_len,struct i8254x_data * d)1011 static int dev_i8254x_handle_rxring(netio_desc_t *nio,
1012                                     u_char *pkt,ssize_t pkt_len,
1013                                     struct i8254x_data *d)
1014 {
1015    /*
1016     * Don't start receive if RX has not been enabled in RCTL register.
1017     */
1018    if (!(d->rctl & I8254X_RCTL_EN))
1019       return(FALSE);
1020 
1021 #if DEBUG_RECEIVE
1022    LVG_LOG(d,"receiving a packet of %d bytes\n",pkt_len);
1023    mem_dump(log_file,pkt,pkt_len);
1024 #endif
1025 
1026    /*
1027     * Receive only multicast/broadcast trafic + unicast traffic
1028     * for this virtual machine.
1029     */
1030    //if (dec21140_handle_mac_addr(d,pkt))
1031    return(dev_i8254x_receive_pkt(d,pkt,pkt_len));
1032 
1033    return(FALSE);
1034 }
1035 
1036 /*
1037  * pci_i8254x_read()
1038  *
1039  * Read a PCI register.
1040  */
pci_i8254x_read(cpu_gen_t * cpu,struct pci_device * dev,int reg)1041 static m_uint32_t pci_i8254x_read(cpu_gen_t *cpu,struct pci_device *dev,
1042                                   int reg)
1043 {
1044    struct i8254x_data *d = dev->priv_data;
1045 
1046 #if DEBUG_PCI_REGS
1047    I8254X_LOG(d,"read PCI register 0x%x\n",reg);
1048 #endif
1049 
1050    switch (reg) {
1051       case 0x00:
1052          return((I8254X_PCI_PRODUCT_ID << 16) | I8254X_PCI_VENDOR_ID);
1053       case 0x08:
1054          return(0x02000003);
1055       case PCI_REG_BAR0:
1056          return(d->dev->phys_addr);
1057       default:
1058          return(0);
1059    }
1060 }
1061 
1062 /*
1063  * pci_i8254x_write()
1064  *
1065  * Write a PCI register.
1066  */
pci_i8254x_write(cpu_gen_t * cpu,struct pci_device * dev,int reg,m_uint32_t value)1067 static void pci_i8254x_write(cpu_gen_t *cpu,struct pci_device *dev,
1068                              int reg,m_uint32_t value)
1069 {
1070    struct i8254x_data *d = dev->priv_data;
1071 
1072 #if DEBUG_PCI_REGS
1073    LVG_LOG(d,"write PCI register 0x%x, value 0x%x\n",reg,value);
1074 #endif
1075 
1076    switch(reg) {
1077       case PCI_REG_BAR0:
1078          vm_map_device(cpu->vm,d->dev,(m_uint64_t)value);
1079          LVG_LOG(d,"registers are mapped at 0x%x\n",value);
1080          break;
1081    }
1082 }
1083 
1084 /*
1085  * dev_i8254x_init()
1086  */
1087 struct i8254x_data *
dev_i8254x_init(vm_instance_t * vm,char * name,int interface_type,struct pci_bus * pci_bus,int pci_device,int irq)1088 dev_i8254x_init(vm_instance_t *vm,char *name,int interface_type,
1089                 struct pci_bus *pci_bus,int pci_device,int irq)
1090 {
1091    struct i8254x_data *d;
1092    struct pci_device *pci_dev;
1093    struct vdevice *dev;
1094 
1095    /* Allocate the private data structure for I8254X */
1096    if (!(d = malloc(sizeof(*d)))) {
1097       fprintf(stderr,"%s (i8254x): out of memory\n",name);
1098       return NULL;
1099    }
1100 
1101    memset(d,0,sizeof(*d));
1102    pthread_mutex_init(&d->lock,NULL);
1103 
1104    /* Add as PCI device */
1105    pci_dev = pci_dev_add(pci_bus,name,
1106                          I8254X_PCI_VENDOR_ID,I8254X_PCI_PRODUCT_ID,
1107                          pci_device,0,irq,
1108                          d,NULL,pci_i8254x_read,pci_i8254x_write);
1109 
1110    if (!pci_dev) {
1111       fprintf(stderr,"%s (i8254x): unable to create PCI device.\n",name);
1112       goto err_pci_dev;
1113    }
1114 
1115    /* Create the device itself */
1116    if (!(dev = dev_create(name))) {
1117       fprintf(stderr,"%s (i8254x): unable to create device.\n",name);
1118       goto err_dev;
1119    }
1120 
1121    d->name     = name;
1122    d->vm       = vm;
1123    d->pci_dev  = pci_dev;
1124    d->dev      = dev;
1125 
1126    dev->phys_addr = 0;
1127    dev->phys_len  = 0x10000;
1128    dev->handler   = dev_i8254x_access;
1129    dev->priv_data = d;
1130    return(d);
1131 
1132  err_dev:
1133    pci_dev_remove(pci_dev);
1134  err_pci_dev:
1135    free(d);
1136    return NULL;
1137 }
1138 
1139 /* Remove an Intel i8254x device */
dev_i8254x_remove(struct i8254x_data * d)1140 void dev_i8254x_remove(struct i8254x_data *d)
1141 {
1142    if (d != NULL) {
1143       pci_dev_remove(d->pci_dev);
1144       vm_unbind_device(d->vm,d->dev);
1145       cpu_group_rebuild_mts(d->vm->cpu_group);
1146       free(d->dev);
1147       free(d);
1148    }
1149 }
1150 
1151 /* Bind a NIO to an Intel i8254x device */
dev_i8254x_set_nio(struct i8254x_data * d,netio_desc_t * nio)1152 int dev_i8254x_set_nio(struct i8254x_data *d,netio_desc_t *nio)
1153 {
1154    /* check that a NIO is not already bound */
1155    if (d->nio != NULL)
1156       return(-1);
1157 
1158    d->nio = nio;
1159    d->tx_tid = ptask_add((ptask_callback)dev_i8254x_handle_txring,d,NULL);
1160    netio_rxl_add(nio,(netio_rx_handler_t)dev_i8254x_handle_rxring,d,NULL);
1161    return(0);
1162 }
1163 
1164 /* Unbind a NIO from an Intel i8254x device */
dev_i8254x_unset_nio(struct i8254x_data * d)1165 void dev_i8254x_unset_nio(struct i8254x_data *d)
1166 {
1167    if (d->nio != NULL) {
1168       ptask_remove(d->tx_tid);
1169       netio_rxl_remove(d->nio);
1170       d->nio = NULL;
1171    }
1172 }
1173