aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c57
-rw-r--r--include/linux/ethtool.h5
-rw-r--r--net/core/ethtool.c34
3 files changed, 51 insertions, 45 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 3e06a61da921..e80657c75506 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -1910,56 +1910,27 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
1910 (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); 1910 (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
1911 1911
1912 /* 1912 /*
1913 * Program the relevant mask registers. If src/dst_port or src/dst_addr 1913 * Program the relevant mask registers. L4type cannot be
1914 * are zero, then assume a full mask for that field. Also assume that 1914 * masked out in this implementation.
1915 * a VLAN of 0 is unspecified, so mask that out as well. L4type
1916 * cannot be masked out in this implementation.
1917 * 1915 *
1918 * This also assumes IPv4 only. IPv6 masking isn't supported at this 1916 * This also assumes IPv4 only. IPv6 masking isn't supported at this
1919 * point in time. 1917 * point in time.
1920 */ 1918 */
1921 if (src_ipv4 == 0) 1919 IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask);
1922 IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff); 1920 IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask);
1923 else
1924 IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask);
1925
1926 if (dst_ipv4 == 0)
1927 IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff);
1928 else
1929 IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask);
1930 1921
1931 switch (l4type & IXGBE_ATR_L4TYPE_MASK) { 1922 switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
1932 case IXGBE_ATR_L4TYPE_TCP: 1923 case IXGBE_ATR_L4TYPE_TCP:
1933 if (src_port == 0) 1924 IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, input_masks->src_port_mask);
1934 IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff); 1925 IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
1935 else 1926 (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
1936 IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 1927 (input_masks->dst_port_mask << 16)));
1937 input_masks->src_port_mask);
1938
1939 if (dst_port == 0)
1940 IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
1941 (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
1942 (0xffff << 16)));
1943 else
1944 IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
1945 (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
1946 (input_masks->dst_port_mask << 16)));
1947 break; 1928 break;
1948 case IXGBE_ATR_L4TYPE_UDP: 1929 case IXGBE_ATR_L4TYPE_UDP:
1949 if (src_port == 0) 1930 IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, input_masks->src_port_mask);
1950 IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff); 1931 IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
1951 else 1932 (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
1952 IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 1933 (input_masks->src_port_mask << 16)));
1953 input_masks->src_port_mask);
1954
1955 if (dst_port == 0)
1956 IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
1957 (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
1958 (0xffff << 16)));
1959 else
1960 IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
1961 (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
1962 (input_masks->src_port_mask << 16)));
1963 break; 1934 break;
1964 default: 1935 default:
1965 /* this already would have failed above */ 1936 /* this already would have failed above */
@@ -1967,11 +1938,11 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
1967 } 1938 }
1968 1939
1969 /* Program the last mask register, FDIRM */ 1940 /* Program the last mask register, FDIRM */
1970 if (input_masks->vlan_id_mask || !vlan_id) 1941 if (input_masks->vlan_id_mask)
1971 /* Mask both VLAN and VLANP - bits 0 and 1 */ 1942 /* Mask both VLAN and VLANP - bits 0 and 1 */
1972 fdirm |= 0x3; 1943 fdirm |= 0x3;
1973 1944
1974 if (input_masks->data_mask || !flex_bytes) 1945 if (input_masks->data_mask)
1975 /* Flex bytes need masking, so mask the whole thing - bit 4 */ 1946 /* Flex bytes need masking, so mask the whole thing - bit 4 */
1976 fdirm |= 0x10; 1947 fdirm |= 0x10;
1977 1948
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index d64e246a39e7..00334eebbe26 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -470,8 +470,9 @@ struct ethtool_rxfh_indir {
470 * @action: RX ring/queue index to deliver to (non-negative) or other action 470 * @action: RX ring/queue index to deliver to (non-negative) or other action
471 * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP) 471 * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
472 * 472 *
473 * Zero values in @h_u may be ignored, as if all the corresponding 473 * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
474 * mask bits were set. 474 * a field value and mask are both zero this is treated as if all mask
475 * bits are set i.e. the field is ignored.
475 */ 476 */
476struct ethtool_rx_ntuple_flow_spec { 477struct ethtool_rx_ntuple_flow_spec {
477 __u32 flow_type; 478 __u32 flow_type;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 248c25c3e820..91ffce20c36b 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -485,6 +485,38 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
485 list->count++; 485 list->count++;
486} 486}
487 487
488/*
489 * ethtool does not (or did not) set masks for flow parameters that are
490 * not specified, so if both value and mask are 0 then this must be
491 * treated as equivalent to a mask with all bits set. Implement that
492 * here rather than in drivers.
493 */
494static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs)
495{
496 struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec;
497 struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
498
499 if (fs->flow_type != TCP_V4_FLOW &&
500 fs->flow_type != UDP_V4_FLOW &&
501 fs->flow_type != SCTP_V4_FLOW)
502 return;
503
504 if (!(entry->ip4src | mask->ip4src))
505 mask->ip4src = htonl(0xffffffff);
506 if (!(entry->ip4dst | mask->ip4dst))
507 mask->ip4dst = htonl(0xffffffff);
508 if (!(entry->psrc | mask->psrc))
509 mask->psrc = htons(0xffff);
510 if (!(entry->pdst | mask->pdst))
511 mask->pdst = htons(0xffff);
512 if (!(entry->tos | mask->tos))
513 mask->tos = 0xff;
514 if (!(fs->vlan_tag | fs->vlan_tag_mask))
515 fs->vlan_tag_mask = 0xffff;
516 if (!(fs->data | fs->data_mask))
517 fs->data_mask = 0xffffffffffffffffULL;
518}
519
488static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, 520static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
489 void __user *useraddr) 521 void __user *useraddr)
490{ 522{
@@ -499,6 +531,8 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
499 if (copy_from_user(&cmd, useraddr, sizeof(cmd))) 531 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
500 return -EFAULT; 532 return -EFAULT;
501 533
534 rx_ntuple_fix_masks(&cmd.fs);
535
502 /* 536 /*
503 * Cache filter in dev struct for GET operation only if 537 * Cache filter in dev struct for GET operation only if
504 * the underlying driver doesn't have its own GET operation, and 538 * the underlying driver doesn't have its own GET operation, and