diff options
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 55 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82599.c | 925 |
2 files changed, 980 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 59167d7e08ca..7adf959e2038 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -402,6 +402,61 @@ extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); | |||
402 | extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); | 402 | extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); |
403 | extern void ixgbe_write_eitr(struct ixgbe_q_vector *); | 403 | extern void ixgbe_write_eitr(struct ixgbe_q_vector *); |
404 | extern int ethtool_ioctl(struct ifreq *ifr); | 404 | extern int ethtool_ioctl(struct ifreq *ifr); |
405 | extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); | ||
406 | extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); | ||
407 | extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); | ||
408 | extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, | ||
409 | struct ixgbe_atr_input *input, | ||
410 | u8 queue); | ||
411 | extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | ||
412 | struct ixgbe_atr_input *input, | ||
413 | u16 soft_id, | ||
414 | u8 queue); | ||
415 | extern u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key); | ||
416 | extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, | ||
417 | u16 vlan_id); | ||
418 | extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, | ||
419 | u32 src_addr); | ||
420 | extern s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, | ||
421 | u32 dst_addr); | ||
422 | extern s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, | ||
423 | u32 src_addr_1, u32 src_addr_2, | ||
424 | u32 src_addr_3, u32 src_addr_4); | ||
425 | extern s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, | ||
426 | u32 dst_addr_1, u32 dst_addr_2, | ||
427 | u32 dst_addr_3, u32 dst_addr_4); | ||
428 | extern s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, | ||
429 | u16 src_port); | ||
430 | extern s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, | ||
431 | u16 dst_port); | ||
432 | extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, | ||
433 | u16 flex_byte); | ||
434 | extern s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, | ||
435 | u8 vm_pool); | ||
436 | extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, | ||
437 | u8 l4type); | ||
438 | extern s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, | ||
439 | u16 *vlan_id); | ||
440 | extern s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, | ||
441 | u32 *src_addr); | ||
442 | extern s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, | ||
443 | u32 *dst_addr); | ||
444 | extern s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, | ||
445 | u32 *src_addr_1, u32 *src_addr_2, | ||
446 | u32 *src_addr_3, u32 *src_addr_4); | ||
447 | extern s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, | ||
448 | u32 *dst_addr_1, u32 *dst_addr_2, | ||
449 | u32 *dst_addr_3, u32 *dst_addr_4); | ||
450 | extern s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, | ||
451 | u16 *src_port); | ||
452 | extern s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, | ||
453 | u16 *dst_port); | ||
454 | extern s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, | ||
455 | u16 *flex_byte); | ||
456 | extern s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, | ||
457 | u8 *vm_pool); | ||
458 | extern s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, | ||
459 | u8 *l4type); | ||
405 | #ifdef IXGBE_FCOE | 460 | #ifdef IXGBE_FCOE |
406 | extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); | 461 | extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); |
407 | extern int ixgbe_fso(struct ixgbe_adapter *adapter, | 462 | extern int ixgbe_fso(struct ixgbe_adapter *adapter, |
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 3f36d834ccfd..5c2627b68c2d 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -1165,6 +1165,931 @@ s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw) | |||
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | /** | 1167 | /** |
1168 | * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables. | ||
1169 | * @hw: pointer to hardware structure | ||
1170 | **/ | ||
1171 | s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) | ||
1172 | { | ||
1173 | int i; | ||
1174 | u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL); | ||
1175 | fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE; | ||
1176 | |||
1177 | /* | ||
1178 | * Before starting reinitialization process, | ||
1179 | * FDIRCMD.CMD must be zero. | ||
1180 | */ | ||
1181 | for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) { | ||
1182 | if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & | ||
1183 | IXGBE_FDIRCMD_CMD_MASK)) | ||
1184 | break; | ||
1185 | udelay(10); | ||
1186 | } | ||
1187 | if (i >= IXGBE_FDIRCMD_CMD_POLL) { | ||
1188 | hw_dbg(hw ,"Flow Director previous command isn't complete, " | ||
1189 | "aborting table re-initialization. \n"); | ||
1190 | return IXGBE_ERR_FDIR_REINIT_FAILED; | ||
1191 | } | ||
1192 | |||
1193 | IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0); | ||
1194 | IXGBE_WRITE_FLUSH(hw); | ||
1195 | /* | ||
1196 | * 82599 adapters flow director init flow cannot be restarted, | ||
1197 | * Workaround 82599 silicon errata by performing the following steps | ||
1198 | * before re-writing the FDIRCTRL control register with the same value. | ||
1199 | * - write 1 to bit 8 of FDIRCMD register & | ||
1200 | * - write 0 to bit 8 of FDIRCMD register | ||
1201 | */ | ||
1202 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, | ||
1203 | (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) | | ||
1204 | IXGBE_FDIRCMD_CLEARHT)); | ||
1205 | IXGBE_WRITE_FLUSH(hw); | ||
1206 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, | ||
1207 | (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & | ||
1208 | ~IXGBE_FDIRCMD_CLEARHT)); | ||
1209 | IXGBE_WRITE_FLUSH(hw); | ||
1210 | /* | ||
1211 | * Clear FDIR Hash register to clear any leftover hashes | ||
1212 | * waiting to be programmed. | ||
1213 | */ | ||
1214 | IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00); | ||
1215 | IXGBE_WRITE_FLUSH(hw); | ||
1216 | |||
1217 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); | ||
1218 | IXGBE_WRITE_FLUSH(hw); | ||
1219 | |||
1220 | /* Poll init-done after we write FDIRCTRL register */ | ||
1221 | for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { | ||
1222 | if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & | ||
1223 | IXGBE_FDIRCTRL_INIT_DONE) | ||
1224 | break; | ||
1225 | udelay(10); | ||
1226 | } | ||
1227 | if (i >= IXGBE_FDIR_INIT_DONE_POLL) { | ||
1228 | hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); | ||
1229 | return IXGBE_ERR_FDIR_REINIT_FAILED; | ||
1230 | } | ||
1231 | |||
1232 | /* Clear FDIR statistics registers (read to clear) */ | ||
1233 | IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT); | ||
1234 | IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT); | ||
1235 | IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); | ||
1236 | IXGBE_READ_REG(hw, IXGBE_FDIRMISS); | ||
1237 | IXGBE_READ_REG(hw, IXGBE_FDIRLEN); | ||
1238 | |||
1239 | return 0; | ||
1240 | } | ||
1241 | |||
1242 | /** | ||
1243 | * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters | ||
1244 | * @hw: pointer to hardware structure | ||
1245 | * @pballoc: which mode to allocate filters with | ||
1246 | **/ | ||
1247 | s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) | ||
1248 | { | ||
1249 | u32 fdirctrl = 0; | ||
1250 | u32 pbsize; | ||
1251 | int i; | ||
1252 | |||
1253 | /* | ||
1254 | * Before enabling Flow Director, the Rx Packet Buffer size | ||
1255 | * must be reduced. The new value is the current size minus | ||
1256 | * flow director memory usage size. | ||
1257 | */ | ||
1258 | pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc)); | ||
1259 | IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), | ||
1260 | (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize)); | ||
1261 | |||
1262 | /* | ||
1263 | * The defaults in the HW for RX PB 1-7 are not zero and so should be | ||
1264 | * intialized to zero for non DCB mode otherwise actual total RX PB | ||
1265 | * would be bigger than programmed and filter space would run into | ||
1266 | * the PB 0 region. | ||
1267 | */ | ||
1268 | for (i = 1; i < 8; i++) | ||
1269 | IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); | ||
1270 | |||
1271 | /* Send interrupt when 64 filters are left */ | ||
1272 | fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; | ||
1273 | |||
1274 | /* Set the maximum length per hash bucket to 0xA filters */ | ||
1275 | fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT; | ||
1276 | |||
1277 | switch (pballoc) { | ||
1278 | case IXGBE_FDIR_PBALLOC_64K: | ||
1279 | /* 8k - 1 signature filters */ | ||
1280 | fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K; | ||
1281 | break; | ||
1282 | case IXGBE_FDIR_PBALLOC_128K: | ||
1283 | /* 16k - 1 signature filters */ | ||
1284 | fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K; | ||
1285 | break; | ||
1286 | case IXGBE_FDIR_PBALLOC_256K: | ||
1287 | /* 32k - 1 signature filters */ | ||
1288 | fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K; | ||
1289 | break; | ||
1290 | default: | ||
1291 | /* bad value */ | ||
1292 | return IXGBE_ERR_CONFIG; | ||
1293 | }; | ||
1294 | |||
1295 | /* Move the flexible bytes to use the ethertype - shift 6 words */ | ||
1296 | fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); | ||
1297 | |||
1298 | fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS; | ||
1299 | |||
1300 | /* Prime the keys for hashing */ | ||
1301 | IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, | ||
1302 | htonl(IXGBE_ATR_BUCKET_HASH_KEY)); | ||
1303 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, | ||
1304 | htonl(IXGBE_ATR_SIGNATURE_HASH_KEY)); | ||
1305 | |||
1306 | /* | ||
1307 | * Poll init-done after we write the register. Estimated times: | ||
1308 | * 10G: PBALLOC = 11b, timing is 60us | ||
1309 | * 1G: PBALLOC = 11b, timing is 600us | ||
1310 | * 100M: PBALLOC = 11b, timing is 6ms | ||
1311 | * | ||
1312 | * Multiple these timings by 4 if under full Rx load | ||
1313 | * | ||
1314 | * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for | ||
1315 | * 1 msec per poll time. If we're at line rate and drop to 100M, then | ||
1316 | * this might not finish in our poll time, but we can live with that | ||
1317 | * for now. | ||
1318 | */ | ||
1319 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); | ||
1320 | IXGBE_WRITE_FLUSH(hw); | ||
1321 | for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { | ||
1322 | if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & | ||
1323 | IXGBE_FDIRCTRL_INIT_DONE) | ||
1324 | break; | ||
1325 | msleep(1); | ||
1326 | } | ||
1327 | if (i >= IXGBE_FDIR_INIT_DONE_POLL) | ||
1328 | hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); | ||
1329 | |||
1330 | return 0; | ||
1331 | } | ||
1332 | |||
1333 | /** | ||
1334 | * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters | ||
1335 | * @hw: pointer to hardware structure | ||
1336 | * @pballoc: which mode to allocate filters with | ||
1337 | **/ | ||
1338 | s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) | ||
1339 | { | ||
1340 | u32 fdirctrl = 0; | ||
1341 | u32 pbsize; | ||
1342 | int i; | ||
1343 | |||
1344 | /* | ||
1345 | * Before enabling Flow Director, the Rx Packet Buffer size | ||
1346 | * must be reduced. The new value is the current size minus | ||
1347 | * flow director memory usage size. | ||
1348 | */ | ||
1349 | pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc)); | ||
1350 | IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), | ||
1351 | (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize)); | ||
1352 | |||
1353 | /* | ||
1354 | * The defaults in the HW for RX PB 1-7 are not zero and so should be | ||
1355 | * intialized to zero for non DCB mode otherwise actual total RX PB | ||
1356 | * would be bigger than programmed and filter space would run into | ||
1357 | * the PB 0 region. | ||
1358 | */ | ||
1359 | for (i = 1; i < 8; i++) | ||
1360 | IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); | ||
1361 | |||
1362 | /* Send interrupt when 64 filters are left */ | ||
1363 | fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; | ||
1364 | |||
1365 | switch (pballoc) { | ||
1366 | case IXGBE_FDIR_PBALLOC_64K: | ||
1367 | /* 2k - 1 perfect filters */ | ||
1368 | fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K; | ||
1369 | break; | ||
1370 | case IXGBE_FDIR_PBALLOC_128K: | ||
1371 | /* 4k - 1 perfect filters */ | ||
1372 | fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K; | ||
1373 | break; | ||
1374 | case IXGBE_FDIR_PBALLOC_256K: | ||
1375 | /* 8k - 1 perfect filters */ | ||
1376 | fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K; | ||
1377 | break; | ||
1378 | default: | ||
1379 | /* bad value */ | ||
1380 | return IXGBE_ERR_CONFIG; | ||
1381 | }; | ||
1382 | |||
1383 | /* Turn perfect match filtering on */ | ||
1384 | fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH; | ||
1385 | fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS; | ||
1386 | |||
1387 | /* Move the flexible bytes to use the ethertype - shift 6 words */ | ||
1388 | fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); | ||
1389 | |||
1390 | /* Prime the keys for hashing */ | ||
1391 | IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, | ||
1392 | htonl(IXGBE_ATR_BUCKET_HASH_KEY)); | ||
1393 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, | ||
1394 | htonl(IXGBE_ATR_SIGNATURE_HASH_KEY)); | ||
1395 | |||
1396 | /* | ||
1397 | * Poll init-done after we write the register. Estimated times: | ||
1398 | * 10G: PBALLOC = 11b, timing is 60us | ||
1399 | * 1G: PBALLOC = 11b, timing is 600us | ||
1400 | * 100M: PBALLOC = 11b, timing is 6ms | ||
1401 | * | ||
1402 | * Multiple these timings by 4 if under full Rx load | ||
1403 | * | ||
1404 | * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for | ||
1405 | * 1 msec per poll time. If we're at line rate and drop to 100M, then | ||
1406 | * this might not finish in our poll time, but we can live with that | ||
1407 | * for now. | ||
1408 | */ | ||
1409 | |||
1410 | /* Set the maximum length per hash bucket to 0xA filters */ | ||
1411 | fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT); | ||
1412 | |||
1413 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); | ||
1414 | IXGBE_WRITE_FLUSH(hw); | ||
1415 | for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { | ||
1416 | if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & | ||
1417 | IXGBE_FDIRCTRL_INIT_DONE) | ||
1418 | break; | ||
1419 | msleep(1); | ||
1420 | } | ||
1421 | if (i >= IXGBE_FDIR_INIT_DONE_POLL) | ||
1422 | hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n"); | ||
1423 | |||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | |||
1428 | /** | ||
1429 | * ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR | ||
1430 | * @stream: input bitstream to compute the hash on | ||
1431 | * @key: 32-bit hash key | ||
1432 | **/ | ||
1433 | u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key) | ||
1434 | { | ||
1435 | /* | ||
1436 | * The algorithm is as follows: | ||
1437 | * Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350 | ||
1438 | * where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n] | ||
1439 | * and A[n] x B[n] is bitwise AND between same length strings | ||
1440 | * | ||
1441 | * K[n] is 16 bits, defined as: | ||
1442 | * for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15] | ||
1443 | * for n modulo 32 < 15, K[n] = | ||
1444 | * K[(n % 32:0) | (31:31 - (14 - (n % 32)))] | ||
1445 | * | ||
1446 | * S[n] is 16 bits, defined as: | ||
1447 | * for n >= 15, S[n] = S[n:n - 15] | ||
1448 | * for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))] | ||
1449 | * | ||
1450 | * To simplify for programming, the algorithm is implemented | ||
1451 | * in software this way: | ||
1452 | * | ||
1453 | * Key[31:0], Stream[335:0] | ||
1454 | * | ||
1455 | * tmp_key[11 * 32 - 1:0] = 11{Key[31:0] = key concatenated 11 times | ||
1456 | * int_key[350:0] = tmp_key[351:1] | ||
1457 | * int_stream[365:0] = Stream[14:0] | Stream[335:0] | Stream[335:321] | ||
1458 | * | ||
1459 | * hash[15:0] = 0; | ||
1460 | * for (i = 0; i < 351; i++) { | ||
1461 | * if (int_key[i]) | ||
1462 | * hash ^= int_stream[(i + 15):i]; | ||
1463 | * } | ||
1464 | */ | ||
1465 | |||
1466 | union { | ||
1467 | u64 fill[6]; | ||
1468 | u32 key[11]; | ||
1469 | u8 key_stream[44]; | ||
1470 | } tmp_key; | ||
1471 | |||
1472 | u8 *stream = (u8 *)atr_input; | ||
1473 | u8 int_key[44]; /* upper-most bit unused */ | ||
1474 | u8 hash_str[46]; /* upper-most 2 bits unused */ | ||
1475 | u16 hash_result = 0; | ||
1476 | int i, j, k, h; | ||
1477 | |||
1478 | /* | ||
1479 | * Initialize the fill member to prevent warnings | ||
1480 | * on some compilers | ||
1481 | */ | ||
1482 | tmp_key.fill[0] = 0; | ||
1483 | |||
1484 | /* First load the temporary key stream */ | ||
1485 | for (i = 0; i < 6; i++) { | ||
1486 | u64 fillkey = ((u64)key << 32) | key; | ||
1487 | tmp_key.fill[i] = fillkey; | ||
1488 | } | ||
1489 | |||
1490 | /* | ||
1491 | * Set the interim key for the hashing. Bit 352 is unused, so we must | ||
1492 | * shift and compensate when building the key. | ||
1493 | */ | ||
1494 | |||
1495 | int_key[0] = tmp_key.key_stream[0] >> 1; | ||
1496 | for (i = 1, j = 0; i < 44; i++) { | ||
1497 | unsigned int this_key = tmp_key.key_stream[j] << 7; | ||
1498 | j++; | ||
1499 | int_key[i] = (u8)(this_key | (tmp_key.key_stream[j] >> 1)); | ||
1500 | } | ||
1501 | |||
1502 | /* | ||
1503 | * Set the interim bit string for the hashing. Bits 368 and 367 are | ||
1504 | * unused, so shift and compensate when building the string. | ||
1505 | */ | ||
1506 | hash_str[0] = (stream[40] & 0x7f) >> 1; | ||
1507 | for (i = 1, j = 40; i < 46; i++) { | ||
1508 | unsigned int this_str = stream[j] << 7; | ||
1509 | j++; | ||
1510 | if (j > 41) | ||
1511 | j = 0; | ||
1512 | hash_str[i] = (u8)(this_str | (stream[j] >> 1)); | ||
1513 | } | ||
1514 | |||
1515 | /* | ||
1516 | * Now compute the hash. i is the index into hash_str, j is into our | ||
1517 | * key stream, k is counting the number of bits, and h interates within | ||
1518 | * each byte. | ||
1519 | */ | ||
1520 | for (i = 45, j = 43, k = 0; k < 351 && i >= 2 && j >= 0; i--, j--) { | ||
1521 | for (h = 0; h < 8 && k < 351; h++, k++) { | ||
1522 | if (int_key[j] & (1 << h)) { | ||
1523 | /* | ||
1524 | * Key bit is set, XOR in the current 16-bit | ||
1525 | * string. Example of processing: | ||
1526 | * h = 0, | ||
1527 | * tmp = (hash_str[i - 2] & 0 << 16) | | ||
1528 | * (hash_str[i - 1] & 0xff << 8) | | ||
1529 | * (hash_str[i] & 0xff >> 0) | ||
1530 | * So tmp = hash_str[15 + k:k], since the | ||
1531 | * i + 2 clause rolls off the 16-bit value | ||
1532 | * h = 7, | ||
1533 | * tmp = (hash_str[i - 2] & 0x7f << 9) | | ||
1534 | * (hash_str[i - 1] & 0xff << 1) | | ||
1535 | * (hash_str[i] & 0x80 >> 7) | ||
1536 | */ | ||
1537 | int tmp = (hash_str[i] >> h); | ||
1538 | tmp |= (hash_str[i - 1] << (8 - h)); | ||
1539 | tmp |= (int)(hash_str[i - 2] & ((1 << h) - 1)) | ||
1540 | << (16 - h); | ||
1541 | hash_result ^= (u16)tmp; | ||
1542 | } | ||
1543 | } | ||
1544 | } | ||
1545 | |||
1546 | return hash_result; | ||
1547 | } | ||
1548 | |||
1549 | /** | ||
1550 | * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream | ||
1551 | * @input: input stream to modify | ||
1552 | * @vlan: the VLAN id to load | ||
1553 | **/ | ||
1554 | s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) | ||
1555 | { | ||
1556 | input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] = vlan >> 8; | ||
1557 | input->byte_stream[IXGBE_ATR_VLAN_OFFSET] = vlan & 0xff; | ||
1558 | |||
1559 | return 0; | ||
1560 | } | ||
1561 | |||
1562 | /** | ||
1563 | * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address | ||
1564 | * @input: input stream to modify | ||
1565 | * @src_addr: the IP address to load | ||
1566 | **/ | ||
1567 | s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) | ||
1568 | { | ||
1569 | input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] = src_addr >> 24; | ||
1570 | input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] = | ||
1571 | (src_addr >> 16) & 0xff; | ||
1572 | input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] = | ||
1573 | (src_addr >> 8) & 0xff; | ||
1574 | input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET] = src_addr & 0xff; | ||
1575 | |||
1576 | return 0; | ||
1577 | } | ||
1578 | |||
1579 | /** | ||
1580 | * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address | ||
1581 | * @input: input stream to modify | ||
1582 | * @dst_addr: the IP address to load | ||
1583 | **/ | ||
1584 | s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) | ||
1585 | { | ||
1586 | input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] = dst_addr >> 24; | ||
1587 | input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] = | ||
1588 | (dst_addr >> 16) & 0xff; | ||
1589 | input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] = | ||
1590 | (dst_addr >> 8) & 0xff; | ||
1591 | input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET] = dst_addr & 0xff; | ||
1592 | |||
1593 | return 0; | ||
1594 | } | ||
1595 | |||
1596 | /** | ||
1597 | * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address | ||
1598 | * @input: input stream to modify | ||
1599 | * @src_addr_1: the first 4 bytes of the IP address to load | ||
1600 | * @src_addr_2: the second 4 bytes of the IP address to load | ||
1601 | * @src_addr_3: the third 4 bytes of the IP address to load | ||
1602 | * @src_addr_4: the fourth 4 bytes of the IP address to load | ||
1603 | **/ | ||
1604 | s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, | ||
1605 | u32 src_addr_1, u32 src_addr_2, | ||
1606 | u32 src_addr_3, u32 src_addr_4) | ||
1607 | { | ||
1608 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; | ||
1609 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = | ||
1610 | (src_addr_4 >> 8) & 0xff; | ||
1611 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] = | ||
1612 | (src_addr_4 >> 16) & 0xff; | ||
1613 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24; | ||
1614 | |||
1615 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff; | ||
1616 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] = | ||
1617 | (src_addr_3 >> 8) & 0xff; | ||
1618 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] = | ||
1619 | (src_addr_3 >> 16) & 0xff; | ||
1620 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24; | ||
1621 | |||
1622 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff; | ||
1623 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] = | ||
1624 | (src_addr_2 >> 8) & 0xff; | ||
1625 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] = | ||
1626 | (src_addr_2 >> 16) & 0xff; | ||
1627 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24; | ||
1628 | |||
1629 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff; | ||
1630 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] = | ||
1631 | (src_addr_1 >> 8) & 0xff; | ||
1632 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] = | ||
1633 | (src_addr_1 >> 16) & 0xff; | ||
1634 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24; | ||
1635 | |||
1636 | return 0; | ||
1637 | } | ||
1638 | |||
1639 | /** | ||
1640 | * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address | ||
1641 | * @input: input stream to modify | ||
1642 | * @dst_addr_1: the first 4 bytes of the IP address to load | ||
1643 | * @dst_addr_2: the second 4 bytes of the IP address to load | ||
1644 | * @dst_addr_3: the third 4 bytes of the IP address to load | ||
1645 | * @dst_addr_4: the fourth 4 bytes of the IP address to load | ||
1646 | **/ | ||
1647 | s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, | ||
1648 | u32 dst_addr_1, u32 dst_addr_2, | ||
1649 | u32 dst_addr_3, u32 dst_addr_4) | ||
1650 | { | ||
1651 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; | ||
1652 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = | ||
1653 | (dst_addr_4 >> 8) & 0xff; | ||
1654 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] = | ||
1655 | (dst_addr_4 >> 16) & 0xff; | ||
1656 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24; | ||
1657 | |||
1658 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff; | ||
1659 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] = | ||
1660 | (dst_addr_3 >> 8) & 0xff; | ||
1661 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] = | ||
1662 | (dst_addr_3 >> 16) & 0xff; | ||
1663 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24; | ||
1664 | |||
1665 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff; | ||
1666 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] = | ||
1667 | (dst_addr_2 >> 8) & 0xff; | ||
1668 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] = | ||
1669 | (dst_addr_2 >> 16) & 0xff; | ||
1670 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24; | ||
1671 | |||
1672 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff; | ||
1673 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] = | ||
1674 | (dst_addr_1 >> 8) & 0xff; | ||
1675 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] = | ||
1676 | (dst_addr_1 >> 16) & 0xff; | ||
1677 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24; | ||
1678 | |||
1679 | return 0; | ||
1680 | } | ||
1681 | |||
1682 | /** | ||
1683 | * ixgbe_atr_set_src_port_82599 - Sets the source port | ||
1684 | * @input: input stream to modify | ||
1685 | * @src_port: the source port to load | ||
1686 | **/ | ||
1687 | s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) | ||
1688 | { | ||
1689 | input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1] = src_port >> 8; | ||
1690 | input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] = src_port & 0xff; | ||
1691 | |||
1692 | return 0; | ||
1693 | } | ||
1694 | |||
1695 | /** | ||
1696 | * ixgbe_atr_set_dst_port_82599 - Sets the destination port | ||
1697 | * @input: input stream to modify | ||
1698 | * @dst_port: the destination port to load | ||
1699 | **/ | ||
1700 | s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port) | ||
1701 | { | ||
1702 | input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1] = dst_port >> 8; | ||
1703 | input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] = dst_port & 0xff; | ||
1704 | |||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1708 | /** | ||
1709 | * ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes | ||
1710 | * @input: input stream to modify | ||
1711 | * @flex_bytes: the flexible bytes to load | ||
1712 | **/ | ||
1713 | s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) | ||
1714 | { | ||
1715 | input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] = flex_byte >> 8; | ||
1716 | input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET] = flex_byte & 0xff; | ||
1717 | |||
1718 | return 0; | ||
1719 | } | ||
1720 | |||
1721 | /** | ||
1722 | * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool | ||
1723 | * @input: input stream to modify | ||
1724 | * @vm_pool: the Virtual Machine pool to load | ||
1725 | **/ | ||
1726 | s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool) | ||
1727 | { | ||
1728 | input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; | ||
1729 | |||
1730 | return 0; | ||
1731 | } | ||
1732 | |||
1733 | /** | ||
1734 | * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type | ||
1735 | * @input: input stream to modify | ||
1736 | * @l4type: the layer 4 type value to load | ||
1737 | **/ | ||
1738 | s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type) | ||
1739 | { | ||
1740 | input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET] = l4type; | ||
1741 | |||
1742 | return 0; | ||
1743 | } | ||
1744 | |||
1745 | /** | ||
1746 | * ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream | ||
1747 | * @input: input stream to search | ||
1748 | * @vlan: the VLAN id to load | ||
1749 | **/ | ||
1750 | s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan) | ||
1751 | { | ||
1752 | *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET]; | ||
1753 | *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8; | ||
1754 | |||
1755 | return 0; | ||
1756 | } | ||
1757 | |||
1758 | /** | ||
1759 | * ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address | ||
1760 | * @input: input stream to search | ||
1761 | * @src_addr: the IP address to load | ||
1762 | **/ | ||
1763 | s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr) | ||
1764 | { | ||
1765 | *src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET]; | ||
1766 | *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8; | ||
1767 | *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] << 16; | ||
1768 | *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] << 24; | ||
1769 | |||
1770 | return 0; | ||
1771 | } | ||
1772 | |||
1773 | /** | ||
1774 | * ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address | ||
1775 | * @input: input stream to search | ||
1776 | * @dst_addr: the IP address to load | ||
1777 | **/ | ||
1778 | s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr) | ||
1779 | { | ||
1780 | *dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET]; | ||
1781 | *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8; | ||
1782 | *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] << 16; | ||
1783 | *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] << 24; | ||
1784 | |||
1785 | return 0; | ||
1786 | } | ||
1787 | |||
1788 | /** | ||
1789 | * ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address | ||
1790 | * @input: input stream to search | ||
1791 | * @src_addr_1: the first 4 bytes of the IP address to load | ||
1792 | * @src_addr_2: the second 4 bytes of the IP address to load | ||
1793 | * @src_addr_3: the third 4 bytes of the IP address to load | ||
1794 | * @src_addr_4: the fourth 4 bytes of the IP address to load | ||
1795 | **/ | ||
1796 | s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, | ||
1797 | u32 *src_addr_1, u32 *src_addr_2, | ||
1798 | u32 *src_addr_3, u32 *src_addr_4) | ||
1799 | { | ||
1800 | *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12]; | ||
1801 | *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8; | ||
1802 | *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] << 16; | ||
1803 | *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] << 24; | ||
1804 | |||
1805 | *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8]; | ||
1806 | *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] << 8; | ||
1807 | *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] << 16; | ||
1808 | *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] << 24; | ||
1809 | |||
1810 | *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4]; | ||
1811 | *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] << 8; | ||
1812 | *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] << 16; | ||
1813 | *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] << 24; | ||
1814 | |||
1815 | *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET]; | ||
1816 | *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] << 8; | ||
1817 | *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] << 16; | ||
1818 | *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] << 24; | ||
1819 | |||
1820 | return 0; | ||
1821 | } | ||
1822 | |||
1823 | /** | ||
1824 | * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address | ||
1825 | * @input: input stream to search | ||
1826 | * @dst_addr_1: the first 4 bytes of the IP address to load | ||
1827 | * @dst_addr_2: the second 4 bytes of the IP address to load | ||
1828 | * @dst_addr_3: the third 4 bytes of the IP address to load | ||
1829 | * @dst_addr_4: the fourth 4 bytes of the IP address to load | ||
1830 | **/ | ||
1831 | s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, | ||
1832 | u32 *dst_addr_1, u32 *dst_addr_2, | ||
1833 | u32 *dst_addr_3, u32 *dst_addr_4) | ||
1834 | { | ||
1835 | *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12]; | ||
1836 | *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8; | ||
1837 | *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16; | ||
1838 | *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24; | ||
1839 | |||
1840 | *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8]; | ||
1841 | *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8; | ||
1842 | *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16; | ||
1843 | *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24; | ||
1844 | |||
1845 | *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4]; | ||
1846 | *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8; | ||
1847 | *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16; | ||
1848 | *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24; | ||
1849 | |||
1850 | *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET]; | ||
1851 | *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8; | ||
1852 | *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16; | ||
1853 | *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24; | ||
1854 | |||
1855 | return 0; | ||
1856 | } | ||
1857 | |||
1858 | /** | ||
1859 | * ixgbe_atr_get_src_port_82599 - Gets the source port | ||
1860 | * @input: input stream to modify | ||
1861 | * @src_port: the source port to load | ||
1862 | * | ||
1863 | * Even though the input is given in big-endian, the FDIRPORT registers | ||
1864 | * expect the ports to be programmed in little-endian. Hence the need to swap | ||
1865 | * endianness when retrieving the data. This can be confusing since the | ||
1866 | * internal hash engine expects it to be big-endian. | ||
1867 | **/ | ||
1868 | s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port) | ||
1869 | { | ||
1870 | *src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8; | ||
1871 | *src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1]; | ||
1872 | |||
1873 | return 0; | ||
1874 | } | ||
1875 | |||
1876 | /** | ||
1877 | * ixgbe_atr_get_dst_port_82599 - Gets the destination port | ||
1878 | * @input: input stream to modify | ||
1879 | * @dst_port: the destination port to load | ||
1880 | * | ||
1881 | * Even though the input is given in big-endian, the FDIRPORT registers | ||
1882 | * expect the ports to be programmed in little-endian. Hence the need to swap | ||
1883 | * endianness when retrieving the data. This can be confusing since the | ||
1884 | * internal hash engine expects it to be big-endian. | ||
1885 | **/ | ||
1886 | s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port) | ||
1887 | { | ||
1888 | *dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8; | ||
1889 | *dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1]; | ||
1890 | |||
1891 | return 0; | ||
1892 | } | ||
1893 | |||
1894 | /** | ||
1895 | * ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes | ||
1896 | * @input: input stream to modify | ||
1897 | * @flex_bytes: the flexible bytes to load | ||
1898 | **/ | ||
1899 | s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte) | ||
1900 | { | ||
1901 | *flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET]; | ||
1902 | *flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8; | ||
1903 | |||
1904 | return 0; | ||
1905 | } | ||
1906 | |||
1907 | /** | ||
1908 | * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool | ||
1909 | * @input: input stream to modify | ||
1910 | * @vm_pool: the Virtual Machine pool to load | ||
1911 | **/ | ||
1912 | s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool) | ||
1913 | { | ||
1914 | *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET]; | ||
1915 | |||
1916 | return 0; | ||
1917 | } | ||
1918 | |||
1919 | /** | ||
1920 | * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type | ||
1921 | * @input: input stream to modify | ||
1922 | * @l4type: the layer 4 type value to load | ||
1923 | **/ | ||
1924 | s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type) | ||
1925 | { | ||
1926 | *l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET]; | ||
1927 | |||
1928 | return 0; | ||
1929 | } | ||
1930 | |||
1931 | /** | ||
1932 | * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter | ||
1933 | * @hw: pointer to hardware structure | ||
1934 | * @stream: input bitstream | ||
1935 | * @queue: queue index to direct traffic to | ||
1936 | **/ | ||
1937 | s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, | ||
1938 | struct ixgbe_atr_input *input, | ||
1939 | u8 queue) | ||
1940 | { | ||
1941 | u64 fdirhashcmd; | ||
1942 | u64 fdircmd; | ||
1943 | u32 fdirhash; | ||
1944 | u16 bucket_hash, sig_hash; | ||
1945 | u8 l4type; | ||
1946 | |||
1947 | bucket_hash = ixgbe_atr_compute_hash_82599(input, | ||
1948 | IXGBE_ATR_BUCKET_HASH_KEY); | ||
1949 | |||
1950 | /* bucket_hash is only 15 bits */ | ||
1951 | bucket_hash &= IXGBE_ATR_HASH_MASK; | ||
1952 | |||
1953 | sig_hash = ixgbe_atr_compute_hash_82599(input, | ||
1954 | IXGBE_ATR_SIGNATURE_HASH_KEY); | ||
1955 | |||
1956 | /* Get the l4type in order to program FDIRCMD properly */ | ||
1957 | /* lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 */ | ||
1958 | ixgbe_atr_get_l4type_82599(input, &l4type); | ||
1959 | |||
1960 | /* | ||
1961 | * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits | ||
1962 | * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH. | ||
1963 | */ | ||
1964 | fdirhash = sig_hash << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash; | ||
1965 | |||
1966 | fdircmd = (IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | | ||
1967 | IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN); | ||
1968 | |||
1969 | switch (l4type & IXGBE_ATR_L4TYPE_MASK) { | ||
1970 | case IXGBE_ATR_L4TYPE_TCP: | ||
1971 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP; | ||
1972 | break; | ||
1973 | case IXGBE_ATR_L4TYPE_UDP: | ||
1974 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP; | ||
1975 | break; | ||
1976 | case IXGBE_ATR_L4TYPE_SCTP: | ||
1977 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP; | ||
1978 | break; | ||
1979 | default: | ||
1980 | hw_dbg(hw, "Error on l4type input\n"); | ||
1981 | return IXGBE_ERR_CONFIG; | ||
1982 | } | ||
1983 | |||
1984 | if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) | ||
1985 | fdircmd |= IXGBE_FDIRCMD_IPV6; | ||
1986 | |||
1987 | fdircmd |= ((u64)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT); | ||
1988 | fdirhashcmd = ((fdircmd << 32) | fdirhash); | ||
1989 | |||
1990 | IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd); | ||
1991 | |||
1992 | return 0; | ||
1993 | } | ||
1994 | |||
1995 | /** | ||
1996 | * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter | ||
1997 | * @hw: pointer to hardware structure | ||
1998 | * @input: input bitstream | ||
1999 | * @queue: queue index to direct traffic to | ||
2000 | * | ||
2001 | * Note that the caller to this function must lock before calling, since the | ||
2002 | * hardware writes must be protected from one another. | ||
2003 | **/ | ||
2004 | s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | ||
2005 | struct ixgbe_atr_input *input, | ||
2006 | u16 soft_id, | ||
2007 | u8 queue) | ||
2008 | { | ||
2009 | u32 fdircmd = 0; | ||
2010 | u32 fdirhash; | ||
2011 | u32 src_ipv4, dst_ipv4; | ||
2012 | u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; | ||
2013 | u16 src_port, dst_port, vlan_id, flex_bytes; | ||
2014 | u16 bucket_hash; | ||
2015 | u8 l4type; | ||
2016 | |||
2017 | /* Get our input values */ | ||
2018 | ixgbe_atr_get_l4type_82599(input, &l4type); | ||
2019 | |||
2020 | /* | ||
2021 | * Check l4type formatting, and bail out before we touch the hardware | ||
2022 | * if there's a configuration issue | ||
2023 | */ | ||
2024 | switch (l4type & IXGBE_ATR_L4TYPE_MASK) { | ||
2025 | case IXGBE_ATR_L4TYPE_TCP: | ||
2026 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP; | ||
2027 | break; | ||
2028 | case IXGBE_ATR_L4TYPE_UDP: | ||
2029 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP; | ||
2030 | break; | ||
2031 | case IXGBE_ATR_L4TYPE_SCTP: | ||
2032 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP; | ||
2033 | break; | ||
2034 | default: | ||
2035 | hw_dbg(hw, "Error on l4type input\n"); | ||
2036 | return IXGBE_ERR_CONFIG; | ||
2037 | } | ||
2038 | |||
2039 | bucket_hash = ixgbe_atr_compute_hash_82599(input, | ||
2040 | IXGBE_ATR_BUCKET_HASH_KEY); | ||
2041 | |||
2042 | /* bucket_hash is only 15 bits */ | ||
2043 | bucket_hash &= IXGBE_ATR_HASH_MASK; | ||
2044 | |||
2045 | ixgbe_atr_get_vlan_id_82599(input, &vlan_id); | ||
2046 | ixgbe_atr_get_src_port_82599(input, &src_port); | ||
2047 | ixgbe_atr_get_dst_port_82599(input, &dst_port); | ||
2048 | ixgbe_atr_get_flex_byte_82599(input, &flex_bytes); | ||
2049 | |||
2050 | fdirhash = soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash; | ||
2051 | |||
2052 | /* Now figure out if we're IPv4 or IPv6 */ | ||
2053 | if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) { | ||
2054 | /* IPv6 */ | ||
2055 | ixgbe_atr_get_src_ipv6_82599(input, &src_ipv6_1, &src_ipv6_2, | ||
2056 | &src_ipv6_3, &src_ipv6_4); | ||
2057 | |||
2058 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), src_ipv6_1); | ||
2059 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(1), src_ipv6_2); | ||
2060 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), src_ipv6_3); | ||
2061 | /* The last 4 bytes is the same register as IPv4 */ | ||
2062 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv6_4); | ||
2063 | |||
2064 | fdircmd |= IXGBE_FDIRCMD_IPV6; | ||
2065 | fdircmd |= IXGBE_FDIRCMD_IPv6DMATCH; | ||
2066 | } else { | ||
2067 | /* IPv4 */ | ||
2068 | ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4); | ||
2069 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4); | ||
2070 | |||
2071 | } | ||
2072 | |||
2073 | ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4); | ||
2074 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, dst_ipv4); | ||
2075 | |||
2076 | IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id | | ||
2077 | (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT))); | ||
2078 | IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | | ||
2079 | (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); | ||
2080 | |||
2081 | fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; | ||
2082 | fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; | ||
2083 | fdircmd |= IXGBE_FDIRCMD_LAST; | ||
2084 | fdircmd |= IXGBE_FDIRCMD_QUEUE_EN; | ||
2085 | fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; | ||
2086 | |||
2087 | IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); | ||
2088 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); | ||
2089 | |||
2090 | return 0; | ||
2091 | } | ||
2092 | /** | ||
1168 | * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register | 2093 | * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register |
1169 | * @hw: pointer to hardware structure | 2094 | * @hw: pointer to hardware structure |
1170 | * @reg: analog register to read | 2095 | * @reg: analog register to read |