i82596.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*
  2. * QEMU Intel i82596 (Apricot) emulation
  3. *
  4. * Copyright (c) 2019 Helge Deller <deller@gmx.de>
  5. * This work is licensed under the GNU GPL license version 2 or later.
  6. *
  7. * This software was written to be compatible with the specification:
  8. * https://www.intel.com/assets/pdf/general/82596ca.pdf
  9. */
  10. #include "qemu/osdep.h"
  11. #include "qemu/timer.h"
  12. #include "net/net.h"
  13. #include "net/eth.h"
  14. #include "hw/irq.h"
  15. #include "hw/qdev-properties.h"
  16. #include "migration/vmstate.h"
  17. #include "exec/address-spaces.h"
  18. #include "qemu/module.h"
  19. #include "trace.h"
  20. #include "i82596.h"
  21. #include <zlib.h> /* for crc32 */
  22. #if defined(ENABLE_DEBUG)
  23. #define DBG(x) x
  24. #else
  25. #define DBG(x) do { } while (0)
  26. #endif
  27. #define USE_TIMER 0
  28. #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
  29. #define PKT_BUF_SZ 1536
  30. #define MAX_MC_CNT 64
  31. #define ISCP_BUSY 0x0001
  32. #define I596_NULL ((uint32_t)0xffffffff)
  33. #define SCB_STATUS_CX 0x8000 /* CU finished command with I bit */
  34. #define SCB_STATUS_FR 0x4000 /* RU finished receiving a frame */
  35. #define SCB_STATUS_CNA 0x2000 /* CU left active state */
  36. #define SCB_STATUS_RNR 0x1000 /* RU left active state */
  37. #define SCB_COMMAND_ACK_MASK \
  38. (SCB_STATUS_CX | SCB_STATUS_FR | SCB_STATUS_CNA | SCB_STATUS_RNR)
  39. #define CU_IDLE 0
  40. #define CU_SUSPENDED 1
  41. #define CU_ACTIVE 2
  42. #define RX_IDLE 0
  43. #define RX_SUSPENDED 1
  44. #define RX_READY 4
  45. #define CMD_EOL 0x8000 /* The last command of the list, stop. */
  46. #define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
  47. #define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
  48. #define CMD_FLEX 0x0008 /* Enable flexible memory model */
  49. enum commands {
  50. CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
  51. CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7
  52. };
  53. #define STAT_C 0x8000 /* Set to 0 after execution */
  54. #define STAT_B 0x4000 /* Command being executed */
  55. #define STAT_OK 0x2000 /* Command executed ok */
  56. #define STAT_A 0x1000 /* Command aborted */
  57. #define I596_EOF 0x8000
  58. #define SIZE_MASK 0x3fff
  59. /* various flags in the chip config registers */
  60. #define I596_PREFETCH (s->config[0] & 0x80)
  61. #define I596_PROMISC (s->config[8] & 0x01)
  62. #define I596_BC_DISABLE (s->config[8] & 0x02) /* broadcast disable */
  63. #define I596_NOCRC_INS (s->config[8] & 0x08)
  64. #define I596_CRCINM (s->config[11] & 0x04) /* CRC appended */
  65. #define I596_MC_ALL (s->config[11] & 0x20)
  66. #define I596_MULTIIA (s->config[13] & 0x40)
  67. static uint8_t get_byte(uint32_t addr)
  68. {
  69. return ldub_phys(&address_space_memory, addr);
  70. }
  71. static void set_byte(uint32_t addr, uint8_t c)
  72. {
  73. return stb_phys(&address_space_memory, addr, c);
  74. }
  75. static uint16_t get_uint16(uint32_t addr)
  76. {
  77. return lduw_be_phys(&address_space_memory, addr);
  78. }
  79. static void set_uint16(uint32_t addr, uint16_t w)
  80. {
  81. return stw_be_phys(&address_space_memory, addr, w);
  82. }
  83. static uint32_t get_uint32(uint32_t addr)
  84. {
  85. uint32_t lo = lduw_be_phys(&address_space_memory, addr);
  86. uint32_t hi = lduw_be_phys(&address_space_memory, addr + 2);
  87. return (hi << 16) | lo;
  88. }
  89. static void set_uint32(uint32_t addr, uint32_t val)
  90. {
  91. set_uint16(addr, (uint16_t) val);
  92. set_uint16(addr + 2, val >> 16);
  93. }
  94. struct qemu_ether_header {
  95. uint8_t ether_dhost[6];
  96. uint8_t ether_shost[6];
  97. uint16_t ether_type;
  98. };
  99. #define PRINT_PKTHDR(txt, BUF) do { \
  100. struct qemu_ether_header *hdr = (void *)(BUF); \
  101. printf(txt ": packet dhost=" MAC_FMT ", shost=" MAC_FMT ", type=0x%04x\n",\
  102. MAC_ARG(hdr->ether_dhost), MAC_ARG(hdr->ether_shost), \
  103. be16_to_cpu(hdr->ether_type)); \
  104. } while (0)
  105. static void i82596_transmit(I82596State *s, uint32_t addr)
  106. {
  107. uint32_t tdb_p; /* Transmit Buffer Descriptor */
  108. /* TODO: Check flexible mode */
  109. tdb_p = get_uint32(addr + 8);
  110. while (tdb_p != I596_NULL) {
  111. uint16_t size, len;
  112. uint32_t tba;
  113. size = get_uint16(tdb_p);
  114. len = size & SIZE_MASK;
  115. tba = get_uint32(tdb_p + 8);
  116. trace_i82596_transmit(len, tba);
  117. if (s->nic && len) {
  118. assert(len <= sizeof(s->tx_buffer));
  119. address_space_read(&address_space_memory, tba,
  120. MEMTXATTRS_UNSPECIFIED, s->tx_buffer, len);
  121. DBG(PRINT_PKTHDR("Send", &s->tx_buffer));
  122. DBG(printf("Sending %d bytes\n", len));
  123. qemu_send_packet(qemu_get_queue(s->nic), s->tx_buffer, len);
  124. }
  125. /* was this the last package? */
  126. if (size & I596_EOF) {
  127. break;
  128. }
  129. /* get next buffer pointer */
  130. tdb_p = get_uint32(tdb_p + 4);
  131. }
  132. }
  133. static void set_individual_address(I82596State *s, uint32_t addr)
  134. {
  135. NetClientState *nc;
  136. uint8_t *m;
  137. nc = qemu_get_queue(s->nic);
  138. m = s->conf.macaddr.a;
  139. address_space_read(&address_space_memory, addr + 8,
  140. MEMTXATTRS_UNSPECIFIED, m, ETH_ALEN);
  141. qemu_format_nic_info_str(nc, m);
  142. trace_i82596_new_mac(nc->info_str);
  143. }
  144. static void set_multicast_list(I82596State *s, uint32_t addr)
  145. {
  146. uint16_t mc_count, i;
  147. memset(&s->mult[0], 0, sizeof(s->mult));
  148. mc_count = get_uint16(addr + 8) / ETH_ALEN;
  149. addr += 10;
  150. if (mc_count > MAX_MC_CNT) {
  151. mc_count = MAX_MC_CNT;
  152. }
  153. for (i = 0; i < mc_count; i++) {
  154. uint8_t multicast_addr[ETH_ALEN];
  155. address_space_read(&address_space_memory, addr + i * ETH_ALEN,
  156. MEMTXATTRS_UNSPECIFIED, multicast_addr, ETH_ALEN);
  157. DBG(printf("Add multicast entry " MAC_FMT "\n",
  158. MAC_ARG(multicast_addr)));
  159. unsigned mcast_idx = (net_crc32(multicast_addr, ETH_ALEN) &
  160. BITS(7, 2)) >> 2;
  161. assert(mcast_idx < 8 * sizeof(s->mult));
  162. s->mult[mcast_idx >> 3] |= (1 << (mcast_idx & 7));
  163. }
  164. trace_i82596_set_multicast(mc_count);
  165. }
  166. void i82596_set_link_status(NetClientState *nc)
  167. {
  168. I82596State *d = qemu_get_nic_opaque(nc);
  169. d->lnkst = nc->link_down ? 0 : 0x8000;
  170. }
  171. static void update_scb_status(I82596State *s)
  172. {
  173. s->scb_status = (s->scb_status & 0xf000)
  174. | (s->cu_status << 8) | (s->rx_status << 4);
  175. set_uint16(s->scb, s->scb_status);
  176. }
  177. static void i82596_s_reset(I82596State *s)
  178. {
  179. trace_i82596_s_reset(s);
  180. s->scp = 0;
  181. s->scb_status = 0;
  182. s->cu_status = CU_IDLE;
  183. s->rx_status = RX_SUSPENDED;
  184. s->cmd_p = I596_NULL;
  185. s->lnkst = 0x8000; /* initial link state: up */
  186. s->ca = s->ca_active = 0;
  187. s->send_irq = 0;
  188. }
  189. static void command_loop(I82596State *s)
  190. {
  191. uint16_t cmd;
  192. uint16_t status;
  193. uint8_t byte_cnt;
  194. DBG(printf("STARTING COMMAND LOOP cmd_p=%08x\n", s->cmd_p));
  195. while (s->cmd_p != I596_NULL) {
  196. /* set status */
  197. status = STAT_B;
  198. set_uint16(s->cmd_p, status);
  199. status = STAT_C | STAT_OK; /* update, but write later */
  200. cmd = get_uint16(s->cmd_p + 2);
  201. DBG(printf("Running command %04x at %08x\n", cmd, s->cmd_p));
  202. switch (cmd & 0x07) {
  203. case CmdNOp:
  204. break;
  205. case CmdSASetup:
  206. set_individual_address(s, s->cmd_p);
  207. break;
  208. case CmdConfigure:
  209. byte_cnt = get_byte(s->cmd_p + 8) & 0x0f;
  210. byte_cnt = MAX(byte_cnt, 4);
  211. byte_cnt = MIN(byte_cnt, sizeof(s->config));
  212. /* copy byte_cnt max. */
  213. address_space_read(&address_space_memory, s->cmd_p + 8,
  214. MEMTXATTRS_UNSPECIFIED, s->config, byte_cnt);
  215. /* config byte according to page 35ff */
  216. s->config[2] &= 0x82; /* mask valid bits */
  217. s->config[2] |= 0x40;
  218. s->config[7] &= 0xf7; /* clear zero bit */
  219. assert(I596_NOCRC_INS == 0); /* do CRC insertion */
  220. s->config[10] = MAX(s->config[10], 5); /* min frame length */
  221. s->config[12] &= 0x40; /* only full duplex field valid */
  222. s->config[13] |= 0x3f; /* set ones in byte 13 */
  223. break;
  224. case CmdTDR:
  225. /* get signal LINK */
  226. set_uint32(s->cmd_p + 8, s->lnkst);
  227. break;
  228. case CmdTx:
  229. i82596_transmit(s, s->cmd_p);
  230. break;
  231. case CmdMulticastList:
  232. set_multicast_list(s, s->cmd_p);
  233. break;
  234. case CmdDump:
  235. case CmdDiagnose:
  236. printf("FIXME Command %d !!\n", cmd & 7);
  237. g_assert_not_reached();
  238. }
  239. /* update status */
  240. set_uint16(s->cmd_p, status);
  241. s->cmd_p = get_uint32(s->cmd_p + 4); /* get link address */
  242. DBG(printf("NEXT addr would be %08x\n", s->cmd_p));
  243. if (s->cmd_p == 0) {
  244. s->cmd_p = I596_NULL;
  245. }
  246. /* Stop when last command of the list. */
  247. if (cmd & CMD_EOL) {
  248. s->cmd_p = I596_NULL;
  249. }
  250. /* Suspend after doing cmd? */
  251. if (cmd & CMD_SUSP) {
  252. s->cu_status = CU_SUSPENDED;
  253. printf("FIXME SUSPEND !!\n");
  254. }
  255. /* Interrupt after doing cmd? */
  256. if (cmd & CMD_INTR) {
  257. s->scb_status |= SCB_STATUS_CX;
  258. } else {
  259. s->scb_status &= ~SCB_STATUS_CX;
  260. }
  261. update_scb_status(s);
  262. /* Interrupt after doing cmd? */
  263. if (cmd & CMD_INTR) {
  264. s->send_irq = 1;
  265. }
  266. if (s->cu_status != CU_ACTIVE) {
  267. break;
  268. }
  269. }
  270. DBG(printf("FINISHED COMMAND LOOP\n"));
  271. qemu_flush_queued_packets(qemu_get_queue(s->nic));
  272. }
  273. static void i82596_flush_queue_timer(void *opaque)
  274. {
  275. I82596State *s = opaque;
  276. if (0) {
  277. timer_del(s->flush_queue_timer);
  278. qemu_flush_queued_packets(qemu_get_queue(s->nic));
  279. timer_mod(s->flush_queue_timer,
  280. qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
  281. }
  282. }
  283. static void examine_scb(I82596State *s)
  284. {
  285. uint16_t command, cuc, ruc;
  286. /* get the scb command word */
  287. command = get_uint16(s->scb + 2);
  288. cuc = (command >> 8) & 0x7;
  289. ruc = (command >> 4) & 0x7;
  290. DBG(printf("MAIN COMMAND %04x cuc %02x ruc %02x\n", command, cuc, ruc));
  291. /* and clear the scb command word */
  292. set_uint16(s->scb + 2, 0);
  293. s->scb_status &= ~(command & SCB_COMMAND_ACK_MASK);
  294. switch (cuc) {
  295. case 0: /* no change */
  296. break;
  297. case 1: /* CUC_START */
  298. s->cu_status = CU_ACTIVE;
  299. break;
  300. case 4: /* CUC_ABORT */
  301. s->cu_status = CU_SUSPENDED;
  302. s->scb_status |= SCB_STATUS_CNA; /* CU left active state */
  303. break;
  304. default:
  305. printf("WARNING: Unknown CUC %d!\n", cuc);
  306. }
  307. switch (ruc) {
  308. case 0: /* no change */
  309. break;
  310. case 1: /* RX_START */
  311. case 2: /* RX_RESUME */
  312. s->rx_status = RX_IDLE;
  313. if (USE_TIMER) {
  314. timer_mod(s->flush_queue_timer, qemu_clock_get_ms(
  315. QEMU_CLOCK_VIRTUAL) + 1000);
  316. }
  317. break;
  318. case 3: /* RX_SUSPEND */
  319. case 4: /* RX_ABORT */
  320. s->rx_status = RX_SUSPENDED;
  321. s->scb_status |= SCB_STATUS_RNR; /* RU left active state */
  322. break;
  323. default:
  324. printf("WARNING: Unknown RUC %d!\n", ruc);
  325. }
  326. if (command & 0x80) { /* reset bit set? */
  327. i82596_s_reset(s);
  328. }
  329. /* execute commands from SCBL */
  330. if (s->cu_status != CU_SUSPENDED) {
  331. if (s->cmd_p == I596_NULL) {
  332. s->cmd_p = get_uint32(s->scb + 4);
  333. }
  334. }
  335. /* update scb status */
  336. update_scb_status(s);
  337. command_loop(s);
  338. }
  339. static void signal_ca(I82596State *s)
  340. {
  341. uint32_t iscp = 0;
  342. /* trace_i82596_channel_attention(s); */
  343. if (s->scp) {
  344. /* CA after reset -> do init with new scp. */
  345. s->sysbus = get_byte(s->scp + 3); /* big endian */
  346. DBG(printf("SYSBUS = %08x\n", s->sysbus));
  347. if (((s->sysbus >> 1) & 0x03) != 2) {
  348. printf("WARNING: NO LINEAR MODE !!\n");
  349. }
  350. if ((s->sysbus >> 7)) {
  351. printf("WARNING: 32BIT LINMODE IN B-STEPPING NOT SUPPORTED !!\n");
  352. }
  353. iscp = get_uint32(s->scp + 8);
  354. s->scb = get_uint32(iscp + 4);
  355. set_byte(iscp + 1, 0); /* clear BUSY flag in iscp */
  356. s->scp = 0;
  357. }
  358. s->ca++; /* count ca() */
  359. if (!s->ca_active) {
  360. s->ca_active = 1;
  361. while (s->ca) {
  362. examine_scb(s);
  363. s->ca--;
  364. }
  365. s->ca_active = 0;
  366. }
  367. if (s->send_irq) {
  368. s->send_irq = 0;
  369. qemu_set_irq(s->irq, 1);
  370. }
  371. }
  372. void i82596_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
  373. {
  374. I82596State *s = opaque;
  375. /* printf("i82596_ioport_writew addr=0x%08x val=0x%04x\n", addr, val); */
  376. switch (addr) {
  377. case PORT_RESET: /* Reset */
  378. i82596_s_reset(s);
  379. break;
  380. case PORT_ALTSCP:
  381. s->scp = val;
  382. break;
  383. case PORT_CA:
  384. signal_ca(s);
  385. break;
  386. }
  387. }
  388. uint32_t i82596_ioport_readw(void *opaque, uint32_t addr)
  389. {
  390. return -1;
  391. }
  392. void i82596_h_reset(void *opaque)
  393. {
  394. I82596State *s = opaque;
  395. i82596_s_reset(s);
  396. }
  397. bool i82596_can_receive(NetClientState *nc)
  398. {
  399. I82596State *s = qemu_get_nic_opaque(nc);
  400. if (s->rx_status == RX_SUSPENDED) {
  401. return false;
  402. }
  403. if (!s->lnkst) {
  404. return false;
  405. }
  406. if (USE_TIMER && !timer_pending(s->flush_queue_timer)) {
  407. return true;
  408. }
  409. return true;
  410. }
  411. ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
  412. {
  413. I82596State *s = qemu_get_nic_opaque(nc);
  414. uint32_t rfd_p;
  415. uint32_t rbd;
  416. uint16_t is_broadcast = 0;
  417. size_t len = sz; /* length of data for guest (including CRC) */
  418. size_t bufsz = sz; /* length of data in buf */
  419. uint32_t crc;
  420. uint8_t *crc_ptr;
  421. static const uint8_t broadcast_macaddr[6] = {
  422. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  423. DBG(printf("i82596_receive() start\n"));
  424. if (USE_TIMER && timer_pending(s->flush_queue_timer)) {
  425. return 0;
  426. }
  427. /* first check if receiver is enabled */
  428. if (s->rx_status == RX_SUSPENDED) {
  429. trace_i82596_receive_analysis(">>> Receiving suspended");
  430. return -1;
  431. }
  432. if (!s->lnkst) {
  433. trace_i82596_receive_analysis(">>> Link down");
  434. return -1;
  435. }
  436. /* Received frame smaller than configured "min frame len"? */
  437. if (sz < s->config[10]) {
  438. printf("Received frame too small, %zu vs. %u bytes\n",
  439. sz, s->config[10]);
  440. return -1;
  441. }
  442. DBG(printf("Received %lu bytes\n", sz));
  443. if (I596_PROMISC) {
  444. /* promiscuous: receive all */
  445. trace_i82596_receive_analysis(
  446. ">>> packet received in promiscuous mode");
  447. } else {
  448. if (!memcmp(buf, broadcast_macaddr, 6)) {
  449. /* broadcast address */
  450. if (I596_BC_DISABLE) {
  451. trace_i82596_receive_analysis(">>> broadcast packet rejected");
  452. return len;
  453. }
  454. trace_i82596_receive_analysis(">>> broadcast packet received");
  455. is_broadcast = 1;
  456. } else if (buf[0] & 0x01) {
  457. /* multicast */
  458. if (!I596_MC_ALL) {
  459. trace_i82596_receive_analysis(">>> multicast packet rejected");
  460. return len;
  461. }
  462. int mcast_idx = (net_crc32(buf, ETH_ALEN) & BITS(7, 2)) >> 2;
  463. assert(mcast_idx < 8 * sizeof(s->mult));
  464. if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
  465. trace_i82596_receive_analysis(">>> multicast address mismatch");
  466. return len;
  467. }
  468. trace_i82596_receive_analysis(">>> multicast packet received");
  469. is_broadcast = 1;
  470. } else if (!memcmp(s->conf.macaddr.a, buf, 6)) {
  471. /* match */
  472. trace_i82596_receive_analysis(
  473. ">>> physical address matching packet received");
  474. } else {
  475. trace_i82596_receive_analysis(">>> unknown packet");
  476. return len;
  477. }
  478. }
  479. /* Calculate the ethernet checksum (4 bytes) */
  480. len += 4;
  481. crc = cpu_to_be32(crc32(~0, buf, sz));
  482. crc_ptr = (uint8_t *) &crc;
  483. rfd_p = get_uint32(s->scb + 8); /* get Receive Frame Descriptor */
  484. assert(rfd_p && rfd_p != I596_NULL);
  485. /* get first Receive Buffer Descriptor Address */
  486. rbd = get_uint32(rfd_p + 8);
  487. assert(rbd && rbd != I596_NULL);
  488. trace_i82596_receive_packet(len);
  489. /* PRINT_PKTHDR("Receive", buf); */
  490. while (len) {
  491. uint16_t command, status;
  492. uint32_t next_rfd;
  493. command = get_uint16(rfd_p + 2);
  494. assert(command & CMD_FLEX); /* assert Flex Mode */
  495. /* get first Receive Buffer Descriptor Address */
  496. rbd = get_uint32(rfd_p + 8);
  497. assert(get_uint16(rfd_p + 14) == 0);
  498. /* printf("Receive: rfd is %08x\n", rfd_p); */
  499. while (len) {
  500. uint16_t buffer_size, num;
  501. uint32_t rba;
  502. size_t bufcount, crccount;
  503. /* printf("Receive: rbd is %08x\n", rbd); */
  504. buffer_size = get_uint16(rbd + 12);
  505. /* printf("buffer_size is 0x%x\n", buffer_size); */
  506. assert(buffer_size != 0);
  507. num = buffer_size & SIZE_MASK;
  508. if (num > len) {
  509. num = len;
  510. }
  511. rba = get_uint32(rbd + 8);
  512. /* printf("rba is 0x%x\n", rba); */
  513. /*
  514. * Calculate how many bytes we want from buf[] and how many
  515. * from the CRC.
  516. */
  517. if ((len - num) >= 4) {
  518. /* The whole guest buffer, we haven't hit the CRC yet */
  519. bufcount = num;
  520. } else {
  521. /* All that's left of buf[] */
  522. bufcount = len - 4;
  523. }
  524. crccount = num - bufcount;
  525. if (bufcount > 0) {
  526. /* Still some of the actual data buffer to transfer */
  527. assert(bufsz >= bufcount);
  528. bufsz -= bufcount;
  529. address_space_write(&address_space_memory, rba,
  530. MEMTXATTRS_UNSPECIFIED, buf, bufcount);
  531. rba += bufcount;
  532. buf += bufcount;
  533. len -= bufcount;
  534. }
  535. /* Write as much of the CRC as fits */
  536. if (crccount > 0) {
  537. address_space_write(&address_space_memory, rba,
  538. MEMTXATTRS_UNSPECIFIED, crc_ptr, crccount);
  539. rba += crccount;
  540. crc_ptr += crccount;
  541. len -= crccount;
  542. }
  543. num |= 0x4000; /* set F BIT */
  544. if (len == 0) {
  545. num |= I596_EOF; /* set EOF BIT */
  546. }
  547. set_uint16(rbd + 0, num); /* write actual count with flags */
  548. /* get next rbd */
  549. rbd = get_uint32(rbd + 4);
  550. /* printf("Next Receive: rbd is %08x\n", rbd); */
  551. if (buffer_size & I596_EOF) /* last entry */
  552. break;
  553. }
  554. /* Housekeeping, see pg. 18 */
  555. next_rfd = get_uint32(rfd_p + 4);
  556. set_uint32(next_rfd + 8, rbd);
  557. status = STAT_C | STAT_OK | is_broadcast;
  558. set_uint16(rfd_p, status);
  559. if (command & CMD_SUSP) { /* suspend after command? */
  560. s->rx_status = RX_SUSPENDED;
  561. s->scb_status |= SCB_STATUS_RNR; /* RU left active state */
  562. break;
  563. }
  564. if (command & CMD_EOL) /* was it last Frame Descriptor? */
  565. break;
  566. assert(len == 0);
  567. }
  568. assert(len == 0);
  569. s->scb_status |= SCB_STATUS_FR; /* set "RU finished receiving frame" bit. */
  570. update_scb_status(s);
  571. /* send IRQ that we received data */
  572. qemu_set_irq(s->irq, 1);
  573. /* s->send_irq = 1; */
  574. if (0) {
  575. DBG(printf("Checking:\n"));
  576. rfd_p = get_uint32(s->scb + 8); /* get Receive Frame Descriptor */
  577. DBG(printf("Next Receive: rfd is %08x\n", rfd_p));
  578. rfd_p = get_uint32(rfd_p + 4); /* get Next Receive Frame Descriptor */
  579. DBG(printf("Next Receive: rfd is %08x\n", rfd_p));
  580. /* get first Receive Buffer Descriptor Address */
  581. rbd = get_uint32(rfd_p + 8);
  582. DBG(printf("Next Receive: rbd is %08x\n", rbd));
  583. }
  584. return sz;
  585. }
  586. const VMStateDescription vmstate_i82596 = {
  587. .name = "i82596",
  588. .version_id = 1,
  589. .minimum_version_id = 1,
  590. .fields = (const VMStateField[]) {
  591. VMSTATE_UINT16(lnkst, I82596State),
  592. VMSTATE_TIMER_PTR(flush_queue_timer, I82596State),
  593. VMSTATE_END_OF_LIST()
  594. }
  595. };
  596. void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info)
  597. {
  598. if (s->conf.macaddr.a[0] == 0) {
  599. qemu_macaddr_default_if_unset(&s->conf.macaddr);
  600. }
  601. s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)),
  602. dev->id, &dev->mem_reentrancy_guard, s);
  603. qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
  604. if (USE_TIMER) {
  605. s->flush_queue_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
  606. i82596_flush_queue_timer, s);
  607. }
  608. s->lnkst = 0x8000; /* initial link state: up */
  609. }