2 * drivers/net/ethernet/mellanox/mlxsw/i2c.c
3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the names of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
35 #include <linux/err.h>
36 #include <linux/i2c.h>
37 #include <linux/init.h>
38 #include <linux/jiffies.h>
39 #include <linux/kernel.h>
40 #include <linux/mutex.h>
41 #include <linux/module.h>
42 #include <linux/mod_devicetable.h>
43 #include <linux/slab.h>
49 static const char mlxsw_i2c_driver_name
[] = "mlxsw_i2c";
51 #define MLXSW_I2C_CIR2_BASE 0x72000
52 #define MLXSW_I2C_CIR_STATUS_OFF 0x18
53 #define MLXSW_I2C_CIR2_OFF_STATUS (MLXSW_I2C_CIR2_BASE + \
54 MLXSW_I2C_CIR_STATUS_OFF)
55 #define MLXSW_I2C_OPMOD_SHIFT 12
56 #define MLXSW_I2C_GO_BIT_SHIFT 23
57 #define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
58 #define MLXSW_I2C_GO_BIT BIT(MLXSW_I2C_GO_BIT_SHIFT)
59 #define MLXSW_I2C_GO_OPMODE BIT(MLXSW_I2C_OPMOD_SHIFT)
60 #define MLXSW_I2C_SET_IMM_CMD (MLXSW_I2C_GO_OPMODE | \
61 MLXSW_CMD_OPCODE_QUERY_FW)
62 #define MLXSW_I2C_PUSH_IMM_CMD (MLXSW_I2C_GO_BIT | \
63 MLXSW_I2C_SET_IMM_CMD)
64 #define MLXSW_I2C_SET_CMD (MLXSW_CMD_OPCODE_ACCESS_REG)
65 #define MLXSW_I2C_PUSH_CMD (MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)
66 #define MLXSW_I2C_TLV_HDR_SIZE 0x10
67 #define MLXSW_I2C_ADDR_WIDTH 4
68 #define MLXSW_I2C_PUSH_CMD_SIZE (MLXSW_I2C_ADDR_WIDTH + 4)
69 #define MLXSW_I2C_READ_SEMA_SIZE 4
70 #define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28)
71 #define MLXSW_I2C_MBOX_SIZE 20
72 #define MLXSW_I2C_MBOX_OUT_PARAM_OFF 12
73 #define MLXSW_I2C_MAX_BUFF_SIZE 32
74 #define MLXSW_I2C_MBOX_OFFSET_BITS 20
75 #define MLXSW_I2C_MBOX_SIZE_BITS 12
76 #define MLXSW_I2C_ADDR_BUF_SIZE 4
77 #define MLXSW_I2C_BLK_MAX 32
78 #define MLXSW_I2C_RETRY 5
79 #define MLXSW_I2C_TIMEOUT_MSECS 5000
82 * struct mlxsw_i2c - device private data:
83 * @cmd.mb_size_in: input mailbox size;
84 * @cmd.mb_off_in: input mailbox offset in register space;
85 * @cmd.mb_size_out: output mailbox size;
86 * @cmd.mb_off_out: output mailbox offset in register space;
87 * @cmd.lock: command execution lock;
89 * @core: switch core pointer;
90 * @bus_info: bus info block;
101 struct mlxsw_core
*core
;
102 struct mlxsw_bus_info bus_info
;
105 #define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
106 { .addr = (_client)->addr, \
107 .buf = (_addr_buf), \
108 .len = MLXSW_I2C_ADDR_BUF_SIZE, \
110 { .addr = (_client)->addr, \
113 .flags = I2C_M_RD } }
115 #define MLXSW_I2C_WRITE_MSG(_client, _buf, _len) \
116 { .addr = (_client)->addr, \
117 .buf = (u8 *)(_buf), \
121 /* Routine converts in and out mail boxes offset and size. */
123 mlxsw_i2c_convert_mbox(struct mlxsw_i2c
*mlxsw_i2c
, u8
*buf
)
127 /* Local in/out mailboxes: 20 bits for offset, 12 for size */
128 tmp
= be32_to_cpup((__be32
*) buf
);
129 mlxsw_i2c
->cmd
.mb_off_in
= tmp
&
130 GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS
- 1, 0);
131 mlxsw_i2c
->cmd
.mb_size_in
= (tmp
& GENMASK(31,
132 MLXSW_I2C_MBOX_OFFSET_BITS
)) >>
133 MLXSW_I2C_MBOX_OFFSET_BITS
;
135 tmp
= be32_to_cpup((__be32
*) (buf
+ MLXSW_I2C_ADDR_WIDTH
));
136 mlxsw_i2c
->cmd
.mb_off_out
= tmp
&
137 GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS
- 1, 0);
138 mlxsw_i2c
->cmd
.mb_size_out
= (tmp
& GENMASK(31,
139 MLXSW_I2C_MBOX_OFFSET_BITS
)) >>
140 MLXSW_I2C_MBOX_OFFSET_BITS
;
143 /* Routine obtains register size from mail box buffer. */
144 static inline int mlxsw_i2c_get_reg_size(u8
*in_mbox
)
146 u16 tmp
= be16_to_cpup((__be16
*) (in_mbox
+ MLXSW_I2C_TLV_HDR_SIZE
));
148 return (tmp
& 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE
;
151 /* Routine sets I2C device internal offset in the transaction buffer. */
152 static inline void mlxsw_i2c_set_slave_addr(u8
*buf
, u32 off
)
154 __be32
*val
= (__be32
*) buf
;
159 /* Routine waits until go bit is cleared. */
160 static int mlxsw_i2c_wait_go_bit(struct i2c_client
*client
,
161 struct mlxsw_i2c
*mlxsw_i2c
, u8
*p_status
)
163 u8 addr_buf
[MLXSW_I2C_ADDR_BUF_SIZE
];
164 u8 buf
[MLXSW_I2C_READ_SEMA_SIZE
];
165 int len
= MLXSW_I2C_READ_SEMA_SIZE
;
166 struct i2c_msg read_sema
[] =
167 MLXSW_I2C_READ_MSG(client
, addr_buf
, buf
, len
);
168 bool wait_done
= false;
172 mlxsw_i2c_set_slave_addr(addr_buf
, MLXSW_I2C_CIR2_OFF_STATUS
);
174 end
= jiffies
+ msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS
);
178 err
= i2c_transfer(client
->adapter
, read_sema
,
179 ARRAY_SIZE(read_sema
));
181 ctrl
= be32_to_cpu(*(__be32
*) buf
);
182 if (err
== ARRAY_SIZE(read_sema
)) {
183 if (!(ctrl
& MLXSW_I2C_GO_BIT
)) {
186 MLXSW_I2C_CIR_CTRL_STATUS_SHIFT
;
191 } while ((time_before(jiffies
, end
)) || (i
++ < MLXSW_I2C_RETRY
));
200 return err
> 0 ? 0 : err
;
203 /* Routine posts a command to ASIC though mail box. */
204 static int mlxsw_i2c_write_cmd(struct i2c_client
*client
,
205 struct mlxsw_i2c
*mlxsw_i2c
,
208 __be32 push_cmd_buf
[MLXSW_I2C_PUSH_CMD_SIZE
/ 4] = {
209 0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD
)
211 __be32 prep_cmd_buf
[MLXSW_I2C_PREP_SIZE
/ 4] = {
213 cpu_to_be32(client
->adapter
->nr
& 0xffff),
214 cpu_to_be32(MLXSW_I2C_SET_IMM_CMD
)
216 struct i2c_msg push_cmd
=
217 MLXSW_I2C_WRITE_MSG(client
, push_cmd_buf
,
218 MLXSW_I2C_PUSH_CMD_SIZE
);
219 struct i2c_msg prep_cmd
=
220 MLXSW_I2C_WRITE_MSG(client
, prep_cmd_buf
, MLXSW_I2C_PREP_SIZE
);
224 push_cmd_buf
[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD
);
225 prep_cmd_buf
[7] = cpu_to_be32(MLXSW_I2C_SET_CMD
);
227 mlxsw_i2c_set_slave_addr((u8
*)prep_cmd_buf
,
228 MLXSW_I2C_CIR2_BASE
);
229 mlxsw_i2c_set_slave_addr((u8
*)push_cmd_buf
,
230 MLXSW_I2C_CIR2_OFF_STATUS
);
232 /* Prepare Command Interface Register for transaction */
233 err
= i2c_transfer(client
->adapter
, &prep_cmd
, 1);
239 /* Write out Command Interface Register GO bit to push transaction */
240 err
= i2c_transfer(client
->adapter
, &push_cmd
, 1);
249 /* Routine obtains mail box offsets from ASIC register space. */
250 static int mlxsw_i2c_get_mbox(struct i2c_client
*client
,
251 struct mlxsw_i2c
*mlxsw_i2c
)
253 u8 addr_buf
[MLXSW_I2C_ADDR_BUF_SIZE
];
254 u8 buf
[MLXSW_I2C_MBOX_SIZE
];
255 struct i2c_msg mbox_cmd
[] =
256 MLXSW_I2C_READ_MSG(client
, addr_buf
, buf
, MLXSW_I2C_MBOX_SIZE
);
259 /* Read mail boxes offsets. */
260 mlxsw_i2c_set_slave_addr(addr_buf
, MLXSW_I2C_CIR2_BASE
);
261 err
= i2c_transfer(client
->adapter
, mbox_cmd
, 2);
263 dev_err(&client
->dev
, "Could not obtain mail boxes\n");
270 /* Convert mail boxes. */
271 mlxsw_i2c_convert_mbox(mlxsw_i2c
, &buf
[MLXSW_I2C_MBOX_OUT_PARAM_OFF
]);
276 /* Routine sends I2C write transaction to ASIC device. */
278 mlxsw_i2c_write(struct device
*dev
, size_t in_mbox_size
, u8
*in_mbox
, int num
,
281 struct i2c_client
*client
= to_i2c_client(dev
);
282 struct mlxsw_i2c
*mlxsw_i2c
= i2c_get_clientdata(client
);
283 unsigned long timeout
= msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS
);
284 u8 tran_buf
[MLXSW_I2C_MAX_BUFF_SIZE
+ MLXSW_I2C_ADDR_BUF_SIZE
];
285 int off
= mlxsw_i2c
->cmd
.mb_off_in
, chunk_size
, i
, j
;
287 struct i2c_msg write_tran
=
288 MLXSW_I2C_WRITE_MSG(client
, tran_buf
, MLXSW_I2C_PUSH_CMD_SIZE
);
291 for (i
= 0; i
< num
; i
++) {
292 chunk_size
= (in_mbox_size
> MLXSW_I2C_BLK_MAX
) ?
293 MLXSW_I2C_BLK_MAX
: in_mbox_size
;
294 write_tran
.len
= MLXSW_I2C_ADDR_WIDTH
+ chunk_size
;
295 mlxsw_i2c_set_slave_addr(tran_buf
, off
);
296 memcpy(&tran_buf
[MLXSW_I2C_ADDR_BUF_SIZE
], in_mbox
+
297 MLXSW_I2C_BLK_MAX
* i
, chunk_size
);
300 end
= jiffies
+ timeout
;
302 err
= i2c_transfer(client
->adapter
, &write_tran
, 1);
307 } while ((time_before(jiffies
, end
)) ||
308 (j
++ < MLXSW_I2C_RETRY
));
317 in_mbox_size
-= chunk_size
;
320 /* Prepare and write out Command Interface Register for transaction. */
321 err
= mlxsw_i2c_write_cmd(client
, mlxsw_i2c
, 0);
323 dev_err(&client
->dev
, "Could not start transaction");
327 /* Wait until go bit is cleared. */
328 err
= mlxsw_i2c_wait_go_bit(client
, mlxsw_i2c
, p_status
);
330 dev_err(&client
->dev
, "HW semaphore is not released");
334 /* Validate transaction completion status. */
336 dev_err(&client
->dev
, "Bad transaction completion status %x\n",
344 /* Routine executes I2C command. */
346 mlxsw_i2c_cmd(struct device
*dev
, size_t in_mbox_size
, u8
*in_mbox
,
347 size_t out_mbox_size
, u8
*out_mbox
, u8
*status
)
349 struct i2c_client
*client
= to_i2c_client(dev
);
350 struct mlxsw_i2c
*mlxsw_i2c
= i2c_get_clientdata(client
);
351 unsigned long timeout
= msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS
);
352 u8 tran_buf
[MLXSW_I2C_ADDR_BUF_SIZE
];
353 int num
, chunk_size
, reg_size
, i
, j
;
354 int off
= mlxsw_i2c
->cmd
.mb_off_out
;
356 struct i2c_msg read_tran
[] =
357 MLXSW_I2C_READ_MSG(client
, tran_buf
, NULL
, 0);
360 WARN_ON(in_mbox_size
% sizeof(u32
) || out_mbox_size
% sizeof(u32
));
362 reg_size
= mlxsw_i2c_get_reg_size(in_mbox
);
363 num
= reg_size
/ MLXSW_I2C_BLK_MAX
;
364 if (reg_size
% MLXSW_I2C_BLK_MAX
)
367 if (mutex_lock_interruptible(&mlxsw_i2c
->cmd
.lock
) < 0) {
368 dev_err(&client
->dev
, "Could not acquire lock");
372 err
= mlxsw_i2c_write(dev
, reg_size
, in_mbox
, num
, status
);
376 /* No out mailbox is case of write transaction. */
378 mutex_unlock(&mlxsw_i2c
->cmd
.lock
);
382 /* Send read transaction to get output mailbox content. */
383 read_tran
[1].buf
= out_mbox
;
384 for (i
= 0; i
< num
; i
++) {
385 chunk_size
= (reg_size
> MLXSW_I2C_BLK_MAX
) ?
386 MLXSW_I2C_BLK_MAX
: reg_size
;
387 read_tran
[1].len
= chunk_size
;
388 mlxsw_i2c_set_slave_addr(tran_buf
, off
);
391 end
= jiffies
+ timeout
;
393 err
= i2c_transfer(client
->adapter
, read_tran
,
394 ARRAY_SIZE(read_tran
));
395 if (err
== ARRAY_SIZE(read_tran
))
399 } while ((time_before(jiffies
, end
)) ||
400 (j
++ < MLXSW_I2C_RETRY
));
402 if (err
!= ARRAY_SIZE(read_tran
)) {
410 reg_size
-= chunk_size
;
411 read_tran
[1].buf
+= chunk_size
;
414 mutex_unlock(&mlxsw_i2c
->cmd
.lock
);
419 mutex_unlock(&mlxsw_i2c
->cmd
.lock
);
423 static int mlxsw_i2c_cmd_exec(void *bus_priv
, u16 opcode
, u8 opcode_mod
,
424 u32 in_mod
, bool out_mbox_direct
,
425 char *in_mbox
, size_t in_mbox_size
,
426 char *out_mbox
, size_t out_mbox_size
,
429 struct mlxsw_i2c
*mlxsw_i2c
= bus_priv
;
431 return mlxsw_i2c_cmd(mlxsw_i2c
->dev
, in_mbox_size
, in_mbox
,
432 out_mbox_size
, out_mbox
, status
);
435 static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv
,
436 const struct mlxsw_tx_info
*tx_info
)
441 static int mlxsw_i2c_skb_transmit(void *bus_priv
, struct sk_buff
*skb
,
442 const struct mlxsw_tx_info
*tx_info
)
448 mlxsw_i2c_init(void *bus_priv
, struct mlxsw_core
*mlxsw_core
,
449 const struct mlxsw_config_profile
*profile
,
450 struct mlxsw_res
*resources
)
452 struct mlxsw_i2c
*mlxsw_i2c
= bus_priv
;
454 mlxsw_i2c
->core
= mlxsw_core
;
459 static void mlxsw_i2c_fini(void *bus_priv
)
461 struct mlxsw_i2c
*mlxsw_i2c
= bus_priv
;
463 mlxsw_i2c
->core
= NULL
;
466 static const struct mlxsw_bus mlxsw_i2c_bus
= {
468 .init
= mlxsw_i2c_init
,
469 .fini
= mlxsw_i2c_fini
,
470 .skb_transmit_busy
= mlxsw_i2c_skb_transmit_busy
,
471 .skb_transmit
= mlxsw_i2c_skb_transmit
,
472 .cmd_exec
= mlxsw_i2c_cmd_exec
,
475 static int mlxsw_i2c_probe(struct i2c_client
*client
,
476 const struct i2c_device_id
*id
)
478 struct mlxsw_i2c
*mlxsw_i2c
;
482 mlxsw_i2c
= devm_kzalloc(&client
->dev
, sizeof(*mlxsw_i2c
), GFP_KERNEL
);
486 i2c_set_clientdata(client
, mlxsw_i2c
);
487 mutex_init(&mlxsw_i2c
->cmd
.lock
);
489 /* In order to use mailboxes through the i2c, special area is reserved
490 * on the i2c address space that can be used for input and output
491 * mailboxes. Such mailboxes are called local mailboxes. When using a
492 * local mailbox, software should specify 0 as the Input/Output
493 * parameters. The location of the Local Mailbox addresses on the i2c
494 * space can be retrieved through the QUERY_FW command.
495 * For this purpose QUERY_FW is to be issued with opcode modifier equal
496 * 0x01. For such command the output parameter is an immediate value.
497 * Here QUERY_FW command is invoked for ASIC probing and for getting
498 * local mailboxes addresses from immedate output parameters.
501 /* Prepare and write out Command Interface Register for transaction */
502 err
= mlxsw_i2c_write_cmd(client
, mlxsw_i2c
, 1);
504 dev_err(&client
->dev
, "Could not start transaction");
508 /* Wait until go bit is cleared. */
509 err
= mlxsw_i2c_wait_go_bit(client
, mlxsw_i2c
, &status
);
511 dev_err(&client
->dev
, "HW semaphore is not released");
515 /* Validate transaction completion status. */
517 dev_err(&client
->dev
, "Bad transaction completion status %x\n",
523 /* Get mailbox offsets. */
524 err
= mlxsw_i2c_get_mbox(client
, mlxsw_i2c
);
526 dev_err(&client
->dev
, "Fail to get mailboxes\n");
530 dev_info(&client
->dev
, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",
531 id
->name
, mlxsw_i2c
->cmd
.mb_size_in
,
532 mlxsw_i2c
->cmd
.mb_off_in
, mlxsw_i2c
->cmd
.mb_size_out
,
533 mlxsw_i2c
->cmd
.mb_off_out
);
535 /* Register device bus. */
536 mlxsw_i2c
->bus_info
.device_kind
= id
->name
;
537 mlxsw_i2c
->bus_info
.device_name
= client
->name
;
538 mlxsw_i2c
->bus_info
.dev
= &client
->dev
;
539 mlxsw_i2c
->dev
= &client
->dev
;
541 err
= mlxsw_core_bus_device_register(&mlxsw_i2c
->bus_info
,
542 &mlxsw_i2c_bus
, mlxsw_i2c
, false,
545 dev_err(&client
->dev
, "Fail to register core bus\n");
552 i2c_set_clientdata(client
, NULL
);
557 static int mlxsw_i2c_remove(struct i2c_client
*client
)
559 struct mlxsw_i2c
*mlxsw_i2c
= i2c_get_clientdata(client
);
561 mlxsw_core_bus_device_unregister(mlxsw_i2c
->core
, false);
562 mutex_destroy(&mlxsw_i2c
->cmd
.lock
);
567 int mlxsw_i2c_driver_register(struct i2c_driver
*i2c_driver
)
569 i2c_driver
->probe
= mlxsw_i2c_probe
;
570 i2c_driver
->remove
= mlxsw_i2c_remove
;
571 return i2c_add_driver(i2c_driver
);
573 EXPORT_SYMBOL(mlxsw_i2c_driver_register
);
575 void mlxsw_i2c_driver_unregister(struct i2c_driver
*i2c_driver
)
577 i2c_del_driver(i2c_driver
);
579 EXPORT_SYMBOL(mlxsw_i2c_driver_unregister
);
581 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
582 MODULE_DESCRIPTION("Mellanox switch I2C interface driver");
583 MODULE_LICENSE("Dual BSD/GPL");