@@ -110,12 +110,29 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
110110
111111static void ionic_qcqs_free (struct ionic_lif * lif )
112112{
113+ if (lif -> notifyqcq ) {
114+ ionic_qcq_free (lif , lif -> notifyqcq );
115+ lif -> notifyqcq = NULL ;
116+ }
117+
113118 if (lif -> adminqcq ) {
114119 ionic_qcq_free (lif , lif -> adminqcq );
115120 lif -> adminqcq = NULL ;
116121 }
117122}
118123
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+
119136static int ionic_qcq_alloc (struct ionic_lif * lif , unsigned int type ,
120137 unsigned int index ,
121138 const char * name , unsigned int flags ,
@@ -269,7 +286,91 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
269286 if (err )
270287 return err ;
271288
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+
272303 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 ;
273374}
274375
275376static bool ionic_adminq_service (struct ionic_cq * cq ,
@@ -287,7 +388,15 @@ static bool ionic_adminq_service(struct ionic_cq *cq,
287388
288389static int ionic_adminq_napi (struct napi_struct * napi , int budget )
289390{
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 );
291400}
292401
293402static 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)
417526 clear_bit (IONIC_LIF_INITED , lif -> state );
418527
419528 napi_disable (& lif -> adminqcq -> napi );
529+ ionic_lif_qcq_deinit (lif , lif -> notifyqcq );
420530 ionic_lif_qcq_deinit (lif , lif -> adminqcq );
421531
422532 ionic_lif_reset (lif );
@@ -486,6 +596,55 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif)
486596 return 0 ;
487597}
488598
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+
489648static int ionic_lif_init (struct ionic_lif * lif )
490649{
491650 struct ionic_dev * idev = & lif -> ionic -> idev ;
@@ -535,10 +694,18 @@ static int ionic_lif_init(struct ionic_lif *lif)
535694 if (err )
536695 goto err_out_adminq_deinit ;
537696
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+
538703 set_bit (IONIC_LIF_INITED , lif -> state );
539704
540705 return 0 ;
541706
707+ err_out_notifyq_deinit :
708+ ionic_lif_qcq_deinit (lif , lif -> notifyqcq );
542709err_out_adminq_deinit :
543710 ionic_lif_qcq_deinit (lif , lif -> adminqcq );
544711 ionic_lif_reset (lif );
0 commit comments