~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to hw/net/dp8393x.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
174
174
    AddressSpace as;
175
175
} dp8393xState;
176
176
 
 
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.
 
182
 */
 
183
static uint32_t dp8393x_cdp(dp8393xState *s)
 
184
{
 
185
    return (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP];
 
186
}
 
187
 
 
188
static uint32_t dp8393x_crba(dp8393xState *s)
 
189
{
 
190
    return (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0];
 
191
}
 
192
 
 
193
static uint32_t dp8393x_crda(dp8393xState *s)
 
194
{
 
195
    return (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA];
 
196
}
 
197
 
 
198
static uint32_t dp8393x_rbwc(dp8393xState *s)
 
199
{
 
200
    return (s->regs[SONIC_RBWC1] << 16) | s->regs[SONIC_RBWC0];
 
201
}
 
202
 
 
203
static uint32_t dp8393x_rrp(dp8393xState *s)
 
204
{
 
205
    return (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP];
 
206
}
 
207
 
 
208
static uint32_t dp8393x_tsa(dp8393xState *s)
 
209
{
 
210
    return (s->regs[SONIC_TSA1] << 16) | s->regs[SONIC_TSA0];
 
211
}
 
212
 
 
213
static uint32_t dp8393x_ttda(dp8393xState *s)
 
214
{
 
215
    return (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA];
 
216
}
 
217
 
 
218
static uint32_t dp8393x_wt(dp8393xState *s)
 
219
{
 
220
    return s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
 
221
}
 
222
 
177
223
static void dp8393x_update_irq(dp8393xState *s)
178
224
{
179
225
    int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0;
203
249
 
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;
222
267
    }
223
268
 
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);
248
291
 
249
292
    /* Update SONIC registers */
292
335
        return;
293
336
    }
294
337
 
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);
309
352
    }
310
353
 
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];
 
355
    val = dp8393x_wt(s);
313
356
    val -= elapsed / 5000000;
314
357
    s->regs[SONIC_WT1] = (val >> 16) & 0xffff;
315
358
    s->regs[SONIC_WT0] = (val >> 0)  & 0xffff;
356
399
 
357
400
    while (1) {
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);
366
408
        tx_len = 0;
367
409
 
386
428
            if (tx_len + len > sizeof(s->tx_buffer)) {
387
429
                len = sizeof(s->tx_buffer) - tx_len;
388
430
            }
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);
392
433
            tx_len += len;
393
434
 
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],
 
474
            dp8393x_ttda(s),
434
475
            MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1);
435
476
 
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,
 
481
                dp8393x_ttda(s) +
 
482
                             sizeof(uint16_t) *
 
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));
720
763
 
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;
729
772
    rx_len += 4;
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;
736
779
 
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;
740
783
    }
741
784
    s->regs[SONIC_RCR] |= packet_type;
746
789
    }
747
790
 
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);
758
801
 
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;
768
810
    } else {
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;