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
e1000_write_pci_cfg(struct e1000_hw * hw,uint32_t reg,uint16_t * value)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
e1000_read_pci_cfg(struct e1000_hw * hw,uint32_t reg,uint16_t * value)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
e1000_read_pcie_cap_reg(struct e1000_hw * hw,uint32_t reg,uint16_t * value)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
e1000_write_pcie_cap_reg(struct e1000_hw * hw,uint32_t reg,uint16_t * value)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
e1000_rar_clear(struct e1000_hw * hw,uint32_t index)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
e1000_rar_set_vmdq(struct e1000_hw * hw,const uint8_t * addr,uint32_t index,uint32_t vmdq_mode,uint8_t qsel)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