diff options
author | Greg Rose <gregory.v.rose@intel.com> | 2010-01-08 21:26:26 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-10 16:34:26 -0500 |
commit | 096a58fdec72335d9cbee94bd10b312c5f14f8af (patch) | |
tree | 18949369cf550ea8b001d556b4c5eedd5689a914 /drivers/net/ixgbe/ixgbe_82599.c | |
parent | 92ed72d536445334829af65c63516557fd50f554 (diff) |
ixgbe: Add SR-IOV feature enablement code
Adds code to the core 82599 module to support SR-IOV features of the 82599
network controller
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_82599.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82599.c | 126 |
1 files changed, 68 insertions, 58 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 538340527aa6..9ec296cf4c40 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "ixgbe.h" | 32 | #include "ixgbe.h" |
33 | #include "ixgbe_phy.h" | 33 | #include "ixgbe_phy.h" |
34 | #include "ixgbe_mbx.h" | ||
34 | 35 | ||
35 | #define IXGBE_82599_MAX_TX_QUEUES 128 | 36 | #define IXGBE_82599_MAX_TX_QUEUES 128 |
36 | #define IXGBE_82599_MAX_RX_QUEUES 128 | 37 | #define IXGBE_82599_MAX_RX_QUEUES 128 |
@@ -951,8 +952,6 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) | |||
951 | 952 | ||
952 | msleep(50); | 953 | msleep(50); |
953 | 954 | ||
954 | |||
955 | |||
956 | /* | 955 | /* |
957 | * Store the original AUTOC/AUTOC2 values if they have not been | 956 | * Store the original AUTOC/AUTOC2 values if they have not been |
958 | * stored off yet. Otherwise restore the stored original | 957 | * stored off yet. Otherwise restore the stored original |
@@ -1095,9 +1094,11 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, | |||
1095 | bool vlan_on) | 1094 | bool vlan_on) |
1096 | { | 1095 | { |
1097 | u32 regindex; | 1096 | u32 regindex; |
1097 | u32 vlvf_index; | ||
1098 | u32 bitindex; | 1098 | u32 bitindex; |
1099 | u32 bits; | 1099 | u32 bits; |
1100 | u32 first_empty_slot; | 1100 | u32 first_empty_slot; |
1101 | u32 vt_ctl; | ||
1101 | 1102 | ||
1102 | if (vlan > 4095) | 1103 | if (vlan > 4095) |
1103 | return IXGBE_ERR_PARAM; | 1104 | return IXGBE_ERR_PARAM; |
@@ -1124,76 +1125,84 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, | |||
1124 | 1125 | ||
1125 | 1126 | ||
1126 | /* Part 2 | 1127 | /* Part 2 |
1127 | * If the vind is set | 1128 | * If VT mode is set |
1128 | * Either vlan_on | 1129 | * Either vlan_on |
1129 | * make sure the vlan is in VLVF | 1130 | * make sure the vlan is in VLVF |
1130 | * set the vind bit in the matching VLVFB | 1131 | * set the vind bit in the matching VLVFB |
1131 | * Or !vlan_on | 1132 | * Or !vlan_on |
1132 | * clear the pool bit and possibly the vind | 1133 | * clear the pool bit and possibly the vind |
1133 | */ | 1134 | */ |
1134 | if (vind) { | 1135 | vt_ctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); |
1135 | /* find the vlanid or the first empty slot */ | 1136 | if (!(vt_ctl & IXGBE_VT_CTL_VT_ENABLE)) |
1136 | first_empty_slot = 0; | 1137 | goto out; |
1137 | |||
1138 | for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { | ||
1139 | bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); | ||
1140 | if (!bits && !first_empty_slot) | ||
1141 | first_empty_slot = regindex; | ||
1142 | else if ((bits & 0x0FFF) == vlan) | ||
1143 | break; | ||
1144 | } | ||
1145 | 1138 | ||
1146 | if (regindex >= IXGBE_VLVF_ENTRIES) { | 1139 | /* find the vlanid or the first empty slot */ |
1147 | if (first_empty_slot) | 1140 | first_empty_slot = 0; |
1148 | regindex = first_empty_slot; | 1141 | |
1149 | else { | 1142 | for (vlvf_index = 1; vlvf_index < IXGBE_VLVF_ENTRIES; vlvf_index++) { |
1150 | hw_dbg(hw, "No space in VLVF.\n"); | 1143 | bits = IXGBE_READ_REG(hw, IXGBE_VLVF(vlvf_index)); |
1151 | goto out; | 1144 | if (!bits && !first_empty_slot) |
1152 | } | 1145 | first_empty_slot = vlvf_index; |
1146 | else if ((bits & 0x0FFF) == vlan) | ||
1147 | break; | ||
1148 | } | ||
1149 | |||
1150 | if (vlvf_index >= IXGBE_VLVF_ENTRIES) { | ||
1151 | if (first_empty_slot) | ||
1152 | vlvf_index = first_empty_slot; | ||
1153 | else { | ||
1154 | hw_dbg(hw, "No space in VLVF.\n"); | ||
1155 | goto out; | ||
1153 | } | 1156 | } |
1157 | } | ||
1154 | 1158 | ||
1155 | if (vlan_on) { | 1159 | if (vlan_on) { |
1156 | /* set the pool bit */ | 1160 | /* set the pool bit */ |
1157 | if (vind < 32) { | 1161 | if (vind < 32) { |
1158 | bits = IXGBE_READ_REG(hw, | 1162 | bits = IXGBE_READ_REG(hw, |
1159 | IXGBE_VLVFB(regindex * 2)); | 1163 | IXGBE_VLVFB(vlvf_index * 2)); |
1160 | bits |= (1 << vind); | 1164 | bits |= (1 << vind); |
1161 | IXGBE_WRITE_REG(hw, | 1165 | IXGBE_WRITE_REG(hw, |
1162 | IXGBE_VLVFB(regindex * 2), bits); | 1166 | IXGBE_VLVFB(vlvf_index * 2), bits); |
1163 | } else { | ||
1164 | bits = IXGBE_READ_REG(hw, | ||
1165 | IXGBE_VLVFB((regindex * 2) + 1)); | ||
1166 | bits |= (1 << vind); | ||
1167 | IXGBE_WRITE_REG(hw, | ||
1168 | IXGBE_VLVFB((regindex * 2) + 1), bits); | ||
1169 | } | ||
1170 | } else { | 1167 | } else { |
1171 | /* clear the pool bit */ | 1168 | bits = IXGBE_READ_REG(hw, |
1172 | if (vind < 32) { | 1169 | IXGBE_VLVFB((vlvf_index * 2) + 1)); |
1173 | bits = IXGBE_READ_REG(hw, | 1170 | bits |= (1 << (vind - 32)); |
1174 | IXGBE_VLVFB(regindex * 2)); | 1171 | IXGBE_WRITE_REG(hw, |
1172 | IXGBE_VLVFB((vlvf_index * 2) + 1), bits); | ||
1173 | } | ||
1174 | } else { | ||
1175 | /* clear the pool bit */ | ||
1176 | if (vind < 32) { | ||
1177 | bits = IXGBE_READ_REG(hw, | ||
1178 | IXGBE_VLVFB(vlvf_index * 2)); | ||
1175 | bits &= ~(1 << vind); | 1179 | bits &= ~(1 << vind); |
1176 | IXGBE_WRITE_REG(hw, | 1180 | IXGBE_WRITE_REG(hw, |
1177 | IXGBE_VLVFB(regindex * 2), bits); | 1181 | IXGBE_VLVFB(vlvf_index * 2), bits); |
1178 | bits |= IXGBE_READ_REG(hw, | 1182 | bits |= IXGBE_READ_REG(hw, |
1179 | IXGBE_VLVFB((regindex * 2) + 1)); | 1183 | IXGBE_VLVFB((vlvf_index * 2) + 1)); |
1180 | } else { | 1184 | } else { |
1181 | bits = IXGBE_READ_REG(hw, | 1185 | bits = IXGBE_READ_REG(hw, |
1182 | IXGBE_VLVFB((regindex * 2) + 1)); | 1186 | IXGBE_VLVFB((vlvf_index * 2) + 1)); |
1183 | bits &= ~(1 << vind); | 1187 | bits &= ~(1 << (vind - 32)); |
1184 | IXGBE_WRITE_REG(hw, | 1188 | IXGBE_WRITE_REG(hw, |
1185 | IXGBE_VLVFB((regindex * 2) + 1), bits); | 1189 | IXGBE_VLVFB((vlvf_index * 2) + 1), bits); |
1186 | bits |= IXGBE_READ_REG(hw, | 1190 | bits |= IXGBE_READ_REG(hw, |
1187 | IXGBE_VLVFB(regindex * 2)); | 1191 | IXGBE_VLVFB(vlvf_index * 2)); |
1188 | } | ||
1189 | } | 1192 | } |
1193 | } | ||
1190 | 1194 | ||
1191 | if (bits) | 1195 | if (bits) { |
1192 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), | 1196 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), |
1193 | (IXGBE_VLVF_VIEN | vlan)); | 1197 | (IXGBE_VLVF_VIEN | vlan)); |
1194 | else | 1198 | /* if bits is non-zero then some pools/VFs are still |
1195 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0); | 1199 | * using this VLAN ID. Force the VFTA entry to on */ |
1200 | bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); | ||
1201 | bits |= (1 << bitindex); | ||
1202 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits); | ||
1196 | } | 1203 | } |
1204 | else | ||
1205 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); | ||
1197 | 1206 | ||
1198 | out: | 1207 | out: |
1199 | return 0; | 1208 | return 0; |
@@ -2655,4 +2664,5 @@ struct ixgbe_info ixgbe_82599_info = { | |||
2655 | .mac_ops = &mac_ops_82599, | 2664 | .mac_ops = &mac_ops_82599, |
2656 | .eeprom_ops = &eeprom_ops_82599, | 2665 | .eeprom_ops = &eeprom_ops_82599, |
2657 | .phy_ops = &phy_ops_82599, | 2666 | .phy_ops = &phy_ops_82599, |
2667 | .mbx_ops = &mbx_ops_82599, | ||
2658 | }; | 2668 | }; |