@@ -3046,6 +3046,7 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)
3046
3046
static void ice_ena_misc_vector (struct ice_pf * pf )
3047
3047
{
3048
3048
struct ice_hw * hw = & pf -> hw ;
3049
+ u32 pf_intr_start_offset ;
3049
3050
u32 val ;
3050
3051
3051
3052
/* Disable anti-spoof detection interrupt to prevent spurious event
@@ -3074,6 +3075,47 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
3074
3075
/* SW_ITR_IDX = 0, but don't change INTENA */
3075
3076
wr32 (hw , GLINT_DYN_CTL (pf -> oicr_irq .index ),
3076
3077
GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M );
3078
+
3079
+ if (!pf -> hw .dev_caps .ts_dev_info .ts_ll_int_read )
3080
+ return ;
3081
+ pf_intr_start_offset = rd32 (hw , PFINT_ALLOC ) & PFINT_ALLOC_FIRST ;
3082
+ wr32 (hw , GLINT_DYN_CTL (pf -> ll_ts_irq .index + pf_intr_start_offset ),
3083
+ GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M );
3084
+ }
3085
+
3086
+ /**
3087
+ * ice_ll_ts_intr - ll_ts interrupt handler
3088
+ * @irq: interrupt number
3089
+ * @data: pointer to a q_vector
3090
+ */
3091
+ static irqreturn_t ice_ll_ts_intr (int __always_unused irq , void * data )
3092
+ {
3093
+ struct ice_pf * pf = data ;
3094
+ u32 pf_intr_start_offset ;
3095
+ struct ice_ptp_tx * tx ;
3096
+ unsigned long flags ;
3097
+ struct ice_hw * hw ;
3098
+ u32 val ;
3099
+ u8 idx ;
3100
+
3101
+ hw = & pf -> hw ;
3102
+ tx = & pf -> ptp .port .tx ;
3103
+ spin_lock_irqsave (& tx -> lock , flags );
3104
+ ice_ptp_complete_tx_single_tstamp (tx );
3105
+
3106
+ idx = find_next_bit_wrap (tx -> in_use , tx -> len ,
3107
+ tx -> last_ll_ts_idx_read + 1 );
3108
+ if (idx != tx -> len )
3109
+ ice_ptp_req_tx_single_tstamp (tx , idx );
3110
+ spin_unlock_irqrestore (& tx -> lock , flags );
3111
+
3112
+ val = GLINT_DYN_CTL_INTENA_M | GLINT_DYN_CTL_CLEARPBA_M |
3113
+ (ICE_ITR_NONE << GLINT_DYN_CTL_ITR_INDX_S );
3114
+ pf_intr_start_offset = rd32 (hw , PFINT_ALLOC ) & PFINT_ALLOC_FIRST ;
3115
+ wr32 (hw , GLINT_DYN_CTL (pf -> ll_ts_irq .index + pf_intr_start_offset ),
3116
+ val );
3117
+
3118
+ return IRQ_HANDLED ;
3077
3119
}
3078
3120
3079
3121
/**
@@ -3166,7 +3208,19 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
3166
3208
3167
3209
if (oicr & PFINT_OICR_TSYN_TX_M ) {
3168
3210
ena_mask &= ~PFINT_OICR_TSYN_TX_M ;
3169
- if (ice_ptp_pf_handles_tx_interrupt (pf )) {
3211
+ if (ice_pf_state_is_nominal (pf ) &&
3212
+ pf -> hw .dev_caps .ts_dev_info .ts_ll_int_read ) {
3213
+ struct ice_ptp_tx * tx = & pf -> ptp .port .tx ;
3214
+ unsigned long flags ;
3215
+ u8 idx ;
3216
+
3217
+ spin_lock_irqsave (& tx -> lock , flags );
3218
+ idx = find_next_bit_wrap (tx -> in_use , tx -> len ,
3219
+ tx -> last_ll_ts_idx_read + 1 );
3220
+ if (idx != tx -> len )
3221
+ ice_ptp_req_tx_single_tstamp (tx , idx );
3222
+ spin_unlock_irqrestore (& tx -> lock , flags );
3223
+ } else if (ice_ptp_pf_handles_tx_interrupt (pf )) {
3170
3224
set_bit (ICE_MISC_THREAD_TX_TSTAMP , pf -> misc_thread );
3171
3225
ret = IRQ_WAKE_THREAD ;
3172
3226
}
@@ -3270,6 +3324,20 @@ static void ice_dis_ctrlq_interrupts(struct ice_hw *hw)
3270
3324
ice_flush (hw );
3271
3325
}
3272
3326
3327
+ /**
3328
+ * ice_free_irq_msix_ll_ts- Unroll ll_ts vector setup
3329
+ * @pf: board private structure
3330
+ */
3331
+ static void ice_free_irq_msix_ll_ts (struct ice_pf * pf )
3332
+ {
3333
+ int irq_num = pf -> ll_ts_irq .virq ;
3334
+
3335
+ synchronize_irq (irq_num );
3336
+ devm_free_irq (ice_pf_to_dev (pf ), irq_num , pf );
3337
+
3338
+ ice_free_irq (pf , pf -> ll_ts_irq );
3339
+ }
3340
+
3273
3341
/**
3274
3342
* ice_free_irq_msix_misc - Unroll misc vector setup
3275
3343
* @pf: board private structure
@@ -3289,6 +3357,8 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
3289
3357
devm_free_irq (ice_pf_to_dev (pf ), misc_irq_num , pf );
3290
3358
3291
3359
ice_free_irq (pf , pf -> oicr_irq );
3360
+ if (pf -> hw .dev_caps .ts_dev_info .ts_ll_int_read )
3361
+ ice_free_irq_msix_ll_ts (pf );
3292
3362
}
3293
3363
3294
3364
/**
@@ -3314,10 +3384,12 @@ static void ice_ena_ctrlq_interrupts(struct ice_hw *hw, u16 reg_idx)
3314
3384
PFINT_MBX_CTL_CAUSE_ENA_M );
3315
3385
wr32 (hw , PFINT_MBX_CTL , val );
3316
3386
3317
- /* This enables Sideband queue Interrupt causes */
3318
- val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M ) |
3319
- PFINT_SB_CTL_CAUSE_ENA_M );
3320
- wr32 (hw , PFINT_SB_CTL , val );
3387
+ if (!hw -> dev_caps .ts_dev_info .ts_ll_int_read ) {
3388
+ /* enable Sideband queue Interrupt causes */
3389
+ val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M ) |
3390
+ PFINT_SB_CTL_CAUSE_ENA_M );
3391
+ wr32 (hw , PFINT_SB_CTL , val );
3392
+ }
3321
3393
3322
3394
ice_flush (hw );
3323
3395
}
@@ -3334,13 +3406,17 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
3334
3406
{
3335
3407
struct device * dev = ice_pf_to_dev (pf );
3336
3408
struct ice_hw * hw = & pf -> hw ;
3337
- struct msi_map oicr_irq ;
3409
+ u32 pf_intr_start_offset ;
3410
+ struct msi_map irq ;
3338
3411
int err = 0 ;
3339
3412
3340
3413
if (!pf -> int_name [0 ])
3341
3414
snprintf (pf -> int_name , sizeof (pf -> int_name ) - 1 , "%s-%s:misc" ,
3342
3415
dev_driver_string (dev ), dev_name (dev ));
3343
3416
3417
+ if (!pf -> int_name_ll_ts [0 ])
3418
+ snprintf (pf -> int_name_ll_ts , sizeof (pf -> int_name_ll_ts ) - 1 ,
3419
+ "%s-%s:ll_ts" , dev_driver_string (dev ), dev_name (dev ));
3344
3420
/* Do not request IRQ but do enable OICR interrupt since settings are
3345
3421
* lost during reset. Note that this function is called only during
3346
3422
* rebuild path and not while reset is in progress.
@@ -3349,11 +3425,11 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
3349
3425
goto skip_req_irq ;
3350
3426
3351
3427
/* reserve one vector in irq_tracker for misc interrupts */
3352
- oicr_irq = ice_alloc_irq (pf , false);
3353
- if (oicr_irq .index < 0 )
3354
- return oicr_irq .index ;
3428
+ irq = ice_alloc_irq (pf , false);
3429
+ if (irq .index < 0 )
3430
+ return irq .index ;
3355
3431
3356
- pf -> oicr_irq = oicr_irq ;
3432
+ pf -> oicr_irq = irq ;
3357
3433
err = devm_request_threaded_irq (dev , pf -> oicr_irq .virq , ice_misc_intr ,
3358
3434
ice_misc_intr_thread_fn , 0 ,
3359
3435
pf -> int_name , pf );
@@ -3364,10 +3440,34 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
3364
3440
return err ;
3365
3441
}
3366
3442
3443
+ /* reserve one vector in irq_tracker for ll_ts interrupt */
3444
+ if (!pf -> hw .dev_caps .ts_dev_info .ts_ll_int_read )
3445
+ goto skip_req_irq ;
3446
+
3447
+ irq = ice_alloc_irq (pf , false);
3448
+ if (irq .index < 0 )
3449
+ return irq .index ;
3450
+
3451
+ pf -> ll_ts_irq = irq ;
3452
+ err = devm_request_irq (dev , pf -> ll_ts_irq .virq , ice_ll_ts_intr , 0 ,
3453
+ pf -> int_name_ll_ts , pf );
3454
+ if (err ) {
3455
+ dev_err (dev , "devm_request_irq for %s failed: %d\n" ,
3456
+ pf -> int_name_ll_ts , err );
3457
+ ice_free_irq (pf , pf -> ll_ts_irq );
3458
+ return err ;
3459
+ }
3460
+
3367
3461
skip_req_irq :
3368
3462
ice_ena_misc_vector (pf );
3369
3463
3370
3464
ice_ena_ctrlq_interrupts (hw , pf -> oicr_irq .index );
3465
+ /* This enables LL TS interrupt */
3466
+ pf_intr_start_offset = rd32 (hw , PFINT_ALLOC ) & PFINT_ALLOC_FIRST ;
3467
+ if (pf -> hw .dev_caps .ts_dev_info .ts_ll_int_read )
3468
+ wr32 (hw , PFINT_SB_CTL ,
3469
+ ((pf -> ll_ts_irq .index + pf_intr_start_offset ) &
3470
+ PFINT_SB_CTL_MSIX_INDX_M ) | PFINT_SB_CTL_CAUSE_ENA_M );
3371
3471
wr32 (hw , GLINT_ITR (ICE_RX_ITR , pf -> oicr_irq .index ),
3372
3472
ITR_REG_ALIGN (ICE_ITR_8K ) >> ICE_ITR_GRAN_S );
3373
3473
0 commit comments