Revision 5fafdf24 hw/pcnet.c

b/hw/pcnet.c
1 1
/*
2 2
 * QEMU AMD PC-Net II (Am79C970A) emulation
3
 * 
3
 *
4 4
 * Copyright (c) 2004 Antony T Curtis
5
 * 
5
 *
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
8 8
 * in the Software without restriction, including without limitation the rights
......
21 21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 22
 * THE SOFTWARE.
23 23
 */
24
 
24

  
25 25
/* This software was written to be compatible with the specification:
26 26
 * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
27 27
 * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
28 28
 */
29
 
29

  
30 30
/*
31 31
 * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
32 32
 * produced as NCR89C100. See
......
652 652
static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
653 653
{
654 654
    struct qemu_ether_header *hdr = (void *)buf;
655
    uint8_t padr[6] = { 
655
    uint8_t padr[6] = {
656 656
        s->csr[12] & 0xff, s->csr[12] >> 8,
657 657
        s->csr[13] & 0xff, s->csr[13] >> 8,
658
        s->csr[14] & 0xff, s->csr[14] >> 8 
658
        s->csr[14] & 0xff, s->csr[14] >> 8
659 659
    };
660 660
    int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
661 661
#ifdef PCNET_DEBUG_MATCH
......
683 683
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
684 684
{
685 685
    struct qemu_ether_header *hdr = (void *)buf;
686
    if ((*(hdr->ether_dhost)&0x01) && 
686
    if ((*(hdr->ether_dhost)&0x01) &&
687 687
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
688
        uint8_t ladr[8] = { 
688
        uint8_t ladr[8] = {
689 689
            s->csr[8] & 0xff, s->csr[8] >> 8,
690 690
            s->csr[9] & 0xff, s->csr[9] >> 8,
691
            s->csr[10] & 0xff, s->csr[10] >> 8, 
692
            s->csr[11] & 0xff, s->csr[11] >> 8 
691
            s->csr[10] & 0xff, s->csr[10] >> 8,
692
            s->csr[11] & 0xff, s->csr[11] >> 8
693 693
        };
694 694
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
695 695
        return !!(ladr[index >> 3] & (1 << (index & 7)));
......
697 697
    return 0;
698 698
}
699 699

  
700
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx) 
700
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
701 701
{
702 702
    while (idx < 1) idx += CSR_RCVRL(s);
703 703
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
......
705 705

  
706 706
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
707 707
{
708
    int64_t next_time = current_time + 
709
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)), 
708
    int64_t next_time = current_time +
709
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
710 710
                 ticks_per_sec, 33000000L);
711 711
    if (next_time <= current_time)
712 712
        next_time = current_time + 1;
......
731 731
    s->rdra = 0;
732 732
    s->tdra = 0;
733 733
    s->rap = 0;
734
    
734
   
735 735
    s->bcr[BCR_BSBC] &= ~0x0080;
736 736

  
737 737
    s->csr[0]   = 0x0004;
......
770 770
{
771 771
    int isr = 0;
772 772
    s->csr[0] &= ~0x0080;
773
    
773
   
774 774
#if 1
775 775
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
776 776
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
......
790 790
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
791 791
#endif
792 792
    {
793
       
793
      
794 794
        isr = CSR_INEA(s);
795 795
        s->csr[0] |= 0x0080;
796 796
    }
797
    
797
   
798 798
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
799 799
        s->csr[4] &= ~0x0080;
800 800
        s->csr[4] |= 0x0040;
......
806 806
    }
807 807

  
808 808
#if 1
809
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500) 
809
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
810 810
#else
811 811
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
812 812
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
......
834 834
#ifdef PCNET_DEBUG
835 835
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
836 836
#endif
837
    
837
   
838 838
    if (BCR_SSIZE32(s)) {
839 839
        struct pcnet_initblk32 initblk;
840 840
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
......
893 893
    CSR_XMTRC(s) = CSR_XMTRL(s);
894 894

  
895 895
#ifdef PCNET_DEBUG
896
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", 
896
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
897 897
        BCR_SSIZE32(s),
898 898
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
899 899
#endif
900 900

  
901
    s->csr[0] |= 0x0101;    
901
    s->csr[0] |= 0x0101;   
902 902
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
903 903
}
904 904

  
......
910 910

  
911 911
    if (!CSR_DTX(s))
912 912
        s->csr[0] |= 0x0010;    /* set TXON */
