1366 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.4 * All rights reserved.5 */6 7#include <linux/clk.h>8#include <linux/spi/spi.h>9#include <linux/crc7.h>10#include <linux/crc-itu-t.h>11#include <linux/gpio/consumer.h>12 13#include "netdev.h"14#include "cfg80211.h"15 16#define SPI_MODALIAS "wilc1000_spi"17 18static bool enable_crc7; /* protect SPI commands with CRC7 */19module_param(enable_crc7, bool, 0644);20MODULE_PARM_DESC(enable_crc7,21 "Enable CRC7 checksum to protect command transfers\n"22 "\t\t\tagainst corruption during the SPI transfer.\n"23 "\t\t\tCommand transfers are short and the CPU-cycle cost\n"24 "\t\t\tof enabling this is small.");25 26static bool enable_crc16; /* protect SPI data with CRC16 */27module_param(enable_crc16, bool, 0644);28MODULE_PARM_DESC(enable_crc16,29 "Enable CRC16 checksum to protect data transfers\n"30 "\t\t\tagainst corruption during the SPI transfer.\n"31 "\t\t\tData transfers can be large and the CPU-cycle cost\n"32 "\t\t\tof enabling this may be substantial.");33 34/*35 * For CMD_SINGLE_READ and CMD_INTERNAL_READ, WILC may insert one or36 * more zero bytes between the command response and the DATA Start tag37 * (0xf3). This behavior appears to be undocumented in "ATWILC100038 * USER GUIDE" (https://tinyurl.com/4hhshdts) but we have observed 1-439 * zero bytes when the SPI bus operates at 48MHz and none when it40 * operates at 1MHz.41 */42#define WILC_SPI_RSP_HDR_EXTRA_DATA 843 44struct wilc_spi {45 bool isinit; /* true if wilc_spi_init was successful */46 bool probing_crc; /* true if we're probing chip's CRC config */47 bool crc7_enabled; /* true if crc7 is currently enabled */48 bool crc16_enabled; /* true if crc16 is currently enabled */49 struct wilc_gpios {50 struct gpio_desc *enable; /* ENABLE GPIO or NULL */51 struct gpio_desc *reset; /* RESET GPIO or NULL */52 } gpios;53};54 55static const struct wilc_hif_func wilc_hif_spi;56 57static int wilc_spi_reset(struct wilc *wilc);58static int wilc_spi_configure_bus_protocol(struct wilc *wilc);59static int wilc_validate_chipid(struct wilc *wilc);60 61/********************************************62 *63 * Spi protocol Function64 *65 ********************************************/66 67#define CMD_DMA_WRITE 0xc168#define CMD_DMA_READ 0xc269#define CMD_INTERNAL_WRITE 0xc370#define CMD_INTERNAL_READ 0xc471#define CMD_TERMINATE 0xc572#define CMD_REPEAT 0xc673#define CMD_DMA_EXT_WRITE 0xc774#define CMD_DMA_EXT_READ 0xc875#define CMD_SINGLE_WRITE 0xc976#define CMD_SINGLE_READ 0xca77#define CMD_RESET 0xcf78 79#define SPI_RETRY_MAX_LIMIT 1080#define SPI_ENABLE_VMM_RETRY_LIMIT 281 82/* SPI response fields (section 11.1.2 in ATWILC1000 User Guide): */83#define RSP_START_FIELD GENMASK(7, 4)84#define RSP_TYPE_FIELD GENMASK(3, 0)85 86/* SPI response values for the response fields: */87#define RSP_START_TAG 0xc88#define RSP_TYPE_FIRST_PACKET 0x189#define RSP_TYPE_INNER_PACKET 0x290#define RSP_TYPE_LAST_PACKET 0x391#define RSP_STATE_NO_ERROR 0x0092 93#define PROTOCOL_REG_PKT_SZ_MASK GENMASK(6, 4)94#define PROTOCOL_REG_CRC16_MASK GENMASK(3, 3)95#define PROTOCOL_REG_CRC7_MASK GENMASK(2, 2)96 97/*98 * The SPI data packet size may be any integer power of two in the99 * range from 256 to 8192 bytes.100 */101#define DATA_PKT_LOG_SZ_MIN 8 /* 256 B */102#define DATA_PKT_LOG_SZ_MAX 13 /* 8 KiB */103 104/*105 * Select the data packet size (log2 of number of bytes): Use the106 * maximum data packet size. We only retransmit complete packets, so107 * there is no benefit from using smaller data packets.108 */109#define DATA_PKT_LOG_SZ DATA_PKT_LOG_SZ_MAX110#define DATA_PKT_SZ (1 << DATA_PKT_LOG_SZ)111 112#define WILC_SPI_COMMAND_STAT_SUCCESS 0113#define WILC_GET_RESP_HDR_START(h) (((h) >> 4) & 0xf)114 115struct wilc_spi_cmd {116 u8 cmd_type;117 union {118 struct {119 u8 addr[3];120 u8 crc[];121 } __packed simple_cmd;122 struct {123 u8 addr[3];124 u8 size[2];125 u8 crc[];126 } __packed dma_cmd;127 struct {128 u8 addr[3];129 u8 size[3];130 u8 crc[];131 } __packed dma_cmd_ext;132 struct {133 u8 addr[2];134 __be32 data;135 u8 crc[];136 } __packed internal_w_cmd;137 struct {138 u8 addr[3];139 __be32 data;140 u8 crc[];141 } __packed w_cmd;142 } u;143} __packed;144 145struct wilc_spi_read_rsp_data {146 u8 header;147 u8 data[4];148 u8 crc[];149} __packed;150 151struct wilc_spi_rsp_data {152 u8 rsp_cmd_type;153 u8 status;154 u8 data[];155} __packed;156 157struct wilc_spi_special_cmd_rsp {158 u8 skip_byte;159 u8 rsp_cmd_type;160 u8 status;161} __packed;162 163static int wilc_parse_gpios(struct wilc *wilc)164{165 struct spi_device *spi = to_spi_device(wilc->dev);166 struct wilc_spi *spi_priv = wilc->bus_data;167 struct wilc_gpios *gpios = &spi_priv->gpios;168 169 /* get ENABLE pin and deassert it (if it is defined): */170 gpios->enable = devm_gpiod_get_optional(&spi->dev,171 "enable", GPIOD_OUT_LOW);172 /* get RESET pin and assert it (if it is defined): */173 if (gpios->enable) {174 /* if enable pin exists, reset must exist as well */175 gpios->reset = devm_gpiod_get(&spi->dev,176 "reset", GPIOD_OUT_HIGH);177 if (IS_ERR(gpios->reset)) {178 dev_err(&spi->dev, "missing reset gpio.\n");179 return PTR_ERR(gpios->reset);180 }181 } else {182 gpios->reset = devm_gpiod_get_optional(&spi->dev,183 "reset", GPIOD_OUT_HIGH);184 }185 return 0;186}187 188static void wilc_wlan_power(struct wilc *wilc, bool on)189{190 struct wilc_spi *spi_priv = wilc->bus_data;191 struct wilc_gpios *gpios = &spi_priv->gpios;192 193 if (on) {194 /* assert ENABLE: */195 gpiod_set_value(gpios->enable, 1);196 mdelay(5);197 /* deassert RESET: */198 gpiod_set_value(gpios->reset, 0);199 } else {200 /* assert RESET: */201 gpiod_set_value(gpios->reset, 1);202 /* deassert ENABLE: */203 gpiod_set_value(gpios->enable, 0);204 }205}206 207static int wilc_bus_probe(struct spi_device *spi)208{209 struct wilc_spi *spi_priv;210 struct wilc_vif *vif;211 struct wilc *wilc;212 int ret;213 214 spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL);215 if (!spi_priv)216 return -ENOMEM;217 218 ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);219 if (ret)220 goto free;221 222 spi_set_drvdata(spi, wilc);223 wilc->dev = &spi->dev;224 wilc->bus_data = spi_priv;225 wilc->dev_irq_num = spi->irq;226 227 ret = wilc_parse_gpios(wilc);228 if (ret < 0)229 goto netdev_cleanup;230 231 wilc->rtc_clk = devm_clk_get_optional_enabled(&spi->dev, "rtc");232 if (IS_ERR(wilc->rtc_clk)) {233 ret = PTR_ERR(wilc->rtc_clk);234 goto netdev_cleanup;235 }236 237 dev_info(&spi->dev, "Selected CRC config: crc7=%s, crc16=%s\n",238 enable_crc7 ? "on" : "off", enable_crc16 ? "on" : "off");239 240 /* we need power to configure the bus protocol and to read the chip id: */241 242 wilc_wlan_power(wilc, true);243 244 ret = wilc_spi_configure_bus_protocol(wilc);245 if (ret)246 goto power_down;247 248 ret = wilc_validate_chipid(wilc);249 if (ret)250 goto power_down;251 252 ret = wilc_load_mac_from_nv(wilc);253 if (ret) {254 pr_err("Can not retrieve MAC address from chip\n");255 goto power_down;256 }257 258 wilc_wlan_power(wilc, false);259 vif = wilc_netdev_ifc_init(wilc, "wlan%d", WILC_STATION_MODE,260 NL80211_IFTYPE_STATION, false);261 if (IS_ERR(vif)) {262 ret = PTR_ERR(vif);263 goto power_down;264 }265 return 0;266 267power_down:268 wilc_wlan_power(wilc, false);269netdev_cleanup:270 wilc_netdev_cleanup(wilc);271free:272 kfree(spi_priv);273 return ret;274}275 276static void wilc_bus_remove(struct spi_device *spi)277{278 struct wilc *wilc = spi_get_drvdata(spi);279 struct wilc_spi *spi_priv = wilc->bus_data;280 281 wilc_netdev_cleanup(wilc);282 kfree(spi_priv);283}284 285static const struct of_device_id wilc_of_match[] = {286 { .compatible = "microchip,wilc1000", },287 { /* sentinel */ }288};289MODULE_DEVICE_TABLE(of, wilc_of_match);290 291static const struct spi_device_id wilc_spi_id[] = {292 { "wilc1000", 0 },293 { /* sentinel */ }294};295MODULE_DEVICE_TABLE(spi, wilc_spi_id);296 297static struct spi_driver wilc_spi_driver = {298 .driver = {299 .name = SPI_MODALIAS,300 .of_match_table = wilc_of_match,301 },302 .id_table = wilc_spi_id,303 .probe = wilc_bus_probe,304 .remove = wilc_bus_remove,305};306module_spi_driver(wilc_spi_driver);307MODULE_DESCRIPTION("Atmel WILC1000 SPI wireless driver");308MODULE_LICENSE("GPL");309 310static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)311{312 struct spi_device *spi = to_spi_device(wilc->dev);313 int ret;314 struct spi_message msg;315 316 if (len > 0 && b) {317 struct spi_transfer tr = {318 .tx_buf = b,319 .len = len,320 .delay = {321 .value = 0,322 .unit = SPI_DELAY_UNIT_USECS323 },324 };325 char *r_buffer = kzalloc(len, GFP_KERNEL);326 327 if (!r_buffer)328 return -ENOMEM;329 330 tr.rx_buf = r_buffer;331 dev_dbg(&spi->dev, "Request writing %d bytes\n", len);332 333 memset(&msg, 0, sizeof(msg));334 spi_message_init(&msg);335 spi_message_add_tail(&tr, &msg);336 337 ret = spi_sync(spi, &msg);338 if (ret < 0)339 dev_err(&spi->dev, "SPI transaction failed\n");340 341 kfree(r_buffer);342 } else {343 dev_err(&spi->dev,344 "can't write data with the following length: %d\n",345 len);346 ret = -EINVAL;347 }348 349 return ret;350}351 352static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)353{354 struct spi_device *spi = to_spi_device(wilc->dev);355 int ret;356 357 if (rlen > 0) {358 struct spi_message msg;359 struct spi_transfer tr = {360 .rx_buf = rb,361 .len = rlen,362 .delay = {363 .value = 0,364 .unit = SPI_DELAY_UNIT_USECS365 },366 367 };368 char *t_buffer = kzalloc(rlen, GFP_KERNEL);369 370 if (!t_buffer)371 return -ENOMEM;372 373 tr.tx_buf = t_buffer;374 375 memset(&msg, 0, sizeof(msg));376 spi_message_init(&msg);377 spi_message_add_tail(&tr, &msg);378 379 ret = spi_sync(spi, &msg);380 if (ret < 0)381 dev_err(&spi->dev, "SPI transaction failed\n");382 kfree(t_buffer);383 } else {384 dev_err(&spi->dev,385 "can't read data with the following length: %u\n",386 rlen);387 ret = -EINVAL;388 }389 390 return ret;391}392 393static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)394{395 struct spi_device *spi = to_spi_device(wilc->dev);396 int ret;397 398 if (rlen > 0) {399 struct spi_message msg;400 struct spi_transfer tr = {401 .rx_buf = rb,402 .tx_buf = wb,403 .len = rlen,404 .bits_per_word = 8,405 .delay = {406 .value = 0,407 .unit = SPI_DELAY_UNIT_USECS408 },409 410 };411 412 memset(&msg, 0, sizeof(msg));413 spi_message_init(&msg);414 spi_message_add_tail(&tr, &msg);415 ret = spi_sync(spi, &msg);416 if (ret < 0)417 dev_err(&spi->dev, "SPI transaction failed\n");418 } else {419 dev_err(&spi->dev,420 "can't read data with the following length: %u\n",421 rlen);422 ret = -EINVAL;423 }424 425 return ret;426}427 428static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)429{430 struct spi_device *spi = to_spi_device(wilc->dev);431 struct wilc_spi *spi_priv = wilc->bus_data;432 int ix, nbytes;433 int result = 0;434 u8 cmd, order, crc[2];435 u16 crc_calc;436 437 /*438 * Data439 */440 ix = 0;441 do {442 if (sz <= DATA_PKT_SZ) {443 nbytes = sz;444 order = 0x3;445 } else {446 nbytes = DATA_PKT_SZ;447 if (ix == 0)448 order = 0x1;449 else450 order = 0x02;451 }452 453 /*454 * Write command455 */456 cmd = 0xf0;457 cmd |= order;458 459 if (wilc_spi_tx(wilc, &cmd, 1)) {460 dev_err(&spi->dev,461 "Failed data block cmd write, bus error...\n");462 result = -EINVAL;463 break;464 }465 466 /*467 * Write data468 */469 if (wilc_spi_tx(wilc, &b[ix], nbytes)) {470 dev_err(&spi->dev,471 "Failed data block write, bus error...\n");472 result = -EINVAL;473 break;474 }475 476 /*477 * Write CRC478 */479 if (spi_priv->crc16_enabled) {480 crc_calc = crc_itu_t(0xffff, &b[ix], nbytes);481 crc[0] = crc_calc >> 8;482 crc[1] = crc_calc;483 if (wilc_spi_tx(wilc, crc, 2)) {484 dev_err(&spi->dev, "Failed data block crc write, bus error...\n");485 result = -EINVAL;486 break;487 }488 }489 490 /*491 * No need to wait for response492 */493 ix += nbytes;494 sz -= nbytes;495 } while (sz);496 497 return result;498}499 500/********************************************501 *502 * Spi Internal Read/Write Function503 *504 ********************************************/505static u8 wilc_get_crc7(u8 *buffer, u32 len)506{507 return crc7_be(0xfe, buffer, len) | 0x01;508}509 510static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,511 u8 clockless)512{513 struct spi_device *spi = to_spi_device(wilc->dev);514 struct wilc_spi *spi_priv = wilc->bus_data;515 u8 wb[32], rb[32];516 int cmd_len, resp_len, i;517 u16 crc_calc, crc_recv;518 struct wilc_spi_cmd *c;519 struct wilc_spi_rsp_data *r;520 struct wilc_spi_read_rsp_data *r_data;521 522 memset(wb, 0x0, sizeof(wb));523 memset(rb, 0x0, sizeof(rb));524 c = (struct wilc_spi_cmd *)wb;525 c->cmd_type = cmd;526 if (cmd == CMD_SINGLE_READ) {527 c->u.simple_cmd.addr[0] = adr >> 16;528 c->u.simple_cmd.addr[1] = adr >> 8;529 c->u.simple_cmd.addr[2] = adr;530 } else if (cmd == CMD_INTERNAL_READ) {531 c->u.simple_cmd.addr[0] = adr >> 8;532 if (clockless == 1)533 c->u.simple_cmd.addr[0] |= BIT(7);534 c->u.simple_cmd.addr[1] = adr;535 c->u.simple_cmd.addr[2] = 0x0;536 } else {537 dev_err(&spi->dev, "cmd [%x] not supported\n", cmd);538 return -EINVAL;539 }540 541 cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);542 resp_len = sizeof(*r) + sizeof(*r_data) + WILC_SPI_RSP_HDR_EXTRA_DATA;543 544 if (spi_priv->crc7_enabled) {545 c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);546 cmd_len += 1;547 resp_len += 2;548 }549 550 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {551 dev_err(&spi->dev,552 "spi buffer size too small (%d) (%d) (%zu)\n",553 cmd_len, resp_len, ARRAY_SIZE(wb));554 return -EINVAL;555 }556 557 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {558 dev_err(&spi->dev, "Failed cmd write, bus error...\n");559 return -EINVAL;560 }561 562 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];563 if (r->rsp_cmd_type != cmd && !clockless) {564 if (!spi_priv->probing_crc)565 dev_err(&spi->dev,566 "Failed cmd, cmd (%02x), resp (%02x)\n",567 cmd, r->rsp_cmd_type);568 return -EINVAL;569 }570 571 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS && !clockless) {572 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",573 r->status);574 return -EINVAL;575 }576 577 for (i = 0; i < WILC_SPI_RSP_HDR_EXTRA_DATA; ++i)578 if (WILC_GET_RESP_HDR_START(r->data[i]) == 0xf)579 break;580 581 if (i >= WILC_SPI_RSP_HDR_EXTRA_DATA) {582 dev_err(&spi->dev, "Error, data start missing\n");583 return -EINVAL;584 }585 586 r_data = (struct wilc_spi_read_rsp_data *)&r->data[i];587 588 if (b)589 memcpy(b, r_data->data, 4);590 591 if (!clockless && spi_priv->crc16_enabled) {592 crc_recv = (r_data->crc[0] << 8) | r_data->crc[1];593 crc_calc = crc_itu_t(0xffff, r_data->data, 4);594 if (crc_recv != crc_calc) {595 dev_err(&spi->dev, "%s: bad CRC 0x%04x "596 "(calculated 0x%04x)\n", __func__,597 crc_recv, crc_calc);598 return -EINVAL;599 }600 }601 602 return 0;603}604 605static int wilc_spi_write_cmd(struct wilc *wilc, u8 cmd, u32 adr, u32 data,606 u8 clockless)607{608 struct spi_device *spi = to_spi_device(wilc->dev);609 struct wilc_spi *spi_priv = wilc->bus_data;610 u8 wb[32], rb[32];611 int cmd_len, resp_len;612 struct wilc_spi_cmd *c;613 struct wilc_spi_rsp_data *r;614 615 memset(wb, 0x0, sizeof(wb));616 memset(rb, 0x0, sizeof(rb));617 c = (struct wilc_spi_cmd *)wb;618 c->cmd_type = cmd;619 if (cmd == CMD_INTERNAL_WRITE) {620 c->u.internal_w_cmd.addr[0] = adr >> 8;621 if (clockless == 1)622 c->u.internal_w_cmd.addr[0] |= BIT(7);623 624 c->u.internal_w_cmd.addr[1] = adr;625 c->u.internal_w_cmd.data = cpu_to_be32(data);626 cmd_len = offsetof(struct wilc_spi_cmd, u.internal_w_cmd.crc);627 if (spi_priv->crc7_enabled)628 c->u.internal_w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);629 } else if (cmd == CMD_SINGLE_WRITE) {630 c->u.w_cmd.addr[0] = adr >> 16;631 c->u.w_cmd.addr[1] = adr >> 8;632 c->u.w_cmd.addr[2] = adr;633 c->u.w_cmd.data = cpu_to_be32(data);634 cmd_len = offsetof(struct wilc_spi_cmd, u.w_cmd.crc);635 if (spi_priv->crc7_enabled)636 c->u.w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);637 } else {638 dev_err(&spi->dev, "write cmd [%x] not supported\n", cmd);639 return -EINVAL;640 }641 642 if (spi_priv->crc7_enabled)643 cmd_len += 1;644 645 resp_len = sizeof(*r);646 647 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {648 dev_err(&spi->dev,649 "spi buffer size too small (%d) (%d) (%zu)\n",650 cmd_len, resp_len, ARRAY_SIZE(wb));651 return -EINVAL;652 }653 654 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {655 dev_err(&spi->dev, "Failed cmd write, bus error...\n");656 return -EINVAL;657 }658 659 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];660 /*661 * Clockless registers operations might return unexptected responses,662 * even if successful.663 */664 if (r->rsp_cmd_type != cmd && !clockless) {665 dev_err(&spi->dev,666 "Failed cmd response, cmd (%02x), resp (%02x)\n",667 cmd, r->rsp_cmd_type);668 return -EINVAL;669 }670 671 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS && !clockless) {672 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",673 r->status);674 return -EINVAL;675 }676 677 return 0;678}679 680static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)681{682 struct spi_device *spi = to_spi_device(wilc->dev);683 struct wilc_spi *spi_priv = wilc->bus_data;684 u16 crc_recv, crc_calc;685 u8 wb[32], rb[32];686 int cmd_len, resp_len;687 int retry, ix = 0;688 u8 crc[2];689 struct wilc_spi_cmd *c;690 struct wilc_spi_rsp_data *r;691 692 memset(wb, 0x0, sizeof(wb));693 memset(rb, 0x0, sizeof(rb));694 c = (struct wilc_spi_cmd *)wb;695 c->cmd_type = cmd;696 if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_READ) {697 c->u.dma_cmd.addr[0] = adr >> 16;698 c->u.dma_cmd.addr[1] = adr >> 8;699 c->u.dma_cmd.addr[2] = adr;700 c->u.dma_cmd.size[0] = sz >> 8;701 c->u.dma_cmd.size[1] = sz;702 cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd.crc);703 if (spi_priv->crc7_enabled)704 c->u.dma_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);705 } else if (cmd == CMD_DMA_EXT_WRITE || cmd == CMD_DMA_EXT_READ) {706 c->u.dma_cmd_ext.addr[0] = adr >> 16;707 c->u.dma_cmd_ext.addr[1] = adr >> 8;708 c->u.dma_cmd_ext.addr[2] = adr;709 c->u.dma_cmd_ext.size[0] = sz >> 16;710 c->u.dma_cmd_ext.size[1] = sz >> 8;711 c->u.dma_cmd_ext.size[2] = sz;712 cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd_ext.crc);713 if (spi_priv->crc7_enabled)714 c->u.dma_cmd_ext.crc[0] = wilc_get_crc7(wb, cmd_len);715 } else {716 dev_err(&spi->dev, "dma read write cmd [%x] not supported\n",717 cmd);718 return -EINVAL;719 }720 if (spi_priv->crc7_enabled)721 cmd_len += 1;722 723 resp_len = sizeof(*r);724 725 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {726 dev_err(&spi->dev, "spi buffer size too small (%d)(%d) (%zu)\n",727 cmd_len, resp_len, ARRAY_SIZE(wb));728 return -EINVAL;729 }730 731 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {732 dev_err(&spi->dev, "Failed cmd write, bus error...\n");733 return -EINVAL;734 }735 736 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];737 if (r->rsp_cmd_type != cmd) {738 dev_err(&spi->dev,739 "Failed cmd response, cmd (%02x), resp (%02x)\n",740 cmd, r->rsp_cmd_type);741 return -EINVAL;742 }743 744 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {745 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",746 r->status);747 return -EINVAL;748 }749 750 if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_EXT_WRITE)751 return 0;752 753 while (sz > 0) {754 int nbytes;755 u8 rsp;756 757 nbytes = min_t(u32, sz, DATA_PKT_SZ);758 759 /*760 * Data Response header761 */762 retry = 100;763 do {764 if (wilc_spi_rx(wilc, &rsp, 1)) {765 dev_err(&spi->dev,766 "Failed resp read, bus err\n");767 return -EINVAL;768 }769 if (WILC_GET_RESP_HDR_START(rsp) == 0xf)770 break;771 } while (retry--);772 773 /*774 * Read bytes775 */776 if (wilc_spi_rx(wilc, &b[ix], nbytes)) {777 dev_err(&spi->dev,778 "Failed block read, bus err\n");779 return -EINVAL;780 }781 782 /*783 * Read CRC784 */785 if (spi_priv->crc16_enabled) {786 if (wilc_spi_rx(wilc, crc, 2)) {787 dev_err(&spi->dev,788 "Failed block CRC read, bus err\n");789 return -EINVAL;790 }791 crc_recv = (crc[0] << 8) | crc[1];792 crc_calc = crc_itu_t(0xffff, &b[ix], nbytes);793 if (crc_recv != crc_calc) {794 dev_err(&spi->dev, "%s: bad CRC 0x%04x "795 "(calculated 0x%04x)\n", __func__,796 crc_recv, crc_calc);797 return -EINVAL;798 }799 }800 801 ix += nbytes;802 sz -= nbytes;803 }804 return 0;805}806 807static int wilc_spi_special_cmd(struct wilc *wilc, u8 cmd)808{809 struct spi_device *spi = to_spi_device(wilc->dev);810 struct wilc_spi *spi_priv = wilc->bus_data;811 u8 wb[32], rb[32];812 int cmd_len, resp_len = 0;813 struct wilc_spi_cmd *c;814 struct wilc_spi_special_cmd_rsp *r;815 816 if (cmd != CMD_TERMINATE && cmd != CMD_REPEAT && cmd != CMD_RESET)817 return -EINVAL;818 819 memset(wb, 0x0, sizeof(wb));820 memset(rb, 0x0, sizeof(rb));821 c = (struct wilc_spi_cmd *)wb;822 c->cmd_type = cmd;823 824 if (cmd == CMD_RESET)825 memset(c->u.simple_cmd.addr, 0xFF, 3);826 827 cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);828 resp_len = sizeof(*r);829 830 if (spi_priv->crc7_enabled) {831 c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);832 cmd_len += 1;833 }834 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {835 dev_err(&spi->dev, "spi buffer size too small (%d) (%d) (%zu)\n",836 cmd_len, resp_len, ARRAY_SIZE(wb));837 return -EINVAL;838 }839 840 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {841 dev_err(&spi->dev, "Failed cmd write, bus error...\n");842 return -EINVAL;843 }844 845 r = (struct wilc_spi_special_cmd_rsp *)&rb[cmd_len];846 if (r->rsp_cmd_type != cmd) {847 if (!spi_priv->probing_crc)848 dev_err(&spi->dev,849 "Failed cmd response, cmd (%02x), resp (%02x)\n",850 cmd, r->rsp_cmd_type);851 return -EINVAL;852 }853 854 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {855 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",856 r->status);857 return -EINVAL;858 }859 return 0;860}861 862static void wilc_spi_reset_cmd_sequence(struct wilc *wl, u8 attempt, u32 addr)863{864 struct spi_device *spi = to_spi_device(wl->dev);865 struct wilc_spi *spi_priv = wl->bus_data;866 867 if (!spi_priv->probing_crc)868 dev_err(&spi->dev, "Reset and retry %d %x\n", attempt, addr);869 870 usleep_range(1000, 1100);871 wilc_spi_reset(wl);872 usleep_range(1000, 1100);873}874 875static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)876{877 struct spi_device *spi = to_spi_device(wilc->dev);878 int result;879 u8 cmd = CMD_SINGLE_READ;880 u8 clockless = 0;881 u8 i;882 883 if (addr <= WILC_SPI_CLOCKLESS_ADDR_LIMIT) {884 /* Clockless register */885 cmd = CMD_INTERNAL_READ;886 clockless = 1;887 }888 889 for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) {890 result = wilc_spi_single_read(wilc, cmd, addr, data, clockless);891 if (!result) {892 le32_to_cpus(data);893 return 0;894 }895 896 /* retry is not applicable for clockless registers */897 if (clockless)898 break;899 900 dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);901 wilc_spi_reset_cmd_sequence(wilc, i, addr);902 }903 904 return result;905}906 907static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)908{909 struct spi_device *spi = to_spi_device(wilc->dev);910 int result;911 u8 i;912 913 if (size <= 4)914 return -EINVAL;915 916 for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) {917 result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr,918 buf, size);919 if (!result)920 return 0;921 922 dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);923 924 wilc_spi_reset_cmd_sequence(wilc, i, addr);925 }926 927 return result;928}929 930static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)931{932 struct spi_device *spi = to_spi_device(wilc->dev);933 int result;934 u8 i;935 936 for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) {937 result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr,938 dat, 0);939 if (!result)940 return 0;941 dev_err(&spi->dev, "Failed internal write cmd...\n");942 943 wilc_spi_reset_cmd_sequence(wilc, i, adr);944 }945 946 return result;947}948 949static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)950{951 struct spi_device *spi = to_spi_device(wilc->dev);952 struct wilc_spi *spi_priv = wilc->bus_data;953 int result;954 u8 i;955 956 for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) {957 result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr,958 data, 0);959 if (!result) {960 le32_to_cpus(data);961 return 0;962 }963 if (!spi_priv->probing_crc)964 dev_err(&spi->dev, "Failed internal read cmd...\n");965 966 wilc_spi_reset_cmd_sequence(wilc, i, adr);967 }968 969 return result;970}971 972/********************************************973 *974 * Spi interfaces975 *976 ********************************************/977 978static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)979{980 struct spi_device *spi = to_spi_device(wilc->dev);981 int result;982 u8 cmd = CMD_SINGLE_WRITE;983 u8 clockless = 0;984 u8 i;985 986 if (addr <= WILC_SPI_CLOCKLESS_ADDR_LIMIT) {987 /* Clockless register */988 cmd = CMD_INTERNAL_WRITE;989 clockless = 1;990 }991 992 for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) {993 result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless);994 if (!result)995 return 0;996 997 dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);998 999 if (clockless)1000 break;1001 1002 wilc_spi_reset_cmd_sequence(wilc, i, addr);1003 }1004 return result;1005}1006 1007static int spi_data_rsp(struct wilc *wilc, u8 cmd)1008{1009 struct spi_device *spi = to_spi_device(wilc->dev);1010 int result, i;1011 u8 rsp[4];1012 1013 /*1014 * The response to data packets is two bytes long. For1015 * efficiency's sake, wilc_spi_write() wisely ignores the1016 * responses for all packets but the final one. The downside1017 * of that optimization is that when the final data packet is1018 * short, we may receive (part of) the response to the1019 * second-to-last packet before the one for the final packet.1020 * To handle this, we always read 4 bytes and then search for1021 * the last byte that contains the "Response Start" code (0xc1022 * in the top 4 bits). We then know that this byte is the1023 * first response byte of the final data packet.1024 */1025 result = wilc_spi_rx(wilc, rsp, sizeof(rsp));1026 if (result) {1027 dev_err(&spi->dev, "Failed bus error...\n");1028 return result;1029 }1030 1031 for (i = sizeof(rsp) - 2; i >= 0; --i)1032 if (FIELD_GET(RSP_START_FIELD, rsp[i]) == RSP_START_TAG)1033 break;1034 1035 if (i < 0) {1036 dev_err(&spi->dev,1037 "Data packet response missing (%02x %02x %02x %02x)\n",1038 rsp[0], rsp[1], rsp[2], rsp[3]);1039 return -1;1040 }1041 1042 /* rsp[i] is the last response start byte */1043 1044 if (FIELD_GET(RSP_TYPE_FIELD, rsp[i]) != RSP_TYPE_LAST_PACKET1045 || rsp[i + 1] != RSP_STATE_NO_ERROR) {1046 dev_err(&spi->dev, "Data response error (%02x %02x)\n",1047 rsp[i], rsp[i + 1]);1048 return -1;1049 }1050 return 0;1051}1052 1053static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)1054{1055 struct spi_device *spi = to_spi_device(wilc->dev);1056 int result;1057 u8 i;1058 1059 /*1060 * has to be greated than 41061 */1062 if (size <= 4)1063 return -EINVAL;1064 1065 for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) {1066 result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr,1067 NULL, size);1068 if (result) {1069 dev_err(&spi->dev,1070 "Failed cmd, write block (%08x)...\n", addr);1071 wilc_spi_reset_cmd_sequence(wilc, i, addr);1072 continue;1073 }1074 1075 /*1076 * Data1077 */1078 result = spi_data_write(wilc, buf, size);1079 if (result) {1080 dev_err(&spi->dev, "Failed block data write...\n");1081 wilc_spi_reset_cmd_sequence(wilc, i, addr);1082 continue;1083 }1084 1085 /*1086 * Data response1087 */1088 result = spi_data_rsp(wilc, CMD_DMA_EXT_WRITE);1089 if (result) {1090 dev_err(&spi->dev, "Failed block data rsp...\n");1091 wilc_spi_reset_cmd_sequence(wilc, i, addr);1092 continue;1093 }1094 break;1095 }1096 return result;1097}1098 1099/********************************************1100 *1101 * Bus interfaces1102 *1103 ********************************************/1104 1105static int wilc_spi_reset(struct wilc *wilc)1106{1107 struct spi_device *spi = to_spi_device(wilc->dev);1108 struct wilc_spi *spi_priv = wilc->bus_data;1109 int result;1110 1111 result = wilc_spi_special_cmd(wilc, CMD_RESET);1112 if (result && !spi_priv->probing_crc)1113 dev_err(&spi->dev, "Failed cmd reset\n");1114 1115 return result;1116}1117 1118static bool wilc_spi_is_init(struct wilc *wilc)1119{1120 struct wilc_spi *spi_priv = wilc->bus_data;1121 1122 return spi_priv->isinit;1123}1124 1125static int wilc_spi_deinit(struct wilc *wilc)1126{1127 struct wilc_spi *spi_priv = wilc->bus_data;1128 1129 spi_priv->isinit = false;1130 wilc_wlan_power(wilc, false);1131 return 0;1132}1133 1134static int wilc_spi_init(struct wilc *wilc, bool resume)1135{1136 struct wilc_spi *spi_priv = wilc->bus_data;1137 int ret;1138 1139 if (spi_priv->isinit) {1140 /* Confirm we can read chipid register without error: */1141 if (wilc_validate_chipid(wilc) == 0)1142 return 0;1143 }1144 1145 wilc_wlan_power(wilc, true);1146 1147 ret = wilc_spi_configure_bus_protocol(wilc);1148 if (ret) {1149 wilc_wlan_power(wilc, false);1150 return ret;1151 }1152 1153 spi_priv->isinit = true;1154 1155 return 0;1156}1157 1158static int wilc_spi_configure_bus_protocol(struct wilc *wilc)1159{1160 struct spi_device *spi = to_spi_device(wilc->dev);1161 struct wilc_spi *spi_priv = wilc->bus_data;1162 u32 reg;1163 int ret, i;1164 1165 /*1166 * Infer the CRC settings that are currently in effect. This1167 * is necessary because we can't be sure that the chip has1168 * been RESET (e.g, after module unload and reload).1169 */1170 spi_priv->probing_crc = true;1171 spi_priv->crc7_enabled = enable_crc7;1172 spi_priv->crc16_enabled = false; /* don't check CRC16 during probing */1173 for (i = 0; i < 2; ++i) {1174 ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®);1175 if (ret == 0)1176 break;1177 spi_priv->crc7_enabled = !enable_crc7;1178 }1179 if (ret) {1180 dev_err(&spi->dev, "Failed with CRC7 on and off.\n");1181 return ret;1182 }1183 1184 /* set up the desired CRC configuration: */1185 reg &= ~(PROTOCOL_REG_CRC7_MASK | PROTOCOL_REG_CRC16_MASK);1186 if (enable_crc7)1187 reg |= PROTOCOL_REG_CRC7_MASK;1188 if (enable_crc16)1189 reg |= PROTOCOL_REG_CRC16_MASK;1190 1191 /* set up the data packet size: */1192 BUILD_BUG_ON(DATA_PKT_LOG_SZ < DATA_PKT_LOG_SZ_MIN1193 || DATA_PKT_LOG_SZ > DATA_PKT_LOG_SZ_MAX);1194 reg &= ~PROTOCOL_REG_PKT_SZ_MASK;1195 reg |= FIELD_PREP(PROTOCOL_REG_PKT_SZ_MASK,1196 DATA_PKT_LOG_SZ - DATA_PKT_LOG_SZ_MIN);1197 1198 /* establish the new setup: */1199 ret = spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg);1200 if (ret) {1201 dev_err(&spi->dev,1202 "[wilc spi %d]: Failed internal write reg\n",1203 __LINE__);1204 return ret;1205 }1206 /* update our state to match new protocol settings: */1207 spi_priv->crc7_enabled = enable_crc7;1208 spi_priv->crc16_enabled = enable_crc16;1209 1210 /* re-read to make sure new settings are in effect: */1211 spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®);1212 1213 spi_priv->probing_crc = false;1214 1215 return 0;1216}1217 1218static int wilc_validate_chipid(struct wilc *wilc)1219{1220 struct spi_device *spi = to_spi_device(wilc->dev);1221 u32 chipid;1222 int ret;1223 1224 /*1225 * make sure can read chip id without protocol error1226 */1227 ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);1228 if (ret) {1229 dev_err(&spi->dev, "Fail cmd read chip id...\n");1230 return ret;1231 }1232 if (!is_wilc1000(chipid)) {1233 dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid);1234 return -ENODEV;1235 }1236 return 0;1237}1238 1239static int wilc_spi_read_size(struct wilc *wilc, u32 *size)1240{1241 int ret;1242 1243 ret = spi_internal_read(wilc,1244 WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE, size);1245 *size = FIELD_GET(IRQ_DMA_WD_CNT_MASK, *size);1246 1247 return ret;1248}1249 1250static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)1251{1252 return spi_internal_read(wilc, WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE,1253 int_status);1254}1255 1256static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)1257{1258 int ret;1259 int retry = SPI_ENABLE_VMM_RETRY_LIMIT;1260 u32 check;1261 1262 while (retry) {1263 ret = spi_internal_write(wilc,1264 WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,1265 val);1266 if (ret)1267 break;1268 1269 ret = spi_internal_read(wilc,1270 WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,1271 &check);1272 if (ret || ((check & EN_VMM) == (val & EN_VMM)))1273 break;1274 1275 retry--;1276 }1277 return ret;1278}1279 1280static int wilc_spi_sync_ext(struct wilc *wilc, int nint)1281{1282 struct spi_device *spi = to_spi_device(wilc->dev);1283 u32 reg;1284 int ret, i;1285 1286 if (nint > MAX_NUM_INT) {1287 dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);1288 return -EINVAL;1289 }1290 1291 /*1292 * interrupt pin mux select1293 */1294 ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®);1295 if (ret) {1296 dev_err(&spi->dev, "Failed read reg (%08x)...\n",1297 WILC_PIN_MUX_0);1298 return ret;1299 }1300 reg |= BIT(8);1301 ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);1302 if (ret) {1303 dev_err(&spi->dev, "Failed write reg (%08x)...\n",1304 WILC_PIN_MUX_0);1305 return ret;1306 }1307 1308 /*1309 * interrupt enable1310 */1311 ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®);1312 if (ret) {1313 dev_err(&spi->dev, "Failed read reg (%08x)...\n",1314 WILC_INTR_ENABLE);1315 return ret;1316 }1317 1318 for (i = 0; (i < 5) && (nint > 0); i++, nint--)1319 reg |= (BIT((27 + i)));1320 1321 ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);1322 if (ret) {1323 dev_err(&spi->dev, "Failed write reg (%08x)...\n",1324 WILC_INTR_ENABLE);1325 return ret;1326 }1327 if (nint) {1328 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®);1329 if (ret) {1330 dev_err(&spi->dev, "Failed read reg (%08x)...\n",1331 WILC_INTR2_ENABLE);1332 return ret;1333 }1334 1335 for (i = 0; (i < 3) && (nint > 0); i++, nint--)1336 reg |= BIT(i);1337 1338 ret = wilc_spi_write_reg(wilc, WILC_INTR2_ENABLE, reg);1339 if (ret) {1340 dev_err(&spi->dev, "Failed write reg (%08x)...\n",1341 WILC_INTR2_ENABLE);1342 return ret;1343 }1344 }1345 1346 return 0;1347}1348 1349/* Global spi HIF function table */1350static const struct wilc_hif_func wilc_hif_spi = {1351 .hif_init = wilc_spi_init,1352 .hif_deinit = wilc_spi_deinit,1353 .hif_read_reg = wilc_spi_read_reg,1354 .hif_write_reg = wilc_spi_write_reg,1355 .hif_block_rx = wilc_spi_read,1356 .hif_block_tx = wilc_spi_write,1357 .hif_read_int = wilc_spi_read_int,1358 .hif_clear_int_ext = wilc_spi_clear_int_ext,1359 .hif_read_size = wilc_spi_read_size,1360 .hif_block_tx_ext = wilc_spi_write,1361 .hif_block_rx_ext = wilc_spi_read,1362 .hif_sync_ext = wilc_spi_sync_ext,1363 .hif_reset = wilc_spi_reset,1364 .hif_is_init = wilc_spi_is_init,1365};1366