0001
0002
0003
0004 #include "fm10k_vf.h"
0005
0006
0007
0008
0009
0010
0011 static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw)
0012 {
0013 u8 *perm_addr = hw->mac.perm_addr;
0014 u32 bal = 0, bah = 0, tdlen;
0015 s32 err;
0016 u16 i;
0017
0018
0019 err = fm10k_stop_hw_generic(hw);
0020 if (err && err != FM10K_ERR_REQUESTS_PENDING)
0021 return err;
0022
0023
0024 if (is_valid_ether_addr(perm_addr)) {
0025 bal = (((u32)perm_addr[3]) << 24) |
0026 (((u32)perm_addr[4]) << 16) |
0027 (((u32)perm_addr[5]) << 8);
0028 bah = (((u32)0xFF) << 24) |
0029 (((u32)perm_addr[0]) << 16) |
0030 (((u32)perm_addr[1]) << 8) |
0031 ((u32)perm_addr[2]);
0032 }
0033
0034
0035 tdlen = hw->mac.itr_scale << FM10K_TDLEN_ITR_SCALE_SHIFT;
0036
0037
0038
0039
0040 for (i = 0; i < hw->mac.max_queues; i++) {
0041 fm10k_write_reg(hw, FM10K_TDBAL(i), bal);
0042 fm10k_write_reg(hw, FM10K_TDBAH(i), bah);
0043 fm10k_write_reg(hw, FM10K_RDBAL(i), bal);
0044 fm10k_write_reg(hw, FM10K_RDBAH(i), bah);
0045
0046
0047
0048
0049
0050 fm10k_write_reg(hw, FM10K_TDLEN(i), tdlen);
0051 }
0052
0053 return err;
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063 static s32 fm10k_reset_hw_vf(struct fm10k_hw *hw)
0064 {
0065 s32 err;
0066
0067
0068 err = fm10k_stop_hw_vf(hw);
0069 if (err == FM10K_ERR_REQUESTS_PENDING)
0070 hw->mac.reset_while_pending++;
0071 else if (err)
0072 return err;
0073
0074
0075 fm10k_write_reg(hw, FM10K_VFCTRL, FM10K_VFCTRL_RST);
0076
0077
0078 fm10k_write_flush(hw);
0079 udelay(FM10K_RESET_TIMEOUT);
0080
0081
0082 fm10k_write_reg(hw, FM10K_VFCTRL, 0);
0083 if (fm10k_read_reg(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST)
0084 return FM10K_ERR_RESET_FAILED;
0085
0086 return 0;
0087 }
0088
0089
0090
0091
0092
0093
0094 static s32 fm10k_init_hw_vf(struct fm10k_hw *hw)
0095 {
0096 u32 tqdloc, tqdloc0 = ~fm10k_read_reg(hw, FM10K_TQDLOC(0));
0097 s32 err;
0098 u16 i;
0099
0100
0101 if (!~fm10k_read_reg(hw, FM10K_TXQCTL(0)) ||
0102 !~fm10k_read_reg(hw, FM10K_RXQCTL(0))) {
0103 err = FM10K_ERR_NO_RESOURCES;
0104 goto reset_max_queues;
0105 }
0106
0107
0108 for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
0109
0110 tqdloc = ~fm10k_read_reg(hw, FM10K_TQDLOC(i));
0111 if (!tqdloc || (tqdloc == tqdloc0))
0112 break;
0113
0114
0115 if (!~fm10k_read_reg(hw, FM10K_TXQCTL(i)) ||
0116 !~fm10k_read_reg(hw, FM10K_RXQCTL(i)))
0117 break;
0118 }
0119
0120
0121 err = fm10k_disable_queues_generic(hw, i);
0122 if (err)
0123 goto reset_max_queues;
0124
0125
0126 hw->mac.max_queues = i;
0127
0128
0129 hw->mac.default_vid = (fm10k_read_reg(hw, FM10K_TXQCTL(0)) &
0130 FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;
0131
0132
0133
0134
0135 hw->mac.itr_scale = (fm10k_read_reg(hw, FM10K_TDLEN(0)) &
0136 FM10K_TDLEN_ITR_SCALE_MASK) >>
0137 FM10K_TDLEN_ITR_SCALE_SHIFT;
0138
0139 return 0;
0140
0141 reset_max_queues:
0142 hw->mac.max_queues = 0;
0143
0144 return err;
0145 }
0146
0147
0148 const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = {
0149 FM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN),
0150 FM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET),
0151 FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC),
0152 FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC),
0153 FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST),
0154 FM10K_TLV_ATTR_LAST
0155 };
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 static s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
0168 {
0169 struct fm10k_mbx_info *mbx = &hw->mbx;
0170 u32 msg[4];
0171
0172
0173 if (vsi)
0174 return FM10K_ERR_PARAM;
0175
0176
0177 if ((vid << 16 | vid) >> 28)
0178 return FM10K_ERR_PARAM;
0179
0180
0181 if (!set)
0182 vid |= FM10K_VLAN_CLEAR;
0183
0184
0185 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
0186 fm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid);
0187
0188
0189 return mbx->ops.enqueue_tx(hw, mbx, msg);
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results,
0201 struct fm10k_mbx_info __always_unused *mbx)
0202 {
0203 u8 perm_addr[ETH_ALEN];
0204 u16 vid;
0205 s32 err;
0206
0207
0208 err = fm10k_tlv_attr_get_mac_vlan(
0209 results[FM10K_MAC_VLAN_MSG_DEFAULT_MAC],
0210 perm_addr, &vid);
0211 if (err)
0212 return err;
0213
0214 ether_addr_copy(hw->mac.perm_addr, perm_addr);
0215 hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1);
0216 hw->mac.vlan_override = !!(vid & FM10K_VLAN_OVERRIDE);
0217
0218 return 0;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227 static s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw)
0228 {
0229 u8 perm_addr[ETH_ALEN];
0230 u32 base_addr;
0231
0232 base_addr = fm10k_read_reg(hw, FM10K_TDBAL(0));
0233
0234
0235 if (base_addr << 24)
0236 return FM10K_ERR_INVALID_MAC_ADDR;
0237
0238 perm_addr[3] = (u8)(base_addr >> 24);
0239 perm_addr[4] = (u8)(base_addr >> 16);
0240 perm_addr[5] = (u8)(base_addr >> 8);
0241
0242 base_addr = fm10k_read_reg(hw, FM10K_TDBAH(0));
0243
0244
0245 if ((~base_addr) >> 24)
0246 return FM10K_ERR_INVALID_MAC_ADDR;
0247
0248 perm_addr[0] = (u8)(base_addr >> 16);
0249 perm_addr[1] = (u8)(base_addr >> 8);
0250 perm_addr[2] = (u8)(base_addr);
0251
0252 ether_addr_copy(hw->mac.perm_addr, perm_addr);
0253 ether_addr_copy(hw->mac.addr, perm_addr);
0254
0255 return 0;
0256 }
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 static s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw,
0271 u16 __always_unused glort,
0272 const u8 *mac, u16 vid, bool add,
0273 u8 __always_unused flags)
0274 {
0275 struct fm10k_mbx_info *mbx = &hw->mbx;
0276 u32 msg[7];
0277
0278
0279 if (vid >= FM10K_VLAN_TABLE_VID_MAX)
0280 return FM10K_ERR_PARAM;
0281
0282
0283 if (!is_valid_ether_addr(mac))
0284 return FM10K_ERR_PARAM;
0285
0286
0287 if (is_valid_ether_addr(hw->mac.perm_addr) &&
0288 !ether_addr_equal(hw->mac.perm_addr, mac))
0289 return FM10K_ERR_PARAM;
0290
0291
0292 if (!add)
0293 vid |= FM10K_VLAN_CLEAR;
0294
0295
0296 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
0297 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid);
0298
0299
0300 return mbx->ops.enqueue_tx(hw, mbx, msg);
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 static s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw,
0315 u16 __always_unused glort,
0316 const u8 *mac, u16 vid, bool add)
0317 {
0318 struct fm10k_mbx_info *mbx = &hw->mbx;
0319 u32 msg[7];
0320
0321
0322 if (vid >= FM10K_VLAN_TABLE_VID_MAX)
0323 return FM10K_ERR_PARAM;
0324
0325
0326 if (!is_multicast_ether_addr(mac))
0327 return FM10K_ERR_PARAM;
0328
0329
0330 if (!add)
0331 vid |= FM10K_VLAN_CLEAR;
0332
0333
0334 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
0335 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST,
0336 mac, vid);
0337
0338
0339 return mbx->ops.enqueue_tx(hw, mbx, msg);
0340 }
0341
0342
0343
0344
0345
0346
0347
0348
0349 static void fm10k_update_int_moderator_vf(struct fm10k_hw *hw)
0350 {
0351 struct fm10k_mbx_info *mbx = &hw->mbx;
0352 u32 msg[1];
0353
0354
0355 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX);
0356
0357
0358 mbx->ops.enqueue_tx(hw, mbx, msg);
0359 }
0360
0361
0362 const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = {
0363 FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE),
0364 FM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE),
0365 FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY),
0366 FM10K_TLV_ATTR_LAST
0367 };
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results,
0379 struct fm10k_mbx_info __always_unused *mbx)
0380 {
0381 hw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ?
0382 FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO;
0383
0384 return 0;
0385 }
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 static s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw,
0399 u16 __always_unused glort,
0400 u16 __always_unused count, bool enable)
0401 {
0402 struct fm10k_mbx_info *mbx = &hw->mbx;
0403 u32 msg[2];
0404
0405
0406 hw->mac.dglort_map = FM10K_DGLORTMAP_NONE;
0407
0408
0409 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
0410 if (!enable)
0411 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);
0412
0413
0414 return mbx->ops.enqueue_tx(hw, mbx, msg);
0415 }
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 static s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw,
0428 u16 __always_unused glort, u8 mode)
0429 {
0430 struct fm10k_mbx_info *mbx = &hw->mbx;
0431 u32 msg[3];
0432
0433 if (mode > FM10K_XCAST_MODE_NONE)
0434 return FM10K_ERR_PARAM;
0435
0436
0437 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
0438 fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);
0439
0440
0441 return mbx->ops.enqueue_tx(hw, mbx, msg);
0442 }
0443
0444
0445
0446
0447
0448
0449
0450
0451 static void fm10k_update_hw_stats_vf(struct fm10k_hw *hw,
0452 struct fm10k_hw_stats *stats)
0453 {
0454 fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
0455 }
0456
0457
0458
0459
0460
0461
0462
0463
0464 static void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw,
0465 struct fm10k_hw_stats *stats)
0466 {
0467
0468 fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
0469
0470
0471 fm10k_update_hw_stats_vf(hw, stats);
0472 }
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483 static s32 fm10k_configure_dglort_map_vf(struct fm10k_hw __always_unused *hw,
0484 struct fm10k_dglort_cfg *dglort)
0485 {
0486
0487 if (!dglort)
0488 return FM10K_ERR_PARAM;
0489
0490
0491
0492 return 0;
0493 }
0494
0495 static const struct fm10k_msg_data fm10k_msg_data_vf[] = {
0496 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
0497 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
0498 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
0499 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
0500 };
0501
0502 static const struct fm10k_mac_ops mac_ops_vf = {
0503 .get_bus_info = fm10k_get_bus_info_generic,
0504 .reset_hw = fm10k_reset_hw_vf,
0505 .init_hw = fm10k_init_hw_vf,
0506 .start_hw = fm10k_start_hw_generic,
0507 .stop_hw = fm10k_stop_hw_vf,
0508 .update_vlan = fm10k_update_vlan_vf,
0509 .read_mac_addr = fm10k_read_mac_addr_vf,
0510 .update_uc_addr = fm10k_update_uc_addr_vf,
0511 .update_mc_addr = fm10k_update_mc_addr_vf,
0512 .update_xcast_mode = fm10k_update_xcast_mode_vf,
0513 .update_int_moderator = fm10k_update_int_moderator_vf,
0514 .update_lport_state = fm10k_update_lport_state_vf,
0515 .update_hw_stats = fm10k_update_hw_stats_vf,
0516 .rebind_hw_stats = fm10k_rebind_hw_stats_vf,
0517 .configure_dglort_map = fm10k_configure_dglort_map_vf,
0518 .get_host_state = fm10k_get_host_state_generic,
0519 };
0520
0521 static s32 fm10k_get_invariants_vf(struct fm10k_hw *hw)
0522 {
0523 fm10k_get_invariants_generic(hw);
0524
0525 return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);
0526 }
0527
0528 const struct fm10k_info fm10k_vf_info = {
0529 .mac = fm10k_mac_vf,
0530 .get_invariants = fm10k_get_invariants_vf,
0531 .mac_ops = &mac_ops_vf,
0532 };