root/drivers/net/ethernet/qualcomm/qca_7k.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qcaspi_spi_error
  2. qcaspi_read_register
  3. __qcaspi_write_register
  4. qcaspi_write_register

   1 /*
   2  *
   3  *   Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
   4  *   Copyright (c) 2014, I2SE GmbH
   5  *
   6  *   Permission to use, copy, modify, and/or distribute this software
   7  *   for any purpose with or without fee is hereby granted, provided
   8  *   that the above copyright notice and this permission notice appear
   9  *   in all copies.
  10  *
  11  *   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  12  *   WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  13  *   WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  14  *   THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  15  *   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  16  *   LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  17  *   NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  18  *   CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19  *
  20  */
  21 
  22 /*   This module implements the Qualcomm Atheros SPI protocol for
  23  *   kernel-based SPI device.
  24  */
  25 
  26 #include <linux/kernel.h>
  27 #include <linux/netdevice.h>
  28 #include <linux/spi/spi.h>
  29 
  30 #include "qca_7k.h"
  31 
  32 void
  33 qcaspi_spi_error(struct qcaspi *qca)
  34 {
  35         if (qca->sync != QCASPI_SYNC_READY)
  36                 return;
  37 
  38         netdev_err(qca->net_dev, "spi error\n");
  39         qca->sync = QCASPI_SYNC_UNKNOWN;
  40         qca->stats.spi_err++;
  41 }
  42 
  43 int
  44 qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result)
  45 {
  46         __be16 rx_data;
  47         __be16 tx_data;
  48         struct spi_transfer transfer[2];
  49         struct spi_message msg;
  50         int ret;
  51 
  52         memset(transfer, 0, sizeof(transfer));
  53 
  54         spi_message_init(&msg);
  55 
  56         tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg);
  57         *result = 0;
  58 
  59         transfer[0].tx_buf = &tx_data;
  60         transfer[0].len = QCASPI_CMD_LEN;
  61         transfer[1].rx_buf = &rx_data;
  62         transfer[1].len = QCASPI_CMD_LEN;
  63 
  64         spi_message_add_tail(&transfer[0], &msg);
  65 
  66         if (qca->legacy_mode) {
  67                 spi_sync(qca->spi_dev, &msg);
  68                 spi_message_init(&msg);
  69         }
  70         spi_message_add_tail(&transfer[1], &msg);
  71         ret = spi_sync(qca->spi_dev, &msg);
  72 
  73         if (!ret)
  74                 ret = msg.status;
  75 
  76         if (ret)
  77                 qcaspi_spi_error(qca);
  78         else
  79                 *result = be16_to_cpu(rx_data);
  80 
  81         return ret;
  82 }
  83 
  84 static int
  85 __qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value)
  86 {
  87         __be16 tx_data[2];
  88         struct spi_transfer transfer[2];
  89         struct spi_message msg;
  90         int ret;
  91 
  92         memset(&transfer, 0, sizeof(transfer));
  93 
  94         spi_message_init(&msg);
  95 
  96         tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg);
  97         tx_data[1] = cpu_to_be16(value);
  98 
  99         transfer[0].tx_buf = &tx_data[0];
 100         transfer[0].len = QCASPI_CMD_LEN;
 101         transfer[1].tx_buf = &tx_data[1];
 102         transfer[1].len = QCASPI_CMD_LEN;
 103 
 104         spi_message_add_tail(&transfer[0], &msg);
 105         if (qca->legacy_mode) {
 106                 spi_sync(qca->spi_dev, &msg);
 107                 spi_message_init(&msg);
 108         }
 109         spi_message_add_tail(&transfer[1], &msg);
 110         ret = spi_sync(qca->spi_dev, &msg);
 111 
 112         if (!ret)
 113                 ret = msg.status;
 114 
 115         if (ret)
 116                 qcaspi_spi_error(qca);
 117 
 118         return ret;
 119 }
 120 
 121 int
 122 qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value, int retry)
 123 {
 124         int ret, i = 0;
 125         u16 confirmed;
 126 
 127         do {
 128                 ret = __qcaspi_write_register(qca, reg, value);
 129                 if (ret)
 130                         return ret;
 131 
 132                 if (!retry)
 133                         return 0;
 134 
 135                 ret = qcaspi_read_register(qca, reg, &confirmed);
 136                 if (ret)
 137                         return ret;
 138 
 139                 ret = confirmed != value;
 140                 if (!ret)
 141                         return 0;
 142 
 143                 i++;
 144                 qca->stats.write_verify_failed++;
 145 
 146         } while (i <= retry);
 147 
 148         return ret;
 149 }

/* [<][>][^][v][top][bottom][index][help] */