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 | |
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')
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 4 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82599.c | 106 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 111 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 16 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 9 |
5 files changed, 228 insertions, 18 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index bffbe0d52d33..19e94ee155a2 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -453,6 +453,10 @@ extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); | |||
453 | extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, | 453 | extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, |
454 | struct ixgbe_atr_input *input, | 454 | struct ixgbe_atr_input *input, |
455 | u8 queue); | 455 | u8 queue); |
456 | extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, | ||
457 | struct ixgbe_atr_input *input, | ||
458 | struct ixgbe_atr_input_masks *input_masks, | ||
459 | u16 soft_id, u8 queue); | ||
456 | extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, | 460 | extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, |
457 | u16 vlan_id); | 461 | u16 vlan_id); |
458 | extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, | 462 | extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, |
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; |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 07a9410c08d4..0d234346a4ea 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -979,6 +979,9 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset) | |||
979 | return IXGBE_TEST_LEN; | 979 | return IXGBE_TEST_LEN; |
980 | case ETH_SS_STATS: | 980 | case ETH_SS_STATS: |
981 | return IXGBE_STATS_LEN; | 981 | return IXGBE_STATS_LEN; |
982 | case ETH_SS_NTUPLE_FILTERS: | ||
983 | return (ETHTOOL_MAX_NTUPLE_LIST_ENTRY * | ||
984 | ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY); | ||
982 | default: | 985 | default: |
983 | return -EOPNOTSUPP; | 986 | return -EOPNOTSUPP; |
984 | } | 987 | } |
@@ -2150,23 +2153,124 @@ static int ixgbe_set_coalesce(struct net_device *netdev, | |||
2150 | static int ixgbe_set_flags(struct net_device *netdev, u32 data) | 2153 | static int ixgbe_set_flags(struct net_device *netdev, u32 data) |
2151 | { | 2154 | { |
2152 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 2155 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
2156 | bool need_reset = false; | ||
2153 | 2157 | ||
2154 | ethtool_op_set_flags(netdev, data); | 2158 | ethtool_op_set_flags(netdev, data); |
2155 | 2159 | ||
2156 | if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) | ||
2157 | return 0; | ||
2158 | |||
2159 | /* if state changes we need to update adapter->flags and reset */ | 2160 | /* if state changes we need to update adapter->flags and reset */ |
2160 | if ((!!(data & ETH_FLAG_LRO)) != | 2161 | if ((!!(data & ETH_FLAG_LRO)) != |
2161 | (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { | 2162 | (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { |
2162 | adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; | 2163 | adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; |
2164 | need_reset = true; | ||
2165 | } | ||
2166 | |||
2167 | /* | ||
2168 | * Check if Flow Director n-tuple support was enabled or disabled. If | ||
2169 | * the state changed, we need to reset. | ||
2170 | */ | ||
2171 | if ((adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) && | ||
2172 | (!(data & ETH_FLAG_NTUPLE))) { | ||
2173 | /* turn off Flow Director perfect, set hash and reset */ | ||
2174 | adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
2175 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
2176 | need_reset = true; | ||
2177 | } else if ((!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) && | ||
2178 | (data & ETH_FLAG_NTUPLE)) { | ||
2179 | /* turn off Flow Director hash, enable perfect and reset */ | ||
2180 | adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
2181 | adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
2182 | need_reset = true; | ||
2183 | } else { | ||
2184 | /* no state change */ | ||
2185 | } | ||
2186 | |||
2187 | if (need_reset) { | ||
2163 | if (netif_running(netdev)) | 2188 | if (netif_running(netdev)) |
2164 | ixgbe_reinit_locked(adapter); | 2189 | ixgbe_reinit_locked(adapter); |
2165 | else | 2190 | else |
2166 | ixgbe_reset(adapter); | 2191 | ixgbe_reset(adapter); |
2167 | } | 2192 | } |
2193 | |||
2168 | return 0; | 2194 | return 0; |
2195 | } | ||
2196 | |||
2197 | static int ixgbe_set_rx_ntuple(struct net_device *dev, | ||
2198 | struct ethtool_rx_ntuple *cmd) | ||
2199 | { | ||
2200 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
2201 | struct ethtool_rx_ntuple_flow_spec fs = cmd->fs; | ||
2202 | struct ixgbe_atr_input input_struct; | ||
2203 | struct ixgbe_atr_input_masks input_masks; | ||
2204 | int target_queue; | ||
2205 | |||
2206 | if (adapter->hw.mac.type == ixgbe_mac_82598EB) | ||
2207 | return -EOPNOTSUPP; | ||
2208 | |||
2209 | /* | ||
2210 | * Don't allow programming if the action is a queue greater than | ||
2211 | * the number of online Tx queues. | ||
2212 | */ | ||
2213 | if ((fs.action >= adapter->num_tx_queues) || | ||
2214 | (fs.action < ETHTOOL_RXNTUPLE_ACTION_DROP)) | ||
2215 | return -EINVAL; | ||
2216 | |||
2217 | memset(&input_struct, 0, sizeof(struct ixgbe_atr_input)); | ||
2218 | memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks)); | ||
2219 | |||
2220 | input_masks.src_ip_mask = fs.m_u.tcp_ip4_spec.ip4src; | ||
2221 | input_masks.dst_ip_mask = fs.m_u.tcp_ip4_spec.ip4dst; | ||
2222 | input_masks.src_port_mask = fs.m_u.tcp_ip4_spec.psrc; | ||
2223 | input_masks.dst_port_mask = fs.m_u.tcp_ip4_spec.pdst; | ||
2224 | input_masks.vlan_id_mask = fs.vlan_tag_mask; | ||
2225 | /* only use the lowest 2 bytes for flex bytes */ | ||
2226 | input_masks.data_mask = (fs.data_mask & 0xffff); | ||
2227 | |||
2228 | switch (fs.flow_type) { | ||
2229 | case TCP_V4_FLOW: | ||
2230 | ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_TCP); | ||
2231 | break; | ||
2232 | case UDP_V4_FLOW: | ||
2233 | ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_UDP); | ||
2234 | break; | ||
2235 | case SCTP_V4_FLOW: | ||
2236 | ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_SCTP); | ||
2237 | break; | ||
2238 | default: | ||
2239 | return -1; | ||
2240 | } | ||
2169 | 2241 | ||
2242 | /* Mask bits from the inputs based on user-supplied mask */ | ||
2243 | ixgbe_atr_set_src_ipv4_82599(&input_struct, | ||
2244 | (fs.h_u.tcp_ip4_spec.ip4src & ~fs.m_u.tcp_ip4_spec.ip4src)); | ||
2245 | ixgbe_atr_set_dst_ipv4_82599(&input_struct, | ||
2246 | (fs.h_u.tcp_ip4_spec.ip4dst & ~fs.m_u.tcp_ip4_spec.ip4dst)); | ||
2247 | /* 82599 expects these to be byte-swapped for perfect filtering */ | ||
2248 | ixgbe_atr_set_src_port_82599(&input_struct, | ||
2249 | ((ntohs(fs.h_u.tcp_ip4_spec.psrc)) & ~fs.m_u.tcp_ip4_spec.psrc)); | ||
2250 | ixgbe_atr_set_dst_port_82599(&input_struct, | ||
2251 | ((ntohs(fs.h_u.tcp_ip4_spec.pdst)) & ~fs.m_u.tcp_ip4_spec.pdst)); | ||
2252 | |||
2253 | /* VLAN and Flex bytes are either completely masked or not */ | ||
2254 | if (!fs.vlan_tag_mask) | ||
2255 | ixgbe_atr_set_vlan_id_82599(&input_struct, fs.vlan_tag); | ||
2256 | |||
2257 | if (!input_masks.data_mask) | ||
2258 | /* make sure we only use the first 2 bytes of user data */ | ||
2259 | ixgbe_atr_set_flex_byte_82599(&input_struct, | ||
2260 | (fs.data & 0xffff)); | ||
2261 | |||
2262 | /* determine if we need to drop or route the packet */ | ||
2263 | if (fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) | ||
2264 | target_queue = MAX_RX_QUEUES - 1; | ||
2265 | else | ||
2266 | target_queue = fs.action; | ||
2267 | |||
2268 | spin_lock(&adapter->fdir_perfect_lock); | ||
2269 | ixgbe_fdir_add_perfect_filter_82599(&adapter->hw, &input_struct, | ||
2270 | &input_masks, 0, target_queue); | ||
2271 | spin_unlock(&adapter->fdir_perfect_lock); | ||
2272 | |||
2273 | return 0; | ||
2170 | } | 2274 | } |
2171 | 2275 | ||
2172 | static const struct ethtool_ops ixgbe_ethtool_ops = { | 2276 | static const struct ethtool_ops ixgbe_ethtool_ops = { |
@@ -2204,6 +2308,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { | |||
2204 | .set_coalesce = ixgbe_set_coalesce, | 2308 | .set_coalesce = ixgbe_set_coalesce, |
2205 | .get_flags = ethtool_op_get_flags, | 2309 | .get_flags = ethtool_op_get_flags, |
2206 | .set_flags = ixgbe_set_flags, | 2310 | .set_flags = ixgbe_set_flags, |
2311 | .set_rx_ntuple = ixgbe_set_rx_ntuple, | ||
2207 | }; | 2312 | }; |
2208 | 2313 | ||
2209 | void ixgbe_set_ethtool_ops(struct net_device *netdev) | 2314 | void ixgbe_set_ethtool_ops(struct net_device *netdev) |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 2a3c8315e357..f04b5396e057 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -3253,6 +3253,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
3253 | 3253 | ||
3254 | netif_carrier_off(netdev); | 3254 | netif_carrier_off(netdev); |
3255 | 3255 | ||
3256 | /* clear n-tuple filters that are cached */ | ||
3257 | ethtool_ntuple_flush(netdev); | ||
3258 | |||
3256 | if (!pci_channel_offline(adapter->pdev)) | 3259 | if (!pci_channel_offline(adapter->pdev)) |
3257 | ixgbe_reset(adapter); | 3260 | ixgbe_reset(adapter); |
3258 | ixgbe_clean_all_tx_rings(adapter); | 3261 | ixgbe_clean_all_tx_rings(adapter); |
@@ -4187,6 +4190,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) | |||
4187 | { | 4190 | { |
4188 | struct ixgbe_hw *hw = &adapter->hw; | 4191 | struct ixgbe_hw *hw = &adapter->hw; |
4189 | struct pci_dev *pdev = adapter->pdev; | 4192 | struct pci_dev *pdev = adapter->pdev; |
4193 | struct net_device *dev = adapter->netdev; | ||
4190 | unsigned int rss; | 4194 | unsigned int rss; |
4191 | #ifdef CONFIG_IXGBE_DCB | 4195 | #ifdef CONFIG_IXGBE_DCB |
4192 | int j; | 4196 | int j; |
@@ -4214,10 +4218,18 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) | |||
4214 | adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; | 4218 | adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; |
4215 | adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; | 4219 | adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; |
4216 | adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; | 4220 | adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; |
4217 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; | 4221 | if (dev->features & NETIF_F_NTUPLE) { |
4222 | /* Flow Director perfect filter enabled */ | ||
4223 | adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
4224 | adapter->atr_sample_rate = 0; | ||
4225 | spin_lock_init(&adapter->fdir_perfect_lock); | ||
4226 | } else { | ||
4227 | /* Flow Director hash filters enabled */ | ||
4228 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
4229 | adapter->atr_sample_rate = 20; | ||
4230 | } | ||
4218 | adapter->ring_feature[RING_F_FDIR].indices = | 4231 | adapter->ring_feature[RING_F_FDIR].indices = |
4219 | IXGBE_MAX_FDIR_INDICES; | 4232 | IXGBE_MAX_FDIR_INDICES; |
4220 | adapter->atr_sample_rate = 20; | ||
4221 | adapter->fdir_pballoc = 0; | 4233 | adapter->fdir_pballoc = 0; |
4222 | #ifdef IXGBE_FCOE | 4234 | #ifdef IXGBE_FCOE |
4223 | adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; | 4235 | adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 0db67c19b2c4..2be907466593 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -2129,6 +2129,15 @@ struct ixgbe_atr_input { | |||
2129 | u8 byte_stream[42]; | 2129 | u8 byte_stream[42]; |
2130 | }; | 2130 | }; |
2131 | 2131 | ||
2132 | struct ixgbe_atr_input_masks { | ||
2133 | u32 src_ip_mask; | ||
2134 | u32 dst_ip_mask; | ||
2135 | u16 src_port_mask; | ||
2136 | u16 dst_port_mask; | ||
2137 | u16 vlan_id_mask; | ||
2138 | u16 data_mask; | ||
2139 | }; | ||
2140 | |||
2132 | enum ixgbe_eeprom_type { | 2141 | enum ixgbe_eeprom_type { |
2133 | ixgbe_eeprom_uninitialized = 0, | 2142 | ixgbe_eeprom_uninitialized = 0, |
2134 | ixgbe_eeprom_spi, | 2143 | ixgbe_eeprom_spi, |