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