@@ -864,6 +864,7 @@ static void liquidio_schedule_droq_pkt_handlers(struct octeon_device *oct)
864
864
* @param irq unused
865
865
* @param dev octeon device
866
866
*/
867
+ static
867
868
irqreturn_t liquidio_legacy_intr_handler (int irq __attribute__((unused )),
868
869
void * dev )
869
870
{
@@ -884,3 +885,202 @@ irqreturn_t liquidio_legacy_intr_handler(int irq __attribute__((unused)),
884
885
885
886
return ret ;
886
887
}
888
+
889
+ /**
890
+ * \brief Setup interrupt for octeon device
891
+ * @param oct octeon device
892
+ *
893
+ * Enable interrupt in Octeon device as given in the PCI interrupt mask.
894
+ */
895
+ int octeon_setup_interrupt (struct octeon_device * oct )
896
+ {
897
+ struct msix_entry * msix_entries ;
898
+ char * queue_irq_names = NULL ;
899
+ int i , num_interrupts = 0 ;
900
+ int num_alloc_ioq_vectors ;
901
+ char * aux_irq_name = NULL ;
902
+ int num_ioq_vectors ;
903
+ int irqret , err ;
904
+
905
+ if (oct -> msix_on ) {
906
+ if (OCTEON_CN23XX_PF (oct )) {
907
+ oct -> num_msix_irqs = oct -> sriov_info .num_pf_rings ;
908
+ num_interrupts = MAX_IOQ_INTERRUPTS_PER_PF + 1 ;
909
+
910
+ /* one non ioq interrupt for handling
911
+ * sli_mac_pf_int_sum
912
+ */
913
+ oct -> num_msix_irqs += 1 ;
914
+ } else if (OCTEON_CN23XX_VF (oct )) {
915
+ oct -> num_msix_irqs = oct -> sriov_info .rings_per_vf ;
916
+ num_interrupts = MAX_IOQ_INTERRUPTS_PER_VF ;
917
+ }
918
+
919
+ /* allocate storage for the names assigned to each irq */
920
+ oct -> irq_name_storage =
921
+ kcalloc (num_interrupts , INTRNAMSIZ , GFP_KERNEL );
922
+ if (!oct -> irq_name_storage ) {
923
+ dev_err (& oct -> pci_dev -> dev , "Irq name storage alloc failed...\n" );
924
+ return - ENOMEM ;
925
+ }
926
+
927
+ queue_irq_names = oct -> irq_name_storage ;
928
+
929
+ if (OCTEON_CN23XX_PF (oct ))
930
+ aux_irq_name = & queue_irq_names
931
+ [IRQ_NAME_OFF (MAX_IOQ_INTERRUPTS_PER_PF )];
932
+
933
+ oct -> msix_entries = kcalloc (oct -> num_msix_irqs ,
934
+ sizeof (struct msix_entry ),
935
+ GFP_KERNEL );
936
+ if (!oct -> msix_entries ) {
937
+ dev_err (& oct -> pci_dev -> dev , "Memory Alloc failed...\n" );
938
+ kfree (oct -> irq_name_storage );
939
+ oct -> irq_name_storage = NULL ;
940
+ return - ENOMEM ;
941
+ }
942
+
943
+ msix_entries = (struct msix_entry * )oct -> msix_entries ;
944
+
945
+ /*Assumption is that pf msix vectors start from pf srn to pf to
946
+ * trs and not from 0. if not change this code
947
+ */
948
+ if (OCTEON_CN23XX_PF (oct )) {
949
+ for (i = 0 ; i < oct -> num_msix_irqs - 1 ; i ++ )
950
+ msix_entries [i ].entry =
951
+ oct -> sriov_info .pf_srn + i ;
952
+
953
+ msix_entries [oct -> num_msix_irqs - 1 ].entry =
954
+ oct -> sriov_info .trs ;
955
+ } else if (OCTEON_CN23XX_VF (oct )) {
956
+ for (i = 0 ; i < oct -> num_msix_irqs ; i ++ )
957
+ msix_entries [i ].entry = i ;
958
+ }
959
+ num_alloc_ioq_vectors = pci_enable_msix_range (
960
+ oct -> pci_dev , msix_entries ,
961
+ oct -> num_msix_irqs ,
962
+ oct -> num_msix_irqs );
963
+ if (num_alloc_ioq_vectors < 0 ) {
964
+ dev_err (& oct -> pci_dev -> dev , "unable to Allocate MSI-X interrupts\n" );
965
+ kfree (oct -> msix_entries );
966
+ oct -> msix_entries = NULL ;
967
+ kfree (oct -> irq_name_storage );
968
+ oct -> irq_name_storage = NULL ;
969
+ return num_alloc_ioq_vectors ;
970
+ }
971
+
972
+ dev_dbg (& oct -> pci_dev -> dev , "OCTEON: Enough MSI-X interrupts are allocated...\n" );
973
+
974
+ num_ioq_vectors = oct -> num_msix_irqs ;
975
+ /** For PF, there is one non-ioq interrupt handler */
976
+ if (OCTEON_CN23XX_PF (oct )) {
977
+ num_ioq_vectors -= 1 ;
978
+
979
+ snprintf (aux_irq_name , INTRNAMSIZ ,
980
+ "LiquidIO%u-pf%u-aux" , oct -> octeon_id ,
981
+ oct -> pf_num );
982
+ irqret = request_irq (
983
+ msix_entries [num_ioq_vectors ].vector ,
984
+ liquidio_legacy_intr_handler , 0 ,
985
+ aux_irq_name , oct );
986
+ if (irqret ) {
987
+ dev_err (& oct -> pci_dev -> dev ,
988
+ "Request_irq failed for MSIX interrupt Error: %d\n" ,
989
+ irqret );
990
+ pci_disable_msix (oct -> pci_dev );
991
+ kfree (oct -> msix_entries );
992
+ kfree (oct -> irq_name_storage );
993
+ oct -> irq_name_storage = NULL ;
994
+ oct -> msix_entries = NULL ;
995
+ return irqret ;
996
+ }
997
+ }
998
+ for (i = 0 ; i < num_ioq_vectors ; i ++ ) {
999
+ if (OCTEON_CN23XX_PF (oct ))
1000
+ snprintf (& queue_irq_names [IRQ_NAME_OFF (i )],
1001
+ INTRNAMSIZ , "LiquidIO%u-pf%u-rxtx-%u" ,
1002
+ oct -> octeon_id , oct -> pf_num , i );
1003
+
1004
+ if (OCTEON_CN23XX_VF (oct ))
1005
+ snprintf (& queue_irq_names [IRQ_NAME_OFF (i )],
1006
+ INTRNAMSIZ , "LiquidIO%u-vf%u-rxtx-%u" ,
1007
+ oct -> octeon_id , oct -> vf_num , i );
1008
+
1009
+ irqret = request_irq (msix_entries [i ].vector ,
1010
+ liquidio_msix_intr_handler , 0 ,
1011
+ & queue_irq_names [IRQ_NAME_OFF (i )],
1012
+ & oct -> ioq_vector [i ]);
1013
+
1014
+ if (irqret ) {
1015
+ dev_err (& oct -> pci_dev -> dev ,
1016
+ "Request_irq failed for MSIX interrupt Error: %d\n" ,
1017
+ irqret );
1018
+ /** Freeing the non-ioq irq vector here . */
1019
+ free_irq (msix_entries [num_ioq_vectors ].vector ,
1020
+ oct );
1021
+
1022
+ while (i ) {
1023
+ i -- ;
1024
+ /** clearing affinity mask. */
1025
+ irq_set_affinity_hint (
1026
+ msix_entries [i ].vector ,
1027
+ NULL );
1028
+ free_irq (msix_entries [i ].vector ,
1029
+ & oct -> ioq_vector [i ]);
1030
+ }
1031
+ pci_disable_msix (oct -> pci_dev );
1032
+ kfree (oct -> msix_entries );
1033
+ kfree (oct -> irq_name_storage );
1034
+ oct -> irq_name_storage = NULL ;
1035
+ oct -> msix_entries = NULL ;
1036
+ return irqret ;
1037
+ }
1038
+ oct -> ioq_vector [i ].vector = msix_entries [i ].vector ;
1039
+ /* assign the cpu mask for this msix interrupt vector */
1040
+ irq_set_affinity_hint (msix_entries [i ].vector ,
1041
+ & oct -> ioq_vector [i ].affinity_mask
1042
+ );
1043
+ }
1044
+ dev_dbg (& oct -> pci_dev -> dev , "OCTEON[%d]: MSI-X enabled\n" ,
1045
+ oct -> octeon_id );
1046
+ } else {
1047
+ err = pci_enable_msi (oct -> pci_dev );
1048
+ if (err )
1049
+ dev_warn (& oct -> pci_dev -> dev , "Reverting to legacy interrupts. Error: %d\n" ,
1050
+ err );
1051
+ else
1052
+ oct -> flags |= LIO_FLAG_MSI_ENABLED ;
1053
+
1054
+ /* allocate storage for the names assigned to the irq */
1055
+ oct -> irq_name_storage = kcalloc (1 , INTRNAMSIZ , GFP_KERNEL );
1056
+ if (!oct -> irq_name_storage )
1057
+ return - ENOMEM ;
1058
+
1059
+ queue_irq_names = oct -> irq_name_storage ;
1060
+
1061
+ if (OCTEON_CN23XX_PF (oct ))
1062
+ snprintf (& queue_irq_names [IRQ_NAME_OFF (0 )], INTRNAMSIZ ,
1063
+ "LiquidIO%u-pf%u-rxtx-%u" ,
1064
+ oct -> octeon_id , oct -> pf_num , 0 );
1065
+
1066
+ if (OCTEON_CN23XX_VF (oct ))
1067
+ snprintf (& queue_irq_names [IRQ_NAME_OFF (0 )], INTRNAMSIZ ,
1068
+ "LiquidIO%u-vf%u-rxtx-%u" ,
1069
+ oct -> octeon_id , oct -> vf_num , 0 );
1070
+
1071
+ irqret = request_irq (oct -> pci_dev -> irq ,
1072
+ liquidio_legacy_intr_handler ,
1073
+ IRQF_SHARED ,
1074
+ & queue_irq_names [IRQ_NAME_OFF (0 )], oct );
1075
+ if (irqret ) {
1076
+ if (oct -> flags & LIO_FLAG_MSI_ENABLED )
1077
+ pci_disable_msi (oct -> pci_dev );
1078
+ dev_err (& oct -> pci_dev -> dev , "Request IRQ failed with code: %d\n" ,
1079
+ irqret );
1080
+ kfree (oct -> irq_name_storage );
1081
+ oct -> irq_name_storage = NULL ;
1082
+ return irqret ;
1083
+ }
1084
+ }
1085
+ return 0 ;
1086
+ }
0 commit comments