diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_82599.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82599.c | 436 |
1 files changed, 136 insertions, 300 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index d41931f5c3d3..8d316d9cd29d 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -1422,211 +1422,6 @@ static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input, | |||
1422 | } | 1422 | } |
1423 | 1423 | ||
1424 | /** | 1424 | /** |
1425 | * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream | ||
1426 | * @input: input stream to modify | ||
1427 | * @vlan: the VLAN id to load | ||
1428 | **/ | ||
1429 | s32 ixgbe_atr_set_vlan_id_82599(union ixgbe_atr_input *input, __be16 vlan) | ||
1430 | { | ||
1431 | input->formatted.vlan_id = vlan; | ||
1432 | |||
1433 | return 0; | ||
1434 | } | ||
1435 | |||
1436 | /** | ||
1437 | * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address | ||
1438 | * @input: input stream to modify | ||
1439 | * @src_addr: the IP address to load | ||
1440 | **/ | ||
1441 | s32 ixgbe_atr_set_src_ipv4_82599(union ixgbe_atr_input *input, __be32 src_addr) | ||
1442 | { | ||
1443 | input->formatted.src_ip[0] = src_addr; | ||
1444 | |||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | /** | ||
1449 | * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address | ||
1450 | * @input: input stream to modify | ||
1451 | * @dst_addr: the IP address to load | ||
1452 | **/ | ||
1453 | s32 ixgbe_atr_set_dst_ipv4_82599(union ixgbe_atr_input *input, __be32 dst_addr) | ||
1454 | { | ||
1455 | input->formatted.dst_ip[0] = dst_addr; | ||
1456 | |||
1457 | return 0; | ||
1458 | } | ||
1459 | |||
1460 | /** | ||
1461 | * ixgbe_atr_set_src_port_82599 - Sets the source port | ||
1462 | * @input: input stream to modify | ||
1463 | * @src_port: the source port to load | ||
1464 | **/ | ||
1465 | s32 ixgbe_atr_set_src_port_82599(union ixgbe_atr_input *input, __be16 src_port) | ||
1466 | { | ||
1467 | input->formatted.src_port = src_port; | ||
1468 | |||
1469 | return 0; | ||
1470 | } | ||
1471 | |||
1472 | /** | ||
1473 | * ixgbe_atr_set_dst_port_82599 - Sets the destination port | ||
1474 | * @input: input stream to modify | ||
1475 | * @dst_port: the destination port to load | ||
1476 | **/ | ||
1477 | s32 ixgbe_atr_set_dst_port_82599(union ixgbe_atr_input *input, __be16 dst_port) | ||
1478 | { | ||
1479 | input->formatted.dst_port = dst_port; | ||
1480 | |||
1481 | return 0; | ||
1482 | } | ||
1483 | |||
1484 | /** | ||
1485 | * ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes | ||
1486 | * @input: input stream to modify | ||
1487 | * @flex_bytes: the flexible bytes to load | ||
1488 | **/ | ||
1489 | s32 ixgbe_atr_set_flex_byte_82599(union ixgbe_atr_input *input, | ||
1490 | __be16 flex_bytes) | ||
1491 | { | ||
1492 | input->formatted.flex_bytes = flex_bytes; | ||
1493 | |||
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | /** | ||
1498 | * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type | ||
1499 | * @input: input stream to modify | ||
1500 | * @l4type: the layer 4 type value to load | ||
1501 | **/ | ||
1502 | s32 ixgbe_atr_set_l4type_82599(union ixgbe_atr_input *input, u8 l4type) | ||
1503 | { | ||
1504 | input->formatted.flow_type = l4type; | ||
1505 | |||
1506 | return 0; | ||
1507 | } | ||
1508 | |||
1509 | /** | ||
1510 | * ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream | ||
1511 | * @input: input stream to search | ||
1512 | * @vlan: the VLAN id to load | ||
1513 | **/ | ||
1514 | static s32 ixgbe_atr_get_vlan_id_82599(union ixgbe_atr_input *input, __be16 *vlan) | ||
1515 | { | ||
1516 | *vlan = input->formatted.vlan_id; | ||
1517 | |||
1518 | return 0; | ||
1519 | } | ||
1520 | |||
1521 | /** | ||
1522 | * ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address | ||
1523 | * @input: input stream to search | ||
1524 | * @src_addr: the IP address to load | ||
1525 | **/ | ||
1526 | static s32 ixgbe_atr_get_src_ipv4_82599(union ixgbe_atr_input *input, | ||
1527 | __be32 *src_addr) | ||
1528 | { | ||
1529 | *src_addr = input->formatted.src_ip[0]; | ||
1530 | |||
1531 | return 0; | ||
1532 | } | ||
1533 | |||
1534 | /** | ||
1535 | * ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address | ||
1536 | * @input: input stream to search | ||
1537 | * @dst_addr: the IP address to load | ||
1538 | **/ | ||
1539 | static s32 ixgbe_atr_get_dst_ipv4_82599(union ixgbe_atr_input *input, | ||
1540 | __be32 *dst_addr) | ||
1541 | { | ||
1542 | *dst_addr = input->formatted.dst_ip[0]; | ||
1543 | |||
1544 | return 0; | ||
1545 | } | ||
1546 | |||
1547 | /** | ||
1548 | * ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address | ||
1549 | * @input: input stream to search | ||
1550 | * @src_addr_1: the first 4 bytes of the IP address to load | ||
1551 | * @src_addr_2: the second 4 bytes of the IP address to load | ||
1552 | * @src_addr_3: the third 4 bytes of the IP address to load | ||
1553 | * @src_addr_4: the fourth 4 bytes of the IP address to load | ||
1554 | **/ | ||
1555 | static s32 ixgbe_atr_get_src_ipv6_82599(union ixgbe_atr_input *input, | ||
1556 | __be32 *src_addr_0, __be32 *src_addr_1, | ||
1557 | __be32 *src_addr_2, __be32 *src_addr_3) | ||
1558 | { | ||
1559 | *src_addr_0 = input->formatted.src_ip[0]; | ||
1560 | *src_addr_1 = input->formatted.src_ip[1]; | ||
1561 | *src_addr_2 = input->formatted.src_ip[2]; | ||
1562 | *src_addr_3 = input->formatted.src_ip[3]; | ||
1563 | |||
1564 | return 0; | ||
1565 | } | ||
1566 | |||
1567 | /** | ||
1568 | * ixgbe_atr_get_src_port_82599 - Gets the source port | ||
1569 | * @input: input stream to modify | ||
1570 | * @src_port: the source port to load | ||
1571 | * | ||
1572 | * Even though the input is given in big-endian, the FDIRPORT registers | ||
1573 | * expect the ports to be programmed in little-endian. Hence the need to swap | ||
1574 | * endianness when retrieving the data. This can be confusing since the | ||
1575 | * internal hash engine expects it to be big-endian. | ||
1576 | **/ | ||
1577 | static s32 ixgbe_atr_get_src_port_82599(union ixgbe_atr_input *input, | ||
1578 | __be16 *src_port) | ||
1579 | { | ||
1580 | *src_port = input->formatted.src_port; | ||
1581 | |||
1582 | return 0; | ||
1583 | } | ||
1584 | |||
1585 | /** | ||
1586 | * ixgbe_atr_get_dst_port_82599 - Gets the destination port | ||
1587 | * @input: input stream to modify | ||
1588 | * @dst_port: the destination port to load | ||
1589 | * | ||
1590 | * Even though the input is given in big-endian, the FDIRPORT registers | ||
1591 | * expect the ports to be programmed in little-endian. Hence the need to swap | ||
1592 | * endianness when retrieving the data. This can be confusing since the | ||
1593 | * internal hash engine expects it to be big-endian. | ||
1594 | **/ | ||
1595 | static s32 ixgbe_atr_get_dst_port_82599(union ixgbe_atr_input *input, | ||
1596 | __be16 *dst_port) | ||
1597 | { | ||
1598 | *dst_port = input->formatted.dst_port; | ||
1599 | |||
1600 | return 0; | ||
1601 | } | ||
1602 | |||
1603 | /** | ||
1604 | * ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes | ||
1605 | * @input: input stream to modify | ||
1606 | * @flex_bytes: the flexible bytes to load | ||
1607 | **/ | ||
1608 | static s32 ixgbe_atr_get_flex_byte_82599(union ixgbe_atr_input *input, | ||
1609 | __be16 *flex_bytes) | ||
1610 | { | ||
1611 | *flex_bytes = input->formatted.flex_bytes; | ||
1612 | |||
1613 | return 0; | ||
1614 | } | ||
1615 | |||
1616 | /** | ||
1617 | * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type | ||
1618 | * @input: input stream to modify | ||
1619 | * @l4type: the layer 4 type value to load | ||
1620 | **/ | ||
1621 | static s32 ixgbe_atr_get_l4type_82599(union ixgbe_atr_input *input, | ||
1622 | u8 *l4type) | ||
1623 | { | ||
1624 | *l4type = input->formatted.flow_type; | ||
1625 | |||
1626 | return 0; | ||
1627 | } | ||
1628 | |||
1629 | /** | ||
1630 | * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter | 1425 | * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter |
1631 | * @hw: pointer to hardware structure | 1426 | * @hw: pointer to hardware structure |
1632 | * @input: unique input dword | 1427 | * @input: unique input dword |
@@ -1679,6 +1474,43 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, | |||
1679 | } | 1474 | } |
1680 | 1475 | ||
1681 | /** | 1476 | /** |
1477 | * ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks | ||
1478 | * @input_mask: mask to be bit swapped | ||
1479 | * | ||
1480 | * The source and destination port masks for flow director are bit swapped | ||
1481 | * in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc. In order to | ||
1482 | * generate a correctly swapped value we need to bit swap the mask and that | ||
1483 | * is what is accomplished by this function. | ||
1484 | **/ | ||
1485 | static u32 ixgbe_get_fdirtcpm_82599(struct ixgbe_atr_input_masks *input_masks) | ||
1486 | { | ||
1487 | u32 mask = ntohs(input_masks->dst_port_mask); | ||
1488 | mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT; | ||
1489 | mask |= ntohs(input_masks->src_port_mask); | ||
1490 | mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1); | ||
1491 | mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2); | ||
1492 | mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4); | ||
1493 | return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8); | ||
1494 | } | ||
1495 | |||
1496 | /* | ||
1497 | * These two macros are meant to address the fact that we have registers | ||
1498 | * that are either all or in part big-endian. As a result on big-endian | ||
1499 | * systems we will end up byte swapping the value to little-endian before | ||
1500 | * it is byte swapped again and written to the hardware in the original | ||
1501 | * big-endian format. | ||
1502 | */ | ||
1503 | #define IXGBE_STORE_AS_BE32(_value) \ | ||
1504 | (((u32)(_value) >> 24) | (((u32)(_value) & 0x00FF0000) >> 8) | \ | ||
1505 | (((u32)(_value) & 0x0000FF00) << 8) | ((u32)(_value) << 24)) | ||
1506 | |||
1507 | #define IXGBE_WRITE_REG_BE32(a, reg, value) \ | ||
1508 | IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(ntohl(value))) | ||
1509 | |||
1510 | #define IXGBE_STORE_AS_BE16(_value) \ | ||
1511 | (((u16)(_value) >> 8) | ((u16)(_value) << 8)) | ||
1512 | |||
1513 | /** | ||
1682 | * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter | 1514 | * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter |
1683 | * @hw: pointer to hardware structure | 1515 | * @hw: pointer to hardware structure |
1684 | * @input: input bitstream | 1516 | * @input: input bitstream |
@@ -1694,131 +1526,135 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | |||
1694 | struct ixgbe_atr_input_masks *input_masks, | 1526 | struct ixgbe_atr_input_masks *input_masks, |
1695 | u16 soft_id, u8 queue) | 1527 | u16 soft_id, u8 queue) |
1696 | { | 1528 | { |
1697 | u32 fdircmd = 0; | ||
1698 | u32 fdirhash; | 1529 | u32 fdirhash; |
1699 | u32 src_ipv4 = 0, dst_ipv4 = 0; | 1530 | u32 fdircmd; |
1700 | u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; | 1531 | u32 fdirport, fdirtcpm; |
1701 | u16 src_port, dst_port, vlan_id, flex_bytes; | 1532 | u32 fdirvlan; |
1702 | u16 bucket_hash; | 1533 | /* start with VLAN, flex bytes, VM pool, and IPv6 destination masked */ |
1703 | u8 l4type; | 1534 | u32 fdirm = IXGBE_FDIRM_VLANID | IXGBE_FDIRM_VLANP | IXGBE_FDIRM_FLEX | |
1704 | u8 fdirm = 0; | 1535 | IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6; |
1705 | |||
1706 | /* Get our input values */ | ||
1707 | ixgbe_atr_get_l4type_82599(input, &l4type); | ||
1708 | 1536 | ||
1709 | /* | 1537 | /* |
1710 | * Check l4type formatting, and bail out before we touch the hardware | 1538 | * Check flow_type formatting, and bail out before we touch the hardware |
1711 | * if there's a configuration issue | 1539 | * if there's a configuration issue |
1712 | */ | 1540 | */ |
1713 | switch (l4type & IXGBE_ATR_L4TYPE_MASK) { | 1541 | switch (input->formatted.flow_type) { |
1714 | case IXGBE_ATR_L4TYPE_TCP: | 1542 | case IXGBE_ATR_FLOW_TYPE_IPV4: |
1715 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP; | 1543 | /* use the L4 protocol mask for raw IPv4/IPv6 traffic */ |
1716 | break; | 1544 | fdirm |= IXGBE_FDIRM_L4P; |
1717 | case IXGBE_ATR_L4TYPE_UDP: | 1545 | case IXGBE_ATR_FLOW_TYPE_SCTPV4: |
1718 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP; | 1546 | if (input_masks->dst_port_mask || input_masks->src_port_mask) { |
1719 | break; | 1547 | hw_dbg(hw, " Error on src/dst port mask\n"); |
1720 | case IXGBE_ATR_L4TYPE_SCTP: | 1548 | return IXGBE_ERR_CONFIG; |
1721 | fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP; | 1549 | } |
1550 | case IXGBE_ATR_FLOW_TYPE_TCPV4: | ||
1551 | case IXGBE_ATR_FLOW_TYPE_UDPV4: | ||
1722 | break; | 1552 | break; |
1723 | default: | 1553 | default: |
1724 | hw_dbg(hw, "Error on l4type input\n"); | 1554 | hw_dbg(hw, " Error on flow type input\n"); |
1725 | return IXGBE_ERR_CONFIG; | 1555 | return IXGBE_ERR_CONFIG; |
1726 | } | 1556 | } |
1727 | 1557 | ||
1728 | bucket_hash = ixgbe_atr_compute_hash_82599(input, | ||
1729 | IXGBE_ATR_BUCKET_HASH_KEY); | ||
1730 | |||
1731 | /* bucket_hash is only 15 bits */ | ||
1732 | bucket_hash &= IXGBE_ATR_HASH_MASK; | ||
1733 | |||
1734 | ixgbe_atr_get_vlan_id_82599(input, &vlan_id); | ||
1735 | ixgbe_atr_get_src_port_82599(input, &src_port); | ||
1736 | ixgbe_atr_get_dst_port_82599(input, &dst_port); | ||
1737 | ixgbe_atr_get_flex_byte_82599(input, &flex_bytes); | ||
1738 | |||
1739 | fdirhash = soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash; | ||
1740 | |||
1741 | /* Now figure out if we're IPv4 or IPv6 */ | ||
1742 | if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) { | ||
1743 | /* IPv6 */ | ||
1744 | ixgbe_atr_get_src_ipv6_82599(input, &src_ipv6_1, &src_ipv6_2, | ||
1745 | &src_ipv6_3, &src_ipv6_4); | ||
1746 | |||
1747 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), src_ipv6_1); | ||
1748 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(1), src_ipv6_2); | ||
1749 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), src_ipv6_3); | ||
1750 | /* The last 4 bytes is the same register as IPv4 */ | ||
1751 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv6_4); | ||
1752 | |||
1753 | fdircmd |= IXGBE_FDIRCMD_IPV6; | ||
1754 | fdircmd |= IXGBE_FDIRCMD_IPv6DMATCH; | ||
1755 | } else { | ||
1756 | /* IPv4 */ | ||
1757 | ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4); | ||
1758 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4); | ||
1759 | } | ||
1760 | |||
1761 | ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4); | ||
1762 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, dst_ipv4); | ||
1763 | |||
1764 | IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id | | ||
1765 | (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT))); | ||
1766 | IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | | ||
1767 | (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); | ||
1768 | |||
1769 | /* | 1558 | /* |
1770 | * Program the relevant mask registers. L4type cannot be | 1559 | * Program the relevant mask registers. If src/dst_port or src/dst_addr |
1771 | * masked out in this implementation. | 1560 | * are zero, then assume a full mask for that field. Also assume that |
1561 | * a VLAN of 0 is unspecified, so mask that out as well. L4type | ||
1562 | * cannot be masked out in this implementation. | ||
1772 | * | 1563 | * |
1773 | * This also assumes IPv4 only. IPv6 masking isn't supported at this | 1564 | * This also assumes IPv4 only. IPv6 masking isn't supported at this |
1774 | * point in time. | 1565 | * point in time. |
1775 | */ | 1566 | */ |
1776 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); | 1567 | |
1777 | IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); | 1568 | /* Program FDIRM */ |
1778 | 1569 | switch (ntohs(input_masks->vlan_id_mask) & 0xEFFF) { | |
1779 | switch (l4type & IXGBE_ATR_L4TYPE_MASK) { | 1570 | case 0xEFFF: |
1780 | case IXGBE_ATR_L4TYPE_TCP: | 1571 | /* Unmask VLAN ID - bit 0 and fall through to unmask prio */ |
1781 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, input_masks->src_port_mask); | 1572 | fdirm &= ~IXGBE_FDIRM_VLANID; |
1782 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, | 1573 | case 0xE000: |
1783 | (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | | 1574 | /* Unmask VLAN prio - bit 1 */ |
1784 | (input_masks->dst_port_mask << 16))); | 1575 | fdirm &= ~IXGBE_FDIRM_VLANP; |
1785 | break; | 1576 | break; |
1786 | case IXGBE_ATR_L4TYPE_UDP: | 1577 | case 0x0FFF: |
1787 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, input_masks->src_port_mask); | 1578 | /* Unmask VLAN ID - bit 0 */ |
1788 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, | 1579 | fdirm &= ~IXGBE_FDIRM_VLANID; |
1789 | (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | | ||
1790 | (input_masks->src_port_mask << 16))); | ||
1791 | break; | 1580 | break; |
1792 | default: | 1581 | case 0x0000: |
1793 | /* this already would have failed above */ | 1582 | /* do nothing, vlans already masked */ |
1794 | break; | 1583 | break; |
1584 | default: | ||
1585 | hw_dbg(hw, " Error on VLAN mask\n"); | ||
1586 | return IXGBE_ERR_CONFIG; | ||
1795 | } | 1587 | } |
1796 | 1588 | ||
1797 | /* Program the last mask register, FDIRM */ | 1589 | if (input_masks->flex_mask & 0xFFFF) { |
1798 | if (input_masks->vlan_id_mask) | 1590 | if ((input_masks->flex_mask & 0xFFFF) != 0xFFFF) { |
1799 | /* Mask both VLAN and VLANP - bits 0 and 1 */ | 1591 | hw_dbg(hw, " Error on flexible byte mask\n"); |
1800 | fdirm |= 0x3; | 1592 | return IXGBE_ERR_CONFIG; |
1801 | 1593 | } | |
1802 | if (input_masks->data_mask) | 1594 | /* Unmask Flex Bytes - bit 4 */ |
1803 | /* Flex bytes need masking, so mask the whole thing - bit 4 */ | 1595 | fdirm &= ~IXGBE_FDIRM_FLEX; |
1804 | fdirm |= 0x10; | 1596 | } |
1805 | 1597 | ||
1806 | /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ | 1598 | /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ |
1807 | fdirm |= 0x24; | ||
1808 | |||
1809 | IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); | 1599 | IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); |
1810 | 1600 | ||
1811 | fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; | 1601 | /* store the TCP/UDP port masks, bit reversed from port layout */ |
1812 | fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; | 1602 | fdirtcpm = ixgbe_get_fdirtcpm_82599(input_masks); |
1813 | fdircmd |= IXGBE_FDIRCMD_LAST; | 1603 | |
1814 | fdircmd |= IXGBE_FDIRCMD_QUEUE_EN; | 1604 | /* write both the same so that UDP and TCP use the same mask */ |
1815 | fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; | 1605 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm); |
1606 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm); | ||
1607 | |||
1608 | /* store source and destination IP masks (big-enian) */ | ||
1609 | IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, | ||
1610 | ~input_masks->src_ip_mask[0]); | ||
1611 | IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M, | ||
1612 | ~input_masks->dst_ip_mask[0]); | ||
1613 | |||
1614 | /* Apply masks to input data */ | ||
1615 | input->formatted.vlan_id &= input_masks->vlan_id_mask; | ||
1616 | input->formatted.flex_bytes &= input_masks->flex_mask; | ||
1617 | input->formatted.src_port &= input_masks->src_port_mask; | ||
1618 | input->formatted.dst_port &= input_masks->dst_port_mask; | ||
1619 | input->formatted.src_ip[0] &= input_masks->src_ip_mask[0]; | ||
1620 | input->formatted.dst_ip[0] &= input_masks->dst_ip_mask[0]; | ||
1621 | |||
1622 | /* record vlan (little-endian) and flex_bytes(big-endian) */ | ||
1623 | fdirvlan = | ||
1624 | IXGBE_STORE_AS_BE16(ntohs(input->formatted.flex_bytes)); | ||
1625 | fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT; | ||
1626 | fdirvlan |= ntohs(input->formatted.vlan_id); | ||
1627 | IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan); | ||
1628 | |||
1629 | /* record source and destination port (little-endian)*/ | ||
1630 | fdirport = ntohs(input->formatted.dst_port); | ||
1631 | fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT; | ||
1632 | fdirport |= ntohs(input->formatted.src_port); | ||
1633 | IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport); | ||
1634 | |||
1635 | /* record the first 32 bits of the destination address (big-endian) */ | ||
1636 | IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]); | ||
1637 | |||
1638 | /* record the source address (big-endian) */ | ||
1639 | IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]); | ||
1640 | |||
1641 | /* configure FDIRCMD register */ | ||
1642 | fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | | ||
1643 | IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN; | ||
1644 | fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; | ||
1645 | fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; | ||
1646 | |||
1647 | /* we only want the bucket hash so drop the upper 16 bits */ | ||
1648 | fdirhash = ixgbe_atr_compute_hash_82599(input, | ||
1649 | IXGBE_ATR_BUCKET_HASH_KEY); | ||
1650 | fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; | ||
1816 | 1651 | ||
1817 | IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); | 1652 | IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); |
1818 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); | 1653 | IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); |
1819 | 1654 | ||
1820 | return 0; | 1655 | return 0; |
1821 | } | 1656 | } |
1657 | |||
1822 | /** | 1658 | /** |
1823 | * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register | 1659 | * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register |
1824 | * @hw: pointer to hardware structure | 1660 | * @hw: pointer to hardware structure |