* Re: [PATCH 1/1] netlink: nla_nest_end return "unsigned init"
From: David Miller @ 2011-05-16 17:51 UTC (permalink / raw)
To: linville; +Cc: wey-yi.w.guy, linux-wireless, ipw3945-devel, netdev
In-Reply-To: <20110516173548.GB6551@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Mon, 16 May 2011 13:35:48 -0400
> This should go to netdev@vger.kernel.org instead...
>
> On Mon, May 16, 2011 at 07:23:30AM -0700, Wey-Yi Guy wrote:
>> skb->len has unsigned int, return the correct value from nla_nest_end call.
>>
>> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Plus, the only users of the return value use it to feed "int"
return values of functions. F.e. net/core/neighbour.c's use
in neightbl_fill_parms().
I don't see this as being any better or worse, and we should
just leave the return value alone.
^ permalink raw reply
* [PATCH] ipv4: Trivial rt->rt_src conversions in net/ipv4/route.c
From: David Miller @ 2011-05-16 17:52 UTC (permalink / raw)
To: netdev
At these points we have a fully filled in value via the IP
header the form of ip_hdr(skb)->saddr
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/route.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ad141d8..cb93c32 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1435,7 +1435,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
peer->rate_tokens == ip_rt_redirect_number &&
net_ratelimit())
printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n",
- &rt->rt_src, rt->rt_iif,
+ &ip_hdr(skb)->saddr, rt->rt_iif,
&rt->rt_dst, &rt->rt_gateway);
#endif
}
@@ -1704,7 +1704,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
__be32 src;
if (rt_is_output_route(rt))
- src = rt->rt_src;
+ src = ip_hdr(skb)->saddr;
else {
struct fib_result res;
struct flowi4 fl4;
--
1.7.4.4
^ permalink raw reply related
* [PATCH net-next-2.6 3/3] be2net: FW download for Lancer
From: Padmanabh Ratnakar @ 2011-05-16 17:36 UTC (permalink / raw)
To: davem, netdev; +Cc: Padmanabh Ratnakar, Shripad Nunjundarao, Sevin Xavier
From: Shripad Nunjundarao <shripad.nunjundarao@emulex.com>
Added implementation of FW download feature for Lancer.
Signed-off-by: Shripad Nunjundarao <shripad.nunjundarao@emulex.com>
Signed-off-by: Sevin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
---
drivers/net/benet/be_cmds.c | 78 +++++++++++++++++++++++++-
drivers/net/benet/be_cmds.h | 36 ++++++++++++
drivers/net/benet/be_main.c | 129 ++++++++++++++++++++++++++++++++++++------
3 files changed, 223 insertions(+), 20 deletions(-)
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index aaef0c7..2463b1c 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -71,7 +71,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
- if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) &&
+ if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
+ (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
(compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
adapter->flash_status = compl_status;
complete(&adapter->flash_compl);
@@ -1801,6 +1802,81 @@ err:
return status;
}
+int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
+ u32 data_size, u32 data_offset, const char *obj_name,
+ u32 *data_written, u8 *addn_status)
+{
+ struct be_mcc_wrb *wrb;
+ struct lancer_cmd_req_write_object *req;
+ struct lancer_cmd_resp_write_object *resp;
+ void *ctxt = NULL;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+ adapter->flash_status = 0;
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err_unlock;
+ }
+
+ req = embedded_payload(wrb);
+
+ be_wrb_hdr_prepare(wrb, sizeof(struct lancer_cmd_req_write_object),
+ true, 1, OPCODE_COMMON_WRITE_OBJECT);
+ wrb->tag1 = CMD_SUBSYSTEM_COMMON;
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_WRITE_OBJECT,
+ sizeof(struct lancer_cmd_req_write_object));
+
+ ctxt = &req->context;
+ AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+ write_length, ctxt, data_size);
+
+ if (data_size == 0)
+ AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+ eof, ctxt, 1);
+ else
+ AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+ eof, ctxt, 0);
+
+ be_dws_cpu_to_le(ctxt, sizeof(req->context));
+ req->write_offset = cpu_to_le32(data_offset);
+ strcpy(req->object_name, obj_name);
+ req->descriptor_count = cpu_to_le32(1);
+ req->buf_len = cpu_to_le32(data_size);
+ req->addr_low = cpu_to_le32((cmd->dma +
+ sizeof(struct lancer_cmd_req_write_object))
+ & 0xFFFFFFFF);
+ req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
+ sizeof(struct lancer_cmd_req_write_object)));
+
+ be_mcc_notify(adapter);
+ spin_unlock_bh(&adapter->mcc_lock);
+
+ if (!wait_for_completion_timeout(&adapter->flash_compl,
+ msecs_to_jiffies(12000)))
+ status = -1;
+ else
+ status = adapter->flash_status;
+
+ resp = embedded_payload(wrb);
+ if (!status) {
+ *data_written = le32_to_cpu(resp->actual_write_len);
+ } else {
+ *addn_status = resp->additional_status;
+ status = resp->status;
+ }
+
+ return status;
+
+err_unlock:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 flash_type, u32 flash_opcode, u32 buf_size)
{
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 9cff226..8148cc6 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -193,6 +193,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_PHY_DETAILS 102
#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
+#define OPCODE_COMMON_WRITE_OBJECT 172
#define OPCODE_ETH_RSS_CONFIG 1
#define OPCODE_ETH_ACPI_CONFIG 2
@@ -1131,6 +1132,36 @@ struct be_cmd_write_flashrom {
struct flashrom_params params;
};
+/**************** Lancer Firmware Flash ************/
+struct amap_lancer_write_obj_context {
+ u8 write_length[24];
+ u8 reserved1[7];
+ u8 eof;
+} __packed;
+
+struct lancer_cmd_req_write_object {
+ struct be_cmd_req_hdr hdr;
+ u8 context[sizeof(struct amap_lancer_write_obj_context) / 8];
+ u32 write_offset;
+ u8 object_name[104];
+ u32 descriptor_count;
+ u32 buf_len;
+ u32 addr_low;
+ u32 addr_high;
+};
+
+struct lancer_cmd_resp_write_object {
+ u8 opcode;
+ u8 subsystem;
+ u8 rsvd1[2];
+ u8 status;
+ u8 additional_status;
+ u8 rsvd2[2];
+ u32 resp_len;
+ u32 actual_resp_len;
+ u32 actual_write_len;
+};
+
/************************ WOL *******************************/
struct be_cmd_req_acpi_wol_magic_config{
struct be_cmd_req_hdr hdr;
@@ -1481,6 +1512,11 @@ extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
extern int be_cmd_write_flashrom(struct be_adapter *adapter,
struct be_dma_mem *cmd, u32 flash_oper,
u32 flash_opcode, u32 buf_size);
+extern int lancer_cmd_write_object(struct be_adapter *adapter,
+ struct be_dma_mem *cmd,
+ u32 data_size, u32 data_offset,
+ const char *obj_name,
+ u32 *data_written, u8 *addn_status);
int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
int offset);
extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 93be84c..7322a51 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -2712,7 +2712,6 @@ static int be_flash_data(struct be_adapter *adapter,
"cmd to write to flash rom failed.\n");
return -1;
}
- yield();
}
}
return 0;
@@ -2730,32 +2729,98 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
return 0;
}
-int be_load_fw(struct be_adapter *adapter, u8 *func)
+static int lancer_fw_download(struct be_adapter *adapter,
+ const struct firmware *fw)
{
- char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
- const struct firmware *fw;
- struct flash_file_hdr_g2 *fhdr;
- struct flash_file_hdr_g3 *fhdr3;
- struct image_hdr *img_hdr_ptr = NULL;
+#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024)
+#define LANCER_FW_DOWNLOAD_LOCATION "/prg"
struct be_dma_mem flash_cmd;
- int status, i = 0, num_imgs = 0;
- const u8 *p;
+ struct lancer_cmd_req_write_object *req;
+ const u8 *data_ptr = NULL;
+ u8 *dest_image_ptr = NULL;
+ size_t image_size = 0;
+ u32 chunk_size = 0;
+ u32 data_written = 0;
+ u32 offset = 0;
+ int status = 0;
+ u8 add_status = 0;
- if (!netif_running(adapter->netdev)) {
+ if (!IS_ALIGNED(fw->size, sizeof(u32))) {
dev_err(&adapter->pdev->dev,
- "Firmware load not allowed (interface is down)\n");
- return -EPERM;
+ "FW Image not properly aligned. "
+ "Length must be 4 byte aligned.\n");
+ status = -EINVAL;
+ goto lancer_fw_exit;
}
- strcpy(fw_file, func);
+ flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
+ + LANCER_FW_DOWNLOAD_CHUNK;
+ flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
+ &flash_cmd.dma, GFP_KERNEL);
+ if (!flash_cmd.va) {
+ status = -ENOMEM;
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failure while flashing\n");
+ goto lancer_fw_exit;
+ }
- status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
- if (status)
- goto fw_exit;
+ req = flash_cmd.va;
+ dest_image_ptr = flash_cmd.va +
+ sizeof(struct lancer_cmd_req_write_object);
+ image_size = fw->size;
+ data_ptr = fw->data;
+
+ while (image_size) {
+ chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
+
+ /* Copy the image chunk content. */
+ memcpy(dest_image_ptr, data_ptr, chunk_size);
+
+ status = lancer_cmd_write_object(adapter, &flash_cmd,
+ chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION,
+ &data_written, &add_status);
+
+ if (status)
+ break;
+
+ offset += data_written;
+ data_ptr += data_written;
+ image_size -= data_written;
+ }
+
+ if (!status) {
+ /* Commit the FW written */
+ status = lancer_cmd_write_object(adapter, &flash_cmd,
+ 0, offset, LANCER_FW_DOWNLOAD_LOCATION,
+ &data_written, &add_status);
+ }
+
+ dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
+ flash_cmd.dma);
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware load error. "
+ "Status code: 0x%x Additional Status: 0x%x\n",
+ status, add_status);
+ goto lancer_fw_exit;
+ }
+
+ dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+lancer_fw_exit:
+ return status;
+}
+
+static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
+{
+ struct flash_file_hdr_g2 *fhdr;
+ struct flash_file_hdr_g3 *fhdr3;
+ struct image_hdr *img_hdr_ptr = NULL;
+ struct be_dma_mem flash_cmd;
+ const u8 *p;
+ int status = 0, i = 0, num_imgs = 0;
p = fw->data;
fhdr = (struct flash_file_hdr_g2 *) p;
- dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
@@ -2764,7 +2829,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
status = -ENOMEM;
dev_err(&adapter->pdev->dev,
"Memory allocation failure while flashing\n");
- goto fw_exit;
+ goto be_fw_exit;
}
if ((adapter->generation == BE_GEN3) &&
@@ -2792,11 +2857,37 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
flash_cmd.dma);
if (status) {
dev_err(&adapter->pdev->dev, "Firmware load error\n");
- goto fw_exit;
+ goto be_fw_exit;
}
dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+be_fw_exit:
+ return status;
+}
+
+int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
+{
+ const struct firmware *fw;
+ int status;
+
+ if (!netif_running(adapter->netdev)) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware load not allowed (interface is down)\n");
+ return -1;
+ }
+
+ status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
+ if (status)
+ goto fw_exit;
+
+ dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
+
+ if (lancer_chip(adapter))
+ status = lancer_fw_download(adapter, fw);
+ else
+ status = be_fw_download(adapter, fw);
+
fw_exit:
release_firmware(fw);
return status;
--
1.6.0.2
^ permalink raw reply related
* [PATCH net-next-2.6 2/3] be2net: Stats for Lancer
From: Padmanabh Ratnakar @ 2011-05-16 17:36 UTC (permalink / raw)
To: davem, netdev; +Cc: Padmanabh Ratnakar, Selvin Xavier
From: Selvin Xavier <selvin.xavier@emulex.com>
Added Lancer stats implementation.
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
---
drivers/net/benet/be.h | 74 ++++++++--------
drivers/net/benet/be_cmds.c | 55 ++++++++++++-
drivers/net/benet/be_cmds.h | 197 +++++++++++++++++++++++++++++++++++++++++++
drivers/net/benet/be_main.c | 91 +++++++++++++++++---
4 files changed, 367 insertions(+), 50 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 0da0384..0b73dcf 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -244,43 +244,43 @@ struct be_rx_obj {
struct be_drv_stats {
u8 be_on_die_temperature;
- u32 be_tx_events;
- u32 eth_red_drops;
- u32 rx_drops_no_pbuf;
- u32 rx_drops_no_txpb;
- u32 rx_drops_no_erx_descr;
- u32 rx_drops_no_tpre_descr;
- u32 rx_drops_too_many_frags;
- u32 rx_drops_invalid_ring;
- u32 forwarded_packets;
- u32 rx_drops_mtu;
- u32 rx_crc_errors;
- u32 rx_alignment_symbol_errors;
- u32 rx_pause_frames;
- u32 rx_priority_pause_frames;
- u32 rx_control_frames;
- u32 rx_in_range_errors;
- u32 rx_out_range_errors;
- u32 rx_frame_too_long;
- u32 rx_address_match_errors;
- u32 rx_dropped_too_small;
- u32 rx_dropped_too_short;
- u32 rx_dropped_header_too_small;
- u32 rx_dropped_tcp_length;
- u32 rx_dropped_runt;
- u32 rx_ip_checksum_errs;
- u32 rx_tcp_checksum_errs;
- u32 rx_udp_checksum_errs;
- u32 rx_switched_unicast_packets;
- u32 rx_switched_multicast_packets;
- u32 rx_switched_broadcast_packets;
- u32 tx_pauseframes;
- u32 tx_priority_pauseframes;
- u32 tx_controlframes;
- u32 rxpp_fifo_overflow_drop;
- u32 rx_input_fifo_overflow_drop;
- u32 pmem_fifo_overflow_drop;
- u32 jabber_events;
+ u64 be_tx_events;
+ u64 eth_red_drops;
+ u64 rx_drops_no_pbuf;
+ u64 rx_drops_no_txpb;
+ u64 rx_drops_no_erx_descr;
+ u64 rx_drops_no_tpre_descr;
+ u64 rx_drops_too_many_frags;
+ u64 rx_drops_invalid_ring;
+ u64 forwarded_packets;
+ u64 rx_drops_mtu;
+ u64 rx_crc_errors;
+ u64 rx_alignment_symbol_errors;
+ u64 rx_pause_frames;
+ u64 rx_priority_pause_frames;
+ u64 rx_control_frames;
+ u64 rx_in_range_errors;
+ u64 rx_out_range_errors;
+ u64 rx_frame_too_long;
+ u64 rx_address_match_errors;
+ u64 rx_dropped_too_small;
+ u64 rx_dropped_too_short;
+ u64 rx_dropped_header_too_small;
+ u64 rx_dropped_tcp_length;
+ u64 rx_dropped_runt;
+ u64 rx_ip_checksum_errs;
+ u64 rx_tcp_checksum_errs;
+ u64 rx_udp_checksum_errs;
+ u64 rx_switched_unicast_packets;
+ u64 rx_switched_multicast_packets;
+ u64 rx_switched_broadcast_packets;
+ u64 tx_pauseframes;
+ u64 tx_priority_pauseframes;
+ u64 tx_controlframes;
+ u64 rxpp_fifo_overflow_drop;
+ u64 rx_input_fifo_overflow_drop;
+ u64 pmem_fifo_overflow_drop;
+ u64 jabber_events;
};
struct be_vf_cfg {
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 08e0938..aaef0c7 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -78,14 +78,22 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
}
if (compl_status == MCC_STATUS_SUCCESS) {
- if ((compl->tag0 == OPCODE_ETH_GET_STATISTICS) &&
+ if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
+ (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
(compl->tag1 == CMD_SUBSYSTEM_ETH)) {
if (adapter->generation == BE_GEN3) {
- struct be_cmd_resp_get_stats_v1 *resp =
+ if (lancer_chip(adapter)) {
+ struct lancer_cmd_resp_pport_stats
+ *resp = adapter->stats_cmd.va;
+ be_dws_le_to_cpu(&resp->pport_stats,
+ sizeof(resp->pport_stats));
+ } else {
+ struct be_cmd_resp_get_stats_v1 *resp =
adapter->stats_cmd.va;
be_dws_le_to_cpu(&resp->hw_stats,
sizeof(resp->hw_stats));
+ }
} else {
struct be_cmd_resp_get_stats_v0 *resp =
adapter->stats_cmd.va;
@@ -1124,6 +1132,49 @@ err:
return status;
}
+/* Lancer Stats */
+int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+ struct be_dma_mem *nonemb_cmd)
+{
+
+ struct be_mcc_wrb *wrb;
+ struct lancer_cmd_req_pport_stats *req;
+ struct be_sge *sge;
+ int status = 0;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+ req = nonemb_cmd->va;
+ sge = nonembedded_sgl(wrb);
+
+ be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
+ OPCODE_ETH_GET_PPORT_STATS);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size);
+
+
+ req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num);
+ req->cmd_params.params.reset_stats = 0;
+
+ wrb->tag1 = CMD_SUBSYSTEM_ETH;
+ sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+ sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(nonemb_cmd->size);
+
+ be_mcc_notify(adapter);
+ adapter->stats_cmd_sent = true;
+
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
/* Uses synchronous mcc */
int be_cmd_link_status_query(struct be_adapter *adapter,
bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom)
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index bcf816d..9cff226 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -203,6 +203,7 @@ struct be_mcc_mailbox {
#define OPCODE_ETH_TX_DESTROY 9
#define OPCODE_ETH_RX_DESTROY 10
#define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG 12
+#define OPCODE_ETH_GET_PPORT_STATS 18
#define OPCODE_LOWLEVEL_HOST_DDR_DMA 17
#define OPCODE_LOWLEVEL_LOOPBACK_TEST 18
@@ -688,6 +689,200 @@ struct be_cmd_resp_get_stats_v0 {
struct be_hw_stats_v0 hw_stats;
};
+#define make_64bit_val(hi_32, lo_32) (((u64)hi_32<<32) | lo_32)
+struct lancer_cmd_pport_stats {
+ u32 tx_packets_lo;
+ u32 tx_packets_hi;
+ u32 tx_unicast_packets_lo;
+ u32 tx_unicast_packets_hi;
+ u32 tx_multicast_packets_lo;
+ u32 tx_multicast_packets_hi;
+ u32 tx_broadcast_packets_lo;
+ u32 tx_broadcast_packets_hi;
+ u32 tx_bytes_lo;
+ u32 tx_bytes_hi;
+ u32 tx_unicast_bytes_lo;
+ u32 tx_unicast_bytes_hi;
+ u32 tx_multicast_bytes_lo;
+ u32 tx_multicast_bytes_hi;
+ u32 tx_broadcast_bytes_lo;
+ u32 tx_broadcast_bytes_hi;
+ u32 tx_discards_lo;
+ u32 tx_discards_hi;
+ u32 tx_errors_lo;
+ u32 tx_errors_hi;
+ u32 tx_pause_frames_lo;
+ u32 tx_pause_frames_hi;
+ u32 tx_pause_on_frames_lo;
+ u32 tx_pause_on_frames_hi;
+ u32 tx_pause_off_frames_lo;
+ u32 tx_pause_off_frames_hi;
+ u32 tx_internal_mac_errors_lo;
+ u32 tx_internal_mac_errors_hi;
+ u32 tx_control_frames_lo;
+ u32 tx_control_frames_hi;
+ u32 tx_packets_64_bytes_lo;
+ u32 tx_packets_64_bytes_hi;
+ u32 tx_packets_65_to_127_bytes_lo;
+ u32 tx_packets_65_to_127_bytes_hi;
+ u32 tx_packets_128_to_255_bytes_lo;
+ u32 tx_packets_128_to_255_bytes_hi;
+ u32 tx_packets_256_to_511_bytes_lo;
+ u32 tx_packets_256_to_511_bytes_hi;
+ u32 tx_packets_512_to_1023_bytes_lo;
+ u32 tx_packets_512_to_1023_bytes_hi;
+ u32 tx_packets_1024_to_1518_bytes_lo;
+ u32 tx_packets_1024_to_1518_bytes_hi;
+ u32 tx_packets_1519_to_2047_bytes_lo;
+ u32 tx_packets_1519_to_2047_bytes_hi;
+ u32 tx_packets_2048_to_4095_bytes_lo;
+ u32 tx_packets_2048_to_4095_bytes_hi;
+ u32 tx_packets_4096_to_8191_bytes_lo;
+ u32 tx_packets_4096_to_8191_bytes_hi;
+ u32 tx_packets_8192_to_9216_bytes_lo;
+ u32 tx_packets_8192_to_9216_bytes_hi;
+ u32 tx_lso_packets_lo;
+ u32 tx_lso_packets_hi;
+ u32 rx_packets_lo;
+ u32 rx_packets_hi;
+ u32 rx_unicast_packets_lo;
+ u32 rx_unicast_packets_hi;
+ u32 rx_multicast_packets_lo;
+ u32 rx_multicast_packets_hi;
+ u32 rx_broadcast_packets_lo;
+ u32 rx_broadcast_packets_hi;
+ u32 rx_bytes_lo;
+ u32 rx_bytes_hi;
+ u32 rx_unicast_bytes_lo;
+ u32 rx_unicast_bytes_hi;
+ u32 rx_multicast_bytes_lo;
+ u32 rx_multicast_bytes_hi;
+ u32 rx_broadcast_bytes_lo;
+ u32 rx_broadcast_bytes_hi;
+ u32 rx_unknown_protos;
+ u32 rsvd_69; /* Word 69 is reserved */
+ u32 rx_discards_lo;
+ u32 rx_discards_hi;
+ u32 rx_errors_lo;
+ u32 rx_errors_hi;
+ u32 rx_crc_errors_lo;
+ u32 rx_crc_errors_hi;
+ u32 rx_alignment_errors_lo;
+ u32 rx_alignment_errors_hi;
+ u32 rx_symbol_errors_lo;
+ u32 rx_symbol_errors_hi;
+ u32 rx_pause_frames_lo;
+ u32 rx_pause_frames_hi;
+ u32 rx_pause_on_frames_lo;
+ u32 rx_pause_on_frames_hi;
+ u32 rx_pause_off_frames_lo;
+ u32 rx_pause_off_frames_hi;
+ u32 rx_frames_too_long_lo;
+ u32 rx_frames_too_long_hi;
+ u32 rx_internal_mac_errors_lo;
+ u32 rx_internal_mac_errors_hi;
+ u32 rx_undersize_packets;
+ u32 rx_oversize_packets;
+ u32 rx_fragment_packets;
+ u32 rx_jabbers;
+ u32 rx_control_frames_lo;
+ u32 rx_control_frames_hi;
+ u32 rx_control_frames_unknown_opcode_lo;
+ u32 rx_control_frames_unknown_opcode_hi;
+ u32 rx_in_range_errors;
+ u32 rx_out_of_range_errors;
+ u32 rx_address_match_errors;
+ u32 rx_vlan_mismatch_errors;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+ u32 rx_dropped_invalid_tcp_length;
+ u32 rx_dropped_runt;
+ u32 rx_ip_checksum_errors;
+ u32 rx_tcp_checksum_errors;
+ u32 rx_udp_checksum_errors;
+ u32 rx_non_rss_packets;
+ u32 rsvd_111;
+ u32 rx_ipv4_packets_lo;
+ u32 rx_ipv4_packets_hi;
+ u32 rx_ipv6_packets_lo;
+ u32 rx_ipv6_packets_hi;
+ u32 rx_ipv4_bytes_lo;
+ u32 rx_ipv4_bytes_hi;
+ u32 rx_ipv6_bytes_lo;
+ u32 rx_ipv6_bytes_hi;
+ u32 rx_nic_packets_lo;
+ u32 rx_nic_packets_hi;
+ u32 rx_tcp_packets_lo;
+ u32 rx_tcp_packets_hi;
+ u32 rx_iscsi_packets_lo;
+ u32 rx_iscsi_packets_hi;
+ u32 rx_management_packets_lo;
+ u32 rx_management_packets_hi;
+ u32 rx_switched_unicast_packets_lo;
+ u32 rx_switched_unicast_packets_hi;
+ u32 rx_switched_multicast_packets_lo;
+ u32 rx_switched_multicast_packets_hi;
+ u32 rx_switched_broadcast_packets_lo;
+ u32 rx_switched_broadcast_packets_hi;
+ u32 num_forwards_lo;
+ u32 num_forwards_hi;
+ u32 rx_fifo_overflow;
+ u32 rx_input_fifo_overflow;
+ u32 rx_drops_too_many_frags_lo;
+ u32 rx_drops_too_many_frags_hi;
+ u32 rx_drops_invalid_queue;
+ u32 rsvd_141;
+ u32 rx_drops_mtu_lo;
+ u32 rx_drops_mtu_hi;
+ u32 rx_packets_64_bytes_lo;
+ u32 rx_packets_64_bytes_hi;
+ u32 rx_packets_65_to_127_bytes_lo;
+ u32 rx_packets_65_to_127_bytes_hi;
+ u32 rx_packets_128_to_255_bytes_lo;
+ u32 rx_packets_128_to_255_bytes_hi;
+ u32 rx_packets_256_to_511_bytes_lo;
+ u32 rx_packets_256_to_511_bytes_hi;
+ u32 rx_packets_512_to_1023_bytes_lo;
+ u32 rx_packets_512_to_1023_bytes_hi;
+ u32 rx_packets_1024_to_1518_bytes_lo;
+ u32 rx_packets_1024_to_1518_bytes_hi;
+ u32 rx_packets_1519_to_2047_bytes_lo;
+ u32 rx_packets_1519_to_2047_bytes_hi;
+ u32 rx_packets_2048_to_4095_bytes_lo;
+ u32 rx_packets_2048_to_4095_bytes_hi;
+ u32 rx_packets_4096_to_8191_bytes_lo;
+ u32 rx_packets_4096_to_8191_bytes_hi;
+ u32 rx_packets_8192_to_9216_bytes_lo;
+ u32 rx_packets_8192_to_9216_bytes_hi;
+};
+
+struct pport_stats_params {
+ u16 pport_num;
+ u8 rsvd;
+ u8 reset_stats;
+};
+
+struct lancer_cmd_req_pport_stats {
+ struct be_cmd_req_hdr hdr;
+ union {
+ struct pport_stats_params params;
+ u8 rsvd[sizeof(struct lancer_cmd_pport_stats)];
+ } cmd_params;
+};
+
+struct lancer_cmd_resp_pport_stats {
+ struct be_cmd_resp_hdr hdr;
+ struct lancer_cmd_pport_stats pport_stats;
+};
+
+static inline struct lancer_cmd_pport_stats*
+ pport_stats_from_cmd(struct be_adapter *adapter)
+{
+ struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va;
+ return &cmd->pport_stats;
+}
+
struct be_cmd_req_get_cntl_addnl_attribs {
struct be_cmd_req_hdr hdr;
u8 rsvd[8];
@@ -1258,6 +1453,8 @@ extern int be_cmd_link_status_query(struct be_adapter *adapter,
extern int be_cmd_reset(struct be_adapter *adapter);
extern int be_cmd_get_stats(struct be_adapter *adapter,
struct be_dma_mem *nonemb_cmd);
+extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+ struct be_dma_mem *nonemb_cmd);
extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver);
extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index cff2cca..93be84c 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -351,14 +351,73 @@ static void populate_be3_stats(struct be_adapter *adapter)
adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
}
+static void populate_lancer_stats(struct be_adapter *adapter)
+{
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+ struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd
+ (adapter);
+ drvs->rx_priority_pause_frames = 0;
+ drvs->pmem_fifo_overflow_drop = 0;
+ drvs->rx_pause_frames =
+ make_64bit_val(pport_stats->rx_pause_frames_lo,
+ pport_stats->rx_pause_frames_hi);
+ drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi,
+ pport_stats->rx_crc_errors_lo);
+ drvs->rx_control_frames =
+ make_64bit_val(pport_stats->rx_control_frames_hi,
+ pport_stats->rx_control_frames_lo);
+ drvs->rx_in_range_errors = pport_stats->rx_in_range_errors;
+ drvs->rx_frame_too_long =
+ make_64bit_val(pport_stats->rx_internal_mac_errors_hi,
+ pport_stats->rx_frames_too_long_lo);
+ drvs->rx_dropped_runt = pport_stats->rx_dropped_runt;
+ drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors;
+ drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors;
+ drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors;
+ drvs->rx_dropped_tcp_length =
+ pport_stats->rx_dropped_invalid_tcp_length;
+ drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small;
+ drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short;
+ drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors;
+ drvs->rx_dropped_header_too_small =
+ pport_stats->rx_dropped_header_too_small;
+ drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+ drvs->rx_address_match_errors = pport_stats->rx_address_match_errors;
+ drvs->rx_alignment_symbol_errors =
+ make_64bit_val(pport_stats->rx_symbol_errors_hi,
+ pport_stats->rx_symbol_errors_lo);
+ drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+ drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi,
+ pport_stats->tx_pause_frames_lo);
+ drvs->tx_controlframes =
+ make_64bit_val(pport_stats->tx_control_frames_hi,
+ pport_stats->tx_control_frames_lo);
+ drvs->jabber_events = pport_stats->rx_jabbers;
+ drvs->rx_drops_no_pbuf = 0;
+ drvs->rx_drops_no_txpb = 0;
+ drvs->rx_drops_no_erx_descr = 0;
+ drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue;
+ drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi,
+ pport_stats->num_forwards_lo);
+ drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi,
+ pport_stats->rx_drops_mtu_lo);
+ drvs->rx_drops_no_tpre_descr = 0;
+ drvs->rx_drops_too_many_frags =
+ make_64bit_val(pport_stats->rx_drops_too_many_frags_hi,
+ pport_stats->rx_drops_too_many_frags_lo);
+}
void be_parse_stats(struct be_adapter *adapter)
{
- if (adapter->generation == BE_GEN3)
- populate_be3_stats(adapter);
- else
+ if (adapter->generation == BE_GEN3) {
+ if (lancer_chip(adapter))
+ populate_lancer_stats(adapter);
+ else
+ populate_be3_stats(adapter);
+ } else {
populate_be2_stats(adapter);
+ }
}
void netdev_stats_update(struct be_adapter *adapter)
@@ -375,10 +434,12 @@ void netdev_stats_update(struct be_adapter *adapter)
dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
/* no space in linux buffers: best possible approximation */
if (adapter->generation == BE_GEN3) {
- struct be_erx_stats_v1 *erx_stats =
+ if (!(lancer_chip(adapter))) {
+ struct be_erx_stats_v1 *erx_stats =
be_erx_stats_from_cmd(adapter);
- dev_stats->rx_dropped +=
+ dev_stats->rx_dropped +=
erx_stats->rx_drops_no_fragments[rxo->q.id];
+ }
} else {
struct be_erx_stats_v0 *erx_stats =
be_erx_stats_from_cmd(adapter);
@@ -2022,9 +2083,13 @@ static void be_worker(struct work_struct *work)
goto reschedule;
}
- if (!adapter->stats_cmd_sent)
- be_cmd_get_stats(adapter, &adapter->stats_cmd);
-
+ if (!adapter->stats_cmd_sent) {
+ if (lancer_chip(adapter))
+ lancer_cmd_get_pport_stats(adapter,
+ &adapter->stats_cmd);
+ else
+ be_cmd_get_stats(adapter, &adapter->stats_cmd);
+ }
be_tx_rate_update(adapter);
for_all_rx_queues(adapter, rxo, i) {
@@ -2944,10 +3009,14 @@ static int be_stats_init(struct be_adapter *adapter)
{
struct be_dma_mem *cmd = &adapter->stats_cmd;
- if (adapter->generation == BE_GEN2)
+ if (adapter->generation == BE_GEN2) {
cmd->size = sizeof(struct be_cmd_req_get_stats_v0);
- else
- cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
+ } else {
+ if (lancer_chip(adapter))
+ cmd->size = sizeof(struct lancer_cmd_req_pport_stats);
+ else
+ cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
+ }
cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
GFP_KERNEL);
if (cmd->va == NULL)
--
1.6.0.2
^ permalink raw reply related
* [PATCH net-next-2.6 1/3] be2net: Support for version 1 of stats for BE3
From: Padmanabh Ratnakar @ 2011-05-16 17:36 UTC (permalink / raw)
To: davem, netdev; +Cc: Padmanabh Ratnakar, Ajit Khaparde, Selvin Xavier
From: Ajit Khaparde <ajit.khaparde@emulex.com>
Added support to get version 1 of the stats for BE3.
Use old stats command for BE2.
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
---
drivers/net/benet/be.h | 38 ++++++++
drivers/net/benet/be_cmds.c | 32 +++++--
drivers/net/benet/be_cmds.h | 181 ++++++++++++++++++++++++++++++++++-----
drivers/net/benet/be_ethtool.c | 108 +++++++++---------------
drivers/net/benet/be_main.c | 182 +++++++++++++++++++++++++++++++++-------
5 files changed, 413 insertions(+), 128 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 41bbc32..0da0384 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -244,6 +244,43 @@ struct be_rx_obj {
struct be_drv_stats {
u8 be_on_die_temperature;
+ u32 be_tx_events;
+ u32 eth_red_drops;
+ u32 rx_drops_no_pbuf;
+ u32 rx_drops_no_txpb;
+ u32 rx_drops_no_erx_descr;
+ u32 rx_drops_no_tpre_descr;
+ u32 rx_drops_too_many_frags;
+ u32 rx_drops_invalid_ring;
+ u32 forwarded_packets;
+ u32 rx_drops_mtu;
+ u32 rx_crc_errors;
+ u32 rx_alignment_symbol_errors;
+ u32 rx_pause_frames;
+ u32 rx_priority_pause_frames;
+ u32 rx_control_frames;
+ u32 rx_in_range_errors;
+ u32 rx_out_range_errors;
+ u32 rx_frame_too_long;
+ u32 rx_address_match_errors;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+ u32 rx_dropped_tcp_length;
+ u32 rx_dropped_runt;
+ u32 rx_ip_checksum_errs;
+ u32 rx_tcp_checksum_errs;
+ u32 rx_udp_checksum_errs;
+ u32 rx_switched_unicast_packets;
+ u32 rx_switched_multicast_packets;
+ u32 rx_switched_broadcast_packets;
+ u32 tx_pauseframes;
+ u32 tx_priority_pauseframes;
+ u32 tx_controlframes;
+ u32 rxpp_fifo_overflow_drop;
+ u32 rx_input_fifo_overflow_drop;
+ u32 pmem_fifo_overflow_drop;
+ u32 jabber_events;
};
struct be_vf_cfg {
@@ -483,5 +520,6 @@ extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
extern void netdev_stats_update(struct be_adapter *adapter);
+extern void be_parse_stats(struct be_adapter *adapter);
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
#endif /* BE_H */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index f2c9099..08e0938 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -80,10 +80,20 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
if (compl_status == MCC_STATUS_SUCCESS) {
if ((compl->tag0 == OPCODE_ETH_GET_STATISTICS) &&
(compl->tag1 == CMD_SUBSYSTEM_ETH)) {
- struct be_cmd_resp_get_stats *resp =
- adapter->stats_cmd.va;
- be_dws_le_to_cpu(&resp->hw_stats,
- sizeof(resp->hw_stats));
+ if (adapter->generation == BE_GEN3) {
+ struct be_cmd_resp_get_stats_v1 *resp =
+ adapter->stats_cmd.va;
+
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ } else {
+ struct be_cmd_resp_get_stats_v0 *resp =
+ adapter->stats_cmd.va;
+
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ }
+ be_parse_stats(adapter);
netdev_stats_update(adapter);
adapter->stats_cmd_sent = false;
}
@@ -1075,7 +1085,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
{
struct be_mcc_wrb *wrb;
- struct be_cmd_req_get_stats *req;
+ struct be_cmd_req_hdr *hdr;
struct be_sge *sge;
int status = 0;
@@ -1089,14 +1099,18 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
status = -EBUSY;
goto err;
}
- req = nonemb_cmd->va;
+ hdr = nonemb_cmd->va;
sge = nonembedded_sgl(wrb);
- be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+ be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
OPCODE_ETH_GET_STATISTICS);
- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
- OPCODE_ETH_GET_STATISTICS, sizeof(*req));
+ be_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size);
+
+ if (adapter->generation == BE_GEN3)
+ hdr->version = 1;
+
wrb->tag1 = CMD_SUBSYSTEM_ETH;
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 78256b6..bcf816d 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -568,7 +568,7 @@ struct be_cmd_req_if_destroy {
};
/*************** HW Stats Get **********************************/
-struct be_port_rxf_stats {
+struct be_port_rxf_stats_v0 {
u32 rx_bytes_lsd; /* dword 0*/
u32 rx_bytes_msd; /* dword 1*/
u32 rx_total_frames; /* dword 2*/
@@ -637,8 +637,8 @@ struct be_port_rxf_stats {
u32 rx_input_fifo_overflow; /* dword 65*/
};
-struct be_rxf_stats {
- struct be_port_rxf_stats port[2];
+struct be_rxf_stats_v0 {
+ struct be_port_rxf_stats_v0 port[2];
u32 rx_drops_no_pbuf; /* dword 132*/
u32 rx_drops_no_txpb; /* dword 133*/
u32 rx_drops_no_erx_descr; /* dword 134*/
@@ -661,34 +661,31 @@ struct be_rxf_stats {
u32 rsvd1[6];
};
-struct be_erx_stats {
+struct be_erx_stats_v0 {
u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/
- u32 debug_wdma_sent_hold; /* dword 44*/
- u32 debug_wdma_pbfree_sent_hold; /* dword 45*/
- u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/
- u32 debug_pmem_pbuf_dealloc; /* dword 47*/
+ u32 rsvd[4];
};
struct be_pmem_stats {
u32 eth_red_drops;
- u32 rsvd[4];
+ u32 rsvd[5];
};
-struct be_hw_stats {
- struct be_rxf_stats rxf;
+struct be_hw_stats_v0 {
+ struct be_rxf_stats_v0 rxf;
u32 rsvd[48];
- struct be_erx_stats erx;
+ struct be_erx_stats_v0 erx;
struct be_pmem_stats pmem;
};
-struct be_cmd_req_get_stats {
+struct be_cmd_req_get_stats_v0 {
struct be_cmd_req_hdr hdr;
- u8 rsvd[sizeof(struct be_hw_stats)];
+ u8 rsvd[sizeof(struct be_hw_stats_v0)];
};
-struct be_cmd_resp_get_stats {
+struct be_cmd_resp_get_stats_v0 {
struct be_cmd_resp_hdr hdr;
- struct be_hw_stats hw_stats;
+ struct be_hw_stats_v0 hw_stats;
};
struct be_cmd_req_get_cntl_addnl_attribs {
@@ -728,13 +725,6 @@ struct be_cmd_req_mcast_mac_config {
struct macaddr mac[BE_MAX_MC];
} __packed;
-static inline struct be_hw_stats *
-hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd)
-{
- return &cmd->hw_stats;
-}
-
-
/******************* RX FILTER ******************************/
struct be_cmd_req_rx_filter {
struct be_cmd_req_hdr hdr;
@@ -1087,6 +1077,151 @@ struct be_cmd_resp_set_func_cap {
u8 rsvd[212];
};
+/*************** HW Stats Get v1 **********************************/
+#define BE_TXP_SW_SZ 48
+struct be_port_rxf_stats_v1 {
+ u32 rsvd0[12];
+ u32 rx_crc_errors;
+ u32 rx_alignment_symbol_errors;
+ u32 rx_pause_frames;
+ u32 rx_priority_pause_frames;
+ u32 rx_control_frames;
+ u32 rx_in_range_errors;
+ u32 rx_out_range_errors;
+ u32 rx_frame_too_long;
+ u32 rx_address_match_errors;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+ u32 rx_dropped_tcp_length;
+ u32 rx_dropped_runt;
+ u32 rsvd1[10];
+ u32 rx_ip_checksum_errs;
+ u32 rx_tcp_checksum_errs;
+ u32 rx_udp_checksum_errs;
+ u32 rsvd2[7];
+ u32 rx_switched_unicast_packets;
+ u32 rx_switched_multicast_packets;
+ u32 rx_switched_broadcast_packets;
+ u32 rsvd3[3];
+ u32 tx_pauseframes;
+ u32 tx_priority_pauseframes;
+ u32 tx_controlframes;
+ u32 rsvd4[10];
+ u32 rxpp_fifo_overflow_drop;
+ u32 rx_input_fifo_overflow_drop;
+ u32 pmem_fifo_overflow_drop;
+ u32 jabber_events;
+ u32 rsvd5[3];
+};
+
+
+struct be_rxf_stats_v1 {
+ struct be_port_rxf_stats_v1 port[4];
+ u32 rsvd0[2];
+ u32 rx_drops_no_pbuf;
+ u32 rx_drops_no_txpb;
+ u32 rx_drops_no_erx_descr;
+ u32 rx_drops_no_tpre_descr;
+ u32 rsvd1[6];
+ u32 rx_drops_too_many_frags;
+ u32 rx_drops_invalid_ring;
+ u32 forwarded_packets;
+ u32 rx_drops_mtu;
+ u32 rsvd2[14];
+};
+
+struct be_erx_stats_v1 {
+ u32 rx_drops_no_fragments[68]; /* dwordS 0 to 67*/
+ u32 rsvd[4];
+};
+
+struct be_hw_stats_v1 {
+ struct be_rxf_stats_v1 rxf;
+ u32 rsvd0[BE_TXP_SW_SZ];
+ struct be_erx_stats_v1 erx;
+ struct be_pmem_stats pmem;
+ u32 rsvd1[3];
+};
+
+struct be_cmd_req_get_stats_v1 {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd[sizeof(struct be_hw_stats_v1)];
+};
+
+struct be_cmd_resp_get_stats_v1 {
+ struct be_cmd_resp_hdr hdr;
+ struct be_hw_stats_v1 hw_stats;
+};
+
+static inline void *
+hw_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va;
+
+ return &cmd->hw_stats;
+ } else {
+ struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va;
+
+ return &cmd->hw_stats;
+ }
+}
+
+static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+ struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
+
+ return &rxf_stats->port[adapter->port_num];
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+ struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
+
+ return &rxf_stats->port[adapter->port_num];
+ }
+}
+
+static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->rxf;
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->rxf;
+ }
+}
+
+static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->erx;
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->erx;
+ }
+}
+
+static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->pmem;
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->pmem;
+ }
+}
+
extern int be_pci_fnum_get(struct be_adapter *adapter);
extern int be_cmd_POST(struct be_adapter *adapter);
extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 8e770e8..facfe3c 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -26,8 +26,8 @@ struct be_ethtool_stat {
int offset;
};
-enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
- PMEMSTAT, DRVSTAT};
+enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
+ DRVSTAT};
#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
offsetof(_struct, field)
#define NETSTAT_INFO(field) #field, NETSTAT,\
@@ -37,15 +37,8 @@ enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
FIELDINFO(struct be_tx_stats, field)
#define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\
FIELDINFO(struct be_rx_stats, field)
-#define MISCSTAT_INFO(field) #field, MISCSTAT,\
- FIELDINFO(struct be_rxf_stats, field)
-#define PORTSTAT_INFO(field) #field, PORTSTAT,\
- FIELDINFO(struct be_port_rxf_stats, \
- field)
-#define ERXSTAT_INFO(field) #field, ERXSTAT,\
- FIELDINFO(struct be_erx_stats, field)
-#define PMEMSTAT_INFO(field) #field, PMEMSTAT,\
- FIELDINFO(struct be_pmem_stats, field)
+#define ERXSTAT_INFO(field) #field, ERXSTAT,\
+ FIELDINFO(struct be_erx_stats_v1, field)
#define DRVSTAT_INFO(field) #field, DRVSTAT,\
FIELDINFO(struct be_drv_stats, \
field)
@@ -65,50 +58,41 @@ static const struct be_ethtool_stat et_stats[] = {
{DRVSTAT_TX_INFO(be_tx_stops)},
{DRVSTAT_TX_INFO(be_tx_events)},
{DRVSTAT_TX_INFO(be_tx_compl)},
- {PORTSTAT_INFO(rx_unicast_frames)},
- {PORTSTAT_INFO(rx_multicast_frames)},
- {PORTSTAT_INFO(rx_broadcast_frames)},
- {PORTSTAT_INFO(rx_crc_errors)},
- {PORTSTAT_INFO(rx_alignment_symbol_errors)},
- {PORTSTAT_INFO(rx_pause_frames)},
- {PORTSTAT_INFO(rx_control_frames)},
- {PORTSTAT_INFO(rx_in_range_errors)},
- {PORTSTAT_INFO(rx_out_range_errors)},
- {PORTSTAT_INFO(rx_frame_too_long)},
- {PORTSTAT_INFO(rx_address_match_errors)},
- {PORTSTAT_INFO(rx_vlan_mismatch)},
- {PORTSTAT_INFO(rx_dropped_too_small)},
- {PORTSTAT_INFO(rx_dropped_too_short)},
- {PORTSTAT_INFO(rx_dropped_header_too_small)},
- {PORTSTAT_INFO(rx_dropped_tcp_length)},
- {PORTSTAT_INFO(rx_dropped_runt)},
- {PORTSTAT_INFO(rx_fifo_overflow)},
- {PORTSTAT_INFO(rx_input_fifo_overflow)},
- {PORTSTAT_INFO(rx_ip_checksum_errs)},
- {PORTSTAT_INFO(rx_tcp_checksum_errs)},
- {PORTSTAT_INFO(rx_udp_checksum_errs)},
- {PORTSTAT_INFO(rx_non_rss_packets)},
- {PORTSTAT_INFO(rx_ipv4_packets)},
- {PORTSTAT_INFO(rx_ipv6_packets)},
- {PORTSTAT_INFO(rx_switched_unicast_packets)},
- {PORTSTAT_INFO(rx_switched_multicast_packets)},
- {PORTSTAT_INFO(rx_switched_broadcast_packets)},
- {PORTSTAT_INFO(tx_unicastframes)},
- {PORTSTAT_INFO(tx_multicastframes)},
- {PORTSTAT_INFO(tx_broadcastframes)},
- {PORTSTAT_INFO(tx_pauseframes)},
- {PORTSTAT_INFO(tx_controlframes)},
- {MISCSTAT_INFO(rx_drops_no_pbuf)},
- {MISCSTAT_INFO(rx_drops_no_txpb)},
- {MISCSTAT_INFO(rx_drops_no_erx_descr)},
- {MISCSTAT_INFO(rx_drops_no_tpre_descr)},
- {MISCSTAT_INFO(rx_drops_too_many_frags)},
- {MISCSTAT_INFO(rx_drops_invalid_ring)},
- {MISCSTAT_INFO(forwarded_packets)},
- {MISCSTAT_INFO(rx_drops_mtu)},
- {MISCSTAT_INFO(port0_jabber_events)},
- {MISCSTAT_INFO(port1_jabber_events)},
- {PMEMSTAT_INFO(eth_red_drops)},
+ {DRVSTAT_INFO(rx_crc_errors)},
+ {DRVSTAT_INFO(rx_alignment_symbol_errors)},
+ {DRVSTAT_INFO(rx_pause_frames)},
+ {DRVSTAT_INFO(rx_control_frames)},
+ {DRVSTAT_INFO(rx_in_range_errors)},
+ {DRVSTAT_INFO(rx_out_range_errors)},
+ {DRVSTAT_INFO(rx_frame_too_long)},
+ {DRVSTAT_INFO(rx_address_match_errors)},
+ {DRVSTAT_INFO(rx_dropped_too_small)},
+ {DRVSTAT_INFO(rx_dropped_too_short)},
+ {DRVSTAT_INFO(rx_dropped_header_too_small)},
+ {DRVSTAT_INFO(rx_dropped_tcp_length)},
+ {DRVSTAT_INFO(rx_dropped_runt)},
+ {DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
+ {DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
+ {DRVSTAT_INFO(rx_ip_checksum_errs)},
+ {DRVSTAT_INFO(rx_tcp_checksum_errs)},
+ {DRVSTAT_INFO(rx_udp_checksum_errs)},
+ {DRVSTAT_INFO(rx_switched_unicast_packets)},
+ {DRVSTAT_INFO(rx_switched_multicast_packets)},
+ {DRVSTAT_INFO(rx_switched_broadcast_packets)},
+ {DRVSTAT_INFO(tx_pauseframes)},
+ {DRVSTAT_INFO(tx_controlframes)},
+ {DRVSTAT_INFO(rx_priority_pause_frames)},
+ {DRVSTAT_INFO(pmem_fifo_overflow_drop)},
+ {DRVSTAT_INFO(jabber_events)},
+ {DRVSTAT_INFO(rx_drops_no_pbuf)},
+ {DRVSTAT_INFO(rx_drops_no_txpb)},
+ {DRVSTAT_INFO(rx_drops_no_erx_descr)},
+ {DRVSTAT_INFO(rx_drops_no_tpre_descr)},
+ {DRVSTAT_INFO(rx_drops_too_many_frags)},
+ {DRVSTAT_INFO(rx_drops_invalid_ring)},
+ {DRVSTAT_INFO(forwarded_packets)},
+ {DRVSTAT_INFO(rx_drops_mtu)},
+ {DRVSTAT_INFO(eth_red_drops)},
{DRVSTAT_INFO(be_on_die_temperature)}
};
#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
@@ -268,8 +252,6 @@ be_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va);
- struct be_erx_stats *erx_stats = &hw_stats->erx;
struct be_rx_obj *rxo;
void *p = NULL;
int i, j;
@@ -282,15 +264,6 @@ be_get_ethtool_stats(struct net_device *netdev,
case DRVSTAT_TX:
p = &adapter->tx_stats;
break;
- case PORTSTAT:
- p = &hw_stats->rxf.port[adapter->port_num];
- break;
- case MISCSTAT:
- p = &hw_stats->rxf;
- break;
- case PMEMSTAT:
- p = &hw_stats->pmem;
- break;
case DRVSTAT:
p = &adapter->drv_stats;
break;
@@ -308,7 +281,8 @@ be_get_ethtool_stats(struct net_device *netdev,
p = (u8 *)&rxo->stats + et_rx_stats[i].offset;
break;
case ERXSTAT:
- p = (u32 *)erx_stats + rxo->q.id;
+ p = (u32 *)be_erx_stats_from_cmd(adapter) +
+ rxo->q.id;
break;
}
data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] =
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 243172b..cff2cca 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -245,14 +245,126 @@ netdev_addr:
return status;
}
+static void populate_be2_stats(struct be_adapter *adapter)
+{
+
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+ struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+ struct be_port_rxf_stats_v0 *port_stats =
+ be_port_rxf_stats_from_cmd(adapter);
+ struct be_rxf_stats_v0 *rxf_stats =
+ be_rxf_stats_from_cmd(adapter);
+
+ drvs->rx_pause_frames = port_stats->rx_pause_frames;
+ drvs->rx_crc_errors = port_stats->rx_crc_errors;
+ drvs->rx_control_frames = port_stats->rx_control_frames;
+ drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
+ drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
+ drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
+ drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+ drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+ drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+ drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow;
+ drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
+ drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
+ drvs->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow;
+ drvs->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ drvs->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ drvs->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+
+ drvs->tx_pauseframes = port_stats->tx_pauseframes;
+ drvs->tx_controlframes = port_stats->tx_controlframes;
+
+ if (adapter->port_num)
+ drvs->jabber_events =
+ rxf_stats->port1_jabber_events;
+ else
+ drvs->jabber_events =
+ rxf_stats->port0_jabber_events;
+ drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+ drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+ drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ drvs->forwarded_packets = rxf_stats->forwarded_packets;
+ drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ drvs->rx_drops_no_tpre_descr =
+ rxf_stats->rx_drops_no_tpre_descr;
+ drvs->rx_drops_too_many_frags =
+ rxf_stats->rx_drops_too_many_frags;
+ adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
+}
+
+static void populate_be3_stats(struct be_adapter *adapter)
+{
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+ struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+
+ struct be_rxf_stats_v1 *rxf_stats =
+ be_rxf_stats_from_cmd(adapter);
+ struct be_port_rxf_stats_v1 *port_stats =
+ be_port_rxf_stats_from_cmd(adapter);
+
+ drvs->rx_priority_pause_frames = 0;
+ drvs->pmem_fifo_overflow_drop = 0;
+ drvs->rx_pause_frames = port_stats->rx_pause_frames;
+ drvs->rx_crc_errors = port_stats->rx_crc_errors;
+ drvs->rx_control_frames = port_stats->rx_control_frames;
+ drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
+ drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
+ drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
+ drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+ drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+ drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+ drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
+ drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
+ drvs->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ drvs->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow_drop;
+ drvs->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ drvs->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+ drvs->rxpp_fifo_overflow_drop =
+ port_stats->rxpp_fifo_overflow_drop;
+ drvs->tx_pauseframes = port_stats->tx_pauseframes;
+ drvs->tx_controlframes = port_stats->tx_controlframes;
+ drvs->jabber_events = port_stats->jabber_events;
+ drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+ drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+ drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ drvs->forwarded_packets = rxf_stats->forwarded_packets;
+ drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ drvs->rx_drops_no_tpre_descr =
+ rxf_stats->rx_drops_no_tpre_descr;
+ drvs->rx_drops_too_many_frags =
+ rxf_stats->rx_drops_too_many_frags;
+ adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
+}
+
+
+
+void be_parse_stats(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3)
+ populate_be3_stats(adapter);
+ else
+ populate_be2_stats(adapter);
+}
+
void netdev_stats_update(struct be_adapter *adapter)
{
- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va);
- struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
- struct be_port_rxf_stats *port_stats =
- &rxf_stats->port[adapter->port_num];
+ struct be_drv_stats *drvs = &adapter->drv_stats;
struct net_device_stats *dev_stats = &adapter->netdev->stats;
- struct be_erx_stats *erx_stats = &hw_stats->erx;
struct be_rx_obj *rxo;
int i;
@@ -262,43 +374,52 @@ void netdev_stats_update(struct be_adapter *adapter)
dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes;
dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
/* no space in linux buffers: best possible approximation */
- dev_stats->rx_dropped +=
- erx_stats->rx_drops_no_fragments[rxo->q.id];
+ if (adapter->generation == BE_GEN3) {
+ struct be_erx_stats_v1 *erx_stats =
+ be_erx_stats_from_cmd(adapter);
+ dev_stats->rx_dropped +=
+ erx_stats->rx_drops_no_fragments[rxo->q.id];
+ } else {
+ struct be_erx_stats_v0 *erx_stats =
+ be_erx_stats_from_cmd(adapter);
+ dev_stats->rx_dropped +=
+ erx_stats->rx_drops_no_fragments[rxo->q.id];
+ }
}
dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts;
dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes;
/* bad pkts received */
- dev_stats->rx_errors = port_stats->rx_crc_errors +
- port_stats->rx_alignment_symbol_errors +
- port_stats->rx_in_range_errors +
- port_stats->rx_out_range_errors +
- port_stats->rx_frame_too_long +
- port_stats->rx_dropped_too_small +
- port_stats->rx_dropped_too_short +
- port_stats->rx_dropped_header_too_small +
- port_stats->rx_dropped_tcp_length +
- port_stats->rx_dropped_runt +
- port_stats->rx_tcp_checksum_errs +
- port_stats->rx_ip_checksum_errs +
- port_stats->rx_udp_checksum_errs;
+ dev_stats->rx_errors = drvs->rx_crc_errors +
+ drvs->rx_alignment_symbol_errors +
+ drvs->rx_in_range_errors +
+ drvs->rx_out_range_errors +
+ drvs->rx_frame_too_long +
+ drvs->rx_dropped_too_small +
+ drvs->rx_dropped_too_short +
+ drvs->rx_dropped_header_too_small +
+ drvs->rx_dropped_tcp_length +
+ drvs->rx_dropped_runt +
+ drvs->rx_tcp_checksum_errs +
+ drvs->rx_ip_checksum_errs +
+ drvs->rx_udp_checksum_errs;
/* detailed rx errors */
- dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
- port_stats->rx_out_range_errors +
- port_stats->rx_frame_too_long;
+ dev_stats->rx_length_errors = drvs->rx_in_range_errors +
+ drvs->rx_out_range_errors +
+ drvs->rx_frame_too_long;
- dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
+ dev_stats->rx_crc_errors = drvs->rx_crc_errors;
/* frame alignment errors */
- dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors;
+ dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
/* receiver fifo overrun */
/* drops_no_pbuf is no per i/f, it's per BE card */
- dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
- port_stats->rx_input_fifo_overflow +
- rxf_stats->rx_drops_no_pbuf;
+ dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
+ drvs->rx_input_fifo_overflow_drop +
+ drvs->rx_drops_no_pbuf;
}
void be_link_status_update(struct be_adapter *adapter, bool link_up)
@@ -2823,7 +2944,10 @@ static int be_stats_init(struct be_adapter *adapter)
{
struct be_dma_mem *cmd = &adapter->stats_cmd;
- cmd->size = sizeof(struct be_cmd_req_get_stats);
+ if (adapter->generation == BE_GEN2)
+ cmd->size = sizeof(struct be_cmd_req_get_stats_v0);
+ else
+ cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
GFP_KERNEL);
if (cmd->va == NULL)
--
1.6.0.2
^ permalink raw reply related
* [PATCH net-next-2.6 0/3] be2net: patch series
From: Padmanabh Ratnakar @ 2011-05-16 17:36 UTC (permalink / raw)
To: davem, netdev; +Cc: Padmanabh Ratnakar
Please Apply.
Thanks,
Padmanabh
Padmanabh Ratnakar (3):
be2net: Support for version 1 of stats for BE3
be2net: Stats for Lancer
be2net: FW download for Lancer
drivers/net/benet/be.h | 38 ++++
drivers/net/benet/be_cmds.c | 161 +++++++++++++++-
drivers/net/benet/be_cmds.h | 414 +++++++++++++++++++++++++++++++++++++---
drivers/net/benet/be_ethtool.c | 108 ++++-------
drivers/net/benet/be_main.c | 386 ++++++++++++++++++++++++++++++++-----
5 files changed, 956 insertions(+), 151 deletions(-)
^ permalink raw reply
* Re: [PATCH 1/1] netlink: nla_nest_end return "unsigned init"
From: John W. Linville @ 2011-05-16 17:35 UTC (permalink / raw)
To: Wey-Yi Guy
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1305555810-17565-1-git-send-email-wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
This should go to netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org instead...
On Mon, May 16, 2011 at 07:23:30AM -0700, Wey-Yi Guy wrote:
> skb->len has unsigned int, return the correct value from nla_nest_end call.
>
> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> include/net/netlink.h | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/netlink.h b/include/net/netlink.h
> index 8a3906a..241fc0d 100644
> --- a/include/net/netlink.h
> +++ b/include/net/netlink.h
> @@ -1015,7 +1015,8 @@ static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
> *
> * Returns the total data length of the skb.
> */
> -static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
> +static inline unsigned int nla_nest_end(struct sk_buff *skb,
> + struct nlattr *start)
> {
> start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
> return skb->len;
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
John W. Linville Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org might be all we have. Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next-2.6] ipv4: more compliant RFC 3168 support
From: Eric Dumazet @ 2011-05-16 17:16 UTC (permalink / raw)
To: Stefanos Harhalakis; +Cc: David Miller, netdev
In-Reply-To: <1305475310.3120.146.camel@edumazet-laptop>
Le dimanche 15 mai 2011 à 18:01 +0200, Eric Dumazet a écrit :
> Problem of this version is that common frames in the Internet (NOT_ECT
> or ECT_X or ECT_X) will take the longest path to come to "return 0;"
>
> a switch() version is fast because gcc emits a table based jump
Oh well, a table lookup is even faster...
I'll submit another version
^ permalink raw reply
* Re: [PATCH] vmxnet3: Fix inconsistent LRO state after initialization
From: Stephen Hemminger @ 2011-05-16 17:14 UTC (permalink / raw)
To: Thomas Jarosch; +Cc: netdev, Shreyas Bhatewara
In-Reply-To: <201105161828.15237.thomas.jarosch@intra2net.com>
On Mon, 16 May 2011 18:28:15 +0200
Thomas Jarosch <thomas.jarosch@intra2net.com> wrote:
> During initialization of vmxnet3, the state of LRO
> gets out of sync with netdev->features.
>
> This leads to very poor TCP performance in a IP forwarding
> setup and is hitting many VMware users.
>
> Simplified call sequence:
> 1. vmxnet3_declare_features() initializes "adapter->lro" to true.
>
> 2. The kernel automatically disables LRO if IP forwarding is enabled,
> so vmxnet3_set_flags() gets called. This also updates netdev->features.
>
> 3. Now vmxnet3_setup_driver_shared() is called. "adapter->lro" is still
> set to true and LRO gets enabled again, even though
> netdev->features shows it's disabled.
>
> Fix it by updating "adapter->lro", too.
>
>
> The private vmxnet3 adapter flags are scheduled for removal
> in net-next, see commit a0d2730c9571aeba793cb5d3009094ee1d8fda35
> "net: vmxnet3: convert to hw_features".
>
> Patch applies to 2.6.37 / 2.6.38 and 2.6.39-rc6.
>
> Please CC: comments.
>
> Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com>
>
> diff -u -r -p linux-2.6.37.i686/drivers/net/vmxnet3/vmxnet3_ethtool.c linux-2.6.37.lro/drivers/net/vmxnet3/vmxnet3_ethtool.c
> --- linux-2.6.37.i686/drivers/net/vmxnet3/vmxnet3_ethtool.c 2011-05-16 17:43:26.652081801 +0200
> +++ linux-2.6.37.lro/drivers/net/vmxnet3/vmxnet3_ethtool.c 2011-05-16 17:47:52.784081802 +0200
> @@ -287,6 +287,9 @@ vmxnet3_set_flags(struct net_device *net
> /* toggle the LRO feature*/
> netdev->features ^= NETIF_F_LRO;
>
> + /* Update private LRO flag */
> + adapter->lro = lro_requested;
> +
> /* update harware LRO capability accordingly */
> if (lro_requested)
> adapter->shared->devRead.misc.uptFeatures |=
Thanks for finding this. Vyatta ended up changing the default of adapter->lro
to workaround just this problem
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
--
^ permalink raw reply
* [PATCH] vmxnet3: Fix inconsistent LRO state after initialization
From: Thomas Jarosch @ 2011-05-16 16:28 UTC (permalink / raw)
To: netdev; +Cc: Shreyas Bhatewara
During initialization of vmxnet3, the state of LRO
gets out of sync with netdev->features.
This leads to very poor TCP performance in a IP forwarding
setup and is hitting many VMware users.
Simplified call sequence:
1. vmxnet3_declare_features() initializes "adapter->lro" to true.
2. The kernel automatically disables LRO if IP forwarding is enabled,
so vmxnet3_set_flags() gets called. This also updates netdev->features.
3. Now vmxnet3_setup_driver_shared() is called. "adapter->lro" is still
set to true and LRO gets enabled again, even though
netdev->features shows it's disabled.
Fix it by updating "adapter->lro", too.
The private vmxnet3 adapter flags are scheduled for removal
in net-next, see commit a0d2730c9571aeba793cb5d3009094ee1d8fda35
"net: vmxnet3: convert to hw_features".
Patch applies to 2.6.37 / 2.6.38 and 2.6.39-rc6.
Please CC: comments.
Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com>
diff -u -r -p linux-2.6.37.i686/drivers/net/vmxnet3/vmxnet3_ethtool.c linux-2.6.37.lro/drivers/net/vmxnet3/vmxnet3_ethtool.c
--- linux-2.6.37.i686/drivers/net/vmxnet3/vmxnet3_ethtool.c 2011-05-16 17:43:26.652081801 +0200
+++ linux-2.6.37.lro/drivers/net/vmxnet3/vmxnet3_ethtool.c 2011-05-16 17:47:52.784081802 +0200
@@ -287,6 +287,9 @@ vmxnet3_set_flags(struct net_device *net
/* toggle the LRO feature*/
netdev->features ^= NETIF_F_LRO;
+ /* Update private LRO flag */
+ adapter->lro = lro_requested;
+
/* update harware LRO capability accordingly */
if (lro_requested)
adapter->shared->devRead.misc.uptFeatures |=
^ permalink raw reply
* Re: [ethtool PATCH 0/4] v6 Add support for network flow classifier
From: Alexander Duyck @ 2011-05-16 16:32 UTC (permalink / raw)
To: Ben Hutchings
Cc: davem@davemloft.net, Kirsher, Jeffrey T, dm@chelsio.com,
netdev@vger.kernel.org
In-Reply-To: <1305249292.14174.13.camel@bwh-desktop>
On 5/12/2011 6:14 PM, Ben Hutchings wrote:
> Thanks a lot for persevering with this, Alexander.
>
> I've applied this series with minor changes to the last patch. I
> abbreviated the version history in the commit message, and I deleted a
> blank line in the manual page additions which made the indentation wrong
> for the -U option. I also recorded the author as you, since you've
> largely rewritten it! The commit message credits Santwona Behera.
>
> You managed to uncover a bug in the sfc driver, which is that
> set_rx_ntuple can return a positive value. Previously ethtool accepted
> any non-negative return value as successful, so I made a separate commit
> to restore that behaviour. Of course I'll fix the driver too.
>
> Ben.
>
Thanks for getting this all applied. Our validation team is now testing
the ixgbe patches with your version of ethtool and if I hear about any
other bugs I might have introduced I will let you know.
Alex
^ permalink raw reply
* [PATCH net-2.6] sfc: Fix oops in register dump after mapping change
From: Ben Hutchings @ 2011-05-16 16:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Commit 747df2258b1b9a2e25929ef496262c339c380009 ('sfc: Always map MCDI
shared memory as uncacheable') introduced a separate mapping for the
MCDI shared memory (MC_TREG_SMEM). This means we can no longer easily
include it in the register dump. Since it is not particularly useful
in debugging, substitute a recognisable dummy value.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
'ethtool -d' on a Siena controller will now result in an 'oops'. This
is not a huge problem because I suspect I'm the only one actually
actually using this feature. The patch is against net-2.6 because the
above commit has not yet been merged into net-next-2.6, but I don't
particularly mind if this misses 2.6.39.
Ben.
drivers/net/sfc/nic.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 10f1cb7..9b29a8d 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -1937,6 +1937,13 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf)
size = min_t(size_t, table->step, 16);
+ if (table->offset >= efx->type->mem_map_size) {
+ /* No longer mapped; return dummy data */
+ memcpy(buf, "\xde\xc0\xad\xde", 4);
+ buf += table->rows * size;
+ continue;
+ }
+
for (i = 0; i < table->rows; i++) {
switch (table->step) {
case 4: /* 32-bit register or SRAM */
--
1.7.4
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [RFC PATCH ethtool 3/3] ethtool: Use ETHTOOL_{G,S}FEATURES where available
From: Ben Hutchings @ 2011-05-16 15:58 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Michał Mirosław, netdev,
David Miller
In-Reply-To: <BANLkTi=Q_RrGgw0H=OeNeJ4JkkCgyYckFA@mail.gmail.com>
Also use the new structures in any case.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 294 +++++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 199 insertions(+), 95 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 5eeca64..db1873c 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -297,8 +297,7 @@ static void show_usage(void)
static char *devname = NULL;
static int goffload_changed = 0;
-static u32 off_features_wanted = 0;
-static u32 off_features_mask = 0;
+struct ethtool_set_features_block off_features;
static struct ethtool_pauseparam epause;
static int gpause_changed = 0;
@@ -439,30 +438,30 @@ static struct cmdline_info cmdline_seeprom[] = {
};
static struct cmdline_info cmdline_offload[] = {
- { "rx", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_RXCSUM, &off_features_mask },
- { "tx", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_ALL_CSUM, &off_features_mask },
- { "sg", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_SG, &off_features_mask },
- { "tso", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_ALL_TSO, &off_features_mask },
- { "ufo", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_UFO, &off_features_mask },
- { "gso", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_GSO, &off_features_mask },
- { "lro", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_LRO, &off_features_mask },
- { "gro", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_GRO, &off_features_mask },
- { "rxvlan", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_HW_VLAN_TX, &off_features_mask },
- { "txvlan", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_HW_VLAN_TX, &off_features_mask },
- { "ntuple", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_NTUPLE, &off_features_mask },
- { "rxhash", CMDL_FLAG, &off_features_wanted, NULL,
- NETIF_F_RXHASH, &off_features_mask },
+ { "rx", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_RXCSUM, &off_features.valid },
+ { "tx", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_ALL_CSUM, &off_features.valid },
+ { "sg", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_SG, &off_features.valid },
+ { "tso", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_ALL_TSO, &off_features.valid },
+ { "ufo", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_UFO, &off_features.valid },
+ { "gso", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_GSO, &off_features.valid },
+ { "lro", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_LRO, &off_features.valid },
+ { "gro", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_GRO, &off_features.valid },
+ { "rxvlan", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_HW_VLAN_TX, &off_features.valid },
+ { "txvlan", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_HW_VLAN_TX, &off_features.valid },
+ { "ntuple", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_NTUPLE, &off_features.valid },
+ { "rxhash", CMDL_FLAG, &off_features.requested, NULL,
+ NETIF_F_RXHASH, &off_features.valid },
};
static struct cmdline_info cmdline_pause[] = {
@@ -1807,7 +1806,8 @@ static const struct {
{ "receive-hashing", 0, NETIF_F_RXHASH },
};
-static int dump_offload(u32 active, u32 mask)
+static int
+dump_offload(const struct ethtool_get_features_block *features, u32 mask)
{
u32 value;
int i;
@@ -1816,9 +1816,12 @@ static int dump_offload(u32 active, u32 mask)
value = off_feature_def[i].value;
if (!(mask & value))
continue;
- printf("%s: %s\n",
+ printf("%s: %s%s%s\n",
off_feature_def[i].long_name,
- (active & value) ? "on" : "off");
+ (features->active & value) ? "on" : "off",
+ (features->requested & ~features->active & value) ?
+ " [requested on]" : "",
+ !(features->available & value) ? " [unchangeable]" : "");
}
return 0;
@@ -2149,41 +2152,65 @@ static const u32 flags_dup_features =
(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
ETH_FLAG_RXHASH);
-static int get_offload(int fd, struct ifreq *ifr, u32 *features)
+static int get_offload(int fd, struct ifreq *ifr,
+ struct ethtool_get_features_block *pfeatures)
{
+ struct {
+ struct ethtool_gfeatures cmd;
+ struct ethtool_get_features_block data[1];
+ } features;
struct ethtool_value eval;
int err, allfail = 1;
u32 value;
int i;
- *features = 0;
+ features.cmd.cmd = ETHTOOL_GFEATURES;
+ features.cmd.size = ARRAY_SIZE(features.data);
+ ifr->ifr_data = (caddr_t)&features;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err == 0) {
+ allfail = 0;
+ pfeatures[0] = features.data[0];
+ } else if (errno != EOPNOTSUPP && errno != EPERM) {
+ perror("Cannot get device offload settings");
+ } else {
+ memset(pfeatures, 0, sizeof(*pfeatures));
- for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
- value = off_feature_def[i].value;
- if (!off_feature_def[i].cmd)
- continue;
- eval.cmd = off_feature_def[i].cmd;
+ for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
+ value = off_feature_def[i].value;
+
+ /* Assume that anything we can get is changeable */
+ pfeatures[0].available |= value;
+
+ if (!off_feature_def[i].cmd)
+ continue;
+
+ eval.cmd = off_feature_def[i].cmd;
+ ifr->ifr_data = (caddr_t)&eval;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ fprintf(stderr,
+ "Cannot get device %s settings: %m\n",
+ off_feature_def[i].long_name);
+ } else {
+ if (eval.data)
+ pfeatures[0].active |= value;
+ allfail = 0;
+ }
+ }
+
+ eval.cmd = ETHTOOL_GFLAGS;
ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = ioctl(fd, SIOCETHTOOL, ifr);
if (err) {
- fprintf(stderr,
- "Cannot get device %s settings: %m\n",
- off_feature_def[i].long_name);
+ perror("Cannot get device flags");
} else {
- if (eval.data)
- *features |= value;
+ pfeatures[0].active |=
+ eval.data & flags_dup_features;
allfail = 0;
}
- }
- eval.cmd = ETHTOOL_GFLAGS;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot get device flags");
- } else {
- *features |= eval.data & flags_dup_features;
- allfail = 0;
+ pfeatures[0].requested = pfeatures[0].active;
}
return allfail;
@@ -2191,7 +2218,7 @@ static int get_offload(int fd, struct ifreq *ifr, u32 *features)
static int do_goffload(int fd, struct ifreq *ifr)
{
- u32 features;
+ struct ethtool_get_features_block features;
fprintf(stdout, "Offload parameters for %s:\n", devname);
@@ -2200,79 +2227,156 @@ static int do_goffload(int fd, struct ifreq *ifr)
return 83;
}
- return dump_offload(features, ~(u32)0);
+ return dump_offload(&features, ~(u32)0);
}
static int do_soffload(int fd, struct ifreq *ifr)
{
- u32 old_features, new_features, diff;
- struct ethtool_value eval;
+ struct ethtool_get_features_block old_features, new_features;
+ struct {
+ struct ethtool_sfeatures cmd;
+ struct ethtool_set_features_block data[1];
+ } set_features;
+ int failed;
+ u32 diff;
int err;
int i;
+ if (off_features.valid == 0) {
+ fprintf(stdout, "no offload settings changed\n");
+ return 0;
+ }
+
if (get_offload(fd, ifr, &old_features)) {
fprintf(stderr, "no offload info available\n");
return 1;
}
+ set_features.cmd.cmd = ETHTOOL_SFEATURES;
+ set_features.cmd.size = ARRAY_SIZE(set_features.data);
+ set_features.data[0] = off_features;
+
for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
- if (!off_feature_def[i].cmd)
+ u32 value = off_feature_def[i].value;
+
+ if (!(off_features.valid & value))
continue;
- if (off_features_mask & off_feature_def[i].value) {
- eval.cmd = off_feature_def[i].cmd + 1;
- eval.data = !!(off_features_wanted &
- off_feature_def[i].value);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err) {
- fprintf(stderr,
- "Cannot set device %s settings: %m\n",
- off_feature_def[i].long_name);
- return 1;
- }
+ if (!(old_features.available & value)) {
+ /* None of these features can be changed */
+ fprintf(stderr,
+ "Cannot set device %s settings: "
+ "Operation not supported\n",
+ off_feature_def[i].long_name);
+ return 1;
}
+ /* At least some of these features can be
+ * enabled; mask out any that cannot
+ */
+ set_features.data[0].valid &=
+ ~(value & ~old_features.available);
}
- if (off_features_mask & flags_dup_features) {
- eval.cmd = ETHTOOL_GFLAGS;
- eval.data = 0;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot get device flag settings");
- return 91;
+
+ ifr->ifr_data = (caddr_t)&set_features;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err >= 0) {
+ /* We'll break down the warnings/errors below */
+ } else if (errno != EOPNOTSUPP && errno != EPERM) {
+ perror("Cannot set device offload settings");
+ return 1;
+ } else {
+ struct ethtool_value eval;
+
+ for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
+ if (!off_feature_def[i].cmd)
+ continue;
+ if (off_features.valid & off_feature_def[i].value) {
+ eval.cmd = off_feature_def[i].cmd + 1;
+ eval.data = !!(off_features.requested &
+ off_feature_def[i].value);
+ ifr->ifr_data = (caddr_t)&eval;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ fprintf(stderr,
+ "Cannot set device %s settings: %m\n",
+ off_feature_def[i].long_name);
+ return 1;
+ }
+ }
}
+ if (off_features.valid & flags_dup_features) {
+ eval.cmd = ETHTOOL_GFLAGS;
+ eval.data = 0;
+ ifr->ifr_data = (caddr_t)&eval;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err) {
+ perror("Cannot get device flag settings");
+ return 91;
+ }
- eval.cmd = ETHTOOL_SFLAGS;
- eval.data &= ~(off_features_mask & flags_dup_features);
- eval.data |= (off_features_wanted &
- flags_dup_features);
+ eval.cmd = ETHTOOL_SFLAGS;
+ eval.data &= ~(off_features.valid & flags_dup_features);
+ eval.data |= (off_features.requested &
+ flags_dup_features);
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot set device flag settings");
- return 92;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err) {
+ perror("Cannot set device flag settings");
+ return 92;
+ }
}
}
- if (off_features_mask == 0) {
- fprintf(stdout, "no offload settings changed\n");
- return 0;
- }
-
- /* Were any additional changes made automatically? */
if (get_offload(fd, ifr, &new_features)) {
fprintf(stderr, "no offload info available\n");
return 1;
}
- diff = ((old_features & ~off_features_mask) |
- (off_features_wanted & off_features_mask)) ^
- new_features;
+
+ failed = 0;
+
+ /* Report specific failures */
+ for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
+ if (!(off_feature_def[i].value & off_features.valid))
+ continue;
+
+ /* For offloads where we have one name for multiple
+ * feature flags, squash them into a boolean.
+ */
+ if (!(off_features.requested & off_feature_def[i].value) !=
+ !(new_features.active & off_feature_def[i].value)) {
+ int did1 = 0;
+
+ fprintf(stderr,
+ "Cannot set device %s settings",
+ off_feature_def[i].long_name);
+ if (err & ETHTOOL_F_WISH) {
+ fprintf(stderr,
+ ": Feature depends on other settings");
+ did1++;
+ }
+ /* Report any remaining warning flags (including
+ * ETHTOOL_F_UNSUPPORTED, which should not be set
+ * since we checked for unsupported flags above).
+ */
+ if (err & ~ETHTOOL_F_WISH) {
+ fprintf(stderr, "%s Warning flags %#x",
+ did1 ? ";" : ":",
+ err & ~ETHTOOL_F_WISH);
+ }
+ fprintf(stderr, "\n");
+
+ failed = 1;
+ }
+ }
+
+ /* Were any additional changes made automatically? */
+ diff = (new_features.active ^ old_features.active) &
+ ~off_features.valid;
if (diff) {
printf("Additional changes:\n");
- dump_offload(new_features, diff);
+ dump_offload(&new_features, diff);
}
- return 0;
+ return failed;
}
static int do_gset(int fd, struct ifreq *ifr)
--
1.7.4
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [RFC PATCH ethtool 2/3] ethtool: Report any consequential offload feature changes
From: Ben Hutchings @ 2011-05-16 15:57 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Michał Mirosław, netdev,
David Miller
In-Reply-To: <BANLkTi=Q_RrGgw0H=OeNeJ4JkkCgyYckFA@mail.gmail.com>
When an offload feature is enabled or disabled, this can change the
state of other features that depend on it. Report any such changes.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 47 +++++++++++++++++++++++++++++++++++++++--------
1 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 419f349..5eeca64 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1807,13 +1807,15 @@ static const struct {
{ "receive-hashing", 0, NETIF_F_RXHASH },
};
-static int dump_offload(u32 active)
+static int dump_offload(u32 active, u32 mask)
{
u32 value;
int i;
for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
value = off_feature_def[i].value;
+ if (!(mask & value))
+ continue;
printf("%s: %s\n",
off_feature_def[i].long_name,
(active & value) ? "on" : "off");
@@ -2147,14 +2149,14 @@ static const u32 flags_dup_features =
(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
ETH_FLAG_RXHASH);
-static int do_goffload(int fd, struct ifreq *ifr)
+static int get_offload(int fd, struct ifreq *ifr, u32 *features)
{
struct ethtool_value eval;
int err, allfail = 1;
- u32 features = 0, value;
+ u32 value;
int i;
- fprintf(stdout, "Offload parameters for %s:\n", devname);
+ *features = 0;
for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
value = off_feature_def[i].value;
@@ -2169,7 +2171,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
off_feature_def[i].long_name);
} else {
if (eval.data)
- features |= value;
+ *features |= value;
allfail = 0;
}
}
@@ -2180,24 +2182,39 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err) {
perror("Cannot get device flags");
} else {
- features |= eval.data & flags_dup_features;
+ *features |= eval.data & flags_dup_features;
allfail = 0;
}
- if (allfail) {
+ return allfail;
+}
+
+static int do_goffload(int fd, struct ifreq *ifr)
+{
+ u32 features;
+
+ fprintf(stdout, "Offload parameters for %s:\n", devname);
+
+ if (get_offload(fd, ifr, &features)) {
fprintf(stdout, "no offload info available\n");
return 83;
}
- return dump_offload(features);
+ return dump_offload(features, ~(u32)0);
}
static int do_soffload(int fd, struct ifreq *ifr)
{
+ u32 old_features, new_features, diff;
struct ethtool_value eval;
int err;
int i;
+ if (get_offload(fd, ifr, &old_features)) {
+ fprintf(stderr, "no offload info available\n");
+ return 1;
+ }
+
for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
if (!off_feature_def[i].cmd)
continue;
@@ -2239,6 +2256,20 @@ static int do_soffload(int fd, struct ifreq *ifr)
if (off_features_mask == 0) {
fprintf(stdout, "no offload settings changed\n");
+ return 0;
+ }
+
+ /* Were any additional changes made automatically? */
+ if (get_offload(fd, ifr, &new_features)) {
+ fprintf(stderr, "no offload info available\n");
+ return 1;
+ }
+ diff = ((old_features & ~off_features_mask) |
+ (off_features_wanted & off_features_mask)) ^
+ new_features;
+ if (diff) {
+ printf("Additional changes:\n");
+ dump_offload(new_features, diff);
}
return 0;
--
1.7.4
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [RFC PATCH ethtool 1/3] ethtool: Regularise offload feature settings
From: Ben Hutchings @ 2011-05-16 15:57 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Michał Mirosław, netdev,
David Miller
In-Reply-To: <BANLkTi=Q_RrGgw0H=OeNeJ4JkkCgyYckFA@mail.gmail.com>
This is partly preparation for use of the new net device features API,
but is useful in its own right.
Replace repetitive code for getting/setting offload flags with data-
driven loops.
This changes error messages to use the same long names for offload
flags as in dump_offload(), and changes various exit codes to 1.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool-util.h | 24 ++++
ethtool.c | 321 ++++++++++++++++++-------------------------------------
2 files changed, 129 insertions(+), 216 deletions(-)
diff --git a/ethtool-util.h b/ethtool-util.h
index 79be7f2..10b8c00 100644
--- a/ethtool-util.h
+++ b/ethtool-util.h
@@ -67,6 +67,30 @@ static inline u64 cpu_to_be64(u64 value)
#define RX_CLS_LOC_UNSPEC 0xffffffffUL
+#ifndef NETIF_F_SG
+#define NETIF_F_SG (1 << 0)
+#define NETIF_F_IP_CSUM (1 << 1)
+#define NETIF_F_NO_CSUM (1 << 2)
+#define NETIF_F_HW_CSUM (1 << 3)
+#define NETIF_F_IPV6_CSUM (1 << 4)
+#define NETIF_F_HW_VLAN_TX (1 << 7)
+#define NETIF_F_HW_VLAN_RX (1 << 8)
+#define NETIF_F_HW_VLAN_FILTER (1 << 9)
+#define NETIF_F_GSO (1 << 11)
+#define NETIF_F_GRO (1 << 14)
+#define NETIF_F_LRO (1 << 15)
+#define NETIF_F_TSO (1 << 16)
+#define NETIF_F_UFO (1 << 17)
+#define NETIF_F_TSO_ECN (1 << 19)
+#define NETIF_F_TSO6 (1 << 20)
+#define NETIF_F_NTUPLE (1 << 27)
+#define NETIF_F_RXHASH (1 << 28)
+#define NETIF_F_RXCSUM (1 << 29)
+#define NETIF_F_ALL_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM | \
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)
+#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
+#endif
+
/* National Semiconductor DP83815, DP83816 */
int natsemi_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
int natsemi_dump_eeprom(struct ethtool_drvinfo *info,
diff --git a/ethtool.c b/ethtool.c
index 34fe107..419f349 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -297,15 +297,8 @@ static void show_usage(void)
static char *devname = NULL;
static int goffload_changed = 0;
-static int off_csum_rx_wanted = -1;
-static int off_csum_tx_wanted = -1;
-static int off_sg_wanted = -1;
-static int off_tso_wanted = -1;
-static int off_ufo_wanted = -1;
-static int off_gso_wanted = -1;
-static u32 off_flags_wanted = 0;
-static u32 off_flags_mask = 0;
-static int off_gro_wanted = -1;
+static u32 off_features_wanted = 0;
+static u32 off_features_mask = 0;
static struct ethtool_pauseparam epause;
static int gpause_changed = 0;
@@ -446,23 +439,30 @@ static struct cmdline_info cmdline_seeprom[] = {
};
static struct cmdline_info cmdline_offload[] = {
- { "rx", CMDL_BOOL, &off_csum_rx_wanted, NULL },
- { "tx", CMDL_BOOL, &off_csum_tx_wanted, NULL },
- { "sg", CMDL_BOOL, &off_sg_wanted, NULL },
- { "tso", CMDL_BOOL, &off_tso_wanted, NULL },
- { "ufo", CMDL_BOOL, &off_ufo_wanted, NULL },
- { "gso", CMDL_BOOL, &off_gso_wanted, NULL },
- { "lro", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_LRO, &off_flags_mask },
- { "gro", CMDL_BOOL, &off_gro_wanted, NULL },
- { "rxvlan", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_RXVLAN, &off_flags_mask },
- { "txvlan", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_TXVLAN, &off_flags_mask },
- { "ntuple", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_NTUPLE, &off_flags_mask },
- { "rxhash", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_RXHASH, &off_flags_mask },
+ { "rx", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_RXCSUM, &off_features_mask },
+ { "tx", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_ALL_CSUM, &off_features_mask },
+ { "sg", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_SG, &off_features_mask },
+ { "tso", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_ALL_TSO, &off_features_mask },
+ { "ufo", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_UFO, &off_features_mask },
+ { "gso", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_GSO, &off_features_mask },
+ { "lro", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_LRO, &off_features_mask },
+ { "gro", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_GRO, &off_features_mask },
+ { "rxvlan", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_HW_VLAN_TX, &off_features_mask },
+ { "txvlan", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_HW_VLAN_TX, &off_features_mask },
+ { "ntuple", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_NTUPLE, &off_features_mask },
+ { "rxhash", CMDL_FLAG, &off_features_wanted, NULL,
+ NETIF_F_RXHASH, &off_features_mask },
};
static struct cmdline_info cmdline_pause[] = {
@@ -1788,35 +1788,36 @@ static int dump_coalesce(void)
return 0;
}
-static int dump_offload(int rx, int tx, int sg, int tso, int ufo, int gso,
- int gro, int lro, int rxvlan, int txvlan, int ntuple,
- int rxhash)
+static const struct {
+ const char *long_name;
+ u32 cmd;
+ u32 value;
+} off_feature_def[] = {
+ { "rx-checksumming", ETHTOOL_GRXCSUM, NETIF_F_RXCSUM },
+ { "tx-checksumming", ETHTOOL_GTXCSUM, NETIF_F_ALL_CSUM },
+ { "scatter-gather", ETHTOOL_GSG, NETIF_F_SG },
+ { "tcp-segmentation-offload", ETHTOOL_GTSO, NETIF_F_ALL_TSO },
+ { "udp-fragmentation-offload", ETHTOOL_GUFO, NETIF_F_UFO },
+ { "generic-segmentation-offload", ETHTOOL_GGSO, NETIF_F_GSO },
+ { "generic-receive-offload", ETHTOOL_GGRO, NETIF_F_GRO },
+ { "large-receive-offload", 0, NETIF_F_LRO },
+ { "rx-vlan-offload", 0, NETIF_F_HW_VLAN_RX },
+ { "tx-vlan-offload", 0, NETIF_F_HW_VLAN_TX },
+ { "ntuple-filters", 0, NETIF_F_NTUPLE },
+ { "receive-hashing", 0, NETIF_F_RXHASH },
+};
+
+static int dump_offload(u32 active)
{
- fprintf(stdout,
- "rx-checksumming: %s\n"
- "tx-checksumming: %s\n"
- "scatter-gather: %s\n"
- "tcp-segmentation-offload: %s\n"
- "udp-fragmentation-offload: %s\n"
- "generic-segmentation-offload: %s\n"
- "generic-receive-offload: %s\n"
- "large-receive-offload: %s\n"
- "rx-vlan-offload: %s\n"
- "tx-vlan-offload: %s\n"
- "ntuple-filters: %s\n"
- "receive-hashing: %s\n",
- rx ? "on" : "off",
- tx ? "on" : "off",
- sg ? "on" : "off",
- tso ? "on" : "off",
- ufo ? "on" : "off",
- gso ? "on" : "off",
- gro ? "on" : "off",
- lro ? "on" : "off",
- rxvlan ? "on" : "off",
- txvlan ? "on" : "off",
- ntuple ? "on" : "off",
- rxhash ? "on" : "off");
+ u32 value;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
+ value = off_feature_def[i].value;
+ printf("%s: %s\n",
+ off_feature_def[i].long_name,
+ (active & value) ? "on" : "off");
+ }
return 0;
}
@@ -2139,73 +2140,38 @@ static int do_scoalesce(int fd, struct ifreq *ifr)
return 0;
}
+/* the following list of flags are the same as their associated
+ * NETIF_F_xxx values in include/linux/netdevice.h
+ */
+static const u32 flags_dup_features =
+ (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
+ ETH_FLAG_RXHASH);
+
static int do_goffload(int fd, struct ifreq *ifr)
{
struct ethtool_value eval;
- int err, allfail = 1, rx = 0, tx = 0, sg = 0;
- int tso = 0, ufo = 0, gso = 0, gro = 0, lro = 0, rxvlan = 0, txvlan = 0,
- ntuple = 0, rxhash = 0;
+ int err, allfail = 1;
+ u32 features = 0, value;
+ int i;
fprintf(stdout, "Offload parameters for %s:\n", devname);
- eval.cmd = ETHTOOL_GRXCSUM;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err)
- perror("Cannot get device rx csum settings");
- else {
- rx = eval.data;
- allfail = 0;
- }
-
- eval.cmd = ETHTOOL_GTXCSUM;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err)
- perror("Cannot get device tx csum settings");
- else {
- tx = eval.data;
- allfail = 0;
- }
-
- eval.cmd = ETHTOOL_GSG;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err)
- perror("Cannot get device scatter-gather settings");
- else {
- sg = eval.data;
- allfail = 0;
- }
-
- eval.cmd = ETHTOOL_GTSO;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err)
- perror("Cannot get device tcp segmentation offload settings");
- else {
- tso = eval.data;
- allfail = 0;
- }
-
- eval.cmd = ETHTOOL_GUFO;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err)
- perror("Cannot get device udp large send offload settings");
- else {
- ufo = eval.data;
- allfail = 0;
- }
-
- eval.cmd = ETHTOOL_GGSO;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err)
- perror("Cannot get device generic segmentation offload settings");
- else {
- gso = eval.data;
- allfail = 0;
+ for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
+ value = off_feature_def[i].value;
+ if (!off_feature_def[i].cmd)
+ continue;
+ eval.cmd = off_feature_def[i].cmd;
+ ifr->ifr_data = (caddr_t)&eval;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ fprintf(stderr,
+ "Cannot get device %s settings: %m\n",
+ off_feature_def[i].long_name);
+ } else {
+ if (eval.data)
+ features |= value;
+ allfail = 0;
+ }
}
eval.cmd = ETHTOOL_GFLAGS;
@@ -2214,21 +2180,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err) {
perror("Cannot get device flags");
} else {
- lro = (eval.data & ETH_FLAG_LRO) != 0;
- rxvlan = (eval.data & ETH_FLAG_RXVLAN) != 0;
- txvlan = (eval.data & ETH_FLAG_TXVLAN) != 0;
- ntuple = (eval.data & ETH_FLAG_NTUPLE) != 0;
- rxhash = (eval.data & ETH_FLAG_RXHASH) != 0;
- allfail = 0;
- }
-
- eval.cmd = ETHTOOL_GGRO;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err)
- perror("Cannot get device GRO settings");
- else {
- gro = eval.data;
+ features |= eval.data & flags_dup_features;
allfail = 0;
}
@@ -2237,86 +2189,33 @@ static int do_goffload(int fd, struct ifreq *ifr)
return 83;
}
- return dump_offload(rx, tx, sg, tso, ufo, gso, gro, lro, rxvlan, txvlan,
- ntuple, rxhash);
+ return dump_offload(features);
}
static int do_soffload(int fd, struct ifreq *ifr)
{
struct ethtool_value eval;
- int err, changed = 0;
-
- if (off_csum_rx_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_SRXCSUM;
- eval.data = (off_csum_rx_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err) {
- perror("Cannot set device rx csum settings");
- return 84;
- }
- }
-
- if (off_csum_tx_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_STXCSUM;
- eval.data = (off_csum_tx_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err) {
- perror("Cannot set device tx csum settings");
- return 85;
- }
- }
-
- if (off_sg_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_SSG;
- eval.data = (off_sg_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err) {
- perror("Cannot set device scatter-gather settings");
- return 86;
- }
- }
+ int err;
+ int i;
- if (off_tso_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_STSO;
- eval.data = (off_tso_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
- if (err) {
- perror("Cannot set device tcp segmentation offload settings");
- return 88;
- }
- }
- if (off_ufo_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_SUFO;
- eval.data = (off_ufo_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot set device udp large send offload settings");
- return 89;
- }
- }
- if (off_gso_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_SGSO;
- eval.data = (off_gso_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot set device generic segmentation offload settings");
- return 90;
+ for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
+ if (!off_feature_def[i].cmd)
+ continue;
+ if (off_features_mask & off_feature_def[i].value) {
+ eval.cmd = off_feature_def[i].cmd + 1;
+ eval.data = !!(off_features_wanted &
+ off_feature_def[i].value);
+ ifr->ifr_data = (caddr_t)&eval;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ fprintf(stderr,
+ "Cannot set device %s settings: %m\n",
+ off_feature_def[i].long_name);
+ return 1;
+ }
}
}
- if (off_flags_mask) {
- changed = 1;
+ if (off_features_mask & flags_dup_features) {
eval.cmd = ETHTOOL_GFLAGS;
eval.data = 0;
ifr->ifr_data = (caddr_t)&eval;
@@ -2327,8 +2226,9 @@ static int do_soffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_SFLAGS;
- eval.data = ((eval.data & ~off_flags_mask) |
- off_flags_wanted);
+ eval.data &= ~(off_features_mask & flags_dup_features);
+ eval.data |= (off_features_wanted &
+ flags_dup_features);
err = ioctl(fd, SIOCETHTOOL, ifr);
if (err) {
@@ -2336,19 +2236,8 @@ static int do_soffload(int fd, struct ifreq *ifr)
return 92;
}
}
- if (off_gro_wanted >= 0) {
- changed = 1;
- eval.cmd = ETHTOOL_SGRO;
- eval.data = (off_gro_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot set device GRO settings");
- return 93;
- }
- }
- if (!changed) {
+ if (off_features_mask == 0) {
fprintf(stdout, "no offload settings changed\n");
}
--
1.7.4
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* Re: [PATCH net-next-2.6 v2] net: ping: dont call udp_ioctl()
From: David Miller @ 2011-05-16 15:50 UTC (permalink / raw)
To: eric.dumazet
Cc: solar, segoon, linux-kernel, netdev, peak, kees.cook,
dan.j.rosenberg, eugene, nelhage, kuznet, pekkas, jmorris,
yoshfuji, kaber
In-Reply-To: <1305530791.3120.217.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 16 May 2011 09:26:31 +0200
> Le dimanche 15 mai 2011 à 17:44 -0400, David Miller a écrit :
>
>> Just get rid of ping_ioctl() entirely, as that is the effect of
>> this change since inet_ioctl() returns -ENOIOCTLCMD when
>> sk_prot->ioctl is NULL.
>>
>> Also get rid of asm/ioctls.h since that will be no longer needed.
>
> Sure, here is updated version, thanks.
>
> [PATCH net-next-2.6 v2] net: ping: dont call udp_ioctl()
>
> udp_ioctl() really handles UDP and UDPLite protocols.
>
> 1) It can increment UDP_MIB_INERRORS in case first_packet_length() finds
> a frame with bad checksum.
>
> 2) It has a dependency on sizeof(struct udphdr), not applicable to
> ICMP/PING
>
> If ping sockets need to handle SIOCINQ/SIOCOUTQ ioctl, this should be
> done differently.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Vasiliy Kulikov <segoon@openwall.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] 2.6.38 ENC28J60 works with half-duplex DMA
From: David Miller @ 2011-05-16 15:48 UTC (permalink / raw)
To: elpa.rizzo; +Cc: netdev
In-Reply-To: <BANLkTinG+nj6CmqRYsUuC7MDWaKVFssNMA@mail.gmail.com>
You've sent this patch 3 times, we've noticed and seen them all,
our silence doesn't mean it hasn't been received.
What new thing do you hope to accomplish on each subsequent
submission?
^ permalink raw reply
* Re: kernel bug relating to networking
From: Daniel Baluta @ 2011-05-16 15:47 UTC (permalink / raw)
To: James; +Cc: Kernel Mailing List, netdev
In-Reply-To: <4DD14424.8000003@lockie.ca>
On Mon, May 16, 2011 at 6:35 PM, James <bjlockie@lockie.ca> wrote:
> I originally posted to linux-net@vger.kernel.org but all that list
This should be netdev@vger.kernel.org.
> received in the last day was 3 Russian (spam?) messages.
> I'm hoping here will be less spam.
>
> I'm having a wireless problem that I think is kernel issue.
> kernel-2.6.36.4 is good but recent kernels are bad.
> CompatWireless (recent wireless code) works on kernel-2.6.36.4 so I
> don't think it is the wireless subsystem..
>
> I have a Network controller: Atheros Communications Inc. AR5008 Wireless
> Network Adapter (rev 01).
>
> "iwlist wlan0 scan | grep SSID" under kernel-2.6.36.4 returns ~15 APs
> and associates to my AP.
> Recent kernels are bad and return ~0-3 APs and do not associate to my AP.
>
> I need help to debug this.
>
> I think the scans fail whenever dmesg shows this:
>> ath: Failed to stop TX DMA in 100 msec after killing last frame
>> ath: Failed to stop TX DMA!
> It seems to be 100% if I boot a kernel and that message is there, it'll
> be a bad kernel.
>
> I tried:
> $ git clone
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.37.y.git
> $ cd linux-2.6.37.y
> # git tag
> What tag is 2.6.36.4?
>
> v2.6.36
> v2.6.36-rc1
> v2.6.36-rc2
> v2.6.36-rc3
> v2.6.36-rc4
> v2.6.36-rc5
> v2.6.36-rc6
> v2.6.36-rc7
> v2.6.36-rc8
> v2.6.37
> v2.6.37-rc1
> v2.6.37-rc2
> v2.6.37-rc3
> v2.6.37-rc4
> v2.6.37-rc5
> v2.6.37-rc6
> v2.6.37-rc7
> v2.6.37-rc8
> v2.6.37.1
> v2.6.37.2
> v2.6.37.3
> v2.6.37.4
> v2.6.37.5
> v2.6.37.6
>
> Is the next step to do:
> $ git bisect start
> $ git bisect good v2.6.36.4
> $ git bisect bad v2.6.37.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* Re: [RFC] ethernet: avoid pre-assigned OUI values in random_ether_addr
From: Stephen Hemminger @ 2011-05-16 15:46 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Joe Perches, netdev
In-Reply-To: <1305493826.3120.174.camel@edumazet-laptop>
On Sun, 15 May 2011 23:10:26 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le dimanche 15 mai 2011 à 13:20 -0700, Joe Perches a écrit :
> > On Sun, 2011-05-15 at 21:46 +0200, Eric Dumazet wrote:
> > > Le vendredi 13 mai 2011 à 17:17 -0700, Stephen Hemminger a écrit :
> > > > There are some addresses in the assigned vendor block that don't obey
> > > > the locally assigned convention. These should be avoided by random_ether_addr
> > > > assignment.
> > > We call random_ether_addr() for some virtual devices, maybe we can add a
> > > __random_ether_addr() helper for them and not avoid these OUI ?
> >
> > Unless it's speed critical, it's probably not worthwhile.
> >
>
> Speed was not my concern, but getting idea of why avoiding pre-assigned
> OUI was a concern for them, if they dont hit a real Ethernet domain.
My concern was that after some discussion with IEEE committee that many
virtual environments are using locally assigned addresses that get bridged
onto real networks.
That started me thinking that the current code should be more careful
to avoid potential conflicts. My opinion is that this not worth worrying
about because the likelihood of conflict with any one of these old
addresses is as about as the unlikely as two hosts choosing the same
value. But I wanted to raise the issue for explicit discussion and frame
it with what would be required to handle it.
--
^ permalink raw reply
* RE: [RFC 2/3] RDMA/cma: Add support for netlink statistics export
From: Hefty, Sean @ 2011-05-16 15:08 UTC (permalink / raw)
To: Or Gerlitz
Cc: Roland Dreier, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <4DD0DAB2.1080600-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Isn't the port space enough here? specifically, what qp type buys us
> over port space?
That assumes a 1:1 relationship between the port space and QP type, or more specifically, that the IB SID range is divided based on QP type. This is outside of the architecture. If we look at UC or XRC, it's not clear what port space those map to, but I believe it's desirable for the rdma_cm to support those. Note that the AF_IB patch set ended up requiring that the user specify the qp type for these reasons.
- Sean
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ethtool: ETHTOOL_SFEATURES: remove NETIF_F_COMPAT return
From: Michał Mirosław @ 2011-05-16 15:01 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Michał Mirosław, netdev, David Miller
In-Reply-To: <1305557597.2885.5.camel@bwh-desktop>
W dniu 16 maja 2011 16:53 użytkownik Ben Hutchings
<bhutchings@solarflare.com> napisał:
> On Mon, 2011-05-16 at 16:23 +0200, Michał Mirosław wrote:
>> On Mon, May 16, 2011 at 02:37:46PM +0100, Ben Hutchings wrote:
>> > On Mon, 2011-05-16 at 15:28 +0200, Michał Mirosław wrote:
>> > > Remove NETIF_F_COMPAT since it's redundant and will be unused after
>> > > all drivers are converted to fix/set_features.
>> > >
>> > > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> > > ---
>> > >
>> > > For net as we don't want to have ETHTOOL_F_COMPAT hit stable release.
>> > [...]
>> > ETHTOOL_F_WISH means that the requested features could not all be
>> > enabled, *but are remembered*. ETHTOOL_F_COMPAT means they were not
>> > remembered.
>>
>> Hmm. So, lets just revert 39fc0ce5710c53bad14aaba1a789eec810c556f9
>> (net: Implement SFEATURES compatibility for not updated drivers).
> That's also problematic because it means we can't make any use of the
> 'available' masks from ETHTOOL_GFEATURES.
>
> The patch I sent is actually tested with a modified ethtool. The
> fallback works. I don't think you've tested whether any of your
> proposals can actually practically be used by ethtool.
You haven't posted the updates to ethtool to netdev. I just work blind here.
For now I use userspace version I sent along some of the first series
of the conversion patches. It actually makes it easier to use if the
compatibility handling stays in kernel (doesn't care about
ETHTOOL_F_COMPAT, BTW).
Best Regards,
Michał Mirosław
^ permalink raw reply
* Re: [PATCH] ethtool: ETHTOOL_SFEATURES: remove NETIF_F_COMPAT return
From: Ben Hutchings @ 2011-05-16 14:53 UTC (permalink / raw)
To: Michał Mirosław; +Cc: netdev, David Miller
In-Reply-To: <20110516142340.GA2980@rere.qmqm.pl>
On Mon, 2011-05-16 at 16:23 +0200, Michał Mirosław wrote:
> On Mon, May 16, 2011 at 02:37:46PM +0100, Ben Hutchings wrote:
> > On Mon, 2011-05-16 at 15:28 +0200, Michał Mirosław wrote:
> > > Remove NETIF_F_COMPAT since it's redundant and will be unused after
> > > all drivers are converted to fix/set_features.
> > >
> > > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> > > ---
> > >
> > > For net as we don't want to have ETHTOOL_F_COMPAT hit stable release.
> > [...]
> > ETHTOOL_F_WISH means that the requested features could not all be
> > enabled, *but are remembered*. ETHTOOL_F_COMPAT means they were not
> > remembered.
>
> Hmm. So, lets just revert 39fc0ce5710c53bad14aaba1a789eec810c556f9
> (net: Implement SFEATURES compatibility for not updated drivers).
That's also problematic because it means we can't make any use of the
'available' masks from ETHTOOL_GFEATURES.
The patch I sent is actually tested with a modified ethtool. The
fallback works. I don't think you've tested whether any of your
proposals can actually practically be used by ethtool.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH v3 2/2] net: postpone net device uevent to fix a race
From: Kalle Valo @ 2011-05-16 14:46 UTC (permalink / raw)
To: netdev; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20110516143913.13838.85357.stgit@localhost6.localdomain6>
From: Kalle Valo <kalle.valo@atheros.com>
There's a race in register_netdevice() so that the udev event is sent before
the device is actually ready. This was visible with flimflam, chrome os
connection manager:
00:21:35 roska flimflamd[2598]: src/udev.c:add_net_device()
00:21:35 roska flimflamd[2598]: connman_inet_ifname: SIOCGIFNAME(index
4): No such device
So the kobject is visible in udev before the device is ready.
The issue is reported here:
https://bugzilla.kernel.org/show_bug.cgi?id=15606
Fix this by postponing the uevent with device_add_noevent() and
calling device_uevent() once the device is really ready.
Thanks to Johannes Berg for the original idea.
Signed-off-by: Kalle Valo <kalle.valo@atheros.com>
---
net/core/dev.c | 3 +++
net/core/net-sysfs.c | 2 +-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 856b6ee..80cfa23 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5454,6 +5454,9 @@ int register_netdevice(struct net_device *dev)
rollback_registered(dev);
dev->reg_state = NETREG_UNREGISTERED;
}
+
+ device_uevent(&(dev->dev));
+
/*
* Prevent userspace races by waiting until the network
* device is fully setup before sending notifications.
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 5ceb257..c10b1d5 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1337,7 +1337,7 @@ int netdev_register_kobject(struct net_device *net)
#endif
#endif /* CONFIG_SYSFS */
- error = device_add(dev);
+ error = device_add_noevent(dev);
if (error)
return error;
^ permalink raw reply related
* [PATCH v3 1/2] driver core: add device_add_noevent() and device_uevent()
From: Kalle Valo @ 2011-05-16 14:46 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110516143913.13838.85357.stgit-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>
From: Kalle Valo <kalle.valo-DlyHzToyqoxBDgjK7y7TUQ@public.gmane.org>
To make it possible to postpone uevent after the device is registered
create the two new functions: device_add_noevent() and device_uevent().
This is needed by register_netdevice() to fix a race where the netdevice
is not ready until the initialisation has finished.
Signed-off-by: Kalle Valo <kalle.valo-DlyHzToyqoxBDgjK7y7TUQ@public.gmane.org>
---
drivers/base/core.c | 76 +++++++++++++++++++++++++++++++++++++-----------
include/linux/device.h | 2 +
2 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 81b78ed..54208e0 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -872,22 +872,7 @@ int device_private_init(struct device *dev)
return 0;
}
-/**
- * device_add - add device to device hierarchy.
- * @dev: device.
- *
- * This is part 2 of device_register(), though may be called
- * separately _iff_ device_initialize() has been called separately.
- *
- * This adds @dev to the kobject hierarchy via kobject_add(), adds it
- * to the global and sibling lists for the device, then
- * adds it to the other relevant subsystems of the driver model.
- *
- * NOTE: _Never_ directly free @dev after calling this function, even
- * if it returned an error! Always use put_device() to give up your
- * reference instead.
- */
-int device_add(struct device *dev)
+static int __device_add(struct device *dev, bool event)
{
struct device *parent = NULL;
struct class_interface *class_intf;
@@ -974,7 +959,9 @@ int device_add(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_ADD_DEVICE, dev);
- kobject_uevent(&dev->kobj, KOBJ_ADD);
+ if (event)
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+
bus_probe_device(dev);
if (parent)
klist_add_tail(&dev->p->knode_parent,
@@ -1026,6 +1013,61 @@ name_error:
}
/**
+ * device_add - add device to device hierarchy.
+ * @dev: device.
+ *
+ * This is part 2 of device_register(), though may be called
+ * separately _iff_ device_initialize() has been called separately.
+ *
+ * This adds @dev to the kobject hierarchy via kobject_add(), adds it
+ * to the global and sibling lists for the device, then
+ * adds it to the other relevant subsystems of the driver model.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up your
+ * reference instead.
+ */
+int device_add(struct device *dev)
+{
+ return __device_add(dev, true);
+}
+
+/**
+ * device_add - add device to device hierarchy but omit uevent
+ * @dev: device.
+ *
+ * This is part 2 of device_register(), though may be called
+ * separately _iff_ device_initialize() has been called separately.
+ *
+ * This adds @dev to the kobject hierarchy via kobject_add(), adds it
+ * to the global and sibling lists for the device, then
+ * adds it to the other relevant subsystems of the driver model.
+ *
+ * This version differs from device_add() so that it does not emit uevent.
+ * Instead call device_uevent() separately.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up your
+ * reference instead.
+ */
+int device_add_noevent(struct device *dev)
+{
+ return __device_add(dev, false);
+}
+
+/**
+ * device_uevent - emit uevent for device addition
+ * @dev: device.
+ *
+ * This is part 2 of device_add_noevent(). It emits the signal which was
+ * not sent when device_add_noevent() was called.
+ */
+void device_uevent(struct device *dev)
+{
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+}
+
+/**
* device_register - register a device with the system.
* @dev: pointer to the device structure
*
diff --git a/include/linux/device.h b/include/linux/device.h
index ab8dfc0..408d4f0 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -546,6 +546,8 @@ extern int __must_check device_register(struct device *dev);
extern void device_unregister(struct device *dev);
extern void device_initialize(struct device *dev);
extern int __must_check device_add(struct device *dev);
+extern int __must_check device_add_noevent(struct device *dev);
+extern void device_uevent(struct device *dev);
extern void device_del(struct device *dev);
extern int device_for_each_child(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data));
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 0/2] Fix uevent race in register_netdevice()
From: Kalle Valo @ 2011-05-16 14:46 UTC (permalink / raw)
To: netdev; +Cc: linux-wireless, linux-kernel
I'm trying to fix a race in register_netdevice(). The problem is that
there's a uevent to userspace before the netdevice is ready for use. The
problem is described here:
https://bugzilla.kernel.org/show_bug.cgi?id=15606
I have sent few different ways to fix this, but none of them have been
really usable. Now I came up with a way which changes the driver core
to make it possible send the uevent in a separate call. This is a clean
and safe way to fix the race. Downside is that two new functions are
added to the driver core interface.
Please comment.
---
Kalle Valo (2):
driver core: add device_add_noevent() and device_uevent()
net: postpone net device uevent to fix a race
drivers/base/core.c | 76 +++++++++++++++++++++++++++++++++++++-----------
include/linux/device.h | 2 +
net/core/dev.c | 3 ++
net/core/net-sysfs.c | 2 +
4 files changed, 65 insertions(+), 18 deletions(-)
^ permalink raw reply
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