@@ -110,12 +110,29 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
110
110
111
111
static void ionic_qcqs_free (struct ionic_lif * lif )
112
112
{
113
+ if (lif -> notifyqcq ) {
114
+ ionic_qcq_free (lif , lif -> notifyqcq );
115
+ lif -> notifyqcq = NULL ;
116
+ }
117
+
113
118
if (lif -> adminqcq ) {
114
119
ionic_qcq_free (lif , lif -> adminqcq );
115
120
lif -> adminqcq = NULL ;
116
121
}
117
122
}
118
123
124
+ static void ionic_link_qcq_interrupts (struct ionic_qcq * src_qcq ,
125
+ struct ionic_qcq * n_qcq )
126
+ {
127
+ if (WARN_ON (n_qcq -> flags & IONIC_QCQ_F_INTR )) {
128
+ ionic_intr_free (n_qcq -> cq .lif , n_qcq -> intr .index );
129
+ n_qcq -> flags &= ~IONIC_QCQ_F_INTR ;
130
+ }
131
+
132
+ n_qcq -> intr .vector = src_qcq -> intr .vector ;
133
+ n_qcq -> intr .index = src_qcq -> intr .index ;
134
+ }
135
+
119
136
static int ionic_qcq_alloc (struct ionic_lif * lif , unsigned int type ,
120
137
unsigned int index ,
121
138
const char * name , unsigned int flags ,
@@ -269,7 +286,91 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
269
286
if (err )
270
287
return err ;
271
288
289
+ if (lif -> ionic -> nnqs_per_lif ) {
290
+ flags = IONIC_QCQ_F_NOTIFYQ ;
291
+ err = ionic_qcq_alloc (lif , IONIC_QTYPE_NOTIFYQ , 0 , "notifyq" ,
292
+ flags , IONIC_NOTIFYQ_LENGTH ,
293
+ sizeof (struct ionic_notifyq_cmd ),
294
+ sizeof (union ionic_notifyq_comp ),
295
+ 0 , lif -> kern_pid , & lif -> notifyqcq );
296
+ if (err )
297
+ goto err_out_free_adminqcq ;
298
+
299
+ /* Let the notifyq ride on the adminq interrupt */
300
+ ionic_link_qcq_interrupts (lif -> adminqcq , lif -> notifyqcq );
301
+ }
302
+
272
303
return 0 ;
304
+
305
+ err_out_free_adminqcq :
306
+ ionic_qcq_free (lif , lif -> adminqcq );
307
+ lif -> adminqcq = NULL ;
308
+
309
+ return err ;
310
+ }
311
+
312
+ static bool ionic_notifyq_service (struct ionic_cq * cq ,
313
+ struct ionic_cq_info * cq_info )
314
+ {
315
+ union ionic_notifyq_comp * comp = cq_info -> cq_desc ;
316
+ struct net_device * netdev ;
317
+ struct ionic_queue * q ;
318
+ struct ionic_lif * lif ;
319
+ u64 eid ;
320
+
321
+ q = cq -> bound_q ;
322
+ lif = q -> info [0 ].cb_arg ;
323
+ netdev = lif -> netdev ;
324
+ eid = le64_to_cpu (comp -> event .eid );
325
+
326
+ /* Have we run out of new completions to process? */
327
+ if (eid <= lif -> last_eid )
328
+ return false;
329
+
330
+ lif -> last_eid = eid ;
331
+
332
+ dev_dbg (lif -> ionic -> dev , "notifyq event:\n" );
333
+ dynamic_hex_dump ("event " , DUMP_PREFIX_OFFSET , 16 , 1 ,
334
+ comp , sizeof (* comp ), true);
335
+
336
+ switch (le16_to_cpu (comp -> event .ecode )) {
337
+ case IONIC_EVENT_LINK_CHANGE :
338
+ netdev_info (netdev , "Notifyq IONIC_EVENT_LINK_CHANGE eid=%lld\n" ,
339
+ eid );
340
+ netdev_info (netdev ,
341
+ " link_status=%d link_speed=%d\n" ,
342
+ le16_to_cpu (comp -> link_change .link_status ),
343
+ le32_to_cpu (comp -> link_change .link_speed ));
344
+ break ;
345
+ case IONIC_EVENT_RESET :
346
+ netdev_info (netdev , "Notifyq IONIC_EVENT_RESET eid=%lld\n" ,
347
+ eid );
348
+ netdev_info (netdev , " reset_code=%d state=%d\n" ,
349
+ comp -> reset .reset_code ,
350
+ comp -> reset .state );
351
+ break ;
352
+ default :
353
+ netdev_warn (netdev , "Notifyq unknown event ecode=%d eid=%lld\n" ,
354
+ comp -> event .ecode , eid );
355
+ break ;
356
+ }
357
+
358
+ return true;
359
+ }
360
+
361
+ static int ionic_notifyq_clean (struct ionic_lif * lif , int budget )
362
+ {
363
+ struct ionic_dev * idev = & lif -> ionic -> idev ;
364
+ struct ionic_cq * cq = & lif -> notifyqcq -> cq ;
365
+ u32 work_done ;
366
+
367
+ work_done = ionic_cq_service (cq , budget , ionic_notifyq_service ,
368
+ NULL , NULL );
369
+ if (work_done )
370
+ ionic_intr_credits (idev -> intr_ctrl , cq -> bound_intr -> index ,
371
+ work_done , IONIC_INTR_CRED_RESET_COALESCE );
372
+
373
+ return work_done ;
273
374
}
274
375
275
376
static bool ionic_adminq_service (struct ionic_cq * cq ,
@@ -287,7 +388,15 @@ static bool ionic_adminq_service(struct ionic_cq *cq,
287
388
288
389
static int ionic_adminq_napi (struct napi_struct * napi , int budget )
289
390
{
290
- return ionic_napi (napi , budget , ionic_adminq_service , NULL , NULL );
391
+ struct ionic_lif * lif = napi_to_cq (napi )-> lif ;
392
+ int n_work = 0 ;
393
+ int a_work = 0 ;
394
+
395
+ if (likely (lif -> notifyqcq && lif -> notifyqcq -> flags & IONIC_QCQ_F_INITED ))
396
+ n_work = ionic_notifyq_clean (lif , budget );
397
+ a_work = ionic_napi (napi , budget , ionic_adminq_service , NULL , NULL );
398
+
399
+ return max (n_work , a_work );
291
400
}
292
401
293
402
static struct ionic_lif * ionic_lif_alloc (struct ionic * ionic , unsigned int index )
@@ -417,6 +526,7 @@ static void ionic_lif_deinit(struct ionic_lif *lif)
417
526
clear_bit (IONIC_LIF_INITED , lif -> state );
418
527
419
528
napi_disable (& lif -> adminqcq -> napi );
529
+ ionic_lif_qcq_deinit (lif , lif -> notifyqcq );
420
530
ionic_lif_qcq_deinit (lif , lif -> adminqcq );
421
531
422
532
ionic_lif_reset (lif );
@@ -486,6 +596,55 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif)
486
596
return 0 ;
487
597
}
488
598
599
+ static int ionic_lif_notifyq_init (struct ionic_lif * lif )
600
+ {
601
+ struct ionic_qcq * qcq = lif -> notifyqcq ;
602
+ struct device * dev = lif -> ionic -> dev ;
603
+ struct ionic_queue * q = & qcq -> q ;
604
+ int err ;
605
+
606
+ struct ionic_admin_ctx ctx = {
607
+ .work = COMPLETION_INITIALIZER_ONSTACK (ctx .work ),
608
+ .cmd .q_init = {
609
+ .opcode = IONIC_CMD_Q_INIT ,
610
+ .lif_index = cpu_to_le16 (lif -> index ),
611
+ .type = q -> type ,
612
+ .index = cpu_to_le32 (q -> index ),
613
+ .flags = cpu_to_le16 (IONIC_QINIT_F_IRQ |
614
+ IONIC_QINIT_F_ENA ),
615
+ .intr_index = cpu_to_le16 (lif -> adminqcq -> intr .index ),
616
+ .pid = cpu_to_le16 (q -> pid ),
617
+ .ring_size = ilog2 (q -> num_descs ),
618
+ .ring_base = cpu_to_le64 (q -> base_pa ),
619
+ }
620
+ };
621
+
622
+ dev_dbg (dev , "notifyq_init.pid %d\n" , ctx .cmd .q_init .pid );
623
+ dev_dbg (dev , "notifyq_init.index %d\n" , ctx .cmd .q_init .index );
624
+ dev_dbg (dev , "notifyq_init.ring_base 0x%llx\n" , ctx .cmd .q_init .ring_base );
625
+ dev_dbg (dev , "notifyq_init.ring_size %d\n" , ctx .cmd .q_init .ring_size );
626
+
627
+ err = ionic_adminq_post_wait (lif , & ctx );
628
+ if (err )
629
+ return err ;
630
+
631
+ q -> hw_type = ctx .comp .q_init .hw_type ;
632
+ q -> hw_index = le32_to_cpu (ctx .comp .q_init .hw_index );
633
+ q -> dbval = IONIC_DBELL_QID (q -> hw_index );
634
+
635
+ dev_dbg (dev , "notifyq->hw_type %d\n" , q -> hw_type );
636
+ dev_dbg (dev , "notifyq->hw_index %d\n" , q -> hw_index );
637
+
638
+ /* preset the callback info */
639
+ q -> info [0 ].cb_arg = lif ;
640
+
641
+ qcq -> flags |= IONIC_QCQ_F_INITED ;
642
+
643
+ ionic_debugfs_add_qcq (lif , qcq );
644
+
645
+ return 0 ;
646
+ }
647
+
489
648
static int ionic_lif_init (struct ionic_lif * lif )
490
649
{
491
650
struct ionic_dev * idev = & lif -> ionic -> idev ;
@@ -535,10 +694,18 @@ static int ionic_lif_init(struct ionic_lif *lif)
535
694
if (err )
536
695
goto err_out_adminq_deinit ;
537
696
697
+ if (lif -> ionic -> nnqs_per_lif ) {
698
+ err = ionic_lif_notifyq_init (lif );
699
+ if (err )
700
+ goto err_out_notifyq_deinit ;
701
+ }
702
+
538
703
set_bit (IONIC_LIF_INITED , lif -> state );
539
704
540
705
return 0 ;
541
706
707
+ err_out_notifyq_deinit :
708
+ ionic_lif_qcq_deinit (lif , lif -> notifyqcq );
542
709
err_out_adminq_deinit :
543
710
ionic_lif_qcq_deinit (lif , lif -> adminqcq );
544
711
ionic_lif_reset (lif );
0 commit comments