1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */
6 #include <linux/init.h>
7 #include <linux/jiffies.h>
8 #include <linux/kernel.h>
9 #include <linux/mutex.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/slab.h>
18 #define MLXSW_I2C_CIR2_BASE 0x72000
19 #define MLXSW_I2C_CIR_STATUS_OFF 0x18
20 #define MLXSW_I2C_CIR2_OFF_STATUS (MLXSW_I2C_CIR2_BASE + \
21 MLXSW_I2C_CIR_STATUS_OFF)
22 #define MLXSW_I2C_OPMOD_SHIFT 12
23 #define MLXSW_I2C_GO_BIT_SHIFT 23
24 #define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
25 #define MLXSW_I2C_GO_BIT BIT(MLXSW_I2C_GO_BIT_SHIFT)
26 #define MLXSW_I2C_GO_OPMODE BIT(MLXSW_I2C_OPMOD_SHIFT)
27 #define MLXSW_I2C_SET_IMM_CMD (MLXSW_I2C_GO_OPMODE | \
28 MLXSW_CMD_OPCODE_QUERY_FW)
29 #define MLXSW_I2C_PUSH_IMM_CMD (MLXSW_I2C_GO_BIT | \
30 MLXSW_I2C_SET_IMM_CMD)
31 #define MLXSW_I2C_SET_CMD (MLXSW_CMD_OPCODE_ACCESS_REG)
32 #define MLXSW_I2C_PUSH_CMD (MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)
33 #define MLXSW_I2C_TLV_HDR_SIZE 0x10
34 #define MLXSW_I2C_ADDR_WIDTH 4
35 #define MLXSW_I2C_PUSH_CMD_SIZE (MLXSW_I2C_ADDR_WIDTH + 4)
36 #define MLXSW_I2C_READ_SEMA_SIZE 4
37 #define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28)
38 #define MLXSW_I2C_MBOX_SIZE 20
39 #define MLXSW_I2C_MBOX_OUT_PARAM_OFF 12
40 #define MLXSW_I2C_MAX_BUFF_SIZE 32
41 #define MLXSW_I2C_MBOX_OFFSET_BITS 20
42 #define MLXSW_I2C_MBOX_SIZE_BITS 12
43 #define MLXSW_I2C_ADDR_BUF_SIZE 4
44 #define MLXSW_I2C_BLK_MAX 32
45 #define MLXSW_I2C_RETRY 5
46 #define MLXSW_I2C_TIMEOUT_MSECS 5000
49 * struct mlxsw_i2c - device private data:
50 * @cmd.mb_size_in: input mailbox size;
51 * @cmd.mb_off_in: input mailbox offset in register space;
52 * @cmd.mb_size_out: output mailbox size;
53 * @cmd.mb_off_out: output mailbox offset in register space;
54 * @cmd.lock: command execution lock;
56 * @core: switch core pointer;
57 * @bus_info: bus info block;
68 struct mlxsw_core *core;
69 struct mlxsw_bus_info bus_info;
72 #define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
73 { .addr = (_client)->addr, \
75 .len = MLXSW_I2C_ADDR_BUF_SIZE, \
77 { .addr = (_client)->addr, \
82 #define MLXSW_I2C_WRITE_MSG(_client, _buf, _len) \
83 { .addr = (_client)->addr, \
84 .buf = (u8 *)(_buf), \
88 /* Routine converts in and out mail boxes offset and size. */
90 mlxsw_i2c_convert_mbox(struct mlxsw_i2c *mlxsw_i2c, u8 *buf)
94 /* Local in/out mailboxes: 20 bits for offset, 12 for size */
95 tmp = be32_to_cpup((__be32 *) buf);
96 mlxsw_i2c->cmd.mb_off_in = tmp &
97 GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
98 mlxsw_i2c->cmd.mb_size_in = (tmp & GENMASK(31,
99 MLXSW_I2C_MBOX_OFFSET_BITS)) >>
100 MLXSW_I2C_MBOX_OFFSET_BITS;
102 tmp = be32_to_cpup((__be32 *) (buf + MLXSW_I2C_ADDR_WIDTH));
103 mlxsw_i2c->cmd.mb_off_out = tmp &
104 GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
105 mlxsw_i2c->cmd.mb_size_out = (tmp & GENMASK(31,
106 MLXSW_I2C_MBOX_OFFSET_BITS)) >>
107 MLXSW_I2C_MBOX_OFFSET_BITS;
110 /* Routine obtains register size from mail box buffer. */
111 static inline int mlxsw_i2c_get_reg_size(u8 *in_mbox)
113 u16 tmp = be16_to_cpup((__be16 *) (in_mbox + MLXSW_I2C_TLV_HDR_SIZE));
115 return (tmp & 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE;
118 /* Routine sets I2C device internal offset in the transaction buffer. */
119 static inline void mlxsw_i2c_set_slave_addr(u8 *buf, u32 off)
121 __be32 *val = (__be32 *) buf;
126 /* Routine waits until go bit is cleared. */
127 static int mlxsw_i2c_wait_go_bit(struct i2c_client *client,
128 struct mlxsw_i2c *mlxsw_i2c, u8 *p_status)
130 u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
131 u8 buf[MLXSW_I2C_READ_SEMA_SIZE];
132 int len = MLXSW_I2C_READ_SEMA_SIZE;
133 struct i2c_msg read_sema[] =
134 MLXSW_I2C_READ_MSG(client, addr_buf, buf, len);
135 bool wait_done = false;
139 mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_OFF_STATUS);
141 end = jiffies + msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
145 err = i2c_transfer(client->adapter, read_sema,
146 ARRAY_SIZE(read_sema));
148 ctrl = be32_to_cpu(*(__be32 *) buf);
149 if (err == ARRAY_SIZE(read_sema)) {
150 if (!(ctrl & MLXSW_I2C_GO_BIT)) {
153 MLXSW_I2C_CIR_CTRL_STATUS_SHIFT;
158 } while ((time_before(jiffies, end)) || (i++ < MLXSW_I2C_RETRY));
167 return err > 0 ? 0 : err;
170 /* Routine posts a command to ASIC though mail box. */
171 static int mlxsw_i2c_write_cmd(struct i2c_client *client,
172 struct mlxsw_i2c *mlxsw_i2c,
175 __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
176 0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD)
178 __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
180 cpu_to_be32(client->adapter->nr & 0xffff),
181 cpu_to_be32(MLXSW_I2C_SET_IMM_CMD)
183 struct i2c_msg push_cmd =
184 MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
185 MLXSW_I2C_PUSH_CMD_SIZE);
186 struct i2c_msg prep_cmd =
187 MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
191 push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD);
192 prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_SET_CMD);
194 mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
195 MLXSW_I2C_CIR2_BASE);
196 mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
197 MLXSW_I2C_CIR2_OFF_STATUS);
199 /* Prepare Command Interface Register for transaction */
200 err = i2c_transfer(client->adapter, &prep_cmd, 1);
206 /* Write out Command Interface Register GO bit to push transaction */
207 err = i2c_transfer(client->adapter, &push_cmd, 1);
216 /* Routine obtains mail box offsets from ASIC register space. */
217 static int mlxsw_i2c_get_mbox(struct i2c_client *client,
218 struct mlxsw_i2c *mlxsw_i2c)
220 u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
221 u8 buf[MLXSW_I2C_MBOX_SIZE];
222 struct i2c_msg mbox_cmd[] =
223 MLXSW_I2C_READ_MSG(client, addr_buf, buf, MLXSW_I2C_MBOX_SIZE);
226 /* Read mail boxes offsets. */
227 mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_BASE);
228 err = i2c_transfer(client->adapter, mbox_cmd, 2);
230 dev_err(&client->dev, "Could not obtain mail boxes\n");
237 /* Convert mail boxes. */
238 mlxsw_i2c_convert_mbox(mlxsw_i2c, &buf[MLXSW_I2C_MBOX_OUT_PARAM_OFF]);
243 /* Routine sends I2C write transaction to ASIC device. */
245 mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
248 struct i2c_client *client = to_i2c_client(dev);
249 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
250 unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
251 u8 tran_buf[MLXSW_I2C_MAX_BUFF_SIZE + MLXSW_I2C_ADDR_BUF_SIZE];
252 int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
254 struct i2c_msg write_tran =
255 MLXSW_I2C_WRITE_MSG(client, tran_buf, MLXSW_I2C_PUSH_CMD_SIZE);
258 for (i = 0; i < num; i++) {
259 chunk_size = (in_mbox_size > MLXSW_I2C_BLK_MAX) ?
260 MLXSW_I2C_BLK_MAX : in_mbox_size;
261 write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
262 mlxsw_i2c_set_slave_addr(tran_buf, off);
263 memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
264 MLXSW_I2C_BLK_MAX * i, chunk_size);
267 end = jiffies + timeout;
269 err = i2c_transfer(client->adapter, &write_tran, 1);
274 } while ((time_before(jiffies, end)) ||
275 (j++ < MLXSW_I2C_RETRY));
284 in_mbox_size -= chunk_size;
287 /* Prepare and write out Command Interface Register for transaction. */
288 err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
290 dev_err(&client->dev, "Could not start transaction");
294 /* Wait until go bit is cleared. */
295 err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
297 dev_err(&client->dev, "HW semaphore is not released");
301 /* Validate transaction completion status. */
303 dev_err(&client->dev, "Bad transaction completion status %x\n",
311 /* Routine executes I2C command. */
313 mlxsw_i2c_cmd(struct device *dev, size_t in_mbox_size, u8 *in_mbox,
314 size_t out_mbox_size, u8 *out_mbox, u8 *status)
316 struct i2c_client *client = to_i2c_client(dev);
317 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
318 unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
319 u8 tran_buf[MLXSW_I2C_ADDR_BUF_SIZE];
320 int num, chunk_size, reg_size, i, j;
321 int off = mlxsw_i2c->cmd.mb_off_out;
323 struct i2c_msg read_tran[] =
324 MLXSW_I2C_READ_MSG(client, tran_buf, NULL, 0);
327 WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
329 reg_size = mlxsw_i2c_get_reg_size(in_mbox);
330 num = reg_size / MLXSW_I2C_BLK_MAX;
331 if (reg_size % MLXSW_I2C_BLK_MAX)
334 if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
335 dev_err(&client->dev, "Could not acquire lock");
339 err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
343 /* No out mailbox is case of write transaction. */
345 mutex_unlock(&mlxsw_i2c->cmd.lock);
349 /* Send read transaction to get output mailbox content. */
350 read_tran[1].buf = out_mbox;
351 for (i = 0; i < num; i++) {
352 chunk_size = (reg_size > MLXSW_I2C_BLK_MAX) ?
353 MLXSW_I2C_BLK_MAX : reg_size;
354 read_tran[1].len = chunk_size;
355 mlxsw_i2c_set_slave_addr(tran_buf, off);
358 end = jiffies + timeout;
360 err = i2c_transfer(client->adapter, read_tran,
361 ARRAY_SIZE(read_tran));
362 if (err == ARRAY_SIZE(read_tran))
366 } while ((time_before(jiffies, end)) ||
367 (j++ < MLXSW_I2C_RETRY));
369 if (err != ARRAY_SIZE(read_tran)) {
377 reg_size -= chunk_size;
378 read_tran[1].buf += chunk_size;
381 mutex_unlock(&mlxsw_i2c->cmd.lock);
386 mutex_unlock(&mlxsw_i2c->cmd.lock);
390 static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
391 u32 in_mod, bool out_mbox_direct,
392 char *in_mbox, size_t in_mbox_size,
393 char *out_mbox, size_t out_mbox_size,
396 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
398 return mlxsw_i2c_cmd(mlxsw_i2c->dev, in_mbox_size, in_mbox,
399 out_mbox_size, out_mbox, status);
402 static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,
403 const struct mlxsw_tx_info *tx_info)
408 static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,
409 const struct mlxsw_tx_info *tx_info)
415 mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
416 const struct mlxsw_config_profile *profile,
417 struct mlxsw_res *resources)
419 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
421 mlxsw_i2c->core = mlxsw_core;
426 static void mlxsw_i2c_fini(void *bus_priv)
428 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
430 mlxsw_i2c->core = NULL;
433 static const struct mlxsw_bus mlxsw_i2c_bus = {
435 .init = mlxsw_i2c_init,
436 .fini = mlxsw_i2c_fini,
437 .skb_transmit_busy = mlxsw_i2c_skb_transmit_busy,
438 .skb_transmit = mlxsw_i2c_skb_transmit,
439 .cmd_exec = mlxsw_i2c_cmd_exec,
442 static int mlxsw_i2c_probe(struct i2c_client *client,
443 const struct i2c_device_id *id)
445 struct mlxsw_i2c *mlxsw_i2c;
449 mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);
453 i2c_set_clientdata(client, mlxsw_i2c);
454 mutex_init(&mlxsw_i2c->cmd.lock);
456 /* In order to use mailboxes through the i2c, special area is reserved
457 * on the i2c address space that can be used for input and output
458 * mailboxes. Such mailboxes are called local mailboxes. When using a
459 * local mailbox, software should specify 0 as the Input/Output
460 * parameters. The location of the Local Mailbox addresses on the i2c
461 * space can be retrieved through the QUERY_FW command.
462 * For this purpose QUERY_FW is to be issued with opcode modifier equal
463 * 0x01. For such command the output parameter is an immediate value.
464 * Here QUERY_FW command is invoked for ASIC probing and for getting
465 * local mailboxes addresses from immedate output parameters.
468 /* Prepare and write out Command Interface Register for transaction */
469 err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 1);
471 dev_err(&client->dev, "Could not start transaction");
475 /* Wait until go bit is cleared. */
476 err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
478 dev_err(&client->dev, "HW semaphore is not released");
482 /* Validate transaction completion status. */
484 dev_err(&client->dev, "Bad transaction completion status %x\n",
490 /* Get mailbox offsets. */
491 err = mlxsw_i2c_get_mbox(client, mlxsw_i2c);
493 dev_err(&client->dev, "Fail to get mailboxes\n");
497 dev_info(&client->dev, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",
498 id->name, mlxsw_i2c->cmd.mb_size_in,
499 mlxsw_i2c->cmd.mb_off_in, mlxsw_i2c->cmd.mb_size_out,
500 mlxsw_i2c->cmd.mb_off_out);
502 /* Register device bus. */
503 mlxsw_i2c->bus_info.device_kind = id->name;
504 mlxsw_i2c->bus_info.device_name = client->name;
505 mlxsw_i2c->bus_info.dev = &client->dev;
506 mlxsw_i2c->dev = &client->dev;
508 err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
509 &mlxsw_i2c_bus, mlxsw_i2c, false,
512 dev_err(&client->dev, "Fail to register core bus\n");
519 i2c_set_clientdata(client, NULL);
524 static int mlxsw_i2c_remove(struct i2c_client *client)
526 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
528 mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
529 mutex_destroy(&mlxsw_i2c->cmd.lock);
534 int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
536 i2c_driver->probe = mlxsw_i2c_probe;
537 i2c_driver->remove = mlxsw_i2c_remove;
538 return i2c_add_driver(i2c_driver);
540 EXPORT_SYMBOL(mlxsw_i2c_driver_register);
542 void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
544 i2c_del_driver(i2c_driver);
546 EXPORT_SYMBOL(mlxsw_i2c_driver_unregister);
548 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
549 MODULE_DESCRIPTION("Mellanox switch I2C interface driver");
550 MODULE_LICENSE("Dual BSD/GPL");