/*====================================================================* * * 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 #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 <cmaier@qca.qualcomm.com> * *--------------------------------------------------------------------*/ char const * chipsetname (uint8_t MDEVICE_CLASS) { static const struct _type_ chipsets [] = { { CHIPSET_UNKNOWN, "UNKNOWN" }, { CHIPSET_INT6000, "INT6000" }, { CHIPSET_INT6300, "INT6300" }, { CHIPSET_INT6400, "INT6400" }, { CHIPSET_AR7400, " AR7400" }, { CHIPSET_AR6405, " AR6405" }, { CHIPSET_PANTHER_LYNX, "PANTHER/LYNX" }, { CHIPSET_QCA7450, "QCA7450" }, { CHIPSET_QCA7451, "QCA7451" }, { CHIPSET_QCA7420, "QCA7420" }, { CHIPSET_QCA6410, "QCA6410" }, { CHIPSET_QCA7000, "QCA7000" } }; return (typename (chipsets, SIZEOF (chipsets), MDEVICE_CLASS, chipsets [0].name)); } /*====================================================================* * * void chipset (void const * memory); * * Chipset.h * * replace VS_SW_VER message MDEVICE_CLASS field with correct value; * the MDEVICE_CLASS field was named MDEVICEID at one time; * * 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 * QCA7000 0x06 / 0x22 0x001B589C * QCA7000 0x06 / 0x22 0x001B58DC * QCA7005 0x06 / 0x22 0x001B587C * * some chipsets have have multiple IDENT field values; this is * not an error; there may be multiple versions of a chipset; * *--------------------------------------------------------------------*/ void chipset (void const * memory) { #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); typedef struct __packed { uint32_t IDENT; uint8_t DEVICE_CLASS; uint8_t DEVICE; } tDevMap; struct __packed tDevClass { uint8_t RESERVED; uint32_t IDENT; uint32_t STEP_NUMBER; } * pDevClass = (struct tDevClass *) (& confirm->MVERSION [64]); #ifndef __GNUC__ #pragma pack (pop) #endif tDevMap bootrom [] = { { 0x00000042, 0x01, CHIPSET_INT6000 }, { 0x00006300, 0x01, CHIPSET_INT6300 }, { 0x00006400, 0x03, CHIPSET_INT6400 }, { 0x00007400, 0x03, CHIPSET_AR7400 }, { 0x0F001D1A, 0x03, CHIPSET_QCA7450 }, { 0x0E001D1A, 0x03, CHIPSET_QCA7451 }, { 0x001CFC00, 0x05, CHIPSET_QCA7420 }, { 0x001CFCFC, 0x05, CHIPSET_QCA7420 }, { 0x001CFCFC, 0x06, CHIPSET_QCA7420 }, { 0x001B58EC, 0x06, CHIPSET_QCA6410 }, { 0x001B58BC, 0x06, CHIPSET_QCA6411 }, { 0x001B58DC, 0x06, CHIPSET_QCA7000 }, { 0x001B587C, 0x06, CHIPSET_QCA7000 } }; tDevMap firmware [] = { { 0x00000000, 0x01, CHIPSET_INT6000 }, { 0x00000000, 0x02, CHIPSET_INT6300 }, { 0x00000000, 0x03, CHIPSET_INT6400 }, { 0x00000000, 0x05, CHIPSET_AR6405 }, { 0x00000000, 0x04, CHIPSET_AR7400 }, { 0x0F001D1A, 0x20, CHIPSET_QCA7450 }, { 0x0E001D1A, 0x20, CHIPSET_QCA7451 }, { 0x001CFCFC, 0x20, CHIPSET_QCA7420 }, { 0x001B58EC, 0x21, CHIPSET_QCA6410 }, { 0x001B58BC, 0x21, CHIPSET_QCA6411 }, { 0x001B58DC, 0x22, CHIPSET_QCA7000 } }; unsigned chip; if (!strcmp (confirm->MVERSION, "BootLoader")) { for (chip = 0; chip < SIZEOF (bootrom); chip++) { if (bootrom [chip].DEVICE_CLASS != confirm->MDEVICE_CLASS) { continue; } if (bootrom [chip].IDENT != LE32TOH (pDevClass->IDENT)) { continue; } confirm->MDEVICE_CLASS = bootrom [chip].DEVICE; return; } } else { for (chip = 0; chip < SIZEOF (firmware); chip++) { if (firmware [chip].DEVICE_CLASS != confirm->MDEVICE_CLASS) { continue; } if (firmware [chip].IDENT <= 5) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; return; } pDevClass = (struct tDevClass *) (& confirm->MVERSION [65]); if (firmware [chip].IDENT == LE32TOH (pDevClass->IDENT)) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; return; } pDevClass = (struct tDevClass *) (& confirm->MVERSION [129]); if (firmware [chip].IDENT == LE32TOH (pDevClass->IDENT)) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; return; } pDevClass = (struct tDevClass *) (& confirm->MVERSION [254]); if (firmware [chip].IDENT == LE32TOH (pDevClass->IDENT)) { confirm->MDEVICE_CLASS = firmware [chip].DEVICE; return; } } } return; } #endif