xref: /qemu/hw/net/e1000x_common.h (revision 757704f1b7bffd441101bdab0bbcff27cd11ab34)
1093454e2SDmitry Fleytman /*
2093454e2SDmitry Fleytman * QEMU e1000(e) emulation - shared code
3093454e2SDmitry Fleytman *
4093454e2SDmitry Fleytman * Copyright (c) 2008 Qumranet
5093454e2SDmitry Fleytman *
6093454e2SDmitry Fleytman * Based on work done by:
7093454e2SDmitry Fleytman * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
8093454e2SDmitry Fleytman * Copyright (c) 2007 Dan Aloni
9093454e2SDmitry Fleytman * Copyright (c) 2004 Antony T Curtis
10093454e2SDmitry Fleytman *
11093454e2SDmitry Fleytman * This library is free software; you can redistribute it and/or
12093454e2SDmitry Fleytman * modify it under the terms of the GNU Lesser General Public
13093454e2SDmitry Fleytman * License as published by the Free Software Foundation; either
14093454e2SDmitry Fleytman * version 2 of the License, or (at your option) any later version.
15093454e2SDmitry Fleytman *
16093454e2SDmitry Fleytman * This library is distributed in the hope that it will be useful,
17093454e2SDmitry Fleytman * but WITHOUT ANY WARRANTY; without even the implied warranty of
18093454e2SDmitry Fleytman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19093454e2SDmitry Fleytman * Lesser General Public License for more details.
20093454e2SDmitry Fleytman *
21093454e2SDmitry Fleytman * You should have received a copy of the GNU Lesser General Public
22093454e2SDmitry Fleytman * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23093454e2SDmitry Fleytman */
24093454e2SDmitry Fleytman 
25093454e2SDmitry Fleytman #include "e1000_regs.h"
26093454e2SDmitry Fleytman 
27093454e2SDmitry Fleytman #define defreg(x)   x = (E1000_##x >> 2)
28093454e2SDmitry Fleytman enum {
29093454e2SDmitry Fleytman     defreg(CTRL),    defreg(EECD),    defreg(EERD),    defreg(GPRC),
30093454e2SDmitry Fleytman     defreg(GPTC),    defreg(ICR),     defreg(ICS),     defreg(IMC),
31093454e2SDmitry Fleytman     defreg(IMS),     defreg(LEDCTL),  defreg(MANC),    defreg(MDIC),
32093454e2SDmitry Fleytman     defreg(MPC),     defreg(PBA),     defreg(RCTL),    defreg(RDBAH0),
33093454e2SDmitry Fleytman     defreg(RDBAL0),  defreg(RDH0),    defreg(RDLEN0),  defreg(RDT0),
34093454e2SDmitry Fleytman     defreg(STATUS),  defreg(SWSM),    defreg(TCTL),    defreg(TDBAH),
35093454e2SDmitry Fleytman     defreg(TDBAL),   defreg(TDH),     defreg(TDLEN),   defreg(TDT),
36093454e2SDmitry Fleytman     defreg(TDLEN1),  defreg(TDBAL1),  defreg(TDBAH1),  defreg(TDH1),
37093454e2SDmitry Fleytman     defreg(TDT1),    defreg(TORH),    defreg(TORL),    defreg(TOTH),
38093454e2SDmitry Fleytman     defreg(TOTL),    defreg(TPR),     defreg(TPT),     defreg(TXDCTL),
39093454e2SDmitry Fleytman     defreg(WUFC),    defreg(RA),      defreg(MTA),     defreg(CRCERRS),
40093454e2SDmitry Fleytman     defreg(VFTA),    defreg(VET),     defreg(RDTR),    defreg(RADV),
41093454e2SDmitry Fleytman     defreg(TADV),    defreg(ITR),     defreg(SCC),     defreg(ECOL),
42093454e2SDmitry Fleytman     defreg(MCC),     defreg(LATECOL), defreg(COLC),    defreg(DC),
43*757704f1SKamil Rytarowski     defreg(TNCRS),   defreg(SEQEC),   defreg(CEXTERR), defreg(RLEC),
44093454e2SDmitry Fleytman     defreg(XONRXC),  defreg(XONTXC),  defreg(XOFFRXC), defreg(XOFFTXC),
45093454e2SDmitry Fleytman     defreg(FCRUC),   defreg(AIT),     defreg(TDFH),    defreg(TDFT),
46093454e2SDmitry Fleytman     defreg(TDFHS),   defreg(TDFTS),   defreg(TDFPC),   defreg(WUC),
47093454e2SDmitry Fleytman     defreg(WUS),     defreg(POEMB),   defreg(PBS),     defreg(RDFH),
48093454e2SDmitry Fleytman     defreg(RDFT),    defreg(RDFHS),   defreg(RDFTS),   defreg(RDFPC),
49093454e2SDmitry Fleytman     defreg(PBM),     defreg(IPAV),    defreg(IP4AT),   defreg(IP6AT),
50093454e2SDmitry Fleytman     defreg(WUPM),    defreg(FFLT),    defreg(FFMT),    defreg(FFVT),
51093454e2SDmitry Fleytman     defreg(TARC0),   defreg(TARC1),   defreg(IAM),     defreg(EXTCNF_CTRL),
52093454e2SDmitry Fleytman     defreg(GCR),     defreg(TIMINCA), defreg(EIAC),    defreg(CTRL_EXT),
53093454e2SDmitry Fleytman     defreg(IVAR),    defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H),
54093454e2SDmitry Fleytman     defreg(MFVAL),   defreg(MDEF),    defreg(FACTPS),  defreg(FTFT),
55093454e2SDmitry Fleytman     defreg(RUC),     defreg(ROC),     defreg(RFC),     defreg(RJC),
56093454e2SDmitry Fleytman     defreg(PRC64),   defreg(PRC127),  defreg(PRC255),  defreg(PRC511),
57093454e2SDmitry Fleytman     defreg(PRC1023), defreg(PRC1522), defreg(PTC64),   defreg(PTC127),
58093454e2SDmitry Fleytman     defreg(PTC255),  defreg(PTC511),  defreg(PTC1023), defreg(PTC1522),
59093454e2SDmitry Fleytman     defreg(GORCL),   defreg(GORCH),   defreg(GOTCL),   defreg(GOTCH),
60093454e2SDmitry Fleytman     defreg(RNBC),    defreg(BPRC),    defreg(MPRC),    defreg(RFCTL),
61093454e2SDmitry Fleytman     defreg(PSRCTL),  defreg(MPTC),    defreg(BPTC),    defreg(TSCTFC),
62093454e2SDmitry Fleytman     defreg(IAC),     defreg(MGTPRC),  defreg(MGTPDC),  defreg(MGTPTC),
63093454e2SDmitry Fleytman     defreg(TSCTC),   defreg(RXCSUM),  defreg(FUNCTAG), defreg(GSCL_1),
64093454e2SDmitry Fleytman     defreg(GSCL_2),  defreg(GSCL_3),  defreg(GSCL_4),  defreg(GSCN_0),
65093454e2SDmitry Fleytman     defreg(GSCN_1),  defreg(GSCN_2),  defreg(GSCN_3),  defreg(GCR2),
66093454e2SDmitry Fleytman     defreg(RAID),    defreg(RSRPD),   defreg(TIDV),    defreg(EITR),
67093454e2SDmitry Fleytman     defreg(MRQC),    defreg(RETA),    defreg(RSSRK),   defreg(RDBAH1),
68093454e2SDmitry Fleytman     defreg(RDBAL1),  defreg(RDLEN1),  defreg(RDH1),    defreg(RDT1),
69093454e2SDmitry Fleytman     defreg(PBACLR),  defreg(FCAL),    defreg(FCAH),    defreg(FCT),
70093454e2SDmitry Fleytman     defreg(FCRTH),   defreg(FCRTL),   defreg(FCTTV),   defreg(FCRTV),
71093454e2SDmitry Fleytman     defreg(FLA),     defreg(EEWR),    defreg(FLOP),    defreg(FLOL),
72093454e2SDmitry Fleytman     defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL),  defreg(RXDCTL1),
73093454e2SDmitry Fleytman     defreg(MAVTV0),  defreg(MAVTV1),  defreg(MAVTV2),  defreg(MAVTV3),
74093454e2SDmitry Fleytman     defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
75093454e2SDmitry Fleytman     defreg(RXCFGL),  defreg(RXUDP),   defreg(TIMADJL), defreg(TIMADJH),
76093454e2SDmitry Fleytman     defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
77093454e2SDmitry Fleytman     defreg(FLASHT),  defreg(TIPG),    defreg(RDH),     defreg(RDT),
78093454e2SDmitry Fleytman     defreg(RDLEN),   defreg(RDBAH),   defreg(RDBAL),
79093454e2SDmitry Fleytman     defreg(TXDCTL1),
80093454e2SDmitry Fleytman     defreg(FLSWDATA),
81093454e2SDmitry Fleytman     defreg(CTRL_DUP),
82093454e2SDmitry Fleytman     defreg(EXTCNF_SIZE),
83093454e2SDmitry Fleytman     defreg(EEMNGCTL),
84093454e2SDmitry Fleytman     defreg(EEMNGDATA),
85093454e2SDmitry Fleytman     defreg(FLMNGCTL),
86093454e2SDmitry Fleytman     defreg(FLMNGDATA),
87093454e2SDmitry Fleytman     defreg(FLMNGCNT),
88093454e2SDmitry Fleytman     defreg(TSYNCRXCTL),
89093454e2SDmitry Fleytman     defreg(TSYNCTXCTL),
90093454e2SDmitry Fleytman 
91093454e2SDmitry Fleytman     /* Aliases */
92093454e2SDmitry Fleytman     defreg(RDH0_A),  defreg(RDT0_A),  defreg(RDTR_A),  defreg(RDFH_A),
93093454e2SDmitry Fleytman     defreg(RDFT_A),  defreg(TDH_A),   defreg(TDT_A),   defreg(TIDV_A),
94093454e2SDmitry Fleytman     defreg(TDFH_A),  defreg(TDFT_A),  defreg(RA_A),    defreg(RDBAL0_A),
95093454e2SDmitry Fleytman     defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A),  defreg(RDLEN0_A),
96093454e2SDmitry Fleytman     defreg(FCRTL_A), defreg(FCRTH_A)
97093454e2SDmitry Fleytman };
98093454e2SDmitry Fleytman 
99093454e2SDmitry Fleytman static inline void
100093454e2SDmitry Fleytman e1000x_inc_reg_if_not_full(uint32_t *mac, int index)
101093454e2SDmitry Fleytman {
102093454e2SDmitry Fleytman     if (mac[index] != 0xffffffff) {
103093454e2SDmitry Fleytman         mac[index]++;
104093454e2SDmitry Fleytman     }
105093454e2SDmitry Fleytman }
106093454e2SDmitry Fleytman 
107093454e2SDmitry Fleytman static inline void
108093454e2SDmitry Fleytman e1000x_grow_8reg_if_not_full(uint32_t *mac, int index, int size)
109093454e2SDmitry Fleytman {
110093454e2SDmitry Fleytman     uint64_t sum = mac[index] | (uint64_t)mac[index + 1] << 32;
111093454e2SDmitry Fleytman 
112093454e2SDmitry Fleytman     if (sum + size < sum) {
113093454e2SDmitry Fleytman         sum = ~0ULL;
114093454e2SDmitry Fleytman     } else {
115093454e2SDmitry Fleytman         sum += size;
116093454e2SDmitry Fleytman     }
117093454e2SDmitry Fleytman     mac[index] = sum;
118093454e2SDmitry Fleytman     mac[index + 1] = sum >> 32;
119093454e2SDmitry Fleytman }
120093454e2SDmitry Fleytman 
121093454e2SDmitry Fleytman static inline int
122093454e2SDmitry Fleytman e1000x_vlan_enabled(uint32_t *mac)
123093454e2SDmitry Fleytman {
124093454e2SDmitry Fleytman     return ((mac[CTRL] & E1000_CTRL_VME) != 0);
125093454e2SDmitry Fleytman }
126093454e2SDmitry Fleytman 
127093454e2SDmitry Fleytman static inline int
128093454e2SDmitry Fleytman e1000x_is_vlan_txd(uint32_t txd_lower)
129093454e2SDmitry Fleytman {
130093454e2SDmitry Fleytman     return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
131093454e2SDmitry Fleytman }
132093454e2SDmitry Fleytman 
133093454e2SDmitry Fleytman static inline int
134093454e2SDmitry Fleytman e1000x_vlan_rx_filter_enabled(uint32_t *mac)
135093454e2SDmitry Fleytman {
136093454e2SDmitry Fleytman     return ((mac[RCTL] & E1000_RCTL_VFE) != 0);
137093454e2SDmitry Fleytman }
138093454e2SDmitry Fleytman 
139093454e2SDmitry Fleytman static inline int
140093454e2SDmitry Fleytman e1000x_fcs_len(uint32_t *mac)
141093454e2SDmitry Fleytman {
142093454e2SDmitry Fleytman     /* FCS aka Ethernet CRC-32. We don't get it from backends and can't
143093454e2SDmitry Fleytman     * fill it in, just pad descriptor length by 4 bytes unless guest
144093454e2SDmitry Fleytman     * told us to strip it off the packet. */
145093454e2SDmitry Fleytman     return (mac[RCTL] & E1000_RCTL_SECRC) ? 0 : 4;
146093454e2SDmitry Fleytman }
147093454e2SDmitry Fleytman 
148093454e2SDmitry Fleytman static inline void
149093454e2SDmitry Fleytman e1000x_update_regs_on_link_down(uint32_t *mac, uint16_t *phy)
150093454e2SDmitry Fleytman {
151093454e2SDmitry Fleytman     mac[STATUS] &= ~E1000_STATUS_LU;
152093454e2SDmitry Fleytman     phy[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
153093454e2SDmitry Fleytman     phy[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
154093454e2SDmitry Fleytman     phy[PHY_LP_ABILITY] &= ~MII_LPAR_LPACK;
155093454e2SDmitry Fleytman }
156093454e2SDmitry Fleytman 
157093454e2SDmitry Fleytman static inline void
158093454e2SDmitry Fleytman e1000x_update_regs_on_link_up(uint32_t *mac, uint16_t *phy)
159093454e2SDmitry Fleytman {
160093454e2SDmitry Fleytman     mac[STATUS] |= E1000_STATUS_LU;
161093454e2SDmitry Fleytman     phy[PHY_STATUS] |= MII_SR_LINK_STATUS;
162093454e2SDmitry Fleytman }
163093454e2SDmitry Fleytman 
164093454e2SDmitry Fleytman void e1000x_update_rx_total_stats(uint32_t *mac,
165093454e2SDmitry Fleytman                                   size_t data_size,
166093454e2SDmitry Fleytman                                   size_t data_fcs_size);
167093454e2SDmitry Fleytman 
168093454e2SDmitry Fleytman void e1000x_core_prepare_eeprom(uint16_t       *eeprom,
169093454e2SDmitry Fleytman                                 const uint16_t *templ,
170093454e2SDmitry Fleytman                                 uint32_t        templ_size,
171093454e2SDmitry Fleytman                                 uint16_t        dev_id,
172093454e2SDmitry Fleytman                                 const uint8_t  *macaddr);
173093454e2SDmitry Fleytman 
174093454e2SDmitry Fleytman uint32_t e1000x_rxbufsize(uint32_t rctl);
175093454e2SDmitry Fleytman 
176093454e2SDmitry Fleytman bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac);
177093454e2SDmitry Fleytman 
178093454e2SDmitry Fleytman bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet);
179093454e2SDmitry Fleytman 
180093454e2SDmitry Fleytman bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf);
181093454e2SDmitry Fleytman 
182093454e2SDmitry Fleytman bool e1000x_hw_rx_enabled(uint32_t *mac);
183093454e2SDmitry Fleytman 
184093454e2SDmitry Fleytman bool e1000x_is_oversized(uint32_t *mac, size_t size);
185093454e2SDmitry Fleytman 
186093454e2SDmitry Fleytman void e1000x_restart_autoneg(uint32_t *mac, uint16_t *phy, QEMUTimer *timer);
187093454e2SDmitry Fleytman 
188093454e2SDmitry Fleytman void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
189093454e2SDmitry Fleytman                            uint8_t *mac_addr);
190093454e2SDmitry Fleytman 
191093454e2SDmitry Fleytman void e1000x_update_regs_on_autoneg_done(uint32_t *mac, uint16_t *phy);
192093454e2SDmitry Fleytman 
193093454e2SDmitry Fleytman void e1000x_increase_size_stats(uint32_t *mac, const int *size_regs, int size);
194093454e2SDmitry Fleytman 
195093454e2SDmitry Fleytman typedef struct e1000x_txd_props {
196093454e2SDmitry Fleytman     unsigned char sum_needed;
197093454e2SDmitry Fleytman     uint8_t ipcss;
198093454e2SDmitry Fleytman     uint8_t ipcso;
199093454e2SDmitry Fleytman     uint16_t ipcse;
200093454e2SDmitry Fleytman     uint8_t tucss;
201093454e2SDmitry Fleytman     uint8_t tucso;
202093454e2SDmitry Fleytman     uint16_t tucse;
203093454e2SDmitry Fleytman     uint32_t paylen;
204093454e2SDmitry Fleytman     uint8_t hdr_len;
205093454e2SDmitry Fleytman     uint16_t mss;
206093454e2SDmitry Fleytman     int8_t ip;
207093454e2SDmitry Fleytman     int8_t tcp;
208093454e2SDmitry Fleytman     bool tse;
209093454e2SDmitry Fleytman     bool cptse;
210093454e2SDmitry Fleytman } e1000x_txd_props;
211093454e2SDmitry Fleytman 
212093454e2SDmitry Fleytman void e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
213093454e2SDmitry Fleytman                               e1000x_txd_props *props);
214