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 'bnxt_en-net-next-updates'

Michael Chan says:

====================
bnxt_en: net-next updates.

This series starts off with the usual update of the firmware interface
spec. A new firmware status bit in the interface will be used in patch
add the infrastructure to read the firmware status very early during
driver probe and this will allow patch #4 to do the recovery if needed.

The rest of the patches add improvements to the current RX reset
logic by localizing the reset to the affected RX ring only and to
reset only if firmware has determined that the RX ring is in permanent
error state.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+421 -175
+393 -172
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 254 254 ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE, 255 255 ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY, 256 256 ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY, 257 + ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG, 257 258 }; 258 259 259 260 static struct workqueue_struct *bnxt_pf_wq; ··· 1173 1172 { 1174 1173 if (!rxr->bnapi->in_reset) { 1175 1174 rxr->bnapi->in_reset = true; 1176 - set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event); 1175 + if (bp->flags & BNXT_FLAG_CHIP_P5) 1176 + set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event); 1177 + else 1178 + set_bit(BNXT_RST_RING_SP_EVENT, &bp->sp_event); 1177 1179 bnxt_queue_sp_work(bp); 1178 1180 } 1179 1181 rxr->rx_next_cons = 0xffff; ··· 1742 1738 if (unlikely(cons != rxr->rx_next_cons)) { 1743 1739 int rc1 = bnxt_discard_rx(bp, cpr, raw_cons, rxcmp); 1744 1740 1745 - netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", 1746 - cons, rxr->rx_next_cons); 1741 + /* 0xffff is forced error, don't print it */ 1742 + if (rxr->rx_next_cons != 0xffff) 1743 + netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", 1744 + cons, rxr->rx_next_cons); 1747 1745 bnxt_sched_reset(bp, rxr); 1748 1746 return rc1; 1749 1747 } ··· 1778 1772 rc = -EIO; 1779 1773 if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { 1780 1774 bnapi->cp_ring.sw_stats.rx.rx_buf_errors++; 1781 - if (!(bp->flags & BNXT_FLAG_CHIP_P5)) { 1782 - netdev_warn(bp->dev, "RX buffer error %x\n", 1783 - rx_err); 1775 + if (!(bp->flags & BNXT_FLAG_CHIP_P5) && 1776 + !(bp->fw_cap & BNXT_FW_CAP_RING_MONITOR)) { 1777 + netdev_warn_once(bp->dev, "RX buffer error %x\n", 1778 + rx_err); 1784 1779 bnxt_sched_reset(bp, rxr); 1785 1780 } 1786 1781 } ··· 1948 1941 return val; 1949 1942 } 1950 1943 1944 + static u16 bnxt_agg_ring_id_to_grp_idx(struct bnxt *bp, u16 ring_id) 1945 + { 1946 + int i; 1947 + 1948 + for (i = 0; i < bp->rx_nr_rings; i++) { 1949 + u16 grp_idx = bp->rx_ring[i].bnapi->index; 1950 + struct bnxt_ring_grp_info *grp_info; 1951 + 1952 + grp_info = &bp->grp_info[grp_idx]; 1953 + if (grp_info->agg_fw_ring_id == ring_id) 1954 + return grp_idx; 1955 + } 1956 + return INVALID_HW_RING_ID; 1957 + } 1958 + 1951 1959 #define BNXT_GET_EVENT_PORT(data) \ 1952 1960 ((data) & \ 1953 1961 ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_PORT_ID_MASK) 1962 + 1963 + #define BNXT_EVENT_RING_TYPE(data2) \ 1964 + ((data2) & \ 1965 + ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_MASK) 1966 + 1967 + #define BNXT_EVENT_RING_TYPE_RX(data2) \ 1968 + (BNXT_EVENT_RING_TYPE(data2) == \ 1969 + ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_RX) 1954 1970 1955 1971 static int bnxt_async_event_process(struct bnxt *bp, 1956 1972 struct hwrm_async_event_cmpl *cmpl) ··· 2080 2050 bnxt_fw_health_readl(bp, BNXT_FW_HEARTBEAT_REG); 2081 2051 fw_health->last_fw_reset_cnt = 2082 2052 bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG); 2053 + goto async_event_process_exit; 2054 + } 2055 + case ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG: { 2056 + u32 data1 = le32_to_cpu(cmpl->event_data1); 2057 + u32 data2 = le32_to_cpu(cmpl->event_data2); 2058 + struct bnxt_rx_ring_info *rxr; 2059 + u16 grp_idx; 2060 + 2061 + if (bp->flags & BNXT_FLAG_CHIP_P5) 2062 + goto async_event_process_exit; 2063 + 2064 + netdev_warn(bp->dev, "Ring monitor event, ring type %lu id 0x%x\n", 2065 + BNXT_EVENT_RING_TYPE(data2), data1); 2066 + if (!BNXT_EVENT_RING_TYPE_RX(data2)) 2067 + goto async_event_process_exit; 2068 + 2069 + grp_idx = bnxt_agg_ring_id_to_grp_idx(bp, data1); 2070 + if (grp_idx == INVALID_HW_RING_ID) { 2071 + netdev_warn(bp->dev, "Unknown RX agg ring id 0x%x\n", 2072 + data1); 2073 + goto async_event_process_exit; 2074 + } 2075 + rxr = bp->bnapi[grp_idx]->rx_ring; 2076 + bnxt_sched_reset(bp, rxr); 2083 2077 goto async_event_process_exit; 2084 2078 } 2085 2079 default: ··· 2304 2250 bnapi->tx_pkts = 0; 2305 2251 } 2306 2252 2307 - if (bnapi->events & BNXT_RX_EVENT) { 2253 + if ((bnapi->events & BNXT_RX_EVENT) && !(bnapi->in_reset)) { 2308 2254 struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; 2309 2255 2310 2256 if (bnapi->events & BNXT_AGG_EVENT) ··· 2594 2540 } 2595 2541 } 2596 2542 2543 + static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr) 2544 + { 2545 + struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr]; 2546 + struct pci_dev *pdev = bp->pdev; 2547 + struct bnxt_tpa_idx_map *map; 2548 + int i, max_idx, max_agg_idx; 2549 + 2550 + max_idx = bp->rx_nr_pages * RX_DESC_CNT; 2551 + max_agg_idx = bp->rx_agg_nr_pages * RX_DESC_CNT; 2552 + if (!rxr->rx_tpa) 2553 + goto skip_rx_tpa_free; 2554 + 2555 + for (i = 0; i < bp->max_tpa; i++) { 2556 + struct bnxt_tpa_info *tpa_info = &rxr->rx_tpa[i]; 2557 + u8 *data = tpa_info->data; 2558 + 2559 + if (!data) 2560 + continue; 2561 + 2562 + dma_unmap_single_attrs(&pdev->dev, tpa_info->mapping, 2563 + bp->rx_buf_use_size, bp->rx_dir, 2564 + DMA_ATTR_WEAK_ORDERING); 2565 + 2566 + tpa_info->data = NULL; 2567 + 2568 + kfree(data); 2569 + } 2570 + 2571 + skip_rx_tpa_free: 2572 + for (i = 0; i < max_idx; i++) { 2573 + struct bnxt_sw_rx_bd *rx_buf = &rxr->rx_buf_ring[i]; 2574 + dma_addr_t mapping = rx_buf->mapping; 2575 + void *data = rx_buf->data; 2576 + 2577 + if (!data) 2578 + continue; 2579 + 2580 + rx_buf->data = NULL; 2581 + if (BNXT_RX_PAGE_MODE(bp)) { 2582 + mapping -= bp->rx_dma_offset; 2583 + dma_unmap_page_attrs(&pdev->dev, mapping, PAGE_SIZE, 2584 + bp->rx_dir, 2585 + DMA_ATTR_WEAK_ORDERING); 2586 + page_pool_recycle_direct(rxr->page_pool, data); 2587 + } else { 2588 + dma_unmap_single_attrs(&pdev->dev, mapping, 2589 + bp->rx_buf_use_size, bp->rx_dir, 2590 + DMA_ATTR_WEAK_ORDERING); 2591 + kfree(data); 2592 + } 2593 + } 2594 + for (i = 0; i < max_agg_idx; i++) { 2595 + struct bnxt_sw_rx_agg_bd *rx_agg_buf = &rxr->rx_agg_ring[i]; 2596 + struct page *page = rx_agg_buf->page; 2597 + 2598 + if (!page) 2599 + continue; 2600 + 2601 + dma_unmap_page_attrs(&pdev->dev, rx_agg_buf->mapping, 2602 + BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE, 2603 + DMA_ATTR_WEAK_ORDERING); 2604 + 2605 + rx_agg_buf->page = NULL; 2606 + __clear_bit(i, rxr->rx_agg_bmap); 2607 + 2608 + __free_page(page); 2609 + } 2610 + if (rxr->rx_page) { 2611 + __free_page(rxr->rx_page); 2612 + rxr->rx_page = NULL; 2613 + } 2614 + map = rxr->rx_tpa_idx_map; 2615 + if (map) 2616 + memset(map->agg_idx_bmap, 0, sizeof(map->agg_idx_bmap)); 2617 + } 2618 + 2597 2619 static void bnxt_free_rx_skbs(struct bnxt *bp) 2598 2620 { 2599 - int i, max_idx, max_agg_idx; 2600 - struct pci_dev *pdev = bp->pdev; 2621 + int i; 2601 2622 2602 2623 if (!bp->rx_ring) 2603 2624 return; 2604 2625 2605 - max_idx = bp->rx_nr_pages * RX_DESC_CNT; 2606 - max_agg_idx = bp->rx_agg_nr_pages * RX_DESC_CNT; 2607 - for (i = 0; i < bp->rx_nr_rings; i++) { 2608 - struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; 2609 - struct bnxt_tpa_idx_map *map; 2610 - int j; 2611 - 2612 - if (rxr->rx_tpa) { 2613 - for (j = 0; j < bp->max_tpa; j++) { 2614 - struct bnxt_tpa_info *tpa_info = 2615 - &rxr->rx_tpa[j]; 2616 - u8 *data = tpa_info->data; 2617 - 2618 - if (!data) 2619 - continue; 2620 - 2621 - dma_unmap_single_attrs(&pdev->dev, 2622 - tpa_info->mapping, 2623 - bp->rx_buf_use_size, 2624 - bp->rx_dir, 2625 - DMA_ATTR_WEAK_ORDERING); 2626 - 2627 - tpa_info->data = NULL; 2628 - 2629 - kfree(data); 2630 - } 2631 - } 2632 - 2633 - for (j = 0; j < max_idx; j++) { 2634 - struct bnxt_sw_rx_bd *rx_buf = &rxr->rx_buf_ring[j]; 2635 - dma_addr_t mapping = rx_buf->mapping; 2636 - void *data = rx_buf->data; 2637 - 2638 - if (!data) 2639 - continue; 2640 - 2641 - rx_buf->data = NULL; 2642 - 2643 - if (BNXT_RX_PAGE_MODE(bp)) { 2644 - mapping -= bp->rx_dma_offset; 2645 - dma_unmap_page_attrs(&pdev->dev, mapping, 2646 - PAGE_SIZE, bp->rx_dir, 2647 - DMA_ATTR_WEAK_ORDERING); 2648 - page_pool_recycle_direct(rxr->page_pool, data); 2649 - } else { 2650 - dma_unmap_single_attrs(&pdev->dev, mapping, 2651 - bp->rx_buf_use_size, 2652 - bp->rx_dir, 2653 - DMA_ATTR_WEAK_ORDERING); 2654 - kfree(data); 2655 - } 2656 - } 2657 - 2658 - for (j = 0; j < max_agg_idx; j++) { 2659 - struct bnxt_sw_rx_agg_bd *rx_agg_buf = 2660 - &rxr->rx_agg_ring[j]; 2661 - struct page *page = rx_agg_buf->page; 2662 - 2663 - if (!page) 2664 - continue; 2665 - 2666 - dma_unmap_page_attrs(&pdev->dev, rx_agg_buf->mapping, 2667 - BNXT_RX_PAGE_SIZE, 2668 - PCI_DMA_FROMDEVICE, 2669 - DMA_ATTR_WEAK_ORDERING); 2670 - 2671 - rx_agg_buf->page = NULL; 2672 - __clear_bit(j, rxr->rx_agg_bmap); 2673 - 2674 - __free_page(page); 2675 - } 2676 - if (rxr->rx_page) { 2677 - __free_page(rxr->rx_page); 2678 - rxr->rx_page = NULL; 2679 - } 2680 - map = rxr->rx_tpa_idx_map; 2681 - if (map) 2682 - memset(map->agg_idx_bmap, 0, sizeof(map->agg_idx_bmap)); 2683 - } 2626 + for (i = 0; i < bp->rx_nr_rings; i++) 2627 + bnxt_free_one_rx_ring_skbs(bp, i); 2684 2628 } 2685 2629 2686 2630 static void bnxt_free_skbs(struct bnxt *bp) ··· 3217 3165 } 3218 3166 } 3219 3167 3168 + static int bnxt_alloc_one_rx_ring(struct bnxt *bp, int ring_nr) 3169 + { 3170 + struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr]; 3171 + struct net_device *dev = bp->dev; 3172 + u32 prod; 3173 + int i; 3174 + 3175 + prod = rxr->rx_prod; 3176 + for (i = 0; i < bp->rx_ring_size; i++) { 3177 + if (bnxt_alloc_rx_data(bp, rxr, prod, GFP_KERNEL)) { 3178 + netdev_warn(dev, "init'ed rx ring %d with %d/%d skbs only\n", 3179 + ring_nr, i, bp->rx_ring_size); 3180 + break; 3181 + } 3182 + prod = NEXT_RX(prod); 3183 + } 3184 + rxr->rx_prod = prod; 3185 + 3186 + if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) 3187 + return 0; 3188 + 3189 + prod = rxr->rx_agg_prod; 3190 + for (i = 0; i < bp->rx_agg_ring_size; i++) { 3191 + if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_KERNEL)) { 3192 + netdev_warn(dev, "init'ed rx ring %d with %d/%d pages only\n", 3193 + ring_nr, i, bp->rx_ring_size); 3194 + break; 3195 + } 3196 + prod = NEXT_RX_AGG(prod); 3197 + } 3198 + rxr->rx_agg_prod = prod; 3199 + 3200 + if (rxr->rx_tpa) { 3201 + dma_addr_t mapping; 3202 + u8 *data; 3203 + 3204 + for (i = 0; i < bp->max_tpa; i++) { 3205 + data = __bnxt_alloc_rx_data(bp, &mapping, GFP_KERNEL); 3206 + if (!data) 3207 + return -ENOMEM; 3208 + 3209 + rxr->rx_tpa[i].data = data; 3210 + rxr->rx_tpa[i].data_ptr = data + bp->rx_offset; 3211 + rxr->rx_tpa[i].mapping = mapping; 3212 + } 3213 + } 3214 + return 0; 3215 + } 3216 + 3220 3217 static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr) 3221 3218 { 3222 - struct net_device *dev = bp->dev; 3223 3219 struct bnxt_rx_ring_info *rxr; 3224 3220 struct bnxt_ring_struct *ring; 3225 - u32 prod, type; 3226 - int i; 3221 + u32 type; 3227 3222 3228 3223 type = (bp->rx_buf_use_size << RX_BD_LEN_SHIFT) | 3229 3224 RX_BD_TYPE_RX_PACKET_BD | RX_BD_FLAGS_EOP; ··· 3286 3187 bpf_prog_add(bp->xdp_prog, 1); 3287 3188 rxr->xdp_prog = bp->xdp_prog; 3288 3189 } 3289 - prod = rxr->rx_prod; 3290 - for (i = 0; i < bp->rx_ring_size; i++) { 3291 - if (bnxt_alloc_rx_data(bp, rxr, prod, GFP_KERNEL) != 0) { 3292 - netdev_warn(dev, "init'ed rx ring %d with %d/%d skbs only\n", 3293 - ring_nr, i, bp->rx_ring_size); 3294 - break; 3295 - } 3296 - prod = NEXT_RX(prod); 3297 - } 3298 - rxr->rx_prod = prod; 3299 3190 ring->fw_ring_id = INVALID_HW_RING_ID; 3300 3191 3301 3192 ring = &rxr->rx_agg_ring_struct; 3302 3193 ring->fw_ring_id = INVALID_HW_RING_ID; 3303 3194 3304 - if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) 3305 - return 0; 3195 + if ((bp->flags & BNXT_FLAG_AGG_RINGS)) { 3196 + type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | 3197 + RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; 3306 3198 3307 - type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | 3308 - RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; 3309 - 3310 - bnxt_init_rxbd_pages(ring, type); 3311 - 3312 - prod = rxr->rx_agg_prod; 3313 - for (i = 0; i < bp->rx_agg_ring_size; i++) { 3314 - if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_KERNEL) != 0) { 3315 - netdev_warn(dev, "init'ed rx ring %d with %d/%d pages only\n", 3316 - ring_nr, i, bp->rx_ring_size); 3317 - break; 3318 - } 3319 - prod = NEXT_RX_AGG(prod); 3320 - } 3321 - rxr->rx_agg_prod = prod; 3322 - 3323 - if (bp->flags & BNXT_FLAG_TPA) { 3324 - if (rxr->rx_tpa) { 3325 - u8 *data; 3326 - dma_addr_t mapping; 3327 - 3328 - for (i = 0; i < bp->max_tpa; i++) { 3329 - data = __bnxt_alloc_rx_data(bp, &mapping, 3330 - GFP_KERNEL); 3331 - if (!data) 3332 - return -ENOMEM; 3333 - 3334 - rxr->rx_tpa[i].data = data; 3335 - rxr->rx_tpa[i].data_ptr = data + bp->rx_offset; 3336 - rxr->rx_tpa[i].mapping = mapping; 3337 - } 3338 - } else { 3339 - netdev_err(bp->dev, "No resource allocated for LRO/GRO\n"); 3340 - return -ENOMEM; 3341 - } 3199 + bnxt_init_rxbd_pages(ring, type); 3342 3200 } 3343 3201 3344 - return 0; 3202 + return bnxt_alloc_one_rx_ring(bp, ring_nr); 3345 3203 } 3346 3204 3347 3205 static void bnxt_init_cp_rings(struct bnxt *bp) ··· 6698 6642 } 6699 6643 if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST)) 6700 6644 bp->flags |= BNXT_FLAG_MULTI_HOST; 6645 + if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED) 6646 + bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR; 6701 6647 6702 6648 switch (resp->port_partition_type) { 6703 6649 case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_0: ··· 7394 7336 return rc; 7395 7337 } 7396 7338 7339 + static int __bnxt_alloc_fw_health(struct bnxt *bp) 7340 + { 7341 + if (bp->fw_health) 7342 + return 0; 7343 + 7344 + bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL); 7345 + if (!bp->fw_health) 7346 + return -ENOMEM; 7347 + 7348 + return 0; 7349 + } 7350 + 7351 + static int bnxt_alloc_fw_health(struct bnxt *bp) 7352 + { 7353 + int rc; 7354 + 7355 + if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) && 7356 + !(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) 7357 + return 0; 7358 + 7359 + rc = __bnxt_alloc_fw_health(bp); 7360 + if (rc) { 7361 + bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET; 7362 + bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 7363 + return rc; 7364 + } 7365 + 7366 + return 0; 7367 + } 7368 + 7369 + static void __bnxt_map_fw_health_reg(struct bnxt *bp, u32 reg) 7370 + { 7371 + writel(reg & BNXT_GRC_BASE_MASK, bp->bar0 + 7372 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 7373 + BNXT_FW_HEALTH_WIN_MAP_OFF); 7374 + } 7375 + 7376 + static void bnxt_try_map_fw_health_reg(struct bnxt *bp) 7377 + { 7378 + void __iomem *hs; 7379 + u32 status_loc; 7380 + u32 reg_type; 7381 + u32 sig; 7382 + 7383 + __bnxt_map_fw_health_reg(bp, HCOMM_STATUS_STRUCT_LOC); 7384 + hs = bp->bar0 + BNXT_FW_HEALTH_WIN_OFF(HCOMM_STATUS_STRUCT_LOC); 7385 + 7386 + sig = readl(hs + offsetof(struct hcomm_status, sig_ver)); 7387 + if ((sig & HCOMM_STATUS_SIGNATURE_MASK) != HCOMM_STATUS_SIGNATURE_VAL) { 7388 + if (bp->fw_health) 7389 + bp->fw_health->status_reliable = false; 7390 + return; 7391 + } 7392 + 7393 + if (__bnxt_alloc_fw_health(bp)) { 7394 + netdev_warn(bp->dev, "no memory for firmware status checks\n"); 7395 + return; 7396 + } 7397 + 7398 + status_loc = readl(hs + offsetof(struct hcomm_status, fw_status_loc)); 7399 + bp->fw_health->regs[BNXT_FW_HEALTH_REG] = status_loc; 7400 + reg_type = BNXT_FW_HEALTH_REG_TYPE(status_loc); 7401 + if (reg_type == BNXT_FW_HEALTH_REG_TYPE_GRC) { 7402 + __bnxt_map_fw_health_reg(bp, status_loc); 7403 + bp->fw_health->mapped_regs[BNXT_FW_HEALTH_REG] = 7404 + BNXT_FW_HEALTH_WIN_OFF(status_loc); 7405 + } 7406 + 7407 + bp->fw_health->status_reliable = true; 7408 + } 7409 + 7397 7410 static int bnxt_map_fw_health_regs(struct bnxt *bp) 7398 7411 { 7399 7412 struct bnxt_fw_health *fw_health = bp->fw_health; ··· 7481 7352 reg_base = reg & BNXT_GRC_BASE_MASK; 7482 7353 if ((reg & BNXT_GRC_BASE_MASK) != reg_base) 7483 7354 return -ERANGE; 7484 - fw_health->mapped_regs[i] = BNXT_FW_HEALTH_WIN_BASE + 7485 - (reg & BNXT_GRC_OFFSET_MASK); 7355 + fw_health->mapped_regs[i] = BNXT_FW_HEALTH_WIN_OFF(reg); 7486 7356 } 7487 7357 if (reg_base == 0xffffffff) 7488 7358 return 0; 7489 7359 7490 - writel(reg_base, bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 7491 - BNXT_FW_HEALTH_WIN_MAP_OFF); 7360 + __bnxt_map_fw_health_reg(bp, reg_base); 7492 7361 return 0; 7493 7362 } 7494 7363 ··· 8823 8696 int i; 8824 8697 8825 8698 for (i = 0; i < bp->cp_nr_rings; i++) { 8826 - struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring; 8827 - bp->bnapi[i]->in_reset = false; 8699 + struct bnxt_napi *bnapi = bp->bnapi[i]; 8700 + struct bnxt_cp_ring_info *cpr; 8828 8701 8829 - if (bp->bnapi[i]->rx_ring) { 8702 + cpr = &bnapi->cp_ring; 8703 + if (bnapi->in_reset) 8704 + cpr->sw_stats.rx.rx_resets++; 8705 + bnapi->in_reset = false; 8706 + 8707 + if (bnapi->rx_ring) { 8830 8708 INIT_WORK(&cpr->dim.work, bnxt_dim_work); 8831 8709 cpr->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; 8832 8710 } 8833 - napi_enable(&bp->bnapi[i]->napi); 8711 + napi_enable(&bnapi->napi); 8834 8712 } 8835 8713 } 8836 8714 ··· 10571 10439 } 10572 10440 } 10573 10441 10442 + static int bnxt_hwrm_rx_ring_reset(struct bnxt *bp, int ring_nr) 10443 + { 10444 + struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr]; 10445 + struct hwrm_ring_reset_input req = {0}; 10446 + struct bnxt_napi *bnapi = rxr->bnapi; 10447 + struct bnxt_cp_ring_info *cpr; 10448 + u16 cp_ring_id; 10449 + 10450 + cpr = &bnapi->cp_ring; 10451 + cp_ring_id = cpr->cp_ring_struct.fw_ring_id; 10452 + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_RING_RESET, cp_ring_id, -1); 10453 + req.ring_type = RING_RESET_REQ_RING_TYPE_RX_RING_GRP; 10454 + req.ring_id = cpu_to_le16(bp->grp_info[bnapi->index].fw_grp_id); 10455 + return hwrm_send_message_silent(bp, &req, sizeof(req), 10456 + HWRM_CMD_TIMEOUT); 10457 + } 10458 + 10574 10459 static void bnxt_reset_task(struct bnxt *bp, bool silent) 10575 10460 { 10576 10461 if (!silent) ··· 10720 10571 bnxt_rtnl_lock_sp(bp); 10721 10572 if (test_bit(BNXT_STATE_OPEN, &bp->state)) 10722 10573 bnxt_reset_task(bp, silent); 10574 + bnxt_rtnl_unlock_sp(bp); 10575 + } 10576 + 10577 + /* Only called from bnxt_sp_task() */ 10578 + static void bnxt_rx_ring_reset(struct bnxt *bp) 10579 + { 10580 + int i; 10581 + 10582 + bnxt_rtnl_lock_sp(bp); 10583 + if (!test_bit(BNXT_STATE_OPEN, &bp->state)) { 10584 + bnxt_rtnl_unlock_sp(bp); 10585 + return; 10586 + } 10587 + /* Disable and flush TPA before resetting the RX ring */ 10588 + if (bp->flags & BNXT_FLAG_TPA) 10589 + bnxt_set_tpa(bp, false); 10590 + for (i = 0; i < bp->rx_nr_rings; i++) { 10591 + struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; 10592 + struct bnxt_cp_ring_info *cpr; 10593 + int rc; 10594 + 10595 + if (!rxr->bnapi->in_reset) 10596 + continue; 10597 + 10598 + rc = bnxt_hwrm_rx_ring_reset(bp, i); 10599 + if (rc) { 10600 + if (rc == -EINVAL || rc == -EOPNOTSUPP) 10601 + netdev_info_once(bp->dev, "RX ring reset not supported by firmware, falling back to global reset\n"); 10602 + else 10603 + netdev_warn(bp->dev, "RX ring reset failed, rc = %d, falling back to global reset\n", 10604 + rc); 10605 + bnxt_reset_task(bp, false); 10606 + break; 10607 + } 10608 + bnxt_free_one_rx_ring_skbs(bp, i); 10609 + rxr->rx_prod = 0; 10610 + rxr->rx_agg_prod = 0; 10611 + rxr->rx_sw_agg_prod = 0; 10612 + rxr->rx_next_cons = 0; 10613 + rxr->bnapi->in_reset = false; 10614 + bnxt_alloc_one_rx_ring(bp, i); 10615 + cpr = &rxr->bnapi->cp_ring; 10616 + cpr->sw_stats.rx.rx_resets++; 10617 + if (bp->flags & BNXT_FLAG_AGG_RINGS) 10618 + bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); 10619 + bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); 10620 + } 10621 + if (bp->flags & BNXT_FLAG_TPA) 10622 + bnxt_set_tpa(bp, true); 10723 10623 bnxt_rtnl_unlock_sp(bp); 10724 10624 } 10725 10625 ··· 11060 10862 if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event)) 11061 10863 bnxt_reset(bp, true); 11062 10864 10865 + if (test_and_clear_bit(BNXT_RST_RING_SP_EVENT, &bp->sp_event)) 10866 + bnxt_rx_ring_reset(bp); 10867 + 11063 10868 if (test_and_clear_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event)) 11064 10869 bnxt_devlink_health_report(bp, BNXT_FW_RESET_NOTIFY_SP_EVENT); 11065 10870 ··· 11167 10966 bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS; 11168 10967 } 11169 10968 11170 - static void bnxt_alloc_fw_health(struct bnxt *bp) 10969 + static int bnxt_fw_reset_via_optee(struct bnxt *bp) 11171 10970 { 11172 - if (bp->fw_health) 11173 - return; 10971 + #ifdef CONFIG_TEE_BNXT_FW 10972 + int rc = tee_bnxt_fw_load(); 11174 10973 11175 - if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) && 11176 - !(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) 11177 - return; 10974 + if (rc) 10975 + netdev_err(bp->dev, "Failed FW reset via OP-TEE, rc=%d\n", rc); 11178 10976 11179 - bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL); 11180 - if (!bp->fw_health) { 11181 - netdev_warn(bp->dev, "Failed to allocate fw_health\n"); 11182 - bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET; 11183 - bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 11184 - } 10977 + return rc; 10978 + #else 10979 + netdev_err(bp->dev, "OP-TEE not supported\n"); 10980 + return -ENODEV; 10981 + #endif 11185 10982 } 11186 10983 11187 10984 static int bnxt_fw_init_one_p1(struct bnxt *bp) ··· 11188 10989 11189 10990 bp->fw_cap = 0; 11190 10991 rc = bnxt_hwrm_ver_get(bp); 11191 - if (rc) 11192 - return rc; 10992 + bnxt_try_map_fw_health_reg(bp); 10993 + if (rc) { 10994 + if (bp->fw_health && bp->fw_health->status_reliable) { 10995 + u32 sts = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); 10996 + 10997 + netdev_err(bp->dev, 10998 + "Firmware not responding, status: 0x%x\n", 10999 + sts); 11000 + if (sts & FW_STATUS_REG_CRASHED_NO_MASTER) { 11001 + netdev_warn(bp->dev, "Firmware recover via OP-TEE requested\n"); 11002 + rc = bnxt_fw_reset_via_optee(bp); 11003 + if (!rc) 11004 + rc = bnxt_hwrm_ver_get(bp); 11005 + } 11006 + } 11007 + if (rc) 11008 + return rc; 11009 + } 11193 11010 11194 11011 if (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL) { 11195 11012 rc = bnxt_alloc_kong_hwrm_resources(bp); ··· 11244 11029 netdev_warn(bp->dev, "hwrm query adv flow mgnt failure rc: %d\n", 11245 11030 rc); 11246 11031 11247 - bnxt_alloc_fw_health(bp); 11248 - rc = bnxt_hwrm_error_recovery_qcfg(bp); 11249 - if (rc) 11250 - netdev_warn(bp->dev, "hwrm query error recovery failure rc: %d\n", 11251 - rc); 11032 + if (bnxt_alloc_fw_health(bp)) { 11033 + netdev_warn(bp->dev, "no memory for firmware error recovery\n"); 11034 + } else { 11035 + rc = bnxt_hwrm_error_recovery_qcfg(bp); 11036 + if (rc) 11037 + netdev_warn(bp->dev, "hwrm query error recovery failure rc: %d\n", 11038 + rc); 11039 + } 11252 11040 11253 11041 rc = bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false); 11254 11042 if (rc) ··· 11377 11159 int i, rc; 11378 11160 11379 11161 if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { 11380 - #ifdef CONFIG_TEE_BNXT_FW 11381 - rc = tee_bnxt_fw_load(); 11382 - if (rc) 11383 - netdev_err(bp->dev, "Unable to reset FW rc=%d\n", rc); 11162 + bnxt_fw_reset_via_optee(bp); 11384 11163 bp->fw_reset_timestamp = jiffies; 11385 - #endif 11386 11164 return; 11387 11165 } 11388 11166 ··· 11497 11283 if (time_after(jiffies, bp->fw_reset_timestamp + 11498 11284 (bp->fw_reset_max_dsecs * HZ / 10))) { 11499 11285 netdev_err(bp->dev, "Firmware reset aborted\n"); 11500 - goto fw_reset_abort; 11286 + goto fw_reset_abort_status; 11501 11287 } 11502 11288 bnxt_queue_fw_reset_work(bp, HZ / 5); 11503 11289 return; ··· 11531 11317 } 11532 11318 return; 11533 11319 11320 + fw_reset_abort_status: 11321 + if (bp->fw_health->status_reliable || 11322 + (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) { 11323 + u32 sts = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); 11324 + 11325 + netdev_err(bp->dev, "fw_health_status 0x%x\n", sts); 11326 + } 11534 11327 fw_reset_abort: 11535 11328 clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); 11536 11329 if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF)
+6
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 907 907 908 908 struct bnxt_rx_sw_stats { 909 909 u64 rx_l4_csum_errors; 910 + u64 rx_resets; 910 911 u64 rx_buf_errors; 911 912 }; 912 913 ··· 1495 1494 u8 enabled:1; 1496 1495 u8 master:1; 1497 1496 u8 fatal:1; 1497 + u8 status_reliable:1; 1498 1498 u8 tmr_multiplier; 1499 1499 u8 tmr_counter; 1500 1500 u8 fw_reset_seq_cnt; ··· 1522 1520 1523 1521 #define BNXT_FW_HEALTH_WIN_BASE 0x3000 1524 1522 #define BNXT_FW_HEALTH_WIN_MAP_OFF 8 1523 + 1524 + #define BNXT_FW_HEALTH_WIN_OFF(reg) (BNXT_FW_HEALTH_WIN_BASE + \ 1525 + ((reg) & BNXT_GRC_OFFSET_MASK)) 1525 1526 1526 1527 #define BNXT_FW_STATUS_HEALTHY 0x8000 1527 1528 #define BNXT_FW_STATUS_SHUTDOWN 0x100000 ··· 1822 1817 #define BNXT_FW_CAP_VLAN_TX_INSERT 0x02000000 1823 1818 #define BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED 0x04000000 1824 1819 #define BNXT_FW_CAP_PORT_STATS_NO_RESET 0x10000000 1820 + #define BNXT_FW_CAP_RING_MONITOR 0x40000000 1825 1821 1826 1822 #define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM) 1827 1823 u32 hwrm_spec_code;
+1
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
··· 178 178 179 179 static const char * const bnxt_rx_sw_stats_str[] = { 180 180 "rx_l4_csum_errors", 181 + "rx_resets", 181 182 "rx_buf_errors", 182 183 }; 183 184
+21 -3
drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h
··· 373 373 #define HWRM_TF_SESSION_RESC_FLUSH 0x2cfUL 374 374 #define HWRM_TF_TBL_TYPE_GET 0x2daUL 375 375 #define HWRM_TF_TBL_TYPE_SET 0x2dbUL 376 + #define HWRM_TF_TBL_TYPE_BULK_GET 0x2dcUL 376 377 #define HWRM_TF_CTXT_MEM_ALLOC 0x2e2UL 377 378 #define HWRM_TF_CTXT_MEM_FREE 0x2e3UL 378 379 #define HWRM_TF_CTXT_MEM_RGTR 0x2e4UL ··· 487 486 #define HWRM_VERSION_MAJOR 1 488 487 #define HWRM_VERSION_MINOR 10 489 488 #define HWRM_VERSION_UPDATE 1 490 - #define HWRM_VERSION_RSVD 65 491 - #define HWRM_VERSION_STR "1.10.1.65" 489 + #define HWRM_VERSION_RSVD 68 490 + #define HWRM_VERSION_STR "1.10.1.68" 492 491 493 492 /* hwrm_ver_get_input (size:192b/24B) */ 494 493 struct hwrm_ver_get_input { ··· 8273 8272 __le64 resp_addr; 8274 8273 }; 8275 8274 8276 - /* hwrm_nvm_get_dev_info_output (size:256b/32B) */ 8275 + /* hwrm_nvm_get_dev_info_output (size:640b/80B) */ 8277 8276 struct hwrm_nvm_get_dev_info_output { 8278 8277 __le16 error_code; 8279 8278 __le16 req_type; ··· 8288 8287 u8 nvm_cfg_ver_maj; 8289 8288 u8 nvm_cfg_ver_min; 8290 8289 u8 nvm_cfg_ver_upd; 8290 + u8 flags; 8291 + #define NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID 0x1UL 8292 + char pkg_name[16]; 8293 + __le16 hwrm_fw_major; 8294 + __le16 hwrm_fw_minor; 8295 + __le16 hwrm_fw_build; 8296 + __le16 hwrm_fw_patch; 8297 + __le16 mgmt_fw_major; 8298 + __le16 mgmt_fw_minor; 8299 + __le16 mgmt_fw_build; 8300 + __le16 mgmt_fw_patch; 8301 + __le16 roce_fw_major; 8302 + __le16 roce_fw_minor; 8303 + __le16 roce_fw_build; 8304 + __le16 roce_fw_patch; 8305 + u8 unused_0[7]; 8291 8306 u8 valid; 8292 8307 }; 8293 8308 ··· 8644 8627 #define FW_STATUS_REG_CRASHDUMP_ONGOING 0x40000UL 8645 8628 #define FW_STATUS_REG_CRASHDUMP_COMPLETE 0x80000UL 8646 8629 #define FW_STATUS_REG_SHUTDOWN 0x100000UL 8630 + #define FW_STATUS_REG_CRASHED_NO_MASTER 0x200000UL 8647 8631 }; 8648 8632 8649 8633 /* hcomm_status (size:64b/8B) */