1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright(c) 2007-2008 Intel Corporation. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #include "igb_osdep.h" 32 #include "igb_api.h" 33 34 35 s32 36 e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size) 37 { 38 hw->dev_spec = kmem_zalloc(size, KM_SLEEP); 39 40 return (E1000_SUCCESS); 41 } 42 43 void 44 e1000_free_dev_spec_struct(struct e1000_hw *hw) 45 { 46 if (hw->dev_spec == NULL) 47 return; 48 49 kmem_free(hw->dev_spec, hw->dev_spec_size); 50 hw->dev_spec = NULL; 51 } 52 53 void 54 e1000_pci_set_mwi(struct e1000_hw *hw) 55 { 56 uint16_t val = hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE; 57 58 e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); 59 } 60 61 void 62 e1000_pci_clear_mwi(struct e1000_hw *hw) 63 { 64 uint16_t val = hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE; 65 66 e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); 67 } 68 69 void 70 e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 71 { 72 pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value); 73 } 74 75 void 76 e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 77 { 78 *value = 79 pci_config_get16(OS_DEP(hw)->cfg_handle, reg); 80 } 81 82 /* 83 * The real intent of this routine is to return the value from pci-e 84 * config space at offset reg into the capability space. 85 * ICH devices are "PCI Express"-ish. They have a configuration space, 86 * but do not contain PCI Express Capability registers, so this returns 87 * the equivalent of "not supported" 88 */ 89 int32_t 90 e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 91 { 92 *value = pci_config_get16(OS_DEP(hw)->cfg_handle, 93 PCI_EX_CONF_CAP + reg); 94 95 return (0); 96 } 97 98 /* 99 * Enables PCI-Express master access. 100 * 101 * hw: Struct containing variables accessed by shared code 102 * 103 * returns: - none. 104 */ 105 void 106 e1000_enable_pciex_master(struct e1000_hw *hw) 107 { 108 uint32_t ctrl; 109 110 if (hw->bus.type != e1000_bus_type_pci_express) 111 return; 112 113 ctrl = E1000_READ_REG(hw, E1000_CTRL); 114 ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE; 115 E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 116 } 117 118 /* 119 * e1000_rar_set_vmdq - Clear the RAR registers 120 */ 121 void 122 e1000_rar_clear(struct e1000_hw *hw, uint32_t index) 123 { 124 125 uint32_t rar_high; 126 127 /* Make the hardware the Address invalid by setting the clear bit */ 128 rar_high = ~E1000_RAH_AV; 129 130 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 131 E1000_WRITE_FLUSH(hw); 132 } 133 134 /* 135 * e1000_rar_set_vmdq - Set the RAR registers for VMDq 136 */ 137 void 138 e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *addr, uint32_t index, 139 uint32_t vmdq_mode, uint8_t qsel) 140 { 141 uint32_t rar_low, rar_high; 142 143 /* 144 * NIC expects these in little endian so reverse the byte order 145 * from network order (big endian) to little endian. 146 */ 147 148 rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) | 149 ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24)); 150 151 rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8)); 152 153 /* Indicate to hardware the Address is Valid. */ 154 rar_high |= E1000_RAH_AV; 155 156 /* Set que selector based on vmdq mode */ 157 switch (vmdq_mode) { 158 default: 159 case E1000_VMDQ_OFF: 160 break; 161 case E1000_VMDQ_MAC: 162 rar_high |= (qsel << 18); 163 break; 164 case E1000_VMDQ_MAC_RSS: 165 rar_high |= 1 << (18 + qsel); 166 break; 167 168 } 169 170 /* write to receive address registers */ 171 E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); 172 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 173 E1000_WRITE_FLUSH(hw); 174 } 175