177
/* Accessor functions for values which are formed by
178
* concatenating two 16 bit device registers. By putting these
179
* in their own functions with a uint32_t return type we avoid the
180
* pitfall of implicit sign extension where ((x << 16) | y) is a
181
* signed 32 bit integer that might get sign-extended to a 64 bit integer.
183
static uint32_t dp8393x_cdp(dp8393xState *s)
185
return (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP];
188
static uint32_t dp8393x_crba(dp8393xState *s)
190
return (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0];
193
static uint32_t dp8393x_crda(dp8393xState *s)
195
return (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA];
198
static uint32_t dp8393x_rbwc(dp8393xState *s)
200
return (s->regs[SONIC_RBWC1] << 16) | s->regs[SONIC_RBWC0];
203
static uint32_t dp8393x_rrp(dp8393xState *s)
205
return (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP];
208
static uint32_t dp8393x_tsa(dp8393xState *s)
210
return (s->regs[SONIC_TSA1] << 16) | s->regs[SONIC_TSA0];
213
static uint32_t dp8393x_ttda(dp8393xState *s)
215
return (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA];
218
static uint32_t dp8393x_wt(dp8393xState *s)
220
return s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
177
223
static void dp8393x_update_irq(dp8393xState *s)
179
225
int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0;
204
250
while (s->regs[SONIC_CDC] & 0x1f) {
205
251
/* Fill current entry */
206
address_space_rw(&s->as,
207
(s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP],
252
address_space_rw(&s->as, dp8393x_cdp(s),
208
253
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
209
254
s->cam[index][0] = data[1 * width] & 0xff;
210
255
s->cam[index][1] = data[1 * width] >> 8;
224
269
/* Read CAM enable */
225
address_space_rw(&s->as,
226
(s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP],
270
address_space_rw(&s->as, dp8393x_cdp(s),
227
271
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
228
272
s->regs[SONIC_CE] = data[0 * width];
229
273
DPRINTF("load cam done. cam enable mask 0x%04x\n", s->regs[SONIC_CE]);
242
286
/* Read memory */
243
287
width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;
244
288
size = sizeof(uint16_t) * 4 * width;
245
address_space_rw(&s->as,
246
(s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP],
289
address_space_rw(&s->as, dp8393x_rrp(s),
247
290
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
249
292
/* Update SONIC registers */
295
ticks = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
338
ticks = dp8393x_wt(s);
296
339
s->wt_last_update = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
297
340
delay = NANOSECONDS_PER_SECOND * ticks / 5000000;
298
341
timer_mod(s->watchdog, s->wt_last_update + delay);
311
354
elapsed = s->wt_last_update - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
312
val = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
313
356
val -= elapsed / 5000000;
314
357
s->regs[SONIC_WT1] = (val >> 16) & 0xffff;
315
358
s->regs[SONIC_WT0] = (val >> 0) & 0xffff;
358
401
/* Read memory */
359
DPRINTF("Transmit packet at %08x\n",
360
(s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_CTDA]);
361
402
size = sizeof(uint16_t) * 6 * width;
362
403
s->regs[SONIC_TTDA] = s->regs[SONIC_CTDA];
404
DPRINTF("Transmit packet at %08x\n", dp8393x_ttda(s));
363
405
address_space_rw(&s->as,
364
((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + sizeof(uint16_t) * width,
406
dp8393x_ttda(s) + sizeof(uint16_t) * width,
365
407
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
386
428
if (tx_len + len > sizeof(s->tx_buffer)) {
387
429
len = sizeof(s->tx_buffer) - tx_len;
389
address_space_rw(&s->as,
390
(s->regs[SONIC_TSA1] << 16) | s->regs[SONIC_TSA0],
431
address_space_rw(&s->as, dp8393x_tsa(s),
391
432
MEMTXATTRS_UNSPECIFIED, &s->tx_buffer[tx_len], len, 0);
396
437
/* Read next fragment details */
397
438
size = sizeof(uint16_t) * 3 * width;
398
439
address_space_rw(&s->as,
399
((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + sizeof(uint16_t) * (4 + 3 * i) * width,
440
dp8393x_ttda(s) + sizeof(uint16_t) * (4 + 3 * i) * width,
400
441
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
401
442
s->regs[SONIC_TSA0] = data[0 * width];
402
443
s->regs[SONIC_TSA1] = data[1 * width];
430
471
data[0 * width] = s->regs[SONIC_TCR] & 0x0fff; /* status */
431
472
size = sizeof(uint16_t) * width;
432
473
address_space_rw(&s->as,
433
(s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA],
434
475
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1);
436
477
if (!(s->regs[SONIC_CR] & SONIC_CR_HTX)) {
437
478
/* Read footer of packet */
438
479
size = sizeof(uint16_t) * width;
439
480
address_space_rw(&s->as,
440
((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + sizeof(uint16_t) * (4 + 3 * s->regs[SONIC_TFC]) * width,
483
(4 + 3 * s->regs[SONIC_TFC]) * width,
441
484
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
442
485
s->regs[SONIC_CTDA] = data[0 * width] & ~0x1;
443
486
if (data[0 * width] & 0x1) {
700
743
if (s->regs[SONIC_LLFA] & 0x1) {
701
744
/* Are we still in resource exhaustion? */
702
745
size = sizeof(uint16_t) * 1 * width;
703
address = ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width;
746
address = dp8393x_crda(s) + sizeof(uint16_t) * 5 * width;
704
747
address_space_rw(&s->as, address, MEMTXATTRS_UNSPECIFIED,
705
748
(uint8_t *)data, size, 0);
706
749
if (data[0 * width] & 0x1) {
719
762
checksum = cpu_to_le32(crc32(0, buf, rx_len));
721
764
/* Put packet into RBA */
722
DPRINTF("Receive packet at %08x\n", (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0]);
723
address = (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0];
765
DPRINTF("Receive packet at %08x\n", dp8393x_crba(s));
766
address = dp8393x_crba(s);
724
767
address_space_rw(&s->as, address,
725
768
MEMTXATTRS_UNSPECIFIED, (uint8_t *)buf, rx_len, 1);
726
769
address += rx_len;
730
773
s->regs[SONIC_CRBA1] = address >> 16;
731
774
s->regs[SONIC_CRBA0] = address & 0xffff;
732
available = (s->regs[SONIC_RBWC1] << 16) | s->regs[SONIC_RBWC0];
775
available = dp8393x_rbwc(s);
733
776
available -= rx_len / 2;
734
777
s->regs[SONIC_RBWC1] = available >> 16;
735
778
s->regs[SONIC_RBWC0] = available & 0xffff;
737
780
/* Update status */
738
if (((s->regs[SONIC_RBWC1] << 16) | s->regs[SONIC_RBWC0]) < s->regs[SONIC_EOBC]) {
781
if (dp8393x_rbwc(s) < s->regs[SONIC_EOBC]) {
739
782
s->regs[SONIC_RCR] |= SONIC_RCR_LPKT;
741
784
s->regs[SONIC_RCR] |= packet_type;
748
791
/* Write status to memory */
749
DPRINTF("Write status at %08x\n", (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]);
792
DPRINTF("Write status at %08x\n", dp8393x_crda(s));
750
793
data[0 * width] = s->regs[SONIC_RCR]; /* status */
751
794
data[1 * width] = rx_len; /* byte count */
752
795
data[2 * width] = s->regs[SONIC_TRBA0]; /* pkt_ptr0 */
753
796
data[3 * width] = s->regs[SONIC_TRBA1]; /* pkt_ptr1 */
754
797
data[4 * width] = s->regs[SONIC_RSC]; /* seq_no */
755
798
size = sizeof(uint16_t) * 5 * width;
756
address_space_rw(&s->as, (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA],
799
address_space_rw(&s->as, dp8393x_crda(s),
757
800
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1);
759
802
/* Move to next descriptor */
760
803
size = sizeof(uint16_t) * width;
761
address_space_rw(&s->as,
762
((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width,
804
address_space_rw(&s->as, dp8393x_crda(s) + sizeof(uint16_t) * 5 * width,
763
805
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
764
806
s->regs[SONIC_LLFA] = data[0 * width];
765
807
if (s->regs[SONIC_LLFA] & 0x1) {
767
809
s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
769
811
data[0 * width] = 0; /* in_use */
770
address_space_rw(&s->as,
771
((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 6 * width,
812
address_space_rw(&s->as, dp8393x_crda(s) + sizeof(uint16_t) * 6 * width,
772
813
MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint16_t), 1);
773
814
s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
774
815
s->regs[SONIC_ISR] |= SONIC_ISR_PKTRX;