Mon Dec 30 16:28:15 2019 UTC ()
Follow the Linux driver an use the FDT "compatible" property to build a
filename for the nvram config file, fall back to the standard filename.

E.g.

# ofctl -p /
[Caching 123 nodes and 1093 properties]
#address-cells          00000001 ........ ........ ........     1
#size-cells             00000001 ........ ........ ........     1
compatible              73696e6f 766f6970 2c627069 2d6d322d   "sinovoip,bpi-m2-
            0010:       7a65726f 00...... ........ ........   zero"
            0015:       616c6c77 696e6e65 722c7375 6e38692d   "allwinner,sun8i-
            0025:       68322d70 6c757300 ........ ........   h2-plus"
interrupt-parent        00000001 ........ ........ ........   ....
model                   42616e61 6e612050 69204250 492d4d32   "Banana Pi BPI-M2
            0010:       2d5a6572 6f00.... ........ ........   -Zero"
name                    00...... ........ ........ ........   ""
serial-number           30326330 30303432 65636431 36376566   02c00042ecd167ef
            0010:       00...... ........ ........ ........   .

-rw-r--r--  1 root  wheel     875 Nov  2 12:06 brcmfmac43430-sdio.AP6212.txt
lrwxr-xr-x  1 root  wheel      29 Dec 30 16:19 brcmfmac43430-sdio.sinovoip,bpi-m2-zero.txt -> brcmfmac43430-sdio.AP6212.txt
-rw-r--r--  1 root  wheel     874 Jun 30  2019 brcmfmac43430-sdio.raspberrypi,3-model-b.txt
-rw-r--r--  1 root  wheel    1864 Jun 30  2019 brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt
lrwxr-xr-x  1 root  wheel      29 Dec 30 11:24 brcmfmac43455-sdio.raspberrypi,4-model-b-plus.txt -> brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt


(mlelstv)
diff -r1.9 -r1.10 src/sys/dev/sdmmc/if_bwfm_sdio.c

