Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'disable-interrupts-and-ensure-dbell-updation'

Vimlesh Kumar says:

====================
disable interrupts and ensure dbell updation

Disable per ring interrupts when netdev goes down and ensure dbell BADDR
updation for both PFs and VFs by adding wait and check for updated value.

Resending based on discussion with reviewer.
====================

Link: https://patch.msgid.link/20260206111510.1045092-1-vimleshk@marvell.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+126 -23
+17 -4
drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
··· 307 307 } 308 308 309 309 /* Setup registers for a hardware Rx Queue */ 310 - static void octep_setup_oq_regs_cn93_pf(struct octep_device *oct, int oq_no) 310 + static int octep_setup_oq_regs_cn93_pf(struct octep_device *oct, int oq_no) 311 311 { 312 312 u64 reg_val; 313 313 u64 oq_ctl = 0ULL; ··· 355 355 reg_val = ((u64)time_threshold << 32) | 356 356 CFG_GET_OQ_INTR_PKT(oct->conf); 357 357 octep_write_csr64(oct, CN93_SDP_R_OUT_INT_LEVELS(oq_no), reg_val); 358 + return 0; 358 359 } 359 360 360 361 /* Setup registers for a PF mailbox */ ··· 697 696 /* Disable all interrupts */ 698 697 static void octep_disable_interrupts_cn93_pf(struct octep_device *oct) 699 698 { 700 - u64 intr_mask = 0ULL; 699 + u64 reg_val, intr_mask = 0ULL; 701 700 int srn, num_rings, i; 702 701 703 702 srn = CFG_GET_PORTS_PF_SRN(oct->conf); 704 703 num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); 705 704 706 - for (i = 0; i < num_rings; i++) 707 - intr_mask |= (0x1ULL << (srn + i)); 705 + for (i = 0; i < num_rings; i++) { 706 + intr_mask |= BIT_ULL(srn + i); 707 + reg_val = octep_read_csr64(oct, 708 + CN93_SDP_R_IN_INT_LEVELS(srn + i)); 709 + reg_val &= ~CN93_INT_ENA_BIT; 710 + octep_write_csr64(oct, 711 + CN93_SDP_R_IN_INT_LEVELS(srn + i), reg_val); 712 + 713 + reg_val = octep_read_csr64(oct, 714 + CN93_SDP_R_OUT_INT_LEVELS(srn + i)); 715 + reg_val &= ~CN93_INT_ENA_BIT; 716 + octep_write_csr64(oct, 717 + CN93_SDP_R_OUT_INT_LEVELS(srn + i), reg_val); 718 + } 708 719 709 720 octep_write_csr64(oct, CN93_SDP_EPF_IRERR_RINT_ENA_W1C, intr_mask); 710 721 octep_write_csr64(oct, CN93_SDP_EPF_ORERR_RINT_ENA_W1C, intr_mask);
+53 -11
drivers/net/ethernet/marvell/octeon_ep/octep_cnxk_pf.c
··· 8 8 #include <linux/pci.h> 9 9 #include <linux/netdevice.h> 10 10 #include <linux/etherdevice.h> 11 + #include <linux/jiffies.h> 11 12 12 13 #include "octep_config.h" 13 14 #include "octep_main.h" ··· 328 327 } 329 328 330 329 /* Setup registers for a hardware Rx Queue */ 331 - static void octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no) 330 + static int octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no) 332 331 { 333 - u64 reg_val; 334 - u64 oq_ctl = 0ULL; 335 - u32 time_threshold = 0; 336 332 struct octep_oq *oq = oct->oq[oq_no]; 333 + unsigned long t_out_jiffies; 334 + u32 time_threshold = 0; 335 + u64 oq_ctl = 0ULL; 336 + u64 reg_ba_val; 337 + u64 reg_val; 337 338 338 339 oq_no += CFG_GET_PORTS_PF_SRN(oct->conf); 339 340 reg_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no)); ··· 345 342 do { 346 343 reg_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no)); 347 344 } while (!(reg_val & CNXK_R_OUT_CTL_IDLE)); 345 + } 346 + octep_write_csr64(oct, CNXK_SDP_R_OUT_WMARK(oq_no), oq->max_count); 347 + /* Wait for WMARK to get applied */ 348 + usleep_range(10, 15); 349 + 350 + octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no), 351 + oq->desc_ring_dma); 352 + octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no), 353 + oq->max_count); 354 + reg_ba_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no)); 355 + 356 + if (reg_ba_val != oq->desc_ring_dma) { 357 + t_out_jiffies = jiffies + 10 * HZ; 358 + do { 359 + if (reg_ba_val == ULLONG_MAX) 360 + return -EFAULT; 361 + octep_write_csr64(oct, 362 + CNXK_SDP_R_OUT_SLIST_BADDR(oq_no), 363 + oq->desc_ring_dma); 364 + octep_write_csr64(oct, 365 + CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no), 366 + oq->max_count); 367 + reg_ba_val = 368 + octep_read_csr64(oct, 369 + CNXK_SDP_R_OUT_SLIST_BADDR(oq_no)); 370 + } while ((reg_ba_val != oq->desc_ring_dma) && 371 + time_before(jiffies, t_out_jiffies)); 372 + 373 + if (reg_ba_val != oq->desc_ring_dma) 374 + return -EAGAIN; 348 375 } 349 376 350 377 reg_val &= ~(CNXK_R_OUT_CTL_IMODE); ··· 389 356 reg_val |= (CNXK_R_OUT_CTL_ES_P); 390 357 391 358 octep_write_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no), reg_val); 392 - octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no), 393 - oq->desc_ring_dma); 394 - octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no), 395 - oq->max_count); 396 359 397 360 oq_ctl = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no)); 398 361 ··· 414 385 reg_val &= ~0xFFFFFFFFULL; 415 386 reg_val |= CFG_GET_OQ_WMARK(oct->conf); 416 387 octep_write_csr64(oct, CNXK_SDP_R_OUT_WMARK(oq_no), reg_val); 388 + return 0; 417 389 } 418 390 419 391 /* Setup registers for a PF mailbox */ ··· 750 720 /* Disable all interrupts */ 751 721 static void octep_disable_interrupts_cnxk_pf(struct octep_device *oct) 752 722 { 753 - u64 intr_mask = 0ULL; 723 + u64 reg_val, intr_mask = 0ULL; 754 724 int srn, num_rings, i; 755 725 756 726 srn = CFG_GET_PORTS_PF_SRN(oct->conf); 757 727 num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); 758 728 759 - for (i = 0; i < num_rings; i++) 760 - intr_mask |= (0x1ULL << (srn + i)); 729 + for (i = 0; i < num_rings; i++) { 730 + intr_mask |= BIT_ULL(srn + i); 731 + reg_val = octep_read_csr64(oct, 732 + CNXK_SDP_R_IN_INT_LEVELS(srn + i)); 733 + reg_val &= ~CNXK_INT_ENA_BIT; 734 + octep_write_csr64(oct, 735 + CNXK_SDP_R_IN_INT_LEVELS(srn + i), reg_val); 736 + 737 + reg_val = octep_read_csr64(oct, 738 + CNXK_SDP_R_OUT_INT_LEVELS(srn + i)); 739 + reg_val &= ~CNXK_INT_ENA_BIT; 740 + octep_write_csr64(oct, 741 + CNXK_SDP_R_OUT_INT_LEVELS(srn + i), reg_val); 742 + } 761 743 762 744 octep_write_csr64(oct, CNXK_SDP_EPF_IRERR_RINT_ENA_W1C, intr_mask); 763 745 octep_write_csr64(oct, CNXK_SDP_EPF_ORERR_RINT_ENA_W1C, intr_mask);
+1 -1
drivers/net/ethernet/marvell/octeon_ep/octep_main.h
··· 77 77 78 78 struct octep_hw_ops { 79 79 void (*setup_iq_regs)(struct octep_device *oct, int q); 80 - void (*setup_oq_regs)(struct octep_device *oct, int q); 80 + int (*setup_oq_regs)(struct octep_device *oct, int q); 81 81 void (*setup_mbox_regs)(struct octep_device *oct, int mbox); 82 82 83 83 irqreturn_t (*mbox_intr_handler)(void *ioq_vector);
+1
drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
··· 386 386 #define CN93_PEM_BAR4_INDEX 7 387 387 #define CN93_PEM_BAR4_INDEX_SIZE 0x400000ULL 388 388 #define CN93_PEM_BAR4_INDEX_OFFSET (CN93_PEM_BAR4_INDEX * CN93_PEM_BAR4_INDEX_SIZE) 389 + #define CN93_INT_ENA_BIT BIT_ULL(62) 389 390 390 391 #endif /* _OCTEP_REGS_CN9K_PF_H_ */
+1
drivers/net/ethernet/marvell/octeon_ep/octep_regs_cnxk_pf.h
··· 412 412 #define CNXK_PEM_BAR4_INDEX 7 413 413 #define CNXK_PEM_BAR4_INDEX_SIZE 0x400000ULL 414 414 #define CNXK_PEM_BAR4_INDEX_OFFSET (CNXK_PEM_BAR4_INDEX * CNXK_PEM_BAR4_INDEX_SIZE) 415 + #define CNXK_INT_ENA_BIT BIT_ULL(62) 415 416 416 417 #endif /* _OCTEP_REGS_CNXK_PF_H_ */
+7 -1
drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
··· 12 12 #include "octep_config.h" 13 13 #include "octep_main.h" 14 14 15 + static void octep_oq_free_ring_buffers(struct octep_oq *oq); 16 + 15 17 static void octep_oq_reset_indices(struct octep_oq *oq) 16 18 { 17 19 oq->host_read_idx = 0; ··· 172 170 goto oq_fill_buff_err; 173 171 174 172 octep_oq_reset_indices(oq); 175 - oct->hw_ops.setup_oq_regs(oct, q_no); 173 + if (oct->hw_ops.setup_oq_regs(oct, q_no)) 174 + goto oq_setup_err; 175 + 176 176 oct->num_oqs++; 177 177 178 178 return 0; 179 179 180 + oq_setup_err: 181 + octep_oq_free_ring_buffers(oq); 180 182 oq_fill_buff_err: 181 183 vfree(oq->buff_info); 182 184 oq->buff_info = NULL;
+2 -1
drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_cn9k.c
··· 196 196 } 197 197 198 198 /* Setup registers for a hardware Rx Queue */ 199 - static void octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no) 199 + static int octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no) 200 200 { 201 201 struct octep_vf_oq *oq = oct->oq[oq_no]; 202 202 u32 time_threshold = 0; ··· 239 239 time_threshold = CFG_GET_OQ_INTR_TIME(oct->conf); 240 240 reg_val = ((u64)time_threshold << 32) | CFG_GET_OQ_INTR_PKT(oct->conf); 241 241 octep_vf_write_csr64(oct, CN93_VF_SDP_R_OUT_INT_LEVELS(oq_no), reg_val); 242 + return 0; 242 243 } 243 244 244 245 /* Setup registers for a VF mailbox */
+36 -3
drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_cnxk.c
··· 199 199 } 200 200 201 201 /* Setup registers for a hardware Rx Queue */ 202 - static void octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no) 202 + static int octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no) 203 203 { 204 204 struct octep_vf_oq *oq = oct->oq[oq_no]; 205 + unsigned long t_out_jiffies; 205 206 u32 time_threshold = 0; 206 207 u64 oq_ctl = ULL(0); 208 + u64 reg_ba_val; 207 209 u64 reg_val; 208 210 209 211 reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no)); ··· 215 213 do { 216 214 reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no)); 217 215 } while (!(reg_val & CNXK_VF_R_OUT_CTL_IDLE)); 216 + } 217 + octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no), 218 + oq->max_count); 219 + /* Wait for WMARK to get applied */ 220 + usleep_range(10, 15); 221 + 222 + octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no), 223 + oq->desc_ring_dma); 224 + octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no), 225 + oq->max_count); 226 + reg_ba_val = octep_vf_read_csr64(oct, 227 + CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no)); 228 + if (reg_ba_val != oq->desc_ring_dma) { 229 + t_out_jiffies = jiffies + 10 * HZ; 230 + do { 231 + if (reg_ba_val == ULLONG_MAX) 232 + return -EFAULT; 233 + octep_vf_write_csr64(oct, 234 + CNXK_VF_SDP_R_OUT_SLIST_BADDR 235 + (oq_no), oq->desc_ring_dma); 236 + octep_vf_write_csr64(oct, 237 + CNXK_VF_SDP_R_OUT_SLIST_RSIZE 238 + (oq_no), oq->max_count); 239 + reg_ba_val = 240 + octep_vf_read_csr64(oct, 241 + CNXK_VF_SDP_R_OUT_SLIST_BADDR 242 + (oq_no)); 243 + } while ((reg_ba_val != oq->desc_ring_dma) && 244 + time_before(jiffies, t_out_jiffies)); 245 + 246 + if (reg_ba_val != oq->desc_ring_dma) 247 + return -EAGAIN; 218 248 } 219 249 220 250 reg_val &= ~(CNXK_VF_R_OUT_CTL_IMODE); ··· 261 227 reg_val |= (CNXK_VF_R_OUT_CTL_ES_P); 262 228 263 229 octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no), reg_val); 264 - octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no), oq->desc_ring_dma); 265 - octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no), oq->max_count); 266 230 267 231 oq_ctl = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no)); 268 232 /* Clear the ISIZE and BSIZE (22-0) */ ··· 282 250 reg_val &= ~GENMASK_ULL(31, 0); 283 251 reg_val |= CFG_GET_OQ_WMARK(oct->conf); 284 252 octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no), reg_val); 253 + return 0; 285 254 } 286 255 287 256 /* Setup registers for a VF mailbox */
+1 -1
drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h
··· 55 55 56 56 struct octep_vf_hw_ops { 57 57 void (*setup_iq_regs)(struct octep_vf_device *oct, int q); 58 - void (*setup_oq_regs)(struct octep_vf_device *oct, int q); 58 + int (*setup_oq_regs)(struct octep_vf_device *oct, int q); 59 59 void (*setup_mbox_regs)(struct octep_vf_device *oct, int mbox); 60 60 61 61 irqreturn_t (*non_ioq_intr_handler)(void *ioq_vector);
+7 -1
drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c
··· 12 12 #include "octep_vf_config.h" 13 13 #include "octep_vf_main.h" 14 14 15 + static void octep_vf_oq_free_ring_buffers(struct octep_vf_oq *oq); 16 + 15 17 static void octep_vf_oq_reset_indices(struct octep_vf_oq *oq) 16 18 { 17 19 oq->host_read_idx = 0; ··· 173 171 goto oq_fill_buff_err; 174 172 175 173 octep_vf_oq_reset_indices(oq); 176 - oct->hw_ops.setup_oq_regs(oct, q_no); 174 + if (oct->hw_ops.setup_oq_regs(oct, q_no)) 175 + goto oq_setup_err; 176 + 177 177 oct->num_oqs++; 178 178 179 179 return 0; 180 180 181 + oq_setup_err: 182 + octep_vf_oq_free_ring_buffers(oq); 181 183 oq_fill_buff_err: 182 184 vfree(oq->buff_info); 183 185 oq->buff_info = NULL;