@@ -66,8 +66,9 @@ struct nicpf {
66
66
/* MSI-X */
67
67
bool msix_enabled ;
68
68
u8 num_vec ;
69
- struct msix_entry msix_entries [ NIC_PF_MSIX_VECTORS ] ;
69
+ struct msix_entry * msix_entries ;
70
70
bool irq_allocated [NIC_PF_MSIX_VECTORS ];
71
+ char irq_name [NIC_PF_MSIX_VECTORS ][20 ];
71
72
};
72
73
73
74
/* Supported devices */
@@ -105,9 +106,22 @@ static u64 nic_reg_read(struct nicpf *nic, u64 offset)
105
106
/* PF -> VF mailbox communication APIs */
106
107
static void nic_enable_mbx_intr (struct nicpf * nic )
107
108
{
108
- /* Enable mailbox interrupt for all 128 VFs */
109
- nic_reg_write (nic , NIC_PF_MAILBOX_ENA_W1S , ~0ull );
110
- nic_reg_write (nic , NIC_PF_MAILBOX_ENA_W1S + sizeof (u64 ), ~0ull );
109
+ int vf_cnt = pci_sriov_get_totalvfs (nic -> pdev );
110
+
111
+ #define INTR_MASK (vfs ) ((vfs < 64) ? (BIT_ULL(vfs) - 1) : (~0ull))
112
+
113
+ /* Clear it, to avoid spurious interrupts (if any) */
114
+ nic_reg_write (nic , NIC_PF_MAILBOX_INT , INTR_MASK (vf_cnt ));
115
+
116
+ /* Enable mailbox interrupt for all VFs */
117
+ nic_reg_write (nic , NIC_PF_MAILBOX_ENA_W1S , INTR_MASK (vf_cnt ));
118
+ /* One mailbox intr enable reg per 64 VFs */
119
+ if (vf_cnt > 64 ) {
120
+ nic_reg_write (nic , NIC_PF_MAILBOX_INT + sizeof (u64 ),
121
+ INTR_MASK (vf_cnt - 64 ));
122
+ nic_reg_write (nic , NIC_PF_MAILBOX_ENA_W1S + sizeof (u64 ),
123
+ INTR_MASK (vf_cnt - 64 ));
124
+ }
111
125
}
112
126
113
127
static void nic_clear_mbx_intr (struct nicpf * nic , int vf , int mbx_reg )
@@ -894,11 +908,18 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
894
908
nic -> mbx_lock [vf ] = false;
895
909
}
896
910
897
- static void nic_mbx_intr_handler ( struct nicpf * nic , int mbx )
911
+ static irqreturn_t nic_mbx_intr_handler ( int irq , void * nic_irq )
898
912
{
913
+ struct nicpf * nic = (struct nicpf * )nic_irq ;
914
+ int mbx ;
899
915
u64 intr ;
900
916
u8 vf , vf_per_mbx_reg = 64 ;
901
917
918
+ if (irq == nic -> msix_entries [NIC_PF_INTR_ID_MBOX0 ].vector )
919
+ mbx = 0 ;
920
+ else
921
+ mbx = 1 ;
922
+
902
923
intr = nic_reg_read (nic , NIC_PF_MAILBOX_INT + (mbx << 3 ));
903
924
dev_dbg (& nic -> pdev -> dev , "PF interrupt Mbox%d 0x%llx\n" , mbx , intr );
904
925
for (vf = 0 ; vf < vf_per_mbx_reg ; vf ++ ) {
@@ -910,40 +931,30 @@ static void nic_mbx_intr_handler (struct nicpf *nic, int mbx)
910
931
nic_clear_mbx_intr (nic , vf , mbx );
911
932
}
912
933
}
913
- }
914
-
915
- static irqreturn_t nic_mbx0_intr_handler (int irq , void * nic_irq )
916
- {
917
- struct nicpf * nic = (struct nicpf * )nic_irq ;
918
-
919
- nic_mbx_intr_handler (nic , 0 );
920
-
921
- return IRQ_HANDLED ;
922
- }
923
-
924
- static irqreturn_t nic_mbx1_intr_handler (int irq , void * nic_irq )
925
- {
926
- struct nicpf * nic = (struct nicpf * )nic_irq ;
927
-
928
- nic_mbx_intr_handler (nic , 1 );
929
-
930
934
return IRQ_HANDLED ;
931
935
}
932
936
933
937
static int nic_enable_msix (struct nicpf * nic )
934
938
{
935
939
int i , ret ;
936
940
937
- nic -> num_vec = NIC_PF_MSIX_VECTORS ;
941
+ nic -> num_vec = pci_msix_vec_count (nic -> pdev );
942
+
943
+ nic -> msix_entries = kmalloc_array (nic -> num_vec ,
944
+ sizeof (struct msix_entry ),
945
+ GFP_KERNEL );
946
+ if (!nic -> msix_entries )
947
+ return - ENOMEM ;
938
948
939
949
for (i = 0 ; i < nic -> num_vec ; i ++ )
940
950
nic -> msix_entries [i ].entry = i ;
941
951
942
952
ret = pci_enable_msix (nic -> pdev , nic -> msix_entries , nic -> num_vec );
943
953
if (ret ) {
944
954
dev_err (& nic -> pdev -> dev ,
945
- "Request for #%d msix vectors failed\n" ,
946
- nic -> num_vec );
955
+ "Request for #%d msix vectors failed, returned %d\n" ,
956
+ nic -> num_vec , ret );
957
+ kfree (nic -> msix_entries );
947
958
return ret ;
948
959
}
949
960
@@ -955,6 +966,7 @@ static void nic_disable_msix(struct nicpf *nic)
955
966
{
956
967
if (nic -> msix_enabled ) {
957
968
pci_disable_msix (nic -> pdev );
969
+ kfree (nic -> msix_entries );
958
970
nic -> msix_enabled = 0 ;
959
971
nic -> num_vec = 0 ;
960
972
}
@@ -973,27 +985,26 @@ static void nic_free_all_interrupts(struct nicpf *nic)
973
985
974
986
static int nic_register_interrupts (struct nicpf * nic )
975
987
{
976
- int ret ;
988
+ int i , ret ;
977
989
978
990
/* Enable MSI-X */
979
991
ret = nic_enable_msix (nic );
980
992
if (ret )
981
993
return ret ;
982
994
983
- /* Register mailbox interrupt handlers */
984
- ret = request_irq (nic -> msix_entries [NIC_PF_INTR_ID_MBOX0 ].vector ,
985
- nic_mbx0_intr_handler , 0 , "NIC Mbox0" , nic );
986
- if (ret )
987
- goto fail ;
995
+ /* Register mailbox interrupt handler */
996
+ for (i = NIC_PF_INTR_ID_MBOX0 ; i < nic -> num_vec ; i ++ ) {
997
+ sprintf (nic -> irq_name [i ],
998
+ "NICPF Mbox%d" , (i - NIC_PF_INTR_ID_MBOX0 ));
988
999
989
- nic -> irq_allocated [NIC_PF_INTR_ID_MBOX0 ] = true;
1000
+ ret = request_irq (nic -> msix_entries [i ].vector ,
1001
+ nic_mbx_intr_handler , 0 ,
1002
+ nic -> irq_name [i ], nic );
1003
+ if (ret )
1004
+ goto fail ;
990
1005
991
- ret = request_irq (nic -> msix_entries [NIC_PF_INTR_ID_MBOX1 ].vector ,
992
- nic_mbx1_intr_handler , 0 , "NIC Mbox1" , nic );
993
- if (ret )
994
- goto fail ;
995
-
996
- nic -> irq_allocated [NIC_PF_INTR_ID_MBOX1 ] = true;
1006
+ nic -> irq_allocated [i ] = true;
1007
+ }
997
1008
998
1009
/* Enable mailbox interrupt */
999
1010
nic_enable_mbx_intr (nic );
@@ -1002,6 +1013,7 @@ static int nic_register_interrupts(struct nicpf *nic)
1002
1013
fail :
1003
1014
dev_err (& nic -> pdev -> dev , "Request irq failed\n" );
1004
1015
nic_free_all_interrupts (nic );
1016
+ nic_disable_msix (nic );
1005
1017
return ret ;
1006
1018
}
1007
1019
0 commit comments