cvs diff -r1.9 -r1.10 src/sys/dev/sdmmc/if_bwfm_sdio.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/if_bwfm_sdio.c 2019/10/28 06:37:52 1.9
+++ src/sys/dev/sdmmc/if_bwfm_sdio.c 2019/12/30 16:28:14 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_bwfm_sdio.c,v 1.9 2019/10/28 06:37:52 mlelstv Exp $ */ 1/* $NetBSD: if_bwfm_sdio.c,v 1.10 2019/12/30 16:28:14 mlelstv Exp $ */
2/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ 2/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
3/* 3/*
4 * Copyright (c) 2010-2016 Broadcom Corporation 4 * Copyright (c) 2010-2016 Broadcom Corporation
5 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> 5 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
6 * 6 *
7 * Permission to use, copy, modify, and/or distribute this software for any 7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -106,26 +106,27 @@ struct bwfm_sdio_softc { @@ -106,26 +106,27 @@ struct bwfm_sdio_softc {
106 char *sc_console_buf; 106 char *sc_console_buf;
107 size_t sc_console_buf_size; 107 size_t sc_console_buf_size;
108 uint32_t sc_console_readidx; 108 uint32_t sc_console_readidx;
109 109
110 int sc_phandle; 110 int sc_phandle;
111 void *sc_fdtih; 111 void *sc_fdtih;
112}; 112};
113 113
114static int bwfm_sdio_match(device_t, cfdata_t, void *); 114static int bwfm_sdio_match(device_t, cfdata_t, void *);
115static void bwfm_sdio_attach(device_t, device_t, void *); 115static void bwfm_sdio_attach(device_t, device_t, void *);
116static int bwfm_sdio_detach(device_t, int); 116static int bwfm_sdio_detach(device_t, int);
117static void bwfm_sdio_attachhook(device_t); 117static void bwfm_sdio_attachhook(device_t);
118static int bwfm_fdt_find_phandle(device_t, device_t); 118static int bwfm_fdt_find_phandle(device_t, device_t);
 119static const char *bwfm_fdt_get_model(void);
119 120
120static void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t); 121static void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t);
121static uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t); 122static uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t);
122static uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t); 123static uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t);
123static void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t, 124static void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t,
124 uint8_t); 125 uint8_t);
125static void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t, 126static void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t,
126 uint32_t); 127 uint32_t);
127 128
128static uint32_t bwfm_sdio_dev_read(struct bwfm_sdio_softc *, uint32_t); 129static uint32_t bwfm_sdio_dev_read(struct bwfm_sdio_softc *, uint32_t);
129static void bwfm_sdio_dev_write(struct bwfm_sdio_softc *, uint32_t, 130static void bwfm_sdio_dev_write(struct bwfm_sdio_softc *, uint32_t,
130 uint32_t); 131 uint32_t);
131 132
@@ -367,27 +368,28 @@ bwfm_sdio_attach(device_t parent, device @@ -367,27 +368,28 @@ bwfm_sdio_attach(device_t parent, device
367 368
368 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 0); 369 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 0);
369 sc->sc_clkstate = CLK_SDONLY; 370 sc->sc_clkstate = CLK_SDONLY;
370 371
371 config_mountroot(self, bwfm_sdio_attachhook); 372 config_mountroot(self, bwfm_sdio_attachhook);
372} 373}
373 374
374static void 375static void
375bwfm_sdio_attachhook(device_t self) 376bwfm_sdio_attachhook(device_t self)
376{ 377{
377 struct bwfm_sdio_softc *sc = device_private(self); 378 struct bwfm_sdio_softc *sc = device_private(self);
378 struct bwfm_softc *bwfm = &sc->sc_sc; 379 struct bwfm_softc *bwfm = &sc->sc_sc;
379 firmware_handle_t fwh; 380 firmware_handle_t fwh;
380 const char *name, *nvname; 381 const char *name, *nvname, *model;
 382 char *nvnamebuf;
381 u_char *ucode, *nvram; 383 u_char *ucode, *nvram;
382 size_t size, nvlen, nvsize; 384 size_t size, nvlen, nvsize;
383 uint32_t reg, clk; 385 uint32_t reg, clk;
384 int error; 386 int error;
385 387
386 DPRINTF(("%s: chip 0x%08x rev %u\n", DEVNAME(sc), 388 DPRINTF(("%s: chip 0x%08x rev %u\n", DEVNAME(sc),
387 bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev)); 389 bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev));
388 switch (bwfm->sc_chip.ch_chip) { 390 switch (bwfm->sc_chip.ch_chip) {
389 case BRCM_CC_4330_CHIP_ID: 391 case BRCM_CC_4330_CHIP_ID:
390 name = "brcmfmac4330-sdio.bin"; 392 name = "brcmfmac4330-sdio.bin";
391 nvname = "brcmfmac4330-sdio.txt"; 393 nvname = "brcmfmac4330-sdio.txt";
392 break; 394 break;
393 case BRCM_CC_4334_CHIP_ID: 395 case BRCM_CC_4334_CHIP_ID:
@@ -425,48 +427,64 @@ bwfm_sdio_attachhook(device_t self) @@ -425,48 +427,64 @@ bwfm_sdio_attachhook(device_t self)
425 nvname = "brcmfmac43430-sdio.txt"; 427 nvname = "brcmfmac43430-sdio.txt";
426 } 428 }
427 break; 429 break;
428 case BRCM_CC_4356_CHIP_ID: 430 case BRCM_CC_4356_CHIP_ID:
429 name = "brcmfmac4356-sdio.bin"; 431 name = "brcmfmac4356-sdio.bin";
430 nvname = "brcmfmac4356-sdio.txt"; 432 nvname = "brcmfmac4356-sdio.txt";
431 break; 433 break;
432 default: 434 default:
433 printf("%s: unknown firmware for chip %s\n", 435 printf("%s: unknown firmware for chip %s\n",
434 DEVNAME(sc), bwfm->sc_chip.ch_name); 436 DEVNAME(sc), bwfm->sc_chip.ch_name);
435 goto err; 437 goto err;
436 } 438 }
437 439
 440 /* compute a model specific filename for the NV config */
 441 nvnamebuf = NULL;
 442 model = bwfm_fdt_get_model();
 443 if (model != NULL) {
 444 /* assume nvname ends in ".txt" */
 445 nvnamebuf = kmem_asprintf("%.*s.%s.txt",
 446 (int)(strlen(nvname) - 4),
 447 nvname, model);
 448 }
 449
 450 aprint_verbose_dev(self, "Firmware %s\n", name);
 451 aprint_verbose_dev(self, "Default Config %s\n", nvname);
 452 if (nvnamebuf != NULL)
 453 aprint_verbose_dev(self, "Model Config %s\n", nvnamebuf);
 454
