aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2015-01-27 08:57:59 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-27 20:12:57 -0500
commitbe6a6b43b597a37d96dbf74985f72045ccef0940 (patch)
treec71e0787f3229ae6ac728911a9edab949e0c55d5
parent4967082b469320eeba54ffbca632af1962858fb7 (diff)
net/mlx4_core: Add bad-cable event support
If the firmware can detect a bad cable, allow it to generate an event, and print the problem in the log. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c9
-rw-r--r--include/linux/mlx4/device.h14
3 files changed, 43 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 2f2e6067426d..4df006d8afa4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -88,6 +88,8 @@ static u64 get_async_ev_mask(struct mlx4_dev *dev)
88 u64 async_ev_mask = MLX4_ASYNC_EVENT_MASK; 88 u64 async_ev_mask = MLX4_ASYNC_EVENT_MASK;
89 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV) 89 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV)
90 async_ev_mask |= (1ull << MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT); 90 async_ev_mask |= (1ull << MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT);
91 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT)
92 async_ev_mask |= (1ull << MLX4_EVENT_TYPE_RECOVERABLE_ERROR_EVENT);
91 93
92 return async_ev_mask; 94 return async_ev_mask;
93} 95}
@@ -736,6 +738,26 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
736 (unsigned long) eqe); 738 (unsigned long) eqe);
737 break; 739 break;
738 740
741 case MLX4_EVENT_TYPE_RECOVERABLE_ERROR_EVENT:
742 switch (eqe->subtype) {
743 case MLX4_RECOVERABLE_ERROR_EVENT_SUBTYPE_BAD_CABLE:
744 mlx4_warn(dev, "Bad cable detected on port %u\n",
745 eqe->event.bad_cable.port);
746 break;
747 case MLX4_RECOVERABLE_ERROR_EVENT_SUBTYPE_UNSUPPORTED_CABLE:
748 mlx4_warn(dev, "Unsupported cable detected\n");
749 break;
750 default:
751 mlx4_dbg(dev,
752 "Unhandled recoverable error event detected: %02x(%02x) on EQ %d at index %u. owner=%x, nent=0x%x, ownership=%s\n",
753 eqe->type, eqe->subtype, eq->eqn,
754 eq->cons_index, eqe->owner, eq->nent,
755 !!(eqe->owner & 0x80) ^
756 !!(eq->cons_index & eq->nent) ? "HW" : "SW");
757 break;
758 }
759 break;
760
739 case MLX4_EVENT_TYPE_EEC_CATAS_ERROR: 761 case MLX4_EVENT_TYPE_EEC_CATAS_ERROR:
740 case MLX4_EVENT_TYPE_ECC_DETECT: 762 case MLX4_EVENT_TYPE_ECC_DETECT:
741 default: 763 default:
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 982861d1df44..2eadc2882e4f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -145,7 +145,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
145 [16] = "CONFIG DEV support", 145 [16] = "CONFIG DEV support",
146 [17] = "Asymmetric EQs support", 146 [17] = "Asymmetric EQs support",
147 [18] = "More than 80 VFs support", 147 [18] = "More than 80 VFs support",
148 [19] = "Performance optimized for limited rule configuration flow steering support" 148 [19] = "Performance optimized for limited rule configuration flow steering support",
149 [20] = "Recoverable error events support"
149 }; 150 };
150 int i; 151 int i;
151 152
@@ -859,6 +860,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
859 MLX4_GET(field32, outbox, QUERY_DEV_CAP_ETH_BACKPL_OFFSET); 860 MLX4_GET(field32, outbox, QUERY_DEV_CAP_ETH_BACKPL_OFFSET);
860 if (field32 & (1 << 0)) 861 if (field32 & (1 << 0))
861 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP; 862 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP;
863 if (field32 & (1 << 7))
864 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT;
862 MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC); 865 MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC);
863 if (field & 1<<6) 866 if (field & 1<<6)
864 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN; 867 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN;
@@ -1562,6 +1565,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
1562#define INIT_HCA_VXLAN_OFFSET 0x0c 1565#define INIT_HCA_VXLAN_OFFSET 0x0c
1563#define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e 1566#define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e
1564#define INIT_HCA_FLAGS_OFFSET 0x014 1567#define INIT_HCA_FLAGS_OFFSET 0x014
1568#define INIT_HCA_RECOVERABLE_ERROR_EVENT_OFFSET 0x018
1565#define INIT_HCA_QPC_OFFSET 0x020 1569#define INIT_HCA_QPC_OFFSET 0x020
1566#define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10) 1570#define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10)
1567#define INIT_HCA_LOG_QP_OFFSET (INIT_HCA_QPC_OFFSET + 0x17) 1571#define INIT_HCA_LOG_QP_OFFSET (INIT_HCA_QPC_OFFSET + 0x17)
@@ -1668,6 +1672,9 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
1668 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE; 1672 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE;
1669 } 1673 }
1670 1674
1675 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT)
1676 *(inbox + INIT_HCA_RECOVERABLE_ERROR_EVENT_OFFSET / 4) |= cpu_to_be32(1 << 31);
1677
1671 /* QPC/EEC/CQC/EQC/RDMARC attributes */ 1678 /* QPC/EEC/CQC/EQC/RDMARC attributes */
1672 1679
1673 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); 1680 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET);
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 5ef54e145e4d..c95d659a39f2 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -200,7 +200,8 @@ enum {
200 MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16, 200 MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16,
201 MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17, 201 MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17,
202 MLX4_DEV_CAP_FLAG2_80_VFS = 1LL << 18, 202 MLX4_DEV_CAP_FLAG2_80_VFS = 1LL << 18,
203 MLX4_DEV_CAP_FLAG2_FS_A0 = 1LL << 19 203 MLX4_DEV_CAP_FLAG2_FS_A0 = 1LL << 19,
204 MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20
204}; 205};
205 206
206enum { 207enum {
@@ -280,6 +281,7 @@ enum mlx4_event {
280 MLX4_EVENT_TYPE_FATAL_WARNING = 0x1b, 281 MLX4_EVENT_TYPE_FATAL_WARNING = 0x1b,
281 MLX4_EVENT_TYPE_FLR_EVENT = 0x1c, 282 MLX4_EVENT_TYPE_FLR_EVENT = 0x1c,
282 MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT = 0x1d, 283 MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT = 0x1d,
284 MLX4_EVENT_TYPE_RECOVERABLE_ERROR_EVENT = 0x3e,
283 MLX4_EVENT_TYPE_NONE = 0xff, 285 MLX4_EVENT_TYPE_NONE = 0xff,
284}; 286};
285 287
@@ -289,6 +291,11 @@ enum {
289}; 291};
290 292
291enum { 293enum {
294 MLX4_RECOVERABLE_ERROR_EVENT_SUBTYPE_BAD_CABLE = 1,
295 MLX4_RECOVERABLE_ERROR_EVENT_SUBTYPE_UNSUPPORTED_CABLE = 2,
296};
297
298enum {
292 MLX4_FATAL_WARNING_SUBTYPE_WARMING = 0, 299 MLX4_FATAL_WARNING_SUBTYPE_WARMING = 0,
293}; 300};
294 301
@@ -860,6 +867,11 @@ struct mlx4_eqe {
860 } __packed tbl_change_info; 867 } __packed tbl_change_info;
861 } params; 868 } params;
862 } __packed port_mgmt_change; 869 } __packed port_mgmt_change;
870 struct {
871 u8 reserved[3];
872 u8 port;
873 u32 reserved1[5];
874 } __packed bad_cable;
863 } event; 875 } event;
864 u8 slave_id; 876 u8 slave_id;
865 u8 reserved3[2]; 877 u8 reserved3[2];