|
@@ -151,6 +151,7 @@ static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx,
|
|
|
static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx);
|
|
|
static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data,
|
|
|
int len);
|
|
|
+static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len);
|
|
|
|
|
|
/*
|
|
|
* SCSI host template entry points
|
|
@@ -262,6 +263,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
|
|
|
.login_flashnode = qla4xxx_sysfs_ddb_login,
|
|
|
.logout_flashnode = qla4xxx_sysfs_ddb_logout,
|
|
|
.logout_flashnode_sid = qla4xxx_sysfs_ddb_logout_sid,
|
|
|
+ .get_host_stats = qla4xxx_get_host_stats,
|
|
|
};
|
|
|
|
|
|
static struct scsi_transport_template *qla4xxx_scsi_transport;
|
|
@@ -950,6 +952,209 @@ exit_set_chap:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len)
|
|
|
+{
|
|
|
+ struct scsi_qla_host *ha = to_qla_host(shost);
|
|
|
+ struct iscsi_offload_host_stats *host_stats = NULL;
|
|
|
+ int host_stats_size;
|
|
|
+ int ret = 0;
|
|
|
+ int ddb_idx = 0;
|
|
|
+ struct ql_iscsi_stats *ql_iscsi_stats = NULL;
|
|
|
+ int stats_size;
|
|
|
+ dma_addr_t iscsi_stats_dma;
|
|
|
+
|
|
|
+ DEBUG2(ql4_printk(KERN_INFO, ha, "Func: %s\n", __func__));
|
|
|
+
|
|
|
+ host_stats_size = sizeof(struct iscsi_offload_host_stats);
|
|
|
+
|
|
|
+ if (host_stats_size != len) {
|
|
|
+ ql4_printk(KERN_INFO, ha, "%s: host_stats size mismatch expected = %d, is = %d\n",
|
|
|
+ __func__, len, host_stats_size);
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto exit_host_stats;
|
|
|
+ }
|
|
|
+ host_stats = (struct iscsi_offload_host_stats *)buf;
|
|
|
+
|
|
|
+ if (!buf) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto exit_host_stats;
|
|
|
+ }
|
|
|
+
|
|
|
+ stats_size = PAGE_ALIGN(sizeof(struct ql_iscsi_stats));
|
|
|
+
|
|
|
+ ql_iscsi_stats = dma_alloc_coherent(&ha->pdev->dev, stats_size,
|
|
|
+ &iscsi_stats_dma, GFP_KERNEL);
|
|
|
+ if (!ql_iscsi_stats) {
|
|
|
+ ql4_printk(KERN_ERR, ha,
|
|
|
+ "Unable to allocate memory for iscsi stats\n");
|
|
|
+ goto exit_host_stats;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = qla4xxx_get_mgmt_data(ha, ddb_idx, stats_size,
|
|
|
+ iscsi_stats_dma);
|
|
|
+ if (ret != QLA_SUCCESS) {
|
|
|
+ ql4_printk(KERN_ERR, ha,
|
|
|
+ "Unable to retrieve iscsi stats\n");
|
|
|
+ goto exit_host_stats;
|
|
|
+ }
|
|
|
+ host_stats->mactx_frames = le64_to_cpu(ql_iscsi_stats->mac_tx_frames);
|
|
|
+ host_stats->mactx_bytes = le64_to_cpu(ql_iscsi_stats->mac_tx_bytes);
|
|
|
+ host_stats->mactx_multicast_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_multicast_frames);
|
|
|
+ host_stats->mactx_broadcast_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_broadcast_frames);
|
|
|
+ host_stats->mactx_pause_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_pause_frames);
|
|
|
+ host_stats->mactx_control_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_control_frames);
|
|
|
+ host_stats->mactx_deferral =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_deferral);
|
|
|
+ host_stats->mactx_excess_deferral =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_excess_deferral);
|
|
|
+ host_stats->mactx_late_collision =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_late_collision);
|
|
|
+ host_stats->mactx_abort = le64_to_cpu(ql_iscsi_stats->mac_tx_abort);
|
|
|
+ host_stats->mactx_single_collision =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_single_collision);
|
|
|
+ host_stats->mactx_multiple_collision =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_multiple_collision);
|
|
|
+ host_stats->mactx_collision =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_collision);
|
|
|
+ host_stats->mactx_frames_dropped =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_frames_dropped);
|
|
|
+ host_stats->mactx_jumbo_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_tx_jumbo_frames);
|
|
|
+ host_stats->macrx_frames = le64_to_cpu(ql_iscsi_stats->mac_rx_frames);
|
|
|
+ host_stats->macrx_bytes = le64_to_cpu(ql_iscsi_stats->mac_rx_bytes);
|
|
|
+ host_stats->macrx_unknown_control_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_unknown_control_frames);
|
|
|
+ host_stats->macrx_pause_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_pause_frames);
|
|
|
+ host_stats->macrx_control_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_control_frames);
|
|
|
+ host_stats->macrx_dribble =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_dribble);
|
|
|
+ host_stats->macrx_frame_length_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_frame_length_error);
|
|
|
+ host_stats->macrx_jabber = le64_to_cpu(ql_iscsi_stats->mac_rx_jabber);
|
|
|
+ host_stats->macrx_carrier_sense_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_carrier_sense_error);
|
|
|
+ host_stats->macrx_frame_discarded =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_frame_discarded);
|
|
|
+ host_stats->macrx_frames_dropped =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_frames_dropped);
|
|
|
+ host_stats->mac_crc_error = le64_to_cpu(ql_iscsi_stats->mac_crc_error);
|
|
|
+ host_stats->mac_encoding_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_encoding_error);
|
|
|
+ host_stats->macrx_length_error_large =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_length_error_large);
|
|
|
+ host_stats->macrx_length_error_small =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_length_error_small);
|
|
|
+ host_stats->macrx_multicast_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_multicast_frames);
|
|
|
+ host_stats->macrx_broadcast_frames =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->mac_rx_broadcast_frames);
|
|
|
+ host_stats->iptx_packets = le64_to_cpu(ql_iscsi_stats->ip_tx_packets);
|
|
|
+ host_stats->iptx_bytes = le64_to_cpu(ql_iscsi_stats->ip_tx_bytes);
|
|
|
+ host_stats->iptx_fragments =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_tx_fragments);
|
|
|
+ host_stats->iprx_packets = le64_to_cpu(ql_iscsi_stats->ip_rx_packets);
|
|
|
+ host_stats->iprx_bytes = le64_to_cpu(ql_iscsi_stats->ip_rx_bytes);
|
|
|
+ host_stats->iprx_fragments =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_rx_fragments);
|
|
|
+ host_stats->ip_datagram_reassembly =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_datagram_reassembly);
|
|
|
+ host_stats->ip_invalid_address_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_invalid_address_error);
|
|
|
+ host_stats->ip_error_packets =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_error_packets);
|
|
|
+ host_stats->ip_fragrx_overlap =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_fragrx_overlap);
|
|
|
+ host_stats->ip_fragrx_outoforder =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_fragrx_outoforder);
|
|
|
+ host_stats->ip_datagram_reassembly_timeout =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ip_datagram_reassembly_timeout);
|
|
|
+ host_stats->ipv6tx_packets =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_tx_packets);
|
|
|
+ host_stats->ipv6tx_bytes = le64_to_cpu(ql_iscsi_stats->ipv6_tx_bytes);
|
|
|
+ host_stats->ipv6tx_fragments =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_tx_fragments);
|
|
|
+ host_stats->ipv6rx_packets =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_rx_packets);
|
|
|
+ host_stats->ipv6rx_bytes = le64_to_cpu(ql_iscsi_stats->ipv6_rx_bytes);
|
|
|
+ host_stats->ipv6rx_fragments =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_rx_fragments);
|
|
|
+ host_stats->ipv6_datagram_reassembly =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_datagram_reassembly);
|
|
|
+ host_stats->ipv6_invalid_address_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_invalid_address_error);
|
|
|
+ host_stats->ipv6_error_packets =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_error_packets);
|
|
|
+ host_stats->ipv6_fragrx_overlap =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_fragrx_overlap);
|
|
|
+ host_stats->ipv6_fragrx_outoforder =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_fragrx_outoforder);
|
|
|
+ host_stats->ipv6_datagram_reassembly_timeout =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ipv6_datagram_reassembly_timeout);
|
|
|
+ host_stats->tcptx_segments =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_tx_segments);
|
|
|
+ host_stats->tcptx_bytes = le64_to_cpu(ql_iscsi_stats->tcp_tx_bytes);
|
|
|
+ host_stats->tcprx_segments =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_segments);
|
|
|
+ host_stats->tcprx_byte = le64_to_cpu(ql_iscsi_stats->tcp_rx_byte);
|
|
|
+ host_stats->tcp_duplicate_ack_retx =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_duplicate_ack_retx);
|
|
|
+ host_stats->tcp_retx_timer_expired =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_retx_timer_expired);
|
|
|
+ host_stats->tcprx_duplicate_ack =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_duplicate_ack);
|
|
|
+ host_stats->tcprx_pure_ackr =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_pure_ackr);
|
|
|
+ host_stats->tcptx_delayed_ack =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_tx_delayed_ack);
|
|
|
+ host_stats->tcptx_pure_ack =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_tx_pure_ack);
|
|
|
+ host_stats->tcprx_segment_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_segment_error);
|
|
|
+ host_stats->tcprx_segment_outoforder =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_segment_outoforder);
|
|
|
+ host_stats->tcprx_window_probe =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_window_probe);
|
|
|
+ host_stats->tcprx_window_update =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_rx_window_update);
|
|
|
+ host_stats->tcptx_window_probe_persist =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->tcp_tx_window_probe_persist);
|
|
|
+ host_stats->ecc_error_correction =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->ecc_error_correction);
|
|
|
+ host_stats->iscsi_pdu_tx = le64_to_cpu(ql_iscsi_stats->iscsi_pdu_tx);
|
|
|
+ host_stats->iscsi_data_bytes_tx =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_data_bytes_tx);
|
|
|
+ host_stats->iscsi_pdu_rx = le64_to_cpu(ql_iscsi_stats->iscsi_pdu_rx);
|
|
|
+ host_stats->iscsi_data_bytes_rx =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_data_bytes_rx);
|
|
|
+ host_stats->iscsi_io_completed =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_io_completed);
|
|
|
+ host_stats->iscsi_unexpected_io_rx =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_unexpected_io_rx);
|
|
|
+ host_stats->iscsi_format_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_format_error);
|
|
|
+ host_stats->iscsi_hdr_digest_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_hdr_digest_error);
|
|
|
+ host_stats->iscsi_data_digest_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_data_digest_error);
|
|
|
+ host_stats->iscsi_sequence_error =
|
|
|
+ le64_to_cpu(ql_iscsi_stats->iscsi_sequence_error);
|
|
|
+exit_host_stats:
|
|
|
+ if (ql_iscsi_stats)
|
|
|
+ dma_free_coherent(&ha->pdev->dev, host_stats_size,
|
|
|
+ ql_iscsi_stats, iscsi_stats_dma);
|
|
|
+
|
|
|
+ ql4_printk(KERN_INFO, ha, "%s: Get host stats done\n",
|
|
|
+ __func__);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static int qla4xxx_get_iface_param(struct iscsi_iface *iface,
|
|
|
enum iscsi_param_type param_type,
|
|
|
int param, char *buf)
|