913
        
913
       
914 914
    if (!CSR_DRX(s))
915 915
        s->csr[0] |= 0x0020;    /* set RXON */
916 916

  
......
940 940
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
941 941
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
942 942
#else
943
        target_phys_addr_t crda = s->rdra + 
943
        target_phys_addr_t crda = s->rdra +
944 944
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
945 945
            (BCR_SWSTYLE(s) ? 16 : 8 );
946 946
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
947
        target_phys_addr_t nrda = s->rdra + 
947
        target_phys_addr_t nrda = s->rdra +
948 948
            (CSR_RCVRL(s) - nrdc) *
949 949
            (BCR_SWSTYLE(s) ? 16 : 8 );
950 950
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
951
        target_phys_addr_t nnrd = s->rdra + 
951
        target_phys_addr_t nnrd = s->rdra +
952 952
            (CSR_RCVRL(s) - nnrc) *
953 953
            (BCR_SWSTYLE(s) ? 16 : 8 );
954 954
#endif
......
976 976
#endif
977 977
        }
978 978
    }
979
    
979
   
980 980
    if (CSR_CRDA(s)) {
981 981
        struct pcnet_RMD rmd;
982 982
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
......
991 991
    } else {
992 992
        CSR_CRBC(s) = CSR_CRST(s) = 0;
993 993
    }
994
    
994
   
995 995
    if (CSR_NRDA(s)) {
996 996
        struct pcnet_RMD rmd;
997 997
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
......
1007 1007
{
1008 1008
    s->csr[34] = s->csr[35] = 0;
1009 1009
    if (s->tdra) {
1010
        target_phys_addr_t cxda = s->tdra + 
1010
        target_phys_addr_t cxda = s->tdra +
1011 1011
            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
1012 1012
            (BCR_SWSTYLE(s) ? 16 : 8);
1013 1013
        int bad = 0;
......
1030 1030
    if (CSR_CXDA(s)) {
1031 1031
        struct pcnet_TMD tmd;
1032 1032

  
1033
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
1033
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));               
1034 1034

  
1035 1035
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1036 1036
        CSR_CXST(s) = tmd.status;
1037 1037
    } else {
1038 1038
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1039 1039
    }
1040
    
1040
   
1041 1041
    return !!(CSR_CXST(s) & 0x8000);
1042 1042
}
1043 1043

  
......
1046 1046
    PCNetState *s = opaque;
1047 1047
    if (CSR_STOP(s) || CSR_SPND(s))
1048 1048
        return 0;
1049
        
1049
       
1050 1050
    if (s->recv_pos > 0)
1051 1051
        return 0;
1052 1052

  
......
1076 1076
        size = MIN_BUF_SIZE;
1077 1077
    }
1078 1078

  
1079
    if (CSR_PROM(s) 
1080
        || (is_padr=padr_match(s, buf, size)) 
1079
    if (CSR_PROM(s)
1080
        || (is_padr=padr_match(s, buf, size))
1081 1081
        || (is_bcast=padr_bcast(s, buf, size))
1082 1082
        || (is_ladr=ladr_match(s, buf, size))) {
1083 1083

  
......
1093 1093
                nrda = s->rdra +
1094 1094
                    (CSR_RCVRL(s) - rcvrc) *
1095 1095
                    (BCR_SWSTYLE(s) ? 16 : 8 );
1096
                RMDLOAD(&rmd, PHYSADDR(s,nrda));                  
1096
                RMDLOAD(&rmd, PHYSADDR(s,nrda));                 
1097 1097
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1098 1098
#ifdef PCNET_DEBUG_RMD
1099
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", 
1099
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
1100 1100
                                rcvrc, CSR_RCVRC(s));
1101 1101
#endif
1102 1102
                    CSR_RCVRC(s) = rcvrc;
......
1119 1119
            int pktcount = 0;
1120 1120

  
1121 1121
            memcpy(src, buf, size);
1122
            
1122
           
1123 1123
#if 1
1124 1124
            /* no need to compute the CRC */
1125 1125
            src[size] = 0;
......
1136 1136
                while (size < 46) {
1137 1137
                    src[size++] = 0;
1138 1138
                }
1139
                
1139
               
1140 1140
                while (p != &src[size]) {
1141 1141
                    CRC(fcs, *p++);
1142 1142
                }
......
1178 1178
                            PCNET_RECV_STORE();
1179 1179
                        }
