linux/drivers/net/ethernet/mellanox/mlxsw/i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */
   3
   4#include <linux/err.h>
   5#include <linux/i2c.h>
   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>
  13
  14#include "cmd.h"
  15#include "core.h"
  16#include "i2c.h"
  17#include "resources.h"
  18
  19#define MLXSW_I2C_CIR2_BASE             0x72000
  20#define MLXSW_I2C_CIR_STATUS_OFF        0x18
  21#define MLXSW_I2C_CIR2_OFF_STATUS       (MLXSW_I2C_CIR2_BASE + \
  22                                         MLXSW_I2C_CIR_STATUS_OFF)
  23#define MLXSW_I2C_OPMOD_SHIFT           12
  24#define MLXSW_I2C_EVENT_BIT_SHIFT       22
  25#define MLXSW_I2C_GO_BIT_SHIFT          23
  26#define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
  27#define MLXSW_I2C_EVENT_BIT             BIT(MLXSW_I2C_EVENT_BIT_SHIFT)
  28#define MLXSW_I2C_GO_BIT                BIT(MLXSW_I2C_GO_BIT_SHIFT)
  29#define MLXSW_I2C_GO_OPMODE             BIT(MLXSW_I2C_OPMOD_SHIFT)
  30#define MLXSW_I2C_SET_IMM_CMD           (MLXSW_I2C_GO_OPMODE | \
  31                                         MLXSW_CMD_OPCODE_QUERY_FW)
  32#define MLXSW_I2C_PUSH_IMM_CMD          (MLXSW_I2C_GO_BIT | \
  33                                         MLXSW_I2C_SET_IMM_CMD)
  34#define MLXSW_I2C_SET_CMD               (MLXSW_CMD_OPCODE_ACCESS_REG)
  35#define MLXSW_I2C_PUSH_CMD              (MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)
  36#define MLXSW_I2C_TLV_HDR_SIZE          0x10
  37#define MLXSW_I2C_ADDR_WIDTH            4
  38#define MLXSW_I2C_PUSH_CMD_SIZE         (MLXSW_I2C_ADDR_WIDTH + 4)
  39#define MLXSW_I2C_SET_EVENT_CMD         (MLXSW_I2C_EVENT_BIT)
  40#define MLXSW_I2C_PUSH_EVENT_CMD        (MLXSW_I2C_GO_BIT | \
  41                                         MLXSW_I2C_SET_EVENT_CMD)
  42#define MLXSW_I2C_READ_SEMA_SIZE        4
  43#define MLXSW_I2C_PREP_SIZE             (MLXSW_I2C_ADDR_WIDTH + 28)
  44#define MLXSW_I2C_MBOX_SIZE             20
  45#define MLXSW_I2C_MBOX_OUT_PARAM_OFF    12
  46#define MLXSW_I2C_MBOX_OFFSET_BITS      20
  47#define MLXSW_I2C_MBOX_SIZE_BITS        12
  48#define MLXSW_I2C_ADDR_BUF_SIZE         4
  49#define MLXSW_I2C_BLK_DEF               32
  50#define MLXSW_I2C_RETRY                 5
  51#define MLXSW_I2C_TIMEOUT_MSECS         5000
  52#define MLXSW_I2C_MAX_DATA_SIZE         256
  53
  54/**
  55 * struct mlxsw_i2c - device private data:
  56 * @cmd.mb_size_in: input mailbox size;
  57 * @cmd.mb_off_in: input mailbox offset in register space;
  58 * @cmd.mb_size_out: output mailbox size;
  59 * @cmd.mb_off_out: output mailbox offset in register space;
  60 * @cmd.lock: command execution lock;
  61 * @dev: I2C device;
  62 * @core: switch core pointer;
  63 * @bus_info: bus info block;
  64 * @block_size: maximum block size allowed to pass to under layer;
  65 */
  66struct mlxsw_i2c {
  67        struct {
  68                u32 mb_size_in;
  69                u32 mb_off_in;
  70                u32 mb_size_out;
  71                u32 mb_off_out;
  72                struct mutex lock;
  73        } cmd;
  74        struct device *dev;
  75        struct mlxsw_core *core;
  76        struct mlxsw_bus_info bus_info;
  77        u16 block_size;
  78};
  79
  80#define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) {    \
  81        { .addr = (_client)->addr,                              \
  82          .buf = (_addr_buf),                                   \
  83          .len = MLXSW_I2C_ADDR_BUF_SIZE,                       \
  84          .flags = 0 },                                         \
  85        { .addr = (_client)->addr,                              \
  86          .buf = (_buf),                                        \
  87          .len = (_len),                                        \
  88          .flags = I2C_M_RD } }
  89
  90#define MLXSW_I2C_WRITE_MSG(_client, _buf, _len)                \
  91        { .addr = (_client)->addr,                              \
  92          .buf = (u8 *)(_buf),                                  \
  93          .len = (_len),                                        \
  94          .flags = 0 }
  95
  96/* Routine converts in and out mail boxes offset and size. */
  97static inline void
  98mlxsw_i2c_convert_mbox(struct mlxsw_i2c *mlxsw_i2c, u8 *buf)
  99{
 100        u32 tmp;
 101
 102        /* Local in/out mailboxes: 20 bits for offset, 12 for size */
 103        tmp = be32_to_cpup((__be32 *) buf);
 104        mlxsw_i2c->cmd.mb_off_in = tmp &
 105                                   GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
 106        mlxsw_i2c->cmd.mb_size_in = (tmp & GENMASK(31,
 107                                        MLXSW_I2C_MBOX_OFFSET_BITS)) >>
 108                                        MLXSW_I2C_MBOX_OFFSET_BITS;
 109
 110        tmp = be32_to_cpup((__be32 *) (buf + MLXSW_I2C_ADDR_WIDTH));
 111        mlxsw_i2c->cmd.mb_off_out = tmp &
 112                                    GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
 113        mlxsw_i2c->cmd.mb_size_out = (tmp & GENMASK(31,
 114                                        MLXSW_I2C_MBOX_OFFSET_BITS)) >>
 115                                        MLXSW_I2C_MBOX_OFFSET_BITS;
 116}
 117
 118/* Routine obtains register size from mail box buffer. */
 119static inline int mlxsw_i2c_get_reg_size(u8 *in_mbox)
 120{
 121        u16  tmp = be16_to_cpup((__be16 *) (in_mbox + MLXSW_I2C_TLV_HDR_SIZE));
 122
 123        return (tmp & 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE;
 124}
 125
 126/* Routine sets I2C device internal offset in the transaction buffer. */
 127static inline void mlxsw_i2c_set_slave_addr(u8 *buf, u32 off)
 128{
 129        __be32 *val = (__be32 *) buf;
 130
 131        *val = htonl(off);
 132}
 133
 134/* Routine waits until go bit is cleared. */
 135static int mlxsw_i2c_wait_go_bit(struct i2c_client *client,
 136                                 struct mlxsw_i2c *mlxsw_i2c, u8 *p_status)
 137{
 138        u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
 139        u8 buf[MLXSW_I2C_READ_SEMA_SIZE];
 140        int len = MLXSW_I2C_READ_SEMA_SIZE;
 141        struct i2c_msg read_sema[] =
 142                MLXSW_I2C_READ_MSG(client, addr_buf, buf, len);
 143        bool wait_done = false;
 144        unsigned long end;
 145        int i = 0, err;
 146
 147        mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_OFF_STATUS);
 148
 149        end = jiffies + msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
 150        do {
 151                u32 ctrl;
 152
 153                err = i2c_transfer(client->adapter, read_sema,
 154                                   ARRAY_SIZE(read_sema));
 155
 156                ctrl = be32_to_cpu(*(__be32 *) buf);
 157                if (err == ARRAY_SIZE(read_sema)) {
 158                        if (!(ctrl & MLXSW_I2C_GO_BIT)) {
 159                                wait_done = true;
 160                                *p_status = ctrl >>
 161                                            MLXSW_I2C_CIR_CTRL_STATUS_SHIFT;
 162                                break;
 163                        }
 164                }
 165                cond_resched();
 166        } while ((time_before(jiffies, end)) || (i++ < MLXSW_I2C_RETRY));
 167
 168        if (wait_done) {
 169                if (*p_status)
 170                        err = -EIO;
 171        } else {
 172                return -ETIMEDOUT;
 173        }
 174
 175        return err > 0 ? 0 : err;
 176}
 177
 178/* Routine posts a command to ASIC through mail box. */
 179static int mlxsw_i2c_write_cmd(struct i2c_client *client,
 180                               struct mlxsw_i2c *mlxsw_i2c,
 181                               int immediate)
 182{
 183        __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
 184                0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD)
 185        };
 186        __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
 187                0, 0, 0, 0, 0, 0,
 188                cpu_to_be32(client->adapter->nr & 0xffff),
 189                cpu_to_be32(MLXSW_I2C_SET_IMM_CMD)
 190        };
 191        struct i2c_msg push_cmd =
 192                MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
 193                                    MLXSW_I2C_PUSH_CMD_SIZE);
 194        struct i2c_msg prep_cmd =
 195                MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
 196        int err;
 197
 198        if (!immediate) {
 199                push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD);
 200                prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_SET_CMD);
 201        }
 202        mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
 203                                 MLXSW_I2C_CIR2_BASE);
 204        mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
 205                                 MLXSW_I2C_CIR2_OFF_STATUS);
 206
 207        /* Prepare Command Interface Register for transaction */
 208        err = i2c_transfer(client->adapter, &prep_cmd, 1);
 209        if (err < 0)
 210                return err;
 211        else if (err != 1)
 212                return -EIO;
 213
 214        /* Write out Command Interface Register GO bit to push transaction */
 215        err = i2c_transfer(client->adapter, &push_cmd, 1);
 216        if (err < 0)
 217                return err;
 218        else if (err != 1)
 219                return -EIO;
 220
 221        return 0;
 222}
 223
 224/* Routine posts initialization command to ASIC through mail box. */
 225static int
 226mlxsw_i2c_write_init_cmd(struct i2c_client *client,
 227                         struct mlxsw_i2c *mlxsw_i2c, u16 opcode, u32 in_mod)
 228{
 229        __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
 230                0, cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD)
 231        };
 232        __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
 233                0, 0, 0, 0, 0, 0,
 234                cpu_to_be32(client->adapter->nr & 0xffff),
 235                cpu_to_be32(MLXSW_I2C_SET_EVENT_CMD)
 236        };
 237        struct i2c_msg push_cmd =
 238                MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
 239                                    MLXSW_I2C_PUSH_CMD_SIZE);
 240        struct i2c_msg prep_cmd =
 241                MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
 242        u8 status;
 243        int err;
 244
 245        push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD | opcode);
 246        prep_cmd_buf[3] = cpu_to_be32(in_mod);
 247        prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_GO_BIT | opcode);
 248        mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
 249                                 MLXSW_I2C_CIR2_BASE);
 250        mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
 251                                 MLXSW_I2C_CIR2_OFF_STATUS);
 252
 253        /* Prepare Command Interface Register for transaction */
 254        err = i2c_transfer(client->adapter, &prep_cmd, 1);
 255        if (err < 0)
 256                return err;
 257        else if (err != 1)
 258                return -EIO;
 259
 260        /* Write out Command Interface Register GO bit to push transaction */
 261        err = i2c_transfer(client->adapter, &push_cmd, 1);
 262        if (err < 0)
 263                return err;
 264        else if (err != 1)
 265                return -EIO;
 266
 267        /* Wait until go bit is cleared. */
 268        err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
 269        if (err) {
 270                dev_err(&client->dev, "HW semaphore is not released");
 271                return err;
 272        }
 273
 274        /* Validate transaction completion status. */
 275        if (status) {
 276                dev_err(&client->dev, "Bad transaction completion status %x\n",
 277                        status);
 278                return -EIO;
 279        }
 280
 281        return 0;
 282}
 283
 284/* Routine obtains mail box offsets from ASIC register space. */
 285static int mlxsw_i2c_get_mbox(struct i2c_client *client,
 286                              struct mlxsw_i2c *mlxsw_i2c)
 287{
 288        u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
 289        u8 buf[MLXSW_I2C_MBOX_SIZE];
 290        struct i2c_msg mbox_cmd[] =
 291                MLXSW_I2C_READ_MSG(client, addr_buf, buf, MLXSW_I2C_MBOX_SIZE);
 292        int err;
 293
 294        /* Read mail boxes offsets. */
 295        mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_BASE);
 296        err = i2c_transfer(client->adapter, mbox_cmd, 2);
 297        if (err != 2) {
 298                dev_err(&client->dev, "Could not obtain mail boxes\n");
 299                if (!err)
 300                        return -EIO;
 301                else
 302                        return err;
 303        }
 304
 305        /* Convert mail boxes. */
 306        mlxsw_i2c_convert_mbox(mlxsw_i2c, &buf[MLXSW_I2C_MBOX_OUT_PARAM_OFF]);
 307
 308        return err;
 309}
 310
 311/* Routine sends I2C write transaction to ASIC device. */
 312static int
 313mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
 314                u8 *p_status)
 315{
 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        int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
 320        unsigned long end;
 321        u8 *tran_buf;
 322        struct i2c_msg write_tran =
 323                MLXSW_I2C_WRITE_MSG(client, NULL, MLXSW_I2C_PUSH_CMD_SIZE);
 324        int err;
 325
 326        tran_buf = kmalloc(mlxsw_i2c->block_size + MLXSW_I2C_ADDR_BUF_SIZE,
 327                           GFP_KERNEL);
 328        if (!tran_buf)
 329                return -ENOMEM;
 330
 331        write_tran.buf = tran_buf;
 332        for (i = 0; i < num; i++) {
 333                chunk_size = (in_mbox_size > mlxsw_i2c->block_size) ?
 334                             mlxsw_i2c->block_size : in_mbox_size;
 335                write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
 336                mlxsw_i2c_set_slave_addr(tran_buf, off);
 337                memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
 338                       mlxsw_i2c->block_size * i, chunk_size);
 339
 340                j = 0;
 341                end = jiffies + timeout;
 342                do {
 343                        err = i2c_transfer(client->adapter, &write_tran, 1);
 344                        if (err == 1)
 345                                break;
 346
 347                        cond_resched();
 348                } while ((time_before(jiffies, end)) ||
 349                         (j++ < MLXSW_I2C_RETRY));
 350
 351                if (err != 1) {
 352                        if (!err) {
 353                                err = -EIO;
 354                                goto mlxsw_i2c_write_exit;
 355                        }
 356                }
 357
 358                off += chunk_size;
 359                in_mbox_size -= chunk_size;
 360        }
 361
 362        /* Prepare and write out Command Interface Register for transaction. */
 363        err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
 364        if (err) {
 365                dev_err(&client->dev, "Could not start transaction");
 366                err = -EIO;
 367                goto mlxsw_i2c_write_exit;
 368        }
 369
 370        /* Wait until go bit is cleared. */
 371        err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
 372        if (err) {
 373                dev_err(&client->dev, "HW semaphore is not released");
 374                goto mlxsw_i2c_write_exit;
 375        }
 376
 377        /* Validate transaction completion status. */
 378        if (*p_status) {
 379                dev_err(&client->dev, "Bad transaction completion status %x\n",
 380                        *p_status);
 381                err = -EIO;
 382        }
 383
 384mlxsw_i2c_write_exit:
 385        kfree(tran_buf);
 386        return err;
 387}
 388
 389/* Routine executes I2C command. */
 390static int
 391mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
 392              u8 *in_mbox, size_t out_mbox_size, u8 *out_mbox, u8 *status)
 393{
 394        struct i2c_client *client = to_i2c_client(dev);
 395        struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
 396        unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
 397        u8 tran_buf[MLXSW_I2C_ADDR_BUF_SIZE];
 398        int num, chunk_size, reg_size, i, j;
 399        int off = mlxsw_i2c->cmd.mb_off_out;
 400        unsigned long end;
 401        struct i2c_msg read_tran[] =
 402                MLXSW_I2C_READ_MSG(client, tran_buf, NULL, 0);
 403        int err;
 404
 405        WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
 406
 407        if (in_mbox) {
 408                reg_size = mlxsw_i2c_get_reg_size(in_mbox);
 409                num = reg_size / mlxsw_i2c->block_size;
 410                if (reg_size % mlxsw_i2c->block_size)
 411                        num++;
 412
 413                if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
 414                        dev_err(&client->dev, "Could not acquire lock");
 415                        return -EINVAL;
 416                }
 417
 418                err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
 419                if (err)
 420                        goto cmd_fail;
 421
 422                /* No out mailbox is case of write transaction. */
 423                if (!out_mbox) {
 424                        mutex_unlock(&mlxsw_i2c->cmd.lock);
 425                        return 0;
 426                }
 427        } else {
 428                /* No input mailbox is case of initialization query command. */
 429                reg_size = MLXSW_I2C_MAX_DATA_SIZE;
 430                num = reg_size / mlxsw_i2c->block_size;
 431
 432                if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
 433                        dev_err(&client->dev, "Could not acquire lock");
 434                        return -EINVAL;
 435                }
 436
 437                err = mlxsw_i2c_write_init_cmd(client, mlxsw_i2c, opcode,
 438                                               in_mod);
 439                if (err)
 440                        goto cmd_fail;
 441        }
 442
 443        /* Send read transaction to get output mailbox content. */
 444        read_tran[1].buf = out_mbox;
 445        for (i = 0; i < num; i++) {
 446                chunk_size = (reg_size > mlxsw_i2c->block_size) ?
 447                             mlxsw_i2c->block_size : reg_size;
 448                read_tran[1].len = chunk_size;
 449                mlxsw_i2c_set_slave_addr(tran_buf, off);
 450
 451                j = 0;
 452                end = jiffies + timeout;
 453                do {
 454                        err = i2c_transfer(client->adapter, read_tran,
 455                                           ARRAY_SIZE(read_tran));
 456                        if (err == ARRAY_SIZE(read_tran))
 457                                break;
 458
 459                        cond_resched();
 460                } while ((time_before(jiffies, end)) ||
 461                         (j++ < MLXSW_I2C_RETRY));
 462
 463                if (err != ARRAY_SIZE(read_tran)) {
 464                        if (!err)
 465                                err = -EIO;
 466
 467                        goto cmd_fail;
 468                }
 469
 470                off += chunk_size;
 471                reg_size -= chunk_size;
 472                read_tran[1].buf += chunk_size;
 473        }
 474
 475        mutex_unlock(&mlxsw_i2c->cmd.lock);
 476
 477        return 0;
 478
 479cmd_fail:
 480        mutex_unlock(&mlxsw_i2c->cmd.lock);
 481        return err;
 482}
 483
 484static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 485                              u32 in_mod, bool out_mbox_direct,
 486                              char *in_mbox, size_t in_mbox_size,
 487                              char *out_mbox, size_t out_mbox_size,
 488                              u8 *status)
 489{
 490        struct mlxsw_i2c *mlxsw_i2c = bus_priv;
 491
 492        return mlxsw_i2c_cmd(mlxsw_i2c->dev, opcode, in_mod, in_mbox_size,
 493                             in_mbox, out_mbox_size, out_mbox, status);
 494}
 495
 496static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,
 497                                        const struct mlxsw_tx_info *tx_info)
 498{
 499        return false;
 500}
 501
 502static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,
 503                                  const struct mlxsw_tx_info *tx_info)
 504{
 505        return 0;
 506}
 507
 508static int
 509mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
 510               const struct mlxsw_config_profile *profile,
 511               struct mlxsw_res *res)
 512{
 513        struct mlxsw_i2c *mlxsw_i2c = bus_priv;
 514        char *mbox;
 515        int err;
 516
 517        mlxsw_i2c->core = mlxsw_core;
 518
 519        mbox = mlxsw_cmd_mbox_alloc();
 520        if (!mbox)
 521                return -ENOMEM;
 522
 523        err = mlxsw_cmd_query_fw(mlxsw_core, mbox);
 524        if (err)
 525                goto mbox_put;
 526
 527        mlxsw_i2c->bus_info.fw_rev.major =
 528                mlxsw_cmd_mbox_query_fw_fw_rev_major_get(mbox);
 529        mlxsw_i2c->bus_info.fw_rev.minor =
 530                mlxsw_cmd_mbox_query_fw_fw_rev_minor_get(mbox);
 531        mlxsw_i2c->bus_info.fw_rev.subminor =
 532                mlxsw_cmd_mbox_query_fw_fw_rev_subminor_get(mbox);
 533
 534        err = mlxsw_core_resources_query(mlxsw_core, mbox, res);
 535
 536mbox_put:
 537        mlxsw_cmd_mbox_free(mbox);
 538        return err;
 539}
 540
 541static void mlxsw_i2c_fini(void *bus_priv)
 542{
 543        struct mlxsw_i2c *mlxsw_i2c = bus_priv;
 544
 545        mlxsw_i2c->core = NULL;
 546}
 547
 548static const struct mlxsw_bus mlxsw_i2c_bus = {
 549        .kind                   = "i2c",
 550        .init                   = mlxsw_i2c_init,
 551        .fini                   = mlxsw_i2c_fini,
 552        .skb_transmit_busy      = mlxsw_i2c_skb_transmit_busy,
 553        .skb_transmit           = mlxsw_i2c_skb_transmit,
 554        .cmd_exec               = mlxsw_i2c_cmd_exec,
 555};
 556
 557static int mlxsw_i2c_probe(struct i2c_client *client,
 558                           const struct i2c_device_id *id)
 559{
 560        const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
 561        struct mlxsw_i2c *mlxsw_i2c;
 562        u8 status;
 563        int err;
 564
 565        mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);
 566        if (!mlxsw_i2c)
 567                return -ENOMEM;
 568
 569        if (quirks) {
 570                if ((quirks->max_read_len &&
 571                     quirks->max_read_len < MLXSW_I2C_BLK_DEF) ||
 572                    (quirks->max_write_len &&
 573                     quirks->max_write_len < MLXSW_I2C_BLK_DEF)) {
 574                        dev_err(&client->dev, "Insufficient transaction buffer length\n");
 575                        return -EOPNOTSUPP;
 576                }
 577
 578                mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
 579                                              min_t(u16, quirks->max_read_len,
 580                                                    quirks->max_write_len));
 581        } else {
 582                mlxsw_i2c->block_size = MLXSW_I2C_BLK_DEF;
 583        }
 584
 585        i2c_set_clientdata(client, mlxsw_i2c);
 586        mutex_init(&mlxsw_i2c->cmd.lock);
 587
 588        /* In order to use mailboxes through the i2c, special area is reserved
 589         * on the i2c address space that can be used for input and output
 590         * mailboxes. Such mailboxes are called local mailboxes. When using a
 591         * local mailbox, software should specify 0 as the Input/Output
 592         * parameters. The location of the Local Mailbox addresses on the i2c
 593         * space can be retrieved through the QUERY_FW command.
 594         * For this purpose QUERY_FW is to be issued with opcode modifier equal
 595         * 0x01. For such command the output parameter is an immediate value.
 596         * Here QUERY_FW command is invoked for ASIC probing and for getting
 597         * local mailboxes addresses from immedate output parameters.
 598         */
 599
 600        /* Prepare and write out Command Interface Register for transaction */
 601        err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 1);
 602        if (err) {
 603                dev_err(&client->dev, "Could not start transaction");
 604                goto errout;
 605        }
 606
 607        /* Wait until go bit is cleared. */
 608        err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
 609        if (err) {
 610                dev_err(&client->dev, "HW semaphore is not released");
 611                goto errout;
 612        }
 613
 614        /* Validate transaction completion status. */
 615        if (status) {
 616                dev_err(&client->dev, "Bad transaction completion status %x\n",
 617                        status);
 618                err = -EIO;
 619                goto errout;
 620        }
 621
 622        /* Get mailbox offsets. */
 623        err = mlxsw_i2c_get_mbox(client, mlxsw_i2c);
 624        if (err < 0) {
 625                dev_err(&client->dev, "Fail to get mailboxes\n");
 626                goto errout;
 627        }
 628
 629        dev_info(&client->dev, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",
 630                 id->name, mlxsw_i2c->cmd.mb_size_in,
 631                 mlxsw_i2c->cmd.mb_off_in, mlxsw_i2c->cmd.mb_size_out,
 632                 mlxsw_i2c->cmd.mb_off_out);
 633
 634        /* Register device bus. */
 635        mlxsw_i2c->bus_info.device_kind = id->name;
 636        mlxsw_i2c->bus_info.device_name = client->name;
 637        mlxsw_i2c->bus_info.dev = &client->dev;
 638        mlxsw_i2c->bus_info.low_frequency = true;
 639        mlxsw_i2c->dev = &client->dev;
 640
 641        err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
 642                                             &mlxsw_i2c_bus, mlxsw_i2c, false,
 643                                             NULL);
 644        if (err) {
 645                dev_err(&client->dev, "Fail to register core bus\n");
 646                return err;
 647        }
 648
 649        return 0;
 650
 651errout:
 652        i2c_set_clientdata(client, NULL);
 653
 654        return err;
 655}
 656
 657static int mlxsw_i2c_remove(struct i2c_client *client)
 658{
 659        struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
 660
 661        mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
 662        mutex_destroy(&mlxsw_i2c->cmd.lock);
 663
 664        return 0;
 665}
 666
 667int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
 668{
 669        i2c_driver->probe = mlxsw_i2c_probe;
 670        i2c_driver->remove = mlxsw_i2c_remove;
 671        return i2c_add_driver(i2c_driver);
 672}
 673EXPORT_SYMBOL(mlxsw_i2c_driver_register);
 674
 675void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
 676{
 677        i2c_del_driver(i2c_driver);
 678}
 679EXPORT_SYMBOL(mlxsw_i2c_driver_unregister);
 680
 681MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
 682MODULE_DESCRIPTION("Mellanox switch I2C interface driver");
 683MODULE_LICENSE("Dual BSD/GPL");
 684