0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <linux/ethtool.h>
0037 #include <linux/pci.h>
0038
0039 #include "t4vf_common.h"
0040 #include "t4vf_defs.h"
0041
0042 #include "../cxgb4/t4_regs.h"
0043 #include "../cxgb4/t4_values.h"
0044 #include "../cxgb4/t4fw_api.h"
0045
0046
0047
0048
0049
0050
0051 int t4vf_wait_dev_ready(struct adapter *adapter)
0052 {
0053 const u32 whoami = T4VF_PL_BASE_ADDR + PL_VF_WHOAMI;
0054 const u32 notready1 = 0xffffffff;
0055 const u32 notready2 = 0xeeeeeeee;
0056 u32 val;
0057
0058 val = t4_read_reg(adapter, whoami);
0059 if (val != notready1 && val != notready2)
0060 return 0;
0061 msleep(500);
0062 val = t4_read_reg(adapter, whoami);
0063 if (val != notready1 && val != notready2)
0064 return 0;
0065 else
0066 return -EIO;
0067 }
0068
0069
0070
0071
0072
0073 static void get_mbox_rpl(struct adapter *adapter, __be64 *rpl, int size,
0074 u32 mbox_data)
0075 {
0076 for ( ; size; size -= 8, mbox_data += 8)
0077 *rpl++ = cpu_to_be64(t4_read_reg64(adapter, mbox_data));
0078 }
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 static void t4vf_record_mbox(struct adapter *adapter, const __be64 *cmd,
0089 int size, int access, int execute)
0090 {
0091 struct mbox_cmd_log *log = adapter->mbox_log;
0092 struct mbox_cmd *entry;
0093 int i;
0094
0095 entry = mbox_cmd_log_entry(log, log->cursor++);
0096 if (log->cursor == log->size)
0097 log->cursor = 0;
0098
0099 for (i = 0; i < size / 8; i++)
0100 entry->cmd[i] = be64_to_cpu(cmd[i]);
0101 while (i < MBOX_LEN / 8)
0102 entry->cmd[i++] = 0;
0103 entry->timestamp = jiffies;
0104 entry->seqno = log->seqno++;
0105 entry->access = access;
0106 entry->execute = execute;
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size,
0130 void *rpl, bool sleep_ok)
0131 {
0132 static const int delay[] = {
0133 1, 1, 3, 5, 10, 10, 20, 50, 100
0134 };
0135
0136 u16 access = 0, execute = 0;
0137 u32 v, mbox_data;
0138 int i, ms, delay_idx, ret;
0139 const __be64 *p;
0140 u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL;
0141 u32 cmd_op = FW_CMD_OP_G(be32_to_cpu(((struct fw_cmd_hdr *)cmd)->hi));
0142 __be64 cmd_rpl[MBOX_LEN / 8];
0143 struct mbox_list entry;
0144
0145
0146
0147
0148 if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
0149 mbox_data = T4VF_MBDATA_BASE_ADDR;
0150 else
0151 mbox_data = T6VF_MBDATA_BASE_ADDR;
0152
0153
0154
0155
0156
0157 if ((size % 16) != 0 ||
0158 size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4)
0159 return -EINVAL;
0160
0161
0162
0163
0164
0165
0166 spin_lock(&adapter->mbox_lock);
0167 list_add_tail(&entry.list, &adapter->mlist.list);
0168 spin_unlock(&adapter->mbox_lock);
0169
0170 delay_idx = 0;
0171 ms = delay[0];
0172
0173 for (i = 0; ; i += ms) {
0174
0175
0176
0177
0178
0179 if (i > FW_CMD_MAX_TIMEOUT) {
0180 spin_lock(&adapter->mbox_lock);
0181 list_del(&entry.list);
0182 spin_unlock(&adapter->mbox_lock);
0183 ret = -EBUSY;
0184 t4vf_record_mbox(adapter, cmd, size, access, ret);
0185 return ret;
0186 }
0187
0188
0189
0190
0191 if (list_first_entry(&adapter->mlist.list, struct mbox_list,
0192 list) == &entry)
0193 break;
0194
0195
0196 if (sleep_ok) {
0197 ms = delay[delay_idx];
0198 if (delay_idx < ARRAY_SIZE(delay) - 1)
0199 delay_idx++;
0200 msleep(ms);
0201 } else {
0202 mdelay(ms);
0203 }
0204 }
0205
0206
0207
0208
0209
0210 v = MBOWNER_G(t4_read_reg(adapter, mbox_ctl));
0211 for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
0212 v = MBOWNER_G(t4_read_reg(adapter, mbox_ctl));
0213 if (v != MBOX_OWNER_DRV) {
0214 spin_lock(&adapter->mbox_lock);
0215 list_del(&entry.list);
0216 spin_unlock(&adapter->mbox_lock);
0217 ret = (v == MBOX_OWNER_FW) ? -EBUSY : -ETIMEDOUT;
0218 t4vf_record_mbox(adapter, cmd, size, access, ret);
0219 return ret;
0220 }
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 if (cmd_op != FW_VI_STATS_CMD)
0236 t4vf_record_mbox(adapter, cmd, size, access, 0);
0237 for (i = 0, p = cmd; i < size; i += 8)
0238 t4_write_reg64(adapter, mbox_data + i, be64_to_cpu(*p++));
0239 t4_read_reg(adapter, mbox_data);
0240
0241 t4_write_reg(adapter, mbox_ctl,
0242 MBMSGVALID_F | MBOWNER_V(MBOX_OWNER_FW));
0243 t4_read_reg(adapter, mbox_ctl);
0244
0245
0246
0247
0248 delay_idx = 0;
0249 ms = delay[0];
0250
0251 for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
0252 if (sleep_ok) {
0253 ms = delay[delay_idx];
0254 if (delay_idx < ARRAY_SIZE(delay) - 1)
0255 delay_idx++;
0256 msleep(ms);
0257 } else
0258 mdelay(ms);
0259
0260
0261
0262
0263 v = t4_read_reg(adapter, mbox_ctl);
0264 if (MBOWNER_G(v) == MBOX_OWNER_DRV) {
0265
0266
0267
0268
0269 if ((v & MBMSGVALID_F) == 0) {
0270 t4_write_reg(adapter, mbox_ctl,
0271 MBOWNER_V(MBOX_OWNER_NONE));
0272 continue;
0273 }
0274
0275
0276
0277
0278
0279
0280
0281
0282 get_mbox_rpl(adapter, cmd_rpl, size, mbox_data);
0283
0284
0285 v = be64_to_cpu(cmd_rpl[0]);
0286
0287 if (rpl) {
0288
0289 WARN_ON((be32_to_cpu(*(const __be32 *)cmd)
0290 & FW_CMD_REQUEST_F) == 0);
0291 memcpy(rpl, cmd_rpl, size);
0292 WARN_ON((be32_to_cpu(*(__be32 *)rpl)
0293 & FW_CMD_REQUEST_F) != 0);
0294 }
0295 t4_write_reg(adapter, mbox_ctl,
0296 MBOWNER_V(MBOX_OWNER_NONE));
0297 execute = i + ms;
0298 if (cmd_op != FW_VI_STATS_CMD)
0299 t4vf_record_mbox(adapter, cmd_rpl, size, access,
0300 execute);
0301 spin_lock(&adapter->mbox_lock);
0302 list_del(&entry.list);
0303 spin_unlock(&adapter->mbox_lock);
0304 return -FW_CMD_RETVAL_G(v);
0305 }
0306 }
0307
0308
0309 ret = -ETIMEDOUT;
0310 t4vf_record_mbox(adapter, cmd, size, access, ret);
0311 spin_lock(&adapter->mbox_lock);
0312 list_del(&entry.list);
0313 spin_unlock(&adapter->mbox_lock);
0314 return ret;
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324 #define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
0325 FW_PORT_CAP32_802_3_PAUSE | \
0326 FW_PORT_CAP32_802_3_ASM_DIR | \
0327 FW_PORT_CAP32_FEC_V(FW_PORT_CAP32_FEC_M) | \
0328 FW_PORT_CAP32_ANEG)
0329
0330
0331
0332
0333
0334
0335
0336 static fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
0337 {
0338 fw_port_cap32_t caps32 = 0;
0339
0340 #define CAP16_TO_CAP32(__cap) \
0341 do { \
0342 if (caps16 & FW_PORT_CAP_##__cap) \
0343 caps32 |= FW_PORT_CAP32_##__cap; \
0344 } while (0)
0345
0346 CAP16_TO_CAP32(SPEED_100M);
0347 CAP16_TO_CAP32(SPEED_1G);
0348 CAP16_TO_CAP32(SPEED_25G);
0349 CAP16_TO_CAP32(SPEED_10G);
0350 CAP16_TO_CAP32(SPEED_40G);
0351 CAP16_TO_CAP32(SPEED_100G);
0352 CAP16_TO_CAP32(FC_RX);
0353 CAP16_TO_CAP32(FC_TX);
0354 CAP16_TO_CAP32(ANEG);
0355 CAP16_TO_CAP32(MDIAUTO);
0356 CAP16_TO_CAP32(MDISTRAIGHT);
0357 CAP16_TO_CAP32(FEC_RS);
0358 CAP16_TO_CAP32(FEC_BASER_RS);
0359 CAP16_TO_CAP32(802_3_PAUSE);
0360 CAP16_TO_CAP32(802_3_ASM_DIR);
0361
0362 #undef CAP16_TO_CAP32
0363
0364 return caps32;
0365 }
0366
0367
0368 static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
0369 {
0370 enum cc_pause cc_pause = 0;
0371
0372 if (fw_pause & FW_PORT_CAP32_FC_RX)
0373 cc_pause |= PAUSE_RX;
0374 if (fw_pause & FW_PORT_CAP32_FC_TX)
0375 cc_pause |= PAUSE_TX;
0376
0377 return cc_pause;
0378 }
0379
0380
0381 static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
0382 {
0383 enum cc_fec cc_fec = 0;
0384
0385 if (fw_fec & FW_PORT_CAP32_FEC_RS)
0386 cc_fec |= FEC_RS;
0387 if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
0388 cc_fec |= FEC_BASER_RS;
0389
0390 return cc_fec;
0391 }
0392
0393
0394 static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
0395 {
0396 #define TEST_SPEED_RETURN(__caps_speed, __speed) \
0397 do { \
0398 if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \
0399 return __speed; \
0400 } while (0)
0401
0402 TEST_SPEED_RETURN(400G, 400000);
0403 TEST_SPEED_RETURN(200G, 200000);
0404 TEST_SPEED_RETURN(100G, 100000);
0405 TEST_SPEED_RETURN(50G, 50000);
0406 TEST_SPEED_RETURN(40G, 40000);
0407 TEST_SPEED_RETURN(25G, 25000);
0408 TEST_SPEED_RETURN(10G, 10000);
0409 TEST_SPEED_RETURN(1G, 1000);
0410 TEST_SPEED_RETURN(100M, 100);
0411
0412 #undef TEST_SPEED_RETURN
0413
0414 return 0;
0415 }
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 static fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps)
0426 {
0427 #define TEST_SPEED_RETURN(__caps_speed) \
0428 do { \
0429 if (acaps & FW_PORT_CAP32_SPEED_##__caps_speed) \
0430 return FW_PORT_CAP32_SPEED_##__caps_speed; \
0431 } while (0)
0432
0433 TEST_SPEED_RETURN(400G);
0434 TEST_SPEED_RETURN(200G);
0435 TEST_SPEED_RETURN(100G);
0436 TEST_SPEED_RETURN(50G);
0437 TEST_SPEED_RETURN(40G);
0438 TEST_SPEED_RETURN(25G);
0439 TEST_SPEED_RETURN(10G);
0440 TEST_SPEED_RETURN(1G);
0441 TEST_SPEED_RETURN(100M);
0442
0443 #undef TEST_SPEED_RETURN
0444 return 0;
0445 }
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 static void init_link_config(struct link_config *lc,
0457 fw_port_cap32_t pcaps,
0458 fw_port_cap32_t acaps)
0459 {
0460 lc->pcaps = pcaps;
0461 lc->lpacaps = 0;
0462 lc->speed_caps = 0;
0463 lc->speed = 0;
0464 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
0465
0466
0467
0468
0469 lc->auto_fec = fwcap_to_cc_fec(acaps);
0470 lc->requested_fec = FEC_AUTO;
0471 lc->fec = lc->auto_fec;
0472
0473
0474
0475
0476
0477
0478
0479
0480 if (lc->pcaps & FW_PORT_CAP32_ANEG) {
0481 lc->acaps = acaps & ADVERT_MASK;
0482 lc->autoneg = AUTONEG_ENABLE;
0483 lc->requested_fc |= PAUSE_AUTONEG;
0484 } else {
0485 lc->acaps = 0;
0486 lc->autoneg = AUTONEG_DISABLE;
0487 lc->speed_caps = fwcap_to_fwspeed(acaps);
0488 }
0489 }
0490
0491
0492
0493
0494
0495
0496 int t4vf_port_init(struct adapter *adapter, int pidx)
0497 {
0498 struct port_info *pi = adap2pinfo(adapter, pidx);
0499 unsigned int fw_caps = adapter->params.fw_caps_support;
0500 struct fw_vi_cmd vi_cmd, vi_rpl;
0501 struct fw_port_cmd port_cmd, port_rpl;
0502 enum fw_port_type port_type;
0503 int mdio_addr;
0504 fw_port_cap32_t pcaps, acaps;
0505 int ret;
0506
0507
0508
0509
0510
0511
0512
0513 if (fw_caps == FW_CAPS_UNKNOWN) {
0514 u32 param, val;
0515
0516 param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) |
0517 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
0518 val = 1;
0519 ret = t4vf_set_params(adapter, 1, ¶m, &val);
0520 fw_caps = (ret == 0 ? FW_CAPS32 : FW_CAPS16);
0521 adapter->params.fw_caps_support = fw_caps;
0522 }
0523
0524
0525
0526
0527
0528 memset(&vi_cmd, 0, sizeof(vi_cmd));
0529 vi_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) |
0530 FW_CMD_REQUEST_F |
0531 FW_CMD_READ_F);
0532 vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd));
0533 vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(pi->viid));
0534 ret = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl);
0535 if (ret != FW_SUCCESS)
0536 return ret;
0537
0538 BUG_ON(pi->port_id != FW_VI_CMD_PORTID_G(vi_rpl.portid_pkd));
0539 pi->rss_size = FW_VI_CMD_RSSSIZE_G(be16_to_cpu(vi_rpl.rsssize_pkd));
0540 t4_os_set_hw_addr(adapter, pidx, vi_rpl.mac);
0541
0542
0543
0544
0545
0546 if (!(adapter->params.vfres.r_caps & FW_CMD_CAP_PORT))
0547 return 0;
0548
0549 memset(&port_cmd, 0, sizeof(port_cmd));
0550 port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
0551 FW_CMD_REQUEST_F |
0552 FW_CMD_READ_F |
0553 FW_PORT_CMD_PORTID_V(pi->port_id));
0554 port_cmd.action_to_len16 = cpu_to_be32(
0555 FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
0556 ? FW_PORT_ACTION_GET_PORT_INFO
0557 : FW_PORT_ACTION_GET_PORT_INFO32) |
0558 FW_LEN16(port_cmd));
0559 ret = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), &port_rpl);
0560 if (ret != FW_SUCCESS)
0561 return ret;
0562
0563
0564 if (fw_caps == FW_CAPS16) {
0565 u32 lstatus = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype);
0566
0567 port_type = FW_PORT_CMD_PTYPE_G(lstatus);
0568 mdio_addr = ((lstatus & FW_PORT_CMD_MDIOCAP_F)
0569 ? FW_PORT_CMD_MDIOADDR_G(lstatus)
0570 : -1);
0571 pcaps = fwcaps16_to_caps32(be16_to_cpu(port_rpl.u.info.pcap));
0572 acaps = fwcaps16_to_caps32(be16_to_cpu(port_rpl.u.info.acap));
0573 } else {
0574 u32 lstatus32 =
0575 be32_to_cpu(port_rpl.u.info32.lstatus32_to_cbllen32);
0576
0577 port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
0578 mdio_addr = ((lstatus32 & FW_PORT_CMD_MDIOCAP32_F)
0579 ? FW_PORT_CMD_MDIOADDR32_G(lstatus32)
0580 : -1);
0581 pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
0582 acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
0583 }
0584
0585 pi->port_type = port_type;
0586 pi->mdio_addr = mdio_addr;
0587 pi->mod_type = FW_PORT_MOD_TYPE_NA;
0588
0589 init_link_config(&pi->link_cfg, pcaps, acaps);
0590 return 0;
0591 }
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601 int t4vf_fw_reset(struct adapter *adapter)
0602 {
0603 struct fw_reset_cmd cmd;
0604
0605 memset(&cmd, 0, sizeof(cmd));
0606 cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_RESET_CMD) |
0607 FW_CMD_WRITE_F);
0608 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
0609 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
0610 }
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622 static int t4vf_query_params(struct adapter *adapter, unsigned int nparams,
0623 const u32 *params, u32 *vals)
0624 {
0625 int i, ret;
0626 struct fw_params_cmd cmd, rpl;
0627 struct fw_params_param *p;
0628 size_t len16;
0629
0630 if (nparams > 7)
0631 return -EINVAL;
0632
0633 memset(&cmd, 0, sizeof(cmd));
0634 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
0635 FW_CMD_REQUEST_F |
0636 FW_CMD_READ_F);
0637 len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
0638 param[nparams].mnem), 16);
0639 cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16));
0640 for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++)
0641 p->mnem = htonl(*params++);
0642
0643 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
0644 if (ret == 0)
0645 for (i = 0, p = &rpl.param[0]; i < nparams; i++, p++)
0646 *vals++ = be32_to_cpu(p->val);
0647 return ret;
0648 }
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660 int t4vf_set_params(struct adapter *adapter, unsigned int nparams,
0661 const u32 *params, const u32 *vals)
0662 {
0663 int i;
0664 struct fw_params_cmd cmd;
0665 struct fw_params_param *p;
0666 size_t len16;
0667
0668 if (nparams > 7)
0669 return -EINVAL;
0670
0671 memset(&cmd, 0, sizeof(cmd));
0672 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
0673 FW_CMD_REQUEST_F |
0674 FW_CMD_WRITE_F);
0675 len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
0676 param[nparams]), 16);
0677 cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16));
0678 for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) {
0679 p->mnem = cpu_to_be32(*params++);
0680 p->val = cpu_to_be32(*vals++);
0681 }
0682
0683 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
0684 }
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697 int t4vf_fl_pkt_align(struct adapter *adapter)
0698 {
0699 u32 sge_control, sge_control2;
0700 unsigned int ingpadboundary, ingpackboundary, fl_align, ingpad_shift;
0701
0702 sge_control = adapter->params.sge.sge_control;
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716 if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
0717 ingpad_shift = INGPADBOUNDARY_SHIFT_X;
0718 else
0719 ingpad_shift = T6_INGPADBOUNDARY_SHIFT_X;
0720
0721 ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_control) + ingpad_shift);
0722
0723 fl_align = ingpadboundary;
0724 if (!is_t4(adapter->params.chip)) {
0725
0726
0727
0728 sge_control2 = adapter->params.sge.sge_control2;
0729 ingpackboundary = INGPACKBOUNDARY_G(sge_control2);
0730 if (ingpackboundary == INGPACKBOUNDARY_16B_X)
0731 ingpackboundary = 16;
0732 else
0733 ingpackboundary = 1 << (ingpackboundary +
0734 INGPACKBOUNDARY_SHIFT_X);
0735
0736 fl_align = max(ingpadboundary, ingpackboundary);
0737 }
0738 return fl_align;
0739 }
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766 int t4vf_bar2_sge_qregs(struct adapter *adapter,
0767 unsigned int qid,
0768 enum t4_bar2_qtype qtype,
0769 u64 *pbar2_qoffset,
0770 unsigned int *pbar2_qid)
0771 {
0772 unsigned int page_shift, page_size, qpp_shift, qpp_mask;
0773 u64 bar2_page_offset, bar2_qoffset;
0774 unsigned int bar2_qid, bar2_qid_offset, bar2_qinferred;
0775
0776
0777
0778 if (is_t4(adapter->params.chip))
0779 return -EINVAL;
0780
0781
0782
0783 page_shift = adapter->params.sge.sge_vf_hps + 10;
0784 page_size = 1 << page_shift;
0785
0786
0787
0788 qpp_shift = (qtype == T4_BAR2_QTYPE_EGRESS
0789 ? adapter->params.sge.sge_vf_eq_qpp
0790 : adapter->params.sge.sge_vf_iq_qpp);
0791 qpp_mask = (1 << qpp_shift) - 1;
0792
0793
0794
0795
0796
0797
0798 bar2_page_offset = ((u64)(qid >> qpp_shift) << page_shift);
0799 bar2_qid = qid & qpp_mask;
0800 bar2_qid_offset = bar2_qid * SGE_UDB_SIZE;
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818 bar2_qoffset = bar2_page_offset;
0819 bar2_qinferred = (bar2_qid_offset < page_size);
0820 if (bar2_qinferred) {
0821 bar2_qoffset += bar2_qid_offset;
0822 bar2_qid = 0;
0823 }
0824
0825 *pbar2_qoffset = bar2_qoffset;
0826 *pbar2_qid = bar2_qid;
0827 return 0;
0828 }
0829
0830 unsigned int t4vf_get_pf_from_vf(struct adapter *adapter)
0831 {
0832 u32 whoami;
0833
0834 whoami = t4_read_reg(adapter, T4VF_PL_BASE_ADDR + PL_VF_WHOAMI_A);
0835 return (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
0836 SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami));
0837 }
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847 int t4vf_get_sge_params(struct adapter *adapter)
0848 {
0849 struct sge_params *sge_params = &adapter->params.sge;
0850 u32 params[7], vals[7];
0851 int v;
0852
0853 params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0854 FW_PARAMS_PARAM_XYZ_V(SGE_CONTROL_A));
0855 params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0856 FW_PARAMS_PARAM_XYZ_V(SGE_HOST_PAGE_SIZE_A));
0857 params[2] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0858 FW_PARAMS_PARAM_XYZ_V(SGE_FL_BUFFER_SIZE0_A));
0859 params[3] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0860 FW_PARAMS_PARAM_XYZ_V(SGE_FL_BUFFER_SIZE1_A));
0861 params[4] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0862 FW_PARAMS_PARAM_XYZ_V(SGE_TIMER_VALUE_0_AND_1_A));
0863 params[5] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0864 FW_PARAMS_PARAM_XYZ_V(SGE_TIMER_VALUE_2_AND_3_A));
0865 params[6] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0866 FW_PARAMS_PARAM_XYZ_V(SGE_TIMER_VALUE_4_AND_5_A));
0867 v = t4vf_query_params(adapter, 7, params, vals);
0868 if (v)
0869 return v;
0870 sge_params->sge_control = vals[0];
0871 sge_params->sge_host_page_size = vals[1];
0872 sge_params->sge_fl_buffer_size[0] = vals[2];
0873 sge_params->sge_fl_buffer_size[1] = vals[3];
0874 sge_params->sge_timer_value_0_and_1 = vals[4];
0875 sge_params->sge_timer_value_2_and_3 = vals[5];
0876 sge_params->sge_timer_value_4_and_5 = vals[6];
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
0888 if (!is_t4(adapter->params.chip)) {
0889 params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0890 FW_PARAMS_PARAM_XYZ_V(SGE_CONTROL2_A));
0891 v = t4vf_query_params(adapter, 1, params, vals);
0892 if (v != FW_SUCCESS) {
0893 dev_err(adapter->pdev_dev,
0894 "Unable to get SGE Control2; "
0895 "probably old firmware.\n");
0896 return v;
0897 }
0898 sge_params->sge_control2 = vals[0];
0899 }
0900
0901 params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0902 FW_PARAMS_PARAM_XYZ_V(SGE_INGRESS_RX_THRESHOLD_A));
0903 params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0904 FW_PARAMS_PARAM_XYZ_V(SGE_CONM_CTRL_A));
0905 v = t4vf_query_params(adapter, 2, params, vals);
0906 if (v)
0907 return v;
0908 sge_params->sge_ingress_rx_threshold = vals[0];
0909 sge_params->sge_congestion_control = vals[1];
0910
0911
0912
0913
0914
0915 if (!is_t4(adapter->params.chip)) {
0916 unsigned int pf, s_hps, s_qpp;
0917
0918 params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0919 FW_PARAMS_PARAM_XYZ_V(
0920 SGE_EGRESS_QUEUES_PER_PAGE_VF_A));
0921 params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
0922 FW_PARAMS_PARAM_XYZ_V(
0923 SGE_INGRESS_QUEUES_PER_PAGE_VF_A));
0924 v = t4vf_query_params(adapter, 2, params, vals);
0925 if (v != FW_SUCCESS) {
0926 dev_warn(adapter->pdev_dev,
0927 "Unable to get VF SGE Queues/Page; "
0928 "probably old firmware.\n");
0929 return v;
0930 }
0931 sge_params->sge_egress_queues_per_page = vals[0];
0932 sge_params->sge_ingress_queues_per_page = vals[1];
0933
0934
0935
0936
0937
0938
0939 pf = t4vf_get_pf_from_vf(adapter);
0940 s_hps = (HOSTPAGESIZEPF0_S +
0941 (HOSTPAGESIZEPF1_S - HOSTPAGESIZEPF0_S) * pf);
0942 sge_params->sge_vf_hps =
0943 ((sge_params->sge_host_page_size >> s_hps)
0944 & HOSTPAGESIZEPF0_M);
0945
0946 s_qpp = (QUEUESPERPAGEPF0_S +
0947 (QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S) * pf);
0948 sge_params->sge_vf_eq_qpp =
0949 ((sge_params->sge_egress_queues_per_page >> s_qpp)
0950 & QUEUESPERPAGEPF0_M);
0951 sge_params->sge_vf_iq_qpp =
0952 ((sge_params->sge_ingress_queues_per_page >> s_qpp)
0953 & QUEUESPERPAGEPF0_M);
0954 }
0955
0956 return 0;
0957 }
0958
0959
0960
0961
0962
0963
0964
0965
0966 int t4vf_get_vpd_params(struct adapter *adapter)
0967 {
0968 struct vpd_params *vpd_params = &adapter->params.vpd;
0969 u32 params[7], vals[7];
0970 int v;
0971
0972 params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
0973 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK));
0974 v = t4vf_query_params(adapter, 1, params, vals);
0975 if (v)
0976 return v;
0977 vpd_params->cclk = vals[0];
0978
0979 return 0;
0980 }
0981
0982
0983
0984
0985
0986
0987
0988
0989 int t4vf_get_dev_params(struct adapter *adapter)
0990 {
0991 struct dev_params *dev_params = &adapter->params.dev;
0992 u32 params[7], vals[7];
0993 int v;
0994
0995 params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
0996 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FWREV));
0997 params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
0998 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_TPREV));
0999 v = t4vf_query_params(adapter, 2, params, vals);
1000 if (v)
1001 return v;
1002 dev_params->fwrev = vals[0];
1003 dev_params->tprev = vals[1];
1004
1005 return 0;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014
1015 int t4vf_get_rss_glb_config(struct adapter *adapter)
1016 {
1017 struct rss_params *rss = &adapter->params.rss;
1018 struct fw_rss_glb_config_cmd cmd, rpl;
1019 int v;
1020
1021
1022
1023
1024
1025 memset(&cmd, 0, sizeof(cmd));
1026 cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_RSS_GLB_CONFIG_CMD) |
1027 FW_CMD_REQUEST_F |
1028 FW_CMD_READ_F);
1029 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
1030 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1031 if (v)
1032 return v;
1033
1034
1035
1036
1037
1038
1039
1040 rss->mode = FW_RSS_GLB_CONFIG_CMD_MODE_G(
1041 be32_to_cpu(rpl.u.manual.mode_pkd));
1042 switch (rss->mode) {
1043 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
1044 u32 word = be32_to_cpu(
1045 rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
1046
1047 rss->u.basicvirtual.synmapen =
1048 ((word & FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_F) != 0);
1049 rss->u.basicvirtual.syn4tupenipv6 =
1050 ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_F) != 0);
1051 rss->u.basicvirtual.syn2tupenipv6 =
1052 ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_F) != 0);
1053 rss->u.basicvirtual.syn4tupenipv4 =
1054 ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_F) != 0);
1055 rss->u.basicvirtual.syn2tupenipv4 =
1056 ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_F) != 0);
1057
1058 rss->u.basicvirtual.ofdmapen =
1059 ((word & FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_F) != 0);
1060
1061 rss->u.basicvirtual.tnlmapen =
1062 ((word & FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_F) != 0);
1063 rss->u.basicvirtual.tnlalllookup =
1064 ((word & FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_F) != 0);
1065
1066 rss->u.basicvirtual.hashtoeplitz =
1067 ((word & FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_F) != 0);
1068
1069
1070 if (!rss->u.basicvirtual.tnlmapen)
1071 return -EINVAL;
1072 break;
1073 }
1074
1075 default:
1076
1077 return -EINVAL;
1078 }
1079
1080 return 0;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090 int t4vf_get_vfres(struct adapter *adapter)
1091 {
1092 struct vf_resources *vfres = &adapter->params.vfres;
1093 struct fw_pfvf_cmd cmd, rpl;
1094 int v;
1095 u32 word;
1096
1097
1098
1099
1100
1101 memset(&cmd, 0, sizeof(cmd));
1102 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) |
1103 FW_CMD_REQUEST_F |
1104 FW_CMD_READ_F);
1105 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
1106 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1107 if (v)
1108 return v;
1109
1110
1111
1112
1113 word = be32_to_cpu(rpl.niqflint_niq);
1114 vfres->niqflint = FW_PFVF_CMD_NIQFLINT_G(word);
1115 vfres->niq = FW_PFVF_CMD_NIQ_G(word);
1116
1117 word = be32_to_cpu(rpl.type_to_neq);
1118 vfres->neq = FW_PFVF_CMD_NEQ_G(word);
1119 vfres->pmask = FW_PFVF_CMD_PMASK_G(word);
1120
1121 word = be32_to_cpu(rpl.tc_to_nexactf);
1122 vfres->tc = FW_PFVF_CMD_TC_G(word);
1123 vfres->nvi = FW_PFVF_CMD_NVI_G(word);
1124 vfres->nexactf = FW_PFVF_CMD_NEXACTF_G(word);
1125
1126 word = be32_to_cpu(rpl.r_caps_to_nethctrl);
1127 vfres->r_caps = FW_PFVF_CMD_R_CAPS_G(word);
1128 vfres->wx_caps = FW_PFVF_CMD_WX_CAPS_G(word);
1129 vfres->nethctrl = FW_PFVF_CMD_NETHCTRL_G(word);
1130
1131 return 0;
1132 }
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 int t4vf_read_rss_vi_config(struct adapter *adapter, unsigned int viid,
1144 union rss_vi_config *config)
1145 {
1146 struct fw_rss_vi_config_cmd cmd, rpl;
1147 int v;
1148
1149 memset(&cmd, 0, sizeof(cmd));
1150 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
1151 FW_CMD_REQUEST_F |
1152 FW_CMD_READ_F |
1153 FW_RSS_VI_CONFIG_CMD_VIID(viid));
1154 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
1155 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1156 if (v)
1157 return v;
1158
1159 switch (adapter->params.rss.mode) {
1160 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
1161 u32 word = be32_to_cpu(rpl.u.basicvirtual.defaultq_to_udpen);
1162
1163 config->basicvirtual.ip6fourtupen =
1164 ((word & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) != 0);
1165 config->basicvirtual.ip6twotupen =
1166 ((word & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) != 0);
1167 config->basicvirtual.ip4fourtupen =
1168 ((word & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) != 0);
1169 config->basicvirtual.ip4twotupen =
1170 ((word & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) != 0);
1171 config->basicvirtual.udpen =
1172 ((word & FW_RSS_VI_CONFIG_CMD_UDPEN_F) != 0);
1173 config->basicvirtual.defaultq =
1174 FW_RSS_VI_CONFIG_CMD_DEFAULTQ_G(word);
1175 break;
1176 }
1177
1178 default:
1179 return -EINVAL;
1180 }
1181
1182 return 0;
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194 int t4vf_write_rss_vi_config(struct adapter *adapter, unsigned int viid,
1195 union rss_vi_config *config)
1196 {
1197 struct fw_rss_vi_config_cmd cmd, rpl;
1198
1199 memset(&cmd, 0, sizeof(cmd));
1200 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
1201 FW_CMD_REQUEST_F |
1202 FW_CMD_WRITE_F |
1203 FW_RSS_VI_CONFIG_CMD_VIID(viid));
1204 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
1205 switch (adapter->params.rss.mode) {
1206 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
1207 u32 word = 0;
1208
1209 if (config->basicvirtual.ip6fourtupen)
1210 word |= FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F;
1211 if (config->basicvirtual.ip6twotupen)
1212 word |= FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F;
1213 if (config->basicvirtual.ip4fourtupen)
1214 word |= FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F;
1215 if (config->basicvirtual.ip4twotupen)
1216 word |= FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F;
1217 if (config->basicvirtual.udpen)
1218 word |= FW_RSS_VI_CONFIG_CMD_UDPEN_F;
1219 word |= FW_RSS_VI_CONFIG_CMD_DEFAULTQ_V(
1220 config->basicvirtual.defaultq);
1221 cmd.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(word);
1222 break;
1223 }
1224
1225 default:
1226 return -EINVAL;
1227 }
1228
1229 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247 int t4vf_config_rss_range(struct adapter *adapter, unsigned int viid,
1248 int start, int n, const u16 *rspq, int nrspq)
1249 {
1250 const u16 *rsp = rspq;
1251 const u16 *rsp_end = rspq+nrspq;
1252 struct fw_rss_ind_tbl_cmd cmd;
1253
1254
1255
1256
1257 memset(&cmd, 0, sizeof(cmd));
1258 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) |
1259 FW_CMD_REQUEST_F |
1260 FW_CMD_WRITE_F |
1261 FW_RSS_IND_TBL_CMD_VIID_V(viid));
1262 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
1263
1264
1265
1266
1267
1268
1269
1270 while (n > 0) {
1271 __be32 *qp = &cmd.iq0_to_iq2;
1272 int nq = min(n, 32);
1273 int ret;
1274
1275
1276
1277
1278
1279 cmd.niqid = cpu_to_be16(nq);
1280 cmd.startidx = cpu_to_be16(start);
1281
1282
1283
1284
1285 start += nq;
1286 n -= nq;
1287
1288
1289
1290
1291
1292
1293 while (nq > 0) {
1294
1295
1296
1297
1298
1299
1300 u16 qbuf[3];
1301 u16 *qbp = qbuf;
1302 int nqbuf = min(3, nq);
1303
1304 nq -= nqbuf;
1305 qbuf[0] = qbuf[1] = qbuf[2] = 0;
1306 while (nqbuf) {
1307 nqbuf--;
1308 *qbp++ = *rsp++;
1309 if (rsp >= rsp_end)
1310 rsp = rspq;
1311 }
1312 *qp++ = cpu_to_be32(FW_RSS_IND_TBL_CMD_IQ0_V(qbuf[0]) |
1313 FW_RSS_IND_TBL_CMD_IQ1_V(qbuf[1]) |
1314 FW_RSS_IND_TBL_CMD_IQ2_V(qbuf[2]));
1315 }
1316
1317
1318
1319
1320
1321 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1322 if (ret)
1323 return ret;
1324 }
1325 return 0;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337 int t4vf_alloc_vi(struct adapter *adapter, int port_id)
1338 {
1339 struct fw_vi_cmd cmd, rpl;
1340 int v;
1341
1342
1343
1344
1345
1346 memset(&cmd, 0, sizeof(cmd));
1347 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) |
1348 FW_CMD_REQUEST_F |
1349 FW_CMD_WRITE_F |
1350 FW_CMD_EXEC_F);
1351 cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
1352 FW_VI_CMD_ALLOC_F);
1353 cmd.portid_pkd = FW_VI_CMD_PORTID_V(port_id);
1354 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1355 if (v)
1356 return v;
1357
1358 return FW_VI_CMD_VIID_G(be16_to_cpu(rpl.type_viid));
1359 }
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369 int t4vf_free_vi(struct adapter *adapter, int viid)
1370 {
1371 struct fw_vi_cmd cmd;
1372
1373
1374
1375
1376 memset(&cmd, 0, sizeof(cmd));
1377 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) |
1378 FW_CMD_REQUEST_F |
1379 FW_CMD_EXEC_F);
1380 cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
1381 FW_VI_CMD_FREE_F);
1382 cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(viid));
1383 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1384 }
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395 int t4vf_enable_vi(struct adapter *adapter, unsigned int viid,
1396 bool rx_en, bool tx_en)
1397 {
1398 struct fw_vi_enable_cmd cmd;
1399
1400 memset(&cmd, 0, sizeof(cmd));
1401 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) |
1402 FW_CMD_REQUEST_F |
1403 FW_CMD_EXEC_F |
1404 FW_VI_ENABLE_CMD_VIID_V(viid));
1405 cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN_V(rx_en) |
1406 FW_VI_ENABLE_CMD_EEN_V(tx_en) |
1407 FW_LEN16(cmd));
1408 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1409 }
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423 int t4vf_enable_pi(struct adapter *adapter, struct port_info *pi,
1424 bool rx_en, bool tx_en)
1425 {
1426 int ret = t4vf_enable_vi(adapter, pi->viid, rx_en, tx_en);
1427
1428 if (ret)
1429 return ret;
1430 t4vf_os_link_changed(adapter, pi->pidx,
1431 rx_en && tx_en && pi->link_cfg.link_ok);
1432 return 0;
1433 }
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443 int t4vf_identify_port(struct adapter *adapter, unsigned int viid,
1444 unsigned int nblinks)
1445 {
1446 struct fw_vi_enable_cmd cmd;
1447
1448 memset(&cmd, 0, sizeof(cmd));
1449 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) |
1450 FW_CMD_REQUEST_F |
1451 FW_CMD_EXEC_F |
1452 FW_VI_ENABLE_CMD_VIID_V(viid));
1453 cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED_F |
1454 FW_LEN16(cmd));
1455 cmd.blinkdur = cpu_to_be16(nblinks);
1456 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1457 }
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473 int t4vf_set_rxmode(struct adapter *adapter, unsigned int viid,
1474 int mtu, int promisc, int all_multi, int bcast, int vlanex,
1475 bool sleep_ok)
1476 {
1477 struct fw_vi_rxmode_cmd cmd;
1478
1479
1480 if (mtu < 0)
1481 mtu = FW_VI_RXMODE_CMD_MTU_M;
1482 if (promisc < 0)
1483 promisc = FW_VI_RXMODE_CMD_PROMISCEN_M;
1484 if (all_multi < 0)
1485 all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_M;
1486 if (bcast < 0)
1487 bcast = FW_VI_RXMODE_CMD_BROADCASTEN_M;
1488 if (vlanex < 0)
1489 vlanex = FW_VI_RXMODE_CMD_VLANEXEN_M;
1490
1491 memset(&cmd, 0, sizeof(cmd));
1492 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) |
1493 FW_CMD_REQUEST_F |
1494 FW_CMD_WRITE_F |
1495 FW_VI_RXMODE_CMD_VIID_V(viid));
1496 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
1497 cmd.mtu_to_vlanexen =
1498 cpu_to_be32(FW_VI_RXMODE_CMD_MTU_V(mtu) |
1499 FW_VI_RXMODE_CMD_PROMISCEN_V(promisc) |
1500 FW_VI_RXMODE_CMD_ALLMULTIEN_V(all_multi) |
1501 FW_VI_RXMODE_CMD_BROADCASTEN_V(bcast) |
1502 FW_VI_RXMODE_CMD_VLANEXEN_V(vlanex));
1503 return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok);
1504 }
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527 int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
1528 unsigned int naddr, const u8 **addr, u16 *idx,
1529 u64 *hash, bool sleep_ok)
1530 {
1531 int offset, ret = 0;
1532 unsigned nfilters = 0;
1533 unsigned int rem = naddr;
1534 struct fw_vi_mac_cmd cmd, rpl;
1535 unsigned int max_naddr = adapter->params.arch.mps_tcam_size;
1536
1537 if (naddr > max_naddr)
1538 return -EINVAL;
1539
1540 for (offset = 0; offset < naddr; ) {
1541 unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
1542 ? rem
1543 : ARRAY_SIZE(cmd.u.exact));
1544 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1545 u.exact[fw_naddr]), 16);
1546 struct fw_vi_mac_exact *p;
1547 int i;
1548
1549 memset(&cmd, 0, sizeof(cmd));
1550 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
1551 FW_CMD_REQUEST_F |
1552 FW_CMD_WRITE_F |
1553 (free ? FW_CMD_EXEC_F : 0) |
1554 FW_VI_MAC_CMD_VIID_V(viid));
1555 cmd.freemacs_to_len16 =
1556 cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(free) |
1557 FW_CMD_LEN16_V(len16));
1558
1559 for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
1560 p->valid_to_idx = cpu_to_be16(
1561 FW_VI_MAC_CMD_VALID_F |
1562 FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_ADD_MAC));
1563 memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
1564 }
1565
1566
1567 ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
1568 sleep_ok);
1569 if (ret && ret != -ENOMEM)
1570 break;
1571
1572 for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
1573 u16 index = FW_VI_MAC_CMD_IDX_G(
1574 be16_to_cpu(p->valid_to_idx));
1575
1576 if (idx)
1577 idx[offset+i] =
1578 (index >= max_naddr
1579 ? 0xffff
1580 : index);
1581 if (index < max_naddr)
1582 nfilters++;
1583 else if (hash)
1584 *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
1585 }
1586
1587 free = false;
1588 offset += fw_naddr;
1589 rem -= fw_naddr;
1590 }
1591
1592
1593
1594
1595
1596 if (ret == 0 || ret == -ENOMEM)
1597 ret = nfilters;
1598 return ret;
1599 }
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613 int t4vf_free_mac_filt(struct adapter *adapter, unsigned int viid,
1614 unsigned int naddr, const u8 **addr, bool sleep_ok)
1615 {
1616 int offset, ret = 0;
1617 struct fw_vi_mac_cmd cmd;
1618 unsigned int nfilters = 0;
1619 unsigned int max_naddr = adapter->params.arch.mps_tcam_size;
1620 unsigned int rem = naddr;
1621
1622 if (naddr > max_naddr)
1623 return -EINVAL;
1624
1625 for (offset = 0; offset < (int)naddr ; ) {
1626 unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact) ?
1627 rem : ARRAY_SIZE(cmd.u.exact));
1628 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1629 u.exact[fw_naddr]), 16);
1630 struct fw_vi_mac_exact *p;
1631 int i;
1632
1633 memset(&cmd, 0, sizeof(cmd));
1634 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
1635 FW_CMD_REQUEST_F |
1636 FW_CMD_WRITE_F |
1637 FW_CMD_EXEC_V(0) |
1638 FW_VI_MAC_CMD_VIID_V(viid));
1639 cmd.freemacs_to_len16 =
1640 cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(0) |
1641 FW_CMD_LEN16_V(len16));
1642
1643 for (i = 0, p = cmd.u.exact; i < (int)fw_naddr; i++, p++) {
1644 p->valid_to_idx = cpu_to_be16(
1645 FW_VI_MAC_CMD_VALID_F |
1646 FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_MAC_BASED_FREE));
1647 memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
1648 }
1649
1650 ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &cmd,
1651 sleep_ok);
1652 if (ret)
1653 break;
1654
1655 for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
1656 u16 index = FW_VI_MAC_CMD_IDX_G(
1657 be16_to_cpu(p->valid_to_idx));
1658
1659 if (index < max_naddr)
1660 nfilters++;
1661 }
1662
1663 offset += fw_naddr;
1664 rem -= fw_naddr;
1665 }
1666
1667 if (ret == 0)
1668 ret = nfilters;
1669 return ret;
1670 }
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690 int t4vf_change_mac(struct adapter *adapter, unsigned int viid,
1691 int idx, const u8 *addr, bool persist)
1692 {
1693 int ret;
1694 struct fw_vi_mac_cmd cmd, rpl;
1695 struct fw_vi_mac_exact *p = &cmd.u.exact[0];
1696 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1697 u.exact[1]), 16);
1698 unsigned int max_mac_addr = adapter->params.arch.mps_tcam_size;
1699
1700
1701
1702
1703
1704 if (idx < 0)
1705 idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
1706
1707 memset(&cmd, 0, sizeof(cmd));
1708 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
1709 FW_CMD_REQUEST_F |
1710 FW_CMD_WRITE_F |
1711 FW_VI_MAC_CMD_VIID_V(viid));
1712 cmd.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16));
1713 p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
1714 FW_VI_MAC_CMD_IDX_V(idx));
1715 memcpy(p->macaddr, addr, sizeof(p->macaddr));
1716
1717 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1718 if (ret == 0) {
1719 p = &rpl.u.exact[0];
1720 ret = FW_VI_MAC_CMD_IDX_G(be16_to_cpu(p->valid_to_idx));
1721 if (ret >= max_mac_addr)
1722 ret = -ENOMEM;
1723 }
1724 return ret;
1725 }
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737 int t4vf_set_addr_hash(struct adapter *adapter, unsigned int viid,
1738 bool ucast, u64 vec, bool sleep_ok)
1739 {
1740 struct fw_vi_mac_cmd cmd;
1741 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1742 u.exact[0]), 16);
1743
1744 memset(&cmd, 0, sizeof(cmd));
1745 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
1746 FW_CMD_REQUEST_F |
1747 FW_CMD_WRITE_F |
1748 FW_VI_ENABLE_CMD_VIID_V(viid));
1749 cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN_F |
1750 FW_VI_MAC_CMD_HASHUNIEN_V(ucast) |
1751 FW_CMD_LEN16_V(len16));
1752 cmd.u.hash.hashvec = cpu_to_be64(vec);
1753 return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok);
1754 }
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764 int t4vf_get_port_stats(struct adapter *adapter, int pidx,
1765 struct t4vf_port_stats *s)
1766 {
1767 struct port_info *pi = adap2pinfo(adapter, pidx);
1768 struct fw_vi_stats_vf fwstats;
1769 unsigned int rem = VI_VF_NUM_STATS;
1770 __be64 *fwsp = (__be64 *)&fwstats;
1771
1772
1773
1774
1775
1776
1777 while (rem) {
1778 unsigned int ix = VI_VF_NUM_STATS - rem;
1779 unsigned int nstats = min(6U, rem);
1780 struct fw_vi_stats_cmd cmd, rpl;
1781 size_t len = (offsetof(struct fw_vi_stats_cmd, u) +
1782 sizeof(struct fw_vi_stats_ctl));
1783 size_t len16 = DIV_ROUND_UP(len, 16);
1784 int ret;
1785
1786 memset(&cmd, 0, sizeof(cmd));
1787 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_STATS_CMD) |
1788 FW_VI_STATS_CMD_VIID_V(pi->viid) |
1789 FW_CMD_REQUEST_F |
1790 FW_CMD_READ_F);
1791 cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16));
1792 cmd.u.ctl.nstats_ix =
1793 cpu_to_be16(FW_VI_STATS_CMD_IX_V(ix) |
1794 FW_VI_STATS_CMD_NSTATS_V(nstats));
1795 ret = t4vf_wr_mbox_ns(adapter, &cmd, len, &rpl);
1796 if (ret)
1797 return ret;
1798
1799 memcpy(fwsp, &rpl.u.ctl.stat0, sizeof(__be64) * nstats);
1800
1801 rem -= nstats;
1802 fwsp += nstats;
1803 }
1804
1805
1806
1807
1808 s->tx_bcast_bytes = be64_to_cpu(fwstats.tx_bcast_bytes);
1809 s->tx_bcast_frames = be64_to_cpu(fwstats.tx_bcast_frames);
1810 s->tx_mcast_bytes = be64_to_cpu(fwstats.tx_mcast_bytes);
1811 s->tx_mcast_frames = be64_to_cpu(fwstats.tx_mcast_frames);
1812 s->tx_ucast_bytes = be64_to_cpu(fwstats.tx_ucast_bytes);
1813 s->tx_ucast_frames = be64_to_cpu(fwstats.tx_ucast_frames);
1814 s->tx_drop_frames = be64_to_cpu(fwstats.tx_drop_frames);
1815 s->tx_offload_bytes = be64_to_cpu(fwstats.tx_offload_bytes);
1816 s->tx_offload_frames = be64_to_cpu(fwstats.tx_offload_frames);
1817
1818 s->rx_bcast_bytes = be64_to_cpu(fwstats.rx_bcast_bytes);
1819 s->rx_bcast_frames = be64_to_cpu(fwstats.rx_bcast_frames);
1820 s->rx_mcast_bytes = be64_to_cpu(fwstats.rx_mcast_bytes);
1821 s->rx_mcast_frames = be64_to_cpu(fwstats.rx_mcast_frames);
1822 s->rx_ucast_bytes = be64_to_cpu(fwstats.rx_ucast_bytes);
1823 s->rx_ucast_frames = be64_to_cpu(fwstats.rx_ucast_frames);
1824
1825 s->rx_err_frames = be64_to_cpu(fwstats.rx_err_frames);
1826
1827 return 0;
1828 }
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840 int t4vf_iq_free(struct adapter *adapter, unsigned int iqtype,
1841 unsigned int iqid, unsigned int fl0id, unsigned int fl1id)
1842 {
1843 struct fw_iq_cmd cmd;
1844
1845 memset(&cmd, 0, sizeof(cmd));
1846 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) |
1847 FW_CMD_REQUEST_F |
1848 FW_CMD_EXEC_F);
1849 cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE_F |
1850 FW_LEN16(cmd));
1851 cmd.type_to_iqandstindex =
1852 cpu_to_be32(FW_IQ_CMD_TYPE_V(iqtype));
1853
1854 cmd.iqid = cpu_to_be16(iqid);
1855 cmd.fl0id = cpu_to_be16(fl0id);
1856 cmd.fl1id = cpu_to_be16(fl1id);
1857 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1858 }
1859
1860
1861
1862
1863
1864
1865
1866
1867 int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid)
1868 {
1869 struct fw_eq_eth_cmd cmd;
1870
1871 memset(&cmd, 0, sizeof(cmd));
1872 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_ETH_CMD) |
1873 FW_CMD_REQUEST_F |
1874 FW_CMD_EXEC_F);
1875 cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE_F |
1876 FW_LEN16(cmd));
1877 cmd.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID_V(eqid));
1878 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1879 }
1880
1881
1882
1883
1884
1885
1886
1887 static const char *t4vf_link_down_rc_str(unsigned char link_down_rc)
1888 {
1889 static const char * const reason[] = {
1890 "Link Down",
1891 "Remote Fault",
1892 "Auto-negotiation Failure",
1893 "Reserved",
1894 "Insufficient Airflow",
1895 "Unable To Determine Reason",
1896 "No RX Signal Detected",
1897 "Reserved",
1898 };
1899
1900 if (link_down_rc >= ARRAY_SIZE(reason))
1901 return "Bad Reason Code";
1902
1903 return reason[link_down_rc];
1904 }
1905
1906
1907
1908
1909
1910
1911
1912
1913 static void t4vf_handle_get_port_info(struct port_info *pi,
1914 const struct fw_port_cmd *cmd)
1915 {
1916 fw_port_cap32_t pcaps, acaps, lpacaps, linkattr;
1917 struct link_config *lc = &pi->link_cfg;
1918 struct adapter *adapter = pi->adapter;
1919 unsigned int speed, fc, fec, adv_fc;
1920 enum fw_port_module_type mod_type;
1921 int action, link_ok, linkdnrc;
1922 enum fw_port_type port_type;
1923
1924
1925 action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16));
1926 switch (action) {
1927 case FW_PORT_ACTION_GET_PORT_INFO: {
1928 u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
1929
1930 link_ok = (lstatus & FW_PORT_CMD_LSTATUS_F) != 0;
1931 linkdnrc = FW_PORT_CMD_LINKDNRC_G(lstatus);
1932 port_type = FW_PORT_CMD_PTYPE_G(lstatus);
1933 mod_type = FW_PORT_CMD_MODTYPE_G(lstatus);
1934 pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
1935 acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
1936 lpacaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.lpacap));
1937
1938
1939
1940
1941
1942 linkattr = 0;
1943 if (lstatus & FW_PORT_CMD_RXPAUSE_F)
1944 linkattr |= FW_PORT_CAP32_FC_RX;
1945 if (lstatus & FW_PORT_CMD_TXPAUSE_F)
1946 linkattr |= FW_PORT_CAP32_FC_TX;
1947 if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
1948 linkattr |= FW_PORT_CAP32_SPEED_100M;
1949 if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
1950 linkattr |= FW_PORT_CAP32_SPEED_1G;
1951 if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
1952 linkattr |= FW_PORT_CAP32_SPEED_10G;
1953 if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
1954 linkattr |= FW_PORT_CAP32_SPEED_25G;
1955 if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
1956 linkattr |= FW_PORT_CAP32_SPEED_40G;
1957 if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
1958 linkattr |= FW_PORT_CAP32_SPEED_100G;
1959
1960 break;
1961 }
1962
1963 case FW_PORT_ACTION_GET_PORT_INFO32: {
1964 u32 lstatus32;
1965
1966 lstatus32 = be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
1967 link_ok = (lstatus32 & FW_PORT_CMD_LSTATUS32_F) != 0;
1968 linkdnrc = FW_PORT_CMD_LINKDNRC32_G(lstatus32);
1969 port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
1970 mod_type = FW_PORT_CMD_MODTYPE32_G(lstatus32);
1971 pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
1972 acaps = be32_to_cpu(cmd->u.info32.acaps32);
1973 lpacaps = be32_to_cpu(cmd->u.info32.lpacaps32);
1974 linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
1975 break;
1976 }
1977
1978 default:
1979 dev_err(adapter->pdev_dev, "Handle Port Information: Bad Command/Action %#x\n",
1980 be32_to_cpu(cmd->action_to_len16));
1981 return;
1982 }
1983
1984 fec = fwcap_to_cc_fec(acaps);
1985 adv_fc = fwcap_to_cc_pause(acaps);
1986 fc = fwcap_to_cc_pause(linkattr);
1987 speed = fwcap_to_speed(linkattr);
1988
1989 if (mod_type != pi->mod_type) {
1990
1991
1992
1993
1994
1995
1996
1997 lc->auto_fec = fec;
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009 pi->port_type = port_type;
2010
2011 pi->mod_type = mod_type;
2012 t4vf_os_portmod_changed(adapter, pi->pidx);
2013 }
2014
2015 if (link_ok != lc->link_ok || speed != lc->speed ||
2016 fc != lc->fc || adv_fc != lc->advertised_fc ||
2017 fec != lc->fec) {
2018
2019 if (!link_ok && lc->link_ok) {
2020 lc->link_down_rc = linkdnrc;
2021 dev_warn_ratelimited(adapter->pdev_dev,
2022 "Port %d link down, reason: %s\n",
2023 pi->port_id,
2024 t4vf_link_down_rc_str(linkdnrc));
2025 }
2026 lc->link_ok = link_ok;
2027 lc->speed = speed;
2028 lc->advertised_fc = adv_fc;
2029 lc->fc = fc;
2030 lc->fec = fec;
2031
2032 lc->pcaps = pcaps;
2033 lc->lpacaps = lpacaps;
2034 lc->acaps = acaps & ADVERT_MASK;
2035
2036
2037
2038
2039
2040
2041 if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
2042 lc->autoneg = AUTONEG_DISABLE;
2043 } else if (lc->acaps & FW_PORT_CAP32_ANEG) {
2044 lc->autoneg = AUTONEG_ENABLE;
2045 } else {
2046
2047
2048
2049
2050 lc->acaps = 0;
2051 lc->speed_caps = fwcap_to_speed(acaps);
2052 lc->autoneg = AUTONEG_DISABLE;
2053 }
2054
2055 t4vf_os_link_changed(adapter, pi->pidx, link_ok);
2056 }
2057 }
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067 int t4vf_update_port_info(struct port_info *pi)
2068 {
2069 unsigned int fw_caps = pi->adapter->params.fw_caps_support;
2070 struct fw_port_cmd port_cmd;
2071 int ret;
2072
2073 memset(&port_cmd, 0, sizeof(port_cmd));
2074 port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
2075 FW_CMD_REQUEST_F | FW_CMD_READ_F |
2076 FW_PORT_CMD_PORTID_V(pi->port_id));
2077 port_cmd.action_to_len16 = cpu_to_be32(
2078 FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
2079 ? FW_PORT_ACTION_GET_PORT_INFO
2080 : FW_PORT_ACTION_GET_PORT_INFO32) |
2081 FW_LEN16(port_cmd));
2082 ret = t4vf_wr_mbox(pi->adapter, &port_cmd, sizeof(port_cmd),
2083 &port_cmd);
2084 if (ret)
2085 return ret;
2086 t4vf_handle_get_port_info(pi, &port_cmd);
2087 return 0;
2088 }
2089
2090
2091
2092
2093
2094
2095
2096
2097 int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
2098 {
2099 const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl;
2100 u8 opcode = FW_CMD_OP_G(be32_to_cpu(cmd_hdr->hi));
2101
2102 switch (opcode) {
2103 case FW_PORT_CMD: {
2104
2105
2106
2107 const struct fw_port_cmd *port_cmd =
2108 (const struct fw_port_cmd *)rpl;
2109 int action = FW_PORT_CMD_ACTION_G(
2110 be32_to_cpu(port_cmd->action_to_len16));
2111 int port_id, pidx;
2112
2113 if (action != FW_PORT_ACTION_GET_PORT_INFO &&
2114 action != FW_PORT_ACTION_GET_PORT_INFO32) {
2115 dev_err(adapter->pdev_dev,
2116 "Unknown firmware PORT reply action %x\n",
2117 action);
2118 break;
2119 }
2120
2121 port_id = FW_PORT_CMD_PORTID_G(
2122 be32_to_cpu(port_cmd->op_to_portid));
2123 for_each_port(adapter, pidx) {
2124 struct port_info *pi = adap2pinfo(adapter, pidx);
2125
2126 if (pi->port_id != port_id)
2127 continue;
2128 t4vf_handle_get_port_info(pi, port_cmd);
2129 }
2130 break;
2131 }
2132
2133 default:
2134 dev_err(adapter->pdev_dev, "Unknown firmware reply %X\n",
2135 opcode);
2136 }
2137 return 0;
2138 }
2139
2140 int t4vf_prep_adapter(struct adapter *adapter)
2141 {
2142 int err;
2143 unsigned int chipid;
2144
2145
2146
2147 err = t4vf_wait_dev_ready(adapter);
2148 if (err)
2149 return err;
2150
2151
2152
2153
2154 adapter->params.nports = 1;
2155 adapter->params.vfres.pmask = 1;
2156 adapter->params.vpd.cclk = 50000;
2157
2158 adapter->params.chip = 0;
2159 switch (CHELSIO_PCI_ID_VER(adapter->pdev->device)) {
2160 case CHELSIO_T4:
2161 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, 0);
2162 adapter->params.arch.sge_fl_db = DBPRIO_F;
2163 adapter->params.arch.mps_tcam_size =
2164 NUM_MPS_CLS_SRAM_L_INSTANCES;
2165 break;
2166
2167 case CHELSIO_T5:
2168 chipid = REV_G(t4_read_reg(adapter, PL_VF_REV_A));
2169 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, chipid);
2170 adapter->params.arch.sge_fl_db = DBPRIO_F | DBTYPE_F;
2171 adapter->params.arch.mps_tcam_size =
2172 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
2173 break;
2174
2175 case CHELSIO_T6:
2176 chipid = REV_G(t4_read_reg(adapter, PL_VF_REV_A));
2177 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, chipid);
2178 adapter->params.arch.sge_fl_db = 0;
2179 adapter->params.arch.mps_tcam_size =
2180 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
2181 break;
2182 }
2183
2184 return 0;
2185 }
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198 int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int port,
2199 unsigned int *naddr, u8 *addr)
2200 {
2201 struct fw_acl_mac_cmd cmd;
2202 int ret;
2203
2204 memset(&cmd, 0, sizeof(cmd));
2205 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) |
2206 FW_CMD_REQUEST_F |
2207 FW_CMD_READ_F);
2208 cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
2209 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
2210 if (ret)
2211 return ret;
2212
2213 if (cmd.nmac < *naddr)
2214 *naddr = cmd.nmac;
2215
2216 switch (port) {
2217 case 3:
2218 memcpy(addr, cmd.macaddr3, sizeof(cmd.macaddr3));
2219 break;
2220 case 2:
2221 memcpy(addr, cmd.macaddr2, sizeof(cmd.macaddr2));
2222 break;
2223 case 1:
2224 memcpy(addr, cmd.macaddr1, sizeof(cmd.macaddr1));
2225 break;
2226 case 0:
2227 memcpy(addr, cmd.macaddr0, sizeof(cmd.macaddr0));
2228 break;
2229 }
2230
2231 return ret;
2232 }
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242 int t4vf_get_vf_vlan_acl(struct adapter *adapter)
2243 {
2244 struct fw_acl_vlan_cmd cmd;
2245 int vlan = 0;
2246 int ret = 0;
2247
2248 cmd.op_to_vfn = htonl(FW_CMD_OP_V(FW_ACL_VLAN_CMD) |
2249 FW_CMD_REQUEST_F | FW_CMD_READ_F);
2250
2251
2252 cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
2253
2254 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
2255
2256 if (!ret)
2257 vlan = be16_to_cpu(cmd.vlanid[0]);
2258
2259 return vlan;
2260 }