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