438 if (firmware_open("if_bwfm", name, &fwh) != 0) { 455 if (firmware_open("if_bwfm", name, &fwh) != 0) {
439 printf("%s: failed firmware_open of file %s\n", 456 printf("%s: failed firmware_open of file %s\n",
440 DEVNAME(sc), name); 457 DEVNAME(sc), name);
441 goto err; 458 goto err;
442 } 459 }
443 size = firmware_get_size(fwh); 460 size = firmware_get_size(fwh);
444 ucode = firmware_malloc(size); 461 ucode = firmware_malloc(size);
445 if (ucode == NULL) { 462 if (ucode == NULL) {
446 printf("%s: failed firmware_open of file %s\n", 463 printf("%s: failed firmware_open of file %s\n",
447 DEVNAME(sc), name); 464 DEVNAME(sc), name);
448 firmware_close(fwh); 465 firmware_close(fwh);
449 goto err; 466 goto err;
450 } 467 }
451 error = firmware_read(fwh, 0, ucode, size); 468 error = firmware_read(fwh, 0, ucode, size);
452 firmware_close(fwh); 469 firmware_close(fwh);
453 if (error != 0) { 470 if (error != 0) {
454 printf("%s: failed to read firmware (error %d)\n", 471 printf("%s: failed to read firmware (error %d)\n",
455 DEVNAME(sc), error); 472 DEVNAME(sc), error);
456 goto err1; 473 goto err1;
457 } 474 }
458 475
459 if (firmware_open("if_bwfm", nvname, &fwh) != 0) { 476 if ((nvnamebuf == NULL || firmware_open("if_bwfm", nvnamebuf, &fwh) != 0)
 477 && firmware_open("if_bwfm", nvname, &fwh) != 0) {
460 printf("%s: failed firmware_open of file %s\n", 478 printf("%s: failed firmware_open of file %s\n",
461 DEVNAME(sc), nvname); 479 DEVNAME(sc), nvname);
462 goto err1; 480 goto err1;
463 } 481 }
464 nvlen = firmware_get_size(fwh); 482 nvlen = firmware_get_size(fwh);
465 nvram = firmware_malloc(nvlen); 483 nvram = firmware_malloc(nvlen);
466 if (nvram == NULL) { 484 if (nvram == NULL) {
467 printf("%s: failed firmware_open of file %s\n", 485 printf("%s: failed firmware_open of file %s\n",
468 DEVNAME(sc), name); 486 DEVNAME(sc), name);
469 firmware_close(fwh); 487 firmware_close(fwh);
470 goto err1; 488 goto err1;
471 } 489 }
472 error = firmware_read(fwh, 0, nvram, nvlen); 490 error = firmware_read(fwh, 0, nvram, nvlen);
@@ -482,26 +500,28 @@ bwfm_sdio_attachhook(device_t self) @@ -482,26 +500,28 @@ bwfm_sdio_attachhook(device_t self)
482 goto err2; 500 goto err2;
483 } 501 }
484 502
485 sc->sc_alp_only = true; 503 sc->sc_alp_only = true;
486 if (bwfm_sdio_load_microcode(sc, ucode, size, nvram, nvsize) != 0) { 504 if (bwfm_sdio_load_microcode(sc, ucode, size, nvram, nvsize) != 0) {
487 printf("%s: could not load microcode\n", 505 printf("%s: could not load microcode\n",
488 DEVNAME(sc)); 506 DEVNAME(sc));
489 goto err2; 507 goto err2;
490 } 508 }
491 sc->sc_alp_only = false; 509 sc->sc_alp_only = false;
492 510
493 firmware_free(nvram, nvlen); 511 firmware_free(nvram, nvlen);
494 firmware_free(ucode, size); 512 firmware_free(ucode, size);
 513 if (nvnamebuf != NULL)
 514 kmem_free(nvnamebuf, strlen(nvnamebuf)+1);
