1 /* $Id: ar5312_board.c,v 1.2 2009/07/06 00:43:22 alc Exp $ */ 2 /* 3 * Copyright (c) 2006 Urbana-Champaign Independent Media Center. 4 * Copyright (c) 2006 Garrett D'Amore. 5 * All rights reserved. 6 * 7 * This code was written by Garrett D'Amore for the Champaign-Urbana 8 * Community Wireless Network Project. 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer in the documentation and/or other materials provided 18 * with the distribution. 19 * 3. All advertising materials mentioning features or use of this 20 * software must display the following acknowledgements: 21 * This product includes software developed by the Urbana-Champaign 22 * Independent Media Center. 23 * This product includes software developed by Garrett D'Amore. 24 * 4. Urbana-Champaign Independent Media Center's name and Garrett 25 * D'Amore's name may not be used to endorse or promote products 26 * derived from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT 29 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR 30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT 33 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 37 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 40 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 */ 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: ar5312_board.c,v 1.2 2009/07/06 00:43:22 alc Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/device.h> 48 49 #include <machine/bus.h> 50 #include <mips/atheros/include/ar5312reg.h> 51 #include <mips/atheros/include/ar531xvar.h> 52 53 #include <ah_soc.h> 54 55 extern const char *ether_sprintf(const uint8_t *); 56 57 /* 58 * Locate the Board Configuration data using heuristics. 59 * Search backward from the (aliased) end of flash looking 60 * for the signature string that marks the start of the data. 61 * We search at most 500KB. 62 */ 63 const struct ar531x_boarddata * 64 ar531x_board_info(void) 65 { 66 static const struct ar531x_boarddata *board = NULL; 67 const uint8_t *ptr, *end; 68 uint32_t fctl; 69 70 if (board == NULL) { 71 /* configure flash bank 0 */ 72 fctl = REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_0) & 73 AR5312_FLASHCTL_MW_MASK; 74 75 fctl |= 76 AR5312_FLASHCTL_E | 77 AR5312_FLASHCTL_RBLE | 78 AR5312_FLASHCTL_AC_8M | 79 (1 << AR5312_FLASHCTL_IDCY_SHIFT) | 80 (7 << AR5312_FLASHCTL_WST1_SHIFT) | 81 (7 << AR5312_FLASHCTL_WST2_SHIFT); 82 83 REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_0) = fctl; 84 85 REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_1) &= 86 ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_MASK); 87 88 REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_2) &= 89 ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_MASK); 90 91 /* search backward in the flash looking for the signature */ 92 ptr = (const uint8_t *) MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END - 0x1000); 93 end = ptr - (500 * 1024); /* NB: max 500KB window */ 94 /* XXX validate end */ 95 for (; ptr > end; ptr -= 0x1000) 96 if (*(const uint32_t *)ptr == AR531X_BD_MAGIC) { 97 board = (const struct ar531x_boarddata *) ptr; 98 break; 99 } 100 } 101 return board; 102 } 103 104 /* 105 * Locate the radio configuration data; it is located relative 106 * to the board configuration data. 107 */ 108 const void * 109 ar531x_radio_info(void) 110 { 111 static const void *radio = NULL; 112 const struct ar531x_boarddata *board; 113 const uint8_t *baddr, *ptr, *end; 114 115 if (radio == NULL) { 116 board = ar531x_board_info(); 117 if (board == NULL) 118 return NULL; 119 baddr = (const uint8_t *) board; 120 ptr = baddr + 0x1000; 121 end = (const uint8_t *) 122 MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END-0x1000); 123 again: 124 for (; ptr < end; ptr += 0x1000) 125 if (*(const uint32_t *)ptr != 0xffffffff) { 126 radio = ptr; 127 goto done; 128 } 129 /* sort of an Algol-style for loop ... */ 130 if (end == (uint8_t *) MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END)) { 131 /* NB: AR2316 has radio data in a different location */ 132 ptr = baddr + 0xf8; 133 end = (const uint8_t *) 134 MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END-0x1000 + 0xf8); 135 goto again; 136 } 137 } 138 done: 139 return radio; 140 } 141 142 /* 143 * Locate board and radio configuration data in flash. 144 */ 145 int 146 ar531x_board_config(struct ar531x_config *config) 147 { 148 149 config->board = ar531x_board_info(); 150 if (config->board == NULL) 151 return ENOENT; 152 config->radio = ar531x_radio_info(); 153 if (config->radio == NULL) 154 return ENOENT; /* XXX distinct code */ 155 return 0; 156 } 157