Lines Matching full:s

65 #define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)  argument
66 #define CSR_STRT(S) !!(((S)->csr[0])&0x0002) argument
67 #define CSR_STOP(S) !!(((S)->csr[0])&0x0004) argument
68 #define CSR_TDMD(S) !!(((S)->csr[0])&0x0008) argument
69 #define CSR_TXON(S) !!(((S)->csr[0])&0x0010) argument
70 #define CSR_RXON(S) !!(((S)->csr[0])&0x0020) argument
71 #define CSR_INEA(S) !!(((S)->csr[0])&0x0040) argument
72 #define CSR_BSWP(S) !!(((S)->csr[3])&0x0004) argument
73 #define CSR_LAPPEN(S) !!(((S)->csr[3])&0x0020) argument
74 #define CSR_DXSUFLO(S) !!(((S)->csr[3])&0x0040) argument
75 #define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800) argument
76 #define CSR_DPOLL(S) !!(((S)->csr[4])&0x1000) argument
77 #define CSR_SPND(S) !!(((S)->csr[5])&0x0001) argument
78 #define CSR_LTINTEN(S) !!(((S)->csr[5])&0x4000) argument
79 #define CSR_TOKINTD(S) !!(((S)->csr[5])&0x8000) argument
80 #define CSR_DRX(S) !!(((S)->csr[15])&0x0001) argument
81 #define CSR_DTX(S) !!(((S)->csr[15])&0x0002) argument
82 #define CSR_LOOP(S) !!(((S)->csr[15])&0x0004) argument
83 #define CSR_DXMTFCS(S) !!(((S)->csr[15])&0x0008) argument
84 #define CSR_INTL(S) !!(((S)->csr[15])&0x0040) argument
85 #define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000) argument
86 #define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000) argument
87 #define CSR_PROM(S) !!(((S)->csr[15])&0x8000) argument
89 #define CSR_CRBC(S) ((S)->csr[40]) argument
90 #define CSR_CRST(S) ((S)->csr[41]) argument
91 #define CSR_CXBC(S) ((S)->csr[42]) argument
92 #define CSR_CXST(S) ((S)->csr[43]) argument
93 #define CSR_NRBC(S) ((S)->csr[44]) argument
94 #define CSR_NRST(S) ((S)->csr[45]) argument
95 #define CSR_POLL(S) ((S)->csr[46]) argument
96 #define CSR_PINT(S) ((S)->csr[47]) argument
97 #define CSR_RCVRC(S) ((S)->csr[72]) argument
98 #define CSR_XMTRC(S) ((S)->csr[74]) argument
99 #define CSR_RCVRL(S) ((S)->csr[76]) argument
100 #define CSR_XMTRL(S) ((S)->csr[78]) argument
101 #define CSR_MISSC(S) ((S)->csr[112]) argument
103 #define CSR_IADR(S) ((S)->csr[ 1] | ((uint32_t)(S)->csr[ 2] << 16)) argument
104 #define CSR_CRBA(S) ((S)->csr[18] | ((uint32_t)(S)->csr[19] << 16)) argument
105 #define CSR_CXBA(S) ((S)->csr[20] | ((uint32_t)(S)->csr[21] << 16)) argument
106 #define CSR_NRBA(S) ((S)->csr[22] | ((uint32_t)(S)->csr[23] << 16)) argument
107 #define CSR_BADR(S) ((S)->csr[24] | ((uint32_t)(S)->csr[25] << 16)) argument
108 #define CSR_NRDA(S) ((S)->csr[26] | ((uint32_t)(S)->csr[27] << 16)) argument
109 #define CSR_CRDA(S) ((S)->csr[28] | ((uint32_t)(S)->csr[29] << 16)) argument
110 #define CSR_BADX(S) ((S)->csr[30] | ((uint32_t)(S)->csr[31] << 16)) argument
111 #define CSR_NXDA(S) ((S)->csr[32] | ((uint32_t)(S)->csr[33] << 16)) argument
112 #define CSR_CXDA(S) ((S)->csr[34] | ((uint32_t)(S)->csr[35] << 16)) argument
113 #define CSR_NNRD(S) ((S)->csr[36] | ((uint32_t)(S)->csr[37] << 16)) argument
114 #define CSR_NNXD(S) ((S)->csr[38] | ((uint32_t)(S)->csr[39] << 16)) argument
115 #define CSR_PXDA(S) ((S)->csr[60] | ((uint32_t)(S)->csr[61] << 16)) argument
116 #define CSR_NXBA(S) ((S)->csr[64] | ((uint32_t)(S)->csr[65] << 16)) argument
118 #define PHYSADDR(S,A) \ argument
119 (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
299 static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, in pcnet_tmd_load() argument
302 if (!BCR_SSIZE32(s)) { in pcnet_tmd_load()
308 s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0); in pcnet_tmd_load()
315 s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0); in pcnet_tmd_load()
321 if (BCR_SWSTYLE(s) == 3) { in pcnet_tmd_load()
329 static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd, in pcnet_tmd_store() argument
332 if (!BCR_SSIZE32(s)) { in pcnet_tmd_store()
342 s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0); in pcnet_tmd_store()
356 if (BCR_SWSTYLE(s) == 3) { in pcnet_tmd_store()
361 s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0); in pcnet_tmd_store()
365 static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, in pcnet_rmd_load() argument
368 if (!BCR_SSIZE32(s)) { in pcnet_rmd_load()
374 s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); in pcnet_rmd_load()
381 s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0); in pcnet_rmd_load()
387 if (BCR_SWSTYLE(s) == 3) { in pcnet_rmd_load()
395 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, in pcnet_rmd_store() argument
398 if (!BCR_SSIZE32(s)) { in pcnet_rmd_store()
408 s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); in pcnet_rmd_store()
422 if (BCR_SWSTYLE(s) == 3) { in pcnet_rmd_store()
427 s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); in pcnet_rmd_store()
432 #define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
434 #define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
436 #define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
438 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
458 switch (BCR_SWSTYLE(s)) { \
462 s->phys_mem_read(s->dma_opaque, (ADDR), \
472 s->phys_mem_read(s->dma_opaque, (ADDR), \
481 s->phys_mem_read(s->dma_opaque, (ADDR), \
491 switch (BCR_SWSTYLE(s)) { \
495 s->phys_mem_read(s->dma_opaque, (ADDR), \
505 s->phys_mem_read(s->dma_opaque, (ADDR), \
600 static inline int padr_match(PCNetState *s, const uint8_t *buf, int size) in padr_match() argument
604 s->csr[12] & 0xff, s->csr[12] >> 8, in padr_match()
605 s->csr[13] & 0xff, s->csr[13] >> 8, in padr_match()
606 s->csr[14] & 0xff, s->csr[14] >> 8 in padr_match()
608 int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6); in padr_match()
620 static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size) in padr_bcast() argument
624 int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6); in padr_bcast()
631 static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size) in ladr_match() argument
635 (s->csr[8] | s->csr[9] | s->csr[10] | s->csr[11]) != 0) { in ladr_match()
637 s->csr[8] & 0xff, s->csr[8] >> 8, in ladr_match()
638 s->csr[9] & 0xff, s->csr[9] >> 8, in ladr_match()
639 s->csr[10] & 0xff, s->csr[10] >> 8, in ladr_match()
640 s->csr[11] & 0xff, s->csr[11] >> 8 in ladr_match()
648 static inline hwaddr pcnet_rdra_addr(PCNetState *s, int idx) in pcnet_rdra_addr() argument
651 idx += CSR_RCVRL(s); in pcnet_rdra_addr()
653 return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8)); in pcnet_rdra_addr()
656 static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time) in pcnet_get_next_poll_time() argument
659 (65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s))) * 30; in pcnet_get_next_poll_time()
667 static void pcnet_poll(PCNetState *s);
670 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
671 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
672 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
674 static void pcnet_s_reset(PCNetState *s) in pcnet_s_reset() argument
676 trace_pcnet_s_reset(s); in pcnet_s_reset()
678 s->rdra = 0; in pcnet_s_reset()
679 s->tdra = 0; in pcnet_s_reset()
680 s->rap = 0; in pcnet_s_reset()
682 s->bcr[BCR_BSBC] &= ~0x0080; in pcnet_s_reset()
684 s->csr[0] = 0x0004; in pcnet_s_reset()
685 s->csr[3] = 0x0000; in pcnet_s_reset()
686 s->csr[4] = 0x0115; in pcnet_s_reset()
687 s->csr[5] = 0x0000; in pcnet_s_reset()
688 s->csr[6] = 0x0000; in pcnet_s_reset()
689 s->csr[8] = 0; in pcnet_s_reset()
690 s->csr[9] = 0; in pcnet_s_reset()
691 s->csr[10] = 0; in pcnet_s_reset()
692 s->csr[11] = 0; in pcnet_s_reset()
693 s->csr[12] = le16_to_cpu(((uint16_t *)&s->prom[0])[0]); in pcnet_s_reset()
694 s->csr[13] = le16_to_cpu(((uint16_t *)&s->prom[0])[1]); in pcnet_s_reset()
695 s->csr[14] = le16_to_cpu(((uint16_t *)&s->prom[0])[2]); in pcnet_s_reset()
696 s->csr[15] &= 0x21c4; in pcnet_s_reset()
697 s->csr[72] = 1; in pcnet_s_reset()
698 s->csr[74] = 1; in pcnet_s_reset()
699 s->csr[76] = 1; in pcnet_s_reset()
700 s->csr[78] = 1; in pcnet_s_reset()
701 s->csr[80] = 0x1410; in pcnet_s_reset()
702 s->csr[88] = 0x1003; in pcnet_s_reset()
703 s->csr[89] = 0x0262; in pcnet_s_reset()
704 s->csr[94] = 0x0000; in pcnet_s_reset()
705 s->csr[100] = 0x0200; in pcnet_s_reset()
706 s->csr[103] = 0x0105; in pcnet_s_reset()
707 s->csr[112] = 0x0000; in pcnet_s_reset()
708 s->csr[114] = 0x0000; in pcnet_s_reset()
709 s->csr[122] = 0x0000; in pcnet_s_reset()
710 s->csr[124] = 0x0000; in pcnet_s_reset()
712 s->tx_busy = 0; in pcnet_s_reset()
715 static void pcnet_update_irq(PCNetState *s) in pcnet_update_irq() argument
718 s->csr[0] &= ~0x0080; in pcnet_update_irq()
721 if (((s->csr[0] & ~s->csr[3]) & 0x5f00) || in pcnet_update_irq()
722 (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) || in pcnet_update_irq()
723 (((s->csr[5]>>1) & s->csr[5]) & 0x0048)) in pcnet_update_irq()
725 if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ || in pcnet_update_irq()
726 (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ || in pcnet_update_irq()
727 (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ || in pcnet_update_irq()
728 (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ || in pcnet_update_irq()
729 (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ || in pcnet_update_irq()
730 (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ || in pcnet_update_irq()
731 (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ || in pcnet_update_irq()
732 (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ || in pcnet_update_irq()
733 (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ || in pcnet_update_irq()
734 (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ || in pcnet_update_irq()
735 (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ || in pcnet_update_irq()
736 (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */) in pcnet_update_irq()
740 isr = CSR_INEA(s); in pcnet_update_irq()
741 s->csr[0] |= 0x0080; in pcnet_update_irq()
744 if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */ in pcnet_update_irq()
745 s->csr[4] &= ~0x0080; in pcnet_update_irq()
746 s->csr[4] |= 0x0040; in pcnet_update_irq()
747 s->csr[0] |= 0x0080; in pcnet_update_irq()
749 trace_pcnet_user_int(s); in pcnet_update_irq()
753 if (((s->csr[5]>>1) & s->csr[5]) & 0x0500) in pcnet_update_irq()
755 if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ || in pcnet_update_irq()
756 (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ ) in pcnet_update_irq()
760 s->csr[0] |= 0x0080; in pcnet_update_irq()
763 if (isr != s->isr) { in pcnet_update_irq()
764 trace_pcnet_isr_change(s, isr, s->isr); in pcnet_update_irq()
766 qemu_set_irq(s->irq, isr); in pcnet_update_irq()
767 s->isr = isr; in pcnet_update_irq()
770 static void pcnet_init(PCNetState *s) in pcnet_init() argument
776 trace_pcnet_init(s, PHYSADDR(s, CSR_IADR(s))); in pcnet_init()
778 if (BCR_SSIZE32(s)) { in pcnet_init()
780 s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)), in pcnet_init()
796 s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)), in pcnet_init()
814 trace_pcnet_rlen_tlen(s, rlen, tlen); in pcnet_init()
816 CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512; in pcnet_init()
817 CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512; in pcnet_init()
818 s->csr[ 6] = (tlen << 12) | (rlen << 8); in pcnet_init()
819 s->csr[15] = mode; in pcnet_init()
820 s->csr[ 8] = ladrf[0]; in pcnet_init()
821 s->csr[ 9] = ladrf[1]; in pcnet_init()
822 s->csr[10] = ladrf[2]; in pcnet_init()
823 s->csr[11] = ladrf[3]; in pcnet_init()
824 s->csr[12] = padr[0]; in pcnet_init()
825 s->csr[13] = padr[1]; in pcnet_init()
826 s->csr[14] = padr[2]; in pcnet_init()
827 s->rdra = PHYSADDR(s, rdra); in pcnet_init()
828 s->tdra = PHYSADDR(s, tdra); in pcnet_init()
830 CSR_RCVRC(s) = CSR_RCVRL(s); in pcnet_init()
831 CSR_XMTRC(s) = CSR_XMTRL(s); in pcnet_init()
833 trace_pcnet_ss32_rdra_tdra(s, BCR_SSIZE32(s), in pcnet_init()
834 s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s)); in pcnet_init()
836 s->csr[0] |= 0x0101; in pcnet_init()
837 s->csr[0] &= ~0x0004; /* clear STOP bit */ in pcnet_init()
839 qemu_flush_queued_packets(qemu_get_queue(s->nic)); in pcnet_init()
842 static void pcnet_start(PCNetState *s) in pcnet_start() argument
848 if (!CSR_DTX(s)) { in pcnet_start()
849 s->csr[0] |= 0x0010; /* set TXON */ in pcnet_start()
851 if (!CSR_DRX(s)) { in pcnet_start()
852 s->csr[0] |= 0x0020; /* set RXON */ in pcnet_start()
854 s->csr[0] &= ~0x0004; /* clear STOP bit */ in pcnet_start()
855 s->csr[0] |= 0x0002; in pcnet_start()
856 pcnet_poll_timer(s); in pcnet_start()
858 qemu_flush_queued_packets(qemu_get_queue(s->nic)); in pcnet_start()
861 static void pcnet_stop(PCNetState *s) in pcnet_stop() argument
866 s->csr[0] &= ~0xffeb; in pcnet_stop()
867 s->csr[0] |= 0x0014; in pcnet_stop()
868 s->csr[4] &= ~0x02c2; in pcnet_stop()
869 s->csr[5] &= ~0x0011; in pcnet_stop()
870 pcnet_poll_timer(s); in pcnet_stop()
873 static void pcnet_rdte_poll(PCNetState *s) in pcnet_rdte_poll() argument
875 s->csr[28] = s->csr[29] = 0; in pcnet_rdte_poll()
876 if (s->rdra) { in pcnet_rdte_poll()
879 hwaddr crda = pcnet_rdra_addr(s, CSR_RCVRC(s)); in pcnet_rdte_poll()
880 hwaddr nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s)); in pcnet_rdte_poll()
881 hwaddr nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s)); in pcnet_rdte_poll()
883 hwaddr crda = s->rdra + in pcnet_rdte_poll()
884 (CSR_RCVRL(s) - CSR_RCVRC(s)) * in pcnet_rdte_poll()
885 (BCR_SWSTYLE(s) ? 16 : 8 ); in pcnet_rdte_poll()
886 int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1; in pcnet_rdte_poll()
887 hwaddr nrda = s->rdra + in pcnet_rdte_poll()
888 (CSR_RCVRL(s) - nrdc) * in pcnet_rdte_poll()
889 (BCR_SWSTYLE(s) ? 16 : 8 ); in pcnet_rdte_poll()
890 int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1; in pcnet_rdte_poll()
891 hwaddr nnrd = s->rdra + in pcnet_rdte_poll()
892 (CSR_RCVRL(s) - nnrc) * in pcnet_rdte_poll()
893 (BCR_SWSTYLE(s) ? 16 : 8 ); in pcnet_rdte_poll()
903 s->csr[28] = crda & 0xffff; in pcnet_rdte_poll()
904 s->csr[29] = crda >> 16; in pcnet_rdte_poll()
905 s->csr[26] = nrda & 0xffff; in pcnet_rdte_poll()
906 s->csr[27] = nrda >> 16; in pcnet_rdte_poll()
907 s->csr[36] = nnrd & 0xffff; in pcnet_rdte_poll()
908 s->csr[37] = nnrd >> 16; in pcnet_rdte_poll()
920 if (CSR_CRDA(s)) { in pcnet_rdte_poll()
922 RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s))); in pcnet_rdte_poll()
923 CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT); in pcnet_rdte_poll()
924 CSR_CRST(s) = rmd.status; in pcnet_rdte_poll()
927 PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s), in pcnet_rdte_poll()
932 CSR_CRBC(s) = CSR_CRST(s) = 0; in pcnet_rdte_poll()
935 if (CSR_NRDA(s)) { in pcnet_rdte_poll()
937 RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s))); in pcnet_rdte_poll()
938 CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT); in pcnet_rdte_poll()
939 CSR_NRST(s) = rmd.status; in pcnet_rdte_poll()
941 CSR_NRBC(s) = CSR_NRST(s) = 0; in pcnet_rdte_poll()
946 static int pcnet_tdte_poll(PCNetState *s) in pcnet_tdte_poll() argument
948 s->csr[34] = s->csr[35] = 0; in pcnet_tdte_poll()
949 if (s->tdra) { in pcnet_tdte_poll()
950 hwaddr cxda = s->tdra + in pcnet_tdte_poll()
951 (CSR_XMTRL(s) - CSR_XMTRC(s)) * in pcnet_tdte_poll()
952 (BCR_SWSTYLE(s) ? 16 : 8); in pcnet_tdte_poll()
956 if (CSR_CXDA(s) != cxda) { in pcnet_tdte_poll()
957 s->csr[60] = s->csr[34]; in pcnet_tdte_poll()
958 s->csr[61] = s->csr[35]; in pcnet_tdte_poll()
959 s->csr[62] = CSR_CXBC(s); in pcnet_tdte_poll()
960 s->csr[63] = CSR_CXST(s); in pcnet_tdte_poll()
962 s->csr[34] = cxda & 0xffff; in pcnet_tdte_poll()
963 s->csr[35] = cxda >> 16; in pcnet_tdte_poll()
970 if (CSR_CXDA(s)) { in pcnet_tdte_poll()
973 TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); in pcnet_tdte_poll()
975 CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT); in pcnet_tdte_poll()
976 CSR_CXST(s) = tmd.status; in pcnet_tdte_poll()
978 CSR_CXBC(s) = CSR_CXST(s) = 0; in pcnet_tdte_poll()
981 return !!(CSR_CXST(s) & 0x8000); in pcnet_tdte_poll()
988 PCNetState *s = qemu_get_nic_opaque(nc); in pcnet_receive() local
994 if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size || in pcnet_receive()
995 (CSR_LOOP(s) && !s->looptest)) { in pcnet_receive()
1002 if (CSR_PROM(s) in pcnet_receive()
1003 || (is_padr=padr_match(s, buf, size)) in pcnet_receive()
1004 || (is_bcast=padr_bcast(s, buf, size)) in pcnet_receive()
1005 || (is_ladr=ladr_match(s, buf, size))) { in pcnet_receive()
1007 pcnet_rdte_poll(s); in pcnet_receive()
1009 if (!(CSR_CRST(s) & 0x8000) && s->rdra) { in pcnet_receive()
1011 int rcvrc = CSR_RCVRC(s)-1,i; in pcnet_receive()
1013 for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) { in pcnet_receive()
1015 rcvrc = CSR_RCVRL(s); in pcnet_receive()
1016 nrda = s->rdra + in pcnet_receive()
1017 (CSR_RCVRL(s) - rcvrc) * in pcnet_receive()
1018 (BCR_SWSTYLE(s) ? 16 : 8 ); in pcnet_receive()
1023 rcvrc, CSR_RCVRC(s)); in pcnet_receive()
1025 CSR_RCVRC(s) = rcvrc; in pcnet_receive()
1026 pcnet_rdte_poll(s); in pcnet_receive()
1032 if (!(CSR_CRST(s) & 0x8000)) { in pcnet_receive()
1034 printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s)); in pcnet_receive()
1036 s->csr[0] |= 0x1000; /* Set MISS flag */ in pcnet_receive()
1037 CSR_MISSC(s)++; in pcnet_receive()
1039 uint8_t *src = s->buffer; in pcnet_receive()
1040 hwaddr crda = CSR_CRDA(s); in pcnet_receive()
1044 if (!s->looptest) { in pcnet_receive()
1058 } else if (s->looptest == PCNET_LOOPTEST_CRC || in pcnet_receive()
1059 !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) { in pcnet_receive()
1080 RMDLOAD(&rmd, PHYSADDR(s,crda)); in pcnet_receive()
1081 /*if (!CSR_LAPPEN(s))*/ in pcnet_receive()
1086 hwaddr rbadr = PHYSADDR(s, rmd.rbadr); \ in pcnet_receive()
1087 s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \ in pcnet_receive()
1090 RMDSTORE(&rmd, PHYSADDR(s,crda)); \ in pcnet_receive()
1096 if ((remaining > 0) && CSR_NRDA(s)) { in pcnet_receive()
1097 hwaddr nrda = CSR_NRDA(s); in pcnet_receive()
1101 RMDLOAD(&rmd, PHYSADDR(s,nrda)); in pcnet_receive()
1108 if ((remaining > 0) && (nrda=CSR_NNRD(s))) { in pcnet_receive()
1109 RMDLOAD(&rmd, PHYSADDR(s,nrda)); in pcnet_receive()
1120 RMDLOAD(&rmd, PHYSADDR(s,crda)); in pcnet_receive()
1124 SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr); in pcnet_receive()
1125 SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr); in pcnet_receive()
1126 SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast); in pcnet_receive()
1136 RMDSTORE(&rmd, PHYSADDR(s,crda)); in pcnet_receive()
1137 s->csr[0] |= 0x0400; in pcnet_receive()
1141 CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount); in pcnet_receive()
1148 if (CSR_RCVRC(s) <= 1) { in pcnet_receive()
1149 CSR_RCVRC(s) = CSR_RCVRL(s); in pcnet_receive()
1151 CSR_RCVRC(s)--; in pcnet_receive()
1155 pcnet_rdte_poll(s); in pcnet_receive()
1160 pcnet_poll(s); in pcnet_receive()
1161 pcnet_update_irq(s); in pcnet_receive()
1173 static void pcnet_transmit(PCNetState *s) in pcnet_transmit() argument
1176 int count = CSR_XMTRL(s)-1; in pcnet_transmit()
1179 s->xmit_pos = -1; in pcnet_transmit()
1181 if (!CSR_TXON(s)) { in pcnet_transmit()
1182 s->csr[0] &= ~0x0008; in pcnet_transmit()
1186 s->tx_busy = 1; in pcnet_transmit()
1189 if (pcnet_tdte_poll(s)) { in pcnet_transmit()
1192 TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); in pcnet_transmit()
1195 printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s))); in pcnet_transmit()
1199 s->xmit_pos = 0; in pcnet_transmit()
1200 xmit_cxda = PHYSADDR(s,CSR_CXDA(s)); in pcnet_transmit()
1201 if (BCR_SWSTYLE(s) != 1) in pcnet_transmit()
1204 if (s->lnkst == 0 && in pcnet_transmit()
1205 (!CSR_LOOP(s) || (!CSR_INTL(s) && !BCR_TMAULOOP(s)))) { in pcnet_transmit()
1209 s->csr[0] |= 0xa000; /* ERR | CERR */ in pcnet_transmit()
1210 s->xmit_pos = -1; in pcnet_transmit()
1214 if (s->xmit_pos < 0) { in pcnet_transmit()
1220 /* if multi-tmd packet outsizes s->buffer then skip it silently. in pcnet_transmit()
1222 * Last four bytes of s->buffer are used to store CRC FCS code. in pcnet_transmit()
1224 if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) { in pcnet_transmit()
1225 s->xmit_pos = -1; in pcnet_transmit()
1229 s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), in pcnet_transmit()
1230 s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); in pcnet_transmit()
1231 s->xmit_pos += bcnt; in pcnet_transmit()
1238 printf("pcnet_transmit size=%d\n", s->xmit_pos); in pcnet_transmit()
1240 if (CSR_LOOP(s)) { in pcnet_transmit()
1241 if (BCR_SWSTYLE(s) == 1) in pcnet_transmit()
1243 s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; in pcnet_transmit()
1244 qemu_receive_packet(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); in pcnet_transmit()
1245 s->looptest = 0; in pcnet_transmit()
1247 if (s->nic) { in pcnet_transmit()
1248 qemu_send_packet(qemu_get_queue(s->nic), s->buffer, in pcnet_transmit()
1249 s->xmit_pos); in pcnet_transmit()
1253 s->csr[0] &= ~0x0008; /* clear TDMD */ in pcnet_transmit()
1254 s->csr[4] |= 0x0004; /* set TXSTRT */ in pcnet_transmit()
1255 s->xmit_pos = -1; in pcnet_transmit()
1259 TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); in pcnet_transmit()
1260 if (!CSR_TOKINTD(s) in pcnet_transmit()
1261 || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) { in pcnet_transmit()
1262 s->csr[0] |= 0x0200; /* set TINT */ in pcnet_transmit()
1264 if (CSR_XMTRC(s) <= 1) { in pcnet_transmit()
1265 CSR_XMTRC(s) = CSR_XMTRL(s); in pcnet_transmit()
1267 CSR_XMTRC(s)--; in pcnet_transmit()
1272 } else if (s->xmit_pos >= 0) { in pcnet_transmit()
1280 s->csr[0] |= 0x0200; /* set TINT */ in pcnet_transmit()
1281 if (!CSR_DXSUFLO(s)) { in pcnet_transmit()
1282 s->csr[0] &= ~0x0010; in pcnet_transmit()
1288 s->tx_busy = 0; in pcnet_transmit()
1291 static void pcnet_poll(PCNetState *s) in pcnet_poll() argument
1293 if (CSR_RXON(s)) { in pcnet_poll()
1294 pcnet_rdte_poll(s); in pcnet_poll()
1297 if (CSR_TDMD(s) || (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s))) { in pcnet_poll()
1299 if (s->tx_busy) { in pcnet_poll()
1302 pcnet_transmit(s); in pcnet_poll()
1308 PCNetState *s = opaque; in pcnet_poll_timer() local
1310 timer_del(s->poll_timer); in pcnet_poll_timer()
1312 if (CSR_TDMD(s)) { in pcnet_poll_timer()
1313 pcnet_transmit(s); in pcnet_poll_timer()
1316 pcnet_update_irq(s); in pcnet_poll_timer()
1318 if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) { in pcnet_poll_timer()
1320 if (!s->timer || !now) { in pcnet_poll_timer()
1321 s->timer = now; in pcnet_poll_timer()
1323 uint64_t t = now - s->timer + CSR_POLL(s); in pcnet_poll_timer()
1325 pcnet_poll(s); in pcnet_poll_timer()
1326 CSR_POLL(s) = CSR_PINT(s); in pcnet_poll_timer()
1328 CSR_POLL(s) = t; in pcnet_poll_timer()
1331 timer_mod(s->poll_timer, in pcnet_poll_timer()
1332 pcnet_get_next_poll_time(s,qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))); in pcnet_poll_timer()
1337 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value) in pcnet_csr_writew() argument
1345 s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */ in pcnet_csr_writew()
1347 s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048); in pcnet_csr_writew()
1349 val = (val & 0x007f) | (s->csr[0] & 0x7f00); in pcnet_csr_writew()
1355 if (!CSR_STOP(s) && (val & 4)) { in pcnet_csr_writew()
1356 pcnet_stop(s); in pcnet_csr_writew()
1358 if (!CSR_INIT(s) && (val & 1)) { in pcnet_csr_writew()
1359 pcnet_init(s); in pcnet_csr_writew()
1361 if (!CSR_STRT(s) && (val & 2)) { in pcnet_csr_writew()
1362 pcnet_start(s); in pcnet_csr_writew()
1364 if (CSR_TDMD(s)) { in pcnet_csr_writew()
1365 pcnet_transmit(s); in pcnet_csr_writew()
1416 if (CSR_STOP(s) || CSR_SPND(s)) { in pcnet_csr_writew()
1423 s->csr[4] &= ~(val & 0x026a); in pcnet_csr_writew()
1424 val &= ~0x026a; val |= s->csr[4] & 0x026a; in pcnet_csr_writew()
1427 s->csr[5] &= ~(val & 0x0a90); in pcnet_csr_writew()
1428 val &= ~0x0a90; val |= s->csr[5] & 0x0a90; in pcnet_csr_writew()
1431 pcnet_csr_writew(s,1,val); in pcnet_csr_writew()
1434 pcnet_csr_writew(s,2,val); in pcnet_csr_writew()
1437 pcnet_bcr_writew(s,BCR_SWS,val); in pcnet_csr_writew()
1442 s->csr[rap] = val; in pcnet_csr_writew()
1445 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap) in pcnet_csr_readw() argument
1450 pcnet_update_irq(s); in pcnet_csr_readw()
1451 val = s->csr[0]; in pcnet_csr_readw()
1455 return pcnet_csr_readw(s,1); in pcnet_csr_readw()
1457 return pcnet_csr_readw(s,2); in pcnet_csr_readw()
1459 return pcnet_bcr_readw(s,BCR_SWS); in pcnet_csr_readw()
1461 val = s->csr[89]; in pcnet_csr_readw()
1463 val |= s->csr[88]; in pcnet_csr_readw()
1466 val = s->csr[rap]; in pcnet_csr_readw()
1474 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val) in pcnet_bcr_writew() argument
1482 if (!(CSR_STOP(s) || CSR_SPND(s))) in pcnet_bcr_writew()
1515 s->bcr[rap] = val; in pcnet_bcr_writew()
1522 uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap) in pcnet_bcr_readw() argument
1531 val = s->bcr[rap] & ~0x8000; in pcnet_bcr_readw()
1532 val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0; in pcnet_bcr_readw()
1535 val = rap < 32 ? s->bcr[rap] : 0; in pcnet_bcr_readw()
1546 PCNetState *s = opaque; in pcnet_h_reset() local
1548 s->bcr[BCR_MSRDA] = 0x0005; in pcnet_h_reset()
1549 s->bcr[BCR_MSWRA] = 0x0005; in pcnet_h_reset()
1550 s->bcr[BCR_MC ] = 0x0002; in pcnet_h_reset()
1551 s->bcr[BCR_LNKST] = 0x00c0; in pcnet_h_reset()
1552 s->bcr[BCR_LED1 ] = 0x0084; in pcnet_h_reset()
1553 s->bcr[BCR_LED2 ] = 0x0088; in pcnet_h_reset()
1554 s->bcr[BCR_LED3 ] = 0x0090; in pcnet_h_reset()
1555 s->bcr[BCR_FDC ] = 0x0000; in pcnet_h_reset()
1556 s->bcr[BCR_BSBC ] = 0x9001; in pcnet_h_reset()
1557 s->bcr[BCR_EECAS] = 0x0002; in pcnet_h_reset()
1558 s->bcr[BCR_SWS ] = 0x0200; in pcnet_h_reset()
1559 s->bcr[BCR_PLAT ] = 0xff06; in pcnet_h_reset()
1561 pcnet_s_reset(s); in pcnet_h_reset()
1562 pcnet_update_irq(s); in pcnet_h_reset()
1563 pcnet_poll_timer(s); in pcnet_h_reset()
1568 PCNetState *s = opaque; in pcnet_ioport_writew() local
1569 pcnet_poll_timer(s); in pcnet_ioport_writew()
1573 if (!BCR_DWIO(s)) { in pcnet_ioport_writew()
1576 pcnet_csr_writew(s, s->rap, val); in pcnet_ioport_writew()
1579 s->rap = val & 0x7f; in pcnet_ioport_writew()
1582 pcnet_bcr_writew(s, s->rap, val); in pcnet_ioport_writew()
1586 pcnet_update_irq(s); in pcnet_ioport_writew()
1591 PCNetState *s = opaque; in pcnet_ioport_readw() local
1593 pcnet_poll_timer(s); in pcnet_ioport_readw()
1594 if (!BCR_DWIO(s)) { in pcnet_ioport_readw()
1597 val = pcnet_csr_readw(s, s->rap); in pcnet_ioport_readw()
1600 val = s->rap; in pcnet_ioport_readw()
1603 pcnet_s_reset(s); in pcnet_ioport_readw()
1607 val = pcnet_bcr_readw(s, s->rap); in pcnet_ioport_readw()
1611 pcnet_update_irq(s); in pcnet_ioport_readw()
1620 PCNetState *s = opaque; in pcnet_ioport_writel() local
1621 pcnet_poll_timer(s); in pcnet_ioport_writel()
1625 if (BCR_DWIO(s)) { in pcnet_ioport_writel()
1628 pcnet_csr_writew(s, s->rap, val & 0xffff); in pcnet_ioport_writel()
1631 s->rap = val & 0x7f; in pcnet_ioport_writel()
1634 pcnet_bcr_writew(s, s->rap, val & 0xffff); in pcnet_ioport_writel()
1639 pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080); in pcnet_ioport_writel()
1644 pcnet_update_irq(s); in pcnet_ioport_writel()
1649 PCNetState *s = opaque; in pcnet_ioport_readl() local
1651 pcnet_poll_timer(s); in pcnet_ioport_readl()
1652 if (BCR_DWIO(s)) { in pcnet_ioport_readl()
1655 val = pcnet_csr_readw(s, s->rap); in pcnet_ioport_readl()
1658 val = s->rap; in pcnet_ioport_readl()
1661 pcnet_s_reset(s); in pcnet_ioport_readl()
1665 val = pcnet_bcr_readw(s, s->rap); in pcnet_ioport_readl()
1669 pcnet_update_irq(s); in pcnet_ioport_readl()
1704 void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info) in pcnet_common_init() argument
1709 s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s); in pcnet_common_init()
1711 qemu_macaddr_default_if_unset(&s->conf.macaddr); in pcnet_common_init()
1712 s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), in pcnet_common_init()
1713 dev->id, &dev->mem_reentrancy_guard, s); in pcnet_common_init()
1714 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); in pcnet_common_init()
1722 memcpy(s->prom, s->conf.macaddr.a, 6); in pcnet_common_init()
1724 s->prom[6] = s->prom[7] = 0x00; in pcnet_common_init()
1726 s->prom[8] = 0x00; in pcnet_common_init()
1728 s->prom[9] = 0x11; in pcnet_common_init()
1730 s->prom[10] = s->prom[11] = 0x00; in pcnet_common_init()
1733 s->prom[12] = s->prom[13] = 0x00; in pcnet_common_init()
1736 s->prom[14] = s->prom[15] = 0x57; in pcnet_common_init()
1739 checksum += s->prom[i]; in pcnet_common_init()
1741 *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum); in pcnet_common_init()
1743 s->lnkst = 0x40; /* initial link state: up */ in pcnet_common_init()