aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c142
1 files changed, 98 insertions, 44 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 23ff23e8b39..2002ea88ca2 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1477,9 +1477,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
1477 reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 1477 reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
1478 reg_ctl &= ~IXGBE_RXCTRL_RXEN; 1478 reg_ctl &= ~IXGBE_RXCTRL_RXEN;
1479 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); 1479 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
1480 reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx)); 1480 ixgbe_disable_rx_queue(adapter, rx_ring);
1481 reg_ctl &= ~IXGBE_RXDCTL_ENABLE;
1482 IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl);
1483 1481
1484 /* now Tx */ 1482 /* now Tx */
1485 reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx)); 1483 reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx));
@@ -2279,10 +2277,11 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev,
2279 struct ethtool_rx_ntuple *cmd) 2277 struct ethtool_rx_ntuple *cmd)
2280{ 2278{
2281 struct ixgbe_adapter *adapter = netdev_priv(dev); 2279 struct ixgbe_adapter *adapter = netdev_priv(dev);
2282 struct ethtool_rx_ntuple_flow_spec fs = cmd->fs; 2280 struct ethtool_rx_ntuple_flow_spec *fs = &cmd->fs;
2283 struct ixgbe_atr_input input_struct; 2281 union ixgbe_atr_input input_struct;
2284 struct ixgbe_atr_input_masks input_masks; 2282 struct ixgbe_atr_input_masks input_masks;
2285 int target_queue; 2283 int target_queue;
2284 int err;
2286 2285
2287 if (adapter->hw.mac.type == ixgbe_mac_82598EB) 2286 if (adapter->hw.mac.type == ixgbe_mac_82598EB)
2288 return -EOPNOTSUPP; 2287 return -EOPNOTSUPP;
@@ -2291,67 +2290,122 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev,
2291 * Don't allow programming if the action is a queue greater than 2290 * Don't allow programming if the action is a queue greater than
2292 * the number of online Tx queues. 2291 * the number of online Tx queues.
2293 */ 2292 */
2294 if ((fs.action >= adapter->num_tx_queues) || 2293 if ((fs->action >= adapter->num_tx_queues) ||
2295 (fs.action < ETHTOOL_RXNTUPLE_ACTION_DROP)) 2294 (fs->action < ETHTOOL_RXNTUPLE_ACTION_DROP))
2296 return -EINVAL; 2295 return -EINVAL;
2297 2296
2298 memset(&input_struct, 0, sizeof(struct ixgbe_atr_input)); 2297 memset(&input_struct, 0, sizeof(union ixgbe_atr_input));
2299 memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks)); 2298 memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks));
2300 2299
2301 input_masks.src_ip_mask = fs.m_u.tcp_ip4_spec.ip4src; 2300 /* record flow type */
2302 input_masks.dst_ip_mask = fs.m_u.tcp_ip4_spec.ip4dst; 2301 switch (fs->flow_type) {
2303 input_masks.src_port_mask = fs.m_u.tcp_ip4_spec.psrc; 2302 case IPV4_FLOW:
2304 input_masks.dst_port_mask = fs.m_u.tcp_ip4_spec.pdst; 2303 input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_IPV4;
2305 input_masks.vlan_id_mask = fs.vlan_tag_mask; 2304 break;
2306 /* only use the lowest 2 bytes for flex bytes */
2307 input_masks.data_mask = (fs.data_mask & 0xffff);
2308
2309 switch (fs.flow_type) {
2310 case TCP_V4_FLOW: 2305 case TCP_V4_FLOW:
2311 ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_TCP); 2306 input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4;
2312 break; 2307 break;
2313 case UDP_V4_FLOW: 2308 case UDP_V4_FLOW:
2314 ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_UDP); 2309 input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4;
2315 break; 2310 break;
2316 case SCTP_V4_FLOW: 2311 case SCTP_V4_FLOW:
2317 ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_SCTP); 2312 input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4;
2318 break; 2313 break;
2319 default: 2314 default:
2320 return -1; 2315 return -1;
2321 } 2316 }
2322 2317
2323 /* Mask bits from the inputs based on user-supplied mask */ 2318 /* copy vlan tag minus the CFI bit */
2324 ixgbe_atr_set_src_ipv4_82599(&input_struct, 2319 if ((fs->vlan_tag & 0xEFFF) || (~fs->vlan_tag_mask & 0xEFFF)) {
2325 (fs.h_u.tcp_ip4_spec.ip4src & ~fs.m_u.tcp_ip4_spec.ip4src)); 2320 input_struct.formatted.vlan_id = htons(fs->vlan_tag & 0xEFFF);
2326 ixgbe_atr_set_dst_ipv4_82599(&input_struct, 2321 if (!fs->vlan_tag_mask) {
2327 (fs.h_u.tcp_ip4_spec.ip4dst & ~fs.m_u.tcp_ip4_spec.ip4dst)); 2322 input_masks.vlan_id_mask = htons(0xEFFF);
2328 /* 82599 expects these to be byte-swapped for perfect filtering */ 2323 } else {
2329 ixgbe_atr_set_src_port_82599(&input_struct, 2324 switch (~fs->vlan_tag_mask & 0xEFFF) {
2330 ((ntohs(fs.h_u.tcp_ip4_spec.psrc)) & ~fs.m_u.tcp_ip4_spec.psrc)); 2325 /* all of these are valid vlan-mask values */
2331 ixgbe_atr_set_dst_port_82599(&input_struct, 2326 case 0xEFFF:
2332 ((ntohs(fs.h_u.tcp_ip4_spec.pdst)) & ~fs.m_u.tcp_ip4_spec.pdst)); 2327 case 0xE000:
2333 2328 case 0x0FFF:
2334 /* VLAN and Flex bytes are either completely masked or not */ 2329 case 0x0000:
2335 if (!fs.vlan_tag_mask) 2330 input_masks.vlan_id_mask =
2336 ixgbe_atr_set_vlan_id_82599(&input_struct, fs.vlan_tag); 2331 htons(~fs->vlan_tag_mask);
2337 2332 break;
2338 if (!input_masks.data_mask) 2333 /* exit with error if vlan-mask is invalid */
2339 /* make sure we only use the first 2 bytes of user data */ 2334 default:
2340 ixgbe_atr_set_flex_byte_82599(&input_struct, 2335 e_err(drv, "Partial VLAN ID or "
2341 (fs.data & 0xffff)); 2336 "priority mask in vlan-mask is not "
2337 "supported by hardware\n");
2338 return -1;
2339 }
2340 }
2341 }
2342
2343 /* make sure we only use the first 2 bytes of user data */
2344 if ((fs->data & 0xFFFF) || (~fs->data_mask & 0xFFFF)) {
2345 input_struct.formatted.flex_bytes = htons(fs->data & 0xFFFF);
2346 if (!(fs->data_mask & 0xFFFF)) {
2347 input_masks.flex_mask = 0xFFFF;
2348 } else if (~fs->data_mask & 0xFFFF) {
2349 e_err(drv, "Partial user-def-mask is not "
2350 "supported by hardware\n");
2351 return -1;
2352 }
2353 }
2354
2355 /*
2356 * Copy input into formatted structures
2357 *
2358 * These assignments are based on the following logic
2359 * If neither input or mask are set assume value is masked out.
2360 * If input is set, but mask is not mask should default to accept all.
2361 * If input is not set, but mask is set then mask likely results in 0.
2362 * If input is set and mask is set then assign both.
2363 */
2364 if (fs->h_u.tcp_ip4_spec.ip4src || ~fs->m_u.tcp_ip4_spec.ip4src) {
2365 input_struct.formatted.src_ip[0] = fs->h_u.tcp_ip4_spec.ip4src;
2366 if (!fs->m_u.tcp_ip4_spec.ip4src)
2367 input_masks.src_ip_mask[0] = 0xFFFFFFFF;
2368 else
2369 input_masks.src_ip_mask[0] =
2370 ~fs->m_u.tcp_ip4_spec.ip4src;
2371 }
2372 if (fs->h_u.tcp_ip4_spec.ip4dst || ~fs->m_u.tcp_ip4_spec.ip4dst) {
2373 input_struct.formatted.dst_ip[0] = fs->h_u.tcp_ip4_spec.ip4dst;
2374 if (!fs->m_u.tcp_ip4_spec.ip4dst)
2375 input_masks.dst_ip_mask[0] = 0xFFFFFFFF;
2376 else
2377 input_masks.dst_ip_mask[0] =
2378 ~fs->m_u.tcp_ip4_spec.ip4dst;
2379 }
2380 if (fs->h_u.tcp_ip4_spec.psrc || ~fs->m_u.tcp_ip4_spec.psrc) {
2381 input_struct.formatted.src_port = fs->h_u.tcp_ip4_spec.psrc;
2382 if (!fs->m_u.tcp_ip4_spec.psrc)
2383 input_masks.src_port_mask = 0xFFFF;
2384 else
2385 input_masks.src_port_mask = ~fs->m_u.tcp_ip4_spec.psrc;
2386 }
2387 if (fs->h_u.tcp_ip4_spec.pdst || ~fs->m_u.tcp_ip4_spec.pdst) {
2388 input_struct.formatted.dst_port = fs->h_u.tcp_ip4_spec.pdst;
2389 if (!fs->m_u.tcp_ip4_spec.pdst)
2390 input_masks.dst_port_mask = 0xFFFF;
2391 else
2392 input_masks.dst_port_mask = ~fs->m_u.tcp_ip4_spec.pdst;
2393 }
2342 2394
2343 /* determine if we need to drop or route the packet */ 2395 /* determine if we need to drop or route the packet */
2344 if (fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) 2396 if (fs->action == ETHTOOL_RXNTUPLE_ACTION_DROP)
2345 target_queue = MAX_RX_QUEUES - 1; 2397 target_queue = MAX_RX_QUEUES - 1;
2346 else 2398 else
2347 target_queue = fs.action; 2399 target_queue = fs->action;
2348 2400
2349 spin_lock(&adapter->fdir_perfect_lock); 2401 spin_lock(&adapter->fdir_perfect_lock);
2350 ixgbe_fdir_add_perfect_filter_82599(&adapter->hw, &input_struct, 2402 err = ixgbe_fdir_add_perfect_filter_82599(&adapter->hw,
2351 &input_masks, 0, target_queue); 2403 &input_struct,
2404 &input_masks, 0,
2405 target_queue);
2352 spin_unlock(&adapter->fdir_perfect_lock); 2406 spin_unlock(&adapter->fdir_perfect_lock);
2353 2407
2354 return 0; 2408 return err ? -1 : 0;
2355} 2409}
2356 2410
2357static const struct ethtool_ops ixgbe_ethtool_ops = { 2411static const struct ethtool_ops ixgbe_ethtool_ops = {