4545
4646#define QM_SQ_TYPE_MASK GENMASK(3, 0)
4747#define QM_SQ_TAIL_IDX (sqc ) ((le16_to_cpu((sqc).w11) >> 6) & 0x1)
48+ #define QM_SQC_DISABLE_QP (1U << 6)
49+ #define QM_XQC_RANDOM_DATA 0xaaaa
4850
4951/* cqc shift */
5052#define QM_CQ_HOP_NUM_SHIFT 0
@@ -3194,6 +3196,9 @@ static int qm_eq_aeq_ctx_cfg(struct hisi_qm *qm)
31943196
31953197 qm_init_eq_aeq_status (qm );
31963198
3199+ /* Before starting the dev, clear the memory and then configure to device using. */
3200+ memset (qm -> qdma .va , 0 , qm -> qdma .size );
3201+
31973202 ret = qm_eq_ctx_cfg (qm );
31983203 if (ret ) {
31993204 dev_err (dev , "Set eqc failed!\n" );
@@ -3205,9 +3210,13 @@ static int qm_eq_aeq_ctx_cfg(struct hisi_qm *qm)
32053210
32063211static int __hisi_qm_start (struct hisi_qm * qm )
32073212{
3213+ struct device * dev = & qm -> pdev -> dev ;
32083214 int ret ;
32093215
3210- WARN_ON (!qm -> qdma .va );
3216+ if (!qm -> qdma .va ) {
3217+ dev_err (dev , "qm qdma is NULL!\n" );
3218+ return - EINVAL ;
3219+ }
32113220
32123221 if (qm -> fun_type == QM_HW_PF ) {
32133222 ret = hisi_qm_set_vft (qm , 0 , qm -> qp_base , qm -> qp_num );
@@ -3281,7 +3290,7 @@ static int qm_restart(struct hisi_qm *qm)
32813290 for (i = 0 ; i < qm -> qp_num ; i ++ ) {
32823291 qp = & qm -> qp_array [i ];
32833292 if (atomic_read (& qp -> qp_status .flags ) == QP_STOP &&
3284- qp -> is_resetting == true) {
3293+ qp -> is_resetting == true && qp -> is_in_kernel == true ) {
32853294 ret = qm_start_qp_nolock (qp , 0 );
32863295 if (ret < 0 ) {
32873296 dev_err (dev , "Failed to start qp%d!\n" , i );
@@ -3313,24 +3322,44 @@ static void qm_stop_started_qp(struct hisi_qm *qm)
33133322}
33143323
33153324/**
3316- * qm_clear_queues () - Clear all queues memory in a qm .
3317- * @qm: The qm in which the queues will be cleared .
3325+ * qm_invalid_queues () - invalid all queues in use .
3326+ * @qm: The qm in which the queues will be invalidated .
33183327 *
3319- * This function clears all queues memory in a qm. Reset of accelerator can
3320- * use this to clear queues.
3328+ * This function invalid all queues in use. If the doorbell command is sent
3329+ * to device in user space after the device is reset, the device discards
3330+ * the doorbell command.
33213331 */
3322- static void qm_clear_queues (struct hisi_qm * qm )
3332+ static void qm_invalid_queues (struct hisi_qm * qm )
33233333{
33243334 struct hisi_qp * qp ;
3335+ struct qm_sqc * sqc ;
3336+ struct qm_cqc * cqc ;
33253337 int i ;
33263338
3339+ /*
3340+ * Normal stop queues is no longer used and does not need to be
3341+ * invalid queues.
3342+ */
3343+ if (qm -> status .stop_reason == QM_NORMAL )
3344+ return ;
3345+
3346+ if (qm -> status .stop_reason == QM_DOWN )
3347+ hisi_qm_cache_wb (qm );
3348+
33273349 for (i = 0 ; i < qm -> qp_num ; i ++ ) {
33283350 qp = & qm -> qp_array [i ];
3329- if (qp -> is_in_kernel && qp -> is_resetting )
3351+ if (!qp -> is_resetting )
3352+ continue ;
3353+
3354+ /* Modify random data and set sqc close bit to invalid queue. */
3355+ sqc = qm -> sqc + i ;
3356+ cqc = qm -> cqc + i ;
3357+ sqc -> w8 = cpu_to_le16 (QM_XQC_RANDOM_DATA );
3358+ sqc -> w13 = cpu_to_le16 (QM_SQC_DISABLE_QP );
3359+ cqc -> w8 = cpu_to_le16 (QM_XQC_RANDOM_DATA );
3360+ if (qp -> is_in_kernel )
33303361 memset (qp -> qdma .va , 0 , qp -> qdma .size );
33313362 }
3332-
3333- memset (qm -> qdma .va , 0 , qm -> qdma .size );
33343363}
33353364
33363365/**
@@ -3387,7 +3416,7 @@ int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r)
33873416 }
33883417 }
33893418
3390- qm_clear_queues (qm );
3419+ qm_invalid_queues (qm );
33913420 qm -> status .stop_reason = QM_NORMAL ;
33923421
33933422err_unlock :
@@ -4785,8 +4814,6 @@ void hisi_qm_dev_shutdown(struct pci_dev *pdev)
47854814 ret = hisi_qm_stop (qm , QM_DOWN );
47864815 if (ret )
47874816 dev_err (& pdev -> dev , "Fail to stop qm in shutdown!\n" );
4788-
4789- hisi_qm_cache_wb (qm );
47904817}
47914818EXPORT_SYMBOL_GPL (hisi_qm_dev_shutdown );
47924819
0 commit comments