aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:39 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:07 -0500
commit463a68a7734db3975c0d1c748f5fde713eb9a5b9 (patch)
tree28d994a53a400db72cb58fe286b7ca1f990f3ffe /drivers/net
parent954ea7480b11e67266c760c8c67fc337a3a6d5b9 (diff)
bnx2x: Support of PF driver of a VF q_teardown request
The 'q_teardown' request is basically the opposite of the 'q_setup'. Here the PF driver removes from the device the queue it opened against the VF fastpath ring at 'setup_q' stage, along with all related rx_mode info. 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')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c269
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h5
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c21
3 files changed, 295 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index e63925cbe501..9fd43c079045 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -111,6 +111,13 @@ enum bnx2x_vfop_qctor_state {
111 BNX2X_VFOP_QCTOR_INT_EN 111 BNX2X_VFOP_QCTOR_INT_EN
112}; 112};
113 113
114enum bnx2x_vfop_qdtor_state {
115 BNX2X_VFOP_QDTOR_HALT,
116 BNX2X_VFOP_QDTOR_TERMINATE,
117 BNX2X_VFOP_QDTOR_CFCDEL,
118 BNX2X_VFOP_QDTOR_DONE
119};
120
114enum bnx2x_vfop_vlan_mac_state { 121enum bnx2x_vfop_vlan_mac_state {
115 BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE, 122 BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE,
116 BNX2X_VFOP_VLAN_MAC_CLEAR, 123 BNX2X_VFOP_VLAN_MAC_CLEAR,
@@ -137,6 +144,14 @@ enum bnx2x_vfop_rxmode_state {
137 BNX2X_VFOP_RXMODE_DONE 144 BNX2X_VFOP_RXMODE_DONE
138}; 145};
139 146
147enum bnx2x_vfop_qteardown_state {
148 BNX2X_VFOP_QTEARDOWN_RXMODE,
149 BNX2X_VFOP_QTEARDOWN_CLR_VLAN,
150 BNX2X_VFOP_QTEARDOWN_CLR_MAC,
151 BNX2X_VFOP_QTEARDOWN_QDTOR,
152 BNX2X_VFOP_QTEARDOWN_DONE
153};
154
140#define bnx2x_vfop_reset_wq(vf) atomic_set(&vf->op_in_progress, 0) 155#define bnx2x_vfop_reset_wq(vf) atomic_set(&vf->op_in_progress, 0)
141 156
142void bnx2x_vfop_qctor_dump_tx(struct bnx2x *bp, struct bnx2x_virtf *vf, 157void bnx2x_vfop_qctor_dump_tx(struct bnx2x *bp, struct bnx2x_virtf *vf,
@@ -342,6 +357,101 @@ static int bnx2x_vfop_qctor_cmd(struct bnx2x *bp,
342 return -ENOMEM; 357 return -ENOMEM;
343} 358}
344 359
360/* VFOP queue destruction */
361static void bnx2x_vfop_qdtor(struct bnx2x *bp, struct bnx2x_virtf *vf)
362{
363 struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf);
364 struct bnx2x_vfop_args_qdtor *qdtor = &vfop->args.qdtor;
365 struct bnx2x_queue_state_params *q_params = &vfop->op_p->qctor.qstate;
366 enum bnx2x_vfop_qdtor_state state = vfop->state;
367
368 bnx2x_vfop_reset_wq(vf);
369
370 if (vfop->rc < 0)
371 goto op_err;
372
373 DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state);
374
375 switch (state) {
376 case BNX2X_VFOP_QDTOR_HALT:
377
378 /* has this queue already been stopped? */
379 if (bnx2x_get_q_logical_state(bp, q_params->q_obj) ==
380 BNX2X_Q_LOGICAL_STATE_STOPPED) {
381 DP(BNX2X_MSG_IOV,
382 "Entered qdtor but queue was already stopped. Aborting gracefully\n");
383 goto op_done;
384 }
385
386 /* next state */
387 vfop->state = BNX2X_VFOP_QDTOR_TERMINATE;
388
389 q_params->cmd = BNX2X_Q_CMD_HALT;
390 vfop->rc = bnx2x_queue_state_change(bp, q_params);
391
392 bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
393
394 case BNX2X_VFOP_QDTOR_TERMINATE:
395 /* next state */
396 vfop->state = BNX2X_VFOP_QDTOR_CFCDEL;
397
398 q_params->cmd = BNX2X_Q_CMD_TERMINATE;
399 vfop->rc = bnx2x_queue_state_change(bp, q_params);
400
401 bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
402
403 case BNX2X_VFOP_QDTOR_CFCDEL:
404 /* next state */
405 vfop->state = BNX2X_VFOP_QDTOR_DONE;
406
407 q_params->cmd = BNX2X_Q_CMD_CFC_DEL;
408 vfop->rc = bnx2x_queue_state_change(bp, q_params);
409
410 bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE);
411op_err:
412 BNX2X_ERR("QDTOR[%d:%d] error: cmd %d, rc %d\n",
413 vf->abs_vfid, qdtor->qid, q_params->cmd, vfop->rc);
414op_done:
415 case BNX2X_VFOP_QDTOR_DONE:
416 /* invalidate the context */
417 qdtor->cxt->ustorm_ag_context.cdu_usage = 0;
418 qdtor->cxt->xstorm_ag_context.cdu_reserved = 0;
419 bnx2x_vfop_end(bp, vf, vfop);
420 return;
421 default:
422 bnx2x_vfop_default(state);
423 }
424op_pending:
425 return;
426}
427
428static int bnx2x_vfop_qdtor_cmd(struct bnx2x *bp,
429 struct bnx2x_virtf *vf,
430 struct bnx2x_vfop_cmd *cmd,
431 int qid)
432{
433 struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
434
435 if (vfop) {
436 struct bnx2x_queue_state_params *qstate =
437 &vf->op_params.qctor.qstate;
438
439 memset(qstate, 0, sizeof(*qstate));
440 qstate->q_obj = &bnx2x_vfq(vf, qid, sp_obj);
441
442 vfop->args.qdtor.qid = qid;
443 vfop->args.qdtor.cxt = bnx2x_vfq(vf, qid, cxt);
444
445 bnx2x_vfop_opset(BNX2X_VFOP_QDTOR_HALT,
446 bnx2x_vfop_qdtor, cmd->done);
447 return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdtor,
448 cmd->block);
449 }
450 DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop. rc %d\n",
451 vf->abs_vfid, vfop->rc);
452 return -ENOMEM;
453}
454
345static void 455static void
346bnx2x_vf_set_igu_info(struct bnx2x *bp, u8 igu_sb_id, u8 abs_vfid) 456bnx2x_vf_set_igu_info(struct bnx2x *bp, u8 igu_sb_id, u8 abs_vfid)
347{ 457{
@@ -593,6 +703,44 @@ bnx2x_vfop_mac_prep_ramrod(struct bnx2x_vlan_mac_ramrod_params *ramrod,
593 set_bit(BNX2X_ETH_MAC, &ramrod->user_req.vlan_mac_flags); 703 set_bit(BNX2X_ETH_MAC, &ramrod->user_req.vlan_mac_flags);
594} 704}
595 705
706static int bnx2x_vfop_mac_delall_cmd(struct bnx2x *bp,
707 struct bnx2x_virtf *vf,
708 struct bnx2x_vfop_cmd *cmd,
709 int qid, bool drv_only)
710{
711 struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
712
713 if (vfop) {
714 struct bnx2x_vfop_args_filters filters = {
715 .multi_filter = NULL, /* single */
716 .credit = NULL, /* consume credit */
717 };
718 struct bnx2x_vfop_vlan_mac_flags flags = {
719 .drv_only = drv_only,
720 .dont_consume = (filters.credit != NULL),
721 .single_cmd = true,
722 .add = false /* don't care */,
723 };
724 struct bnx2x_vlan_mac_ramrod_params *ramrod =
725 &vf->op_params.vlan_mac;
726
727 /* set ramrod params */
728 bnx2x_vfop_mac_prep_ramrod(ramrod, &flags);
729
730 /* set object */
731 ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj);
732
733 /* set extra args */
734 vfop->args.filters = filters;
735
736 bnx2x_vfop_opset(BNX2X_VFOP_VLAN_MAC_CLEAR,
737 bnx2x_vfop_vlan_mac, cmd->done);
738 return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac,
739 cmd->block);
740 }
741 return -ENOMEM;
742}
743
596int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, 744int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp,
597 struct bnx2x_virtf *vf, 745 struct bnx2x_virtf *vf,
598 struct bnx2x_vfop_cmd *cmd, 746 struct bnx2x_vfop_cmd *cmd,
@@ -675,6 +823,44 @@ int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp,
675 return -ENOMEM; 823 return -ENOMEM;
676} 824}
677 825
826static int bnx2x_vfop_vlan_delall_cmd(struct bnx2x *bp,
827 struct bnx2x_virtf *vf,
828 struct bnx2x_vfop_cmd *cmd,
829 int qid, bool drv_only)
830{
831 struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
832
833 if (vfop) {
834 struct bnx2x_vfop_args_filters filters = {
835 .multi_filter = NULL, /* single command */
836 .credit = &bnx2x_vfq(vf, qid, vlan_count),
837 };
838 struct bnx2x_vfop_vlan_mac_flags flags = {
839 .drv_only = drv_only,
840 .dont_consume = (filters.credit != NULL),
841 .single_cmd = true,
842 .add = false, /* don't care */
843 };
844 struct bnx2x_vlan_mac_ramrod_params *ramrod =
845 &vf->op_params.vlan_mac;
846
847 /* set ramrod params */
848 bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags);
849
850 /* set object */
851 ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
852
853 /* set extra args */
854 vfop->args.filters = filters;
855
856 bnx2x_vfop_opset(BNX2X_VFOP_VLAN_MAC_CLEAR,
857 bnx2x_vfop_vlan_mac, cmd->done);
858 return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac,
859 cmd->block);
860 }
861 return -ENOMEM;
862}
863
678int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp, 864int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp,
679 struct bnx2x_virtf *vf, 865 struct bnx2x_virtf *vf,
680 struct bnx2x_vfop_cmd *cmd, 866 struct bnx2x_vfop_cmd *cmd,
@@ -956,6 +1142,89 @@ int bnx2x_vfop_rxmode_cmd(struct bnx2x *bp,
956 return -ENOMEM; 1142 return -ENOMEM;
957} 1143}
958 1144
1145/* VFOP queue tear-down ('drop all' rx-mode, clear vlans, clear macs,
1146 * queue destructor)
1147 */
1148static void bnx2x_vfop_qdown(struct bnx2x *bp, struct bnx2x_virtf *vf)
1149{
1150 struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf);
1151 int qid = vfop->args.qx.qid;
1152 enum bnx2x_vfop_qteardown_state state = vfop->state;
1153 struct bnx2x_vfop_cmd cmd;
1154
1155 if (vfop->rc < 0)
1156 goto op_err;
1157
1158 DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state);
1159
1160 cmd.done = bnx2x_vfop_qdown;
1161 cmd.block = false;
1162
1163 switch (state) {
1164 case BNX2X_VFOP_QTEARDOWN_RXMODE:
1165 /* Drop all */
1166 vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_VLAN;
1167 vfop->rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd, qid, 0);
1168 if (vfop->rc)
1169 goto op_err;
1170 return;
1171
1172 case BNX2X_VFOP_QTEARDOWN_CLR_VLAN:
1173 /* vlan-clear-all: don't consume credit */
1174 vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_MAC;
1175 vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, qid, false);
1176 if (vfop->rc)
1177 goto op_err;
1178 return;
1179
1180 case BNX2X_VFOP_QTEARDOWN_CLR_MAC:
1181 /* mac-clear-all: consume credit */
1182 vfop->state = BNX2X_VFOP_QTEARDOWN_QDTOR;
1183 vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, qid, false);
1184 if (vfop->rc)
1185 goto op_err;
1186 return;
1187
1188 case BNX2X_VFOP_QTEARDOWN_QDTOR:
1189 /* run the queue destruction flow */
1190 DP(BNX2X_MSG_IOV, "case: BNX2X_VFOP_QTEARDOWN_QDTOR\n");
1191 vfop->state = BNX2X_VFOP_QTEARDOWN_DONE;
1192 DP(BNX2X_MSG_IOV, "new state: BNX2X_VFOP_QTEARDOWN_DONE\n");
1193 vfop->rc = bnx2x_vfop_qdtor_cmd(bp, vf, &cmd, qid);
1194 DP(BNX2X_MSG_IOV, "returned from cmd\n");
1195 if (vfop->rc)
1196 goto op_err;
1197 return;
1198op_err:
1199 BNX2X_ERR("QTEARDOWN[%d:%d] error: rc %d\n",
1200 vf->abs_vfid, qid, vfop->rc);
1201
1202 case BNX2X_VFOP_QTEARDOWN_DONE:
1203 bnx2x_vfop_end(bp, vf, vfop);
1204 return;
1205 default:
1206 bnx2x_vfop_default(state);
1207 }
1208}
1209
1210int bnx2x_vfop_qdown_cmd(struct bnx2x *bp,
1211 struct bnx2x_virtf *vf,
1212 struct bnx2x_vfop_cmd *cmd,
1213 int qid)
1214{
1215 struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
1216
1217 if (vfop) {
1218 vfop->args.qx.qid = qid;
1219 bnx2x_vfop_opset(BNX2X_VFOP_QTEARDOWN_RXMODE,
1220 bnx2x_vfop_qdown, cmd->done);
1221 return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdown,
1222 cmd->block);
1223 }
1224
1225 return -ENOMEM;
1226}
1227
959/* VF enable primitives 1228/* VF enable primitives
960 * when pretend is required the caller is responsible 1229 * when pretend is required the caller is responsible
961 * for calling pretend prior to calling these routines 1230 * for calling pretend prior to calling these routines
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index f75bd65e46ae..9f0099c543e0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -641,6 +641,11 @@ int bnx2x_vfop_qsetup_cmd(struct bnx2x *bp,
641 struct bnx2x_vfop_cmd *cmd, 641 struct bnx2x_vfop_cmd *cmd,
642 int qid); 642 int qid);
643 643
644int bnx2x_vfop_qdown_cmd(struct bnx2x *bp,
645 struct bnx2x_virtf *vf,
646 struct bnx2x_vfop_cmd *cmd,
647 int qid);
648
644int bnx2x_vfop_mcast_cmd(struct bnx2x *bp, 649int bnx2x_vfop_mcast_cmd(struct bnx2x *bp,
645 struct bnx2x_virtf *vf, 650 struct bnx2x_virtf *vf,
646 struct bnx2x_vfop_cmd *cmd, 651 struct bnx2x_vfop_cmd *cmd,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index ad92bf4227b0..af30eb4a37bf 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -787,6 +787,23 @@ response:
787 bnx2x_vf_mbx_resp(bp, vf); 787 bnx2x_vf_mbx_resp(bp, vf);
788} 788}
789 789
790static void bnx2x_vf_mbx_teardown_q(struct bnx2x *bp, struct bnx2x_virtf *vf,
791 struct bnx2x_vf_mbx *mbx)
792{
793 int qid = mbx->msg->req.q_op.vf_qid;
794 struct bnx2x_vfop_cmd cmd = {
795 .done = bnx2x_vf_mbx_resp,
796 .block = false,
797 };
798
799 DP(BNX2X_MSG_IOV, "VF[%d] Q_TEARDOWN: vf_qid=%d\n",
800 vf->abs_vfid, qid);
801
802 vf->op_rc = bnx2x_vfop_qdown_cmd(bp, vf, &cmd, qid);
803 if (vf->op_rc)
804 bnx2x_vf_mbx_resp(bp, vf);
805}
806
790/* dispatch request */ 807/* dispatch request */
791static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf, 808static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf,
792 struct bnx2x_vf_mbx *mbx) 809 struct bnx2x_vf_mbx *mbx)
@@ -814,7 +831,11 @@ static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf,
814 case CHANNEL_TLV_SET_Q_FILTERS: 831 case CHANNEL_TLV_SET_Q_FILTERS:
815 bnx2x_vf_mbx_set_q_filters(bp, vf, mbx); 832 bnx2x_vf_mbx_set_q_filters(bp, vf, mbx);
816 break; 833 break;
834 case CHANNEL_TLV_TEARDOWN_Q:
835 bnx2x_vf_mbx_teardown_q(bp, vf, mbx);
836 break;
817 } 837 }
838
818 } else { 839 } else {
819 /* unknown TLV - this may belong to a VF driver from the future 840 /* unknown TLV - this may belong to a VF driver from the future
820 * - a version written after this PF driver was written, which 841 * - a version written after this PF driver was written, which