* [PATCH net-next 0/8] Mellanox 100G mlx5 update 2016-11-15
From: Saeed Mahameed @ 2016-11-15 21:29 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
Hi Dave,
This series contains four humble mlx5 features.
from Gal,
- Add the support for PCIe statistics and expose them in ethtool
from Huy,
- Add the support for port module events reporting and statistics
- Add the support for driver version setting into FW (for display purposes only)
>From Mohamad,
- Extended the command interface cache flexibility
This series was generated against commit
c915fe13cbaa ("udplite: fix NULL pointer dereference")
Thanks,
Saeed.
Gal Pressman (2):
net/mlx5: Add MPCNT register infrastructure
net/mlx5e: Expose PCIe statistics to ethtool
Huy Nguyen (4):
net/mlx5: Port module event hardware structures
net/mlx5: Add handling for port module event
net/mlx5e: Add port module event counters to ethtool stats
net/mlx5: Set driver version into firmware
Mohamad Haj Yahia (1):
net/mlx5: Make the command interface cache more flexible
Saeed Mahameed (1):
net/mlx5: Set driver version infrastructure
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 145 ++++++++++-----------
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 40 +++++-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 24 ++++
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | 49 ++++++-
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 12 ++
drivers/net/ethernet/mellanox/mlx5/core/main.c | 37 ++++++
.../net/ethernet/mellanox/mlx5/core/mlx5_core.h | 1 +
drivers/net/ethernet/mellanox/mlx5/core/port.c | 57 ++++++++
include/linux/mlx5/device.h | 16 +++
include/linux/mlx5/driver.h | 42 +++++-
include/linux/mlx5/mlx5_ifc.h | 118 ++++++++++++++++-
include/linux/mlx5/port.h | 3 +
12 files changed, 457 insertions(+), 87 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH net-next 1/8] net/mlx5: Make the command interface cache more flexible
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Mohamad Haj Yahia, Saeed Mahameed
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Mohamad Haj Yahia <mohamad@mellanox.com>
Add more cache command size sets and more entries for each set based on
the current commands set different sizes and commands frequency.
Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters')
Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 145 ++++++++++++--------------
include/linux/mlx5/driver.h | 14 +--
2 files changed, 76 insertions(+), 83 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 8561102..0fe7a60 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -54,14 +54,6 @@ enum {
};
enum {
- NUM_LONG_LISTS = 2,
- NUM_MED_LISTS = 64,
- LONG_LIST_SIZE = (2ULL * 1024 * 1024 * 1024 / PAGE_SIZE) * 8 + 16 +
- MLX5_CMD_DATA_BLOCK_SIZE,
- MED_LIST_SIZE = 16 + MLX5_CMD_DATA_BLOCK_SIZE,
-};
-
-enum {
MLX5_CMD_DELIVERY_STAT_OK = 0x0,
MLX5_CMD_DELIVERY_STAT_SIGNAT_ERR = 0x1,
MLX5_CMD_DELIVERY_STAT_TOK_ERR = 0x2,
@@ -1372,10 +1364,10 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)
{
unsigned long flags;
- if (msg->cache) {
- spin_lock_irqsave(&msg->cache->lock, flags);
- list_add_tail(&msg->list, &msg->cache->head);
- spin_unlock_irqrestore(&msg->cache->lock, flags);
+ if (msg->parent) {
+ spin_lock_irqsave(&msg->parent->lock, flags);
+ list_add_tail(&msg->list, &msg->parent->head);
+ spin_unlock_irqrestore(&msg->parent->lock, flags);
} else {
mlx5_free_cmd_msg(dev, msg);
}
@@ -1472,30 +1464,37 @@ static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size,
gfp_t gfp)
{
struct mlx5_cmd_msg *msg = ERR_PTR(-ENOMEM);
+ struct cmd_msg_cache *ch = NULL;
struct mlx5_cmd *cmd = &dev->cmd;
- struct cache_ent *ent = NULL;
-
- if (in_size > MED_LIST_SIZE && in_size <= LONG_LIST_SIZE)
- ent = &cmd->cache.large;
- else if (in_size > 16 && in_size <= MED_LIST_SIZE)
- ent = &cmd->cache.med;
-
- if (ent) {
- spin_lock_irq(&ent->lock);
- if (!list_empty(&ent->head)) {
- msg = list_entry(ent->head.next, typeof(*msg), list);
- /* For cached lists, we must explicitly state what is
- * the real size
- */
- msg->len = in_size;
- list_del(&msg->list);
+ int i;
+
+ if (in_size <= 16)
+ goto cache_miss;
+
+ for (i = 0; i < MLX5_NUM_COMMAND_CACHES; i++) {
+ ch = &cmd->cache[i];
+ if (in_size > ch->max_inbox_size)
+ continue;
+ spin_lock_irq(&ch->lock);
+ if (list_empty(&ch->head)) {
+ spin_unlock_irq(&ch->lock);
+ continue;
}
- spin_unlock_irq(&ent->lock);
+ msg = list_entry(ch->head.next, typeof(*msg), list);
+ /* For cached lists, we must explicitly state what is
+ * the real size
+ */
+ msg->len = in_size;
+ list_del(&msg->list);
+ spin_unlock_irq(&ch->lock);
+ break;
}
- if (IS_ERR(msg))
- msg = mlx5_alloc_cmd_msg(dev, gfp, in_size, 0);
+ if (!IS_ERR(msg))
+ return msg;
+cache_miss:
+ msg = mlx5_alloc_cmd_msg(dev, gfp, in_size, 0);
return msg;
}
@@ -1593,58 +1592,56 @@ EXPORT_SYMBOL(mlx5_cmd_exec_cb);
static void destroy_msg_cache(struct mlx5_core_dev *dev)
{
- struct mlx5_cmd *cmd = &dev->cmd;
+ struct cmd_msg_cache *ch;
struct mlx5_cmd_msg *msg;
struct mlx5_cmd_msg *n;
+ int i;
- list_for_each_entry_safe(msg, n, &cmd->cache.large.head, list) {
- list_del(&msg->list);
- mlx5_free_cmd_msg(dev, msg);
- }
-
- list_for_each_entry_safe(msg, n, &cmd->cache.med.head, list) {
- list_del(&msg->list);
- mlx5_free_cmd_msg(dev, msg);
+ for (i = 0; i < MLX5_NUM_COMMAND_CACHES; i++) {
+ ch = &dev->cmd.cache[i];
+ list_for_each_entry_safe(msg, n, &ch->head, list) {
+ list_del(&msg->list);
+ mlx5_free_cmd_msg(dev, msg);
+ }
}
}
-static int create_msg_cache(struct mlx5_core_dev *dev)
+static unsigned cmd_cache_num_ent[MLX5_NUM_COMMAND_CACHES] = {
+ 512, 32, 16, 8, 2
+};
+
+static unsigned cmd_cache_ent_size[MLX5_NUM_COMMAND_CACHES] = {
+ 16 + MLX5_CMD_DATA_BLOCK_SIZE,
+ 16 + MLX5_CMD_DATA_BLOCK_SIZE * 2,
+ 16 + MLX5_CMD_DATA_BLOCK_SIZE * 16,
+ 16 + MLX5_CMD_DATA_BLOCK_SIZE * 256,
+ 16 + MLX5_CMD_DATA_BLOCK_SIZE * 512,
+};
+
+static void create_msg_cache(struct mlx5_core_dev *dev)
{
struct mlx5_cmd *cmd = &dev->cmd;
+ struct cmd_msg_cache *ch;
struct mlx5_cmd_msg *msg;
- int err;
int i;
-
- spin_lock_init(&cmd->cache.large.lock);
- INIT_LIST_HEAD(&cmd->cache.large.head);
- spin_lock_init(&cmd->cache.med.lock);
- INIT_LIST_HEAD(&cmd->cache.med.head);
-
- for (i = 0; i < NUM_LONG_LISTS; i++) {
- msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE, 0);
- if (IS_ERR(msg)) {
- err = PTR_ERR(msg);
- goto ex_err;
- }
- msg->cache = &cmd->cache.large;
- list_add_tail(&msg->list, &cmd->cache.large.head);
- }
-
- for (i = 0; i < NUM_MED_LISTS; i++) {
- msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE, 0);
- if (IS_ERR(msg)) {
- err = PTR_ERR(msg);
- goto ex_err;
+ int k;
+
+ /* Initialize and fill the caches with initial entries */
+ for (k = 0; k < MLX5_NUM_COMMAND_CACHES; k++) {
+ ch = &cmd->cache[k];
+ spin_lock_init(&ch->lock);
+ INIT_LIST_HEAD(&ch->head);
+ ch->num_ent = cmd_cache_num_ent[k];
+ ch->max_inbox_size = cmd_cache_ent_size[k];
+ for (i = 0; i < ch->num_ent; i++) {
+ msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL | __GFP_NOWARN,
+ ch->max_inbox_size, 0);
+ if (IS_ERR(msg))
+ break;
+ msg->parent = ch;
+ list_add_tail(&msg->list, &ch->head);
}
- msg->cache = &cmd->cache.med;
- list_add_tail(&msg->list, &cmd->cache.med.head);
}
-
- return 0;
-
-ex_err:
- destroy_msg_cache(dev);
- return err;
}
static int alloc_cmd_page(struct mlx5_core_dev *dev, struct mlx5_cmd *cmd)
@@ -1767,11 +1764,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
cmd->mode = CMD_MODE_POLLING;
- err = create_msg_cache(dev);
- if (err) {
- dev_err(&dev->pdev->dev, "failed to create command cache\n");
- goto err_free_page;
- }
+ create_msg_cache(dev);
set_wqname(dev);
cmd->wq = create_singlethread_workqueue(cmd->wq_name);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index ecc451d..1eb08d3 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -208,7 +208,7 @@ struct mlx5_cmd_first {
struct mlx5_cmd_msg {
struct list_head list;
- struct cache_ent *cache;
+ struct cmd_msg_cache *parent;
u32 len;
struct mlx5_cmd_first first;
struct mlx5_cmd_mailbox *next;
@@ -228,17 +228,17 @@ struct mlx5_cmd_debug {
u16 outlen;
};
-struct cache_ent {
+struct cmd_msg_cache {
/* protect block chain allocations
*/
spinlock_t lock;
struct list_head head;
+ unsigned max_inbox_size;
+ unsigned num_ent;
};
-struct cmd_msg_cache {
- struct cache_ent large;
- struct cache_ent med;
-
+enum {
+ MLX5_NUM_COMMAND_CACHES = 5,
};
struct mlx5_cmd_stats {
@@ -281,7 +281,7 @@ struct mlx5_cmd {
struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS];
struct pci_pool *pool;
struct mlx5_cmd_debug dbg;
- struct cmd_msg_cache cache;
+ struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES];
int checksum_disabled;
struct mlx5_cmd_stats stats[MLX5_CMD_OP_MAX];
};
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 3/8] net/mlx5: Add handling for port module event
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Huy Nguyen <huyn@mellanox.com>
For each asynchronous port module event:
1. print with ratelimit to the dmesg log
2. increment the corresponding event counter
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 12 +++++
.../net/ethernet/mellanox/mlx5/core/mlx5_core.h | 1 +
drivers/net/ethernet/mellanox/mlx5/core/port.c | 57 ++++++++++++++++++++++
include/linux/mlx5/driver.h | 27 ++++++++++
4 files changed, 97 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index e74a73b..8ffcc88 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -139,6 +139,8 @@ static const char *eqe_type_str(u8 type)
return "MLX5_EVENT_TYPE_PORT_CHANGE";
case MLX5_EVENT_TYPE_GPIO_EVENT:
return "MLX5_EVENT_TYPE_GPIO_EVENT";
+ case MLX5_EVENT_TYPE_PORT_MODULE_EVENT:
+ return "MLX5_EVENT_TYPE_PORT_MODULE_EVENT";
case MLX5_EVENT_TYPE_REMOTE_CONFIG:
return "MLX5_EVENT_TYPE_REMOTE_CONFIG";
case MLX5_EVENT_TYPE_DB_BF_CONGESTION:
@@ -285,6 +287,11 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
mlx5_eswitch_vport_event(dev->priv.eswitch, eqe);
break;
#endif
+
+ case MLX5_EVENT_TYPE_PORT_MODULE_EVENT:
+ mlx5_port_module_event(dev, eqe);
+ break;
+
default:
mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
eqe->type, eq->eqn);
@@ -480,6 +487,11 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
mlx5_core_is_pf(dev))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_NIC_VPORT_CHANGE);
+ if (MLX5_CAP_GEN(dev, port_module_event))
+ async_event_mask |= (1ull << MLX5_EVENT_TYPE_PORT_MODULE_EVENT);
+ else
+ mlx5_core_dbg(dev, "port_module_event is not set\n");
+
err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
"mlx5_cmd_eq", &dev->priv.uuari.uars[0]);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 4762bb9..7e635eb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -81,6 +81,7 @@ int mlx5_cmd_init_hca(struct mlx5_core_dev *dev);
int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev);
void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
unsigned long param);
+void mlx5_port_module_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
void mlx5_enter_error_state(struct mlx5_core_dev *dev);
void mlx5_disable_device(struct mlx5_core_dev *dev);
void mlx5_recover_device(struct mlx5_core_dev *dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 34e7184..b77928f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -746,3 +746,60 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
*supported = !!(MLX5_GET(pcmr_reg, out, fcs_cap));
*enabled = !!(MLX5_GET(pcmr_reg, out, fcs_chk));
}
+
+static const char *mlx5_pme_status[MLX5_MODULE_STATUS_NUM] = {
+ "Cable plugged", /* MLX5_MODULE_STATUS_PLUGGED = 0x1 */
+ "Cable unplugged", /* MLX5_MODULE_STATUS_UNPLUGGED = 0x2 */
+ "Cable error", /* MLX5_MODULE_STATUS_ERROR = 0x3 */
+};
+
+static const char *mlx5_pme_error[MLX5_MODULE_EVENT_ERROR_NUM] = {
+ "Power budget exceeded",
+ "Long Range for non MLNX cable",
+ "Bus stuck(I2C or data shorted)",
+ "No EEPROM/retry timeout",
+ "Enforce part number list",
+ "Unknown identifier",
+ "High Temperature",
+ "Bad or shorted cable/module",
+ "Unknown status",
+};
+
+void mlx5_port_module_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe)
+{
+ enum port_module_event_status_type module_status;
+ enum port_module_event_error_type error_type;
+ struct mlx5_eqe_port_module *module_event_eqe;
+ struct mlx5_priv *priv = &dev->priv;
+ u8 module_num;
+
+ module_event_eqe = &eqe->data.port_module;
+ module_num = module_event_eqe->module;
+ module_status = module_event_eqe->module_status &
+ PORT_MODULE_EVENT_MODULE_STATUS_MASK;
+ error_type = module_event_eqe->error_type &
+ PORT_MODULE_EVENT_ERROR_TYPE_MASK;
+
+ if (module_status < MLX5_MODULE_STATUS_ERROR) {
+ priv->pme_stats.status_counters[module_status - 1]++;
+ } else if (module_status == MLX5_MODULE_STATUS_ERROR) {
+ if (error_type >= MLX5_MODULE_EVENT_ERROR_UNKNOWN)
+ /* Unknown error type */
+ error_type = MLX5_MODULE_EVENT_ERROR_UNKNOWN;
+ priv->pme_stats.error_counters[error_type]++;
+ }
+
+ if (!printk_ratelimit())
+ return;
+
+ if (module_status < MLX5_MODULE_STATUS_ERROR)
+ mlx5_core_info(dev,
+ "Port module event: module %u, %s\n",
+ module_num, mlx5_pme_status[module_status - 1]);
+
+ else if (module_status == MLX5_MODULE_STATUS_ERROR)
+ mlx5_core_info(dev,
+ "Port module event[error]: module %u, %s, %s\n",
+ module_num, mlx5_pme_status[module_status - 1],
+ mlx5_pme_error[error_type]);
+}
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 1eb08d3..243b538 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -498,6 +498,31 @@ struct mlx5_rl_table {
struct mlx5_rl_entry *rl_entry;
};
+enum port_module_event_status_type {
+ MLX5_MODULE_STATUS_PLUGGED = 0x1,
+ MLX5_MODULE_STATUS_UNPLUGGED = 0x2,
+ MLX5_MODULE_STATUS_ERROR = 0x3,
+ MLX5_MODULE_STATUS_NUM = 0x3,
+};
+
+enum port_module_event_error_type {
+ MLX5_MODULE_EVENT_ERROR_POWER_BUDGET_EXCEEDED,
+ MLX5_MODULE_EVENT_ERROR_LONG_RANGE_FOR_NON_MLNX_CABLE_MODULE,
+ MLX5_MODULE_EVENT_ERROR_BUS_STUCK,
+ MLX5_MODULE_EVENT_ERROR_NO_EEPROM_RETRY_TIMEOUT,
+ MLX5_MODULE_EVENT_ERROR_ENFORCE_PART_NUMBER_LIST,
+ MLX5_MODULE_EVENT_ERROR_UNKNOWN_IDENTIFIER,
+ MLX5_MODULE_EVENT_ERROR_HIGH_TEMPERATURE,
+ MLX5_MODULE_EVENT_ERROR_BAD_CABLE,
+ MLX5_MODULE_EVENT_ERROR_UNKNOWN,
+ MLX5_MODULE_EVENT_ERROR_NUM,
+};
+
+struct mlx5_port_module_event_stats {
+ u64 status_counters[MLX5_MODULE_STATUS_NUM];
+ u64 error_counters[MLX5_MODULE_EVENT_ERROR_NUM];
+};
+
struct mlx5_priv {
char name[MLX5_MAX_NAME_LEN];
struct mlx5_eq_table eq_table;
@@ -559,6 +584,8 @@ struct mlx5_priv {
unsigned long pci_dev_data;
struct mlx5_fc_stats fc_stats;
struct mlx5_rl_table rl_table;
+
+ struct mlx5_port_module_event_stats pme_stats;
};
enum mlx5_device_state {
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 5/8] net/mlx5: Set driver version infrastructure
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed, Huy Nguyen, Leon Romanovsky
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
Add driver_version capability bit is enabled, and set driver
version command in mlx5_ifc firmware header. The only purpose
of this command is to store a driver version/OS string in FW
to be reported and displayed in various management systems,
such as IPMI/BMC.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
include/linux/mlx5/mlx5_ifc.h | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index cd1d530..f08a0624 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -83,6 +83,7 @@ enum {
MLX5_CMD_OP_SET_HCA_CAP = 0x109,
MLX5_CMD_OP_QUERY_ISSI = 0x10a,
MLX5_CMD_OP_SET_ISSI = 0x10b,
+ MLX5_CMD_OP_SET_DRIVER_VERSION = 0x10d,
MLX5_CMD_OP_CREATE_MKEY = 0x200,
MLX5_CMD_OP_QUERY_MKEY = 0x201,
MLX5_CMD_OP_DESTROY_MKEY = 0x202,
@@ -909,7 +910,7 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 log_pg_sz[0x8];
u8 bf[0x1];
- u8 reserved_at_261[0x1];
+ u8 driver_version[0x1];
u8 pad_tx_eth_packet[0x1];
u8 reserved_at_263[0x8];
u8 log_bf_reg_size[0x5];
@@ -4005,6 +4006,25 @@ struct mlx5_ifc_query_issi_in_bits {
u8 reserved_at_40[0x40];
};
+struct mlx5_ifc_set_driver_version_out_bits {
+ u8 status[0x8];
+ u8 reserved_0[0x18];
+
+ u8 syndrome[0x20];
+ u8 reserved_1[0x40];
+};
+
+struct mlx5_ifc_set_driver_version_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_0[0x10];
+
+ u8 reserved_1[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_2[0x40];
+ u8 driver_version[64][0x8];
+};
+
struct mlx5_ifc_query_hca_vport_pkey_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 7/8] net/mlx5: Add MPCNT register infrastructure
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
Add the needed infrastructure for future use of MPCNT register.
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
include/linux/mlx5/device.h | 5 +++
include/linux/mlx5/driver.h | 1 +
include/linux/mlx5/mlx5_ifc.h | 93 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 99 insertions(+)
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 52b4374..9f48936 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -1071,6 +1071,11 @@ enum {
MLX5_INFINIBAND_PORT_COUNTERS_GROUP = 0x20,
};
+enum {
+ MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP = 0x0,
+ MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP = 0x2,
+};
+
static inline u16 mlx5_to_sw_pkey_sz(int pkey_sz)
{
if (pkey_sz > MLX5_MAX_LOG_PKEY_TABLE)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 243b538..571feab 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -121,6 +121,7 @@ enum {
MLX5_REG_HOST_ENDIANNESS = 0x7004,
MLX5_REG_MCIA = 0x9014,
MLX5_REG_MLCR = 0x902b,
+ MLX5_REG_MPCNT = 0x9051,
};
enum {
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index f08a0624..a5f0fbe 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1757,6 +1757,80 @@ struct mlx5_ifc_eth_802_3_cntrs_grp_data_layout_bits {
u8 reserved_at_4c0[0x300];
};
+struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits {
+ u8 life_time_counter_high[0x20];
+
+ u8 life_time_counter_low[0x20];
+
+ u8 rx_errors[0x20];
+
+ u8 tx_errors[0x20];
+
+ u8 l0_to_recovery_eieos[0x20];
+
+ u8 l0_to_recovery_ts[0x20];
+
+ u8 l0_to_recovery_framing[0x20];
+
+ u8 l0_to_recovery_retrain[0x20];
+
+ u8 crc_error_dllp[0x20];
+
+ u8 crc_error_tlp[0x20];
+
+ u8 reserved_at_140[0x680];
+};
+
+struct mlx5_ifc_pcie_tas_cntrs_grp_data_layout_bits {
+ u8 life_time_counter_high[0x20];
+
+ u8 life_time_counter_low[0x20];
+
+ u8 time_to_boot_image_start[0x20];
+
+ u8 time_to_link_image[0x20];
+
+ u8 calibration_time[0x20];
+
+ u8 time_to_first_perst[0x20];
+
+ u8 time_to_detect_state[0x20];
+
+ u8 time_to_l0[0x20];
+
+ u8 time_to_crs_en[0x20];
+
+ u8 time_to_plastic_image_start[0x20];
+
+ u8 time_to_iron_image_start[0x20];
+
+ u8 perst_handler[0x20];
+
+ u8 times_in_l1[0x20];
+
+ u8 times_in_l23[0x20];
+
+ u8 dl_down[0x20];
+
+ u8 config_cycle1usec[0x20];
+
+ u8 config_cycle2to7usec[0x20];
+
+ u8 config_cycle_8to15usec[0x20];
+
+ u8 config_cycle_16_to_63usec[0x20];
+
+ u8 config_cycle_64usec[0x20];
+
+ u8 correctable_err_msg_sent[0x20];
+
+ u8 non_fatal_err_msg_sent[0x20];
+
+ u8 fatal_err_msg_sent[0x20];
+
+ u8 reserved_at_2e0[0x4e0];
+};
+
struct mlx5_ifc_cmd_inter_comp_event_bits {
u8 command_completion_vector[0x20];
@@ -2921,6 +2995,12 @@ union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits {
u8 reserved_at_0[0x7c0];
};
+union mlx5_ifc_pcie_cntrs_grp_data_layout_auto_bits {
+ struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits pcie_perf_cntrs_grp_data_layout;
+ struct mlx5_ifc_pcie_tas_cntrs_grp_data_layout_bits pcie_tas_cntrs_grp_data_layout;
+ u8 reserved_at_0[0x7c0];
+};
+
union mlx5_ifc_event_auto_bits {
struct mlx5_ifc_comp_event_bits comp_event;
struct mlx5_ifc_dct_events_bits dct_events;
@@ -7240,6 +7320,18 @@ struct mlx5_ifc_ppcnt_reg_bits {
union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits counter_set;
};
+struct mlx5_ifc_mpcnt_reg_bits {
+ u8 reserved_at_0[0x8];
+ u8 pcie_index[0x8];
+ u8 reserved_at_10[0xa];
+ u8 grp[0x6];
+
+ u8 clr[0x1];
+ u8 reserved_at_21[0x1f];
+
+ union mlx5_ifc_pcie_cntrs_grp_data_layout_auto_bits counter_set;
+};
+
struct mlx5_ifc_ppad_reg_bits {
u8 reserved_at_0[0x3];
u8 single_mac[0x1];
@@ -7845,6 +7937,7 @@ union mlx5_ifc_ports_control_registers_document_bits {
struct mlx5_ifc_pmtu_reg_bits pmtu_reg;
struct mlx5_ifc_ppad_reg_bits ppad_reg;
struct mlx5_ifc_ppcnt_reg_bits ppcnt_reg;
+ struct mlx5_ifc_mpcnt_reg_bits mpcnt_reg;
struct mlx5_ifc_pplm_reg_bits pplm_reg;
struct mlx5_ifc_pplr_reg_bits pplr_reg;
struct mlx5_ifc_ppsc_reg_bits ppsc_reg;
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 8/8] net/mlx5e: Expose PCIe statistics to ethtool
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
This patch exposes two groups of PCIe counters:
- Performance counters.
- Timers and states counters.
Queried with ethtool -S <devname>.
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 17 ++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 24 ++++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | 32 +++++++++++++++++++++-
3 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index b154621..9ea7b37 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -171,6 +171,7 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
return NUM_SW_COUNTERS +
MLX5E_NUM_Q_CNTRS(priv) +
NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
+ NUM_PCIE_COUNTERS +
MLX5E_NUM_RQ_STATS(priv) +
MLX5E_NUM_SQ_STATS(priv) +
MLX5E_NUM_PFC_COUNTERS(priv) +
@@ -216,6 +217,14 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
pport_2819_stats_desc[i].format);
+ for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
+ strcpy(data + (idx++) * ETH_GSTRING_LEN,
+ pcie_perf_stats_desc[i].format);
+
+ for (i = 0; i < NUM_PCIE_TAS_COUNTERS; i++)
+ strcpy(data + (idx++) * ETH_GSTRING_LEN,
+ pcie_tas_stats_desc[i].format);
+
for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
sprintf(data + (idx++) * ETH_GSTRING_LEN,
@@ -325,6 +334,14 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
pport_2819_stats_desc, i);
+ for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
+ data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
+ pcie_perf_stats_desc, i);
+
+ for (i = 0; i < NUM_PCIE_TAS_COUNTERS; i++)
+ data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_tas_counters,
+ pcie_tas_stats_desc, i);
+
for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 313b765..7a2540a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -290,12 +290,36 @@ static void mlx5e_update_q_counter(struct mlx5e_priv *priv)
&qcnt->rx_out_of_buffer);
}
+static void mlx5e_update_pcie_counters(struct mlx5e_priv *priv)
+{
+ struct mlx5e_pcie_stats *pcie_stats = &priv->stats.pcie;
+ struct mlx5_core_dev *mdev = priv->mdev;
+ int sz = MLX5_ST_SZ_BYTES(mpcnt_reg);
+ void *out;
+ u32 *in;
+
+ in = mlx5_vzalloc(sz);
+ if (!in)
+ return;
+
+ out = pcie_stats->pcie_perf_counters;
+ MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP);
+ mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0);
+
+ out = pcie_stats->pcie_tas_counters;
+ MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP);
+ mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0);
+
+ kvfree(in);
+}
+
void mlx5e_update_stats(struct mlx5e_priv *priv)
{
mlx5e_update_q_counter(priv);
mlx5e_update_vport_counters(priv);
mlx5e_update_pport_counters(priv);
mlx5e_update_sw_counters(priv);
+ mlx5e_update_pcie_counters(priv);
}
void mlx5e_update_stats_work(struct work_struct *work)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
index b817e51..5da6a1c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
@@ -39,7 +39,7 @@
#define MLX5E_READ_CTR32_CPU(ptr, dsc, i) \
(*(u32 *)((char *)ptr + dsc[i].offset))
#define MLX5E_READ_CTR32_BE(ptr, dsc, i) \
- be64_to_cpu(*(__be32 *)((char *)ptr + dsc[i].offset))
+ be32_to_cpu(*(__be32 *)((char *)ptr + dsc[i].offset))
#define MLX5E_DECLARE_STAT(type, fld) #fld, offsetof(type, fld)
#define MLX5E_DECLARE_RX_STAT(type, fld) "rx%d_"#fld, offsetof(type, fld)
@@ -276,6 +276,32 @@ static const struct counter_desc pport_per_prio_pfc_stats_desc[] = {
{ "rx_%s_pause_transition", PPORT_PER_PRIO_OFF(rx_pause_transition) },
};
+#define PCIE_PERF_OFF(c) \
+ MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c)
+#define PCIE_PERF_GET(pcie_stats, c) \
+ MLX5_GET(mpcnt_reg, pcie_stats->pcie_perf_counters, \
+ counter_set.pcie_perf_cntrs_grp_data_layout.c)
+#define PCIE_TAS_OFF(c) \
+ MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_tas_cntrs_grp_data_layout.c)
+#define PCIE_TAS_GET(pcie_stats, c) \
+ MLX5_GET(mpcnt_reg, pcie_stats->pcie_tas_counters, \
+ counter_set.pcie_tas_cntrs_grp_data_layout.c)
+
+struct mlx5e_pcie_stats {
+ __be64 pcie_perf_counters[MLX5_ST_SZ_QW(mpcnt_reg)];
+ __be64 pcie_tas_counters[MLX5_ST_SZ_QW(mpcnt_reg)];
+};
+
+static const struct counter_desc pcie_perf_stats_desc[] = {
+ { "rx_pci_signal_integrity", PCIE_PERF_OFF(rx_errors) },
+ { "tx_pci_signal_integrity", PCIE_PERF_OFF(tx_errors) },
+};
+
+static const struct counter_desc pcie_tas_stats_desc[] = {
+ { "tx_pci_transport_nonfatal_msg", PCIE_TAS_OFF(non_fatal_err_msg_sent) },
+ { "tx_pci_transport_fatal_msg", PCIE_TAS_OFF(fatal_err_msg_sent) },
+};
+
struct mlx5e_rq_stats {
u64 packets;
u64 bytes;
@@ -360,6 +386,8 @@ static const struct counter_desc sq_stats_desc[] = {
#define NUM_PPORT_802_3_COUNTERS ARRAY_SIZE(pport_802_3_stats_desc)
#define NUM_PPORT_2863_COUNTERS ARRAY_SIZE(pport_2863_stats_desc)
#define NUM_PPORT_2819_COUNTERS ARRAY_SIZE(pport_2819_stats_desc)
+#define NUM_PCIE_PERF_COUNTERS ARRAY_SIZE(pcie_perf_stats_desc)
+#define NUM_PCIE_TAS_COUNTERS ARRAY_SIZE(pcie_tas_stats_desc)
#define NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS \
ARRAY_SIZE(pport_per_prio_traffic_stats_desc)
#define NUM_PPORT_PER_PRIO_PFC_COUNTERS \
@@ -369,6 +397,7 @@ static const struct counter_desc sq_stats_desc[] = {
NUM_PPORT_2819_COUNTERS + \
NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS * \
NUM_PPORT_PRIO)
+#define NUM_PCIE_COUNTERS (NUM_PCIE_PERF_COUNTERS + NUM_PCIE_TAS_COUNTERS)
#define NUM_RQ_STATS ARRAY_SIZE(rq_stats_desc)
#define NUM_SQ_STATS ARRAY_SIZE(sq_stats_desc)
@@ -377,6 +406,7 @@ struct mlx5e_stats {
struct mlx5e_qcounter_stats qcnt;
struct mlx5e_vport_stats vport;
struct mlx5e_pport_stats pport;
+ struct mlx5e_pcie_stats pcie;
};
static const struct counter_desc mlx5e_pme_status_desc[] = {
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 6/8] net/mlx5: Set driver version into firmware
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Huy Nguyen <huyn@mellanox.com>
If driver_version capability bit is enabled, set driver version
to firmware after the init HCA command, for display purposes.
Example of driver version: "Linux,mlx5_core,3.0-1"
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/main.c | 37 ++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index a3a0887..e9e5803 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -175,6 +175,41 @@ static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili)
return err;
}
+static void mlx5_set_driver_version(struct mlx5_core_dev *dev)
+{
+ int driver_ver_sz = MLX5_FLD_SZ_BYTES(set_driver_version_in,
+ driver_version);
+ u8 in[MLX5_ST_SZ_BYTES(set_driver_version_in)] = {0};
+ u8 out[MLX5_ST_SZ_BYTES(set_driver_version_out)] = {0};
+ int remaining_size = driver_ver_sz;
+ char *string;
+
+ if (!MLX5_CAP_GEN(dev, driver_version))
+ return;
+
+ string = MLX5_ADDR_OF(set_driver_version_in, in, driver_version);
+
+ strncpy(string, "Linux", remaining_size);
+
+ remaining_size = max_t(int, 0, driver_ver_sz - strlen(string));
+ strncat(string, ",", remaining_size);
+
+ remaining_size = max_t(int, 0, driver_ver_sz - strlen(string));
+ strncat(string, DRIVER_NAME, remaining_size);
+
+ remaining_size = max_t(int, 0, driver_ver_sz - strlen(string));
+ strncat(string, ",", remaining_size);
+
+ remaining_size = max_t(int, 0, driver_ver_sz - strlen(string));
+ strncat(string, DRIVER_VERSION, remaining_size);
+
+ /*Send the command*/
+ MLX5_SET(set_driver_version_in, in, opcode,
+ MLX5_CMD_OP_SET_DRIVER_VERSION);
+
+ mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
+
static int set_dma_caps(struct pci_dev *pdev)
{
int err;
@@ -1015,6 +1050,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
goto err_pagealloc_stop;
}
+ mlx5_set_driver_version(dev);
+
mlx5_start_health_poll(dev);
err = mlx5_query_hca_caps(dev);
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 2/8] net/mlx5: Port module event hardware structures
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed, Leon Romanovsky
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Huy Nguyen <huyn@mellanox.com>
Add hardware structures and constants definitions needed for module
events support.
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
include/linux/mlx5/device.h | 11 +++++++++++
include/linux/mlx5/mlx5_ifc.h | 3 ++-
include/linux/mlx5/port.h | 3 +++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 5827614..52b4374 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -277,6 +277,7 @@ enum mlx5_event {
MLX5_EVENT_TYPE_INTERNAL_ERROR = 0x08,
MLX5_EVENT_TYPE_PORT_CHANGE = 0x09,
MLX5_EVENT_TYPE_GPIO_EVENT = 0x15,
+ MLX5_EVENT_TYPE_PORT_MODULE_EVENT = 0x16,
MLX5_EVENT_TYPE_REMOTE_CONFIG = 0x19,
MLX5_EVENT_TYPE_DB_BF_CONGESTION = 0x1a,
@@ -552,6 +553,15 @@ struct mlx5_eqe_vport_change {
__be32 rsvd1[6];
} __packed;
+struct mlx5_eqe_port_module {
+ u8 reserved_at_0[1];
+ u8 module;
+ u8 reserved_at_2[1];
+ u8 module_status;
+ u8 reserved_at_4[2];
+ u8 error_type;
+} __packed;
+
union ev_data {
__be32 raw[7];
struct mlx5_eqe_cmd cmd;
@@ -565,6 +575,7 @@ union ev_data {
struct mlx5_eqe_page_req req_pages;
struct mlx5_eqe_page_fault page_fault;
struct mlx5_eqe_vport_change vport_change;
+ struct mlx5_eqe_port_module port_module;
} __packed;
struct mlx5_eqe {
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 2632cb2..cd1d530 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -824,7 +824,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 early_vf_enable[0x1];
u8 reserved_at_1a9[0x2];
u8 local_ca_ack_delay[0x5];
- u8 reserved_at_1af[0x2];
+ u8 port_module_event[0x1];
+ u8 reserved_at_1b0[0x1];
u8 ports_check[0x1];
u8 reserved_at_1b2[0x1];
u8 disable_link_up[0x1];
diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
index b3065ac..dde8c7e 100644
--- a/include/linux/mlx5/port.h
+++ b/include/linux/mlx5/port.h
@@ -94,6 +94,9 @@ enum mlx5e_link_mode {
#define MLX5E_PROT_MASK(link_mode) (1 << link_mode)
+#define PORT_MODULE_EVENT_MODULE_STATUS_MASK 0xF
+#define PORT_MODULE_EVENT_ERROR_TYPE_MASK 0xF
+
int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps);
int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
int ptys_size, int proto_mask, u8 local_port);
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 4/8] net/mlx5e: Add port module event counters to ethtool stats
From: Saeed Mahameed @ 2016-11-15 21:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed
In-Reply-To: <1479245407-6884-1-git-send-email-saeedm@mellanox.com>
From: Huy Nguyen <huyn@mellanox.com>
Add port module event counters to ethtool -S command
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 23 +++++++++++++++++++++-
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | 17 ++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 27ff401..b154621 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -173,7 +173,10 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
MLX5E_NUM_RQ_STATS(priv) +
MLX5E_NUM_SQ_STATS(priv) +
- MLX5E_NUM_PFC_COUNTERS(priv);
+ MLX5E_NUM_PFC_COUNTERS(priv) +
+ ARRAY_SIZE(mlx5e_pme_status_desc) +
+ ARRAY_SIZE(mlx5e_pme_error_desc);
+
case ETH_SS_PRIV_FLAGS:
return ARRAY_SIZE(mlx5e_priv_flags);
/* fallthrough */
@@ -237,6 +240,13 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
}
}
+ /* port module event counters */
+ for (i = 0; i < ARRAY_SIZE(mlx5e_pme_status_desc); i++)
+ strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_status_desc[i].format);
+
+ for (i = 0; i < ARRAY_SIZE(mlx5e_pme_error_desc); i++)
+ strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_error_desc[i].format);
+
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return;
@@ -279,6 +289,7 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct mlx5e_priv *priv = netdev_priv(dev);
+ struct mlx5_priv *mlx5_priv;
int i, j, tc, prio, idx = 0;
unsigned long pfc_combined;
@@ -335,6 +346,16 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
}
}
+ /* port module event counters */
+ mlx5_priv = &priv->mdev->priv;
+ for (i = 0; i < ARRAY_SIZE(mlx5e_pme_status_desc); i++)
+ data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_priv->pme_stats.status_counters,
+ mlx5e_pme_status_desc, i);
+
+ for (i = 0; i < ARRAY_SIZE(mlx5e_pme_error_desc); i++)
+ data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_priv->pme_stats.error_counters,
+ mlx5e_pme_error_desc, i);
+
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
index 57452fd..b817e51 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
@@ -379,4 +379,21 @@ struct mlx5e_stats {
struct mlx5e_pport_stats pport;
};
+static const struct counter_desc mlx5e_pme_status_desc[] = {
+ { "module_plug", 0 },
+ { "module_unplug", 8 },
+};
+
+static const struct counter_desc mlx5e_pme_error_desc[] = {
+ { "module_pwr_budget_exd", 0 }, /* power budget exceed */
+ { "module_long_range", 8 }, /* long range for non MLNX cable */
+ { "module_bus_stuck", 16 }, /* bus stuck (I2C or data shorted) */
+ { "module_no_eeprom", 24 }, /* no eeprom/retry time out */
+ { "module_enforce_part", 32 }, /* enforce part number list */
+ { "module_unknown_id", 40 }, /* unknown identifier */
+ { "module_high_temp", 48 }, /* high temperature */
+ { "module_bad_shorted", 56 }, /* bad or shorted cable/module */
+ { "module_unknown_status", 64 },
+};
+
#endif /* __MLX5_EN_STATS_H__ */
--
2.7.4
^ permalink raw reply related
* Re: [PATCH 00/15] net: phy: Centralize auto-negotation restart
From: David Miller @ 2016-11-15 21:33 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, andrew, tremyfr
In-Reply-To: <20161115180644.3941-1-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Tue, 15 Nov 2016 10:06:29 -0800
> This patch series centralizes how ethtool::nway_reset is implemented
> by providing a PHYLIB function which calls into genphy_restart_aneg().
>
> All drivers below are converted to use this new helper function. Some
> other have specific requirements that make them not quite suitable for
> a straight forward conversion.
>
> There is another patch series which implements ethtool::nway_reset
> using the helper function introduced that depends on this patch
> series.
Series applied, thanks Florian.
^ permalink raw reply
* Re: [PATCH net-next] bpf: Fix compilation warning in __bpf_lru_list_rotate_inactive
From: Alexei Starovoitov @ 2016-11-15 21:44 UTC (permalink / raw)
To: Martin KaFai Lau
Cc: netdev, David Miller, Alexei Starovoitov, Daniel Borkmann,
Kernel Team
In-Reply-To: <1479236404-3906780-1-git-send-email-kafai@fb.com>
On Tue, Nov 15, 2016 at 11:00:04AM -0800, Martin KaFai Lau wrote:
> gcc-6.2.1 gives the following warning:
> kernel/bpf/bpf_lru_list.c: In function ‘__bpf_lru_list_rotate_inactive.isra.3’:
> kernel/bpf/bpf_lru_list.c:201:28: warning: ‘next’ may be used uninitialized in this function [-Wmaybe-uninitialized]
>
> The "next" is currently initialized in the while() loop which must have >=1
> iterations.
>
> This patch initializes next to get rid of the compiler warning.
>
> Fixes: 3a08c2fd7634 ("bpf: LRU List")
> Reported-by: David Miller <davem@davemloft.net>
> Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
^ permalink raw reply
* Re: [Intel-wired-lan] [PATCH v2] e1000e: free IRQ regardless of __E1000_DOWN
From: Baicar, Tyler @ 2016-11-15 21:50 UTC (permalink / raw)
To: Neftin, Sasha, jeffrey.t.kirsher, intel-wired-lan, netdev,
linux-kernel, okaya, timur
In-Reply-To: <70121f26-2d5a-528f-04f5-30a97b93a585@intel.com>
On 11/13/2016 2:25 AM, Neftin, Sasha wrote:
> On 11/13/2016 10:34 AM, Neftin, Sasha wrote:
>> On 11/11/2016 12:35 AM, Baicar, Tyler wrote:
>>> Hello Sasha,
>>>
>>> On 11/9/2016 11:19 PM, Neftin, Sasha wrote:
>>>> On 11/9/2016 11:41 PM, Tyler Baicar wrote:
>>>>> Move IRQ free code so that it will happen regardless of the
>>>>> __E1000_DOWN bit. Currently the e1000e driver only releases its IRQ
>>>>> if the __E1000_DOWN bit is cleared. This is not sufficient because
>>>>> it is possible for __E1000_DOWN to be set without releasing the IRQ.
>>>>> In such a situation, we will hit a kernel bug later in e1000_remove
>>>>> because the IRQ still has action since it was never freed. A
>>>>> secondary bus reset can cause this case to happen.
>>>>>
>>>>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>>>>> ---
>>>>> drivers/net/ethernet/intel/e1000e/netdev.c | 3 ++-
>>>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c
>>>>> b/drivers/net/ethernet/intel/e1000e/netdev.c
>>>>> index 7017281..36cfcb0 100644
>>>>> --- a/drivers/net/ethernet/intel/e1000e/netdev.c
>>>>> +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
>>>>> @@ -4679,12 +4679,13 @@ int e1000e_close(struct net_device *netdev)
>>>>> if (!test_bit(__E1000_DOWN, &adapter->state)) {
>>>>> e1000e_down(adapter, true);
>>>>> - e1000_free_irq(adapter);
>>>>> /* Link status message must follow this format */
>>>>> pr_info("%s NIC Link is Down\n", adapter->netdev->name);
>>>>> }
>>>>> + e1000_free_irq(adapter);
>>>>> +
>>>>> napi_disable(&adapter->napi);
>>>>> e1000e_free_tx_resources(adapter->tx_ring);
>>>>>
>>>> I would like not recommend insert this change. This change related
>>>> driver state machine, we afraid from lot of synchronization problem and
>>>> issues.
>>>> We need keep e1000_free_irq in loop and check for 'test_bit' ready.
>>> What do you mean here? There is no loop. If __E1000_DOWN is set then we
>>> will never free the IRQ.
>>>
>>>> Another point, does before execute secondary bus reset your SW back up
>>>> pcie configuration space as properly?
>>> After a secondary bus reset, the link needs to recover and go back to a
>>> working state after 1 second.
>>>
>>> From the callstack, the issue is happening while removing the endpoint
>>> from the system, before applying the secondary bus reset.
>>>
>>> The order of events is
>>> 1. remove the drivers
>>> 2. cause a secondary bus reset
>>> 3. wait 1 second
>> Actually, this is too much, usually link up in less than 100ms.You can
>> check Data Link Layer indication.
>>> 4. recover the link
>>>
>>> callstack:
>>> free_msi_irqs+0x6c/0x1a8
>>> pci_disable_msi+0xb0/0x148
>>> e1000e_reset_interrupt_capability+0x60/0x78
>>> e1000_remove+0xc8/0x180
>>> pci_device_remove+0x48/0x118
>>> __device_release_driver+0x80/0x108
>>> device_release_driver+0x2c/0x40
>>> pci_stop_bus_device+0xa0/0xb0
>>> pci_stop_bus_device+0x3c/0xb0
>>> pci_stop_root_bus+0x54/0x80
>>> acpi_pci_root_remove+0x28/0x64
>>> acpi_bus_trim+0x6c/0xa4
>>> acpi_device_hotplug+0x19c/0x3f4
>>> acpi_hotplug_work_fn+0x28/0x3c
>>> process_one_work+0x150/0x460
>>> worker_thread+0x50/0x4b8
>>> kthread+0xd4/0xe8
>>> ret_from_fork+0x10/0x50
>>>
>>> Thanks,
>>> Tyler
>>>
>> Hello Tyler,
>> Okay, we need consult more about this suggestion.
>> May I ask what is setup you run? Is there NIC or on board LAN? I would
>> like try reproduce this issue in our lab's too.
>> Also, is same issue observed with same scenario and others NIC's too?
>> Sasha
>> _______________________________________________
>> Intel-wired-lan mailing list
>> Intel-wired-lan@lists.osuosl.org
>> http://lists.osuosl.org/mailman/listinfo/intel-wired-lan
>>
> Please, specify what is device used.
Hello Sasha,
This was on a QDF2432 using an Intel PRO/1000 PT Dual Port server
adapter. I have not tried
other e1000e PCIe cards, but have not seen any similar issues with
Mellanox cards. I'm able to
reproduce it with just pulling the card out. Here is the lspci -vvv
output for this card:
0004:00:00.0 PCI bridge: Airgo Networks, Inc. Device 0400 (prog-if 00
[Normal decode])
Physical Slot: 5
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 297
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
I/O behind bridge: 00002000-00002fff
Memory behind bridge: 00100000-002fffff
Prefetchable memory behind bridge:
00000c0400000000-00000c04001fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0+,D1-,D2-,D3hot+,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000397f0040 Data: 0000
Capabilities: [70] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 512 bytes, PhantFunc 0
ExtTag- RBE+
DevCtl: Report errors: Correctable+ Non-Fatal+ Fatal+
Unsupported+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 256 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq-
AuxPwr- TransPend-
LnkCap: Port #0, Speed 5GT/s, Width x8, ASPM L0s L1,
Exit Latency L0s <1us, L1 <16us
ClockPM- Surprise- LLActRep+ BwNot+ ASPMOptComp+
LnkCtl: ASPM Disabled; RCB 128 bytes Disabled- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+
DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+
HotPlug+ Surprise+
Slot #5, PowerLimit 75.000W; Interlock+ NoCompl-
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt-
HPIrq- LinkChg-
Control: AttnInd Off, PwrInd Off, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt-
PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal-
PMEIntEna+ CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+,
LTR+, OBFF Not Supported ARIFwd+
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-,
LTR-, OBFF Disabled ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance-
SpeedDis-
Transmit Margin: Normal Operating Range,
EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -3.5dB,
EqualizationComplete-, EqualizationPhase1-
EqualizationPhase2-, EqualizationPhase3-,
LinkEqualizationRequest-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt-
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt-
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt-
UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
NonFatalErr+
AERCap: First Error Pointer: 00, GenCap+ CGenEn+
ChkCap+ ChkEn+
Capabilities: [178 v1] #19
Kernel driver in use: pcieport
0004:01:00.0 Ethernet controller: Intel Corporation 82571EB Gigabit
Ethernet Controller (rev 06)
Subsystem: Intel Corporation PRO/1000 PT Dual Port Server Adapter
Physical Slot: 5-1
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 128 bytes
Interrupt: pin A routed to IRQ 299
Region 0: Memory at c0100100000 (32-bit, non-prefetchable)
[size=128K]
Region 1: Memory at c0100120000 (32-bit, non-prefetchable)
[size=128K]
Region 2: I/O ports at 1000 [size=32]
Expansion ROM at c0100140000 [disabled] [size=128K]
Capabilities: [c8] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000397f0040 Data: 0000
Capabilities: [e0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s
<512ns, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset-
DevCtl: Report errors: Correctable+ Non-Fatal+ Fatal+
Unsupported+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 256 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq-
AuxPwr+ TransPend-
LnkCap: Port #8, Speed 2.5GT/s, Width x4, ASPM L0s,
Exit Latency L0s <4us, L1 <64us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+
DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt-
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt-
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt-
UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
NonFatalErr-
AERCap: First Error Pointer: 14, GenCap- CGenEn-
ChkCap- ChkEn-
Capabilities: [140 v1] Device Serial Number 68-05-ca-ff-ff-3e-5b-7a
Kernel driver in use: e1000e
0004:01:00.1 Ethernet controller: Intel Corporation 82571EB Gigabit
Ethernet Controller (rev 06)
Subsystem: Intel Corporation PRO/1000 PT Dual Port Server Adapter
Physical Slot: 5-1
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 128 bytes
Interrupt: pin B routed to IRQ 301
Region 0: Memory at c0100160000 (32-bit, non-prefetchable)
[size=128K]
Region 1: Memory at c0100180000 (32-bit, non-prefetchable)
[size=128K]
Region 2: I/O ports at 1020 [size=32]
Expansion ROM at c01001a0000 [disabled] [size=128K]
Capabilities: [c8] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000397f0040 Data: 0000
Capabilities: [e0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s
<512ns, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset-
DevCtl: Report errors: Correctable+ Non-Fatal+ Fatal+
Unsupported+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 256 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq-
AuxPwr+ TransPend-
LnkCap: Port #8, Speed 2.5GT/s, Width x4, ASPM L0s,
Exit Latency L0s <4us, L1 <64us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+
DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt-
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt-
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt-
UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
NonFatalErr-
AERCap: First Error Pointer: 14, GenCap- CGenEn-
ChkCap- ChkEn-
Capabilities: [140 v1] Device Serial Number 68-05-ca-ff-ff-3e-5b-7a
Kernel driver in use: e1000e
Thanks,
Tyler
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH] lan78xx: relocate mdix setting to phy driver
From: Woojung.Huh @ 2016-11-15 21:57 UTC (permalink / raw)
To: davem; +Cc: f.fainelli, andrew, netdev, UNGLinuxDriver
From: Woojung Huh <woojung.huh@microchip.com>
Relocate mdix code to phy driver to be called at config_init().
Signed-off-by: Woojung Huh <woojung.huh@microchip.com>
---
drivers/net/phy/microchip.c | 43 +++++++++++++++++++++++++-
drivers/net/usb/lan78xx.c | 73 ++-------------------------------------------
2 files changed, 45 insertions(+), 71 deletions(-)
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
index 7c00e50..13553df 100644
--- a/drivers/net/phy/microchip.c
+++ b/drivers/net/phy/microchip.c
@@ -106,6 +106,47 @@ static int lan88xx_set_wol(struct phy_device *phydev,
return 0;
}
+static void lan88xx_set_mdix(struct phy_device *phydev)
+{
+ int buf;
+
+ if (phydev->mdix == ETH_TP_MDI) {
+ phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
+ LAN88XX_EXT_PAGE_SPACE_1);
+ buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
+ buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
+ phy_write(phydev, LAN88XX_EXT_MODE_CTRL,
+ buf | LAN88XX_EXT_MODE_CTRL_MDI_);
+ phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
+ LAN88XX_EXT_PAGE_SPACE_0);
+ } else if (phydev->mdix == ETH_TP_MDI_X) {
+ phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
+ LAN88XX_EXT_PAGE_SPACE_1);
+ buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
+ buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
+ phy_write(phydev, LAN88XX_EXT_MODE_CTRL,
+ buf | LAN88XX_EXT_MODE_CTRL_MDI_X_);
+ phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
+ LAN88XX_EXT_PAGE_SPACE_0);
+ } else if (phydev->mdix == ETH_TP_MDI_AUTO) {
+ phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
+ LAN88XX_EXT_PAGE_SPACE_1);
+ buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
+ buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
+ phy_write(phydev, LAN88XX_EXT_MODE_CTRL,
+ buf | LAN88XX_EXT_MODE_CTRL_AUTO_MDIX_);
+ phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
+ LAN88XX_EXT_PAGE_SPACE_0);
+ }
+}
+
+static int lan88xx_config_aneg(struct phy_device *phydev)
+{
+ lan88xx_set_mdix(phydev);
+
+ return genphy_config_aneg(phydev);
+}
+
static struct phy_driver microchip_phy_driver[] = {
{
.phy_id = 0x0007c130,
@@ -120,7 +161,7 @@ static struct phy_driver microchip_phy_driver[] = {
.remove = lan88xx_remove,
.config_init = genphy_config_init,
- .config_aneg = genphy_config_aneg,
+ .config_aneg = lan88xx_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = lan88xx_phy_ack_interrupt,
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index bcd9010..affc3b4 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1476,62 +1476,12 @@ static void lan78xx_set_msglevel(struct net_device *net, u32 level)
dev->msg_enable = level;
}
-static int lan78xx_get_mdix_status(struct net_device *net)
-{
- struct phy_device *phydev = net->phydev;
- int buf;
-
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_1);
- buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0);
-
- return buf;
-}
-
-static void lan78xx_set_mdix_status(struct net_device *net, __u8 mdix_ctrl)
-{
- struct lan78xx_net *dev = netdev_priv(net);
- struct phy_device *phydev = net->phydev;
- int buf;
-
- if (mdix_ctrl == ETH_TP_MDI) {
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
- LAN88XX_EXT_PAGE_SPACE_1);
- buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
- buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
- phy_write(phydev, LAN88XX_EXT_MODE_CTRL,
- buf | LAN88XX_EXT_MODE_CTRL_MDI_);
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
- LAN88XX_EXT_PAGE_SPACE_0);
- } else if (mdix_ctrl == ETH_TP_MDI_X) {
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
- LAN88XX_EXT_PAGE_SPACE_1);
- buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
- buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
- phy_write(phydev, LAN88XX_EXT_MODE_CTRL,
- buf | LAN88XX_EXT_MODE_CTRL_MDI_X_);
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
- LAN88XX_EXT_PAGE_SPACE_0);
- } else if (mdix_ctrl == ETH_TP_MDI_AUTO) {
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
- LAN88XX_EXT_PAGE_SPACE_1);
- buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
- buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
- phy_write(phydev, LAN88XX_EXT_MODE_CTRL,
- buf | LAN88XX_EXT_MODE_CTRL_AUTO_MDIX_);
- phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS,
- LAN88XX_EXT_PAGE_SPACE_0);
- }
- dev->mdix_ctrl = mdix_ctrl;
-}
-
static int lan78xx_get_link_ksettings(struct net_device *net,
struct ethtool_link_ksettings *cmd)
{
struct lan78xx_net *dev = netdev_priv(net);
struct phy_device *phydev = net->phydev;
int ret;
- int buf;
ret = usb_autopm_get_interface(dev->intf);
if (ret < 0)
@@ -1539,20 +1489,6 @@ static int lan78xx_get_link_ksettings(struct net_device *net,
ret = phy_ethtool_ksettings_get(phydev, cmd);
- buf = lan78xx_get_mdix_status(net);
-
- buf &= LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
- if (buf == LAN88XX_EXT_MODE_CTRL_AUTO_MDIX_) {
- cmd->base.eth_tp_mdix = ETH_TP_MDI_AUTO;
- cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
- } else if (buf == LAN88XX_EXT_MODE_CTRL_MDI_) {
- cmd->base.eth_tp_mdix = ETH_TP_MDI;
- cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI;
- } else if (buf == LAN88XX_EXT_MODE_CTRL_MDI_X_) {
- cmd->base.eth_tp_mdix = ETH_TP_MDI_X;
- cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_X;
- }
-
usb_autopm_put_interface(dev->intf);
return ret;
@@ -1570,9 +1506,6 @@ static int lan78xx_set_link_ksettings(struct net_device *net,
if (ret < 0)
return ret;
- if (dev->mdix_ctrl != cmd->base.eth_tp_mdix_ctrl)
- lan78xx_set_mdix_status(net, cmd->base.eth_tp_mdix_ctrl);
-
/* change speed & duplex */
ret = phy_ethtool_ksettings_set(phydev, cmd);
@@ -2024,6 +1957,9 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
phydev->irq = 0;
netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq);
+ /* set to AUTOMDIX */
+ phydev->mdix = ETH_TP_MDI_AUTO;
+
ret = phy_connect_direct(dev->net, phydev,
lan78xx_link_status_change,
PHY_INTERFACE_MODE_GMII);
@@ -2033,9 +1969,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
return -EIO;
}
- /* set to AUTOMDIX */
- lan78xx_set_mdix_status(dev->net, ETH_TP_MDI_AUTO);
-
/* MAC doesn't support 1000T Half */
phydev->supported &= ~SUPPORTED_1000baseT_Half;
--
2.7.4
^ permalink raw reply related
* Re: [net-next 1/2] net: ethernet: slicoss: add slicoss gigabit ethernet driver
From: Andrew Lunn @ 2016-11-15 21:59 UTC (permalink / raw)
To: Lino Sanfilippo
Cc: Florian Fainelli, davem, charrer, liodot, gregkh, devel,
linux-kernel, netdev
In-Reply-To: <0d1b4dee-11bb-3605-699c-ea417484cb68@gmx.de>
> The link state is retrieved by a command to the application processor that is running
> on the network card. Also the register to set the phy configuration is write-only, so
> it is not even possible to do the usual mdio bit-banging in the Phy read() and write()
> functions (however there seems to be another application processor command reserved
> for retrieving the PHY settings, but I have not tried it yet).
>> + val = MII_BMCR << 16 | SLIC_PCR_AUTONEG |
>> + SLIC_PCR_AUTONEG_RST;
>> + slic_write(sdev, SLIC_REG_WPHY, val);
This actually looks a lot like an MDIO write operation. The upper 16
bits are the register, and the lower 16 bits are the data. What you
don't have is the address. But maybe it is limited to one address.
If the processor command reserved for read works in a similar way, you
have enough to do an MDIO bus.
> Please also note that I do not have any datasheets or other documentation for the hardware,
> all I have as a reference is the driver code in staging. So I do not know which
> PHYs are actually used (the comments in the code mention Marvell and Cicada but this is
> not very specific).
If you can get the read working look at registers 2 and 3. Compare
what you get with the values at the end of marvell.c.
Andrew
^ permalink raw reply
* Re: [PATCH] net: bnx2: use new api ethtool_{get|set}_link_ksettings
From: David Miller @ 2016-11-15 22:05 UTC (permalink / raw)
To: tremyfr; +Cc: rasesh.mody, harish.patil, Dept-GELinuxNICDev, netdev,
linux-kernel
In-Reply-To: <1479076426-9024-1-git-send-email-tremyfr@gmail.com>
From: Philippe Reynes <tremyfr@gmail.com>
Date: Sun, 13 Nov 2016 23:33:46 +0100
> The ethtool api {get|set}_settings is deprecated.
> We move this driver to new api {get|set}_link_ksettings.
>
> Signed-off-by: Philippe Reynes <tremyfr@gmail.com>
Applied.
^ permalink raw reply
* [PATCH net-next 0/2] amd-xgbe: AMD XGBE driver updates 2016-11-15
From: Tom Lendacky @ 2016-11-15 22:10 UTC (permalink / raw)
To: netdev; +Cc: colin.king, David Miller, dan.carpenter
This patch series addresses some minor issues found in the recently
accepted patch series for the AMD XGBE driver.
The following fixes are included in this driver update series:
- Fix a possibly uninitialized variable in the debugfs support
- Fix the GPIO pin number constraint check
This patch series is based on net-next.
---
Tom Lendacky (2):
amd-xgbe: Fix possible uninitialized variable
amd-xgbe: Fix maximum GPIO value check
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | 2 +-
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
--
Tom Lendacky
^ permalink raw reply
* [PATCH net-next 1/2] amd-xgbe: Fix possible uninitialized variable
From: Tom Lendacky @ 2016-11-15 22:11 UTC (permalink / raw)
To: netdev; +Cc: colin.king, David Miller, dan.carpenter
In-Reply-To: <20161115221055.12403.90574.stgit@tlendack-t1.amdoffice.net>
The debugfs support in the driver uses a common routine to write the
debugfs values. In this routine, if the input file position is non-zero
then the write routine will not return an error and an output parameter
will not have been set. Because an error isn't returned an uninitialized
value will be written into a register.
Fix the common write routine to return an error if the input file position
is non-zero, which will propagate back to the caller.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
index 0c0140d..7546b66 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
@@ -153,7 +153,7 @@ static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
int ret;
if (*ppos != 0)
- return 0;
+ return -EINVAL;
if (count >= sizeof(workarea))
return -ENOSPC;
^ permalink raw reply related
* [PATCH net-next 2/2] amd-xgbe: Fix maximum GPIO value check
From: Tom Lendacky @ 2016-11-15 22:11 UTC (permalink / raw)
To: netdev; +Cc: colin.king, David Miller, dan.carpenter
In-Reply-To: <20161115221055.12403.90574.stgit@tlendack-t1.amdoffice.net>
The GPIO support in the hardware allows for up to 16 GPIO pins, enumerated
from 0 to 15. The driver uses the wrong value (16) to validate the GPIO
pin range in the routines to set and clear the GPIO output pins. Update
the code to use the correct value (15).
Reported-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 30056e2..aaf0350 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1099,7 +1099,7 @@ static int xgbe_clr_gpio(struct xgbe_prv_data *pdata, unsigned int gpio)
{
unsigned int reg;
- if (gpio > 16)
+ if (gpio > 15)
return -EINVAL;
reg = XGMAC_IOREAD(pdata, MAC_GPIOSR);
@@ -1114,7 +1114,7 @@ static int xgbe_set_gpio(struct xgbe_prv_data *pdata, unsigned int gpio)
{
unsigned int reg;
- if (gpio > 16)
+ if (gpio > 15)
return -EINVAL;
reg = XGMAC_IOREAD(pdata, MAC_GPIOSR);
^ permalink raw reply related
* Re: linux-next: net->netns_ids is used after calling idr_destroy for it
From: Andrei Vagin @ 2016-11-15 22:21 UTC (permalink / raw)
To: Cong Wang; +Cc: Nicolas Dichtel, Linux Kernel Network Developers
In-Reply-To: <CAM_iQpXYvGnaf=AAD5EJYqQ7WApjRyUResN+0Z_Bq1Xt8G8zQQ@mail.gmail.com>
On Tue, Nov 15, 2016 at 1:07 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Tue, Nov 15, 2016 at 12:48 PM, Andrei Vagin <avagin@gmail.com> wrote:
>> On Tue, Nov 15, 2016 at 10:50 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>> On Tue, Nov 15, 2016 at 10:04 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>>> On Mon, Nov 14, 2016 at 10:23 PM, Andrei Vagin <avagin@gmail.com> wrote:
>>>>> Hi Nicolas,
>>>>>
>>>>> cleanup_net() calls idr_destroy(net->netns_ids) for network namespaces
>>>>> and then it calls unregister_netdevice_many() which calls
>>>>> idr_alloc(net0>netns_ids). It looks wrong, doesn't it?
>>>>>
>>>>
>>>> netns id is designed to allocate lazily, but yeah it makes no sense
>>>> to allocate id for the netns being destroyed, not to mention idr is freed.
>>>>
>>>> I will send a patch.
>>>
>>> Could you try the attached patch? I just did some quick netns creation/destroy
>>> tests.
>>
>> Here is another fail:
>>
>> unreferenced object 0xffff94153912a0c0 (size 2096):
>> comm "ip", pid 29175, jiffies 4294954213 (age 137.624s)
>> hex dump (first 32 bytes):
>> 00 00 00 00 00 00 00 00 00 b2 3b 1d 15 94 ff ff ..........;.....
>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
>> backtrace:
>> [<ffffffffac865c1a>] kmemleak_alloc+0x4a/0xa0
>> [<ffffffffac243b38>] kmem_cache_alloc+0x128/0x280
>> [<ffffffffac42f5ab>] idr_layer_alloc+0x2b/0x90
>> [<ffffffffac42f9cd>] idr_get_empty_slot+0x34d/0x370
>> [<ffffffffac42fa4e>] idr_alloc+0x5e/0x110
>> [<ffffffffac70ac3d>] __peernet2id_alloc+0x6d/0x90
>> [<ffffffffac70bda5>] peernet2id_alloc+0x55/0xb0
>> [<ffffffffac731246>] rtnl_fill_ifinfo+0xaa6/0x10a0
>> [<ffffffffac7330a3>] rtmsg_ifinfo_build_skb+0x73/0xd0
>> [<ffffffffac7125e1>] rollback_registered_many+0x2a1/0x3a0
>> [<ffffffffac712779>] __unregister_netdevice_many+0x29/0x80
>> [<ffffffffac7127e3>] unregister_netdevice_many+0x13/0x20
>> [<ffffffffc02dc4ce>] macvlan_device_event+0x13e/0x235 [macvlan]
>> [<ffffffffac0bef2a>] notifier_call_chain+0x4a/0x70
>> [<ffffffffac0bf066>] raw_notifier_call_chain+0x16/0x20
>> [<ffffffffac710205>] call_netdevice_notifiers_info+0x35/0x60
>>
>
> Oh, drivers send rtmsg in notifiers too, hmm.
>
>>
>> What do you think about calling idr_destroy() at the final step in
>> cleanup_net()? In this case we can avoid this sort of problems in a
>> future.
>
> This was my first idea too, but it looks more risky than my approach.
>
> Also, rtmsg is really not needed because the netns is being destroyed,
> no one cares about it here.
I would like to agree with you here, but looks like sockets with
NETLINK_F_LISTEN_ALL_NSID are able to catch these messages.
^ permalink raw reply
* Re: [net-next 1/2] net: ethernet: slicoss: add slicoss gigabit ethernet driver
From: Lino Sanfilippo @ 2016-11-15 22:34 UTC (permalink / raw)
To: Andrew Lunn
Cc: Florian Fainelli, davem, charrer, liodot, gregkh, devel,
linux-kernel, netdev
In-Reply-To: <20161115215907.GF23231@lunn.ch>
On 15.11.2016 22:59, Andrew Lunn wrote:
>> The link state is retrieved by a command to the application processor that is running
>> on the network card. Also the register to set the phy configuration is write-only, so
>> it is not even possible to do the usual mdio bit-banging in the Phy read() and write()
>> functions (however there seems to be another application processor command reserved
>> for retrieving the PHY settings, but I have not tried it yet).
>
>>> + val = MII_BMCR << 16 | SLIC_PCR_AUTONEG |
>>> + SLIC_PCR_AUTONEG_RST;
>>> + slic_write(sdev, SLIC_REG_WPHY, val);
>
> This actually looks a lot like an MDIO write operation. The upper 16
> bits are the register, and the lower 16 bits are the data. What you
> don't have is the address. But maybe it is limited to one address.
>
> If the processor command reserved for read works in a similar way, you
> have enough to do an MDIO bus.
>
Ok, I will give it a try. Reading values via the application processor
is a bit awkward though, since it requires an address to a dma area as part of
the command and then the AP informs the driver via irq that the dma memory has
been written. So probably the irq handler will have to set some flag and
the mdio_read() function will have to poll for that flag in place of doing
bit-banging a register.
> If you can get the read working look at registers 2 and 3. Compare
> what you get with the values at the end of marvell.c.
>
Will do, thank you!
Lino
^ permalink raw reply
* Re: [net-next 1/2] net: ethernet: slicoss: add slicoss gigabit ethernet driver
From: Florian Fainelli @ 2016-11-15 22:39 UTC (permalink / raw)
To: Lino Sanfilippo, Andrew Lunn
Cc: davem, charrer, liodot, gregkh, devel, linux-kernel, netdev
In-Reply-To: <86165d2b-f9d5-a380-9bb0-f77c12691eb6@gmx.de>
On 11/15/2016 02:34 PM, Lino Sanfilippo wrote:
> On 15.11.2016 22:59, Andrew Lunn wrote:
>>> The link state is retrieved by a command to the application processor that is running
>>> on the network card. Also the register to set the phy configuration is write-only, so
>>> it is not even possible to do the usual mdio bit-banging in the Phy read() and write()
>>> functions (however there seems to be another application processor command reserved
>>> for retrieving the PHY settings, but I have not tried it yet).
>>
>>>> + val = MII_BMCR << 16 | SLIC_PCR_AUTONEG |
>>>> + SLIC_PCR_AUTONEG_RST;
>>>> + slic_write(sdev, SLIC_REG_WPHY, val);
>>
>> This actually looks a lot like an MDIO write operation. The upper 16
>> bits are the register, and the lower 16 bits are the data. What you
>> don't have is the address. But maybe it is limited to one address.
>>
>> If the processor command reserved for read works in a similar way, you
>> have enough to do an MDIO bus.
>>
>
> Ok, I will give it a try. Reading values via the application processor
> is a bit awkward though, since it requires an address to a dma area as part of
> the command and then the AP informs the driver via irq that the dma memory has
> been written. So probably the irq handler will have to set some flag and
> the mdio_read() function will have to poll for that flag in place of doing
> bit-banging a register.
That's a bit unusual compared to typical controllers that are usually
memory-mapped and that you can either write to, read/poll to know about
completion. I suppose that you could still have a mdiobus implementation
that is able to read to/from PHYs by submitting a command to the AP,
wait on a completion structure, and have the interrupt handler do the
completion of the command?
--
Florian
^ permalink raw reply
* Re: linux-next: net->netns_ids is used after calling idr_destroy for it
From: Andrei Vagin @ 2016-11-15 22:45 UTC (permalink / raw)
To: Cong Wang; +Cc: Nicolas Dichtel, Linux Kernel Network Developers
In-Reply-To: <CANaxB-y0_veL0hfdskXrix66FzydTSQ=MXOkmw72RsFqcXj9Pw@mail.gmail.com>
On Tue, Nov 15, 2016 at 2:21 PM, Andrei Vagin <avagin@gmail.com> wrote:
> On Tue, Nov 15, 2016 at 1:07 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>> On Tue, Nov 15, 2016 at 12:48 PM, Andrei Vagin <avagin@gmail.com> wrote:
>>> On Tue, Nov 15, 2016 at 10:50 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>>> On Tue, Nov 15, 2016 at 10:04 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>>>> On Mon, Nov 14, 2016 at 10:23 PM, Andrei Vagin <avagin@gmail.com> wrote:
>>>>>> Hi Nicolas,
>>>>>>
>>>>>> cleanup_net() calls idr_destroy(net->netns_ids) for network namespaces
>>>>>> and then it calls unregister_netdevice_many() which calls
>>>>>> idr_alloc(net0>netns_ids). It looks wrong, doesn't it?
>>>>>>
>>>>>
>>>>> netns id is designed to allocate lazily, but yeah it makes no sense
>>>>> to allocate id for the netns being destroyed, not to mention idr is freed.
>>>>>
>>>>> I will send a patch.
>>>>
>>>> Could you try the attached patch? I just did some quick netns creation/destroy
>>>> tests.
>>>
>>> Here is another fail:
>>>
>>> unreferenced object 0xffff94153912a0c0 (size 2096):
>>> comm "ip", pid 29175, jiffies 4294954213 (age 137.624s)
>>> hex dump (first 32 bytes):
>>> 00 00 00 00 00 00 00 00 00 b2 3b 1d 15 94 ff ff ..........;.....
>>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
>>> backtrace:
>>> [<ffffffffac865c1a>] kmemleak_alloc+0x4a/0xa0
>>> [<ffffffffac243b38>] kmem_cache_alloc+0x128/0x280
>>> [<ffffffffac42f5ab>] idr_layer_alloc+0x2b/0x90
>>> [<ffffffffac42f9cd>] idr_get_empty_slot+0x34d/0x370
>>> [<ffffffffac42fa4e>] idr_alloc+0x5e/0x110
>>> [<ffffffffac70ac3d>] __peernet2id_alloc+0x6d/0x90
>>> [<ffffffffac70bda5>] peernet2id_alloc+0x55/0xb0
>>> [<ffffffffac731246>] rtnl_fill_ifinfo+0xaa6/0x10a0
>>> [<ffffffffac7330a3>] rtmsg_ifinfo_build_skb+0x73/0xd0
>>> [<ffffffffac7125e1>] rollback_registered_many+0x2a1/0x3a0
>>> [<ffffffffac712779>] __unregister_netdevice_many+0x29/0x80
>>> [<ffffffffac7127e3>] unregister_netdevice_many+0x13/0x20
>>> [<ffffffffc02dc4ce>] macvlan_device_event+0x13e/0x235 [macvlan]
>>> [<ffffffffac0bef2a>] notifier_call_chain+0x4a/0x70
>>> [<ffffffffac0bf066>] raw_notifier_call_chain+0x16/0x20
>>> [<ffffffffac710205>] call_netdevice_notifiers_info+0x35/0x60
>>>
>>
>> Oh, drivers send rtmsg in notifiers too, hmm.
>>
>>>
>>> What do you think about calling idr_destroy() at the final step in
>>> cleanup_net()? In this case we can avoid this sort of problems in a
>>> future.
>>
>> This was my first idea too, but it looks more risky than my approach.
>>
>> Also, rtmsg is really not needed because the netns is being destroyed,
>> no one cares about it here.
>
> I would like to agree with you here, but looks like sockets with
> NETLINK_F_LISTEN_ALL_NSID are able to catch these messages.
Actually I found that I was wrong.
do_one_broadcast() sends a notification only if a device network
namespace has an id in a socket netns. But cleanup_net() removes all
id-s to a target namespace, so just ignore my last comment.
Thanks,
Andrei
^ permalink raw reply
* Re: [net-next 1/2] net: ethernet: slicoss: add slicoss gigabit ethernet driver
From: Lino Sanfilippo @ 2016-11-15 22:54 UTC (permalink / raw)
To: Florian Fainelli, Andrew Lunn
Cc: davem, charrer, liodot, gregkh, devel, linux-kernel, netdev
In-Reply-To: <41c0c732-0935-1625-b88d-c084e5000a6c@gmail.com>
On 15.11.2016 23:39, Florian Fainelli wrote:
> On 11/15/2016 02:34 PM, Lino Sanfilippo wrote:
>> On 15.11.2016 22:59, Andrew Lunn wrote:
>>>> The link state is retrieved by a command to the application processor that is running
>>>> on the network card. Also the register to set the phy configuration is write-only, so
>>>> it is not even possible to do the usual mdio bit-banging in the Phy read() and write()
>>>> functions (however there seems to be another application processor command reserved
>>>> for retrieving the PHY settings, but I have not tried it yet).
>>>
>>>>> + val = MII_BMCR << 16 | SLIC_PCR_AUTONEG |
>>>>> + SLIC_PCR_AUTONEG_RST;
>>>>> + slic_write(sdev, SLIC_REG_WPHY, val);
>>>
>>> This actually looks a lot like an MDIO write operation. The upper 16
>>> bits are the register, and the lower 16 bits are the data. What you
>>> don't have is the address. But maybe it is limited to one address.
>>>
>>> If the processor command reserved for read works in a similar way, you
>>> have enough to do an MDIO bus.
>>>
>>
>> Ok, I will give it a try. Reading values via the application processor
>> is a bit awkward though, since it requires an address to a dma area as part of
>> the command and then the AP informs the driver via irq that the dma memory has
>> been written. So probably the irq handler will have to set some flag and
>> the mdio_read() function will have to poll for that flag in place of doing
>> bit-banging a register.
>
> That's a bit unusual compared to typical controllers that are usually
> memory-mapped and that you can either write to, read/poll to know about
> completion. I suppose that you could still have a mdiobus implementation
> that is able to read to/from PHYs by submitting a command to the AP,
> wait on a completion structure, and have the interrupt handler do the
> completion of the command?
>
Thats essentially what I meant by setting a flag in the irq handler. The mdio
function would have to check somehow if the irq has been fired (be it by means
of a flag or a completion that is set by the irq handler and checked by the
mdio function). So I agree that it should work (if reading via the AP command
is actually possible).
Lino
^ permalink raw reply
* Re: [net-next 1/2] net: ethernet: slicoss: add slicoss gigabit ethernet driver
From: Andrew Lunn @ 2016-11-15 23:03 UTC (permalink / raw)
To: Lino Sanfilippo
Cc: devel, Florian Fainelli, gregkh, linux-kernel, liodot, netdev,
davem
In-Reply-To: <c645c726-dbe2-108d-c79a-d8db350a13b8@gmx.de>
> >>>>> + val = MII_BMCR << 16 | SLIC_PCR_AUTONEG |
> >>>>> + SLIC_PCR_AUTONEG_RST;
> >>>>> + slic_write(sdev, SLIC_REG_WPHY, val);
> Thats essentially what I meant by setting a flag in the irq handler. The mdio
> function would have to check somehow if the irq has been fired (be it by means
> of a flag or a completion that is set by the irq handler and checked by the
> mdio function). So I agree that it should work (if reading via the AP command
> is actually possible).
It seems odd you have a nice simple way to do writes, but reads are
very complex. There might be a simple read method hiding somewhere.
Andrew
^ permalink raw reply
* Re: [net-next 1/2] net: ethernet: slicoss: add slicoss gigabit ethernet driver
From: Lino Sanfilippo @ 2016-11-15 23:14 UTC (permalink / raw)
To: Andrew Lunn
Cc: devel, Florian Fainelli, gregkh, linux-kernel, liodot, netdev,
davem
In-Reply-To: <20161115230317.GG23231@lunn.ch>
On 16.11.2016 00:03, Andrew Lunn wrote:
>> >>>>> + val = MII_BMCR << 16 | SLIC_PCR_AUTONEG |
>> >>>>> + SLIC_PCR_AUTONEG_RST;
>> >>>>> + slic_write(sdev, SLIC_REG_WPHY, val);
>
>> Thats essentially what I meant by setting a flag in the irq handler. The mdio
>> function would have to check somehow if the irq has been fired (be it by means
>> of a flag or a completion that is set by the irq handler and checked by the
>> mdio function). So I agree that it should work (if reading via the AP command
>> is actually possible).
>
> It seems odd you have a nice simple way to do writes, but reads are
> very complex. There might be a simple read method hiding somewhere.
>
> Andrew
>
I agree, it IS odd :).
But concerning reading the phy this is all I can see in the original source code:
http://lxr.free-electrons.com/source/drivers/staging/slicoss/slichw.h#L516
I strongly suspect that "RPHY" stand for "read phy". The only one who may
know for sure if there is another/better way is Christopher Harrer. He is also on CC
but I am not sure if he actually follows this discussion.
Lino
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox