diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-02 02:00:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-02 02:00:49 -0400 |
commit | 88e4194712496ace4a24d7541a83f910f0326ef0 (patch) | |
tree | 8e9571e1faf896272ab3d9efccde452f4ed05140 | |
parent | cc25f0cbe4409d6a573b1f3bf7020d5b04076ee9 (diff) | |
parent | 5c937dd3f9eb999e6f4802987a674eae5718be54 (diff) |
Merge branch 'cxgb4'
Hariprasad Shenai says:
====================
Trivial fixes for cxgb4
This patch series adds support to fix T5 adapter accessing T4 adapter registers,
issue mbox command on correct mbox for physical function, avoid dumping write
only registers, use correct length for adapter part number and support to detect
and display firmware reported errors.
The patches series is created against 'net' tree.
And includes patches on cxgb4 driver.
We have included all the maintainers of respective drivers. Kindly review the
change and let us know in case of any review comments.
Thanks
V2:
Added description for each patch as per David Miller's comment
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 79 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 4 |
4 files changed, 84 insertions, 17 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 18fb9c61d7ba..8c34811a1128 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -1253,7 +1253,9 @@ freeout: t4_free_sge_resources(adap); | |||
1253 | goto freeout; | 1253 | goto freeout; |
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | t4_write_reg(adap, MPS_TRC_RSS_CONTROL, | 1256 | t4_write_reg(adap, is_t4(adap->params.chip) ? |
1257 | MPS_TRC_RSS_CONTROL : | ||
1258 | MPS_T5_TRC_RSS_CONTROL, | ||
1257 | RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) | | 1259 | RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) | |
1258 | QUEUENUMBER(s->ethrxq[0].rspq.abs_id)); | 1260 | QUEUENUMBER(s->ethrxq[0].rspq.abs_id)); |
1259 | return 0; | 1261 | return 0; |
@@ -1761,7 +1763,8 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
1761 | 0xd004, 0xd03c, | 1763 | 0xd004, 0xd03c, |
1762 | 0xdfc0, 0xdfe0, | 1764 | 0xdfc0, 0xdfe0, |
1763 | 0xe000, 0xea7c, | 1765 | 0xe000, 0xea7c, |
1764 | 0xf000, 0x11190, | 1766 | 0xf000, 0x11110, |
1767 | 0x11118, 0x11190, | ||
1765 | 0x19040, 0x1906c, | 1768 | 0x19040, 0x1906c, |
1766 | 0x19078, 0x19080, | 1769 | 0x19078, 0x19080, |
1767 | 0x1908c, 0x19124, | 1770 | 0x1908c, 0x19124, |
@@ -1968,7 +1971,8 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
1968 | 0xd004, 0xd03c, | 1971 | 0xd004, 0xd03c, |
1969 | 0xdfc0, 0xdfe0, | 1972 | 0xdfc0, 0xdfe0, |
1970 | 0xe000, 0x11088, | 1973 | 0xe000, 0x11088, |
1971 | 0x1109c, 0x1117c, | 1974 | 0x1109c, 0x11110, |
1975 | 0x11118, 0x1117c, | ||
1972 | 0x11190, 0x11204, | 1976 | 0x11190, 0x11204, |
1973 | 0x19040, 0x1906c, | 1977 | 0x19040, 0x1906c, |
1974 | 0x19078, 0x19080, | 1978 | 0x19078, 0x19080, |
@@ -5955,7 +5959,8 @@ static int adap_init0(struct adapter *adap) | |||
5955 | params[3] = FW_PARAM_PFVF(CQ_END); | 5959 | params[3] = FW_PARAM_PFVF(CQ_END); |
5956 | params[4] = FW_PARAM_PFVF(OCQ_START); | 5960 | params[4] = FW_PARAM_PFVF(OCQ_START); |
5957 | params[5] = FW_PARAM_PFVF(OCQ_END); | 5961 | params[5] = FW_PARAM_PFVF(OCQ_END); |
5958 | ret = t4_query_params(adap, 0, 0, 0, 6, params, val); | 5962 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 6, params, |
5963 | val); | ||
5959 | if (ret < 0) | 5964 | if (ret < 0) |
5960 | goto bye; | 5965 | goto bye; |
5961 | adap->vres.qp.start = val[0]; | 5966 | adap->vres.qp.start = val[0]; |
@@ -5967,7 +5972,8 @@ static int adap_init0(struct adapter *adap) | |||
5967 | 5972 | ||
5968 | params[0] = FW_PARAM_DEV(MAXORDIRD_QP); | 5973 | params[0] = FW_PARAM_DEV(MAXORDIRD_QP); |
5969 | params[1] = FW_PARAM_DEV(MAXIRD_ADAPTER); | 5974 | params[1] = FW_PARAM_DEV(MAXIRD_ADAPTER); |
5970 | ret = t4_query_params(adap, 0, 0, 0, 2, params, val); | 5975 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, |
5976 | val); | ||
5971 | if (ret < 0) { | 5977 | if (ret < 0) { |
5972 | adap->params.max_ordird_qp = 8; | 5978 | adap->params.max_ordird_qp = 8; |
5973 | adap->params.max_ird_adapter = 32 * adap->tids.ntids; | 5979 | adap->params.max_ird_adapter = 32 * adap->tids.ntids; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index a853133d8db8..41d04462b72e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -168,6 +168,34 @@ void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * t4_report_fw_error - report firmware error | ||
172 | * @adap: the adapter | ||
173 | * | ||
174 | * The adapter firmware can indicate error conditions to the host. | ||
175 | * If the firmware has indicated an error, print out the reason for | ||
176 | * the firmware error. | ||
177 | */ | ||
178 | static void t4_report_fw_error(struct adapter *adap) | ||
179 | { | ||
180 | static const char *const reason[] = { | ||
181 | "Crash", /* PCIE_FW_EVAL_CRASH */ | ||
182 | "During Device Preparation", /* PCIE_FW_EVAL_PREP */ | ||
183 | "During Device Configuration", /* PCIE_FW_EVAL_CONF */ | ||
184 | "During Device Initialization", /* PCIE_FW_EVAL_INIT */ | ||
185 | "Unexpected Event", /* PCIE_FW_EVAL_UNEXPECTEDEVENT */ | ||
186 | "Insufficient Airflow", /* PCIE_FW_EVAL_OVERHEAT */ | ||
187 | "Device Shutdown", /* PCIE_FW_EVAL_DEVICESHUTDOWN */ | ||
188 | "Reserved", /* reserved */ | ||
189 | }; | ||
190 | u32 pcie_fw; | ||
191 | |||
192 | pcie_fw = t4_read_reg(adap, MA_PCIE_FW); | ||
193 | if (pcie_fw & FW_PCIE_FW_ERR) | ||
194 | dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n", | ||
195 | reason[FW_PCIE_FW_EVAL_GET(pcie_fw)]); | ||
196 | } | ||
197 | |||
198 | /* | ||
171 | * Get the reply to a mailbox command and store it in @rpl in big-endian order. | 199 | * Get the reply to a mailbox command and store it in @rpl in big-endian order. |
172 | */ | 200 | */ |
173 | static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, | 201 | static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, |
@@ -300,6 +328,7 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, | |||
300 | dump_mbox(adap, mbox, data_reg); | 328 | dump_mbox(adap, mbox, data_reg); |
301 | dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", | 329 | dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", |
302 | *(const u8 *)cmd, mbox); | 330 | *(const u8 *)cmd, mbox); |
331 | t4_report_fw_error(adap); | ||
303 | return -ETIMEDOUT; | 332 | return -ETIMEDOUT; |
304 | } | 333 | } |
305 | 334 | ||
@@ -566,6 +595,7 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, | |||
566 | #define VPD_BASE 0x400 | 595 | #define VPD_BASE 0x400 |
567 | #define VPD_BASE_OLD 0 | 596 | #define VPD_BASE_OLD 0 |
568 | #define VPD_LEN 1024 | 597 | #define VPD_LEN 1024 |
598 | #define CHELSIO_VPD_UNIQUE_ID 0x82 | ||
569 | 599 | ||
570 | /** | 600 | /** |
571 | * t4_seeprom_wp - enable/disable EEPROM write protection | 601 | * t4_seeprom_wp - enable/disable EEPROM write protection |
@@ -603,7 +633,14 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
603 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd); | 633 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd); |
604 | if (ret < 0) | 634 | if (ret < 0) |
605 | goto out; | 635 | goto out; |
606 | addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD; | 636 | |
637 | /* The VPD shall have a unique identifier specified by the PCI SIG. | ||
638 | * For chelsio adapters, the identifier is 0x82. The first byte of a VPD | ||
639 | * shall be CHELSIO_VPD_UNIQUE_ID (0x82). The VPD programming software | ||
640 | * is expected to automatically put this entry at the | ||
641 | * beginning of the VPD. | ||
642 | */ | ||
643 | addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD; | ||
607 | 644 | ||
608 | ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd); | 645 | ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd); |
609 | if (ret < 0) | 646 | if (ret < 0) |
@@ -667,6 +704,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
667 | i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); | 704 | i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); |
668 | memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); | 705 | memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); |
669 | strim(p->sn); | 706 | strim(p->sn); |
707 | i = pci_vpd_info_field_size(vpd + pn - PCI_VPD_INFO_FLD_HDR_SIZE); | ||
670 | memcpy(p->pn, vpd + pn, min(i, PN_LEN)); | 708 | memcpy(p->pn, vpd + pn, min(i, PN_LEN)); |
671 | strim(p->pn); | 709 | strim(p->pn); |
672 | 710 | ||
@@ -1394,15 +1432,18 @@ static void pcie_intr_handler(struct adapter *adapter) | |||
1394 | 1432 | ||
1395 | int fat; | 1433 | int fat; |
1396 | 1434 | ||
1397 | fat = t4_handle_intr_status(adapter, | 1435 | if (is_t4(adapter->params.chip)) |
1398 | PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, | 1436 | fat = t4_handle_intr_status(adapter, |
1399 | sysbus_intr_info) + | 1437 | PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, |
1400 | t4_handle_intr_status(adapter, | 1438 | sysbus_intr_info) + |
1401 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, | 1439 | t4_handle_intr_status(adapter, |
1402 | pcie_port_intr_info) + | 1440 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, |
1403 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, | 1441 | pcie_port_intr_info) + |
1404 | is_t4(adapter->params.chip) ? | 1442 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, |
1405 | pcie_intr_info : t5_pcie_intr_info); | 1443 | pcie_intr_info); |
1444 | else | ||
1445 | fat = t4_handle_intr_status(adapter, PCIE_INT_CAUSE, | ||
1446 | t5_pcie_intr_info); | ||
1406 | 1447 | ||
1407 | if (fat) | 1448 | if (fat) |
1408 | t4_fatal_err(adapter); | 1449 | t4_fatal_err(adapter); |
@@ -1521,6 +1562,9 @@ static void cim_intr_handler(struct adapter *adapter) | |||
1521 | 1562 | ||
1522 | int fat; | 1563 | int fat; |
1523 | 1564 | ||
1565 | if (t4_read_reg(adapter, MA_PCIE_FW) & FW_PCIE_FW_ERR) | ||
1566 | t4_report_fw_error(adapter); | ||
1567 | |||
1524 | fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, | 1568 | fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, |
1525 | cim_intr_info) + | 1569 | cim_intr_info) + |
1526 | t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE, | 1570 | t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE, |
@@ -1768,10 +1812,16 @@ static void ma_intr_handler(struct adapter *adap) | |||
1768 | { | 1812 | { |
1769 | u32 v, status = t4_read_reg(adap, MA_INT_CAUSE); | 1813 | u32 v, status = t4_read_reg(adap, MA_INT_CAUSE); |
1770 | 1814 | ||
1771 | if (status & MEM_PERR_INT_CAUSE) | 1815 | if (status & MEM_PERR_INT_CAUSE) { |
1772 | dev_alert(adap->pdev_dev, | 1816 | dev_alert(adap->pdev_dev, |
1773 | "MA parity error, parity status %#x\n", | 1817 | "MA parity error, parity status %#x\n", |
1774 | t4_read_reg(adap, MA_PARITY_ERROR_STATUS)); | 1818 | t4_read_reg(adap, MA_PARITY_ERROR_STATUS)); |
1819 | if (is_t5(adap->params.chip)) | ||
1820 | dev_alert(adap->pdev_dev, | ||
1821 | "MA parity error, parity status %#x\n", | ||
1822 | t4_read_reg(adap, | ||
1823 | MA_PARITY_ERROR_STATUS2)); | ||
1824 | } | ||
1775 | if (status & MEM_WRAP_INT_CAUSE) { | 1825 | if (status & MEM_WRAP_INT_CAUSE) { |
1776 | v = t4_read_reg(adap, MA_INT_WRAP_STATUS); | 1826 | v = t4_read_reg(adap, MA_INT_WRAP_STATUS); |
1777 | dev_alert(adap->pdev_dev, "MA address wrap-around error by " | 1827 | dev_alert(adap->pdev_dev, "MA address wrap-around error by " |
@@ -2733,12 +2783,16 @@ retry: | |||
2733 | /* | 2783 | /* |
2734 | * Issue the HELLO command to the firmware. If it's not successful | 2784 | * Issue the HELLO command to the firmware. If it's not successful |
2735 | * but indicates that we got a "busy" or "timeout" condition, retry | 2785 | * but indicates that we got a "busy" or "timeout" condition, retry |
2736 | * the HELLO until we exhaust our retry limit. | 2786 | * the HELLO until we exhaust our retry limit. If we do exceed our |
2787 | * retry limit, check to see if the firmware left us any error | ||
2788 | * information and report that if so. | ||
2737 | */ | 2789 | */ |
2738 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | 2790 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); |
2739 | if (ret < 0) { | 2791 | if (ret < 0) { |
2740 | if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) | 2792 | if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) |
2741 | goto retry; | 2793 | goto retry; |
2794 | if (t4_read_reg(adap, MA_PCIE_FW) & FW_PCIE_FW_ERR) | ||
2795 | t4_report_fw_error(adap); | ||
2742 | return ret; | 2796 | return ret; |
2743 | } | 2797 | } |
2744 | 2798 | ||
@@ -3742,6 +3796,7 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) | |||
3742 | lc->link_ok = link_ok; | 3796 | lc->link_ok = link_ok; |
3743 | lc->speed = speed; | 3797 | lc->speed = speed; |
3744 | lc->fc = fc; | 3798 | lc->fc = fc; |
3799 | lc->supported = be16_to_cpu(p->u.info.pcap); | ||
3745 | t4_os_link_changed(adap, port, link_ok); | 3800 | t4_os_link_changed(adap, port, link_ok); |
3746 | } | 3801 | } |
3747 | if (mod != pi->mod_type) { | 3802 | if (mod != pi->mod_type) { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index e3146e83df20..39fb325474f7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | |||
@@ -511,6 +511,7 @@ | |||
511 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) | 511 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) |
512 | #define MA_PCIE_FW 0x30b8 | 512 | #define MA_PCIE_FW 0x30b8 |
513 | #define MA_PARITY_ERROR_STATUS 0x77f4 | 513 | #define MA_PARITY_ERROR_STATUS 0x77f4 |
514 | #define MA_PARITY_ERROR_STATUS2 0x7804 | ||
514 | 515 | ||
515 | #define MA_EXT_MEMORY1_BAR 0x7808 | 516 | #define MA_EXT_MEMORY1_BAR 0x7808 |
516 | #define EDC_0_BASE_ADDR 0x7900 | 517 | #define EDC_0_BASE_ADDR 0x7900 |
@@ -959,6 +960,7 @@ | |||
959 | #define TRCMULTIFILTER 0x00000001U | 960 | #define TRCMULTIFILTER 0x00000001U |
960 | 961 | ||
961 | #define MPS_TRC_RSS_CONTROL 0x9808 | 962 | #define MPS_TRC_RSS_CONTROL 0x9808 |
963 | #define MPS_T5_TRC_RSS_CONTROL 0xa00c | ||
962 | #define RSSCONTROL_MASK 0x00ff0000U | 964 | #define RSSCONTROL_MASK 0x00ff0000U |
963 | #define RSSCONTROL_SHIFT 16 | 965 | #define RSSCONTROL_SHIFT 16 |
964 | #define RSSCONTROL(x) ((x) << RSSCONTROL_SHIFT) | 966 | #define RSSCONTROL(x) ((x) << RSSCONTROL_SHIFT) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 5f2729ebadbe..3409756a85b9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
@@ -2228,6 +2228,10 @@ struct fw_debug_cmd { | |||
2228 | #define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT) | 2228 | #define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT) |
2229 | #define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \ | 2229 | #define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \ |
2230 | FW_PCIE_FW_MASTER_MASK) | 2230 | FW_PCIE_FW_MASTER_MASK) |
2231 | #define FW_PCIE_FW_EVAL_MASK 0x7 | ||
2232 | #define FW_PCIE_FW_EVAL_SHIFT 24 | ||
2233 | #define FW_PCIE_FW_EVAL_GET(x) (((x) >> FW_PCIE_FW_EVAL_SHIFT) & \ | ||
2234 | FW_PCIE_FW_EVAL_MASK) | ||
2231 | 2235 | ||
2232 | struct fw_hdr { | 2236 | struct fw_hdr { |
2233 | u8 ver; | 2237 | u8 ver; |