aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:36 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:06 -0500
commit67c431a5f2f3e0dda511509ed5773346839c07c0 (patch)
tree17592f12d0de49dfe3277318505607241c706a2d /drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
parentb93288d5e7efc57628c59fe3f1844fb87982b409 (diff)
bnx2x: Support statistics collection for VFs by the PF
Statistics are collected by the PF driver. The collection is performed via a query sent to the device which is basically an array of 3-tuples of the form (statistics client, function, DMAE address). In this patch the PF driver adds to the query, on top of the statistics clients it is maintaining for itself (rss queues, storage, etc), the 3-tuples for the VFs it is maintaining. The addresses used are the GPAs of the statistics buffers supplied by the VF in the init message on the VF <-> PF channel. The function parameter ensures that the iommu will translate the GPA to the correct physical address. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 14e49bc455df..71e1c6fb205d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -1069,6 +1069,80 @@ void bnx2x_iov_sp_event(struct bnx2x *bp, int vf_cid, bool queue_work)
1069 } 1069 }
1070} 1070}
1071 1071
1072void bnx2x_iov_adjust_stats_req(struct bnx2x *bp)
1073{
1074 int i;
1075 int first_queue_query_index, num_queues_req;
1076 dma_addr_t cur_data_offset;
1077 struct stats_query_entry *cur_query_entry;
1078 u8 stats_count = 0;
1079 bool is_fcoe = false;
1080
1081 if (!IS_SRIOV(bp))
1082 return;
1083
1084 if (!NO_FCOE(bp))
1085 is_fcoe = true;
1086
1087 /* fcoe adds one global request and one queue request */
1088 num_queues_req = BNX2X_NUM_ETH_QUEUES(bp) + is_fcoe;
1089 first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX -
1090 (is_fcoe ? 0 : 1);
1091
1092 DP(BNX2X_MSG_IOV,
1093 "BNX2X_NUM_ETH_QUEUES %d, is_fcoe %d, first_queue_query_index %d => determined the last non virtual statistics query index is %d. Will add queries on top of that\n",
1094 BNX2X_NUM_ETH_QUEUES(bp), is_fcoe, first_queue_query_index,
1095 first_queue_query_index + num_queues_req);
1096
1097 cur_data_offset = bp->fw_stats_data_mapping +
1098 offsetof(struct bnx2x_fw_stats_data, queue_stats) +
1099 num_queues_req * sizeof(struct per_queue_stats);
1100
1101 cur_query_entry = &bp->fw_stats_req->
1102 query[first_queue_query_index + num_queues_req];
1103
1104 for_each_vf(bp, i) {
1105 int j;
1106 struct bnx2x_virtf *vf = BP_VF(bp, i);
1107
1108 if (vf->state != VF_ENABLED) {
1109 DP(BNX2X_MSG_IOV,
1110 "vf %d not enabled so no stats for it\n",
1111 vf->abs_vfid);
1112 continue;
1113 }
1114
1115 DP(BNX2X_MSG_IOV, "add addresses for vf %d\n", vf->abs_vfid);
1116 for_each_vfq(vf, j) {
1117 struct bnx2x_vf_queue *rxq = vfq_get(vf, j);
1118
1119 /* collect stats fro active queues only */
1120 if (bnx2x_get_q_logical_state(bp, &rxq->sp_obj) ==
1121 BNX2X_Q_LOGICAL_STATE_STOPPED)
1122 continue;
1123
1124 /* create stats query entry for this queue */
1125 cur_query_entry->kind = STATS_TYPE_QUEUE;
1126 cur_query_entry->index = vfq_cl_id(vf, rxq);
1127 cur_query_entry->funcID =
1128 cpu_to_le16(FW_VF_HANDLE(vf->abs_vfid));
1129 cur_query_entry->address.hi =
1130 cpu_to_le32(U64_HI(vf->fw_stat_map));
1131 cur_query_entry->address.lo =
1132 cpu_to_le32(U64_LO(vf->fw_stat_map));
1133 DP(BNX2X_MSG_IOV,
1134 "added address %x %x for vf %d queue %d client %d\n",
1135 cur_query_entry->address.hi,
1136 cur_query_entry->address.lo, cur_query_entry->funcID,
1137 j, cur_query_entry->index);
1138 cur_query_entry++;
1139 cur_data_offset += sizeof(struct per_queue_stats);
1140 stats_count++;
1141 }
1142 }
1143 bp->fw_stats_req->hdr.cmd_num = bp->fw_stats_num + stats_count;
1144}
1145
1072void bnx2x_iov_sp_task(struct bnx2x *bp) 1146void bnx2x_iov_sp_task(struct bnx2x *bp)
1073{ 1147{
1074 int i; 1148 int i;
@@ -1089,6 +1163,23 @@ void bnx2x_iov_sp_task(struct bnx2x *bp)
1089 } 1163 }
1090 } 1164 }
1091} 1165}
1166
1167static inline
1168struct bnx2x_virtf *__vf_from_stat_id(struct bnx2x *bp, u8 stat_id)
1169{
1170 int i;
1171 struct bnx2x_virtf *vf = NULL;
1172
1173 for_each_vf(bp, i) {
1174 vf = BP_VF(bp, i);
1175 if (stat_id >= vf->igu_base_id &&
1176 stat_id < vf->igu_base_id + vf_sb_count(vf))
1177 break;
1178 }
1179 return vf;
1180}
1181
1182/* VF API helpers */
1092static void bnx2x_vf_qtbl_set_q(struct bnx2x *bp, u8 abs_vfid, u8 qid, 1183static void bnx2x_vf_qtbl_set_q(struct bnx2x *bp, u8 abs_vfid, u8 qid,
1093 u8 enable) 1184 u8 enable)
1094{ 1185{