@@ -80,6 +80,79 @@ static DEFINE_MUTEX(bnxt_re_dev_lock);
80
80
static struct workqueue_struct * bnxt_re_wq ;
81
81
static void bnxt_re_ib_unreg (struct bnxt_re_dev * rdev , bool lock_wait );
82
82
83
+ /* SR-IOV helper functions */
84
+
85
+ static void bnxt_re_get_sriov_func_type (struct bnxt_re_dev * rdev )
86
+ {
87
+ struct bnxt * bp ;
88
+
89
+ bp = netdev_priv (rdev -> en_dev -> net );
90
+ if (BNXT_VF (bp ))
91
+ rdev -> is_virtfn = 1 ;
92
+ }
93
+
94
+ /* Set the maximum number of each resource that the driver actually wants
95
+ * to allocate. This may be up to the maximum number the firmware has
96
+ * reserved for the function. The driver may choose to allocate fewer
97
+ * resources than the firmware maximum.
98
+ */
99
+ static void bnxt_re_set_resource_limits (struct bnxt_re_dev * rdev )
100
+ {
101
+ u32 vf_qps = 0 , vf_srqs = 0 , vf_cqs = 0 , vf_mrws = 0 , vf_gids = 0 ;
102
+ u32 i ;
103
+ u32 vf_pct ;
104
+ u32 num_vfs ;
105
+ struct bnxt_qplib_dev_attr * dev_attr = & rdev -> dev_attr ;
106
+
107
+ rdev -> qplib_ctx .qpc_count = min_t (u32 , BNXT_RE_MAX_QPC_COUNT ,
108
+ dev_attr -> max_qp );
109
+
110
+ rdev -> qplib_ctx .mrw_count = BNXT_RE_MAX_MRW_COUNT_256K ;
111
+ /* Use max_mr from fw since max_mrw does not get set */
112
+ rdev -> qplib_ctx .mrw_count = min_t (u32 , rdev -> qplib_ctx .mrw_count ,
113
+ dev_attr -> max_mr );
114
+ rdev -> qplib_ctx .srqc_count = min_t (u32 , BNXT_RE_MAX_SRQC_COUNT ,
115
+ dev_attr -> max_srq );
116
+ rdev -> qplib_ctx .cq_count = min_t (u32 , BNXT_RE_MAX_CQ_COUNT ,
117
+ dev_attr -> max_cq );
118
+
119
+ for (i = 0 ; i < MAX_TQM_ALLOC_REQ ; i ++ )
120
+ rdev -> qplib_ctx .tqm_count [i ] =
121
+ rdev -> dev_attr .tqm_alloc_reqs [i ];
122
+
123
+ if (rdev -> num_vfs ) {
124
+ /*
125
+ * Reserve a set of resources for the PF. Divide the remaining
126
+ * resources among the VFs
127
+ */
128
+ vf_pct = 100 - BNXT_RE_PCT_RSVD_FOR_PF ;
129
+ num_vfs = 100 * rdev -> num_vfs ;
130
+ vf_qps = (rdev -> qplib_ctx .qpc_count * vf_pct ) / num_vfs ;
131
+ vf_srqs = (rdev -> qplib_ctx .srqc_count * vf_pct ) / num_vfs ;
132
+ vf_cqs = (rdev -> qplib_ctx .cq_count * vf_pct ) / num_vfs ;
133
+ /*
134
+ * The driver allows many more MRs than other resources. If the
135
+ * firmware does also, then reserve a fixed amount for the PF
136
+ * and divide the rest among VFs. VFs may use many MRs for NFS
137
+ * mounts, ISER, NVME applications, etc. If the firmware
138
+ * severely restricts the number of MRs, then let PF have
139
+ * half and divide the rest among VFs, as for the other
140
+ * resource types.
141
+ */
142
+ if (rdev -> qplib_ctx .mrw_count < BNXT_RE_MAX_MRW_COUNT_64K )
143
+ vf_mrws = rdev -> qplib_ctx .mrw_count * vf_pct / num_vfs ;
144
+ else
145
+ vf_mrws = (rdev -> qplib_ctx .mrw_count -
146
+ BNXT_RE_RESVD_MR_FOR_PF ) / rdev -> num_vfs ;
147
+ vf_gids = BNXT_RE_MAX_GID_PER_VF ;
148
+ }
149
+ rdev -> qplib_ctx .vf_res .max_mrw_per_vf = vf_mrws ;
150
+ rdev -> qplib_ctx .vf_res .max_gid_per_vf = vf_gids ;
151
+ rdev -> qplib_ctx .vf_res .max_qp_per_vf = vf_qps ;
152
+ rdev -> qplib_ctx .vf_res .max_srq_per_vf = vf_srqs ;
153
+ rdev -> qplib_ctx .vf_res .max_cq_per_vf = vf_cqs ;
154
+ }
155
+
83
156
/* for handling bnxt_en callbacks later */
84
157
static void bnxt_re_stop (void * p )
85
158
{
@@ -91,6 +164,15 @@ static void bnxt_re_start(void *p)
91
164
92
165
static void bnxt_re_sriov_config (void * p , int num_vfs )
93
166
{
167
+ struct bnxt_re_dev * rdev = p ;
168
+
169
+ if (!rdev )
170
+ return ;
171
+
172
+ rdev -> num_vfs = num_vfs ;
173
+ bnxt_re_set_resource_limits (rdev );
174
+ bnxt_qplib_set_func_resources (& rdev -> qplib_res , & rdev -> rcfw ,
175
+ & rdev -> qplib_ctx );
94
176
}
95
177
96
178
static void bnxt_re_shutdown (void * p )
@@ -734,7 +816,8 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
734
816
735
817
/* Configure and allocate resources for qplib */
736
818
rdev -> qplib_res .rcfw = & rdev -> rcfw ;
737
- rc = bnxt_qplib_get_dev_attr (& rdev -> rcfw , & rdev -> dev_attr );
819
+ rc = bnxt_qplib_get_dev_attr (& rdev -> rcfw , & rdev -> dev_attr ,
820
+ rdev -> is_virtfn );
738
821
if (rc )
739
822
goto fail ;
740
823
@@ -1035,19 +1118,6 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
1035
1118
}
1036
1119
}
1037
1120
1038
- static void bnxt_re_set_resource_limits (struct bnxt_re_dev * rdev )
1039
- {
1040
- u32 i ;
1041
-
1042
- rdev -> qplib_ctx .qpc_count = BNXT_RE_MAX_QPC_COUNT ;
1043
- rdev -> qplib_ctx .mrw_count = BNXT_RE_MAX_MRW_COUNT ;
1044
- rdev -> qplib_ctx .srqc_count = BNXT_RE_MAX_SRQC_COUNT ;
1045
- rdev -> qplib_ctx .cq_count = BNXT_RE_MAX_CQ_COUNT ;
1046
- for (i = 0 ; i < MAX_TQM_ALLOC_REQ ; i ++ )
1047
- rdev -> qplib_ctx .tqm_count [i ] =
1048
- rdev -> dev_attr .tqm_alloc_reqs [i ];
1049
- }
1050
-
1051
1121
/* worker thread for polling periodic events. Now used for QoS programming*/
1052
1122
static void bnxt_re_worker (struct work_struct * work )
1053
1123
{
@@ -1070,6 +1140,9 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
1070
1140
}
1071
1141
set_bit (BNXT_RE_FLAG_NETDEV_REGISTERED , & rdev -> flags );
1072
1142
1143
+ /* Check whether VF or PF */
1144
+ bnxt_re_get_sriov_func_type (rdev );
1145
+
1073
1146
rc = bnxt_re_request_msix (rdev );
1074
1147
if (rc ) {
1075
1148
pr_err ("Failed to get MSI-X vectors: %#x\n" , rc );
@@ -1101,16 +1174,18 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
1101
1174
(rdev -> en_dev -> pdev , & rdev -> rcfw ,
1102
1175
rdev -> msix_entries [BNXT_RE_AEQ_IDX ].vector ,
1103
1176
rdev -> msix_entries [BNXT_RE_AEQ_IDX ].db_offset ,
1104
- 0 , & bnxt_re_aeq_handler );
1177
+ rdev -> is_virtfn , & bnxt_re_aeq_handler );
1105
1178
if (rc ) {
1106
1179
pr_err ("Failed to enable RCFW channel: %#x\n" , rc );
1107
1180
goto free_ring ;
1108
1181
}
1109
1182
1110
- rc = bnxt_qplib_get_dev_attr (& rdev -> rcfw , & rdev -> dev_attr );
1183
+ rc = bnxt_qplib_get_dev_attr (& rdev -> rcfw , & rdev -> dev_attr ,
1184
+ rdev -> is_virtfn );
1111
1185
if (rc )
1112
1186
goto disable_rcfw ;
1113
- bnxt_re_set_resource_limits (rdev );
1187
+ if (!rdev -> is_virtfn )
1188
+ bnxt_re_set_resource_limits (rdev );
1114
1189
1115
1190
rc = bnxt_qplib_alloc_ctx (rdev -> en_dev -> pdev , & rdev -> qplib_ctx , 0 );
1116
1191
if (rc ) {
@@ -1125,7 +1200,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
1125
1200
goto free_ctx ;
1126
1201
}
1127
1202
1128
- rc = bnxt_qplib_init_rcfw (& rdev -> rcfw , & rdev -> qplib_ctx , 0 );
1203
+ rc = bnxt_qplib_init_rcfw (& rdev -> rcfw , & rdev -> qplib_ctx ,
1204
+ rdev -> is_virtfn );
1129
1205
if (rc ) {
1130
1206
pr_err ("Failed to initialize RCFW: %#x\n" , rc );
1131
1207
goto free_sctx ;
@@ -1144,13 +1220,15 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
1144
1220
goto fail ;
1145
1221
}
1146
1222
1147
- rc = bnxt_re_setup_qos (rdev );
1148
- if (rc )
1149
- pr_info ("RoCE priority not yet configured\n" );
1223
+ if (!rdev -> is_virtfn ) {
1224
+ rc = bnxt_re_setup_qos (rdev );
1225
+ if (rc )
1226
+ pr_info ("RoCE priority not yet configured\n" );
1150
1227
1151
- INIT_DELAYED_WORK (& rdev -> worker , bnxt_re_worker );
1152
- set_bit (BNXT_RE_FLAG_QOS_WORK_REG , & rdev -> flags );
1153
- schedule_delayed_work (& rdev -> worker , msecs_to_jiffies (30000 ));
1228
+ INIT_DELAYED_WORK (& rdev -> worker , bnxt_re_worker );
1229
+ set_bit (BNXT_RE_FLAG_QOS_WORK_REG , & rdev -> flags );
1230
+ schedule_delayed_work (& rdev -> worker , msecs_to_jiffies (30000 ));
1231
+ }
1154
1232
1155
1233
/* Register ib dev */
1156
1234
rc = bnxt_re_register_ib (rdev );
@@ -1400,16 +1478,19 @@ static int __init bnxt_re_mod_init(void)
1400
1478
1401
1479
static void __exit bnxt_re_mod_exit (void )
1402
1480
{
1403
- struct bnxt_re_dev * rdev ;
1481
+ struct bnxt_re_dev * rdev , * next ;
1404
1482
LIST_HEAD (to_be_deleted );
1405
1483
1406
1484
mutex_lock (& bnxt_re_dev_lock );
1407
1485
/* Free all adapter allocated resources */
1408
1486
if (!list_empty (& bnxt_re_dev_list ))
1409
1487
list_splice_init (& bnxt_re_dev_list , & to_be_deleted );
1410
1488
mutex_unlock (& bnxt_re_dev_lock );
1411
-
1412
- list_for_each_entry (rdev , & to_be_deleted , list ) {
1489
+ /*
1490
+ * Cleanup the devices in reverse order so that the VF device
1491
+ * cleanup is done before PF cleanup
1492
+ */
1493
+ list_for_each_entry_safe_reverse (rdev , next , & to_be_deleted , list ) {
1413
1494
dev_info (rdev_to_dev (rdev ), "Unregistering Device" );
1414
1495
bnxt_re_dev_stop (rdev );
1415
1496
bnxt_re_ib_unreg (rdev , true);
0 commit comments