1180 1180
                    }
1181
                }                
1181
                }               
1182 1182
            }
1183 1183

  
1184 1184
#undef PCNET_RECV_STORE
......
1198 1198
            s->csr[0] |= 0x0400;
1199 1199

  
1200 1200
#ifdef PCNET_DEBUG
1201
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
1201
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1202 1202
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1203 1203
#endif
1204 1204
#ifdef PCNET_DEBUG_RMD
1205 1205
            PRINT_RMD(&rmd);
1206
#endif        
1206
#endif       
1207 1207

  
1208 1208
            while (pktcount--) {
1209 1209
                if (CSR_RCVRC(s) <= 1)
1210 1210
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1211 1211
                else
1212
                    CSR_RCVRC(s)--;            
1212
                    CSR_RCVRC(s)--;           
1213 1213
            }
1214
            
1214
           
1215 1215
            pcnet_rdte_poll(s);
1216 1216

  
1217
        }        
1217
        }       
1218 1218
    }
1219 1219

  
1220 1220
    pcnet_poll(s);
1221
    pcnet_update_irq(s);    
1221
    pcnet_update_irq(s);   
1222 1222
}
1223 1223

  
1224 1224
static void pcnet_transmit(PCNetState *s)
......
1226 1226
    target_phys_addr_t xmit_cxda = 0;
1227 1227
    int count = CSR_XMTRL(s)-1;
1228 1228
    s->xmit_pos = -1;
1229
    
1229
   
1230 1230
    if (!CSR_TXON(s)) {
1231 1231
        s->csr[0] &= ~0x0008;
1232 1232
        return;
......
1285 1285
        if (count--)
1286 1286
            goto txagain;
1287 1287

  
1288
    } else 
1288
    } else
1289 1289
    if (s->xmit_pos >= 0) {
1290 1290
        struct pcnet_TMD tmd;
1291 1291
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
......
1311 1311
        pcnet_rdte_poll(s);
1312 1312
    }
1313 1313

  
1314
    if (CSR_TDMD(s) || 
1314
    if (CSR_TDMD(s) ||
1315 1315
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1316 1316
    {
1317 1317
        /* prevent recursion */
......
1332 1332
        pcnet_transmit(s);
1333 1333
    }
1334 1334

  
1335
    pcnet_update_irq(s);    
1335
    pcnet_update_irq(s);   
1336 1336

  
1337 1337
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1338 1338
        uint64_t now = qemu_get_clock(vm_clock) * 33;
......
1346 1346
            } else
1347 1347
                CSR_POLL(s) = t;
1348 1348
        }
1349
        qemu_mod_timer(s->poll_timer, 
1349
        qemu_mod_timer(s->poll_timer,
1350 1350
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1351 1351
    }
1352 1352
}
......
1379 1379
        if (!CSR_STRT(s) && (val & 2))
1380 1380
            pcnet_start(s);
1381 1381

  
1382
        if (CSR_TDMD(s)) 
1382
        if (CSR_TDMD(s))
1383 1383
            pcnet_transmit(s);
1384 1384

  
1385 1385
        return;
......
1434 1434
    case 3:
1435 1435
        break;
1436 1436
    case 4:
1437
        s->csr[4] &= ~(val & 0x026a); 
1437
        s->csr[4] &= ~(val & 0x026a);
1438 1438
        val &= ~0x026a; val |= s->csr[4] & 0x026a;
1439 1439
        break;
1440 1440
    case 5:
1441
        s->csr[5] &= ~(val & 0x0a90); 
1441
        s->csr[5] &= ~(val & 0x0a90);
1442 1442
        val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1443 1443
        break;
1444 1444
    case 16:
......
1592 1592
    PCNetState *s = opaque;
