diff options
Diffstat (limited to 'drivers/net/ethernet/chelsio/cxgb4/t4_hw.c')
| -rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 294 |
1 files changed, 155 insertions, 139 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index e1413eacdbd..931478e7bd2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -32,12 +32,13 @@ * SOFTWARE. */ -#include <linux/init.h> #include <linux/delay.h> #include "cxgb4.h" #include "t4_regs.h" #include "t4fw_api.h" +static int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, + const u8 *fw_data, unsigned int size, int force); /** * t4_wait_op_done_val - wait until an operation is completed * @adapter: the adapter performing the operation @@ -572,7 +573,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) { u32 cclk_param, cclk_val; int i, ret, addr; - int ec, sn; + int ec, sn, pn; u8 *vpd, csum; unsigned int vpdr_len, kw_offset, id_len; @@ -637,6 +638,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) FIND_VPD_KW(ec, "EC"); FIND_VPD_KW(sn, "SN"); + FIND_VPD_KW(pn, "PN"); #undef FIND_VPD_KW memcpy(p->id, vpd + PCI_VPD_LRDT_TAG_SIZE, id_len); @@ -646,6 +648,8 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); strim(p->sn); + memcpy(p->pn, vpd + pn, min(i, PN_LEN)); + strim(p->pn); /* * Ask firmware for the Core Clock since it knows how to translate the @@ -678,7 +682,7 @@ enum { SF_RD_ID = 0x9f, /* read ID */ SF_ERASE_SECTOR = 0xd8, /* erase sector */ - FW_MAX_SIZE = 512 * 1024, + FW_MAX_SIZE = 16 * SF_SEC_SIZE, }; /** @@ -1070,62 +1074,6 @@ unsigned int t4_flash_cfg_addr(struct adapter *adapter) } /** - * t4_load_cfg - download config file - * @adap: the adapter - * @cfg_data: the cfg text file to write - * @size: text file size - * - * Write the supplied config text file to the card's serial flash. - */ -int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) -{ - int ret, i, n; - unsigned int addr; - unsigned int flash_cfg_start_sec; - unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec; - - addr = t4_flash_cfg_addr(adap); - flash_cfg_start_sec = addr / SF_SEC_SIZE; - - if (size > FLASH_CFG_MAX_SIZE) { - dev_err(adap->pdev_dev, "cfg file too large, max is %u bytes\n", - FLASH_CFG_MAX_SIZE); - return -EFBIG; - } - - i = DIV_ROUND_UP(FLASH_CFG_MAX_SIZE, /* # of sectors spanned */ - sf_sec_size); - ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec, - flash_cfg_start_sec + i - 1); - /* - * If size == 0 then we're simply erasing the FLASH sectors associated - * with the on-adapter Firmware Configuration File. - */ - if (ret || size == 0) - goto out; - - /* this will write to the flash up to SF_PAGE_SIZE at a time */ - for (i = 0; i < size; i += SF_PAGE_SIZE) { - if ((size - i) < SF_PAGE_SIZE) - n = size - i; - else - n = SF_PAGE_SIZE; - ret = t4_write_flash(adap, addr, n, cfg_data); - if (ret) - goto out; - - addr += SF_PAGE_SIZE; - cfg_data += SF_PAGE_SIZE; - } - -out: - if (ret) - dev_err(adap->pdev_dev, "config file %s failed %d\n", - (size == 0 ? "clear" : "download"), ret); - return ret; -} - -/** * t4_load_fw - download firmware * @adap: the adapter * @fw_data: the firmware image to write @@ -1210,7 +1158,8 @@ out: } #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ - FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG) + FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ + FW_PORT_CAP_ANEG) /** * t4_link_start - apply link configuration to MAC/PHY @@ -2302,6 +2251,36 @@ static unsigned int get_mps_bg_map(struct adapter *adap, int idx) } /** + * t4_get_port_type_description - return Port Type string description + * @port_type: firmware Port Type enumeration + */ +const char *t4_get_port_type_description(enum fw_port_type port_type) +{ + static const char *const port_type_description[] = { + "R XFI", + "R XAUI", + "T SGMII", + "T XFI", + "T XAUI", + "KX4", + "CX4", + "KX", + "KR", + "R SFP+", + "KR/KX", + "KR/KX/KX4", + "R QSFP_10G", + "", + "R QSFP", + "R BP40_BA", + }; + + if (port_type < ARRAY_SIZE(port_type_description)) + return port_type_description[port_type]; + return "UNKNOWN"; +} + +/** * t4_get_port_stats - collect port statistics * @adap: the adapter * @idx: the port index @@ -2618,6 +2597,112 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, } /** + * t4_sge_decode_idma_state - decode the idma state + * @adap: the adapter + * @state: the state idma is stuck in + */ +void t4_sge_decode_idma_state(struct adapter *adapter, int state) +{ + static const char * const t4_decode[] = { + "IDMA_IDLE", + "IDMA_PUSH_MORE_CPL_FIFO", + "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", + "Not used", + "IDMA_PHYSADDR_SEND_PCIEHDR", + "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", + "IDMA_PHYSADDR_SEND_PAYLOAD", + "IDMA_SEND_FIFO_TO_IMSG", + "IDMA_FL_REQ_DATA_FL_PREP", + "IDMA_FL_REQ_DATA_FL", + "IDMA_FL_DROP", + "IDMA_FL_H_REQ_HEADER_FL", + "IDMA_FL_H_SEND_PCIEHDR", + "IDMA_FL_H_PUSH_CPL_FIFO", + "IDMA_FL_H_SEND_CPL", + "IDMA_FL_H_SEND_IP_HDR_FIRST", + "IDMA_FL_H_SEND_IP_HDR", + "IDMA_FL_H_REQ_NEXT_HEADER_FL", + "IDMA_FL_H_SEND_NEXT_PCIEHDR", + "IDMA_FL_H_SEND_IP_HDR_PADDING", + "IDMA_FL_D_SEND_PCIEHDR", + "IDMA_FL_D_SEND_CPL_AND_IP_HDR", + "IDMA_FL_D_REQ_NEXT_DATA_FL", + "IDMA_FL_SEND_PCIEHDR", + "IDMA_FL_PUSH_CPL_FIFO", + "IDMA_FL_SEND_CPL", + "IDMA_FL_SEND_PAYLOAD_FIRST", + "IDMA_FL_SEND_PAYLOAD", + "IDMA_FL_REQ_NEXT_DATA_FL", + "IDMA_FL_SEND_NEXT_PCIEHDR", + "IDMA_FL_SEND_PADDING", + "IDMA_FL_SEND_COMPLETION_TO_IMSG", + "IDMA_FL_SEND_FIFO_TO_IMSG", + "IDMA_FL_REQ_DATAFL_DONE", + "IDMA_FL_REQ_HEADERFL_DONE", + }; + static const char * const t5_decode[] = { + "IDMA_IDLE", + "IDMA_ALMOST_IDLE", + "IDMA_PUSH_MORE_CPL_FIFO", + "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", + "IDMA_SGEFLRFLUSH_SEND_PCIEHDR", + "IDMA_PHYSADDR_SEND_PCIEHDR", + "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", + "IDMA_PHYSADDR_SEND_PAYLOAD", + "IDMA_SEND_FIFO_TO_IMSG", + "IDMA_FL_REQ_DATA_FL", + "IDMA_FL_DROP", + "IDMA_FL_DROP_SEND_INC", + "IDMA_FL_H_REQ_HEADER_FL", + "IDMA_FL_H_SEND_PCIEHDR", + "IDMA_FL_H_PUSH_CPL_FIFO", + "IDMA_FL_H_SEND_CPL", + "IDMA_FL_H_SEND_IP_HDR_FIRST", + "IDMA_FL_H_SEND_IP_HDR", + "IDMA_FL_H_REQ_NEXT_HEADER_FL", + "IDMA_FL_H_SEND_NEXT_PCIEHDR", + "IDMA_FL_H_SEND_IP_HDR_PADDING", + "IDMA_FL_D_SEND_PCIEHDR", + "IDMA_FL_D_SEND_CPL_AND_IP_HDR", + "IDMA_FL_D_REQ_NEXT_DATA_FL", + "IDMA_FL_SEND_PCIEHDR", + "IDMA_FL_PUSH_CPL_FIFO", + "IDMA_FL_SEND_CPL", + "IDMA_FL_SEND_PAYLOAD_FIRST", + "IDMA_FL_SEND_PAYLOAD", + "IDMA_FL_REQ_NEXT_DATA_FL", + "IDMA_FL_SEND_NEXT_PCIEHDR", + "IDMA_FL_SEND_PADDING", + "IDMA_FL_SEND_COMPLETION_TO_IMSG", + }; + static const u32 sge_regs[] = { + SGE_DEBUG_DATA_LOW_INDEX_2, + SGE_DEBUG_DATA_LOW_INDEX_3, + SGE_DEBUG_DATA_HIGH_INDEX_10, + }; + const char **sge_idma_decode; + int sge_idma_decode_nstates; + int i; + + if (is_t4(adapter->params.chip)) { + sge_idma_decode = (const char **)t4_decode; + sge_idma_decode_nstates = ARRAY_SIZE(t4_decode); + } else { + sge_idma_decode = (const char **)t5_decode; + sge_idma_decode_nstates = ARRAY_SIZE(t5_decode); + } + + if (state < sge_idma_decode_nstates) + CH_WARN(adapter, "idma state %s\n", sge_idma_decode[state]); + else + CH_WARN(adapter, "idma state %d unknown\n", state); + + for (i = 0; i < ARRAY_SIZE(sge_regs); i++) + CH_WARN(adapter, "SGE register %#x value %#x\n", + sge_regs[i], t4_read_reg(adapter, sge_regs[i])); +} + +/** * t4_fw_hello - establish communication with FW * @adap: the adapter * @mbox: mailbox to use for the FW command @@ -2810,7 +2895,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) * be doing. The only way out of this state is to RESTART the firmware * ... */ -int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) +static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) { int ret = 0; @@ -2875,7 +2960,7 @@ int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) * the chip since older firmware won't recognize the PCIE_FW.HALT * flag and automatically RESET itself on startup. */ -int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset) +static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset) { if (reset) { /* @@ -2938,8 +3023,8 @@ int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset) * positive errno indicates that the adapter is ~probably~ intact, a * negative errno indicates that things are looking bad ... */ -int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, - const u8 *fw_data, unsigned int size, int force) +static int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, + const u8 *fw_data, unsigned int size, int force) { const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data; int reset, ret; @@ -2964,78 +3049,6 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, return t4_fw_restart(adap, mbox, reset); } - -/** - * t4_fw_config_file - setup an adapter via a Configuration File - * @adap: the adapter - * @mbox: mailbox to use for the FW command - * @mtype: the memory type where the Configuration File is located - * @maddr: the memory address where the Configuration File is located - * @finiver: return value for CF [fini] version - * @finicsum: return value for CF [fini] checksum - * @cfcsum: return value for CF computed checksum - * - * Issue a command to get the firmware to process the Configuration - * File located at the specified mtype/maddress. If the Configuration - * File is processed successfully and return value pointers are - * provided, the Configuration File "[fini] section version and - * checksum values will be returned along with the computed checksum. - * It's up to the caller to decide how it wants to respond to the - * checksums not matching but it recommended that a prominant warning - * be emitted in order to help people rapidly identify changed or - * corrupted Configuration Files. - * - * Also note that it's possible to modify things like "niccaps", - * "toecaps",etc. between processing the Configuration File and telling - * the firmware to use the new configuration. Callers which want to - * do this will need to "hand-roll" their own CAPS_CONFIGS commands for - * Configuration Files if they want to do this. - */ -int t4_fw_config_file(struct adapter *adap, unsigned int mbox, - unsigned int mtype, unsigned int maddr, - u32 *finiver, u32 *finicsum, u32 *cfcsum) -{ - struct fw_caps_config_cmd caps_cmd; - int ret; - - /* - * Tell the firmware to process the indicated Configuration File. - * If there are no errors and the caller has provided return value - * pointers for the [fini] section version, checksum and computed - * checksum, pass those back to the caller. - */ - memset(&caps_cmd, 0, sizeof(caps_cmd)); - caps_cmd.op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); - caps_cmd.cfvalid_to_len16 = - htonl(FW_CAPS_CONFIG_CMD_CFVALID | - FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | - FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) | - FW_LEN16(caps_cmd)); - ret = t4_wr_mbox(adap, mbox, &caps_cmd, sizeof(caps_cmd), &caps_cmd); - if (ret < 0) - return ret; - - if (finiver) - *finiver = ntohl(caps_cmd.finiver); - if (finicsum) - *finicsum = ntohl(caps_cmd.finicsum); - if (cfcsum) - *cfcsum = ntohl(caps_cmd.cfcsum); - - /* - * And now tell the firmware to use the configuration we just loaded. - */ - caps_cmd.op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE); - caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); - return t4_wr_mbox(adap, mbox, &caps_cmd, sizeof(caps_cmd), NULL); -} - /** * t4_fixup_host_params - fix up host-dependent parameters * @adap: the adapter @@ -3660,11 +3673,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) if (stat & FW_PORT_CMD_TXPAUSE) fc |= PAUSE_TX; if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) - speed = SPEED_100; + speed = 100; else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) - speed = SPEED_1000; + speed = 1000; else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) - speed = SPEED_10000; + speed = 10000; + else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + speed = 40000; if (link_ok != lc->link_ok || speed != lc->speed || fc != lc->fc) { /* something changed */ @@ -3947,6 +3962,7 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) p->lport = j; p->rss_size = rss_size; memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN); + adap->port[i]->dev_port = j; ret = ntohl(c.u.info.lstatus_to_modtype); p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ? |
