/*====================================================================*
*
* 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 <cmaier@qca.qualcomm.com>
*
*--------------------------------------------------------------------*/
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_QCA7000A0,
"QCA7000"
},
{
CHIPSET_QCA7005A0,
"QCA7005"
},
{
CHIPSET_QCA7500A0,
"QCA7500"
}
};
return (typename (chipname, SIZEOF (chipname), MDEVICE_CLASS, chipname [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
* 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)
{
#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
},
{
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
},
{
0x001CFCFC,
0x20,
CHIPSET_QCA7420A0
},
{
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;
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;
return;
}
chipinfo = (struct chipinfo *) (& confirm->MVERSION [64]);
if (firmware [chip].STRAP == LE32TOH (chipinfo->STRAP))
{
confirm->MDEVICE_CLASS = firmware [chip].DEVICE;
return;
}
chipinfo = (struct chipinfo *) (& confirm->MVERSION [128]);
if (firmware [chip].STRAP == LE32TOH (chipinfo->STRAP))
{
confirm->MDEVICE_CLASS = firmware [chip].DEVICE;
return;
}
chipinfo = (struct chipinfo *) (& confirm->MVERSION [253]);
if (firmware [chip].STRAP == LE32TOH (chipinfo->STRAP))
{
confirm->MDEVICE_CLASS = firmware [chip].DEVICE;
return;
}
}
}
return;
}
#endif