diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-07-20 04:10:03 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-10-23 00:15:35 -0400 |
commit | 56e94095efb3d4f749212bf7c0b151843d157f49 (patch) | |
tree | 5192439b4d53a4fe0b24945d7adb81e3d950912b /drivers/net/ethernet/intel | |
parent | bffb3bc95895ee15ad90c66bfd387bc7342c1cee (diff) |
ixgbevf: Add VF DCB + SR-IOV support
This change adds support for DCB and SR-IOV from the VF. With this change
in place the VF will correctly use a traffic class other than 0 in the case
that the PF is configured with the default user priority belonging to a
traffic class other than 0.
Cc: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/defines.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 159 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/mbx.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/vf.c | 58 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/vf.h | 2 |
6 files changed, 232 insertions, 8 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h b/drivers/net/ethernet/intel/ixgbevf/defines.h index da17ccf5c09d..3147795bd135 100644 --- a/drivers/net/ethernet/intel/ixgbevf/defines.h +++ b/drivers/net/ethernet/intel/ixgbevf/defines.h | |||
@@ -33,8 +33,11 @@ | |||
33 | #define IXGBE_DEV_ID_X540_VF 0x1515 | 33 | #define IXGBE_DEV_ID_X540_VF 0x1515 |
34 | 34 | ||
35 | #define IXGBE_VF_IRQ_CLEAR_MASK 7 | 35 | #define IXGBE_VF_IRQ_CLEAR_MASK 7 |
36 | #define IXGBE_VF_MAX_TX_QUEUES 1 | 36 | #define IXGBE_VF_MAX_TX_QUEUES 8 |
37 | #define IXGBE_VF_MAX_RX_QUEUES 1 | 37 | #define IXGBE_VF_MAX_RX_QUEUES 8 |
38 | |||
39 | /* DCB define */ | ||
40 | #define IXGBE_VF_MAX_TRAFFIC_CLASS 8 | ||
38 | 41 | ||
39 | /* Link speed */ | 42 | /* Link speed */ |
40 | typedef u32 ixgbe_link_speed; | 43 | typedef u32 ixgbe_link_speed; |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 4a9c9c285685..2323ccd211c0 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | |||
@@ -89,8 +89,8 @@ struct ixgbevf_ring { | |||
89 | /* How many Rx Buffers do we bundle into one write to the hardware ? */ | 89 | /* How many Rx Buffers do we bundle into one write to the hardware ? */ |
90 | #define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */ | 90 | #define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */ |
91 | 91 | ||
92 | #define MAX_RX_QUEUES 1 | 92 | #define MAX_RX_QUEUES IXGBE_VF_MAX_RX_QUEUES |
93 | #define MAX_TX_QUEUES 1 | 93 | #define MAX_TX_QUEUES IXGBE_VF_MAX_TX_QUEUES |
94 | 94 | ||
95 | #define IXGBEVF_DEFAULT_TXD 1024 | 95 | #define IXGBEVF_DEFAULT_TXD 1024 |
96 | #define IXGBEVF_DEFAULT_RXD 512 | 96 | #define IXGBEVF_DEFAULT_RXD 512 |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index de1ad506665d..33444b5b5105 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -99,6 +99,7 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | |||
99 | 99 | ||
100 | /* forward decls */ | 100 | /* forward decls */ |
101 | static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector); | 101 | static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector); |
102 | static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter); | ||
102 | 103 | ||
103 | static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw, | 104 | static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw, |
104 | struct ixgbevf_ring *rx_ring, | 105 | struct ixgbevf_ring *rx_ring, |
@@ -1335,7 +1336,8 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) | |||
1335 | static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) | 1336 | static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) |
1336 | { | 1337 | { |
1337 | struct ixgbe_hw *hw = &adapter->hw; | 1338 | struct ixgbe_hw *hw = &adapter->hw; |
1338 | int api[] = { ixgbe_mbox_api_10, | 1339 | int api[] = { ixgbe_mbox_api_11, |
1340 | ixgbe_mbox_api_10, | ||
1339 | ixgbe_mbox_api_unknown }; | 1341 | ixgbe_mbox_api_unknown }; |
1340 | int err = 0, idx = 0; | 1342 | int err = 0, idx = 0; |
1341 | 1343 | ||
@@ -1413,12 +1415,87 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1413 | mod_timer(&adapter->watchdog_timer, jiffies); | 1415 | mod_timer(&adapter->watchdog_timer, jiffies); |
1414 | } | 1416 | } |
1415 | 1417 | ||
1418 | static int ixgbevf_reset_queues(struct ixgbevf_adapter *adapter) | ||
1419 | { | ||
1420 | struct ixgbe_hw *hw = &adapter->hw; | ||
1421 | struct ixgbevf_ring *rx_ring; | ||
1422 | unsigned int def_q = 0; | ||
1423 | unsigned int num_tcs = 0; | ||
1424 | unsigned int num_rx_queues = 1; | ||
1425 | int err, i; | ||
1426 | |||
1427 | spin_lock(&adapter->mbx_lock); | ||
1428 | |||
1429 | /* fetch queue configuration from the PF */ | ||
1430 | err = ixgbevf_get_queues(hw, &num_tcs, &def_q); | ||
1431 | |||
1432 | spin_unlock(&adapter->mbx_lock); | ||
1433 | |||
1434 | if (err) | ||
1435 | return err; | ||
1436 | |||
1437 | if (num_tcs > 1) { | ||
1438 | /* update default Tx ring register index */ | ||
1439 | adapter->tx_ring[0].reg_idx = def_q; | ||
1440 | |||
1441 | /* we need as many queues as traffic classes */ | ||
1442 | num_rx_queues = num_tcs; | ||
1443 | } | ||
1444 | |||
1445 | /* nothing to do if we have the correct number of queues */ | ||
1446 | if (adapter->num_rx_queues == num_rx_queues) | ||
1447 | return 0; | ||
1448 | |||
1449 | /* allocate new rings */ | ||
1450 | rx_ring = kcalloc(num_rx_queues, | ||
1451 | sizeof(struct ixgbevf_ring), GFP_KERNEL); | ||
1452 | if (!rx_ring) | ||
1453 | return -ENOMEM; | ||
1454 | |||
1455 | /* setup ring fields */ | ||
1456 | for (i = 0; i < num_rx_queues; i++) { | ||
1457 | rx_ring[i].count = adapter->rx_ring_count; | ||
1458 | rx_ring[i].queue_index = i; | ||
1459 | rx_ring[i].reg_idx = i; | ||
1460 | rx_ring[i].dev = &adapter->pdev->dev; | ||
1461 | rx_ring[i].netdev = adapter->netdev; | ||
1462 | |||
1463 | /* allocate resources on the ring */ | ||
1464 | err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); | ||
1465 | if (err) { | ||
1466 | while (i) { | ||
1467 | i--; | ||
1468 | ixgbevf_free_rx_resources(adapter, &rx_ring[i]); | ||
1469 | } | ||
1470 | kfree(rx_ring); | ||
1471 | return err; | ||
1472 | } | ||
1473 | } | ||
1474 | |||
1475 | /* free the existing rings and queues */ | ||
1476 | ixgbevf_free_all_rx_resources(adapter); | ||
1477 | adapter->num_rx_queues = 0; | ||
1478 | kfree(adapter->rx_ring); | ||
1479 | |||
1480 | /* move new rings into position on the adapter struct */ | ||
1481 | adapter->rx_ring = rx_ring; | ||
1482 | adapter->num_rx_queues = num_rx_queues; | ||
1483 | |||
1484 | /* reset ring to vector mapping */ | ||
1485 | ixgbevf_reset_q_vectors(adapter); | ||
1486 | ixgbevf_map_rings_to_vectors(adapter); | ||
1487 | |||
1488 | return 0; | ||
1489 | } | ||
1490 | |||
1416 | void ixgbevf_up(struct ixgbevf_adapter *adapter) | 1491 | void ixgbevf_up(struct ixgbevf_adapter *adapter) |
1417 | { | 1492 | { |
1418 | struct ixgbe_hw *hw = &adapter->hw; | 1493 | struct ixgbe_hw *hw = &adapter->hw; |
1419 | 1494 | ||
1420 | ixgbevf_negotiate_api(adapter); | 1495 | ixgbevf_negotiate_api(adapter); |
1421 | 1496 | ||
1497 | ixgbevf_reset_queues(adapter); | ||
1498 | |||
1422 | ixgbevf_configure(adapter); | 1499 | ixgbevf_configure(adapter); |
1423 | 1500 | ||
1424 | ixgbevf_up_complete(adapter); | 1501 | ixgbevf_up_complete(adapter); |
@@ -1717,6 +1794,7 @@ static int ixgbevf_alloc_queues(struct ixgbevf_adapter *adapter) | |||
1717 | for (i = 0; i < adapter->num_tx_queues; i++) { | 1794 | for (i = 0; i < adapter->num_tx_queues; i++) { |
1718 | adapter->tx_ring[i].count = adapter->tx_ring_count; | 1795 | adapter->tx_ring[i].count = adapter->tx_ring_count; |
1719 | adapter->tx_ring[i].queue_index = i; | 1796 | adapter->tx_ring[i].queue_index = i; |
1797 | /* reg_idx may be remapped later by DCB config */ | ||
1720 | adapter->tx_ring[i].reg_idx = i; | 1798 | adapter->tx_ring[i].reg_idx = i; |
1721 | adapter->tx_ring[i].dev = &adapter->pdev->dev; | 1799 | adapter->tx_ring[i].dev = &adapter->pdev->dev; |
1722 | adapter->tx_ring[i].netdev = adapter->netdev; | 1800 | adapter->tx_ring[i].netdev = adapter->netdev; |
@@ -1950,8 +2028,11 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) | |||
1950 | hw->subsystem_device_id = pdev->subsystem_device; | 2028 | hw->subsystem_device_id = pdev->subsystem_device; |
1951 | 2029 | ||
1952 | hw->mbx.ops.init_params(hw); | 2030 | hw->mbx.ops.init_params(hw); |
1953 | hw->mac.max_tx_queues = MAX_TX_QUEUES; | 2031 | |
1954 | hw->mac.max_rx_queues = MAX_RX_QUEUES; | 2032 | /* assume legacy case in which PF would only give VF 2 queues */ |
2033 | hw->mac.max_tx_queues = 2; | ||
2034 | hw->mac.max_rx_queues = 2; | ||
2035 | |||
1955 | err = hw->mac.ops.reset_hw(hw); | 2036 | err = hw->mac.ops.reset_hw(hw); |
1956 | if (err) { | 2037 | if (err) { |
1957 | dev_info(&pdev->dev, | 2038 | dev_info(&pdev->dev, |
@@ -2377,6 +2458,63 @@ static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter) | |||
2377 | &adapter->rx_ring[i]); | 2458 | &adapter->rx_ring[i]); |
2378 | } | 2459 | } |
2379 | 2460 | ||
2461 | static int ixgbevf_setup_queues(struct ixgbevf_adapter *adapter) | ||
2462 | { | ||
2463 | struct ixgbe_hw *hw = &adapter->hw; | ||
2464 | struct ixgbevf_ring *rx_ring; | ||
2465 | unsigned int def_q = 0; | ||
2466 | unsigned int num_tcs = 0; | ||
2467 | unsigned int num_rx_queues = 1; | ||
2468 | int err, i; | ||
2469 | |||
2470 | spin_lock(&adapter->mbx_lock); | ||
2471 | |||
2472 | /* fetch queue configuration from the PF */ | ||
2473 | err = ixgbevf_get_queues(hw, &num_tcs, &def_q); | ||
2474 | |||
2475 | spin_unlock(&adapter->mbx_lock); | ||
2476 | |||
2477 | if (err) | ||
2478 | return err; | ||
2479 | |||
2480 | if (num_tcs > 1) { | ||
2481 | /* update default Tx ring register index */ | ||
2482 | adapter->tx_ring[0].reg_idx = def_q; | ||
2483 | |||
2484 | /* we need as many queues as traffic classes */ | ||
2485 | num_rx_queues = num_tcs; | ||
2486 | } | ||
2487 | |||
2488 | /* nothing to do if we have the correct number of queues */ | ||
2489 | if (adapter->num_rx_queues == num_rx_queues) | ||
2490 | return 0; | ||
2491 | |||
2492 | /* allocate new rings */ | ||
2493 | rx_ring = kcalloc(num_rx_queues, | ||
2494 | sizeof(struct ixgbevf_ring), GFP_KERNEL); | ||
2495 | if (!rx_ring) | ||
2496 | return -ENOMEM; | ||
2497 | |||
2498 | /* setup ring fields */ | ||
2499 | for (i = 0; i < num_rx_queues; i++) { | ||
2500 | rx_ring[i].count = adapter->rx_ring_count; | ||
2501 | rx_ring[i].queue_index = i; | ||
2502 | rx_ring[i].reg_idx = i; | ||
2503 | rx_ring[i].dev = &adapter->pdev->dev; | ||
2504 | rx_ring[i].netdev = adapter->netdev; | ||
2505 | } | ||
2506 | |||
2507 | /* free the existing ring and queues */ | ||
2508 | adapter->num_rx_queues = 0; | ||
2509 | kfree(adapter->rx_ring); | ||
2510 | |||
2511 | /* move new rings into position on the adapter struct */ | ||
2512 | adapter->rx_ring = rx_ring; | ||
2513 | adapter->num_rx_queues = num_rx_queues; | ||
2514 | |||
2515 | return 0; | ||
2516 | } | ||
2517 | |||
2380 | /** | 2518 | /** |
2381 | * ixgbevf_open - Called when a network interface is made active | 2519 | * ixgbevf_open - Called when a network interface is made active |
2382 | * @netdev: network interface device structure | 2520 | * @netdev: network interface device structure |
@@ -2413,6 +2551,11 @@ static int ixgbevf_open(struct net_device *netdev) | |||
2413 | 2551 | ||
2414 | ixgbevf_negotiate_api(adapter); | 2552 | ixgbevf_negotiate_api(adapter); |
2415 | 2553 | ||
2554 | /* setup queue reg_idx and Rx queue count */ | ||
2555 | err = ixgbevf_setup_queues(adapter); | ||
2556 | if (err) | ||
2557 | goto err_setup_queues; | ||
2558 | |||
2416 | /* allocate transmit descriptors */ | 2559 | /* allocate transmit descriptors */ |
2417 | err = ixgbevf_setup_all_tx_resources(adapter); | 2560 | err = ixgbevf_setup_all_tx_resources(adapter); |
2418 | if (err) | 2561 | if (err) |
@@ -2451,6 +2594,7 @@ err_setup_rx: | |||
2451 | ixgbevf_free_all_rx_resources(adapter); | 2594 | ixgbevf_free_all_rx_resources(adapter); |
2452 | err_setup_tx: | 2595 | err_setup_tx: |
2453 | ixgbevf_free_all_tx_resources(adapter); | 2596 | ixgbevf_free_all_tx_resources(adapter); |
2597 | err_setup_queues: | ||
2454 | ixgbevf_reset(adapter); | 2598 | ixgbevf_reset(adapter); |
2455 | 2599 | ||
2456 | err_setup_reset: | 2600 | err_setup_reset: |
@@ -2925,8 +3069,15 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) | |||
2925 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | 3069 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; |
2926 | int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; | 3070 | int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; |
2927 | 3071 | ||
2928 | if (adapter->hw.mac.type == ixgbe_mac_X540_vf) | 3072 | switch (adapter->hw.api_version) { |
3073 | case ixgbe_mbox_api_11: | ||
2929 | max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; | 3074 | max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; |
3075 | break; | ||
3076 | default: | ||
3077 | if (adapter->hw.mac.type == ixgbe_mac_X540_vf) | ||
3078 | max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; | ||
3079 | break; | ||
3080 | } | ||
2930 | 3081 | ||
2931 | /* MTU < 68 is an error and causes problems on some kernels */ | 3082 | /* MTU < 68 is an error and causes problems on some kernels */ |
2932 | if ((new_mtu < 68) || (max_frame > max_possible_frame)) | 3083 | if ((new_mtu < 68) || (max_frame > max_possible_frame)) |
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h index 946ce86f337f..0bc30058ff82 100644 --- a/drivers/net/ethernet/intel/ixgbevf/mbx.h +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h | |||
@@ -85,6 +85,7 @@ | |||
85 | enum ixgbe_pfvf_api_rev { | 85 | enum ixgbe_pfvf_api_rev { |
86 | ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ | 86 | ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ |
87 | ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ | 87 | ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ |
88 | ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ | ||
88 | /* This value should always be last */ | 89 | /* This value should always be last */ |
89 | ixgbe_mbox_api_unknown, /* indicates that API version is not known */ | 90 | ixgbe_mbox_api_unknown, /* indicates that API version is not known */ |
90 | }; | 91 | }; |
@@ -100,6 +101,15 @@ enum ixgbe_pfvf_api_rev { | |||
100 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ | 101 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ |
101 | #define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ | 102 | #define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ |
102 | 103 | ||
104 | /* mailbox API, version 1.1 VF requests */ | ||
105 | #define IXGBE_VF_GET_QUEUE 0x09 /* get queue configuration */ | ||
106 | |||
107 | /* GET_QUEUES return data indices within the mailbox */ | ||
108 | #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ | ||
109 | #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ | ||
110 | #define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */ | ||
111 | #define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */ | ||
112 | |||
103 | /* length of permanent address message returned from PF */ | 113 | /* length of permanent address message returned from PF */ |
104 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 | 114 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 |
105 | /* word in permanent address message with the current multicast type */ | 115 | /* word in permanent address message with the current multicast type */ |
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index 0c7447e6fcc8..5fa397b953eb 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c | |||
@@ -513,6 +513,64 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) | |||
513 | return err; | 513 | return err; |
514 | } | 514 | } |
515 | 515 | ||
516 | int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, | ||
517 | unsigned int *default_tc) | ||
518 | { | ||
519 | int err; | ||
520 | u32 msg[5]; | ||
521 | |||
522 | /* do nothing if API doesn't support ixgbevf_get_queues */ | ||
523 | switch (hw->api_version) { | ||
524 | case ixgbe_mbox_api_11: | ||
525 | break; | ||
526 | default: | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | /* Fetch queue configuration from the PF */ | ||
531 | msg[0] = IXGBE_VF_GET_QUEUE; | ||
532 | msg[1] = msg[2] = msg[3] = msg[4] = 0; | ||
533 | err = hw->mbx.ops.write_posted(hw, msg, 5); | ||
534 | |||
535 | if (!err) | ||
536 | err = hw->mbx.ops.read_posted(hw, msg, 5); | ||
537 | |||
538 | if (!err) { | ||
539 | msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||
540 | |||
541 | /* | ||
542 | * if we we didn't get an ACK there must have been | ||
543 | * some sort of mailbox error so we should treat it | ||
544 | * as such | ||
545 | */ | ||
546 | if (msg[0] != (IXGBE_VF_GET_QUEUE | IXGBE_VT_MSGTYPE_ACK)) | ||
547 | return IXGBE_ERR_MBX; | ||
548 | |||
549 | /* record and validate values from message */ | ||
550 | hw->mac.max_tx_queues = msg[IXGBE_VF_TX_QUEUES]; | ||
551 | if (hw->mac.max_tx_queues == 0 || | ||
552 | hw->mac.max_tx_queues > IXGBE_VF_MAX_TX_QUEUES) | ||
553 | hw->mac.max_tx_queues = IXGBE_VF_MAX_TX_QUEUES; | ||
554 | |||
555 | hw->mac.max_rx_queues = msg[IXGBE_VF_RX_QUEUES]; | ||
556 | if (hw->mac.max_rx_queues == 0 || | ||
557 | hw->mac.max_rx_queues > IXGBE_VF_MAX_RX_QUEUES) | ||
558 | hw->mac.max_rx_queues = IXGBE_VF_MAX_RX_QUEUES; | ||
559 | |||
560 | *num_tcs = msg[IXGBE_VF_TRANS_VLAN]; | ||
561 | /* in case of unknown state assume we cannot tag frames */ | ||
562 | if (*num_tcs > hw->mac.max_rx_queues) | ||
563 | *num_tcs = 1; | ||
564 | |||
565 | *default_tc = msg[IXGBE_VF_DEF_QUEUE]; | ||
566 | /* default to queue 0 on out-of-bounds queue number */ | ||
567 | if (*default_tc >= hw->mac.max_tx_queues) | ||
568 | *default_tc = 0; | ||
569 | } | ||
570 | |||
571 | return err; | ||
572 | } | ||
573 | |||
516 | static const struct ixgbe_mac_operations ixgbevf_mac_ops = { | 574 | static const struct ixgbe_mac_operations ixgbevf_mac_ops = { |
517 | .init_hw = ixgbevf_init_hw_vf, | 575 | .init_hw = ixgbevf_init_hw_vf, |
518 | .reset_hw = ixgbevf_reset_hw_vf, | 576 | .reset_hw = ixgbevf_reset_hw_vf, |
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h index 47f11a584d8c..7b1f502d1716 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.h +++ b/drivers/net/ethernet/intel/ixgbevf/vf.h | |||
@@ -174,5 +174,7 @@ struct ixgbevf_info { | |||
174 | 174 | ||
175 | void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); | 175 | void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); |
176 | int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); | 176 | int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); |
177 | int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, | ||
178 | unsigned int *default_tc); | ||
177 | #endif /* __IXGBE_VF_H__ */ | 179 | #endif /* __IXGBE_VF_H__ */ |
178 | 180 | ||