0001
0002
0003
0004 #include "fm10k_pf.h"
0005 #include "fm10k_vf.h"
0006
0007
0008
0009
0010
0011
0012
0013
0014 static s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
0015 {
0016 s32 err;
0017 u32 reg;
0018 u16 i;
0019
0020
0021 fm10k_write_reg(hw, FM10K_EIMR, FM10K_EIMR_DISABLE(ALL));
0022
0023
0024 fm10k_write_reg(hw, FM10K_ITR2(0), 0);
0025 fm10k_write_reg(hw, FM10K_INT_CTRL, 0);
0026
0027
0028
0029
0030 for (i = 0; i < FM10K_TQMAP_TABLE_SIZE; i++) {
0031 fm10k_write_reg(hw, FM10K_TQMAP(i), 0);
0032 fm10k_write_reg(hw, FM10K_RQMAP(i), 0);
0033 }
0034
0035
0036 err = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES);
0037 if (err == FM10K_ERR_REQUESTS_PENDING) {
0038 hw->mac.reset_while_pending++;
0039 goto force_reset;
0040 } else if (err) {
0041 return err;
0042 }
0043
0044
0045 reg = fm10k_read_reg(hw, FM10K_DMA_CTRL);
0046 if (reg & (FM10K_DMA_CTRL_TX_ACTIVE | FM10K_DMA_CTRL_RX_ACTIVE))
0047 return FM10K_ERR_DMA_PENDING;
0048
0049 force_reset:
0050
0051 reg = FM10K_DMA_CTRL_DATAPATH_RESET;
0052 fm10k_write_reg(hw, FM10K_DMA_CTRL, reg);
0053
0054
0055 fm10k_write_flush(hw);
0056 udelay(FM10K_RESET_TIMEOUT);
0057
0058
0059 reg = fm10k_read_reg(hw, FM10K_IP);
0060 if (!(reg & FM10K_IP_NOTINRESET))
0061 return FM10K_ERR_RESET_FAILED;
0062
0063 return 0;
0064 }
0065
0066
0067
0068
0069
0070
0071
0072 static bool fm10k_is_ari_hierarchy_pf(struct fm10k_hw *hw)
0073 {
0074 u16 sriov_ctrl = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_SRIOV_CTRL);
0075
0076 return !!(sriov_ctrl & FM10K_PCIE_SRIOV_CTRL_VFARI);
0077 }
0078
0079
0080
0081
0082
0083
0084 static s32 fm10k_init_hw_pf(struct fm10k_hw *hw)
0085 {
0086 u32 dma_ctrl, txqctl;
0087 u16 i;
0088
0089
0090 fm10k_write_reg(hw, FM10K_DGLORTDEC(fm10k_dglort_default), 0);
0091 fm10k_write_reg(hw, FM10K_DGLORTMAP(fm10k_dglort_default),
0092 FM10K_DGLORTMAP_ANY);
0093
0094
0095 for (i = 1; i < FM10K_DGLORT_COUNT; i++)
0096 fm10k_write_reg(hw, FM10K_DGLORTMAP(i), FM10K_DGLORTMAP_NONE);
0097
0098
0099 fm10k_write_reg(hw, FM10K_ITR2(0), 0);
0100
0101
0102 fm10k_write_reg(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), 0);
0103
0104
0105 for (i = 1; i < FM10K_ITR_REG_COUNT_PF; i++)
0106 fm10k_write_reg(hw, FM10K_ITR2(i), i - 1);
0107
0108
0109 fm10k_write_reg(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
0110
0111
0112 txqctl = FM10K_TXQCTL_PF | FM10K_TXQCTL_UNLIMITED_BW |
0113 (hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT);
0114
0115 for (i = 0; i < FM10K_MAX_QUEUES; i++) {
0116
0117 fm10k_write_reg(hw, FM10K_TQDLOC(i),
0118 (i * FM10K_TQDLOC_BASE_32_DESC) |
0119 FM10K_TQDLOC_SIZE_32_DESC);
0120 fm10k_write_reg(hw, FM10K_TXQCTL(i), txqctl);
0121
0122
0123 fm10k_write_reg(hw, FM10K_TPH_TXCTRL(i),
0124 FM10K_TPH_TXCTRL_DESC_TPHEN |
0125 FM10K_TPH_TXCTRL_DESC_RROEN |
0126 FM10K_TPH_TXCTRL_DESC_WROEN |
0127 FM10K_TPH_TXCTRL_DATA_RROEN);
0128 fm10k_write_reg(hw, FM10K_TPH_RXCTRL(i),
0129 FM10K_TPH_RXCTRL_DESC_TPHEN |
0130 FM10K_TPH_RXCTRL_DESC_RROEN |
0131 FM10K_TPH_RXCTRL_DATA_WROEN |
0132 FM10K_TPH_RXCTRL_HDR_WROEN);
0133 }
0134
0135
0136
0137
0138 switch (hw->bus.speed) {
0139 case fm10k_bus_speed_2500:
0140 dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1;
0141 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN1;
0142 break;
0143 case fm10k_bus_speed_5000:
0144 dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2;
0145 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN2;
0146 break;
0147 case fm10k_bus_speed_8000:
0148 dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3;
0149 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
0150 break;
0151 default:
0152 dma_ctrl = 0;
0153
0154 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
0155 break;
0156 }
0157
0158
0159 fm10k_write_reg(hw, FM10K_DTXTCPFLGL, FM10K_TSO_FLAGS_LOW);
0160 fm10k_write_reg(hw, FM10K_DTXTCPFLGH, FM10K_TSO_FLAGS_HI);
0161
0162
0163
0164
0165
0166
0167 dma_ctrl |= FM10K_DMA_CTRL_TX_ENABLE | FM10K_DMA_CTRL_RX_ENABLE |
0168 FM10K_DMA_CTRL_RX_DESC_SIZE | FM10K_DMA_CTRL_MINMSS_64 |
0169 FM10K_DMA_CTRL_32_DESC;
0170
0171 fm10k_write_reg(hw, FM10K_DMA_CTRL, dma_ctrl);
0172
0173
0174 hw->mac.max_queues = FM10K_MAX_QUEUES_PF;
0175
0176
0177 hw->iov.total_vfs = fm10k_is_ari_hierarchy_pf(hw) ? 64 : 7;
0178
0179 return 0;
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194 static s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
0195 {
0196 u32 vlan_table, reg, mask, bit, len;
0197
0198
0199 if (vsi > FM10K_VLAN_TABLE_VSI_MAX)
0200 return FM10K_ERR_PARAM;
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 len = vid >> 16;
0216 vid = (vid << 17) >> 17;
0217
0218
0219 if (len >= FM10K_VLAN_TABLE_VID_MAX || vid >= FM10K_VLAN_TABLE_VID_MAX)
0220 return FM10K_ERR_PARAM;
0221
0222
0223 for (reg = FM10K_VLAN_TABLE(vsi, vid / 32), bit = vid % 32;
0224 len < FM10K_VLAN_TABLE_VID_MAX;
0225 len -= 32 - bit, reg++, bit = 0) {
0226
0227 vlan_table = fm10k_read_reg(hw, reg);
0228
0229
0230 mask = (~(u32)0 >> ((len < 31) ? 31 - len : 0)) << bit;
0231
0232
0233 mask &= set ? ~vlan_table : vlan_table;
0234 if (mask)
0235 fm10k_write_reg(hw, reg, vlan_table ^ mask);
0236 }
0237
0238 return 0;
0239 }
0240
0241
0242
0243
0244
0245
0246
0247 static s32 fm10k_read_mac_addr_pf(struct fm10k_hw *hw)
0248 {
0249 u8 perm_addr[ETH_ALEN];
0250 u32 serial_num;
0251
0252 serial_num = fm10k_read_reg(hw, FM10K_SM_AREA(1));
0253
0254
0255 if ((~serial_num) << 24)
0256 return FM10K_ERR_INVALID_MAC_ADDR;
0257
0258 perm_addr[0] = (u8)(serial_num >> 24);
0259 perm_addr[1] = (u8)(serial_num >> 16);
0260 perm_addr[2] = (u8)(serial_num >> 8);
0261
0262 serial_num = fm10k_read_reg(hw, FM10K_SM_AREA(0));
0263
0264
0265 if ((~serial_num) >> 24)
0266 return FM10K_ERR_INVALID_MAC_ADDR;
0267
0268 perm_addr[3] = (u8)(serial_num >> 16);
0269 perm_addr[4] = (u8)(serial_num >> 8);
0270 perm_addr[5] = (u8)(serial_num);
0271
0272 ether_addr_copy(hw->mac.perm_addr, perm_addr);
0273 ether_addr_copy(hw->mac.addr, perm_addr);
0274
0275 return 0;
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285 bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort)
0286 {
0287 glort &= hw->mac.dglort_map >> FM10K_DGLORTMAP_MASK_SHIFT;
0288
0289 return glort == (hw->mac.dglort_map & FM10K_DGLORTMAP_NONE);
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 static s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort,
0305 const u8 *mac, u16 vid, bool add, u8 flags)
0306 {
0307 struct fm10k_mbx_info *mbx = &hw->mbx;
0308 struct fm10k_mac_update mac_update;
0309 u32 msg[5];
0310
0311
0312 vid &= ~FM10K_VLAN_CLEAR;
0313
0314
0315 if (!fm10k_glort_valid_pf(hw, glort) || vid >= FM10K_VLAN_TABLE_VID_MAX)
0316 return FM10K_ERR_PARAM;
0317
0318
0319 mac_update.mac_lower = cpu_to_le32(((u32)mac[2] << 24) |
0320 ((u32)mac[3] << 16) |
0321 ((u32)mac[4] << 8) |
0322 ((u32)mac[5]));
0323 mac_update.mac_upper = cpu_to_le16(((u16)mac[0] << 8) |
0324 ((u16)mac[1]));
0325 mac_update.vlan = cpu_to_le16(vid);
0326 mac_update.glort = cpu_to_le16(glort);
0327 mac_update.action = add ? 0 : 1;
0328 mac_update.flags = flags;
0329
0330
0331 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE);
0332 fm10k_tlv_attr_put_le_struct(msg, FM10K_PF_ATTR_ID_MAC_UPDATE,
0333 &mac_update, sizeof(mac_update));
0334
0335
0336 return mbx->ops.enqueue_tx(hw, mbx, msg);
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 static s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,
0352 const u8 *mac, u16 vid, bool add, u8 flags)
0353 {
0354
0355 if (!is_valid_ether_addr(mac))
0356 return FM10K_ERR_PARAM;
0357
0358 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);
0359 }
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 static s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,
0373 const u8 *mac, u16 vid, bool add)
0374 {
0375
0376 if (!is_multicast_ether_addr(mac))
0377 return FM10K_ERR_PARAM;
0378
0379 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 static s32 fm10k_update_xcast_mode_pf(struct fm10k_hw *hw, u16 glort, u8 mode)
0393 {
0394 struct fm10k_mbx_info *mbx = &hw->mbx;
0395 u32 msg[3], xcast_mode;
0396
0397 if (mode > FM10K_XCAST_MODE_NONE)
0398 return FM10K_ERR_PARAM;
0399
0400
0401 if (!fm10k_glort_valid_pf(hw, glort))
0402 return FM10K_ERR_PARAM;
0403
0404
0405
0406
0407
0408 xcast_mode = ((u32)mode << 16) | glort;
0409
0410
0411 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_XCAST_MODES);
0412 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_XCAST_MODE, xcast_mode);
0413
0414
0415 return mbx->ops.enqueue_tx(hw, mbx, msg);
0416 }
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426 static void fm10k_update_int_moderator_pf(struct fm10k_hw *hw)
0427 {
0428 u32 i;
0429
0430
0431 fm10k_write_reg(hw, FM10K_INT_CTRL, 0);
0432
0433
0434 for (i = FM10K_ITR_REG_COUNT_PF - 1; i; i--) {
0435 if (!fm10k_read_reg(hw, FM10K_MSIX_VECTOR_MASK(i)))
0436 break;
0437 }
0438
0439
0440 fm10k_write_reg(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i);
0441
0442
0443 if (!hw->iov.num_vfs)
0444 fm10k_write_reg(hw, FM10K_ITR2(0), i);
0445
0446
0447 fm10k_write_reg(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
0448 }
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 static s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort,
0460 u16 count, bool enable)
0461 {
0462 struct fm10k_mbx_info *mbx = &hw->mbx;
0463 u32 msg[3], lport_msg;
0464
0465
0466 if (!count)
0467 return 0;
0468
0469
0470 if (!fm10k_glort_valid_pf(hw, glort))
0471 return FM10K_ERR_PARAM;
0472
0473
0474 if (!enable)
0475 fm10k_update_xcast_mode_pf(hw, glort, FM10K_XCAST_MODE_NONE);
0476
0477
0478 lport_msg = ((u32)count << 16) | glort;
0479
0480
0481 fm10k_tlv_msg_init(msg, enable ? FM10K_PF_MSG_ID_LPORT_CREATE :
0482 FM10K_PF_MSG_ID_LPORT_DELETE);
0483 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_PORT, lport_msg);
0484
0485
0486 return mbx->ops.enqueue_tx(hw, mbx, msg);
0487 }
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 static s32 fm10k_configure_dglort_map_pf(struct fm10k_hw *hw,
0499 struct fm10k_dglort_cfg *dglort)
0500 {
0501 u16 glort, queue_count, vsi_count, pc_count;
0502 u16 vsi, queue, pc, q_idx;
0503 u32 txqctl, dglortdec, dglortmap;
0504
0505
0506 if (!dglort)
0507 return FM10K_ERR_PARAM;
0508
0509
0510 if ((dglort->idx > 7) || (dglort->rss_l > 7) || (dglort->pc_l > 3) ||
0511 (dglort->vsi_l > 6) || (dglort->vsi_b > 64) ||
0512 (dglort->queue_l > 8) || (dglort->queue_b >= 256))
0513 return FM10K_ERR_PARAM;
0514
0515
0516 queue_count = BIT(dglort->rss_l + dglort->pc_l);
0517 vsi_count = BIT(dglort->vsi_l + dglort->queue_l);
0518 glort = dglort->glort;
0519 q_idx = dglort->queue_b;
0520
0521
0522 for (vsi = 0; vsi < vsi_count; vsi++, glort++) {
0523 for (queue = 0; queue < queue_count; queue++, q_idx++) {
0524 if (q_idx >= FM10K_MAX_QUEUES)
0525 break;
0526
0527 fm10k_write_reg(hw, FM10K_TX_SGLORT(q_idx), glort);
0528 fm10k_write_reg(hw, FM10K_RX_SGLORT(q_idx), glort);
0529 }
0530 }
0531
0532
0533 queue_count = BIT(dglort->queue_l + dglort->rss_l + dglort->vsi_l);
0534 pc_count = BIT(dglort->pc_l);
0535
0536
0537 for (pc = 0; pc < pc_count; pc++) {
0538 q_idx = pc + dglort->queue_b;
0539 for (queue = 0; queue < queue_count; queue++) {
0540 if (q_idx >= FM10K_MAX_QUEUES)
0541 break;
0542
0543 txqctl = fm10k_read_reg(hw, FM10K_TXQCTL(q_idx));
0544 txqctl &= ~FM10K_TXQCTL_PC_MASK;
0545 txqctl |= pc << FM10K_TXQCTL_PC_SHIFT;
0546 fm10k_write_reg(hw, FM10K_TXQCTL(q_idx), txqctl);
0547
0548 q_idx += pc_count;
0549 }
0550 }
0551
0552
0553 dglortdec = ((u32)(dglort->rss_l) << FM10K_DGLORTDEC_RSSLENGTH_SHIFT) |
0554 ((u32)(dglort->queue_b) << FM10K_DGLORTDEC_QBASE_SHIFT) |
0555 ((u32)(dglort->pc_l) << FM10K_DGLORTDEC_PCLENGTH_SHIFT) |
0556 ((u32)(dglort->vsi_b) << FM10K_DGLORTDEC_VSIBASE_SHIFT) |
0557 ((u32)(dglort->vsi_l) << FM10K_DGLORTDEC_VSILENGTH_SHIFT) |
0558 ((u32)(dglort->queue_l));
0559 if (dglort->inner_rss)
0560 dglortdec |= FM10K_DGLORTDEC_INNERRSS_ENABLE;
0561
0562
0563 dglortmap = (dglort->idx == fm10k_dglort_default) ?
0564 FM10K_DGLORTMAP_ANY : FM10K_DGLORTMAP_ZERO;
0565 dglortmap <<= dglort->vsi_l + dglort->queue_l + dglort->shared_l;
0566 dglortmap |= dglort->glort;
0567
0568
0569 fm10k_write_reg(hw, FM10K_DGLORTDEC(dglort->idx), dglortdec);
0570 fm10k_write_reg(hw, FM10K_DGLORTMAP(dglort->idx), dglortmap);
0571
0572 return 0;
0573 }
0574
0575 u16 fm10k_queues_per_pool(struct fm10k_hw *hw)
0576 {
0577 u16 num_pools = hw->iov.num_pools;
0578
0579 return (num_pools > 32) ? 2 : (num_pools > 16) ? 4 : (num_pools > 8) ?
0580 8 : FM10K_MAX_QUEUES_POOL;
0581 }
0582
0583 u16 fm10k_vf_queue_index(struct fm10k_hw *hw, u16 vf_idx)
0584 {
0585 u16 num_vfs = hw->iov.num_vfs;
0586 u16 vf_q_idx = FM10K_MAX_QUEUES;
0587
0588 vf_q_idx -= fm10k_queues_per_pool(hw) * (num_vfs - vf_idx);
0589
0590 return vf_q_idx;
0591 }
0592
0593 static u16 fm10k_vectors_per_pool(struct fm10k_hw *hw)
0594 {
0595 u16 num_pools = hw->iov.num_pools;
0596
0597 return (num_pools > 32) ? 8 : (num_pools > 16) ? 16 :
0598 FM10K_MAX_VECTORS_POOL;
0599 }
0600
0601 static u16 fm10k_vf_vector_index(struct fm10k_hw *hw, u16 vf_idx)
0602 {
0603 u16 vf_v_idx = FM10K_MAX_VECTORS_PF;
0604
0605 vf_v_idx += fm10k_vectors_per_pool(hw) * vf_idx;
0606
0607 return vf_v_idx;
0608 }
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619 static s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,
0620 u16 num_pools)
0621 {
0622 u16 qmap_stride, qpp, vpp, vf_q_idx, vf_q_idx0, qmap_idx;
0623 u32 vid = hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT;
0624 int i, j;
0625
0626
0627 if (num_pools > 64)
0628 return FM10K_ERR_PARAM;
0629
0630
0631 if ((num_vfs > num_pools) || (num_vfs > hw->iov.total_vfs))
0632 return FM10K_ERR_PARAM;
0633
0634
0635 hw->iov.num_vfs = num_vfs;
0636 hw->iov.num_pools = num_pools;
0637
0638
0639 qmap_stride = (num_vfs > 8) ? 32 : 256;
0640 qpp = fm10k_queues_per_pool(hw);
0641 vpp = fm10k_vectors_per_pool(hw);
0642
0643
0644 vf_q_idx = fm10k_vf_queue_index(hw, 0);
0645 qmap_idx = 0;
0646
0647
0648 for (i = 0; i < num_vfs; i++) {
0649 fm10k_write_reg(hw, FM10K_TC_MAXCREDIT(i), 0);
0650 fm10k_write_reg(hw, FM10K_TC_RATE(i), 0);
0651 fm10k_write_reg(hw, FM10K_TC_CREDIT(i),
0652 FM10K_TC_CREDIT_CREDIT_MASK);
0653 }
0654
0655
0656 for (i = FM10K_VFMBMEM_LEN * num_vfs; i--;)
0657 fm10k_write_reg(hw, FM10K_MBMEM(i), 0);
0658
0659
0660 fm10k_write_reg(hw, FM10K_PFVFLREC(0), ~0);
0661 fm10k_write_reg(hw, FM10K_PFVFLREC(1), ~0);
0662
0663
0664 for (i = FM10K_MAX_QUEUES_PF; i < vf_q_idx; i++) {
0665 fm10k_write_reg(hw, FM10K_TXDCTL(i), 0);
0666 fm10k_write_reg(hw, FM10K_TXQCTL(i), FM10K_TXQCTL_PF |
0667 FM10K_TXQCTL_UNLIMITED_BW | vid);
0668 fm10k_write_reg(hw, FM10K_RXQCTL(i), FM10K_RXQCTL_PF);
0669 }
0670
0671
0672
0673
0674 for (i = FM10K_ITR_REG_COUNT_PF + 1; i < FM10K_ITR_REG_COUNT; i++) {
0675 if (!(i & (vpp - 1)))
0676 fm10k_write_reg(hw, FM10K_ITR2(i), i - vpp);
0677 else
0678 fm10k_write_reg(hw, FM10K_ITR2(i), i - 1);
0679 }
0680
0681
0682 fm10k_write_reg(hw, FM10K_ITR2(0),
0683 fm10k_vf_vector_index(hw, num_vfs - 1));
0684
0685
0686 for (i = 0; i < num_vfs; i++) {
0687
0688 vf_q_idx0 = vf_q_idx;
0689
0690 for (j = 0; j < qpp; j++, qmap_idx++, vf_q_idx++) {
0691
0692 fm10k_write_reg(hw, FM10K_TXDCTL(vf_q_idx), 0);
0693 fm10k_write_reg(hw, FM10K_TXQCTL(vf_q_idx),
0694 (i << FM10K_TXQCTL_TC_SHIFT) | i |
0695 FM10K_TXQCTL_VF | vid);
0696 fm10k_write_reg(hw, FM10K_RXDCTL(vf_q_idx),
0697 FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
0698 FM10K_RXDCTL_DROP_ON_EMPTY);
0699 fm10k_write_reg(hw, FM10K_RXQCTL(vf_q_idx),
0700 (i << FM10K_RXQCTL_VF_SHIFT) |
0701 FM10K_RXQCTL_VF);
0702
0703
0704 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
0705 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx), vf_q_idx);
0706 }
0707
0708
0709 for (; j < qmap_stride; j++, qmap_idx++) {
0710 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), vf_q_idx0);
0711 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx), vf_q_idx0);
0712 }
0713 }
0714
0715
0716 while (qmap_idx < FM10K_TQMAP_TABLE_SIZE) {
0717 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), 0);
0718 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx), 0);
0719 qmap_idx++;
0720 }
0721
0722 return 0;
0723 }
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734 static s32 fm10k_iov_configure_tc_pf(struct fm10k_hw *hw, u16 vf_idx, int rate)
0735 {
0736
0737 u32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;
0738 u32 tc_rate = FM10K_TC_RATE_QUANTA_MASK;
0739
0740
0741 if (vf_idx >= hw->iov.num_vfs)
0742 return FM10K_ERR_PARAM;
0743
0744
0745 switch (hw->bus.speed) {
0746 case fm10k_bus_speed_2500:
0747 interval = FM10K_TC_RATE_INTERVAL_4US_GEN1;
0748 break;
0749 case fm10k_bus_speed_5000:
0750 interval = FM10K_TC_RATE_INTERVAL_4US_GEN2;
0751 break;
0752 default:
0753 break;
0754 }
0755
0756 if (rate) {
0757 if (rate > FM10K_VF_TC_MAX || rate < FM10K_VF_TC_MIN)
0758 return FM10K_ERR_PARAM;
0759
0760
0761
0762
0763
0764
0765
0766
0767 tc_rate = (rate * 128) / 125;
0768
0769
0770
0771
0772 if (rate < 4000)
0773 interval <<= 1;
0774 else
0775 tc_rate >>= 1;
0776 }
0777
0778
0779 fm10k_write_reg(hw, FM10K_TC_RATE(vf_idx), tc_rate | interval);
0780 fm10k_write_reg(hw, FM10K_TC_MAXCREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);
0781 fm10k_write_reg(hw, FM10K_TC_CREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);
0782
0783 return 0;
0784 }
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794 static s32 fm10k_iov_assign_int_moderator_pf(struct fm10k_hw *hw, u16 vf_idx)
0795 {
0796 u16 vf_v_idx, vf_v_limit, i;
0797
0798
0799 if (vf_idx >= hw->iov.num_vfs)
0800 return FM10K_ERR_PARAM;
0801
0802
0803 vf_v_idx = fm10k_vf_vector_index(hw, vf_idx);
0804 vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);
0805
0806
0807 for (i = vf_v_limit - 1; i > vf_v_idx; i--) {
0808 if (!fm10k_read_reg(hw, FM10K_MSIX_VECTOR_MASK(i)))
0809 break;
0810 }
0811
0812
0813 if (vf_idx == (hw->iov.num_vfs - 1))
0814 fm10k_write_reg(hw, FM10K_ITR2(0), i);
0815 else
0816 fm10k_write_reg(hw, FM10K_ITR2(vf_v_limit), i);
0817
0818 return 0;
0819 }
0820
0821
0822
0823
0824
0825
0826
0827
0828 static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
0829 struct fm10k_vf_info *vf_info)
0830 {
0831 u16 qmap_stride, queues_per_pool, vf_q_idx, timeout, qmap_idx, i;
0832 u32 msg[4], txdctl, txqctl, tdbal = 0, tdbah = 0;
0833 s32 err = 0;
0834 u16 vf_idx, vf_vid;
0835
0836
0837 if (!vf_info || vf_info->vf_idx >= hw->iov.num_vfs)
0838 return FM10K_ERR_PARAM;
0839
0840
0841 qmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;
0842 queues_per_pool = fm10k_queues_per_pool(hw);
0843
0844
0845 vf_idx = vf_info->vf_idx;
0846 vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
0847 qmap_idx = qmap_stride * vf_idx;
0848
0849
0850
0851
0852
0853
0854 if (vf_info->pf_vid)
0855 vf_vid = vf_info->pf_vid | FM10K_VLAN_OVERRIDE;
0856 else
0857 vf_vid = vf_info->sw_vid;
0858
0859
0860 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
0861 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
0862 vf_info->mac, vf_vid);
0863
0864
0865
0866
0867
0868 txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
0869 FM10K_TXQCTL_VID_MASK;
0870 txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
0871 FM10K_TXQCTL_VF | vf_idx;
0872
0873 for (i = 0; i < queues_per_pool; i++)
0874 fm10k_write_reg(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
0875
0876
0877 if (vf_info->mbx.ops.enqueue_tx) {
0878 err = vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
0879 if (err != FM10K_MBX_ERR_NO_MBX)
0880 return err;
0881 err = 0;
0882 }
0883
0884
0885
0886
0887
0888
0889
0890
0891 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), 0);
0892 fm10k_write_reg(hw, FM10K_TXDCTL(vf_q_idx), 0);
0893
0894
0895 txdctl = fm10k_read_reg(hw, FM10K_TXDCTL(vf_q_idx));
0896 for (timeout = 0; txdctl & FM10K_TXDCTL_ENABLE; timeout++) {
0897
0898 if (timeout == 10) {
0899 err = FM10K_ERR_DMA_PENDING;
0900 goto err_out;
0901 }
0902
0903 usleep_range(100, 200);
0904 txdctl = fm10k_read_reg(hw, FM10K_TXDCTL(vf_q_idx));
0905 }
0906
0907
0908 if (is_valid_ether_addr(vf_info->mac)) {
0909 tdbal = (((u32)vf_info->mac[3]) << 24) |
0910 (((u32)vf_info->mac[4]) << 16) |
0911 (((u32)vf_info->mac[5]) << 8);
0912
0913 tdbah = (((u32)0xFF) << 24) |
0914 (((u32)vf_info->mac[0]) << 16) |
0915 (((u32)vf_info->mac[1]) << 8) |
0916 ((u32)vf_info->mac[2]);
0917 }
0918
0919
0920 fm10k_write_reg(hw, FM10K_TDBAL(vf_q_idx), tdbal);
0921 fm10k_write_reg(hw, FM10K_TDBAH(vf_q_idx), tdbah);
0922
0923
0924
0925
0926
0927 fm10k_write_reg(hw, FM10K_TDLEN(vf_q_idx), hw->mac.itr_scale <<
0928 FM10K_TDLEN_ITR_SCALE_SHIFT);
0929
0930 err_out:
0931
0932 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
0933 return err;
0934 }
0935
0936
0937
0938
0939
0940
0941
0942
0943 static s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,
0944 struct fm10k_vf_info *vf_info)
0945 {
0946 u16 qmap_stride, queues_per_pool, vf_q_idx, qmap_idx;
0947 u32 tdbal = 0, tdbah = 0, txqctl, rxqctl;
0948 u16 vf_v_idx, vf_v_limit, vf_vid;
0949 u8 vf_idx = vf_info->vf_idx;
0950 int i;
0951
0952
0953 if (vf_idx >= hw->iov.num_vfs)
0954 return FM10K_ERR_PARAM;
0955
0956
0957 fm10k_write_reg(hw, FM10K_PFVFLREC(vf_idx / 32), BIT(vf_idx % 32));
0958
0959
0960 vf_info->mbx.timeout = 0;
0961 if (vf_info->mbx.ops.disconnect)
0962 vf_info->mbx.ops.disconnect(hw, &vf_info->mbx);
0963
0964
0965 vf_v_idx = fm10k_vf_vector_index(hw, vf_idx);
0966 vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);
0967
0968
0969 qmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;
0970 queues_per_pool = fm10k_queues_per_pool(hw);
0971 qmap_idx = qmap_stride * vf_idx;
0972
0973
0974 for (i = qmap_idx; i < (qmap_idx + qmap_stride); i++) {
0975 fm10k_write_reg(hw, FM10K_TQMAP(i), 0);
0976 fm10k_write_reg(hw, FM10K_RQMAP(i), 0);
0977 }
0978
0979
0980 vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
0981
0982
0983 if (vf_info->pf_vid)
0984 vf_vid = vf_info->pf_vid;
0985 else
0986 vf_vid = vf_info->sw_vid;
0987
0988
0989 txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) |
0990 (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
0991 FM10K_TXQCTL_VF | vf_idx;
0992 rxqctl = (vf_idx << FM10K_RXQCTL_VF_SHIFT) | FM10K_RXQCTL_VF;
0993
0994
0995 for (i = vf_q_idx; i < (queues_per_pool + vf_q_idx); i++) {
0996 fm10k_write_reg(hw, FM10K_TXDCTL(i), 0);
0997 fm10k_write_reg(hw, FM10K_TXQCTL(i), txqctl);
0998 fm10k_write_reg(hw, FM10K_RXDCTL(i),
0999 FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
1000 FM10K_RXDCTL_DROP_ON_EMPTY);
1001 fm10k_write_reg(hw, FM10K_RXQCTL(i), rxqctl);
1002 }
1003
1004
1005 fm10k_write_reg(hw, FM10K_TC_MAXCREDIT(vf_idx), 0);
1006 fm10k_write_reg(hw, FM10K_TC_RATE(vf_idx), 0);
1007 fm10k_write_reg(hw, FM10K_TC_CREDIT(vf_idx),
1008 FM10K_TC_CREDIT_CREDIT_MASK);
1009
1010
1011 if (!vf_idx)
1012 hw->mac.ops.update_int_moderator(hw);
1013 else
1014 hw->iov.ops.assign_int_moderator(hw, vf_idx - 1);
1015
1016
1017 if (vf_idx == (hw->iov.num_vfs - 1))
1018 fm10k_write_reg(hw, FM10K_ITR2(0), vf_v_idx);
1019 else
1020 fm10k_write_reg(hw, FM10K_ITR2(vf_v_limit), vf_v_idx);
1021
1022
1023 for (vf_v_idx++; vf_v_idx < vf_v_limit; vf_v_idx++)
1024 fm10k_write_reg(hw, FM10K_ITR2(vf_v_idx), vf_v_idx - 1);
1025
1026
1027 for (i = FM10K_VFMBMEM_LEN; i--;)
1028 fm10k_write_reg(hw, FM10K_MBMEM_VF(vf_idx, i), 0);
1029 for (i = FM10K_VLAN_TABLE_SIZE; i--;)
1030 fm10k_write_reg(hw, FM10K_VLAN_TABLE(vf_info->vsi, i), 0);
1031 for (i = FM10K_RETA_SIZE; i--;)
1032 fm10k_write_reg(hw, FM10K_RETA(vf_info->vsi, i), 0);
1033 for (i = FM10K_RSSRK_SIZE; i--;)
1034 fm10k_write_reg(hw, FM10K_RSSRK(vf_info->vsi, i), 0);
1035 fm10k_write_reg(hw, FM10K_MRQC(vf_info->vsi), 0);
1036
1037
1038 if (is_valid_ether_addr(vf_info->mac)) {
1039 tdbal = (((u32)vf_info->mac[3]) << 24) |
1040 (((u32)vf_info->mac[4]) << 16) |
1041 (((u32)vf_info->mac[5]) << 8);
1042 tdbah = (((u32)0xFF) << 24) |
1043 (((u32)vf_info->mac[0]) << 16) |
1044 (((u32)vf_info->mac[1]) << 8) |
1045 ((u32)vf_info->mac[2]);
1046 }
1047
1048
1049 for (i = queues_per_pool; i--;) {
1050 fm10k_write_reg(hw, FM10K_TDBAL(vf_q_idx + i), tdbal);
1051 fm10k_write_reg(hw, FM10K_TDBAH(vf_q_idx + i), tdbah);
1052
1053
1054
1055 fm10k_write_reg(hw, FM10K_TDLEN(vf_q_idx + i),
1056 hw->mac.itr_scale <<
1057 FM10K_TDLEN_ITR_SCALE_SHIFT);
1058 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx + i);
1059 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i);
1060 }
1061
1062
1063 for (i = queues_per_pool; i < qmap_stride; i++) {
1064 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx);
1065 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx);
1066 }
1067
1068 return 0;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 static s32 fm10k_iov_set_lport_pf(struct fm10k_hw *hw,
1082 struct fm10k_vf_info *vf_info,
1083 u16 lport_idx, u8 flags)
1084 {
1085 u16 glort = (hw->mac.dglort_map + lport_idx) & FM10K_DGLORTMAP_NONE;
1086
1087
1088 if (!fm10k_glort_valid_pf(hw, glort))
1089 return FM10K_ERR_PARAM;
1090
1091 vf_info->vf_flags = flags | FM10K_VF_FLAG_NONE_CAPABLE;
1092 vf_info->glort = glort;
1093
1094 return 0;
1095 }
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 static void fm10k_iov_reset_lport_pf(struct fm10k_hw *hw,
1106 struct fm10k_vf_info *vf_info)
1107 {
1108 u32 msg[1];
1109
1110
1111 if (FM10K_VF_FLAG_ENABLED(vf_info)) {
1112
1113 fm10k_update_lport_state_pf(hw, vf_info->glort, 1, false);
1114
1115
1116 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
1117 vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
1118 }
1119
1120
1121 vf_info->vf_flags = 0;
1122 vf_info->glort = 0;
1123 }
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133 static void fm10k_iov_update_stats_pf(struct fm10k_hw *hw,
1134 struct fm10k_hw_stats_q *q,
1135 u16 vf_idx)
1136 {
1137 u32 idx, qpp;
1138
1139
1140 qpp = fm10k_queues_per_pool(hw);
1141 idx = fm10k_vf_queue_index(hw, vf_idx);
1142 fm10k_update_hw_stats_q(hw, q, idx, qpp);
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 __always_unused **results,
1156 struct fm10k_mbx_info *mbx)
1157 {
1158 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1159 u8 vf_idx = vf_info->vf_idx;
1160
1161 return hw->iov.ops.assign_int_moderator(hw, vf_idx);
1162 }
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid)
1173 {
1174 if (!vid)
1175 return vf_info->pf_vid ? vf_info->pf_vid : vf_info->sw_vid;
1176 else if (vf_info->pf_vid && vid != vf_info->pf_vid)
1177 return FM10K_ERR_PARAM;
1178 else
1179 return vid;
1180 }
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results,
1193 struct fm10k_mbx_info *mbx)
1194 {
1195 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1196 u8 mac[ETH_ALEN];
1197 u32 *result;
1198 int err = 0;
1199 bool set;
1200 u16 vlan;
1201 u32 vid;
1202
1203
1204 if (!FM10K_VF_FLAG_ENABLED(vf_info))
1205 err = FM10K_ERR_PARAM;
1206
1207 if (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) {
1208 result = results[FM10K_MAC_VLAN_MSG_VLAN];
1209
1210
1211 err = fm10k_tlv_attr_get_u32(result, &vid);
1212 if (err)
1213 return err;
1214
1215 set = !(vid & FM10K_VLAN_CLEAR);
1216 vid &= ~FM10K_VLAN_CLEAR;
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228 if (vid >> 16) {
1229
1230
1231
1232 if (vf_info->pf_vid)
1233 return FM10K_ERR_PARAM;
1234 } else {
1235 err = fm10k_iov_select_vid(vf_info, (u16)vid);
1236 if (err < 0)
1237 return err;
1238
1239 vid = err;
1240 }
1241
1242
1243 err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set);
1244 }
1245
1246 if (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) {
1247 result = results[FM10K_MAC_VLAN_MSG_MAC];
1248
1249
1250 err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
1251 if (err)
1252 return err;
1253
1254
1255 if (is_valid_ether_addr(vf_info->mac) &&
1256 !ether_addr_equal(mac, vf_info->mac))
1257 return FM10K_ERR_PARAM;
1258
1259 set = !(vlan & FM10K_VLAN_CLEAR);
1260 vlan &= ~FM10K_VLAN_CLEAR;
1261
1262 err = fm10k_iov_select_vid(vf_info, vlan);
1263 if (err < 0)
1264 return err;
1265
1266 vlan = (u16)err;
1267
1268
1269 err = hw->mac.ops.update_uc_addr(hw, vf_info->glort,
1270 mac, vlan, set, 0);
1271 }
1272
1273 if (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) {
1274 result = results[FM10K_MAC_VLAN_MSG_MULTICAST];
1275
1276
1277 err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
1278 if (err)
1279 return err;
1280
1281
1282 if (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED))
1283 return FM10K_ERR_PARAM;
1284
1285 set = !(vlan & FM10K_VLAN_CLEAR);
1286 vlan &= ~FM10K_VLAN_CLEAR;
1287
1288 err = fm10k_iov_select_vid(vf_info, vlan);
1289 if (err < 0)
1290 return err;
1291
1292 vlan = (u16)err;
1293
1294
1295 err = hw->mac.ops.update_mc_addr(hw, vf_info->glort,
1296 mac, vlan, set);
1297 }
1298
1299 return err;
1300 }
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310 static u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info,
1311 u8 mode)
1312 {
1313 u8 vf_flags = vf_info->vf_flags;
1314
1315
1316 switch (mode) {
1317 case FM10K_XCAST_MODE_PROMISC:
1318 if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE)
1319 return FM10K_XCAST_MODE_PROMISC;
1320 fallthrough;
1321 case FM10K_XCAST_MODE_ALLMULTI:
1322 if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE)
1323 return FM10K_XCAST_MODE_ALLMULTI;
1324 fallthrough;
1325 case FM10K_XCAST_MODE_MULTI:
1326 if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE)
1327 return FM10K_XCAST_MODE_MULTI;
1328 fallthrough;
1329 case FM10K_XCAST_MODE_NONE:
1330 if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE)
1331 return FM10K_XCAST_MODE_NONE;
1332 fallthrough;
1333 default:
1334 break;
1335 }
1336
1337
1338 return FM10K_XCAST_MODE_DISABLE;
1339 }
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351 s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *hw, u32 **results,
1352 struct fm10k_mbx_info *mbx)
1353 {
1354 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1355 s32 err = 0;
1356 u32 msg[2];
1357 u8 mode = 0;
1358
1359
1360 if (!(vf_info->vf_flags & FM10K_VF_FLAG_NONE_CAPABLE))
1361 return FM10K_ERR_PARAM;
1362
1363 if (!!results[FM10K_LPORT_STATE_MSG_XCAST_MODE]) {
1364 u32 *result = results[FM10K_LPORT_STATE_MSG_XCAST_MODE];
1365
1366
1367 err = fm10k_tlv_attr_get_u8(result, &mode);
1368 if (err)
1369 return FM10K_ERR_PARAM;
1370
1371
1372 mode = fm10k_iov_supported_xcast_mode_pf(vf_info, mode);
1373
1374
1375 if (!(FM10K_VF_FLAG_ENABLED(vf_info) & BIT(mode)))
1376 fm10k_update_xcast_mode_pf(hw, vf_info->glort, mode);
1377
1378
1379 mode = FM10K_VF_FLAG_SET_MODE(mode);
1380 } else if (!results[FM10K_LPORT_STATE_MSG_DISABLE]) {
1381
1382 if (FM10K_VF_FLAG_ENABLED(vf_info))
1383 err = fm10k_update_lport_state_pf(hw, vf_info->glort,
1384 1, false);
1385
1386
1387
1388
1389
1390
1391 if (!err)
1392 vf_info->vf_flags = FM10K_VF_FLAG_CAPABLE(vf_info);
1393
1394
1395 hw->iov.ops.configure_tc(hw, vf_info->vf_idx, vf_info->rate);
1396
1397
1398 mode = FM10K_VF_FLAG_SET_MODE_NONE;
1399
1400
1401 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
1402 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_READY);
1403 mbx->ops.enqueue_tx(hw, mbx, msg);
1404 }
1405
1406
1407 if (!err && (!FM10K_VF_FLAG_ENABLED(vf_info) != !mode))
1408 err = fm10k_update_lport_state_pf(hw, vf_info->glort, 1,
1409 !!mode);
1410
1411
1412 mode |= FM10K_VF_FLAG_CAPABLE(vf_info);
1413 if (!err)
1414 vf_info->vf_flags = mode;
1415
1416 return err;
1417 }
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427 static void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
1428 struct fm10k_hw_stats *stats)
1429 {
1430 u32 timeout, ur, ca, um, xec, vlan_drop, loopback_drop, nodesc_drop;
1431 u32 id, id_prev;
1432
1433
1434 id = fm10k_read_reg(hw, FM10K_TXQCTL(0));
1435
1436
1437 do {
1438 timeout = fm10k_read_hw_stats_32b(hw, FM10K_STATS_TIMEOUT,
1439 &stats->timeout);
1440 ur = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UR, &stats->ur);
1441 ca = fm10k_read_hw_stats_32b(hw, FM10K_STATS_CA, &stats->ca);
1442 um = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UM, &stats->um);
1443 xec = fm10k_read_hw_stats_32b(hw, FM10K_STATS_XEC, &stats->xec);
1444 vlan_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_VLAN_DROP,
1445 &stats->vlan_drop);
1446 loopback_drop =
1447 fm10k_read_hw_stats_32b(hw,
1448 FM10K_STATS_LOOPBACK_DROP,
1449 &stats->loopback_drop);
1450 nodesc_drop = fm10k_read_hw_stats_32b(hw,
1451 FM10K_STATS_NODESC_DROP,
1452 &stats->nodesc_drop);
1453
1454
1455 id_prev = id;
1456 id = fm10k_read_reg(hw, FM10K_TXQCTL(0));
1457 } while ((id ^ id_prev) & FM10K_TXQCTL_ID_MASK);
1458
1459
1460 id &= FM10K_TXQCTL_ID_MASK;
1461 id |= FM10K_STAT_VALID;
1462
1463
1464 if (stats->stats_idx == id) {
1465 stats->timeout.count += timeout;
1466 stats->ur.count += ur;
1467 stats->ca.count += ca;
1468 stats->um.count += um;
1469 stats->xec.count += xec;
1470 stats->vlan_drop.count += vlan_drop;
1471 stats->loopback_drop.count += loopback_drop;
1472 stats->nodesc_drop.count += nodesc_drop;
1473 }
1474
1475
1476 fm10k_update_hw_base_32b(&stats->timeout, timeout);
1477 fm10k_update_hw_base_32b(&stats->ur, ur);
1478 fm10k_update_hw_base_32b(&stats->ca, ca);
1479 fm10k_update_hw_base_32b(&stats->um, um);
1480 fm10k_update_hw_base_32b(&stats->xec, xec);
1481 fm10k_update_hw_base_32b(&stats->vlan_drop, vlan_drop);
1482 fm10k_update_hw_base_32b(&stats->loopback_drop, loopback_drop);
1483 fm10k_update_hw_base_32b(&stats->nodesc_drop, nodesc_drop);
1484 stats->stats_idx = id;
1485
1486
1487 fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
1488 }
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498 static void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
1499 struct fm10k_hw_stats *stats)
1500 {
1501
1502 fm10k_unbind_hw_stats_32b(&stats->timeout);
1503 fm10k_unbind_hw_stats_32b(&stats->ur);
1504 fm10k_unbind_hw_stats_32b(&stats->ca);
1505 fm10k_unbind_hw_stats_32b(&stats->um);
1506 fm10k_unbind_hw_stats_32b(&stats->xec);
1507 fm10k_unbind_hw_stats_32b(&stats->vlan_drop);
1508 fm10k_unbind_hw_stats_32b(&stats->loopback_drop);
1509 fm10k_unbind_hw_stats_32b(&stats->nodesc_drop);
1510
1511
1512 fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
1513
1514
1515 fm10k_update_hw_stats_pf(hw, stats);
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 static void fm10k_set_dma_mask_pf(struct fm10k_hw *hw, u64 dma_mask)
1527 {
1528
1529 u32 phyaddr = (u32)(dma_mask >> 32);
1530
1531 fm10k_write_reg(hw, FM10K_PHYADDR, phyaddr);
1532 }
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545 static s32 fm10k_get_fault_pf(struct fm10k_hw *hw, int type,
1546 struct fm10k_fault *fault)
1547 {
1548 u32 func;
1549
1550
1551 switch (type) {
1552 case FM10K_PCA_FAULT:
1553 case FM10K_THI_FAULT:
1554 case FM10K_FUM_FAULT:
1555 break;
1556 default:
1557 return FM10K_ERR_PARAM;
1558 }
1559
1560
1561 func = fm10k_read_reg(hw, type + FM10K_FAULT_FUNC);
1562 if (!(func & FM10K_FAULT_FUNC_VALID))
1563 return FM10K_ERR_PARAM;
1564
1565
1566 fault->address = fm10k_read_reg(hw, type + FM10K_FAULT_ADDR_HI);
1567 fault->address <<= 32;
1568 fault->address |= fm10k_read_reg(hw, type + FM10K_FAULT_ADDR_LO);
1569 fault->specinfo = fm10k_read_reg(hw, type + FM10K_FAULT_SPECINFO);
1570
1571
1572 fm10k_write_reg(hw, type + FM10K_FAULT_FUNC, FM10K_FAULT_FUNC_VALID);
1573
1574
1575 if (func & FM10K_FAULT_FUNC_PF)
1576 fault->func = 0;
1577 else
1578 fault->func = 1 + ((func & FM10K_FAULT_FUNC_VF_MASK) >>
1579 FM10K_FAULT_FUNC_VF_SHIFT);
1580
1581
1582 fault->type = func & FM10K_FAULT_FUNC_TYPE_MASK;
1583
1584 return 0;
1585 }
1586
1587
1588
1589
1590
1591
1592 static s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)
1593 {
1594 struct fm10k_mbx_info *mbx = &hw->mbx;
1595 u32 msg[1];
1596
1597
1598 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_LPORT_MAP);
1599
1600
1601 return mbx->ops.enqueue_tx(hw, mbx, msg);
1602 }
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613 static s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
1614 {
1615 u32 dma_ctrl2;
1616
1617
1618 dma_ctrl2 = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
1619 if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))
1620 return 0;
1621
1622
1623 return fm10k_get_host_state_generic(hw, switch_ready);
1624 }
1625
1626
1627 const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {
1628 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
1629 sizeof(struct fm10k_swapi_error)),
1630 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),
1631 FM10K_TLV_ATTR_LAST
1632 };
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643 s32 fm10k_msg_lport_map_pf(struct fm10k_hw *hw, u32 **results,
1644 struct fm10k_mbx_info __always_unused *mbx)
1645 {
1646 u16 glort, mask;
1647 u32 dglort_map;
1648 s32 err;
1649
1650 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_LPORT_MAP],
1651 &dglort_map);
1652 if (err)
1653 return err;
1654
1655
1656 glort = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_GLORT);
1657 mask = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_MASK);
1658
1659
1660 if (!mask || (glort & ~mask))
1661 return FM10K_ERR_PARAM;
1662
1663
1664 if (((~(mask - 1) & mask) + mask) & FM10K_DGLORTMAP_NONE)
1665 return FM10K_ERR_PARAM;
1666
1667
1668 hw->mac.dglort_map = dglort_map;
1669
1670 return 0;
1671 }
1672
1673 const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[] = {
1674 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_UPDATE_PVID),
1675 FM10K_TLV_ATTR_LAST
1676 };
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686 static s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
1687 struct fm10k_mbx_info __always_unused *mbx)
1688 {
1689 u16 glort, pvid;
1690 u32 pvid_update;
1691 s32 err;
1692
1693 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID],
1694 &pvid_update);
1695 if (err)
1696 return err;
1697
1698
1699 glort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT);
1700 pvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID);
1701
1702
1703 if (!fm10k_glort_valid_pf(hw, glort))
1704 return FM10K_ERR_PARAM;
1705
1706
1707 if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
1708 return FM10K_ERR_PARAM;
1709
1710
1711 hw->mac.default_vid = pvid;
1712
1713 return 0;
1714 }
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724 static void fm10k_record_global_table_data(struct fm10k_global_table_data *from,
1725 struct fm10k_swapi_table_info *to)
1726 {
1727
1728 to->used = le32_to_cpu(from->used);
1729 to->avail = le32_to_cpu(from->avail);
1730 }
1731
1732 const struct fm10k_tlv_attr fm10k_err_msg_attr[] = {
1733 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
1734 sizeof(struct fm10k_swapi_error)),
1735 FM10K_TLV_ATTR_LAST
1736 };
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 s32 fm10k_msg_err_pf(struct fm10k_hw *hw, u32 **results,
1748 struct fm10k_mbx_info __always_unused *mbx)
1749 {
1750 struct fm10k_swapi_error err_msg;
1751 s32 err;
1752
1753
1754 err = fm10k_tlv_attr_get_le_struct(results[FM10K_PF_ATTR_ID_ERR],
1755 &err_msg, sizeof(err_msg));
1756 if (err)
1757 return err;
1758
1759
1760 fm10k_record_global_table_data(&err_msg.mac, &hw->swapi.mac);
1761 fm10k_record_global_table_data(&err_msg.nexthop, &hw->swapi.nexthop);
1762 fm10k_record_global_table_data(&err_msg.ffu, &hw->swapi.ffu);
1763
1764
1765 hw->swapi.status = le32_to_cpu(err_msg.status);
1766
1767 return 0;
1768 }
1769
1770 static const struct fm10k_msg_data fm10k_msg_data_pf[] = {
1771 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
1772 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
1773 FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
1774 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
1775 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
1776 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
1777 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
1778 };
1779
1780 static const struct fm10k_mac_ops mac_ops_pf = {
1781 .get_bus_info = fm10k_get_bus_info_generic,
1782 .reset_hw = fm10k_reset_hw_pf,
1783 .init_hw = fm10k_init_hw_pf,
1784 .start_hw = fm10k_start_hw_generic,
1785 .stop_hw = fm10k_stop_hw_generic,
1786 .update_vlan = fm10k_update_vlan_pf,
1787 .read_mac_addr = fm10k_read_mac_addr_pf,
1788 .update_uc_addr = fm10k_update_uc_addr_pf,
1789 .update_mc_addr = fm10k_update_mc_addr_pf,
1790 .update_xcast_mode = fm10k_update_xcast_mode_pf,
1791 .update_int_moderator = fm10k_update_int_moderator_pf,
1792 .update_lport_state = fm10k_update_lport_state_pf,
1793 .update_hw_stats = fm10k_update_hw_stats_pf,
1794 .rebind_hw_stats = fm10k_rebind_hw_stats_pf,
1795 .configure_dglort_map = fm10k_configure_dglort_map_pf,
1796 .set_dma_mask = fm10k_set_dma_mask_pf,
1797 .get_fault = fm10k_get_fault_pf,
1798 .get_host_state = fm10k_get_host_state_pf,
1799 .request_lport_map = fm10k_request_lport_map_pf,
1800 };
1801
1802 static const struct fm10k_iov_ops iov_ops_pf = {
1803 .assign_resources = fm10k_iov_assign_resources_pf,
1804 .configure_tc = fm10k_iov_configure_tc_pf,
1805 .assign_int_moderator = fm10k_iov_assign_int_moderator_pf,
1806 .assign_default_mac_vlan = fm10k_iov_assign_default_mac_vlan_pf,
1807 .reset_resources = fm10k_iov_reset_resources_pf,
1808 .set_lport = fm10k_iov_set_lport_pf,
1809 .reset_lport = fm10k_iov_reset_lport_pf,
1810 .update_stats = fm10k_iov_update_stats_pf,
1811 };
1812
1813 static s32 fm10k_get_invariants_pf(struct fm10k_hw *hw)
1814 {
1815 fm10k_get_invariants_generic(hw);
1816
1817 return fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);
1818 }
1819
1820 const struct fm10k_info fm10k_pf_info = {
1821 .mac = fm10k_mac_pf,
1822 .get_invariants = fm10k_get_invariants_pf,
1823 .mac_ops = &mac_ops_pf,
1824 .iov_ops = &iov_ops_pf,
1825 };