495 515
496 sdmmc_pause(hztoms(1)*1000, NULL); 516 sdmmc_pause(hztoms(1)*1000, NULL);
497 517
498 bwfm_sdio_clkctl(sc, CLK_AVAIL, false); 518 bwfm_sdio_clkctl(sc, CLK_AVAIL, false);
499 if (sc->sc_clkstate != CLK_AVAIL) { 519 if (sc->sc_clkstate != CLK_AVAIL) {
500 printf("%s: could not access clock\n", 520 printf("%s: could not access clock\n",
501 DEVNAME(sc)); 521 DEVNAME(sc));
502 goto err; 522 goto err;
503 } 523 }
504 524
505 clk = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR); 525 clk = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
506 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 526 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR,
507 clk | BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT); 527 clk | BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT);
@@ -555,26 +575,28 @@ bwfm_sdio_attachhook(device_t self) @@ -555,26 +575,28 @@ bwfm_sdio_attachhook(device_t self)
555 sdmmc_pause(100000, NULL); 575 sdmmc_pause(100000, NULL);
556 576
557 sc->sc_sc.sc_bus_ops = &bwfm_sdio_bus_ops; 577 sc->sc_sc.sc_bus_ops = &bwfm_sdio_bus_ops;
558 sc->sc_sc.sc_proto_ops = &bwfm_proto_bcdc_ops; 578 sc->sc_sc.sc_proto_ops = &bwfm_proto_bcdc_ops;
559 bwfm_attach(&sc->sc_sc); 579 bwfm_attach(&sc->sc_sc);
560 sc->sc_bwfm_attached = true; 580 sc->sc_bwfm_attached = true;
561 581
562 return; 582 return;
563 583
564err2: 584err2:
565 firmware_free(nvram, nvlen); 585 firmware_free(nvram, nvlen);
566err1: 586err1:
567 firmware_free(ucode, size); 587 firmware_free(ucode, size);
 588 if (nvnamebuf != NULL)
 589 kmem_free(nvnamebuf, strlen(nvnamebuf)+1);
568err: 590err:
569 return; 591 return;
570} 592}
571 593
572static int 594static int
573bwfm_fdt_find_phandle(device_t self, device_t parent) 595bwfm_fdt_find_phandle(device_t self, device_t parent)
574{ 596{
575 prop_dictionary_t dict; 597 prop_dictionary_t dict;
576 device_t dev; 598 device_t dev;
577 const char *str; 599 const char *str;
578 int phandle; 600 int phandle;
579 601
580 /* locate in FDT */ 602 /* locate in FDT */
@@ -593,26 +615,35 @@ bwfm_fdt_find_phandle(device_t self, dev @@ -593,26 +615,35 @@ bwfm_fdt_find_phandle(device_t self, dev
593 if (!prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str)) 615 if (!prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str))
594 return -1; 616 return -1;
595 617
596 /* are we the only FDT child ? */ 618 /* are we the only FDT child ? */
597 phandle = OF_child(OF_finddevice(str)); 619 phandle = OF_child(OF_finddevice(str));
598 } 620 }
599 621
600 if (!of_match_compatible(phandle, compatible)) 622 if (!of_match_compatible(phandle, compatible))
601 return -1; 623 return -1;
602 624
603 return phandle; 625 return phandle;
604} 626}
605 627
 628static const char *
 629bwfm_fdt_get_model(void)
 630{
 631 int phandle;
 632
 633 phandle = OF_finddevice("/");
 634 return fdtbus_get_string_index(phandle, "compatible", 0);
 635}
 636
606static int 637static int
607bwfm_sdio_detach(device_t self, int flags) 638bwfm_sdio_detach(device_t self, int flags)
608{ 639{
609 struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self; 640 struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self;
610 641
611#ifdef BWFM_DEBUG 642#ifdef BWFM_DEBUG
612 bwfm_sdio_debug_console(sc); 643 bwfm_sdio_debug_console(sc);
613#endif 644#endif
614 645
615 if (sc->sc_ih || sc->sc_fdtih) { 646 if (sc->sc_ih || sc->sc_fdtih) {
616 sdmmc_intr_disable(sc->sc_sf[1]); 647 sdmmc_intr_disable(sc->sc_sf[1]);
617 if (sc->sc_ih) 648 if (sc->sc_ih)
618 sdmmc_intr_disestablish(sc->sc_ih); 649 sdmmc_intr_disestablish(sc->sc_ih);