* [net-next v2 07/15] i40e: update firmware api to 1.1
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Shannon Nelson <shannon.nelson@intel.com>
The firmware's AdminQ interface has matured a little, so update the
code to use the new fields and values.
Change-Id: I8fcd7b443f268dcf9346bd6a9e940fe9c2958891
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_adminq.c | 12 ++-
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 126 ++++++++++++++++------
drivers/net/ethernet/intel/i40e/i40e_common.c | 2 +-
drivers/net/ethernet/intel/i40e/i40e_type.h | 3 -
4 files changed, 99 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index f75b573..3ee5323 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -572,16 +572,18 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
if (ret_code != I40E_SUCCESS)
goto init_adminq_free_arq;
- if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
- hw->aq.api_min_ver != I40E_FW_API_VERSION_MINOR) {
- ret_code = I40E_ERR_FIRMWARE_API_VERSION;
- goto init_adminq_free_arq;
- }
+ /* get the NVM version info */
i40e_read_nvm_word(hw, I40E_SR_NVM_IMAGE_VERSION, &hw->nvm.version);
i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
+ if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
+ hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR) {
+ ret_code = I40E_ERR_FIRMWARE_API_VERSION;
+ goto init_adminq_free_arq;
+ }
+
ret_code = i40e_aq_set_hmc_resource_profile(hw,
I40E_HMC_PROFILE_DEFAULT,
0,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index 2859377..0075087 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -35,7 +35,7 @@
*/
#define I40E_FW_API_VERSION_MAJOR 0x0001
-#define I40E_FW_API_VERSION_MINOR 0x0000
+#define I40E_FW_API_VERSION_MINOR 0x0001
struct i40e_aq_desc {
__le16 flags;
@@ -137,10 +137,13 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_set_ns_proxy_entry = 0x0105,
/* LAA */
- i40e_aqc_opc_mng_laa = 0x0106,
+ i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */
i40e_aqc_opc_mac_address_read = 0x0107,
i40e_aqc_opc_mac_address_write = 0x0108,
+ /* PXE */
+ i40e_aqc_opc_clear_pxe_mode = 0x0110,
+
/* internal switch commands */
i40e_aqc_opc_get_switch_config = 0x0200,
i40e_aqc_opc_add_statistics = 0x0201,
@@ -317,13 +320,15 @@ struct i40e_aqc_get_version {
I40E_CHECK_CMD_LENGTH(i40e_aqc_get_version);
-/* Send driver version (direct 0x0002) */
+/* Send driver version (indirect 0x0002) */
struct i40e_aqc_driver_version {
u8 driver_major_ver;
u8 driver_minor_ver;
u8 driver_build_ver;
u8 driver_subbuild_ver;
- u8 reserved[12];
+ u8 reserved[4];
+ __le32 address_high;
+ __le32 address_low;
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_driver_version);
@@ -479,7 +484,7 @@ struct i40e_aqc_mng_laa {
u8 reserved2[6];
};
-/* Manage MAC Address Read Command (0x0107) */
+/* Manage MAC Address Read Command (indirect 0x0107) */
struct i40e_aqc_mac_address_read {
__le16 command_flags;
#define I40E_AQC_LAN_ADDR_VALID 0x10
@@ -517,6 +522,16 @@ struct i40e_aqc_mac_address_write {
I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_write);
+/* PXE commands (0x011x) */
+
+/* Clear PXE Command and response (direct 0x0110) */
+struct i40e_aqc_clear_pxe {
+ u8 rx_cnt;
+ u8 reserved[15];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_clear_pxe);
+
/* Switch configuration commands (0x02xx) */
/* Used by many indirect commands that only pass an seid and a buffer in the
@@ -639,13 +654,15 @@ struct i40e_aqc_switch_resource_alloc_element_resp {
u8 reserved2[6];
};
-/* Add VSI (indirect 0x210)
+/* Add VSI (indirect 0x0210)
* this indirect command uses struct i40e_aqc_vsi_properties_data
* as the indirect buffer (128 bytes)
*
- * Update VSI (indirect 0x211) Get VSI (indirect 0x0212)
- * use the generic i40e_aqc_switch_seid descriptor format
- * use the same completion and data structure as Add VSI
+ * Update VSI (indirect 0x211)
+ * uses the same data structure as Add VSI
+ *
+ * Get VSI (indirect 0x0212)
+ * uses the same completion and data structure as Add VSI
*/
struct i40e_aqc_add_get_update_vsi {
__le16 uplink_seid;
@@ -1185,27 +1202,40 @@ struct i40e_aqc_add_remove_cloud_filters_element_data {
#define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0
#define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \
I40E_AQC_ADD_CLOUD_FILTER_SHIFT)
+/* 0x0000 reserved */
#define I40E_AQC_ADD_CLOUD_FILTER_OIP 0x0001
-#define I40E_AQC_ADD_CLOUD_FILTER_OIP_GRE 0x0002
+/* 0x0002 reserved */
#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN 0x0003
-#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_GRE 0x0004
+#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID 0x0004
+/* 0x0005 reserved */
#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID 0x0006
-#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_VNL 0x0007
+/* 0x0007 reserved */
/* 0x0008 reserved */
#define I40E_AQC_ADD_CLOUD_FILTER_OMAC 0x0009
#define I40E_AQC_ADD_CLOUD_FILTER_IMAC 0x000A
+#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B
+#define I40E_AQC_ADD_CLOUD_FILTER_IIP 0x000C
+
#define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080
#define I40E_AQC_ADD_CLOUD_VNK_SHIFT 6
#define I40E_AQC_ADD_CLOUD_VNK_MASK 0x00C0
#define I40E_AQC_ADD_CLOUD_FLAGS_IPV4 0
#define I40E_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100
- __le32 key_low;
- __le32 key_high;
+
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN 0
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE 2
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3
+
+ __le32 tenant_id;
+ u8 reserved[4];
__le16 queue_number;
#define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0
#define I40E_AQC_ADD_CLOUD_QUEUE_MASK (0x3F << \
I40E_AQC_ADD_CLOUD_QUEUE_SHIFT)
- u8 reserved[14];
+ u8 reserved2[14];
/* response section */
u8 allocation_result;
#define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0
@@ -1548,7 +1578,7 @@ struct i40e_aqc_module_desc {
struct i40e_aq_get_phy_abilities_resp {
__le32 phy_type; /* bitmap using the above enum for offsets */
- u8 link_speed; /* bitmap using the above enum */
+ u8 link_speed; /* bitmap using the above enum bit patterns */
u8 abilities;
#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01
#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02
@@ -1582,6 +1612,10 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
__le32 phy_type;
u8 link_speed;
u8 abilities;
+/* bits 0-2 use the values from get_phy_abilities_resp */
+#define I40E_AQ_PHY_ENABLE_LINK 0x08
+#define I40E_AQ_PHY_ENABLE_AN 0x10
+#define I40E_AQ_PHY_ENABLE_ATOMIC_LINK 0x20
__le16 eee_capability;
__le32 eeer;
u8 low_power_ctrl;
@@ -1915,22 +1949,39 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start);
struct i40e_aqc_add_udp_tunnel {
__le16 udp_port;
u8 header_len; /* in DWords, 1 to 15 */
- u8 protocol_index;
-#define I40E_AQC_TUNNEL_TYPE_MAC 0x0
-#define I40E_AQC_TUNNEL_TYPE_UDP 0x1
-#define I40E_AQC_TUNNEL_TYPE_VXLAN 0x2
- u8 reserved[12];
+ u8 protocol_type;
+#define I40E_AQC_TUNNEL_TYPE_TEREDO 0x0
+#define I40E_AQC_TUNNEL_TYPE_VXLAN 0x2
+#define I40E_AQC_TUNNEL_TYPE_NGE 0x3
+ u8 variable_udp_length;
+#define I40E_AQC_TUNNEL_FIXED_UDP_LENGTH 0x0
+#define I40E_AQC_TUNNEL_VARIABLE_UDP_LENGTH 0x1
+ u8 udp_key_index;
+#define I40E_AQC_TUNNEL_KEY_INDEX_VXLAN 0x0
+#define I40E_AQC_TUNNEL_KEY_INDEX_NGE 0x1
+#define I40E_AQC_TUNNEL_KEY_INDEX_PROPRIETARY_UDP 0x2
+ u8 reserved[10];
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel);
+struct i40e_aqc_add_udp_tunnel_completion {
+ __le16 udp_port;
+ u8 filter_entry_index;
+ u8 multiple_pfs;
+#define I40E_AQC_SINGLE_PF 0x0
+#define I40E_AQC_MULTIPLE_PFS 0x1
+ u8 total_filters;
+ u8 reserved[11];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel_completion);
+
/* remove UDP Tunnel command (0x0B01) */
struct i40e_aqc_remove_udp_tunnel {
u8 reserved[2];
u8 index; /* 0 to 15 */
- u8 pf_filters;
- u8 total_filters;
- u8 reserved2[11];
+ u8 reserved2[13];
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel);
@@ -1938,28 +1989,32 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel);
struct i40e_aqc_del_udp_tunnel_completion {
__le16 udp_port;
u8 index; /* 0 to 15 */
- u8 multiple_entries;
- u8 tunnels_used;
- u8 reserved;
- u8 tunnels_free;
- u8 reserved1[9];
+ u8 multiple_pfs;
+ u8 total_filters_used;
+ u8 reserved1[11];
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion);
/* tunnel key structure 0x0B10 */
+
struct i40e_aqc_tunnel_key_structure {
- __le16 key1_off;
- __le16 key1_len;
- __le16 key2_off;
- __le16 key2_len;
- __le16 flags;
+ u8 key1_off;
+ u8 key2_off;
+ u8 key1_len; /* 0 to 15 */
+ u8 key2_len; /* 0 to 15 */
+ u8 flags;
#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01
/* response flags */
#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01
#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02
#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03
- u8 resreved[6];
+ u8 network_key_index;
+#define I40E_AQC_NETWORK_KEY_INDEX_VXLAN 0x0
+#define I40E_AQC_NETWORK_KEY_INDEX_NGE 0x1
+#define I40E_AQC_NETWORK_KEY_INDEX_FLEX_MAC_IN_UDP 0x2
+#define I40E_AQC_NETWORK_KEY_INDEX_GRE 0x3
+ u8 reserved[10];
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure);
@@ -2053,6 +2108,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_reg);
#define I40E_AQ_CLUSTER_ID_DCB 8
#define I40E_AQ_CLUSTER_ID_EMP_MEM 9
#define I40E_AQ_CLUSTER_ID_PKT_BUF 10
+#define I40E_AQ_CLUSTER_ID_ALTRAM 11
struct i40e_aqc_debug_dump_internals {
u8 cluster_id;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 337e913..96c8f15 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -1738,7 +1738,7 @@ i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
cmd->udp_port = cpu_to_le16(udp_port);
cmd->header_len = header_len;
- cmd->protocol_index = protocol_index;
+ cmd->protocol_type = protocol_index;
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 7bbcc71..4ac712e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -53,9 +53,6 @@
(d) == I40E_QSFP_B_DEVICE_ID || \
(d) == I40E_QSFP_C_DEVICE_ID)
-#define I40E_FW_API_VERSION_MAJOR 0x0001
-#define I40E_FW_API_VERSION_MINOR 0x0000
-
#define I40E_MAX_VSI_QP 16
#define I40E_MAX_VF_VSI 3
#define I40E_MAX_CHAINED_RX_BUFFERS 5
--
1.8.3.1
^ permalink raw reply related
* [net-next v2 11/15] i40e: rework shadow ram read functions
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Kamil Krawczyk,
Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Shannon Nelson <shannon.nelson@intel.com>
Rework Shadow RAM read word/buffer functions to not use AQ Request
Resource commands. Requesting resource is not needed for SR read
operations which are done through SRCTL register. Access to SR through
register is controlled through DONE bit within SRCTL. With this change
we do not block whole NVM resource for SR read operations.
Change-Id: I73e96cdea39a45ee7b5bdf038e527308de2d9efe
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 67 +++++++-----------------------
1 file changed, 16 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 97e1bb3..e2da0a2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -166,15 +166,15 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
}
/**
- * i40e_read_nvm_srctl - Reads Shadow RAM.
+ * i40e_read_nvm_word - Reads Shadow RAM
* @hw: pointer to the HW structure.
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
* @data: word read from the Shadow RAM.
*
* Reads 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
**/
-static i40e_status i40e_read_nvm_srctl(struct i40e_hw *hw, u16 offset,
- u16 *data)
+i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+ u16 *data)
{
i40e_status ret_code = I40E_ERR_TIMEOUT;
u32 sr_reg;
@@ -211,29 +211,6 @@ read_nvm_exit:
}
/**
- * i40e_read_nvm_word - Reads Shadow RAM word.
- * @hw: pointer to the HW structure.
- * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
- * @data: word read from the Shadow RAM.
- *
- * Reads 16 bit word from the Shadow RAM. Each read is preceded
- * with the NVM ownership taking and followed by the release.
- **/
-i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
- u16 *data)
-{
- i40e_status ret_code = 0;
-
- ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
- if (!ret_code) {
- ret_code = i40e_read_nvm_srctl(hw, offset, data);
- i40e_release_nvm(hw);
- }
-
- return ret_code;
-}
-
-/**
* i40e_read_nvm_buffer - Reads Shadow RAM buffer.
* @hw: pointer to the HW structure.
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
@@ -250,30 +227,18 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
{
i40e_status ret_code = 0;
u16 index, word;
- u32 time;
- ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
- if (!ret_code) {
- /* Loop thru the selected region. */
- for (word = 0; word < *words; word++) {
- index = offset + word;
- ret_code = i40e_read_nvm_srctl(hw, index, &data[word]);
- if (ret_code)
- break;
- /* Check if we didn't exceeded the semaphore timeout. */
- time = rd32(hw, I40E_GLVFGEN_TIMER);
- if (time >= hw->nvm.hw_semaphore_timeout) {
- ret_code = I40E_ERR_TIMEOUT;
- hw_dbg(hw, "NVM read error: timeout.\n");
- break;
- }
- }
- /* Update the number of words read from the Shadow RAM. */
- *words = word;
- /* Release the NVM ownership. */
- i40e_release_nvm(hw);
+ /* Loop thru the selected region. */
+ for (word = 0; word < *words; word++) {
+ index = offset + word;
+ ret_code = i40e_read_nvm_word(hw, index, &data[word]);
+ if (ret_code)
+ break;
}
+ /* Update the number of words read from the Shadow RAM. */
+ *words = word;
+
return ret_code;
}
@@ -297,14 +262,14 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
u32 i = 0;
/* read pointer to VPD area */
- ret_code = i40e_read_nvm_srctl(hw, I40E_SR_VPD_PTR, &vpd_module);
+ ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
if (ret_code) {
ret_code = I40E_ERR_NVM_CHECKSUM;
goto i40e_calc_nvm_checksum_exit;
}
/* read pointer to PCIe Alt Auto-load module */
- ret_code = i40e_read_nvm_srctl(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
+ ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
&pcie_alt_module);
if (ret_code) {
ret_code = I40E_ERR_NVM_CHECKSUM;
@@ -331,7 +296,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
break;
}
- ret_code = i40e_read_nvm_srctl(hw, (u16)i, &word);
+ ret_code = i40e_read_nvm_word(hw, (u16)i, &word);
if (ret_code) {
ret_code = I40E_ERR_NVM_CHECKSUM;
goto i40e_calc_nvm_checksum_exit;
@@ -371,7 +336,7 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
/* Do not use i40e_read_nvm_word() because we do not want to take
* the synchronization semaphores twice here.
*/
- i40e_read_nvm_srctl(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
+ i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
/* Verify read checksum from EEPROM is the same as
* calculated checksum
--
1.8.3.1
^ permalink raw reply related
* [net-next v2 10/15] i40e: check MAC type before any REG access
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Kamil Krawczyk,
Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Shannon Nelson <shannon.nelson@intel.com>
We need to check if we are dealing with the correct MAC type before we
try to read anything from the registers.
Change-Id: I3989516999d06c3009e87d6a2eafc20af305c5c2
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_common.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 02ad529..7e34de1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -180,14 +180,6 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
i40e_status status = 0;
u32 reg;
- hw->phy.get_link_info = true;
-
- /* Determine port number */
- reg = rd32(hw, I40E_PFGEN_PORTNUM);
- reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
- I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
- hw->port = (u8)reg;
-
i40e_set_mac_type(hw);
switch (hw->mac.type) {
@@ -198,6 +190,14 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
break;
}
+ hw->phy.get_link_info = true;
+
+ /* Determine port number */
+ reg = rd32(hw, I40E_PFGEN_PORTNUM);
+ reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
+ I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
+ hw->port = (u8)reg;
+
/* Determine the PF number based on the PCI fn */
reg = rd32(hw, I40E_GLPCI_CAPSUP);
if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
--
1.8.3.1
^ permalink raw reply related
* [net-next v2 12/15] i40e: whitespace paren and comment tweaks
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Mitch Williams,
Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Shannon Nelson <shannon.nelson@intel.com>
Addresses a few code format issues that have crept in over time.
Change-Id: I1a62cbd16b29a218a933b0f7176abe748f9615e8
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_adminq.c | 4 ++--
drivers/net/ethernet/intel/i40e/i40e_common.c | 1 +
drivers/net/ethernet/intel/i40e/i40e_type.h | 8 ++++----
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 3ee5323..18a768f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -672,7 +672,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
/* AQ designers suggest use of head for better
* timing reliability than DD bit
*/
- return (rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use);
+ return rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use;
}
@@ -682,7 +682,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
* @desc: prefilled descriptor describing the command (non DMA mem)
* @buff: buffer to use for indirect commands
* @buff_size: size of buffer for indirect commands
- * @opaque: pointer to info to be used in async cleanup
+ * @cmd_details: pointer to command details structure
*
* This is the main send command driver routine for the Admin Queue send
* queue. It runs the queue, cleans the queue, etc
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 7e34de1..d564910 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -406,6 +406,7 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
}
i40e_clear_pxe_mode(hw);
+
return 0;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 4ac712e..bcf0317 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -89,7 +89,7 @@ typedef void (*I40E_ADMINQ_CALLBACK)(struct i40e_hw *, struct i40e_aq_desc *);
#define I40E_QTX_CTL_VF_QUEUE 0x0
#define I40E_QTX_CTL_PF_QUEUE 0x2
-/* debug masks */
+/* debug masks - set these bits in hw->debug_mask to control output */
enum i40e_debug_mask {
I40E_DEBUG_INIT = 0x00000001,
I40E_DEBUG_RELEASE = 0x00000002,
@@ -103,10 +103,10 @@ enum i40e_debug_mask {
I40E_DEBUG_DCB = 0x00000400,
I40E_DEBUG_DIAG = 0x00000800,
- I40E_DEBUG_AQ_MESSAGE = 0x01000000, /* for i40e_debug() */
+ I40E_DEBUG_AQ_MESSAGE = 0x01000000,
I40E_DEBUG_AQ_DESCRIPTOR = 0x02000000,
I40E_DEBUG_AQ_DESC_BUFFER = 0x04000000,
- I40E_DEBUG_AQ_COMMAND = 0x06000000, /* for i40e_debug_aq() */
+ I40E_DEBUG_AQ_COMMAND = 0x06000000,
I40E_DEBUG_AQ = 0x0F000000,
I40E_DEBUG_USER = 0xF0000000,
@@ -520,7 +520,7 @@ enum i40e_rx_desc_status_bits {
#define I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT I40E_RX_DESC_STATUS_TSYNVALID_SHIFT
#define I40E_RXD_QW1_STATUS_TSYNVALID_MASK (0x1UL << \
- I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
+ I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
enum i40e_rx_desc_fltstat_values {
I40E_RX_DESC_FLTSTAT_NO_DATA = 0,
--
1.8.3.1
^ permalink raw reply related
* [net-next v2 13/15] i40e: Enable/Disable PF switch LB on SR-IOV configure changes
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem; +Cc: Greg Rose, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Greg Rose <gregory.v.rose@intel.com>
The PF VSI was never updated to enable or disable internal switch loopback
when VFs were created or destroyed via the sysfs interface. Add some
helper functions to take care of that.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 76 +++++++++++++++++++++-
1 file changed, 74 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 5c99164..efb9a24 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -716,6 +716,76 @@ static bool i40e_vfs_are_assigned(struct i40e_pf *pf)
return false;
}
+#ifdef CONFIG_PCI_IOV
+
+/**
+ * i40e_enable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * enable switch loop back or die - no point in a return value
+ **/
+static void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
+{
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_vsi_context ctxt;
+ int aq_ret;
+
+ ctxt.seid = pf->main_vsi_seid;
+ ctxt.pf_num = pf->hw.pf_id;
+ ctxt.vf_num = 0;
+ aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+ __func__, aq_ret, pf->hw.aq.asq_last_status);
+ return;
+ }
+ ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+ ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+ ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+ aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s: update vsi switch failed, aq_err=%d\n",
+ __func__, vsi->back->hw.aq.asq_last_status);
+ }
+}
+#endif
+
+/**
+ * i40e_disable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * disable switch loop back or die - no point in a return value
+ **/
+static void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
+{
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_vsi_context ctxt;
+ int aq_ret;
+
+ ctxt.seid = pf->main_vsi_seid;
+ ctxt.pf_num = pf->hw.pf_id;
+ ctxt.vf_num = 0;
+ aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+ __func__, aq_ret, pf->hw.aq.asq_last_status);
+ return;
+ }
+ ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+ ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+ ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+ aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s: update vsi switch failed, aq_err=%d\n",
+ __func__, vsi->back->hw.aq.asq_last_status);
+ }
+}
/**
* i40e_free_vfs
@@ -759,10 +829,11 @@ void i40e_free_vfs(struct i40e_pf *pf)
bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32;
wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
}
- }
- else
+ i40e_disable_pf_switch_lb(pf);
+ } else {
dev_warn(&pf->pdev->dev,
"unable to disable SR-IOV because VFs are assigned.\n");
+ }
/* Re-enable interrupt 0. */
i40e_irq_dynamic_enable_icr0(pf);
@@ -816,6 +887,7 @@ static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
pf->vf = vfs;
pf->num_alloc_vfs = num_alloc_vfs;
+ i40e_enable_pf_switch_lb(pf);
err_alloc:
if (ret)
i40e_free_vfs(pf);
--
1.8.3.1
^ permalink raw reply related
* [net-next v2 14/15] i40e: remove redundant AQ enable
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem
Cc: Kamil Krawczyk, netdev, gospo, sassmann, Jesse Brandeburg,
Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Kamil Krawczyk <kamil.krawczyk@intel.com>
The admin queue length register is updated in
config_a<sq|rq>_regs functions. We should not update it again,
as we will trigger firmware to init the AQ again. In this case
firmware will lose the information about the AQ Rx tail position
and will see Rx queue as full (no free desc for FW to use).
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_adminq.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 18a768f..c87dc15 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -957,20 +957,14 @@ clean_arq_element_out:
static void i40e_resume_aq(struct i40e_hw *hw)
{
- u32 reg = 0;
-
/* Registers are reset after PF reset */
hw->aq.asq.next_to_use = 0;
hw->aq.asq.next_to_clean = 0;
i40e_config_asq_regs(hw);
- reg = hw->aq.num_asq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
- wr32(hw, hw->aq.asq.len, reg);
hw->aq.arq.next_to_use = 0;
hw->aq.arq.next_to_clean = 0;
i40e_config_arq_regs(hw);
- reg = hw->aq.num_arq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
- wr32(hw, hw->aq.arq.len, reg);
}
--
1.8.3.1
^ permalink raw reply related
* [net-next v2 15/15] i40e: correctly setup ARQ descriptors
From: Jeff Kirsher @ 2014-01-08 6:07 UTC (permalink / raw)
To: davem
Cc: Mitch Williams, netdev, gospo, sassmann, Jesse Brandeburg,
Jeff Kirsher
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
When cleaning descriptors, we must set up ALL fields, not just the DMA
address. The initial setup does this correctly, but not the cleanup
code, so the firmware would process the ring exactly once and then fail.
Change-ID: I2930b83c76194b3016a8ac0fa693f9a573995640
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_adminq.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index c87dc15..2b32084 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -933,6 +933,11 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
* size
*/
bi = &hw->aq.arq.r.arq_bi[ntc];
+ memset((void *)desc, 0, sizeof(struct i40e_aq_desc));
+
+ desc->flags = cpu_to_le16(I40E_AQ_FLAG_BUF);
+ if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF)
+ desc->flags |= cpu_to_le16(I40E_AQ_FLAG_LB);
desc->datalen = cpu_to_le16((u16)bi->size);
desc->params.external.addr_high = cpu_to_le32(upper_32_bits(bi->pa));
desc->params.external.addr_low = cpu_to_le32(lower_32_bits(bi->pa));
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next v3 1/3] ipv4: introduce ip_dst_mtu_secure and protect forwarding path against pmtu spoofing
From: Hannes Frederic Sowa @ 2014-01-08 6:13 UTC (permalink / raw)
To: David Miller
Cc: netdev, eric.dumazet, johnwheffner, steffen.klassert, fweimer
In-Reply-To: <20140108.010213.884915830982848289.davem@davemloft.net>
On Wed, Jan 08, 2014 at 01:02:13AM -0500, David Miller wrote:
> From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Date: Wed, 8 Jan 2014 06:02:25 +0100
>
> > Hi David!
> >
> > On Tue, Jan 07, 2014 at 07:13:14PM -0500, David Miller wrote:
> >> From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> >> Date: Mon, 6 Jan 2014 09:48:27 +0100
> >>
> >> > +ip_forward_use_pmtu - BOOLEAN
> >> > + By default we don't trust protocol path MTUs while forwarding
> >> > + because they could be easily forged and can lead to unwanted
> >> > + fragmentation by the router.
> >> > + You only need to enable this if you have user-space software
> >> > + which tries to discover path mtus by itself and depends on the
> >> > + kernel honoring this information. This is normally not the
> >> > + case.
> >> > + Default: 0 (disabled)
> >> > + Possible values:
> >> > + 0 - disabled
> >> > + 1 - enabled
> >>
> >> You made this default to off, great, but the description text still says
> >> that we don't trust PMTU information by default :-)
> >
> > Hm, sorry, but I don't see the contradiction.
>
> You say "By default we don't trust protocol path MTUs", but if the
> default value of ip_forward_use_pmtu is zero, we in fact do.
I am sorry.. maybe I am just stupid?
static inline unsigned int ip_dst_mtu_secure(const struct dst_entry *dst,
bool forwarding)
{
struct net *net = dev_net(dst->dev);
if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
dst_metric_locked(dst, RTAX_MTU) ||
!forwarding)
return dst_mtu(dst);
return min(dst->dev->mtu, IP_MAX_MTU);
}
The path with dst_mtu is the patch where I want to use the path
mtu information. It only gets reached either by locked route,
sysctl_ip_fwd_use_pmtu not zero or we are not forwarding the packet.
So, if fwd_use_pmtu is zero, either the mtu must be locked or we are
not forwarding the packet to use the path mtu.
Sorry for the confusion,
Hannes
^ permalink raw reply
* Re: [PATCH net-next v2 3/4] virtio-net: auto-tune mergeable rx buffer size for improved performance
From: Jason Wang @ 2014-01-08 6:23 UTC (permalink / raw)
To: Michael Dalton, David S. Miller
Cc: netdev, Eric Dumazet, virtualization, Michael S. Tsirkin
In-Reply-To: <1389072355-20666-3-git-send-email-mwdalton@google.com>
On 01/07/2014 01:25 PM, Michael Dalton wrote:
> Commit 2613af0ed18a ("virtio_net: migrate mergeable rx buffers to page frag
> allocators") changed the mergeable receive buffer size from PAGE_SIZE to
> MTU-size, introducing a single-stream regression for benchmarks with large
> average packet size. There is no single optimal buffer size for all
> workloads. For workloads with packet size <= MTU bytes, MTU + virtio-net
> header-sized buffers are preferred as larger buffers reduce the TCP window
> due to SKB truesize. However, single-stream workloads with large average
> packet sizes have higher throughput if larger (e.g., PAGE_SIZE) buffers
> are used.
>
> This commit auto-tunes the mergeable receiver buffer packet size by
> choosing the packet buffer size based on an EWMA of the recent packet
> sizes for the receive queue. Packet buffer sizes range from MTU_SIZE +
> virtio-net header len to PAGE_SIZE. This improves throughput for
> large packet workloads, as any workload with average packet size >=
> PAGE_SIZE will use PAGE_SIZE buffers.
>
> These optimizations interact positively with recent commit
> ba275241030c ("virtio-net: coalesce rx frags when possible during rx"),
> which coalesces adjacent RX SKB fragments in virtio_net. The coalescing
> optimizations benefit buffers of any size.
>
> Benchmarks taken from an average of 5 netperf 30-second TCP_STREAM runs
> between two QEMU VMs on a single physical machine. Each VM has two VCPUs
> with all offloads & vhost enabled. All VMs and vhost threads run in a
> single 4 CPU cgroup cpuset, using cgroups to ensure that other processes
> in the system will not be scheduled on the benchmark CPUs. Trunk includes
> SKB rx frag coalescing.
>
> net-next w/ virtio_net before 2613af0ed18a (PAGE_SIZE bufs): 14642.85Gb/s
> net-next (MTU-size bufs): 13170.01Gb/s
> net-next + auto-tune: 14555.94Gb/s
>
> Jason Wang also reported a throughput increase on mlx4 from 22Gb/s
> using MTU-sized buffers to about 26Gb/s using auto-tuning.
>
> Signed-off-by: Michael Dalton <mwdalton@google.com>
> ---
> v2: Add per-receive queue metadata ring to track precise truesize for
> mergeable receive buffers. Remove all truesize approximation. Never
> try to fill a full RX ring (required for metadata ring in v2).
>
> drivers/net/virtio_net.c | 145 ++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 107 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 526dfd8..f6e1ee0 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -26,6 +26,7 @@
> #include <linux/if_vlan.h>
> #include <linux/slab.h>
> #include <linux/cpu.h>
> +#include <linux/average.h>
>
> static int napi_weight = NAPI_POLL_WEIGHT;
> module_param(napi_weight, int, 0444);
> @@ -36,11 +37,15 @@ module_param(gso, bool, 0444);
>
> /* FIXME: MTU in config. */
> #define GOOD_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
> -#define MERGE_BUFFER_LEN (ALIGN(GOOD_PACKET_LEN + \
> - sizeof(struct virtio_net_hdr_mrg_rxbuf), \
> - L1_CACHE_BYTES))
> #define GOOD_COPY_LEN 128
>
> +/* Weight used for the RX packet size EWMA. The average packet size is used to
> + * determine the packet buffer size when refilling RX rings. As the entire RX
> + * ring may be refilled at once, the weight is chosen so that the EWMA will be
> + * insensitive to short-term, transient changes in packet size.
> + */
> +#define RECEIVE_AVG_WEIGHT 64
> +
> #define VIRTNET_DRIVER_VERSION "1.0.0"
>
> struct virtnet_stats {
> @@ -65,11 +70,30 @@ struct send_queue {
> char name[40];
> };
>
> +/* Per-packet buffer context for mergeable receive buffers. */
> +struct mergeable_receive_buf_ctx {
> + /* Packet buffer base address. */
> + void *buf;
> +
> + /* Original size of the packet buffer for use in SKB truesize. Does not
> + * include any padding space used to avoid internal fragmentation.
> + */
> + unsigned int truesize;
> +};
> +
> /* Internal representation of a receive virtqueue */
> struct receive_queue {
> /* Virtqueue associated with this receive_queue */
> struct virtqueue *vq;
>
> + /* Circular buffer of mergeable rxbuf contexts. */
> + struct mergeable_receive_buf_ctx *mrg_buf_ctx;
> +
> + /* Number of elements & head index of mrg_buf_ctx. Size must be
> + * equal to the associated virtqueue's vring size.
> + */
> + unsigned int mrg_buf_ctx_size, mrg_buf_ctx_head;
> +
> struct napi_struct napi;
>
> /* Number of input buffers, and max we've ever had. */
> @@ -78,6 +102,9 @@ struct receive_queue {
> /* Chain pages by the private ptr. */
> struct page *pages;
>
> + /* Average packet length for mergeable receive buffers. */
> + struct ewma mrg_avg_pkt_len;
> +
> /* Page frag for packet buffer allocation. */
> struct page_frag alloc_frag;
>
> @@ -327,32 +354,32 @@ err:
>
> static struct sk_buff *receive_mergeable(struct net_device *dev,
> struct receive_queue *rq,
> - void *buf,
> + struct mergeable_receive_buf_ctx *ctx,
> unsigned int len)
> {
> - struct skb_vnet_hdr *hdr = buf;
> + struct skb_vnet_hdr *hdr = ctx->buf;
> int num_buf = hdr->mhdr.num_buffers;
> - struct page *page = virt_to_head_page(buf);
> - int offset = buf - page_address(page);
> - unsigned int truesize = max_t(unsigned int, len, MERGE_BUFFER_LEN);
> + struct page *page = virt_to_head_page(ctx->buf);
> + int offset = ctx->buf - page_address(page);
> + unsigned int truesize = max(len, ctx->truesize);
This looks unnecessary, we've already had precise truesize for this
buffer. ctx->trusize should be always greater or equal to len here.
> +
> struct sk_buff *head_skb = page_to_skb(rq, page, offset, len, truesize);
> struct sk_buff *curr_skb = head_skb;
>
> if (unlikely(!curr_skb))
> goto err_skb;
> -
> while (--num_buf) {
> int num_skb_frags;
>
> - buf = virtqueue_get_buf(rq->vq, &len);
> - if (unlikely(!buf)) {
> + ctx = virtqueue_get_buf(rq->vq, &len);
> + if (unlikely(!ctx)) {
> pr_debug("%s: rx error: %d buffers out of %d missing\n",
> dev->name, num_buf, hdr->mhdr.num_buffers);
> dev->stats.rx_length_errors++;
> goto err_buf;
> }
>
> - page = virt_to_head_page(buf);
> + page = virt_to_head_page(ctx->buf);
> --rq->num;
>
> num_skb_frags = skb_shinfo(curr_skb)->nr_frags;
> @@ -369,13 +396,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> head_skb->truesize += nskb->truesize;
> num_skb_frags = 0;
> }
> - truesize = max_t(unsigned int, len, MERGE_BUFFER_LEN);
> + truesize = max(len, ctx->truesize);
And this.
> if (curr_skb != head_skb) {
> head_skb->data_len += len;
> head_skb->len += len;
> head_skb->truesize += truesize;
> }
> - offset = buf - page_address(page);
> + offset = ctx->buf - page_address(page);
> if (skb_can_coalesce(curr_skb, num_skb_frags, page, offset)) {
> put_page(page);
> skb_coalesce_rx_frag(curr_skb, num_skb_frags - 1,
> @@ -386,19 +413,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> }
> }
>
> + ewma_add(&rq->mrg_avg_pkt_len, head_skb->len);
> return head_skb;
>
> err_skb:
> put_page(page);
> while (--num_buf) {
> - buf = virtqueue_get_buf(rq->vq, &len);
> - if (unlikely(!buf)) {
> + ctx = virtqueue_get_buf(rq->vq, &len);
> + if (unlikely(!ctx)) {
> pr_debug("%s: rx error: %d buffers missing\n",
> dev->name, num_buf);
> dev->stats.rx_length_errors++;
> break;
> }
> - page = virt_to_head_page(buf);
> + page = virt_to_head_page(ctx->buf);
> put_page(page);
> --rq->num;
> }
> @@ -419,12 +447,14 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
> if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
> pr_debug("%s: short packet %i\n", dev->name, len);
> dev->stats.rx_length_errors++;
> - if (vi->mergeable_rx_bufs)
> - put_page(virt_to_head_page(buf));
> - else if (vi->big_packets)
> + if (vi->mergeable_rx_bufs) {
> + struct mergeable_receive_buf_ctx *ctx = buf;
> + put_page(virt_to_head_page(ctx->buf));
> + } else if (vi->big_packets) {
> give_pages(rq, buf);
> - else
> + } else {
> dev_kfree_skb(buf);
> + }
> return;
> }
>
> @@ -572,29 +602,43 @@ static int add_recvbuf_big(struct receive_queue *rq, gfp_t gfp)
>
> static int add_recvbuf_mergeable(struct receive_queue *rq, gfp_t gfp)
> {
> + const unsigned int ring_size = rq->mrg_buf_ctx_size;
> + const size_t hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
> struct page_frag *alloc_frag = &rq->alloc_frag;
> - char *buf;
> + struct mergeable_receive_buf_ctx *ctx;
> int err;
> unsigned int len, hole;
>
> - if (unlikely(!skb_page_frag_refill(MERGE_BUFFER_LEN, alloc_frag, gfp)))
> + len = hdr_len + clamp_t(unsigned int, ewma_read(&rq->mrg_avg_pkt_len),
> + GOOD_PACKET_LEN, PAGE_SIZE - hdr_len);
> + len = ALIGN(len, L1_CACHE_BYTES);
> + if (unlikely(!skb_page_frag_refill(len, alloc_frag, gfp)))
> return -ENOMEM;
> - buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
> +
> + ctx = &rq->mrg_buf_ctx[rq->mrg_buf_ctx_head];
> + ctx->buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
> + ctx->truesize = len;
> get_page(alloc_frag->page);
> - len = MERGE_BUFFER_LEN;
> alloc_frag->offset += len;
> hole = alloc_frag->size - alloc_frag->offset;
> - if (hole < MERGE_BUFFER_LEN) {
> + if (hole < len) {
> + /* To avoid internal fragmentation, if there is very likely not
> + * enough space for another buffer, add the remaining space to
> + * the current buffer. This extra space is not included in
> + * ctx->truesize.
> + */
What's the reason that this extra space is not accounted for truesize?
> len += hole;
> alloc_frag->offset += hole;
> }
>
> - sg_init_one(rq->sg, buf, len);
> - err = virtqueue_add_inbuf(rq->vq, rq->sg, 1, buf, gfp);
> - if (err < 0)
> - put_page(virt_to_head_page(buf));
> -
> - return err;
> + sg_init_one(rq->sg, ctx->buf, len);
> + err = virtqueue_add_inbuf(rq->vq, rq->sg, 1, ctx, gfp);
> + if (err < 0) {
> + put_page(virt_to_head_page(ctx->buf));
> + return err;
Should we also roll back the frag offset added above to avoid leaking frags?
> + }
> + rq->mrg_buf_ctx_head = (rq->mrg_buf_ctx_head + 1) & (ring_size - 1);
> + return 0;
> }
>
> /*
> @@ -610,6 +654,9 @@ static bool try_fill_recv(struct receive_queue *rq, gfp_t gfp)
> int err;
> bool oom;
>
> + /* Do not attempt to add a buffer if the RX ring is full. */
> + if (unlikely(!rq->vq->num_free))
> + return true;
I haven't figured out why this is needed. It seems safe for
virtqueue_add_inbuf() just fail in add_recv_xx()?
> gfp |= __GFP_COLD;
> do {
> if (vi->mergeable_rx_bufs)
> @@ -1354,8 +1401,10 @@ static void virtnet_free_queues(struct virtnet_info *vi)
> {
> int i;
>
> - for (i = 0; i < vi->max_queue_pairs; i++)
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> netif_napi_del(&vi->rq[i].napi);
> + kfree(vi->rq[i].mrg_buf_ctx);
> + }
>
> kfree(vi->rq);
> kfree(vi->sq);
> @@ -1394,12 +1443,14 @@ static void free_unused_bufs(struct virtnet_info *vi)
> struct virtqueue *vq = vi->rq[i].vq;
>
> while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
> - if (vi->mergeable_rx_bufs)
> - put_page(virt_to_head_page(buf));
> - else if (vi->big_packets)
> + if (vi->mergeable_rx_bufs) {
> + struct mergeable_receive_buf_ctx *ctx = buf;
> + put_page(virt_to_head_page(ctx->buf));
> + } else if (vi->big_packets) {
> give_pages(&vi->rq[i], buf);
> - else
> + } else {
> dev_kfree_skb(buf);
> + }
> --vi->rq[i].num;
> }
> BUG_ON(vi->rq[i].num != 0);
> @@ -1509,6 +1560,7 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
> napi_weight);
>
> sg_init_table(vi->rq[i].sg, ARRAY_SIZE(vi->rq[i].sg));
> + ewma_init(&vi->rq[i].mrg_avg_pkt_len, 1, RECEIVE_AVG_WEIGHT);
> sg_init_table(vi->sq[i].sg, ARRAY_SIZE(vi->sq[i].sg));
> }
>
> @@ -1522,7 +1574,8 @@ err_sq:
>
> static int init_vqs(struct virtnet_info *vi)
> {
> - int ret;
> + struct virtio_device *vdev = vi->vdev;
> + int i, ret;
>
> /* Allocate send & receive queues */
> ret = virtnet_alloc_queues(vi);
> @@ -1533,12 +1586,28 @@ static int init_vqs(struct virtnet_info *vi)
> if (ret)
> goto err_free;
>
> + if (vi->mergeable_rx_bufs) {
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> + struct receive_queue *rq = &vi->rq[i];
> + rq->mrg_buf_ctx_size = virtqueue_get_vring_size(rq->vq);
> + rq->mrg_buf_ctx = kmalloc(sizeof(*rq->mrg_buf_ctx) *
> + rq->mrg_buf_ctx_size,
> + GFP_KERNEL);
> + if (!rq->mrg_buf_ctx) {
> + ret = -ENOMEM;
> + goto err_del_vqs;
> + }
> + }
> + }
> +
> get_online_cpus();
> virtnet_set_affinity(vi);
> put_online_cpus();
>
> return 0;
>
> +err_del_vqs:
> + vdev->config->del_vqs(vdev);
> err_free:
> virtnet_free_queues(vi);
> err:
^ permalink raw reply
* Re: [PATCH net-next v2 4/4] virtio-net: initial debugfs support, export mergeable rx buffer size
From: Jason Wang @ 2014-01-08 6:34 UTC (permalink / raw)
To: Michael Dalton, David S. Miller
Cc: netdev, Eric Dumazet, virtualization, Michael S. Tsirkin
In-Reply-To: <1389072355-20666-4-git-send-email-mwdalton@google.com>
On 01/07/2014 01:25 PM, Michael Dalton wrote:
> Add initial support for debugfs to virtio-net. Each virtio-net network
> device will have a directory under /virtio-net in debugfs. The
> per-network device directory will contain one sub-directory per active,
> enabled receive queue. If mergeable receive buffers are enabled, each
> receive queue directory will contain a read-only file that returns the
> current packet buffer size for the receive queue.
>
> Signed-off-by: Michael Dalton <mwdalton@google.com>
This looks more complicated than expected. How about just adding an
entry in sysfs onto the existed network class device which looks more
simpler?
^ permalink raw reply
* Re: [PATCH net-next v3 1/3] ipv4: introduce ip_dst_mtu_secure and protect forwarding path against pmtu spoofing
From: David Miller @ 2014-01-08 6:49 UTC (permalink / raw)
To: hannes; +Cc: netdev, eric.dumazet, johnwheffner, steffen.klassert, fweimer
In-Reply-To: <20140108061320.GA9007@order.stressinduktion.org>
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date: Wed, 8 Jan 2014 07:13:20 +0100
> I am sorry.. maybe I am just stupid?
I thought I was clear about wanting the new behavior to _NOT_ be the
default. I thought we agreed on this.
^ permalink raw reply
* Re: [PATCH] unix: show socket peer if no addr is given in /proc/net/unix
From: Masatake YAMATO @ 2014-01-08 6:50 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20140108.010043.2192738470649350132.davem@davemloft.net>
Thank you for reviwing.
I'll use netlink diag facility.
Masatake YAMATO
On Wed, 08 Jan 2014 01:00:43 -0500 (EST), David Miller <davem@davemloft.net> wrote:
> From: Masatake YAMATO <yamato@redhat.com>
> Date: Wed, 8 Jan 2014 14:18:08 +0900
>
>> Path field of /proc/net/unix is empty if an address is not given
>> to a socket. Typical way to create such socket is calling
>> socketpair. The empty fields make it difficult to understand the
>> communication between processes. e.g. lsof cannot resolve the role of
>> file descriptors well.
>>
>> This patch fills the empty fields with unix_peer.
>>
>> Signed-off-by: Masatake YAMATO <yamato@redhat.com>
>
> You cannot change the format of a procfs file without potentially
> breaking some application which might interpret the output.
>
> In this case an application might be looking for an empty field
> as meaning the sockhad has no given address.
>
> I cannot apply this patch. People have repeatedly tried making
> changes to these networking socket procfs files, and I really wish
> people would stop trying to do so.
>
> If you want specific pieces of new information, extend the socket
> dumping facility that is actually extensible in a way which will not
> break existing applications, and that's netlink.
^ permalink raw reply
* Re: [net-next v2 00/15][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2014-01-08 6:50 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, gospo, sassmann
In-Reply-To: <1389161256-24599-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 7 Jan 2014 22:07:21 -0800
> This series contains updates to i40e only.
...
> v2:
> - Added blank lines after local variable declarations to patch 01
> as suggested by David Miller
> - Used the suggested memset() line in patch 15 as suggested by David
> Miller
Pulled, thanks Jeff.
^ permalink raw reply
* RE: [PATCH net] bnx2x: prevent WARN during driver unload
From: Yuval Mintz @ 2014-01-08 7:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org, Dmitry Kravkov, Ariel Elior
In-Reply-To: <20140108.010140.283557207092663086.davem@davemloft.net>
> >>
> >> > + fp->state &= BNX2X_FP_STATE_DISABLED;
> >> ...
> >> > + fp->state &= BNX2X_FP_STATE_DISABLED;
> >>
> >> Surely you mean "&= ~BNX2X_FP_STATE_DISABLED" here?
> >
> > Thought the comment above the code was sufficient to show
> > this is intentional.
> >
> > The BNX2X_FP_STATE_DISABLED will cause BNX@X_FP_LOCKED to
> > Be true. The bnx2x_fp_ll_disable() works by setting this bit even
> > when BNX2X_FP_OWNED is set; while other flows release the lock
> > the will clear the bit indications except for the disabled indication,
> > so that no other flow could take the lock after it was disabled,
> > and the loop of bnx2x_fp_ll_disable() calls will eventually return true.
>
> This bit handling is completely unintuitive.
>
> The way a boolean state works is you manage it by setting it when
> a condition arises, and clear it when a condition goes away.
True; but we didn't reach this bit of intuitive code on our own -
this is practically a porting of 27d9ce3f "ixgbe: fix qv_lock_napi
call in ixgbe_napi_disable_all" into the bnx2x driver.
^ permalink raw reply
* Re: [B.A.T.M.A.N.] [PATCH v3.6 06/19] batman-adv: use batadv_compare_eth for concise
From: Antonio Quartulli @ 2014-01-08 7:06 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking,
Marek Lindner, Simon Wunderlich, David S. Miller, Netdev,
linux-kernel@vger.kernel.org
In-Reply-To: <52CCBDA9.8090205@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 754 bytes --]
On 08/01/14 03:53, Ding Tianhong wrote:
> It is better to use batadv_compate_eth instead of memcpy for
> concise style.
>
> Cc: Marek Lindner <mareklindner@neomailbox.ch>
> Cc: Simon Wunderlich <sw@simonwunderlich.de>
> Cc: Antonio Quartulli <antonio@meshcoding.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: b.a.t.m.a.n@lists.open-mesh.org
> Cc: netdev@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Tan Xiaojun <tanxiaojun@huawei.com>
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> Acked-by: Antonio Quartulli <antonio@meshcoding.com>
Am I wrong or this patch has already been merged in net-next (together
with other patches from this series)?
Regards,
--
Antonio Quartulli
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v3 1/3] ipv4: introduce ip_dst_mtu_secure and protect forwarding path against pmtu spoofing
From: Hannes Frederic Sowa @ 2014-01-08 7:10 UTC (permalink / raw)
To: David Miller
Cc: netdev, eric.dumazet, johnwheffner, steffen.klassert, fweimer
In-Reply-To: <20140108.014940.1139765295618203197.davem@davemloft.net>
On Wed, Jan 08, 2014 at 01:49:40AM -0500, David Miller wrote:
> From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Date: Wed, 8 Jan 2014 07:13:20 +0100
>
> > I am sorry.. maybe I am just stupid?
>
> I thought I was clear about wanting the new behavior to _NOT_ be the
> default. I thought we agreed on this.
Sorry for not making it clear enough that I changed my mind on this.
I thought that mentioning it in the changelog and after the last
discussion, where I again said that in my opinion this should always be
default behavior unless someone uses a user-space software to discover
MTUs, which normally won't be the case. This is RFC specified and I
never heard a reason why we should do path mtu discovering on a router.
(local connections will still do correct path mtu discovering)
Additionally, given the possible attacks on fragment reassembly, I really
see no point in keeping to use the path mtu for forwarding. The attack
is a new form of the Kaminsky attack on DNS and I think, after it was
shown possible, that this is serious.
I thought I brought all needed arguments last time to make this switch,
I am sorry that I was not stressing these points enough.
I am pretty sure distributions will switch the setting to the mode where
we don't honour path mtu information. This is in fact the only sensible
thing to do.
I personally don't mind the default, I just want the possibility that this can
be documented and people can act accordingly. So I am open for discussion on
the default, but have a strong opinion (and always had) towards not using path
mtu values on forwarding.
Thank you,
Hannes
^ permalink raw reply
* Re: [PATCH net-next v3 1/3] ipv4: introduce ip_dst_mtu_secure and protect forwarding path against pmtu spoofing
From: Hannes Frederic Sowa @ 2014-01-08 7:14 UTC (permalink / raw)
To: netdev, eric.dumazet, davem, johnwheffner, steffen.klassert,
fweimer
In-Reply-To: <20140106084827.GA5766@order.stressinduktion.org>
On Mon, Jan 06, 2014 at 09:48:27AM +0100, Hannes Frederic Sowa wrote:
> v3)
> * forward_use_pmtu default enabled again
Okay, I fucked it up. So sorry...
^ permalink raw reply
* [PATCH net 0/2] bonding: ensure that the TSO being set on bond master
From: Ding Tianhong @ 2014-01-08 7:28 UTC (permalink / raw)
To: Jay Vosburgh, Veaceslav Falico, Eric Dumazet, David S. Miller,
Netdev
The commit b0ce3508(bonding: allow TSO being set on bonding master)
has make the TSO being set for bond dev, but in some situation, if
the slave did not have the NETIF_F_SG features, the bond master will
miss the TSO features in netdev_fix_features because the TSO is
depended on SG. So I have to add SG and TSO features on bond master
together.
The function netdev_add_tso_features() was only be used for bonding,
so no need to export it in netdevice.h, remove it and add it to bonding.
Ding Tianhong (2):
bonding: ensure that the TSO being set on bond master
net: remove the unused function netdev_add_tso_features()
drivers/net/bonding/bond_main.c | 16 +++++++++++++++-
include/linux/netdevice.h | 10 ----------
2 files changed, 15 insertions(+), 11 deletions(-)
--
1.8.0
^ permalink raw reply
* [PATCH net 1/2] bonding: ensure that the TSO being set on bond master
From: Ding Tianhong @ 2014-01-08 7:28 UTC (permalink / raw)
To: Jay Vosburgh, Veaceslav Falico, Eric Dumazet, David S. Miller,
Netdev
The commit b0ce3508(bonding: allow TSO being set on bonding master)
has make the TSO being set for bond dev, but in some situation, if
the slave did not have the NETIF_F_SG features, the bond master will
miss the TSO features in netdev_fix_features because the TSO is
depended on SG. So I have to add SG and TSO features on bond master
together.
The netdev_add_tso_features() was only used for bonding, so I think no
need to export it to netdevice.h.
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
drivers/net/bonding/bond_main.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e06c445..8ce67ed 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1045,6 +1045,20 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev)
/*---------------------------------- IOCTL ----------------------------------*/
+/* Allow TSO being used on stacked device:
+ * Performing the GSO segmentation before last device
+ * is a performance improvement.
+ * The TSO is depended on SG, so add SG and TSO together,
+ * otherwise the netdev_fix_features() may clean the TSO.
+ */
+static netdev_features_t bond_add_tso_features(netdev_features_t features,
+ netdev_features_t mask)
+{
+ return netdev_increment_features(features,
+ NETIF_F_ALL_TSO | NETIF_F_SG,
+ mask);
+}
+
static netdev_features_t bond_fix_features(struct net_device *dev,
netdev_features_t features)
{
@@ -1068,7 +1082,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
slave->dev->features,
mask);
}
- features = netdev_add_tso_features(features, mask);
+ features = bond_add_tso_features(features, mask);
return features;
}
--
1.8.0
^ permalink raw reply related
* [PATCH net 2/2] net: remove the unused function netdev_add_tso_features()
From: Ding Tianhong @ 2014-01-08 7:28 UTC (permalink / raw)
To: Jay Vosburgh, Veaceslav Falico, Eric Dumazet, David S. Miller,
Netdev
The function is only used for bonding and the bond has another
function bond_add_tso_features() to instead of it, so remove it.
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
include/linux/netdevice.h | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 51c0fe2..183cd8e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2985,16 +2985,6 @@ static inline netdev_features_t netdev_get_wanted_features(
netdev_features_t netdev_increment_features(netdev_features_t all,
netdev_features_t one, netdev_features_t mask);
-/* Allow TSO being used on stacked device :
- * Performing the GSO segmentation before last device
- * is a performance improvement.
- */
-static inline netdev_features_t netdev_add_tso_features(netdev_features_t features,
- netdev_features_t mask)
-{
- return netdev_increment_features(features, NETIF_F_ALL_TSO, mask);
-}
-
int __netdev_update_features(struct net_device *dev);
void netdev_update_features(struct net_device *dev);
void netdev_change_features(struct net_device *dev);
--
1.8.0
^ permalink raw reply related
* Re: [PATCH v3.6 06/19] batman-adv: use batadv_compare_eth for concise
From: Ding Tianhong @ 2014-01-08 7:32 UTC (permalink / raw)
To: Antonio Quartulli,
The list for a Better Approach To Mobile Ad-hoc Networking,
Marek Lindner, Simon Wunderlich, David S. Miller, Netdev,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <52CCF906.7000400-x4xJYDvStAgysxA8WJXlww@public.gmane.org>
On 2014/1/8 15:06, Antonio Quartulli wrote:
> On 08/01/14 03:53, Ding Tianhong wrote:
>> It is better to use batadv_compate_eth instead of memcpy for
>> concise style.
>>
>> Cc: Marek Lindner <mareklindner-rVWd3aGhH2z5bpWLKbzFeg@public.gmane.org>
>> Cc: Simon Wunderlich <sw-2YrNx6rUIHYiY0qSoAWiAoQuADTiUCJX@public.gmane.org>
>> Cc: Antonio Quartulli <antonio-x4xJYDvStAgysxA8WJXlww@public.gmane.org>
>> Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
>> Cc: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r@public.gmane.org
>> Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Tan Xiaojun <tanxiaojun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> Acked-by: Antonio Quartulli <antonio-x4xJYDvStAgysxA8WJXlww@public.gmane.org>
>
> Am I wrong or this patch has already been merged in net-next (together
> with other patches from this series)?
>
>
>
> Regards,
>
>
Yes, it is already in net-next, so miss it, thanks.
Regards
Ding
^ permalink raw reply
* [net-next 0/7] Intel Wired LAN Driver Updates
From: Aaron Brown @ 2014-01-08 7:40 UTC (permalink / raw)
To: davem; +Cc: Aaron Brown, netdev, gospo, sassmann
This series contains add Live Error Recovery (LER) support to the ixgbe
driver. This support also improves behavior in Thunderbolt environments.
This involves checking all register reads for a value of all ones and when
that is seen, to read the status register, which should never properly
return all ones, to confirm whether the received value was correct. When
this detects a removal, the hw_addr field is cleared to indicate the
removal. This then blocks subsequent access to the device registers.
All register access macros have been changed to static inline functions
and all register accesses now use them.
The __IXGBE_DOWN bit is no longer overloaded to also mean that device
removal has been initiated. Now the bit can be used to protect ixgbe_down
from multiple entry via test_and_set_bit. A needed smp_mb__before_clear_bit
was also added.
Mark Rustad (7):
1/7 ixbge: Protect ixgbe_down with __IXGBE_DOWN bit
2/7 ixgbe: Indicate removal state explicitly
3/7 ixgbe: Use static inlines instead of macros
4/7 ixgbe: Make ethtool register test use accessors
5/7 ixgbe: Check register reads for adapter removal
6/7 ixgbe: Check for adapter removal on register writes
7/7 ixgbe: Additional adapter removal checks
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 7 ++
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 55 +++++++++---
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 110 +++++++++++++----------
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 74 ++++++++++++---
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c | 3 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 2 +-
6 files changed, 180 insertions(+), 71 deletions(-)
--
1.8.5.GIT
^ permalink raw reply
* [net-next 1/7] ixbge: Protect ixgbe_down with __IXGBE_DOWN bit
From: Aaron Brown @ 2014-01-08 7:40 UTC (permalink / raw)
To: davem; +Cc: Mark Rustad, netdev, gospo, sassmann, Aaron Brown
In-Reply-To: <1389166847-3780-1-git-send-email-aaron.f.brown@intel.com>
From: Mark Rustad <mark.d.rustad@intel.com>
The ixgbe_down function can now prevent multiple executions by
doing test_and_set_bit on __IXGBE_DOWN. This did not work before
introduction of the __IXGBE_REMOVED bit, because of overloading
of __IXGBE_DOWN. Also add smp_mb__before_clear_bit call before
clearing the __IXGBE_DOWN bit.
Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index cc06854..90a0b4a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -4572,6 +4572,7 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
if (hw->mac.ops.enable_tx_laser)
hw->mac.ops.enable_tx_laser(hw);
+ smp_mb__before_clear_bit();
clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter);
@@ -4783,7 +4784,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
int i;
/* signal that we are down to the interrupt handler */
- set_bit(__IXGBE_DOWN, &adapter->state);
+ if (test_and_set_bit(__IXGBE_DOWN, &adapter->state))
+ return; /* do nothing if already down */
/* disable receives */
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
--
1.8.5.GIT
^ permalink raw reply related
* [net-next 2/7] ixgbe: Indicate removal state explicitly
From: Aaron Brown @ 2014-01-08 7:40 UTC (permalink / raw)
To: davem; +Cc: Mark Rustad, netdev, gospo, sassmann, Aaron Brown
In-Reply-To: <1389166847-3780-1-git-send-email-aaron.f.brown@intel.com>
From: Mark Rustad <mark.d.rustad@intel.com>
Add a bit, __IXGBE_REMOVE, to indicate that the module is being
removed. The __IXGBE_DOWN bit had been overloaded for this purpose,
but that leads to trouble. A few places now check both __IXGBE_DOWN
and __IXGBE_REMOVE. Notably, setting either bit will prevent service
task execution.
Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 49531cd..8da263a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -798,6 +798,7 @@ enum ixgbe_state_t {
__IXGBE_TESTING,
__IXGBE_RESETTING,
__IXGBE_DOWN,
+ __IXGBE_REMOVE,
__IXGBE_SERVICE_SCHED,
__IXGBE_IN_SFP_INIT,
__IXGBE_PTP_RUNNING,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 90a0b4a..923b0fa 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -278,6 +278,7 @@ static void ixgbe_check_minimum_link(struct ixgbe_adapter *adapter,
static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
{
if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
+ !test_bit(__IXGBE_REMOVE, &adapter->state) &&
!test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
schedule_work(&adapter->service_task);
}
@@ -5876,8 +5877,9 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
u64 eics = 0;
int i;
- /* If we're down or resetting, just bail */
+ /* If we're down, removing or resetting, just bail */
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+ test_bit(__IXGBE_REMOVE, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
@@ -6124,8 +6126,9 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
**/
static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter)
{
- /* if interface is down do nothing */
+ /* if interface is down, removing or resetting, do nothing */
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+ test_bit(__IXGBE_REMOVE, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
@@ -6343,8 +6346,9 @@ static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;
- /* If we're already down or resetting, just bail */
+ /* If we're already down, removing or resetting, just bail */
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+ test_bit(__IXGBE_REMOVE, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
@@ -8219,7 +8223,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
ixgbe_dbg_adapter_exit(adapter);
- set_bit(__IXGBE_DOWN, &adapter->state);
+ set_bit(__IXGBE_REMOVE, &adapter->state);
cancel_work_sync(&adapter->service_task);
--
1.8.5.GIT
^ permalink raw reply related
* [net-next 3/7] ixgbe: Use static inlines instead of macros
From: Aaron Brown @ 2014-01-08 7:40 UTC (permalink / raw)
To: davem; +Cc: Mark Rustad, netdev, gospo, sassmann, Aaron Brown
In-Reply-To: <1389166847-3780-1-git-send-email-aaron.f.brown@intel.com>
From: Mark Rustad <mark.d.rustad@intel.com>
Kernel coding standard prefers static inline functions instead
of macros, so use them for register accessors. This is to prepare
for adding LER, Live Error Recovery, checks to those accessors.
Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 5 +++++
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 30 +++++++++++++++++--------
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++--
3 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 8da263a..199cf74 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -585,6 +585,11 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
}
+static inline void ixgbe_write_tail(struct ixgbe_ring *ring, u32 value)
+{
+ writel(value, ring->tail);
+}
+
#define IXGBE_RX_DESC(R, i) \
(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBE_TX_DESC(R, i) \
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index d259dc7..5e157ac 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -124,22 +124,34 @@ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw);
s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
-#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
+static inline void IXGBE_WRITE_REG(struct ixgbe_hw *hw, u32 reg, u32 value)
+{
+ writel(value, hw->hw_addr + reg);
+}
#ifndef writeq
-#define writeq(val, addr) writel((u32) (val), addr); \
- writel((u32) (val >> 32), (addr + 4));
+static inline void writeq(u64 val, void __iomem *addr)
+{
+ writel((u32)val, addr);
+ writel((u32)(val >> 32), addr + 4);
+}
#endif
-#define IXGBE_WRITE_REG64(a, reg, value) writeq((value), ((a)->hw_addr + (reg)))
+static inline void IXGBE_WRITE_REG64(struct ixgbe_hw *hw, u32 reg, u64 value)
+{
+ writeq(value, hw->hw_addr + reg);
+}
-#define IXGBE_READ_REG(a, reg) readl((a)->hw_addr + (reg))
+static inline u32 IXGBE_READ_REG(struct ixgbe_hw *hw, u32 reg)
+{
+ return readl(hw->hw_addr + reg);
+}
-#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) (\
- writel((value), ((a)->hw_addr + (reg) + ((offset) << 2))))
+#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) \
+ IXGBE_WRITE_REG((a), (reg) + ((offset) << 2), (value))
-#define IXGBE_READ_REG_ARRAY(a, reg, offset) (\
- readl((a)->hw_addr + (reg) + ((offset) << 2)))
+#define IXGBE_READ_REG_ARRAY(a, reg, offset) \
+ IXGBE_READ_REG((a), (reg) + ((offset) << 2))
#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 923b0fa..4d71277 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1315,7 +1315,7 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
* such as IA-64).
*/
wmb();
- writel(val, rx_ring->tail);
+ ixgbe_write_tail(rx_ring, val);
}
static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
@@ -6699,7 +6699,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
tx_ring->next_to_use = i;
/* notify HW of packet */
- writel(i, tx_ring->tail);
+ ixgbe_write_tail(tx_ring, i);
return;
dma_error:
--
1.8.5.GIT
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox