ia64/xen-unstable

view tools/ioemu/hw/pcnet.h @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 3233e7ecfa9f
children 06d84bf87159
line source
1 /*
2 * QEMU AMD PC-Net II (Am79C970A) emulation
3 *
4 * Copyright (c) 2004 Antony T Curtis
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
25 /* This software was written to be compatible with the specification:
26 * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
27 * AMD Publication# 19436 Rev:E Amendment/0 Issue Date: June 2000
28 */
30 #ifdef __GNUC__
31 #define PACKED(A) A __attribute__ ((packed))
32 #else
33 #error FixMe
34 #endif
36 /* BUS CONFIGURATION REGISTERS */
37 #define BCR_MSRDA 0
38 #define BCR_MSWRA 1
39 #define BCR_MC 2
40 #define BCR_LNKST 4
41 #define BCR_LED1 5
42 #define BCR_LED2 6
43 #define BCR_LED3 7
44 #define BCR_FDC 9
45 #define BCR_BSBC 18
46 #define BCR_EECAS 19
47 #define BCR_SWS 20
48 #define BCR_PLAT 22
50 #define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080)
51 #define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100)
52 #define BCR_SWSTYLE(S) ((S)->bcr[BCR_SWS ] & 0x00FF)
54 #define CSR_INIT(S) !!(((S)->csr[0])&0x0001)
55 #define CSR_STRT(S) !!(((S)->csr[0])&0x0002)
56 #define CSR_STOP(S) !!(((S)->csr[0])&0x0004)
57 #define CSR_TDMD(S) !!(((S)->csr[0])&0x0008)
58 #define CSR_TXON(S) !!(((S)->csr[0])&0x0010)
59 #define CSR_RXON(S) !!(((S)->csr[0])&0x0020)
60 #define CSR_INEA(S) !!(((S)->csr[0])&0x0040)
61 #define CSR_LAPPEN(S) !!(((S)->csr[3])&0x0020)
62 #define CSR_DXSUFLO(S) !!(((S)->csr[3])&0x0040)
63 #define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
64 #define CSR_DPOLL(S) !!(((S)->csr[4])&0x1000)
65 #define CSR_SPND(S) !!(((S)->csr[5])&0x0001)
66 #define CSR_LTINTEN(S) !!(((S)->csr[5])&0x4000)
67 #define CSR_TOKINTD(S) !!(((S)->csr[5])&0x8000)
68 #define CSR_DRX(S) !!(((S)->csr[15])&0x0001)
69 #define CSR_DTX(S) !!(((S)->csr[15])&0x0002)
70 #define CSR_LOOP(S) !!(((S)->csr[15])&0x0004)
71 #define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000)
72 #define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000)
73 #define CSR_PROM(S) !!(((S)->csr[15])&0x8000)
75 #define CSR_CRBC(S) ((S)->csr[40])
76 #define CSR_CRST(S) ((S)->csr[41])
77 #define CSR_CXBC(S) ((S)->csr[42])
78 #define CSR_CXST(S) ((S)->csr[43])
79 #define CSR_NRBC(S) ((S)->csr[44])
80 #define CSR_NRST(S) ((S)->csr[45])
81 #define CSR_POLL(S) ((S)->csr[46])
82 #define CSR_PINT(S) ((S)->csr[47])
83 #define CSR_RCVRC(S) ((S)->csr[72])
84 #define CSR_XMTRC(S) ((S)->csr[74])
85 #define CSR_RCVRL(S) ((S)->csr[76])
86 #define CSR_XMTRL(S) ((S)->csr[78])
87 #define CSR_MISSC(S) ((S)->csr[112])
89 #define CSR_IADR(S) ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
90 #define CSR_CRBA(S) ((S)->csr[18] | ((S)->csr[19] << 16))
91 #define CSR_CXBA(S) ((S)->csr[20] | ((S)->csr[21] << 16))
92 #define CSR_NRBA(S) ((S)->csr[22] | ((S)->csr[23] << 16))
93 #define CSR_BADR(S) ((S)->csr[24] | ((S)->csr[25] << 16))
94 #define CSR_NRDA(S) ((S)->csr[26] | ((S)->csr[27] << 16))
95 #define CSR_CRDA(S) ((S)->csr[28] | ((S)->csr[29] << 16))
96 #define CSR_BADX(S) ((S)->csr[30] | ((S)->csr[31] << 16))
97 #define CSR_NXDA(S) ((S)->csr[32] | ((S)->csr[33] << 16))
98 #define CSR_CXDA(S) ((S)->csr[34] | ((S)->csr[35] << 16))
99 #define CSR_NNRD(S) ((S)->csr[36] | ((S)->csr[37] << 16))
100 #define CSR_NNXD(S) ((S)->csr[38] | ((S)->csr[39] << 16))
101 #define CSR_PXDA(S) ((S)->csr[60] | ((S)->csr[61] << 16))
102 #define CSR_NXBA(S) ((S)->csr[64] | ((S)->csr[65] << 16))
104 #define PHYSADDR(S,A) \
105 (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
107 struct pcnet_initblk16 {
108 uint16_t mode;
109 uint16_t padr1;
110 uint16_t padr2;
111 uint16_t padr3;
112 uint16_t ladrf1;
113 uint16_t ladrf2;
114 uint16_t ladrf3;
115 uint16_t ladrf4;
116 unsigned PACKED(rdra:24);
117 unsigned PACKED(res1:5);
118 unsigned PACKED(rlen:3);
119 unsigned PACKED(tdra:24);
120 unsigned PACKED(res2:5);
121 unsigned PACKED(tlen:3);
122 };
124 struct pcnet_initblk32 {
125 uint16_t mode;
126 unsigned PACKED(res1:4);
127 unsigned PACKED(rlen:4);
128 unsigned PACKED(res2:4);
129 unsigned PACKED(tlen:4);
130 uint16_t padr1;
131 uint16_t padr2;
132 uint16_t padr3;
133 uint16_t _res;
134 uint16_t ladrf1;
135 uint16_t ladrf2;
136 uint16_t ladrf3;
137 uint16_t ladrf4;
138 uint32_t rdra;
139 uint32_t tdra;
140 };
142 struct pcnet_TMD {
143 struct {
144 unsigned tbadr:32;
145 } tmd0;
146 struct {
147 unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:7), PACKED(bpe:1);
148 unsigned PACKED(enp:1), PACKED(stp:1), PACKED(def:1), PACKED(one:1);
149 unsigned PACKED(ltint:1), PACKED(nofcs:1), PACKED(err:1), PACKED(own:1);
150 } tmd1;
151 struct {
152 unsigned PACKED(trc:4), PACKED(res:12);
153 unsigned PACKED(tdr:10), PACKED(rtry:1), PACKED(lcar:1);
154 unsigned PACKED(lcol:1), PACKED(exdef:1), PACKED(uflo:1), PACKED(buff:1);
155 } tmd2;
156 struct {
157 unsigned res:32;
158 } tmd3;
159 };
161 struct pcnet_RMD {
162 struct {
163 unsigned rbadr:32;
164 } rmd0;
165 struct {
166 unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:4);
167 unsigned PACKED(bam:1), PACKED(lafm:1), PACKED(pam:1), PACKED(bpe:1);
168 unsigned PACKED(enp:1), PACKED(stp:1), PACKED(buff:1), PACKED(crc:1);
169 unsigned PACKED(oflo:1), PACKED(fram:1), PACKED(err:1), PACKED(own:1);
170 } rmd1;
171 struct {
172 unsigned PACKED(mcnt:12), PACKED(zeros:4);
173 unsigned PACKED(rpc:8), PACKED(rcc:8);
174 } rmd2;
175 struct {
176 unsigned res:32;
177 } rmd3;
178 };
181 #define PRINT_TMD(T) printf( \
182 "TMD0 : TBADR=0x%08x\n" \
183 "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, " \
184 "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n" \
185 " BPE=%d, BCNT=%d\n" \
186 "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, " \
187 "LCA=%d, RTR=%d,\n" \
188 " TDR=%d, TRC=%d\n", \
189 (T)->tmd0.tbadr, \
190 (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs, \
191 (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def, \
192 (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe, \
193 4096-(T)->tmd1.bcnt, \
194 (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
195 (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
196 (T)->tmd2.tdr, (T)->tmd2.trc)
198 #define PRINT_RMD(R) printf( \
199 "RMD0 : RBADR=0x%08x\n" \
200 "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, " \
201 "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n " \
202 "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
203 "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n", \
204 (R)->rmd0.rbadr, \
205 (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram, \
206 (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff, \
207 (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe, \
208 (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam, \
209 (R)->rmd1.ones, 4096-(R)->rmd1.bcnt, \
210 (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \
211 (R)->rmd2.zeros)
213 static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
214 {
215 if (!BCR_SWSTYLE(s)) {
216 uint16_t xda[4];
217 cpu_physical_memory_read(addr,
218 (void *)&xda[0], sizeof(xda));
219 ((uint32_t *)tmd)[0] = (xda[0]&0xffff) |
220 ((xda[1]&0x00ff) << 16);
221 ((uint32_t *)tmd)[1] = (xda[2]&0xffff)|
222 ((xda[1] & 0xff00) << 16);
223 ((uint32_t *)tmd)[2] =
224 (xda[3] & 0xffff) << 16;
225 ((uint32_t *)tmd)[3] = 0;
226 }
227 else
228 if (BCR_SWSTYLE(s) != 3)
229 cpu_physical_memory_read(addr, (void *)tmd, 16);
230 else {
231 uint32_t xda[4];
232 cpu_physical_memory_read(addr,
233 (void *)&xda[0], sizeof(xda));
234 ((uint32_t *)tmd)[0] = xda[2];
235 ((uint32_t *)tmd)[1] = xda[1];
236 ((uint32_t *)tmd)[2] = xda[0];
237 ((uint32_t *)tmd)[3] = xda[3];
238 }
239 }
241 static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
242 {
243 cpu_physical_memory_set_dirty(addr);
244 if (!BCR_SWSTYLE(s)) {
245 uint16_t xda[4];
246 xda[0] = ((uint32_t *)tmd)[0] & 0xffff;
247 xda[1] = ((((uint32_t *)tmd)[0]>>16)&0x00ff) |
248 ((((uint32_t *)tmd)[1]>>16)&0xff00);
249 xda[2] = ((uint32_t *)tmd)[1] & 0xffff;
250 xda[3] = ((uint32_t *)tmd)[2] >> 16;
251 cpu_physical_memory_write(addr,
252 (void *)&xda[0], sizeof(xda));
253 cpu_physical_memory_set_dirty(addr+7);
254 }
255 else {
256 if (BCR_SWSTYLE(s) != 3)
257 cpu_physical_memory_write(addr, (void *)tmd, 16);
258 else {
259 uint32_t xda[4];
260 xda[0] = ((uint32_t *)tmd)[2];
261 xda[1] = ((uint32_t *)tmd)[1];
262 xda[2] = ((uint32_t *)tmd)[0];
263 xda[3] = ((uint32_t *)tmd)[3];
264 cpu_physical_memory_write(addr,
265 (void *)&xda[0], sizeof(xda));
266 }
267 cpu_physical_memory_set_dirty(addr+15);
268 }
269 }
271 static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
272 {
273 if (!BCR_SWSTYLE(s)) {
274 uint16_t rda[4];
275 cpu_physical_memory_read(addr,
276 (void *)&rda[0], sizeof(rda));
277 ((uint32_t *)rmd)[0] = (rda[0]&0xffff)|
278 ((rda[1] & 0x00ff) << 16);
279 ((uint32_t *)rmd)[1] = (rda[2]&0xffff)|
280 ((rda[1] & 0xff00) << 16);
281 ((uint32_t *)rmd)[2] = rda[3] & 0xffff;
282 ((uint32_t *)rmd)[3] = 0;
283 }
284 else
285 if (BCR_SWSTYLE(s) != 3)
286 cpu_physical_memory_read(addr, (void *)rmd, 16);
287 else {
288 uint32_t rda[4];
289 cpu_physical_memory_read(addr,
290 (void *)&rda[0], sizeof(rda));
291 ((uint32_t *)rmd)[0] = rda[2];
292 ((uint32_t *)rmd)[1] = rda[1];
293 ((uint32_t *)rmd)[2] = rda[0];
294 ((uint32_t *)rmd)[3] = rda[3];
295 }
296 }
298 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
299 {
300 cpu_physical_memory_set_dirty(addr);
301 if (!BCR_SWSTYLE(s)) {
302 uint16_t rda[4]; \
303 rda[0] = ((uint32_t *)rmd)[0] & 0xffff; \
304 rda[1] = ((((uint32_t *)rmd)[0]>>16)&0xff)|\
305 ((((uint32_t *)rmd)[1]>>16)&0xff00);\
306 rda[2] = ((uint32_t *)rmd)[1] & 0xffff; \
307 rda[3] = ((uint32_t *)rmd)[2] & 0xffff; \
308 cpu_physical_memory_write(addr, \
309 (void *)&rda[0], sizeof(rda)); \
310 cpu_physical_memory_set_dirty(addr+7);
311 }
312 else {
313 if (BCR_SWSTYLE(s) != 3)
314 cpu_physical_memory_write(addr, (void *)rmd, 16);
315 else {
316 uint32_t rda[4];
317 rda[0] = ((uint32_t *)rmd)[2];
318 rda[1] = ((uint32_t *)rmd)[1];
319 rda[2] = ((uint32_t *)rmd)[0];
320 rda[3] = ((uint32_t *)rmd)[3];
321 cpu_physical_memory_write(addr,
322 (void *)&rda[0], sizeof(rda));
323 }
324 cpu_physical_memory_set_dirty(addr+15);
325 }
326 }
329 #define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
331 #define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
333 #define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
335 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
337 #if 1
339 #define CHECK_RMD(ADDR,RES) do { \
340 struct pcnet_RMD rmd; \
341 RMDLOAD(&rmd,(ADDR)); \
342 (RES) |= (rmd.rmd1.ones != 15) \
343 || (rmd.rmd2.zeros != 0); \
344 } while (0)
346 #define CHECK_TMD(ADDR,RES) do { \
347 struct pcnet_TMD tmd; \
348 TMDLOAD(&tmd,(ADDR)); \
349 (RES) |= (tmd.tmd1.ones != 15); \
350 } while (0)
352 #else
354 #define CHECK_RMD(ADDR,RES) do { \
355 switch (BCR_SWSTYLE(s)) { \
356 case 0x00: \
357 do { \
358 uint16_t rda[4]; \
359 cpu_physical_memory_read((ADDR), \
360 (void *)&rda[0], sizeof(rda)); \
361 (RES) |= (rda[2] & 0xf000)!=0xf000; \
362 (RES) |= (rda[3] & 0xf000)!=0x0000; \
363 } while (0); \
364 break; \
365 case 0x01: \
366 case 0x02: \
367 do { \
368 uint32_t rda[4]; \
369 cpu_physical_memory_read((ADDR), \
370 (void *)&rda[0], sizeof(rda)); \
371 (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
372 (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
373 } while (0); \
374 break; \
375 case 0x03: \
376 do { \
377 uint32_t rda[4]; \
378 cpu_physical_memory_read((ADDR), \
379 (void *)&rda[0], sizeof(rda)); \
380 (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
381 (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
382 } while (0); \
383 break; \
384 } \
385 } while (0)
387 #define CHECK_TMD(ADDR,RES) do { \
388 switch (BCR_SWSTYLE(s)) { \
389 case 0x00: \
390 do { \
391 uint16_t xda[4]; \
392 cpu_physical_memory_read((ADDR), \
393 (void *)&xda[0], sizeof(xda)); \
394 (RES) |= (xda[2] & 0xf000)!=0xf000;\
395 } while (0); \
396 break; \
397 case 0x01: \
398 case 0x02: \
399 case 0x03: \
400 do { \
401 uint32_t xda[4]; \
402 cpu_physical_memory_read((ADDR), \
403 (void *)&xda[0], sizeof(xda)); \
404 (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
405 } while (0); \
406 break; \
407 } \
408 } while (0)
410 #endif
412 #define PRINT_PKTHDR(BUF) do { \
413 struct ether_header *hdr = (void *)(BUF); \
414 printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
415 "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
416 "type=0x%04x (bcast=%d)\n", \
417 hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
418 hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
419 hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
420 hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
421 htons(hdr->ether_type), \
422 !!ETHER_IS_MULTICAST(hdr->ether_dhost)); \
423 } while (0)
425 #define MULTICAST_FILTER_LEN 8
427 static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
428 {
429 #define LNC_POLYNOMIAL 0xEDB88320UL
430 uint32_t crc = 0xFFFFFFFF;
431 int idx, bit;
432 uint8_t data;
434 for (idx = 0; idx < ETHER_ADDR_LEN; idx++) {
435 for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
436 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
437 data >>= 1;
438 }
439 }
440 return crc;
441 #undef LNC_POLYNOMIAL
442 }
444 #define MIN(X,Y) ((X>Y) ? (Y) : (X))
446 #define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
448 /* generated using the AUTODIN II polynomial
449 * x^32 + x^26 + x^23 + x^22 + x^16 +
450 * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
451 */
452 static const uint32_t crctab[256] = {
453 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
454 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
455 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
456 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
457 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
458 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
459 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
460 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
461 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
462 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
463 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
464 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
465 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
466 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
467 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
468 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
469 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
470 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
471 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
472 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
473 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
474 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
475 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
476 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
477 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
478 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
479 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
480 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
481 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
482 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
483 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
484 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
485 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
486 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
487 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
488 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
489 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
490 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
491 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
492 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
493 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
494 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
495 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
496 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
497 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
498 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
499 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
500 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
501 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
502 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
503 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
504 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
505 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
506 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
507 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
508 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
509 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
510 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
511 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
512 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
513 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
514 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
515 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
516 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
517 };
519 static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
520 {
521 struct ether_header *hdr = (void *)buf;
522 uint8_t padr[6] = {
523 s->csr[12] & 0xff, s->csr[12] >> 8,
524 s->csr[13] & 0xff, s->csr[13] >> 8,
525 s->csr[14] & 0xff, s->csr[14] >> 8
526 };
527 int result = (!CSR_DRCVPA(s)) && !bcmp(hdr->ether_dhost, padr, 6);
528 #ifdef PCNET_DEBUG_MATCH
529 printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
530 "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
531 hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
532 hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
533 padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
534 printf("padr_match result=%d\n", result);
535 #endif
536 return result;
537 }
539 static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
540 {
541 static uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
542 struct ether_header *hdr = (void *)buf;
543 int result = !CSR_DRCVBC(s) && !bcmp(hdr->ether_dhost, BCAST, 6);
544 #ifdef PCNET_DEBUG_MATCH
545 printf("padr_bcast result=%d\n", result);
546 #endif
547 return result;
548 }
550 static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
551 {
552 struct ether_header *hdr = (void *)buf;
553 if ((*(hdr->ether_dhost)&0x01) &&
554 ((uint64_t *)&s->csr[8])[0] != 0LL) {
555 uint8_t ladr[8] = {
556 s->csr[8] & 0xff, s->csr[8] >> 8,
557 s->csr[9] & 0xff, s->csr[9] >> 8,
558 s->csr[10] & 0xff, s->csr[10] >> 8,
559 s->csr[11] & 0xff, s->csr[11] >> 8
560 };
561 int index = lnc_mchash(hdr->ether_dhost) >> 26;
562 return !!(ladr[index >> 3] & (1 << (index & 7)));
563 }
564 return 0;
565 }
567 static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
568 {
569 while (idx < 1) idx += CSR_RCVRL(s);
570 return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
571 }
573 static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
574 {
575 int64_t next_time = current_time +
576 muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
577 ticks_per_sec, 33000000L);
578 if (next_time <= current_time)
579 next_time = current_time + 1;
580 return next_time;
581 }