uboot/drivers/net/e1000_spi.c
<<
>>
Prefs
   1#include <common.h>
   2#include <command.h>
   3#include <console.h>
   4#include <linux/delay.h>
   5#include "e1000.h"
   6#include <malloc.h>
   7#include <linux/compiler.h>
   8
   9/*-----------------------------------------------------------------------
  10 * SPI transfer
  11 *
  12 * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
  13 * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
  14 *
  15 * The source of the outgoing bits is the "dout" parameter and the
  16 * destination of the input bits is the "din" parameter.  Note that "dout"
  17 * and "din" can point to the same memory location, in which case the
  18 * input data overwrites the output data (since both are buffered by
  19 * temporary variables, this is OK).
  20 *
  21 * This may be interrupted with Ctrl-C if "intr" is true, otherwise it will
  22 * never return an error.
  23 */
  24static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen,
  25                const void *dout_mem, void *din_mem, bool intr)
  26{
  27        const uint8_t *dout = dout_mem;
  28        uint8_t *din = din_mem;
  29
  30        uint8_t mask = 0;
  31        uint32_t eecd;
  32        unsigned long i;
  33
  34        /* Pre-read the control register */
  35        eecd = E1000_READ_REG(hw, EECD);
  36
  37        /* Iterate over each bit */
  38        for (i = 0, mask = 0x80; i < bitlen; i++, mask = (mask >> 1)?:0x80) {
  39                /* Check for interrupt */
  40                if (intr && ctrlc())
  41                        return -1;
  42
  43                /* Determine the output bit */
  44                if (dout && dout[i >> 3] & mask)
  45                        eecd |=  E1000_EECD_DI;
  46                else
  47                        eecd &= ~E1000_EECD_DI;
  48
  49                /* Write the output bit and wait 50us */
  50                E1000_WRITE_REG(hw, EECD, eecd);
  51                E1000_WRITE_FLUSH(hw);
  52                udelay(50);
  53
  54                /* Poke the clock (waits 50us) */
  55                e1000_raise_ee_clk(hw, &eecd);
  56
  57                /* Now read the input bit */
  58                eecd = E1000_READ_REG(hw, EECD);
  59                if (din) {
  60                        if (eecd & E1000_EECD_DO)
  61                                din[i >> 3] |=  mask;
  62                        else
  63                                din[i >> 3] &= ~mask;
  64                }
  65
  66                /* Poke the clock again (waits 50us) */
  67                e1000_lower_ee_clk(hw, &eecd);
  68        }
  69
  70        /* Now clear any remaining bits of the input */
  71        if (din && (i & 7))
  72                din[i >> 3] &= ~((mask << 1) - 1);
  73
  74        return 0;
  75}
  76
  77#ifdef CONFIG_E1000_SPI_GENERIC
  78static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi)
  79{
  80        return container_of(spi, struct e1000_hw, spi);
  81}
  82
  83struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  84                unsigned int max_hz, unsigned int mode)
  85{
  86        /* Find the right PCI device */
  87        struct e1000_hw *hw = e1000_find_card(bus);
  88        if (!hw) {
  89                printf("ERROR: No such e1000 device: e1000#%u\n", bus);
  90                return NULL;
  91        }
  92
  93        /* Make sure it has an SPI chip */
  94        if (hw->eeprom.type != e1000_eeprom_spi) {
  95                E1000_ERR(hw, "No attached SPI EEPROM found!\n");
  96                return NULL;
  97        }
  98
  99        /* Argument sanity checks */
 100        if (cs != 0) {
 101                E1000_ERR(hw, "No such SPI chip: %u\n", cs);
 102                return NULL;
 103        }
 104        if (mode != SPI_MODE_0) {
 105                E1000_ERR(hw, "Only SPI MODE-0 is supported!\n");
 106                return NULL;
 107        }
 108
 109        /* TODO: Use max_hz somehow */
 110        E1000_DBG(hw->nic, "EEPROM SPI access requested\n");
 111        return &hw->spi;
 112}
 113
 114void spi_free_slave(struct spi_slave *spi)
 115{
 116        __maybe_unused struct e1000_hw *hw = e1000_hw_from_spi(spi);
 117        E1000_DBG(hw->nic, "EEPROM SPI access released\n");
 118}
 119
 120int spi_claim_bus(struct spi_slave *spi)
 121{
 122        struct e1000_hw *hw = e1000_hw_from_spi(spi);
 123
 124        if (e1000_acquire_eeprom(hw)) {
 125                E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
 126                return -1;
 127        }
 128
 129        return 0;
 130}
 131
 132void spi_release_bus(struct spi_slave *spi)
 133{
 134        struct e1000_hw *hw = e1000_hw_from_spi(spi);
 135        e1000_release_eeprom(hw);
 136}
 137
 138/* Skinny wrapper around e1000_spi_xfer */
 139int spi_xfer(struct spi_slave *spi, unsigned int bitlen,
 140                const void *dout_mem, void *din_mem, unsigned long flags)
 141{
 142        struct e1000_hw *hw = e1000_hw_from_spi(spi);
 143        int ret;
 144
 145        if (flags & SPI_XFER_BEGIN)
 146                e1000_standby_eeprom(hw);
 147
 148        ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, true);
 149
 150        if (flags & SPI_XFER_END)
 151                e1000_standby_eeprom(hw);
 152
 153        return ret;
 154}
 155
 156#endif /* not CONFIG_E1000_SPI_GENERIC */
 157
 158#ifdef CONFIG_CMD_E1000
 159
 160/* The EEPROM opcodes */
 161#define SPI_EEPROM_ENABLE_WR    0x06
 162#define SPI_EEPROM_DISABLE_WR   0x04
 163#define SPI_EEPROM_WRITE_STATUS 0x01
 164#define SPI_EEPROM_READ_STATUS  0x05
 165#define SPI_EEPROM_WRITE_PAGE   0x02
 166#define SPI_EEPROM_READ_PAGE    0x03
 167
 168/* The EEPROM status bits */
 169#define SPI_EEPROM_STATUS_BUSY  0x01
 170#define SPI_EEPROM_STATUS_WREN  0x02
 171
 172static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, bool intr)
 173{
 174        u8 op[] = { SPI_EEPROM_ENABLE_WR };
 175        e1000_standby_eeprom(hw);
 176        return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
 177}
 178
 179/*
 180 * These have been tested to perform correctly, but they are not used by any
 181 * of the EEPROM commands at this time.
 182 */
 183static __maybe_unused int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw,
 184                                                      bool intr)
 185{
 186        u8 op[] = { SPI_EEPROM_DISABLE_WR };
 187        e1000_standby_eeprom(hw);
 188        return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
 189}
 190
 191static __maybe_unused int e1000_spi_eeprom_write_status(struct e1000_hw *hw,
 192                                                        u8 status, bool intr)
 193{
 194        u8 op[] = { SPI_EEPROM_WRITE_STATUS, status };
 195        e1000_standby_eeprom(hw);
 196        return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
 197}
 198
 199static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, bool intr)
 200{
 201        u8 op[] = { SPI_EEPROM_READ_STATUS, 0 };
 202        e1000_standby_eeprom(hw);
 203        if (e1000_spi_xfer(hw, 8*sizeof(op), op, op, intr))
 204                return -1;
 205        return op[1];
 206}
 207
 208static int e1000_spi_eeprom_write_page(struct e1000_hw *hw,
 209                const void *data, u16 off, u16 len, bool intr)
 210{
 211        u8 op[] = {
 212                SPI_EEPROM_WRITE_PAGE,
 213                (off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
 214        };
 215
 216        e1000_standby_eeprom(hw);
 217
 218        if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
 219                return -1;
 220        if (e1000_spi_xfer(hw, len << 3, data, NULL, intr))
 221                return -1;
 222
 223        return 0;
 224}
 225
 226static int e1000_spi_eeprom_read_page(struct e1000_hw *hw,
 227                void *data, u16 off, u16 len, bool intr)
 228{
 229        u8 op[] = {
 230                SPI_EEPROM_READ_PAGE,
 231                (off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
 232        };
 233
 234        e1000_standby_eeprom(hw);
 235
 236        if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
 237                return -1;
 238        if (e1000_spi_xfer(hw, len << 3, NULL, data, intr))
 239                return -1;
 240
 241        return 0;
 242}
 243
 244static int e1000_spi_eeprom_poll_ready(struct e1000_hw *hw, bool intr)
 245{
 246        int status;
 247        while ((status = e1000_spi_eeprom_read_status(hw, intr)) >= 0) {
 248                if (!(status & SPI_EEPROM_STATUS_BUSY))
 249                        return 0;
 250        }
 251        return -1;
 252}
 253
 254static int e1000_spi_eeprom_dump(struct e1000_hw *hw,
 255                void *data, u16 off, unsigned int len, bool intr)
 256{
 257        /* Interruptibly wait for the EEPROM to be ready */
 258        if (e1000_spi_eeprom_poll_ready(hw, intr))
 259                return -1;
 260
 261        /* Dump each page in sequence */
 262        while (len) {
 263                /* Calculate the data bytes on this page */
 264                u16 pg_off = off & (hw->eeprom.page_size - 1);
 265                u16 pg_len = hw->eeprom.page_size - pg_off;
 266                if (pg_len > len)
 267                        pg_len = len;
 268
 269                /* Now dump the page */
 270                if (e1000_spi_eeprom_read_page(hw, data, off, pg_len, intr))
 271                        return -1;
 272
 273                /* Otherwise go on to the next page */
 274                len  -= pg_len;
 275                off  += pg_len;
 276                data += pg_len;
 277        }
 278
 279        /* We're done! */
 280        return 0;
 281}
 282
 283static int e1000_spi_eeprom_program(struct e1000_hw *hw,
 284                const void *data, u16 off, u16 len, bool intr)
 285{
 286        /* Program each page in sequence */
 287        while (len) {
 288                /* Calculate the data bytes on this page */
 289                u16 pg_off = off & (hw->eeprom.page_size - 1);
 290                u16 pg_len = hw->eeprom.page_size - pg_off;
 291                if (pg_len > len)
 292                        pg_len = len;
 293
 294                /* Interruptibly wait for the EEPROM to be ready */
 295                if (e1000_spi_eeprom_poll_ready(hw, intr))
 296                        return -1;
 297
 298                /* Enable write access */
 299                if (e1000_spi_eeprom_enable_wr(hw, intr))
 300                        return -1;
 301
 302                /* Now program the page */
 303                if (e1000_spi_eeprom_write_page(hw, data, off, pg_len, intr))
 304                        return -1;
 305
 306                /* Otherwise go on to the next page */
 307                len  -= pg_len;
 308                off  += pg_len;
 309                data += pg_len;
 310        }
 311
 312        /* Wait for the last write to complete */
 313        if (e1000_spi_eeprom_poll_ready(hw, intr))
 314                return -1;
 315
 316        /* We're done! */
 317        return 0;
 318}
 319
 320static int do_e1000_spi_show(struct cmd_tbl *cmdtp, struct e1000_hw *hw,
 321                             int argc, char *const argv[])
 322{
 323        unsigned int length = 0;
 324        u16 i, offset = 0;
 325        u8 *buffer;
 326        int err;
 327
 328        if (argc > 2) {
 329                cmd_usage(cmdtp);
 330                return 1;
 331        }
 332
 333        /* Parse the offset and length */
 334        if (argc >= 1)
 335                offset = simple_strtoul(argv[0], NULL, 0);
 336        if (argc == 2)
 337                length = simple_strtoul(argv[1], NULL, 0);
 338        else if (offset < (hw->eeprom.word_size << 1))
 339                length = (hw->eeprom.word_size << 1) - offset;
 340
 341        /* Extra sanity checks */
 342        if (!length) {
 343                E1000_ERR(hw, "Requested zero-sized dump!\n");
 344                return 1;
 345        }
 346        if ((0x10000 < length) || (0x10000 - length < offset)) {
 347                E1000_ERR(hw, "Can't dump past 0xFFFF!\n");
 348                return 1;
 349        }
 350
 351        /* Allocate a buffer to hold stuff */
 352        buffer = malloc(length);
 353        if (!buffer) {
 354                E1000_ERR(hw, "Out of Memory!\n");
 355                return 1;
 356        }
 357
 358        /* Acquire the EEPROM and perform the dump */
 359        if (e1000_acquire_eeprom(hw)) {
 360                E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
 361                free(buffer);
 362                return 1;
 363        }
 364        err = e1000_spi_eeprom_dump(hw, buffer, offset, length, true);
 365        e1000_release_eeprom(hw);
 366        if (err) {
 367                E1000_ERR(hw, "Interrupted!\n");
 368                free(buffer);
 369                return 1;
 370        }
 371
 372        /* Now hexdump the result */
 373        printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====",
 374                        hw->name, offset, offset + length - 1);
 375        for (i = 0; i < length; i++) {
 376                if ((i & 0xF) == 0)
 377                        printf("\n%s: %04hX: ", hw->name, offset + i);
 378                else if ((i & 0xF) == 0x8)
 379                        printf(" ");
 380                printf(" %02hx", buffer[i]);
 381        }
 382        printf("\n");
 383
 384        /* Success! */
 385        free(buffer);
 386        return 0;
 387}
 388
 389static int do_e1000_spi_dump(struct cmd_tbl *cmdtp, struct e1000_hw *hw,
 390                             int argc, char *const argv[])
 391{
 392        unsigned int length;
 393        u16 offset;
 394        void *dest;
 395
 396        if (argc != 3) {
 397                cmd_usage(cmdtp);
 398                return 1;
 399        }
 400
 401        /* Parse the arguments */
 402        dest = (void *)simple_strtoul(argv[0], NULL, 16);
 403        offset = simple_strtoul(argv[1], NULL, 0);
 404        length = simple_strtoul(argv[2], NULL, 0);
 405
 406        /* Extra sanity checks */
 407        if (!length) {
 408                E1000_ERR(hw, "Requested zero-sized dump!\n");
 409                return 1;
 410        }
 411        if ((0x10000 < length) || (0x10000 - length < offset)) {
 412                E1000_ERR(hw, "Can't dump past 0xFFFF!\n");
 413                return 1;
 414        }
 415
 416        /* Acquire the EEPROM */
 417        if (e1000_acquire_eeprom(hw)) {
 418                E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
 419                return 1;
 420        }
 421
 422        /* Perform the programming operation */
 423        if (e1000_spi_eeprom_dump(hw, dest, offset, length, true) < 0) {
 424                E1000_ERR(hw, "Interrupted!\n");
 425                e1000_release_eeprom(hw);
 426                return 1;
 427        }
 428
 429        e1000_release_eeprom(hw);
 430        printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->name);
 431        return 0;
 432}
 433
 434static int do_e1000_spi_program(struct cmd_tbl *cmdtp, struct e1000_hw *hw,
 435                                int argc, char *const argv[])
 436{
 437        unsigned int length;
 438        const void *source;
 439        u16 offset;
 440
 441        if (argc != 3) {
 442                cmd_usage(cmdtp);
 443                return 1;
 444        }
 445
 446        /* Parse the arguments */
 447        source = (const void *)simple_strtoul(argv[0], NULL, 16);
 448        offset = simple_strtoul(argv[1], NULL, 0);
 449        length = simple_strtoul(argv[2], NULL, 0);
 450
 451        /* Acquire the EEPROM */
 452        if (e1000_acquire_eeprom(hw)) {
 453                E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
 454                return 1;
 455        }
 456
 457        /* Perform the programming operation */
 458        if (e1000_spi_eeprom_program(hw, source, offset, length, true) < 0) {
 459                E1000_ERR(hw, "Interrupted!\n");
 460                e1000_release_eeprom(hw);
 461                return 1;
 462        }
 463
 464        e1000_release_eeprom(hw);
 465        printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->name);
 466        return 0;
 467}
 468
 469static int do_e1000_spi_checksum(struct cmd_tbl *cmdtp, struct e1000_hw *hw,
 470                                 int argc, char *const argv[])
 471{
 472        uint16_t i, length, checksum = 0, checksum_reg;
 473        uint16_t *buffer;
 474        bool upd;
 475
 476        if (argc == 0)
 477                upd = 0;
 478        else if ((argc == 1) && !strcmp(argv[0], "update"))
 479                upd = 1;
 480        else {
 481                cmd_usage(cmdtp);
 482                return 1;
 483        }
 484
 485        /* Allocate a temporary buffer */
 486        length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1);
 487        buffer = malloc(length);
 488        if (!buffer) {
 489                E1000_ERR(hw, "Unable to allocate EEPROM buffer!\n");
 490                return 1;
 491        }
 492
 493        /* Acquire the EEPROM */
 494        if (e1000_acquire_eeprom(hw)) {
 495                E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
 496                return 1;
 497        }
 498
 499        /* Read the EEPROM */
 500        if (e1000_spi_eeprom_dump(hw, buffer, 0, length, true) < 0) {
 501                E1000_ERR(hw, "Interrupted!\n");
 502                e1000_release_eeprom(hw);
 503                return 1;
 504        }
 505
 506        /* Compute the checksum and read the expected value */
 507        for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
 508                checksum += le16_to_cpu(buffer[i]);
 509        checksum = ((uint16_t)EEPROM_SUM) - checksum;
 510        checksum_reg = le16_to_cpu(buffer[i]);
 511
 512        /* Verify it! */
 513        if (checksum_reg == checksum) {
 514                printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n",
 515                                hw->name, checksum);
 516                e1000_release_eeprom(hw);
 517                return 0;
 518        }
 519
 520        /* Hrm, verification failed, print an error */
 521        E1000_ERR(hw, "EEPROM checksum is incorrect!\n");
 522        E1000_ERR(hw, "  ...register was 0x%04hx, calculated 0x%04hx\n",
 523                  checksum_reg, checksum);
 524
 525        /* If they didn't ask us to update it, just return an error */
 526        if (!upd) {
 527                e1000_release_eeprom(hw);
 528                return 1;
 529        }
 530
 531        /* Ok, correct it! */
 532        printf("%s: Reprogramming the EEPROM checksum...\n", hw->name);
 533        buffer[i] = cpu_to_le16(checksum);
 534        if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t),
 535                        sizeof(uint16_t), true)) {
 536                E1000_ERR(hw, "Interrupted!\n");
 537                e1000_release_eeprom(hw);
 538                return 1;
 539        }
 540
 541        e1000_release_eeprom(hw);
 542        return 0;
 543}
 544
 545int do_e1000_spi(struct cmd_tbl *cmdtp, struct e1000_hw *hw,
 546                 int argc, char *const argv[])
 547{
 548        if (argc < 1) {
 549                cmd_usage(cmdtp);
 550                return 1;
 551        }
 552
 553        /* Make sure it has an SPI chip */
 554        if (hw->eeprom.type != e1000_eeprom_spi) {
 555                E1000_ERR(hw, "No attached SPI EEPROM found (%d)!\n",
 556                          hw->eeprom.type);
 557                return 1;
 558        }
 559
 560        /* Check the eeprom sub-sub-command arguments */
 561        if (!strcmp(argv[0], "show"))
 562                return do_e1000_spi_show(cmdtp, hw, argc - 1, argv + 1);
 563
 564        if (!strcmp(argv[0], "dump"))
 565                return do_e1000_spi_dump(cmdtp, hw, argc - 1, argv + 1);
 566
 567        if (!strcmp(argv[0], "program"))
 568                return do_e1000_spi_program(cmdtp, hw, argc - 1, argv + 1);
 569
 570        if (!strcmp(argv[0], "checksum"))
 571                return do_e1000_spi_checksum(cmdtp, hw, argc - 1, argv + 1);
 572
 573        cmd_usage(cmdtp);
 574        return 1;
 575}
 576
 577#endif /* not CONFIG_CMD_E1000 */
 578