/*====================================================================* * * Copyright (c) 2013 Qualcomm Atheros, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted (subject to the limitations * in the disclaimer below) provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of Qualcomm Atheros nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE * COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *--------------------------------------------------------------------*/ #ifndef CHIPSET_SOURCE #define CHIPSET_SOURCE /*====================================================================* * custom header files; *--------------------------------------------------------------------*/ #include "../plc/plc.h" #include "../tools/types.h" #include "../tools/symbol.h" /*====================================================================* * * char const * chipsetname (uint8_t MDEVICE) * * plc.h * * return the ASCII name string associated with the MDEVICE_CLASS * field in the VS_SW_VER.CNF message; this field represents the * chipset family or class of device; * * the MDEVICE_CLASS field was named MDEVICEID at one time; * * Contributor(s): * Charles Maier * *--------------------------------------------------------------------*/ char const * chipsetname (uint8_t MDEVICE_CLASS) { static const struct _type_ chipname [] = { { CHIPSET_UNKNOWN, "UNKNOWN" }, { CHIPSET_INT6000A1, "INT6000" }, { CHIPSET_INT6300A0, "INT6300" }, { CHIPSET_INT6400A0, "INT6400" }, { CHIPSET_AR7400A0, " AR7400" }, { CHIPSET_AR6405A0, " AR6405" }, { CHIPSET_PANTHER_LYNX, "PANTHER/LYNX" }, { CHIPSET_QCA7450A0, "QCA7450" }, { CHIPSET_QCA7451A0, "QCA7451" }, { CHIPSET_QCA7420A0, "QCA7420" }, { CHIPSET_QCA6410A0, "QCA6410" }, { CHIPSET_QCA7006AQA0, "QCA7006AQ" }, { CHIPSET_QCA7000A0, "QCA7000" }, { CHIPSET_QCA7005A0, "QCA7005" }, { CHIPSET_QCA7500A0, "QCA7500" } }; return (typename (chipname, SIZEOF (chipname), MDEVICE_CLASS, chipname [0].name)); } /*====================================================================* * * char const * chipsetname_by_ident (uint32_t ident, uint8_t chipset) * * chipset.h * * return the ASCII name string associated with the IDENT (aka STRAP) * field in the VS_SW_VER.CNF message; * in case of unknown value, fallback using chipsetname function * *--------------------------------------------------------------------*/ char const * chipsetname_by_ident (uint32_t ident, uint8_t chipset) { static const struct _type_ chipname [] = { { 0x00000042, "INT6000" }, { 0x00006300, "INT6300" }, #if 0 /* don't list these two here since we would need MDEVICE_CLASS * (aka our chipset parameter) to differentiate; instead we rely * on older chipsetname function to handle it during fallback... */ { 0x00006400, " AR6405" }, { 0x00006400, "INT6400" }, #endif { 0x00007400, " AR7400" }, { 0x001B587C, "QCA7005" }, { 0x001B589C, "QCA7000" }, { 0x001B58AC, "QCA7006AQ" }, { 0x001B58BC, "QCA6411" }, { 0x001B58DC, "QCA7000" }, { 0x001B58EC, "QCA6410" }, { 0x001CFC00, "QCA7420" }, { 0x001CFCFC, "QCA7420" }, { 0x001D4C00, "QCA7500" }, { 0x001D4C0F, "QCA7500" }, { 0x0E001D1A, "QCA7451" }, { 0x0F001D1A, "QCA7450" }, }; return (typename (chipname, SIZEOF (chipname), ident, chipsetname (chipset))); } /*====================================================================* * * void chipset (void const * memory, uint32_t * ident); * * chipset.h * * replace VS_SW_VER message MDEVICE_CLASS field with correct value; * the MDEVICE_CLASS field was named MDEVICEID at one time; * while at save the ident field to given (since the offset varies, * it can be used by caller later more easily); * * Atheros chipsets are identified by code in the VS_SW_VER vendor * specific management message; the chipset [] vector translates a * chipset code to a chipset name; * * the basic assumption is that the firmware always tells the truth * but the bootrom does not; because of engineering changes, the * firmware uses a different device identification scheme than that * used by the bootrom and that information appears in different * locations depending on the source of the VS_SW_VER confirmation; * see the Programmer's Guide for more information. * * INT6000 0x01 / 0x01 0x00000042 / NA * INT6300 0x01 / 0x02 0x00006300 / NA * INT6400 0x03 / 0x03 0x00006400 / NA * AR7400 0x03 / 0x04 0x00007400 / NA * AR6405 0x03 / 0x05 0x00006400 / NA * QCA7450 0x03 / 0x20 0x0F001D1A / NA * QCA7420 0x06 / 0x20 0x001CFCFC * QCA6410 0x06 / 0x21 0x001B58EC * QCA6411 0x06 / 0x21 0x001B58BC * QCA7006AQ 0x06 / 0x21 0x001B58AC * QCA7000 0x06 / 0x22 0x001B589C * QCA7000 0x06 / 0x22 0x001B58DC * QCA7005 0x06 / 0x22 0x001B587C * QCA7500 0x06 / 0x30 0x001D4C0F * * some chipsets have have multiple STRAP field values; this is * not an error; there may be multiple versions of a chipset; * *--------------------------------------------------------------------*/ void chipset (void const * memory, uint32_t * ident) { #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_sw_ver_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t MDEVICE_CLASS; uint8_t MVERLENGTH; char MVERSION [254]; } * confirm = (struct vs_sw_ver_confirm *) (memory); struct __packed chipinfo { uint8_t RESVD; uint32_t STRAP; uint32_t STEP_NUMBER; } * chipinfo = (struct chipinfo *) (& confirm->MVERSION [64]); typedef struct __packed { uint32_t STRAP; uint8_t CLASS; uint8_t DEVICE; } chipdata; #ifndef __GNUC__ #pragma pack (pop) #endif chipdata bootrom [] = { { 0x00000042, 0x01, CHIPSET_INT6000A1 }, { 0x00006300, 0x01, CHIPSET_INT6300A0 }, { 0x00006400, 0x03, CHIPSET_INT6400A0 }, { 0x00007400, 0x03, CHIPSET_AR7400A0 }, { 0x0F001D1A, 0x03, CHIPSET_QCA7450A0 }, { 0x0E001D1A, 0x03, CHIPSET_QCA7451A0 }, { 0x001CFC00, 0x05, CHIPSET_QCA7420A0 }, { 0x001CFCFC, 0x05, CHIPSET_QCA7420A0 }, { 0x001CFCFC, 0x06, CHIPSET_QCA7420A0 }, { 0x001B58EC, 0x06, CHIPSET_QCA6410A0 }, { 0x001B58AC, 0x06, CHIPSET_QCA7006AQA0 }, { 0x001B58BC, 0x06, CHIPSET_QCA6411A0 }, { 0x001B58DC, 0x06, CHIPSET_QCA7000A0 }, { 0x001B587C, 0x06, CHIPSET_QCA7005A0 }, { 0x001D4C00, 0x06, CHIPSET_QCA7500A0 }, { 0x001D4C0F, 0x06, CHIPSET_QCA7500A0 } }; chipdata firmware [] = { { 0x00000000, 0x01, CHIPSET_INT6000A1 }, { 0x00000000, 0x02, CHIPSET_INT6300A0 }, { 0x00000000, 0x03, CHIPSET_INT6400A0 }, { 0x00000000, 0x05, CHIPSET_AR6405A0 }, { 0x00000000, 0x04, CHIPSET_AR7400A0 }, { 0x0F001D1A, 0x20, CHIPSET_QCA7450A0 }, { 0x0E001D1A, 0x20, CHIPSET_QCA7451A0 }, { 0x001CFC00, 0x20, CHIPSET_QCA7420A0 }, { 0x001CFCFC, 0x20, CHIPSET_QCA7420A0 }, { 0x001B587C, 0x22, CHIPSET_QCA7005A0 }, { 0x001B58AC, 0x21, CHIPSET_QCA7006AQA0 }, { 0x001B58EC, 0x21, CHIPSET_QCA6410A0 }, { 0x001B58BC, 0x21, CHIPSET_QCA6411A0 }, { 0x001B58DC, 0x22, CHIPSET_QCA7000A0 }, { 0x001D4C00, 0x30, CHIPSET_QCA7500A0 }, { 0x001D4C0F, 0x30, CHIPSET_QCA7500A0 } }; unsigned chip; if (! strcmp (confirm->MVERSION, "BootLoader")) { for (chip = 0; chip < SIZEOF (bootrom); chip++) { if (bootrom [chip].CLASS != confirm->MDEVICE_CLASS) { continue; } if (bootrom [chip].STRAP != LE32TOH (chipinfo->STRAP)) { continue; } confirm->MDEVICE_CLASS = bootrom [chip].DEVICE; * ident = LE32TOH (chipinfo->STRAP); return; } } else { for (chip = 0; chip < SIZEOF (firmware); chip++) { if (firmware [chip].CLASS != confirm->MDEVICE_CLASS) { continue; } if (firmware [chip].STRAP < CHIPSET_PANTHER_LYNX) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; * ident = LE32TOH (chipinfo->STRAP); return; } chipinfo = (struct chipinfo *) (& confirm->MVERSION [64]); if (firmware [chip].STRAP == LE32TOH (chipinfo->STRAP)) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; * ident = LE32TOH (chipinfo->STRAP); return; } chipinfo = (struct chipinfo *) (& confirm->MVERSION [128]); if (firmware [chip].STRAP == LE32TOH (chipinfo->STRAP)) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; * ident = LE32TOH (chipinfo->STRAP); return; } chipinfo = (struct chipinfo *) (& confirm->MVERSION [253]); if (firmware [chip].STRAP == LE32TOH (chipinfo->STRAP)) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; * ident = LE32TOH (chipinfo->STRAP); return; } } } return; } #endif