xref: /qemu/hw/net/e1000x_common.h (revision 7cd2a9fad7a3d5735a7f38d149697fa408de2724)
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
14*7cd2a9faSChetan Pant * version 2.1 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 
25f91005e1SMarkus Armbruster #ifndef HW_NET_E1000X_COMMON_H
26f91005e1SMarkus Armbruster #define HW_NET_E1000X_COMMON_H
27f91005e1SMarkus Armbruster 
28093454e2SDmitry Fleytman #include "e1000_regs.h"
29093454e2SDmitry Fleytman 
30093454e2SDmitry Fleytman #define defreg(x)   x = (E1000_##x >> 2)
31093454e2SDmitry Fleytman enum {
32093454e2SDmitry Fleytman     defreg(CTRL),    defreg(EECD),    defreg(EERD),    defreg(GPRC),
33093454e2SDmitry Fleytman     defreg(GPTC),    defreg(ICR),     defreg(ICS),     defreg(IMC),
34093454e2SDmitry Fleytman     defreg(IMS),     defreg(LEDCTL),  defreg(MANC),    defreg(MDIC),
35093454e2SDmitry Fleytman     defreg(MPC),     defreg(PBA),     defreg(RCTL),    defreg(RDBAH0),
36093454e2SDmitry Fleytman     defreg(RDBAL0),  defreg(RDH0),    defreg(RDLEN0),  defreg(RDT0),
37093454e2SDmitry Fleytman     defreg(STATUS),  defreg(SWSM),    defreg(TCTL),    defreg(TDBAH),
38093454e2SDmitry Fleytman     defreg(TDBAL),   defreg(TDH),     defreg(TDLEN),   defreg(TDT),
39093454e2SDmitry Fleytman     defreg(TDLEN1),  defreg(TDBAL1),  defreg(TDBAH1),  defreg(TDH1),
40093454e2SDmitry Fleytman     defreg(TDT1),    defreg(TORH),    defreg(TORL),    defreg(TOTH),
41093454e2SDmitry Fleytman     defreg(TOTL),    defreg(TPR),     defreg(TPT),     defreg(TXDCTL),
42093454e2SDmitry Fleytman     defreg(WUFC),    defreg(RA),      defreg(MTA),     defreg(CRCERRS),
43093454e2SDmitry Fleytman     defreg(VFTA),    defreg(VET),     defreg(RDTR),    defreg(RADV),
44093454e2SDmitry Fleytman     defreg(TADV),    defreg(ITR),     defreg(SCC),     defreg(ECOL),
45093454e2SDmitry Fleytman     defreg(MCC),     defreg(LATECOL), defreg(COLC),    defreg(DC),
46757704f1SKamil Rytarowski     defreg(TNCRS),   defreg(SEQEC),   defreg(CEXTERR), defreg(RLEC),
47093454e2SDmitry Fleytman     defreg(XONRXC),  defreg(XONTXC),  defreg(XOFFRXC), defreg(XOFFTXC),
48093454e2SDmitry Fleytman     defreg(FCRUC),   defreg(AIT),     defreg(TDFH),    defreg(TDFT),
49093454e2SDmitry Fleytman     defreg(TDFHS),   defreg(TDFTS),   defreg(TDFPC),   defreg(WUC),
50093454e2SDmitry Fleytman     defreg(WUS),     defreg(POEMB),   defreg(PBS),     defreg(RDFH),
51093454e2SDmitry Fleytman     defreg(RDFT),    defreg(RDFHS),   defreg(RDFTS),   defreg(RDFPC),
52093454e2SDmitry Fleytman     defreg(PBM),     defreg(IPAV),    defreg(IP4AT),   defreg(IP6AT),
53093454e2SDmitry Fleytman     defreg(WUPM),    defreg(FFLT),    defreg(FFMT),    defreg(FFVT),
54093454e2SDmitry Fleytman     defreg(TARC0),   defreg(TARC1),   defreg(IAM),     defreg(EXTCNF_CTRL),
55093454e2SDmitry Fleytman     defreg(GCR),     defreg(TIMINCA), defreg(EIAC),    defreg(CTRL_EXT),
56093454e2SDmitry Fleytman     defreg(IVAR),    defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H),
57093454e2SDmitry Fleytman     defreg(MFVAL),   defreg(MDEF),    defreg(FACTPS),  defreg(FTFT),
58093454e2SDmitry Fleytman     defreg(RUC),     defreg(ROC),     defreg(RFC),     defreg(RJC),
59093454e2SDmitry Fleytman     defreg(PRC64),   defreg(PRC127),  defreg(PRC255),  defreg(PRC511),
60093454e2SDmitry Fleytman     defreg(PRC1023), defreg(PRC1522), defreg(PTC64),   defreg(PTC127),
61093454e2SDmitry Fleytman     defreg(PTC255),  defreg(PTC511),  defreg(PTC1023), defreg(PTC1522),
62093454e2SDmitry Fleytman     defreg(GORCL),   defreg(GORCH),   defreg(GOTCL),   defreg(GOTCH),
63093454e2SDmitry Fleytman     defreg(RNBC),    defreg(BPRC),    defreg(MPRC),    defreg(RFCTL),
64093454e2SDmitry Fleytman     defreg(PSRCTL),  defreg(MPTC),    defreg(BPTC),    defreg(TSCTFC),
65093454e2SDmitry Fleytman     defreg(IAC),     defreg(MGTPRC),  defreg(MGTPDC),  defreg(MGTPTC),
66093454e2SDmitry Fleytman     defreg(TSCTC),   defreg(RXCSUM),  defreg(FUNCTAG), defreg(GSCL_1),
67093454e2SDmitry Fleytman     defreg(GSCL_2),  defreg(GSCL_3),  defreg(GSCL_4),  defreg(GSCN_0),
68093454e2SDmitry Fleytman     defreg(GSCN_1),  defreg(GSCN_2),  defreg(GSCN_3),  defreg(GCR2),
69093454e2SDmitry Fleytman     defreg(RAID),    defreg(RSRPD),   defreg(TIDV),    defreg(EITR),
70093454e2SDmitry Fleytman     defreg(MRQC),    defreg(RETA),    defreg(RSSRK),   defreg(RDBAH1),
71093454e2SDmitry Fleytman     defreg(RDBAL1),  defreg(RDLEN1),  defreg(RDH1),    defreg(RDT1),
72093454e2SDmitry Fleytman     defreg(PBACLR),  defreg(FCAL),    defreg(FCAH),    defreg(FCT),
73093454e2SDmitry Fleytman     defreg(FCRTH),   defreg(FCRTL),   defreg(FCTTV),   defreg(FCRTV),
74093454e2SDmitry Fleytman     defreg(FLA),     defreg(EEWR),    defreg(FLOP),    defreg(FLOL),
75093454e2SDmitry Fleytman     defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL),  defreg(RXDCTL1),
76093454e2SDmitry Fleytman     defreg(MAVTV0),  defreg(MAVTV1),  defreg(MAVTV2),  defreg(MAVTV3),
77093454e2SDmitry Fleytman     defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
78093454e2SDmitry Fleytman     defreg(RXCFGL),  defreg(RXUDP),   defreg(TIMADJL), defreg(TIMADJH),
79093454e2SDmitry Fleytman     defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
80093454e2SDmitry Fleytman     defreg(FLASHT),  defreg(TIPG),    defreg(RDH),     defreg(RDT),
81093454e2SDmitry Fleytman     defreg(RDLEN),   defreg(RDBAH),   defreg(RDBAL),
82093454e2SDmitry Fleytman     defreg(TXDCTL1),
83093454e2SDmitry Fleytman     defreg(FLSWDATA),
84093454e2SDmitry Fleytman     defreg(CTRL_DUP),
85093454e2SDmitry Fleytman     defreg(EXTCNF_SIZE),
86093454e2SDmitry Fleytman     defreg(EEMNGCTL),
87093454e2SDmitry Fleytman     defreg(EEMNGDATA),
88093454e2SDmitry Fleytman     defreg(FLMNGCTL),
89093454e2SDmitry Fleytman     defreg(FLMNGDATA),
90093454e2SDmitry Fleytman     defreg(FLMNGCNT),
91093454e2SDmitry Fleytman     defreg(TSYNCRXCTL),
92093454e2SDmitry Fleytman     defreg(TSYNCTXCTL),
93093454e2SDmitry Fleytman 
94093454e2SDmitry Fleytman     /* Aliases */
95093454e2SDmitry Fleytman     defreg(RDH0_A),  defreg(RDT0_A),  defreg(RDTR_A),  defreg(RDFH_A),
96093454e2SDmitry Fleytman     defreg(RDFT_A),  defreg(TDH_A),   defreg(TDT_A),   defreg(TIDV_A),
97093454e2SDmitry Fleytman     defreg(TDFH_A),  defreg(TDFT_A),  defreg(RA_A),    defreg(RDBAL0_A),
98093454e2SDmitry Fleytman     defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A),  defreg(RDLEN0_A),
99093454e2SDmitry Fleytman     defreg(FCRTL_A), defreg(FCRTH_A)
100093454e2SDmitry Fleytman };
101093454e2SDmitry Fleytman 
102093454e2SDmitry Fleytman static inline void
103093454e2SDmitry Fleytman e1000x_inc_reg_if_not_full(uint32_t *mac, int index)
104093454e2SDmitry Fleytman {
105093454e2SDmitry Fleytman     if (mac[index] != 0xffffffff) {
106093454e2SDmitry Fleytman         mac[index]++;
107093454e2SDmitry Fleytman     }
108093454e2SDmitry Fleytman }
109093454e2SDmitry Fleytman 
110093454e2SDmitry Fleytman static inline void
111093454e2SDmitry Fleytman e1000x_grow_8reg_if_not_full(uint32_t *mac, int index, int size)
112093454e2SDmitry Fleytman {
113093454e2SDmitry Fleytman     uint64_t sum = mac[index] | (uint64_t)mac[index + 1] << 32;
114093454e2SDmitry Fleytman 
115093454e2SDmitry Fleytman     if (sum + size < sum) {
116093454e2SDmitry Fleytman         sum = ~0ULL;
117093454e2SDmitry Fleytman     } else {
118093454e2SDmitry Fleytman         sum += size;
119093454e2SDmitry Fleytman     }
120093454e2SDmitry Fleytman     mac[index] = sum;
121093454e2SDmitry Fleytman     mac[index + 1] = sum >> 32;
122093454e2SDmitry Fleytman }
123093454e2SDmitry Fleytman 
124093454e2SDmitry Fleytman static inline int
125093454e2SDmitry Fleytman e1000x_vlan_enabled(uint32_t *mac)
126093454e2SDmitry Fleytman {
127093454e2SDmitry Fleytman     return ((mac[CTRL] & E1000_CTRL_VME) != 0);
128093454e2SDmitry Fleytman }
129093454e2SDmitry Fleytman 
130093454e2SDmitry Fleytman static inline int
131093454e2SDmitry Fleytman e1000x_is_vlan_txd(uint32_t txd_lower)
132093454e2SDmitry Fleytman {
133093454e2SDmitry Fleytman     return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
134093454e2SDmitry Fleytman }
135093454e2SDmitry Fleytman 
136093454e2SDmitry Fleytman static inline int
137093454e2SDmitry Fleytman e1000x_vlan_rx_filter_enabled(uint32_t *mac)
138093454e2SDmitry Fleytman {
139093454e2SDmitry Fleytman     return ((mac[RCTL] & E1000_RCTL_VFE) != 0);
140093454e2SDmitry Fleytman }
141093454e2SDmitry Fleytman 
142093454e2SDmitry Fleytman static inline int
143093454e2SDmitry Fleytman e1000x_fcs_len(uint32_t *mac)
144093454e2SDmitry Fleytman {
145093454e2SDmitry Fleytman     /* FCS aka Ethernet CRC-32. We don't get it from backends and can't
146093454e2SDmitry Fleytman     * fill it in, just pad descriptor length by 4 bytes unless guest
147093454e2SDmitry Fleytman     * told us to strip it off the packet. */
148093454e2SDmitry Fleytman     return (mac[RCTL] & E1000_RCTL_SECRC) ? 0 : 4;
149093454e2SDmitry Fleytman }
150093454e2SDmitry Fleytman 
151093454e2SDmitry Fleytman static inline void
152093454e2SDmitry Fleytman e1000x_update_regs_on_link_down(uint32_t *mac, uint16_t *phy)
153093454e2SDmitry Fleytman {
154093454e2SDmitry Fleytman     mac[STATUS] &= ~E1000_STATUS_LU;
155093454e2SDmitry Fleytman     phy[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
156093454e2SDmitry Fleytman     phy[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
157093454e2SDmitry Fleytman     phy[PHY_LP_ABILITY] &= ~MII_LPAR_LPACK;
158093454e2SDmitry Fleytman }
159093454e2SDmitry Fleytman 
160093454e2SDmitry Fleytman static inline void
161093454e2SDmitry Fleytman e1000x_update_regs_on_link_up(uint32_t *mac, uint16_t *phy)
162093454e2SDmitry Fleytman {
163093454e2SDmitry Fleytman     mac[STATUS] |= E1000_STATUS_LU;
164093454e2SDmitry Fleytman     phy[PHY_STATUS] |= MII_SR_LINK_STATUS;
165093454e2SDmitry Fleytman }
166093454e2SDmitry Fleytman 
167093454e2SDmitry Fleytman void e1000x_update_rx_total_stats(uint32_t *mac,
168093454e2SDmitry Fleytman                                   size_t data_size,
169093454e2SDmitry Fleytman                                   size_t data_fcs_size);
170093454e2SDmitry Fleytman 
171093454e2SDmitry Fleytman void e1000x_core_prepare_eeprom(uint16_t       *eeprom,
172093454e2SDmitry Fleytman                                 const uint16_t *templ,
173093454e2SDmitry Fleytman                                 uint32_t        templ_size,
174093454e2SDmitry Fleytman                                 uint16_t        dev_id,
175093454e2SDmitry Fleytman                                 const uint8_t  *macaddr);
176093454e2SDmitry Fleytman 
177093454e2SDmitry Fleytman uint32_t e1000x_rxbufsize(uint32_t rctl);
178093454e2SDmitry Fleytman 
179093454e2SDmitry Fleytman bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac);
180093454e2SDmitry Fleytman 
181093454e2SDmitry Fleytman bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet);
182093454e2SDmitry Fleytman 
183093454e2SDmitry Fleytman bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf);
184093454e2SDmitry Fleytman 
185093454e2SDmitry Fleytman bool e1000x_hw_rx_enabled(uint32_t *mac);
186093454e2SDmitry Fleytman 
187093454e2SDmitry Fleytman bool e1000x_is_oversized(uint32_t *mac, size_t size);
188093454e2SDmitry Fleytman 
189093454e2SDmitry Fleytman void e1000x_restart_autoneg(uint32_t *mac, uint16_t *phy, QEMUTimer *timer);
190093454e2SDmitry Fleytman 
191093454e2SDmitry Fleytman void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
192093454e2SDmitry Fleytman                            uint8_t *mac_addr);
193093454e2SDmitry Fleytman 
194093454e2SDmitry Fleytman void e1000x_update_regs_on_autoneg_done(uint32_t *mac, uint16_t *phy);
195093454e2SDmitry Fleytman 
196093454e2SDmitry Fleytman void e1000x_increase_size_stats(uint32_t *mac, const int *size_regs, int size);
197093454e2SDmitry Fleytman 
198093454e2SDmitry Fleytman typedef struct e1000x_txd_props {
199093454e2SDmitry Fleytman     uint8_t ipcss;
200093454e2SDmitry Fleytman     uint8_t ipcso;
201093454e2SDmitry Fleytman     uint16_t ipcse;
202093454e2SDmitry Fleytman     uint8_t tucss;
203093454e2SDmitry Fleytman     uint8_t tucso;
204093454e2SDmitry Fleytman     uint16_t tucse;
205093454e2SDmitry Fleytman     uint32_t paylen;
206093454e2SDmitry Fleytman     uint8_t hdr_len;
207093454e2SDmitry Fleytman     uint16_t mss;
208093454e2SDmitry Fleytman     int8_t ip;
209093454e2SDmitry Fleytman     int8_t tcp;
210093454e2SDmitry Fleytman     bool tse;
211093454e2SDmitry Fleytman } e1000x_txd_props;
212093454e2SDmitry Fleytman 
213093454e2SDmitry Fleytman void e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
214093454e2SDmitry Fleytman                               e1000x_txd_props *props);
215f91005e1SMarkus Armbruster 
216f91005e1SMarkus Armbruster #endif
217