| .. | .. |
|---|
| 45 | 45 | |
|---|
| 46 | 46 | max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); |
|---|
| 47 | 47 | if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || |
|---|
| 48 | | - bp->num_stat_ctxs == max_stat_ctxs) |
|---|
| 48 | + bp->cp_nr_rings == max_stat_ctxs) |
|---|
| 49 | 49 | return -ENOMEM; |
|---|
| 50 | | - bnxt_set_max_func_stat_ctxs(bp, max_stat_ctxs - |
|---|
| 51 | | - BNXT_MIN_ROCE_STAT_CTXS); |
|---|
| 52 | 50 | } |
|---|
| 53 | 51 | |
|---|
| 54 | 52 | atomic_set(&ulp->ref_count, 0); |
|---|
| .. | .. |
|---|
| 79 | 77 | netdev_err(bp->dev, "ulp id %d not registered\n", ulp_id); |
|---|
| 80 | 78 | return -EINVAL; |
|---|
| 81 | 79 | } |
|---|
| 82 | | - if (ulp_id == BNXT_ROCE_ULP) { |
|---|
| 83 | | - unsigned int max_stat_ctxs; |
|---|
| 80 | + if (ulp_id == BNXT_ROCE_ULP && ulp->msix_requested) |
|---|
| 81 | + edev->en_ops->bnxt_free_msix(edev, ulp_id); |
|---|
| 84 | 82 | |
|---|
| 85 | | - max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); |
|---|
| 86 | | - bnxt_set_max_func_stat_ctxs(bp, max_stat_ctxs + 1); |
|---|
| 87 | | - if (ulp->msix_requested) |
|---|
| 88 | | - edev->en_ops->bnxt_free_msix(edev, ulp_id); |
|---|
| 89 | | - } |
|---|
| 90 | 83 | if (ulp->max_async_event_id) |
|---|
| 91 | | - bnxt_hwrm_func_rgtr_async_events(bp, NULL, 0); |
|---|
| 84 | + bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, true); |
|---|
| 92 | 85 | |
|---|
| 93 | 86 | RCU_INIT_POINTER(ulp->ulp_ops, NULL); |
|---|
| 94 | 87 | synchronize_rcu(); |
|---|
| .. | .. |
|---|
| 111 | 104 | for (i = 0; i < num_msix; i++) { |
|---|
| 112 | 105 | ent[i].vector = bp->irq_tbl[idx + i].vector; |
|---|
| 113 | 106 | ent[i].ring_idx = idx + i; |
|---|
| 114 | | - ent[i].db_offset = (idx + i) * 0x80; |
|---|
| 107 | + if (bp->flags & BNXT_FLAG_CHIP_P5) { |
|---|
| 108 | + ent[i].db_offset = DB_PF_OFFSET_P5; |
|---|
| 109 | + if (BNXT_VF(bp)) |
|---|
| 110 | + ent[i].db_offset = DB_VF_OFFSET_P5; |
|---|
| 111 | + } else { |
|---|
| 112 | + ent[i].db_offset = (idx + i) * 0x80; |
|---|
| 113 | + } |
|---|
| 115 | 114 | } |
|---|
| 116 | 115 | } |
|---|
| 117 | 116 | |
|---|
| .. | .. |
|---|
| 120 | 119 | { |
|---|
| 121 | 120 | struct net_device *dev = edev->net; |
|---|
| 122 | 121 | struct bnxt *bp = netdev_priv(dev); |
|---|
| 122 | + struct bnxt_hw_resc *hw_resc; |
|---|
| 123 | 123 | int max_idx, max_cp_rings; |
|---|
| 124 | 124 | int avail_msix, idx; |
|---|
| 125 | + int total_vecs; |
|---|
| 125 | 126 | int rc = 0; |
|---|
| 126 | 127 | |
|---|
| 127 | 128 | ASSERT_RTNL(); |
|---|
| .. | .. |
|---|
| 149 | 150 | } |
|---|
| 150 | 151 | edev->ulp_tbl[ulp_id].msix_base = idx; |
|---|
| 151 | 152 | edev->ulp_tbl[ulp_id].msix_requested = avail_msix; |
|---|
| 152 | | - if (bp->total_irqs < (idx + avail_msix)) { |
|---|
| 153 | + hw_resc = &bp->hw_resc; |
|---|
| 154 | + total_vecs = idx + avail_msix; |
|---|
| 155 | + if (bp->total_irqs < total_vecs || |
|---|
| 156 | + (BNXT_NEW_RM(bp) && hw_resc->resv_irqs < total_vecs)) { |
|---|
| 153 | 157 | if (netif_running(dev)) { |
|---|
| 154 | 158 | bnxt_close_nic(bp, true, false); |
|---|
| 155 | 159 | rc = bnxt_open_nic(bp, true, false); |
|---|
| 156 | 160 | } else { |
|---|
| 157 | | - rc = bnxt_reserve_rings(bp); |
|---|
| 161 | + rc = bnxt_reserve_rings(bp, true); |
|---|
| 158 | 162 | } |
|---|
| 159 | 163 | } |
|---|
| 160 | 164 | if (rc) { |
|---|
| .. | .. |
|---|
| 163 | 167 | } |
|---|
| 164 | 168 | |
|---|
| 165 | 169 | if (BNXT_NEW_RM(bp)) { |
|---|
| 166 | | - struct bnxt_hw_resc *hw_resc = &bp->hw_resc; |
|---|
| 170 | + int resv_msix; |
|---|
| 167 | 171 | |
|---|
| 168 | | - avail_msix = hw_resc->resv_cp_rings - bp->cp_nr_rings; |
|---|
| 172 | + resv_msix = hw_resc->resv_irqs - bp->cp_nr_rings; |
|---|
| 173 | + avail_msix = min_t(int, resv_msix, avail_msix); |
|---|
| 169 | 174 | edev->ulp_tbl[ulp_id].msix_requested = avail_msix; |
|---|
| 170 | 175 | } |
|---|
| 171 | 176 | bnxt_fill_msix_vecs(bp, ent); |
|---|
| .. | .. |
|---|
| 187 | 192 | |
|---|
| 188 | 193 | edev->ulp_tbl[ulp_id].msix_requested = 0; |
|---|
| 189 | 194 | edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED; |
|---|
| 190 | | - if (netif_running(dev)) { |
|---|
| 195 | + if (netif_running(dev) && !(edev->flags & BNXT_EN_FLAG_ULP_STOPPED)) { |
|---|
| 191 | 196 | bnxt_close_nic(bp, true, false); |
|---|
| 192 | 197 | bnxt_open_nic(bp, true, false); |
|---|
| 193 | 198 | } |
|---|
| .. | .. |
|---|
| 215 | 220 | return 0; |
|---|
| 216 | 221 | } |
|---|
| 217 | 222 | |
|---|
| 223 | +int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) |
|---|
| 224 | +{ |
|---|
| 225 | + if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { |
|---|
| 226 | + struct bnxt_en_dev *edev = bp->edev; |
|---|
| 227 | + |
|---|
| 228 | + if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) |
|---|
| 229 | + return BNXT_MIN_ROCE_STAT_CTXS; |
|---|
| 230 | + } |
|---|
| 231 | + |
|---|
| 232 | + return 0; |
|---|
| 233 | +} |
|---|
| 234 | + |
|---|
| 218 | 235 | static int bnxt_send_msg(struct bnxt_en_dev *edev, int ulp_id, |
|---|
| 219 | 236 | struct bnxt_fw_msg *fw_msg) |
|---|
| 220 | 237 | { |
|---|
| .. | .. |
|---|
| 222 | 239 | struct bnxt *bp = netdev_priv(dev); |
|---|
| 223 | 240 | struct input *req; |
|---|
| 224 | 241 | int rc; |
|---|
| 242 | + |
|---|
| 243 | + if (ulp_id != BNXT_ROCE_ULP && bp->fw_reset_state) |
|---|
| 244 | + return -EBUSY; |
|---|
| 225 | 245 | |
|---|
| 226 | 246 | mutex_lock(&bp->hwrm_cmd_lock); |
|---|
| 227 | 247 | req = fw_msg->msg; |
|---|
| .. | .. |
|---|
| 260 | 280 | if (!edev) |
|---|
| 261 | 281 | return; |
|---|
| 262 | 282 | |
|---|
| 283 | + edev->flags |= BNXT_EN_FLAG_ULP_STOPPED; |
|---|
| 263 | 284 | for (i = 0; i < BNXT_MAX_ULP; i++) { |
|---|
| 264 | 285 | struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; |
|---|
| 265 | 286 | |
|---|
| .. | .. |
|---|
| 270 | 291 | } |
|---|
| 271 | 292 | } |
|---|
| 272 | 293 | |
|---|
| 273 | | -void bnxt_ulp_start(struct bnxt *bp) |
|---|
| 294 | +void bnxt_ulp_start(struct bnxt *bp, int err) |
|---|
| 274 | 295 | { |
|---|
| 275 | 296 | struct bnxt_en_dev *edev = bp->edev; |
|---|
| 276 | 297 | struct bnxt_ulp_ops *ops; |
|---|
| 277 | 298 | int i; |
|---|
| 278 | 299 | |
|---|
| 279 | 300 | if (!edev) |
|---|
| 301 | + return; |
|---|
| 302 | + |
|---|
| 303 | + edev->flags &= ~BNXT_EN_FLAG_ULP_STOPPED; |
|---|
| 304 | + |
|---|
| 305 | + if (err) |
|---|
| 280 | 306 | return; |
|---|
| 281 | 307 | |
|---|
| 282 | 308 | for (i = 0; i < BNXT_MAX_ULP; i++) { |
|---|
| .. | .. |
|---|
| 429 | 455 | /* Make sure bnxt_ulp_async_events() sees this order */ |
|---|
| 430 | 456 | smp_wmb(); |
|---|
| 431 | 457 | ulp->max_async_event_id = max_id; |
|---|
| 432 | | - bnxt_hwrm_func_rgtr_async_events(bp, events_bmap, max_id + 1); |
|---|
| 458 | + bnxt_hwrm_func_drv_rgtr(bp, events_bmap, max_id + 1, true); |
|---|
| 433 | 459 | return 0; |
|---|
| 434 | 460 | } |
|---|
| 435 | 461 | |
|---|
| .. | .. |
|---|
| 453 | 479 | if (!edev) |
|---|
| 454 | 480 | return ERR_PTR(-ENOMEM); |
|---|
| 455 | 481 | edev->en_ops = &bnxt_en_ops_tbl; |
|---|
| 456 | | - if (bp->flags & BNXT_FLAG_ROCEV1_CAP) |
|---|
| 457 | | - edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; |
|---|
| 458 | | - if (bp->flags & BNXT_FLAG_ROCEV2_CAP) |
|---|
| 459 | | - edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; |
|---|
| 460 | 482 | edev->net = dev; |
|---|
| 461 | 483 | edev->pdev = bp->pdev; |
|---|
| 484 | + edev->l2_db_size = bp->db_size; |
|---|
| 485 | + edev->l2_db_size_nc = bp->db_size; |
|---|
| 462 | 486 | bp->edev = edev; |
|---|
| 463 | 487 | } |
|---|
| 488 | + edev->flags &= ~BNXT_EN_FLAG_ROCE_CAP; |
|---|
| 489 | + if (bp->flags & BNXT_FLAG_ROCEV1_CAP) |
|---|
| 490 | + edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; |
|---|
| 491 | + if (bp->flags & BNXT_FLAG_ROCEV2_CAP) |
|---|
| 492 | + edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; |
|---|
| 464 | 493 | return bp->edev; |
|---|
| 465 | 494 | } |
|---|