1593 1593
#ifdef PCNET_DEBUG
1594 1594
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1595
#endif    
1595
#endif   
1596 1596
    /* Check APROMWE bit to enable write access */
1597 1597
    if (pcnet_bcr_readw(s,2) & 0x80)
1598 1598
        s->prom[addr & 15] = val;
1599
}       
1599
}      
1600 1600

  
1601 1601
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1602 1602
{
......
1685 1685
        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1686 1686
#ifdef PCNET_DEBUG_IO
1687 1687
        printf("device switched into dword i/o mode\n");
1688
#endif        
1688
#endif       
1689 1689
    }
1690 1690
    pcnet_update_irq(s);
1691 1691
}
......
1695 1695
    PCNetState *s = opaque;
1696 1696
    uint32_t val = -1;
1697 1697
    pcnet_poll_timer(s);
1698
    if (BCR_DWIO(s)) {  
1698
    if (BCR_DWIO(s)) { 
1699 1699
        switch (addr & 0x0f) {
1700 1700
        case 0x00: /* RDP */
1701 1701
            val = pcnet_csr_readw(s, s->rap);
......
1719 1719
    return val;
1720 1720
}
1721 1721

  
1722
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, 
1722
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
1723 1723
                             uint32_t addr, uint32_t size, int type)
1724 1724
{
1725 1725
    PCNetState *d = (PCNetState *)pci_dev;
......
1730 1730

  
1731 1731
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1732 1732
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1733
    
1733
   
1734 1734
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1735 1735
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1736 1736
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
......
1747 1747
        pcnet_aprom_writeb(d, addr & 0x0f, val);
1748 1748
}
1749 1749

  
1750
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr) 
1750
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
1751 1751
{
1752 1752
    PCNetState *d = opaque;
1753 1753
    uint32_t val = -1;
......
1774 1774
    }
1775 1775
}
1776 1776

  
1777
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr) 
1777
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
1778 1778
{
1779 1779
    PCNetState *d = opaque;
1780 1780
    uint32_t val = -1;
......
1809 1809
    }
1810 1810
}
1811 1811

  
1812
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) 
1812
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
1813 1813
{
1814 1814
    PCNetState *d = opaque;
1815 1815
    uint32_t val;
......
1931 1931
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1932 1932
};
1933 1933

  
1934
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, 
1934
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1935 1935
                            uint32_t addr, uint32_t size, int type)
1936 1936
{
1937 1937
    PCNetState *d = (PCNetState *)pci_dev;
......
1961 1961
    uint8_t *pci_conf;
1962 1962

  
1963 1963
#if 0
1964
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
1964
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
1965 1965
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1966 1966
#endif
1967 1967

  
1968 1968
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1969 1969
                                          devfn, NULL, NULL);
1970
                                          
1970
                                         
1971 1971
    pci_conf = d->dev.config;
1972
    
1972
   
1973 1973
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1974
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);    
1975
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007); 
1974
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);   
1975
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
1976 1976
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1977 1977
    pci_conf[0x08] = 0x10;
1978 1978
    pci_conf[0x09] = 0x00;
1979
    pci_conf[0x0a] = 0x00; // ethernet network controller 
1979
    pci_conf[0x0a] = 0x00; // ethernet network controller
1980 1980
    pci_conf[0x0b] = 0x02;
1981 1981
    pci_conf[0x0e] = 0x00; // header_type
1982
    
1982
   
1983 1983
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1984 1984
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1985
    
1985
   
1986 1986
    pci_conf[0x3d] = 1; // interrupt pin 0
1987 1987
    pci_conf[0x3e] = 0x06;
1988 1988
    pci_conf[0x3f] = 0xff;
......
1991 1991
    d->mmio_index =
1992 1992
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
1993 1993

  
1994
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, 
1994
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
1995 1995
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
1996
                           
1997
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, 
1996
                          
1997
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
1998 1998
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
1999
                           
1999
                          
2000 2000
    d->irq = d->dev.irq[0];
2001 2001
    d->phys_mem_read = pci_physical_memory_read;
2002 2002
    d->phys_mem_write = pci_physical_memory_write;

Also available in: Unified diff