1 /* 2 * CDDL HEADER START 3 * 4 * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at: 10 * http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When using or redistributing this file, you may do so under the 15 * License only. No other modification of this header is permitted. 16 * 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 */ 23 24 /* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms of the CDDL. 27 */ 28 29 #include "e1000_osdep.h" 30 #include "e1000_api.h" 31 32 void 33 e1000_pci_set_mwi(struct e1000_hw *hw) 34 { 35 uint16_t val = hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE; 36 37 e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); 38 } 39 40 void 41 e1000_pci_clear_mwi(struct e1000_hw *hw) 42 { 43 uint16_t val = hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE; 44 45 e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); 46 } 47 48 void 49 e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 50 { 51 pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value); 52 } 53 54 void 55 e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 56 { 57 *value = 58 pci_config_get16(OS_DEP(hw)->cfg_handle, reg); 59 } 60 61 /* 62 * Return the 16-bit value from pci-e config space at offset reg into the pci-e 63 * capability block. Note that this refers to the pci-e capability block in 64 * standard pci config space, not the block in pci-e extended config space. 65 */ 66 int32_t 67 e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 68 { 69 uint8_t pcie_id = PCI_CAP_ID_PCI_E; 70 uint16_t pcie_cap; 71 int32_t status; 72 73 /* locate the pci-e capability block */ 74 status = pci_lcap_locate((OS_DEP(hw))->cfg_handle, pcie_id, &pcie_cap); 75 if (status == DDI_SUCCESS) { 76 77 /* read at given offset into block */ 78 *value = pci_config_get16(OS_DEP(hw)->cfg_handle, 79 (pcie_cap + reg)); 80 } 81 82 return (status); 83 } 84 85 /* 86 * Write the given 16-bit value to pci-e config space at offset reg into the 87 * pci-e capability block. Note that this refers to the pci-e capability block 88 * in standard pci config space, not the block in pci-e extended config space. 89 */ 90 int32_t 91 e1000_write_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 92 { 93 uint8_t pcie_id = PCI_CAP_ID_PCI_E; 94 uint16_t pcie_cap; 95 int32_t status; 96 97 /* locate the pci-e capability block */ 98 status = pci_lcap_locate(OS_DEP(hw)->cfg_handle, pcie_id, &pcie_cap); 99 if (status == DDI_SUCCESS) { 100 101 /* write at given offset into block */ 102 pci_config_put16(OS_DEP(hw)->cfg_handle, 103 (off_t)(pcie_cap + reg), *value); 104 } 105 106 return (status); 107 } 108 109 /* 110 * e1000_rar_set_vmdq - Clear the RAR registers 111 */ 112 void 113 e1000_rar_clear(struct e1000_hw *hw, uint32_t index) 114 { 115 116 uint32_t rar_high; 117 118 /* Make the hardware the Address invalid by setting the clear bit */ 119 rar_high = ~E1000_RAH_AV; 120 121 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 122 E1000_WRITE_FLUSH(hw); 123 } 124 125 /* 126 * e1000_rar_set_vmdq - Set the RAR registers for VMDq 127 */ 128 void 129 e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *addr, uint32_t index, 130 uint32_t vmdq_mode, uint8_t qsel) 131 { 132 uint32_t rar_low, rar_high; 133 134 /* 135 * NIC expects these in little endian so reverse the byte order 136 * from network order (big endian) to little endian. 137 */ 138 139 rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) | 140 ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24)); 141 142 rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8)); 143 144 /* Indicate to hardware the Address is Valid. */ 145 rar_high |= E1000_RAH_AV; 146 147 /* Set que selector based on vmdq mode */ 148 switch (vmdq_mode) { 149 default: 150 case E1000_VMDQ_OFF: 151 break; 152 case E1000_VMDQ_MAC: 153 rar_high |= (qsel << 18); 154 break; 155 case E1000_VMDQ_MAC_RSS: 156 rar_high |= 1 << (18 + qsel); 157 break; 158 159 } 160 161 /* write to receive address registers */ 162 E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); 163 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 164 E1000_WRITE_FLUSH(hw); 165 } 166