Skip to content

Commit 174dcf8

Browse files
ajaykathatnoglitch
authored andcommitted
wilc1000: handled extra bytes received before response header in SPI
In SPI communication, found that extra bytes were received before the start of response header especially at lower clock speed. Added logic to ignore extra bytes till the start of response header. Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
1 parent d96c255 commit 174dcf8

1 file changed

Lines changed: 26 additions & 16 deletions

File tree

  • drivers/staging/wilc1000

drivers/staging/wilc1000/spi.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,15 @@ struct wilc_spi_cmd {
9191
} __packed;
9292

9393
struct wilc_spi_read_rsp_data {
94-
u8 rsp_cmd_type;
95-
u8 status;
96-
u8 resp_header;
97-
u8 resp_data[4];
94+
u8 header;
95+
u8 data[4];
9896
u8 crc[];
9997
} __packed;
10098

10199
struct wilc_spi_rsp_data {
102100
u8 rsp_cmd_type;
103101
u8 status;
102+
u8 data[];
104103
} __packed;
105104

106105
struct wilc_spi_special_cmd_rsp {
@@ -480,6 +479,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
480479
* Spi Internal Read/Write Function
481480
*
482481
********************************************/
482+
#define WILC_SPI_RSP_HDR_EXTRA_DATA (3)
483483
static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
484484
u8 clockless)
485485
{
@@ -489,7 +489,9 @@ static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
489489
int cmd_len, resp_len = 0;
490490
u8 crc[2];
491491
struct wilc_spi_cmd *c;
492-
struct wilc_spi_read_rsp_data *r;
492+
struct wilc_spi_rsp_data *rsp;
493+
struct wilc_spi_read_rsp_data *r_data;
494+
int i = 0;
493495

494496
memset(wb, 0x0, sizeof(wb));
495497
memset(rb, 0x0, sizeof(rb));
@@ -511,7 +513,7 @@ static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
511513
}
512514

513515
cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
514-
resp_len = sizeof(*r);
516+
resp_len = sizeof(*rsp) + sizeof(*r_data) + WILC_SPI_RSP_HDR_EXTRA_DATA;
515517

516518
if (!spi_priv->crc_off) {
517519
c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
@@ -530,34 +532,42 @@ static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
530532
return -EINVAL;
531533
}
532534

533-
r = (struct wilc_spi_read_rsp_data *)&rb[cmd_len];
535+
rsp = (struct wilc_spi_rsp_data *)&rb[cmd_len];
534536
/*
535537
* Clockless registers operations might return unexptected responses,
536538
* even if successful.
537539
*/
538-
if (r->rsp_cmd_type != cmd && !clockless) {
540+
if (rsp->rsp_cmd_type != cmd && !clockless) {
539541
dev_err(&spi->dev,
540542
"Failed cmd response, cmd (%02x), resp (%02x)\n",
541-
cmd, r->rsp_cmd_type);
543+
cmd, rsp->rsp_cmd_type);
542544
return -EINVAL;
543545
}
544546

545-
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS && !clockless) {
547+
if (rsp->status != WILC_SPI_COMMAND_STAT_SUCCESS && !clockless) {
546548
dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
547-
r->status);
549+
rsp->status);
548550
return -EINVAL;
549551
}
550552

551-
if (WILC_GET_RESP_HDR_START(r->resp_header) != 0xf) {
552-
dev_err(&spi->dev, "Error, data read response (%02x)\n",
553-
r->resp_header);
553+
do {
554+
if (WILC_GET_RESP_HDR_START(rsp->data[i]) == 0xf)
555+
break;
556+
i++;
557+
} while (i < SPI_RESP_RETRY_COUNT);
558+
559+
if (i >= SPI_RESP_RETRY_COUNT) {
560+
dev_err(&spi->dev, "Error, data read response\n");
554561
return -EINVAL;
555562
}
563+
564+
r_data = (struct wilc_spi_read_rsp_data *)&rsp->data[i];
565+
556566
if (b)
557-
memcpy(b, r->resp_data, 4);
567+
memcpy(b, r_data->data, 4);
558568

559569
if (!spi_priv->crc_off)
560-
memcpy(crc, r->crc, 2);
570+
memcpy(crc, r_data->crc, 2);
561571

562572
return 0;
563573
}

0 commit comments

Comments
 (0)