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_pci_set_mwi(struct e1000_hw *hw) 35 { 36 uint16_t val = hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE; 37 38 e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); 39 } 40 41 void 42 e1000_pci_clear_mwi(struct e1000_hw *hw) 43 { 44 uint16_t val = hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE; 45 46 e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); 47 } 48 49 void 50 e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 51 { 52 pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value); 53 } 54 55 void 56 e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 57 { 58 *value = 59 pci_config_get16(OS_DEP(hw)->cfg_handle, reg); 60 } 61 62 /* 63 * The real intent of this routine is to return the value from pci-e 64 * config space at offset reg into the capability space. 65 * ICH devices are "PCI Express"-ish. They have a configuration space, 66 * but do not contain PCI Express Capability registers, so this returns 67 * the equivalent of "not supported" 68 */ 69 int32_t 70 e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) 71 { 72 *value = pci_config_get16(OS_DEP(hw)->cfg_handle, 73 PCI_EX_CONF_CAP + reg); 74 75 return (0); 76 } 77 78 /* 79 * Enables PCI-Express master access. 80 * 81 * hw: Struct containing variables accessed by shared code 82 * 83 * returns: - none. 84 */ 85 void 86 e1000_enable_pciex_master(struct e1000_hw *hw) 87 { 88 uint32_t ctrl; 89 90 if (hw->bus.type != e1000_bus_type_pci_express) 91 return; 92 93 ctrl = E1000_READ_REG(hw, E1000_CTRL); 94 ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE; 95 E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 96 } 97 98 /* 99 * e1000_rar_set_vmdq - Clear the RAR registers 100 */ 101 void 102 e1000_rar_clear(struct e1000_hw *hw, uint32_t index) 103 { 104 105 uint32_t rar_high; 106 107 /* Make the hardware the Address invalid by setting the clear bit */ 108 rar_high = ~E1000_RAH_AV; 109 110 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 111 E1000_WRITE_FLUSH(hw); 112 } 113 114 /* 115 * e1000_rar_set_vmdq - Set the RAR registers for VMDq 116 */ 117 void 118 e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *addr, uint32_t index, 119 uint32_t vmdq_mode, uint8_t qsel) 120 { 121 uint32_t rar_low, rar_high; 122 123 /* 124 * NIC expects these in little endian so reverse the byte order 125 * from network order (big endian) to little endian. 126 */ 127 128 rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) | 129 ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24)); 130 131 rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8)); 132 133 /* Indicate to hardware the Address is Valid. */ 134 rar_high |= E1000_RAH_AV; 135 136 /* Set que selector based on vmdq mode */ 137 switch (vmdq_mode) { 138 default: 139 case E1000_VMDQ_OFF: 140 break; 141 case E1000_VMDQ_MAC: 142 rar_high |= (qsel << 18); 143 break; 144 case E1000_VMDQ_MAC_RSS: 145 rar_high |= 1 << (18 + qsel); 146 break; 147 148 } 149 150 /* write to receive address registers */ 151 E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); 152 E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 153 E1000_WRITE_FLUSH(hw); 154 } 155