Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */
0003 
0004 #include <linux/err.h>
0005 #include <linux/i2c.h>
0006 #include <linux/init.h>
0007 #include <linux/jiffies.h>
0008 #include <linux/kernel.h>
0009 #include <linux/mutex.h>
0010 #include <linux/module.h>
0011 #include <linux/mod_devicetable.h>
0012 #include <linux/slab.h>
0013 
0014 #include "cmd.h"
0015 #include "core.h"
0016 #include "i2c.h"
0017 #include "resources.h"
0018 
0019 #define MLXSW_I2C_CIR2_BASE     0x72000
0020 #define MLXSW_I2C_CIR_STATUS_OFF    0x18
0021 #define MLXSW_I2C_CIR2_OFF_STATUS   (MLXSW_I2C_CIR2_BASE + \
0022                      MLXSW_I2C_CIR_STATUS_OFF)
0023 #define MLXSW_I2C_OPMOD_SHIFT       12
0024 #define MLXSW_I2C_EVENT_BIT_SHIFT   22
0025 #define MLXSW_I2C_GO_BIT_SHIFT      23
0026 #define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
0027 #define MLXSW_I2C_EVENT_BIT     BIT(MLXSW_I2C_EVENT_BIT_SHIFT)
0028 #define MLXSW_I2C_GO_BIT        BIT(MLXSW_I2C_GO_BIT_SHIFT)
0029 #define MLXSW_I2C_GO_OPMODE     BIT(MLXSW_I2C_OPMOD_SHIFT)
0030 #define MLXSW_I2C_SET_IMM_CMD       (MLXSW_I2C_GO_OPMODE | \
0031                      MLXSW_CMD_OPCODE_QUERY_FW)
0032 #define MLXSW_I2C_PUSH_IMM_CMD      (MLXSW_I2C_GO_BIT | \
0033                      MLXSW_I2C_SET_IMM_CMD)
0034 #define MLXSW_I2C_SET_CMD       (MLXSW_CMD_OPCODE_ACCESS_REG)
0035 #define MLXSW_I2C_PUSH_CMD      (MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)
0036 #define MLXSW_I2C_TLV_HDR_SIZE      0x10
0037 #define MLXSW_I2C_ADDR_WIDTH        4
0038 #define MLXSW_I2C_PUSH_CMD_SIZE     (MLXSW_I2C_ADDR_WIDTH + 4)
0039 #define MLXSW_I2C_SET_EVENT_CMD     (MLXSW_I2C_EVENT_BIT)
0040 #define MLXSW_I2C_PUSH_EVENT_CMD    (MLXSW_I2C_GO_BIT | \
0041                      MLXSW_I2C_SET_EVENT_CMD)
0042 #define MLXSW_I2C_READ_SEMA_SIZE    4
0043 #define MLXSW_I2C_PREP_SIZE     (MLXSW_I2C_ADDR_WIDTH + 28)
0044 #define MLXSW_I2C_MBOX_SIZE     20
0045 #define MLXSW_I2C_MBOX_OUT_PARAM_OFF    12
0046 #define MLXSW_I2C_MBOX_OFFSET_BITS  20
0047 #define MLXSW_I2C_MBOX_SIZE_BITS    12
0048 #define MLXSW_I2C_ADDR_BUF_SIZE     4
0049 #define MLXSW_I2C_BLK_DEF       32
0050 #define MLXSW_I2C_RETRY         5
0051 #define MLXSW_I2C_TIMEOUT_MSECS     5000
0052 #define MLXSW_I2C_MAX_DATA_SIZE     256
0053 
0054 /**
0055  * struct mlxsw_i2c - device private data:
0056  * @cmd: command attributes;
0057  * @cmd.mb_size_in: input mailbox size;
0058  * @cmd.mb_off_in: input mailbox offset in register space;
0059  * @cmd.mb_size_out: output mailbox size;
0060  * @cmd.mb_off_out: output mailbox offset in register space;
0061  * @cmd.lock: command execution lock;
0062  * @dev: I2C device;
0063  * @core: switch core pointer;
0064  * @bus_info: bus info block;
0065  * @block_size: maximum block size allowed to pass to under layer;
0066  */
0067 struct mlxsw_i2c {
0068     struct {
0069         u32 mb_size_in;
0070         u32 mb_off_in;
0071         u32 mb_size_out;
0072         u32 mb_off_out;
0073         struct mutex lock;
0074     } cmd;
0075     struct device *dev;
0076     struct mlxsw_core *core;
0077     struct mlxsw_bus_info bus_info;
0078     u16 block_size;
0079 };
0080 
0081 #define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) {    \
0082     { .addr = (_client)->addr,              \
0083       .buf = (_addr_buf),                   \
0084       .len = MLXSW_I2C_ADDR_BUF_SIZE,           \
0085       .flags = 0 },                     \
0086     { .addr = (_client)->addr,              \
0087       .buf = (_buf),                    \
0088       .len = (_len),                    \
0089       .flags = I2C_M_RD } }
0090 
0091 #define MLXSW_I2C_WRITE_MSG(_client, _buf, _len)        \
0092     { .addr = (_client)->addr,              \
0093       .buf = (u8 *)(_buf),                  \
0094       .len = (_len),                    \
0095       .flags = 0 }
0096 
0097 /* Routine converts in and out mail boxes offset and size. */
0098 static inline void
0099 mlxsw_i2c_convert_mbox(struct mlxsw_i2c *mlxsw_i2c, u8 *buf)
0100 {
0101     u32 tmp;
0102 
0103     /* Local in/out mailboxes: 20 bits for offset, 12 for size */
0104     tmp = be32_to_cpup((__be32 *) buf);
0105     mlxsw_i2c->cmd.mb_off_in = tmp &
0106                    GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
0107     mlxsw_i2c->cmd.mb_size_in = (tmp & GENMASK(31,
0108                     MLXSW_I2C_MBOX_OFFSET_BITS)) >>
0109                     MLXSW_I2C_MBOX_OFFSET_BITS;
0110 
0111     tmp = be32_to_cpup((__be32 *) (buf + MLXSW_I2C_ADDR_WIDTH));
0112     mlxsw_i2c->cmd.mb_off_out = tmp &
0113                     GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
0114     mlxsw_i2c->cmd.mb_size_out = (tmp & GENMASK(31,
0115                     MLXSW_I2C_MBOX_OFFSET_BITS)) >>
0116                     MLXSW_I2C_MBOX_OFFSET_BITS;
0117 }
0118 
0119 /* Routine obtains register size from mail box buffer. */
0120 static inline int mlxsw_i2c_get_reg_size(u8 *in_mbox)
0121 {
0122     u16  tmp = be16_to_cpup((__be16 *) (in_mbox + MLXSW_I2C_TLV_HDR_SIZE));
0123 
0124     return (tmp & 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE;
0125 }
0126 
0127 /* Routine sets I2C device internal offset in the transaction buffer. */
0128 static inline void mlxsw_i2c_set_slave_addr(u8 *buf, u32 off)
0129 {
0130     __be32 *val = (__be32 *) buf;
0131 
0132     *val = htonl(off);
0133 }
0134 
0135 /* Routine waits until go bit is cleared. */
0136 static int mlxsw_i2c_wait_go_bit(struct i2c_client *client,
0137                  struct mlxsw_i2c *mlxsw_i2c, u8 *p_status)
0138 {
0139     u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
0140     u8 buf[MLXSW_I2C_READ_SEMA_SIZE];
0141     int len = MLXSW_I2C_READ_SEMA_SIZE;
0142     struct i2c_msg read_sema[] =
0143         MLXSW_I2C_READ_MSG(client, addr_buf, buf, len);
0144     bool wait_done = false;
0145     unsigned long end;
0146     int i = 0, err;
0147 
0148     mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_OFF_STATUS);
0149 
0150     end = jiffies + msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
0151     do {
0152         u32 ctrl;
0153 
0154         err = i2c_transfer(client->adapter, read_sema,
0155                    ARRAY_SIZE(read_sema));
0156 
0157         ctrl = be32_to_cpu(*(__be32 *) buf);
0158         if (err == ARRAY_SIZE(read_sema)) {
0159             if (!(ctrl & MLXSW_I2C_GO_BIT)) {
0160                 wait_done = true;
0161                 *p_status = ctrl >>
0162                         MLXSW_I2C_CIR_CTRL_STATUS_SHIFT;
0163                 break;
0164             }
0165         }
0166         cond_resched();
0167     } while ((time_before(jiffies, end)) || (i++ < MLXSW_I2C_RETRY));
0168 
0169     if (wait_done) {
0170         if (*p_status)
0171             err = -EIO;
0172     } else {
0173         return -ETIMEDOUT;
0174     }
0175 
0176     return err > 0 ? 0 : err;
0177 }
0178 
0179 /* Routine posts a command to ASIC through mail box. */
0180 static int mlxsw_i2c_write_cmd(struct i2c_client *client,
0181                    struct mlxsw_i2c *mlxsw_i2c,
0182                    int immediate)
0183 {
0184     __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
0185         0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD)
0186     };
0187     __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
0188         0, 0, 0, 0, 0, 0,
0189         cpu_to_be32(client->adapter->nr & 0xffff),
0190         cpu_to_be32(MLXSW_I2C_SET_IMM_CMD)
0191     };
0192     struct i2c_msg push_cmd =
0193         MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
0194                     MLXSW_I2C_PUSH_CMD_SIZE);
0195     struct i2c_msg prep_cmd =
0196         MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
0197     int err;
0198 
0199     if (!immediate) {
0200         push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD);
0201         prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_SET_CMD);
0202     }
0203     mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
0204                  MLXSW_I2C_CIR2_BASE);
0205     mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
0206                  MLXSW_I2C_CIR2_OFF_STATUS);
0207 
0208     /* Prepare Command Interface Register for transaction */
0209     err = i2c_transfer(client->adapter, &prep_cmd, 1);
0210     if (err < 0)
0211         return err;
0212     else if (err != 1)
0213         return -EIO;
0214 
0215     /* Write out Command Interface Register GO bit to push transaction */
0216     err = i2c_transfer(client->adapter, &push_cmd, 1);
0217     if (err < 0)
0218         return err;
0219     else if (err != 1)
0220         return -EIO;
0221 
0222     return 0;
0223 }
0224 
0225 /* Routine posts initialization command to ASIC through mail box. */
0226 static int
0227 mlxsw_i2c_write_init_cmd(struct i2c_client *client,
0228              struct mlxsw_i2c *mlxsw_i2c, u16 opcode, u32 in_mod)
0229 {
0230     __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
0231         0, cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD)
0232     };
0233     __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
0234         0, 0, 0, 0, 0, 0,
0235         cpu_to_be32(client->adapter->nr & 0xffff),
0236         cpu_to_be32(MLXSW_I2C_SET_EVENT_CMD)
0237     };
0238     struct i2c_msg push_cmd =
0239         MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
0240                     MLXSW_I2C_PUSH_CMD_SIZE);
0241     struct i2c_msg prep_cmd =
0242         MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
0243     u8 status;
0244     int err;
0245 
0246     push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD | opcode);
0247     prep_cmd_buf[3] = cpu_to_be32(in_mod);
0248     prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_GO_BIT | opcode);
0249     mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
0250                  MLXSW_I2C_CIR2_BASE);
0251     mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
0252                  MLXSW_I2C_CIR2_OFF_STATUS);
0253 
0254     /* Prepare Command Interface Register for transaction */
0255     err = i2c_transfer(client->adapter, &prep_cmd, 1);
0256     if (err < 0)
0257         return err;
0258     else if (err != 1)
0259         return -EIO;
0260 
0261     /* Write out Command Interface Register GO bit to push transaction */
0262     err = i2c_transfer(client->adapter, &push_cmd, 1);
0263     if (err < 0)
0264         return err;
0265     else if (err != 1)
0266         return -EIO;
0267 
0268     /* Wait until go bit is cleared. */
0269     err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
0270     if (err) {
0271         dev_err(&client->dev, "HW semaphore is not released");
0272         return err;
0273     }
0274 
0275     /* Validate transaction completion status. */
0276     if (status) {
0277         dev_err(&client->dev, "Bad transaction completion status %x\n",
0278             status);
0279         return -EIO;
0280     }
0281 
0282     return 0;
0283 }
0284 
0285 /* Routine obtains mail box offsets from ASIC register space. */
0286 static int mlxsw_i2c_get_mbox(struct i2c_client *client,
0287                   struct mlxsw_i2c *mlxsw_i2c)
0288 {
0289     u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
0290     u8 buf[MLXSW_I2C_MBOX_SIZE];
0291     struct i2c_msg mbox_cmd[] =
0292         MLXSW_I2C_READ_MSG(client, addr_buf, buf, MLXSW_I2C_MBOX_SIZE);
0293     int err;
0294 
0295     /* Read mail boxes offsets. */
0296     mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_BASE);
0297     err = i2c_transfer(client->adapter, mbox_cmd, 2);
0298     if (err != 2) {
0299         dev_err(&client->dev, "Could not obtain mail boxes\n");
0300         if (!err)
0301             return -EIO;
0302         else
0303             return err;
0304     }
0305 
0306     /* Convert mail boxes. */
0307     mlxsw_i2c_convert_mbox(mlxsw_i2c, &buf[MLXSW_I2C_MBOX_OUT_PARAM_OFF]);
0308 
0309     return err;
0310 }
0311 
0312 /* Routine sends I2C write transaction to ASIC device. */
0313 static int
0314 mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
0315         u8 *p_status)
0316 {
0317     struct i2c_client *client = to_i2c_client(dev);
0318     struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
0319     unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
0320     int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
0321     unsigned long end;
0322     u8 *tran_buf;
0323     struct i2c_msg write_tran =
0324         MLXSW_I2C_WRITE_MSG(client, NULL, MLXSW_I2C_PUSH_CMD_SIZE);
0325     int err;
0326 
0327     tran_buf = kmalloc(mlxsw_i2c->block_size + MLXSW_I2C_ADDR_BUF_SIZE,
0328                GFP_KERNEL);
0329     if (!tran_buf)
0330         return -ENOMEM;
0331 
0332     write_tran.buf = tran_buf;
0333     for (i = 0; i < num; i++) {
0334         chunk_size = (in_mbox_size > mlxsw_i2c->block_size) ?
0335                  mlxsw_i2c->block_size : in_mbox_size;
0336         write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
0337         mlxsw_i2c_set_slave_addr(tran_buf, off);
0338         memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
0339                mlxsw_i2c->block_size * i, chunk_size);
0340 
0341         j = 0;
0342         end = jiffies + timeout;
0343         do {
0344             err = i2c_transfer(client->adapter, &write_tran, 1);
0345             if (err == 1)
0346                 break;
0347 
0348             cond_resched();
0349         } while ((time_before(jiffies, end)) ||
0350              (j++ < MLXSW_I2C_RETRY));
0351 
0352         if (err != 1) {
0353             if (!err) {
0354                 err = -EIO;
0355                 goto mlxsw_i2c_write_exit;
0356             }
0357         }
0358 
0359         off += chunk_size;
0360         in_mbox_size -= chunk_size;
0361     }
0362 
0363     /* Prepare and write out Command Interface Register for transaction. */
0364     err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
0365     if (err) {
0366         dev_err(&client->dev, "Could not start transaction");
0367         err = -EIO;
0368         goto mlxsw_i2c_write_exit;
0369     }
0370 
0371     /* Wait until go bit is cleared. */
0372     err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
0373     if (err) {
0374         dev_err(&client->dev, "HW semaphore is not released");
0375         goto mlxsw_i2c_write_exit;
0376     }
0377 
0378     /* Validate transaction completion status. */
0379     if (*p_status) {
0380         dev_err(&client->dev, "Bad transaction completion status %x\n",
0381             *p_status);
0382         err = -EIO;
0383     }
0384 
0385 mlxsw_i2c_write_exit:
0386     kfree(tran_buf);
0387     return err;
0388 }
0389 
0390 /* Routine executes I2C command. */
0391 static int
0392 mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
0393           u8 *in_mbox, size_t out_mbox_size, u8 *out_mbox, u8 *status)
0394 {
0395     struct i2c_client *client = to_i2c_client(dev);
0396     struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
0397     unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
0398     u8 tran_buf[MLXSW_I2C_ADDR_BUF_SIZE];
0399     int num, chunk_size, reg_size, i, j;
0400     int off = mlxsw_i2c->cmd.mb_off_out;
0401     unsigned long end;
0402     struct i2c_msg read_tran[] =
0403         MLXSW_I2C_READ_MSG(client, tran_buf, NULL, 0);
0404     int err;
0405 
0406     WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
0407 
0408     if (in_mbox) {
0409         reg_size = mlxsw_i2c_get_reg_size(in_mbox);
0410         num = reg_size / mlxsw_i2c->block_size;
0411         if (reg_size % mlxsw_i2c->block_size)
0412             num++;
0413 
0414         if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
0415             dev_err(&client->dev, "Could not acquire lock");
0416             return -EINVAL;
0417         }
0418 
0419         err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
0420         if (err)
0421             goto cmd_fail;
0422 
0423         /* No out mailbox is case of write transaction. */
0424         if (!out_mbox) {
0425             mutex_unlock(&mlxsw_i2c->cmd.lock);
0426             return 0;
0427         }
0428     } else {
0429         /* No input mailbox is case of initialization query command. */
0430         reg_size = MLXSW_I2C_MAX_DATA_SIZE;
0431         num = reg_size / mlxsw_i2c->block_size;
0432 
0433         if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
0434             dev_err(&client->dev, "Could not acquire lock");
0435             return -EINVAL;
0436         }
0437 
0438         err = mlxsw_i2c_write_init_cmd(client, mlxsw_i2c, opcode,
0439                            in_mod);
0440         if (err)
0441             goto cmd_fail;
0442     }
0443 
0444     /* Send read transaction to get output mailbox content. */
0445     read_tran[1].buf = out_mbox;
0446     for (i = 0; i < num; i++) {
0447         chunk_size = (reg_size > mlxsw_i2c->block_size) ?
0448                  mlxsw_i2c->block_size : reg_size;
0449         read_tran[1].len = chunk_size;
0450         mlxsw_i2c_set_slave_addr(tran_buf, off);
0451 
0452         j = 0;
0453         end = jiffies + timeout;
0454         do {
0455             err = i2c_transfer(client->adapter, read_tran,
0456                        ARRAY_SIZE(read_tran));
0457             if (err == ARRAY_SIZE(read_tran))
0458                 break;
0459 
0460             cond_resched();
0461         } while ((time_before(jiffies, end)) ||
0462              (j++ < MLXSW_I2C_RETRY));
0463 
0464         if (err != ARRAY_SIZE(read_tran)) {
0465             if (!err)
0466                 err = -EIO;
0467 
0468             goto cmd_fail;
0469         }
0470 
0471         off += chunk_size;
0472         reg_size -= chunk_size;
0473         read_tran[1].buf += chunk_size;
0474     }
0475 
0476     mutex_unlock(&mlxsw_i2c->cmd.lock);
0477 
0478     return 0;
0479 
0480 cmd_fail:
0481     mutex_unlock(&mlxsw_i2c->cmd.lock);
0482     return err;
0483 }
0484 
0485 static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
0486                   u32 in_mod, bool out_mbox_direct,
0487                   char *in_mbox, size_t in_mbox_size,
0488                   char *out_mbox, size_t out_mbox_size,
0489                   u8 *status)
0490 {
0491     struct mlxsw_i2c *mlxsw_i2c = bus_priv;
0492 
0493     return mlxsw_i2c_cmd(mlxsw_i2c->dev, opcode, in_mod, in_mbox_size,
0494                  in_mbox, out_mbox_size, out_mbox, status);
0495 }
0496 
0497 static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,
0498                     const struct mlxsw_tx_info *tx_info)
0499 {
0500     return false;
0501 }
0502 
0503 static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,
0504                   const struct mlxsw_tx_info *tx_info)
0505 {
0506     return 0;
0507 }
0508 
0509 static int
0510 mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
0511            const struct mlxsw_config_profile *profile,
0512            struct mlxsw_res *res)
0513 {
0514     struct mlxsw_i2c *mlxsw_i2c = bus_priv;
0515     char *mbox;
0516     int err;
0517 
0518     mlxsw_i2c->core = mlxsw_core;
0519 
0520     mbox = mlxsw_cmd_mbox_alloc();
0521     if (!mbox)
0522         return -ENOMEM;
0523 
0524     err = mlxsw_cmd_query_fw(mlxsw_core, mbox);
0525     if (err)
0526         goto mbox_put;
0527 
0528     mlxsw_i2c->bus_info.fw_rev.major =
0529         mlxsw_cmd_mbox_query_fw_fw_rev_major_get(mbox);
0530     mlxsw_i2c->bus_info.fw_rev.minor =
0531         mlxsw_cmd_mbox_query_fw_fw_rev_minor_get(mbox);
0532     mlxsw_i2c->bus_info.fw_rev.subminor =
0533         mlxsw_cmd_mbox_query_fw_fw_rev_subminor_get(mbox);
0534 
0535     err = mlxsw_core_resources_query(mlxsw_core, mbox, res);
0536 
0537 mbox_put:
0538     mlxsw_cmd_mbox_free(mbox);
0539     return err;
0540 }
0541 
0542 static void mlxsw_i2c_fini(void *bus_priv)
0543 {
0544     struct mlxsw_i2c *mlxsw_i2c = bus_priv;
0545 
0546     mlxsw_i2c->core = NULL;
0547 }
0548 
0549 static const struct mlxsw_bus mlxsw_i2c_bus = {
0550     .kind           = "i2c",
0551     .init           = mlxsw_i2c_init,
0552     .fini           = mlxsw_i2c_fini,
0553     .skb_transmit_busy  = mlxsw_i2c_skb_transmit_busy,
0554     .skb_transmit       = mlxsw_i2c_skb_transmit,
0555     .cmd_exec       = mlxsw_i2c_cmd_exec,
0556 };
0557 
0558 static int mlxsw_i2c_probe(struct i2c_client *client,
0559                const struct i2c_device_id *id)
0560 {
0561     const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
0562     struct mlxsw_i2c *mlxsw_i2c;
0563     u8 status;
0564     int err;
0565 
0566     mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);
0567     if (!mlxsw_i2c)
0568         return -ENOMEM;
0569 
0570     if (quirks) {
0571         if ((quirks->max_read_len &&
0572              quirks->max_read_len < MLXSW_I2C_BLK_DEF) ||
0573             (quirks->max_write_len &&
0574              quirks->max_write_len < MLXSW_I2C_BLK_DEF)) {
0575             dev_err(&client->dev, "Insufficient transaction buffer length\n");
0576             return -EOPNOTSUPP;
0577         }
0578 
0579         mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
0580                           min_t(u16, quirks->max_read_len,
0581                             quirks->max_write_len));
0582     } else {
0583         mlxsw_i2c->block_size = MLXSW_I2C_BLK_DEF;
0584     }
0585 
0586     i2c_set_clientdata(client, mlxsw_i2c);
0587     mutex_init(&mlxsw_i2c->cmd.lock);
0588 
0589     /* In order to use mailboxes through the i2c, special area is reserved
0590      * on the i2c address space that can be used for input and output
0591      * mailboxes. Such mailboxes are called local mailboxes. When using a
0592      * local mailbox, software should specify 0 as the Input/Output
0593      * parameters. The location of the Local Mailbox addresses on the i2c
0594      * space can be retrieved through the QUERY_FW command.
0595      * For this purpose QUERY_FW is to be issued with opcode modifier equal
0596      * 0x01. For such command the output parameter is an immediate value.
0597      * Here QUERY_FW command is invoked for ASIC probing and for getting
0598      * local mailboxes addresses from immedate output parameters.
0599      */
0600 
0601     /* Prepare and write out Command Interface Register for transaction */
0602     err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 1);
0603     if (err) {
0604         dev_err(&client->dev, "Could not start transaction");
0605         goto errout;
0606     }
0607 
0608     /* Wait until go bit is cleared. */
0609     err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
0610     if (err) {
0611         dev_err(&client->dev, "HW semaphore is not released");
0612         goto errout;
0613     }
0614 
0615     /* Validate transaction completion status. */
0616     if (status) {
0617         dev_err(&client->dev, "Bad transaction completion status %x\n",
0618             status);
0619         err = -EIO;
0620         goto errout;
0621     }
0622 
0623     /* Get mailbox offsets. */
0624     err = mlxsw_i2c_get_mbox(client, mlxsw_i2c);
0625     if (err < 0) {
0626         dev_err(&client->dev, "Fail to get mailboxes\n");
0627         goto errout;
0628     }
0629 
0630     dev_info(&client->dev, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",
0631          id->name, mlxsw_i2c->cmd.mb_size_in,
0632          mlxsw_i2c->cmd.mb_off_in, mlxsw_i2c->cmd.mb_size_out,
0633          mlxsw_i2c->cmd.mb_off_out);
0634 
0635     /* Register device bus. */
0636     mlxsw_i2c->bus_info.device_kind = id->name;
0637     mlxsw_i2c->bus_info.device_name = client->name;
0638     mlxsw_i2c->bus_info.dev = &client->dev;
0639     mlxsw_i2c->bus_info.low_frequency = true;
0640     mlxsw_i2c->dev = &client->dev;
0641 
0642     err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
0643                          &mlxsw_i2c_bus, mlxsw_i2c, false,
0644                          NULL, NULL);
0645     if (err) {
0646         dev_err(&client->dev, "Fail to register core bus\n");
0647         return err;
0648     }
0649 
0650     return 0;
0651 
0652 errout:
0653     mutex_destroy(&mlxsw_i2c->cmd.lock);
0654     i2c_set_clientdata(client, NULL);
0655 
0656     return err;
0657 }
0658 
0659 static int mlxsw_i2c_remove(struct i2c_client *client)
0660 {
0661     struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
0662 
0663     mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
0664     mutex_destroy(&mlxsw_i2c->cmd.lock);
0665 
0666     return 0;
0667 }
0668 
0669 int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
0670 {
0671     i2c_driver->probe = mlxsw_i2c_probe;
0672     i2c_driver->remove = mlxsw_i2c_remove;
0673     return i2c_add_driver(i2c_driver);
0674 }
0675 EXPORT_SYMBOL(mlxsw_i2c_driver_register);
0676 
0677 void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
0678 {
0679     i2c_del_driver(i2c_driver);
0680 }
0681 EXPORT_SYMBOL(mlxsw_i2c_driver_unregister);
0682 
0683 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
0684 MODULE_DESCRIPTION("Mellanox switch I2C interface driver");
0685 MODULE_LICENSE("Dual BSD/GPL");