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 "igb_osdep.h" 30 #include "igb_api.h" 31 32 33 void 34 e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 35 { 36 pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value); 37 } 38 39 void 40 e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 41 { 42 *value = 43 pci_config_get16(OS_DEP(hw)->cfg_handle, reg); 44 } 45 46 /* 47 * Return the 16-bit value from pci-e config space at offset reg into the pci-e 48 * capability block. Note that this refers to the pci-e capability block in 49 * standard pci config space, not the block in pci-e extended config space. 50 */ 51 int32_t 52 e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 53 { 54 uint8_t pcie_id = PCI_CAP_ID_PCI_E; 55 uint16_t pcie_cap; 56 int32_t status; 57 58 /* locate the pci-e capability block */ 59 status = pci_lcap_locate((OS_DEP(hw))->cfg_handle, pcie_id, &pcie_cap); 60 if (status == DDI_SUCCESS) { 61 62 /* read at given offset into block */ 63 *value = pci_config_get16(OS_DEP(hw)->cfg_handle, 64 (pcie_cap + reg)); 65 } 66 67 return (status); 68 } 69 70 /* 71 * Write the given 16-bit value to pci-e config space at offset reg into the 72 * pci-e capability block. Note that this refers to the pci-e capability block 73 * in standard pci config space, not the block in pci-e extended config space. 74 */ 75 int32_t 76 e1000_write_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 77 { 78 uint8_t pcie_id = PCI_CAP_ID_PCI_E; 79 uint16_t pcie_cap; 80 int32_t status; 81 82 /* locate the pci-e capability block */ 83 status = pci_lcap_locate(OS_DEP(hw)->cfg_handle, pcie_id, &pcie_cap); 84 if (status == DDI_SUCCESS) { 85 86 /* write at given offset into block */ 87 pci_config_put16(OS_DEP(hw)->cfg_handle, 88 (off_t)(pcie_cap + reg), *value); 89 } 90 91 return (status); 92 } 93 94 /* 95 * e1000_rar_set_vmdq - Clear the RAR registers 96 */ 97 void 98 e1000_rar_clear(struct e1000_hw *hw, uint32_t index) 99 { 100 101 uint32_t rar_high; 102 103 /* Make the hardware the Address invalid by setting the clear bit */ 104 rar_high = ~E1000_RAH_AV; 105 106 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 107 E1000_WRITE_FLUSH(hw); 108 } 109 110 /* 111 * e1000_rar_set_vmdq - Set the RAR registers for VMDq 112 */ 113 void 114 e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *addr, uint32_t index, 115 uint32_t vmdq_mode, uint8_t qsel) 116 { 117 uint32_t rar_low, rar_high; 118 119 /* 120 * NIC expects these in little endian so reverse the byte order 121 * from network order (big endian) to little endian. 122 */ 123 124 rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) | 125 ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24)); 126 127 rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8)); 128 129 /* Indicate to hardware the Address is Valid. */ 130 rar_high |= E1000_RAH_AV; 131 132 /* Set que selector based on vmdq mode */ 133 switch (vmdq_mode) { 134 default: 135 case E1000_VMDQ_OFF: 136 break; 137 case E1000_VMDQ_MAC: 138 rar_high |= (qsel << 18); 139 break; 140 case E1000_VMDQ_MAC_RSS: 141 rar_high |= 1 << (18 + qsel); 142 break; 143 144 } 145 146 /* write to receive address registers */ 147 E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); 148 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 149 E1000_WRITE_FLUSH(hw); 150 } 151