diff options
author | Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com> | 2010-02-10 11:07:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-10 23:03:14 -0500 |
commit | 9a713e7c7cca2f31c89367bb7b48310ab8a3e630 (patch) | |
tree | 5403bff53e13f4c41afeb50ef5f22aed6be13117 /drivers/net/ixgbe/ixgbe_82599.c | |
parent | 15682bc488d4af8c9bb998844a94281025e0a333 (diff) |
ixgbe: Add support for the new ethtool n-tuple programming interface
This patch adds n-tuple filter programming to 82599.
Signed-off-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 | 106 |
1 files changed, 93 insertions, 13 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index d4ed6adb7975..4fa8633fae3c 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -1439,6 +1439,9 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) | |||
1439 | /* Send interrupt when 64 filters are left */ | 1439 | /* Send interrupt when 64 filters are left */ |
1440 | fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; | 1440 | fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; |
1441 | 1441 | ||
1442 | /* Initialize the drop queue to Rx queue 127 */ | ||
1443 | fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT); | ||
1444 | |||
1442 | switch (pballoc) { | 1445 | switch (pballoc) { |
1443 | case IXGBE_FDIR_PBALLOC_64K: | 1446 | case IXGBE_FDIR_PBALLOC_64K: |
1444 | /* 2k - 1 perfect filters */ | 1447 | /* 2k - 1 perfect filters */ |
@@ -1628,6 +1631,7 @@ static u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, | |||
1628 | * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream | 1631 | * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream |
1629 | * @input: input stream to modify | 1632 | * @input: input stream to modify |
1630 | * @vlan: the VLAN id to load | 1633 | * @vlan: the VLAN id to load |
1634 | * @vlan_mask: bitwise mask for the VLAN | ||
1631 | **/ | 1635 | **/ |
1632 | s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) | 1636 | s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) |
1633 | { | 1637 | { |
@@ -1641,6 +1645,7 @@ s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) | |||
1641 | * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address | 1645 | * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address |
1642 | * @input: input stream to modify | 1646 | * @input: input stream to modify |
1643 | * @src_addr: the IP address to load | 1647 | * @src_addr: the IP address to load |
1648 | * @src_addr_mask: bitwise mask for the source IP address | ||
1644 | **/ | 1649 | **/ |
1645 | s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) | 1650 | s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) |
1646 | { | 1651 | { |
@@ -1658,6 +1663,7 @@ s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) | |||
1658 | * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address | 1663 | * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address |
1659 | * @input: input stream to modify | 1664 | * @input: input stream to modify |
1660 | * @dst_addr: the IP address to load | 1665 | * @dst_addr: the IP address to load |
1666 | * @dst_addr_mask: bitwise mask for the destination IP address | ||
1661 | **/ | 1667 | **/ |
1662 | s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) | 1668 | s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) |
1663 | { | 1669 | { |
@@ -1680,8 +1686,8 @@ s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) | |||
1680 | * @src_addr_4: the fourth 4 bytes of the IP address to load | 1686 | * @src_addr_4: the fourth 4 bytes of the IP address to load |
1681 | **/ | 1687 | **/ |
1682 | s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, | 1688 | s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, |
1683 | u32 src_addr_1, u32 src_addr_2, | 1689 | u32 src_addr_1, u32 src_addr_2, |
1684 | u32 src_addr_3, u32 src_addr_4) | 1690 | u32 src_addr_3, u32 src_addr_4) |
1685 | { | 1691 | { |
1686 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; | 1692 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; |
1687 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = | 1693 | input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = |
@@ -1723,8 +1729,8 @@ s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, | |||
1723 | * @dst_addr_4: the fourth 4 bytes of the IP address to load | 1729 | * @dst_addr_4: the fourth 4 bytes of the IP address to load |
1724 | **/ | 1730 | **/ |
1725 | s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, | 1731 | s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, |
1726 | u32 dst_addr_1, u32 dst_addr_2, | 1732 | u32 dst_addr_1, u32 dst_addr_2, |
1727 | u32 dst_addr_3, u32 dst_addr_4) | 1733 | u32 dst_addr_3, u32 dst_addr_4) |
1728 | { | 1734 | { |
1729 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; | 1735 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; |
1730 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = | 1736 | input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = |
@@ -1761,6 +1767,7 @@ s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, | |||
1761 | * ixgbe_atr_set_src_port_82599 - Sets the source port | 1767 | * ixgbe_atr_set_src_port_82599 - Sets the source port |
1762 | * @input: input stream to modify | 1768 | * @input: input stream to modify |
1763 | * @src_port: the source port to load | 1769 | * @src_port: the source port to load |
1770 | * @src_port_mask: bitwise mask for the source port | ||
1764 | **/ | 1771 | **/ |
1765 | s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) | 1772 | s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) |
1766 | { | 1773 | { |
@@ -1774,6 +1781,7 @@ s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) | |||
1774 | * ixgbe_atr_set_dst_port_82599 - Sets the destination port | 1781 | * ixgbe_atr_set_dst_port_82599 - Sets the destination port |
1775 | * @input: input stream to modify | 1782 | * @input: input stream to modify |
1776 | * @dst_port: the destination port to load | 1783 | * @dst_port: the destination port to load |
1784 | * @dst_port_mask: bitwise mask for the destination port | ||
1777 | **/ | 1785 | **/ |
1778 | s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port) | 1786 | s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port) |
1779 | { | 1787 | { |
@@ -1802,7 +1810,7 @@ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) | |||
1802 | * @vm_pool: the Virtual Machine pool to load | 1810 | * @vm_pool: the Virtual Machine pool to load |
1803 | **/ | 1811 | **/ |
1804 | s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, | 1812 | s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, |
1805 | u8 vm_pool) | 1813 | u8 vm_pool) |
1806 | { | 1814 | { |
1807 | input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; | 1815 | input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; |
1808 | 1816 | ||
@@ -1826,8 +1834,7 @@ s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type) | |||
1826 | * @input: input stream to search | 1834 | * @input: input stream to search |
1827 | * @vlan: the VLAN id to load | 1835 | * @vlan: the VLAN id to load |
1828 | **/ | 1836 | **/ |
1829 | static s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, | 1837 | static s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan) |
1830 | u16 *vlan) | ||
1831 | { | 1838 | { |
1832 | *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET]; | 1839 | *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET]; |
1833 | *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8; | 1840 | *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8; |
@@ -2083,23 +2090,26 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, | |||
2083 | * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter | 2090 | * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter |
2084 | * @hw: pointer to hardware structure | 2091 | * @hw: pointer to hardware structure |
2085 | * @input: input bitstream | 2092 | * @input: input bitstream |
2093 | * @input_masks: bitwise masks for relevant fields | ||
2094 | * @soft_id: software index into the silicon hash tables for filter storage | ||
2086 | * @queue: queue index to direct traffic to | 2095 | * @queue: queue index to direct traffic to |
2087 | * | 2096 | * |
2088 | * Note that the caller to this function must lock before calling, since the | 2097 | * Note that the caller to this function must lock before calling, since the |
2089 | * hardware writes must be protected from one another. | 2098 | * hardware writes must be protected from one another. |
2090 | **/ | 2099 | **/ |
2091 | s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | 2100 | s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, |
2092 | struct ixgbe_atr_input *input, | 2101 | struct ixgbe_atr_input *input, |
2093 | u16 soft_id, | 2102 | struct ixgbe_atr_input_masks *input_masks, |
2094 | u8 queue) | 2103 | u16 soft_id, u8 queue) |
2095 | { | 2104 | { |
2096 | u32 fdircmd = 0; | 2105 | u32 fdircmd = 0; |
2097 | u32 fdirhash; | 2106 | u32 fdirhash; |
2098 | u32 src_ipv4, dst_ipv4; | 2107 | u32 src_ipv4 = 0, dst_ipv4 = 0; |
2099 | u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; | 2108 | u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; |
2100 | u16 src_port, dst_port, vlan_id, flex_bytes; | 2109 | u16 src_port, dst_port, vlan_id, flex_bytes; |
2101 | u16 bucket_hash; | 2110 | u16 bucket_hash; |
2102 | u8 l4type; | 2111 | u8 l4type; |
2112 | u8 fdirm = 0; | ||
2103 | 2113 | ||
2104 | /* Get our input values */ | 2114 | /* Get our input values */ |
2105 | ixgbe_atr_get_l4type_82599(input, &l4type); | 2115 | ixgbe_atr_get_l4type_82599(input, &l4type); |
@@ -2154,7 +2164,6 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | |||
2154 | /* IPv4 */ | 2164 | /* IPv4 */ |
2155 | ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4); | 2165 | ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4); |
2156 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4); | 2166 | IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4); |
2157 | |||
2158 | } | 2167 | } |
2159 | 2168 | ||
2160 | ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4); | 2169 | ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4); |
@@ -2163,7 +2172,78 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | |||
2163 | IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id | | 2172 | IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id | |
2164 | (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT))); | 2173 | (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT))); |
2165 | IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | | 2174 | IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | |
2166 | (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); | 2175 | (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); |
2176 | |||
2177 | /* | ||
2178 | * Program the relevant mask registers. If src/dst_port or src/dst_addr | ||
2179 | * are zero, then assume a full mask for that field. Also assume that | ||
2180 | * a VLAN of 0 is unspecified, so mask that out as well. L4type | ||
2181 | * cannot be masked out in this implementation. | ||
2182 | * | ||
2183 | * This also assumes IPv4 only. IPv6 masking isn't supported at this | ||
2184 | * point in time. | ||
2185 | */ | ||
2186 | if (src_ipv4 == 0) | ||
2187 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff); | ||
2188 | else | ||
2189 | IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); | ||
2190 | |||
2191 | if (dst_ipv4 == 0) | ||
2192 | IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff); | ||
2193 | else | ||
2194 | IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); | ||
2195 | |||
2196 | switch (l4type & IXGBE_ATR_L4TYPE_MASK) { | ||
2197 | case IXGBE_ATR_L4TYPE_TCP: | ||
2198 | if (src_port == 0) | ||
2199 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff); | ||
2200 | else | ||
2201 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, | ||
2202 | input_masks->src_port_mask); | ||
2203 | |||
2204 | if (dst_port == 0) | ||
2205 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, | ||
2206 | (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | | ||
2207 | (0xffff << 16))); | ||
2208 | else | ||
2209 | IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, | ||
2210 | (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | | ||
2211 | (input_masks->dst_port_mask << 16))); | ||
2212 | break; | ||
2213 | case IXGBE_ATR_L4TYPE_UDP: | ||
2214 | if (src_port == 0) | ||
2215 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff); | ||
2216 | else | ||
2217 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, | ||
2218 | input_masks->src_port_mask); | ||
2219 | |||
2220 | if (dst_port == 0) | ||
2221 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, | ||
2222 | (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | | ||
2223 | (0xffff << 16))); | ||
2224 | else | ||
2225 | IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, | ||
2226 | (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | | ||
2227 | (input_masks->src_port_mask << 16))); | ||
2228 | break; | ||
2229 | default: | ||
2230 | /* this already would have failed above */ | ||
2231 | break; | ||
2232 | } | ||
2233 | |||
2234 | /* Program the last mask register, FDIRM */ | ||
2235 | if (input_masks->vlan_id_mask || !vlan_id) | ||
2236 | /* Mask both VLAN and VLANP - bits 0 and 1 */ | ||
2237 | fdirm |= 0x3; | ||
2238 | |||
2239 | if (input_masks->data_mask || !flex_bytes) | ||
2240 | /* Flex bytes need masking, so mask the whole thing - bit 4 */ | ||
2241 | fdirm |= 0x10; | ||
2242 | |||
2243 | /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ | ||
2244 | fdirm |= 0x24; | ||
2245 | |||
2246 | IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); | ||
2167 | 2247 | ||
2168 | fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; | 2248 | fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; |
2169 | fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; | 2249 | fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; |