• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/wlags49_h2/
1
2/*   vim:tw=110:ts=4: */
3/**************************************************************************************************************
4*
5* FILE   :	DHF.C
6*
7* DATE	:	$Date: 2004/07/19 08:16:14 $   $Revision: 1.2 $
8* Original	:	2004/05/28 14:05:34    Revision: 1.36      Tag: hcf7_t20040602_01
9* Original	:	2004/05/11 06:22:57    Revision: 1.32      Tag: hcf7_t7_20040513_01
10* Original	:	2004/04/15 09:24:42    Revision: 1.28      Tag: hcf7_t7_20040415_01
11* Original	:	2004/04/08 15:18:16    Revision: 1.27      Tag: t7_20040413_01
12* Original	:	2004/04/01 15:32:55    Revision: 1.25      Tag: t7_20040401_01
13* Original	:	2004/03/10 15:39:28    Revision: 1.21      Tag: t20040310_01
14* Original	:	2004/03/04 11:03:37    Revision: 1.19      Tag: t20040304_01
15* Original	:	2004/03/02 09:27:11    Revision: 1.17      Tag: t20040302_03
16* Original	:	2004/02/24 13:00:28    Revision: 1.15      Tag: t20040224_01
17* Original	:	2004/02/19 10:57:28    Revision: 1.14      Tag: t20040219_01
18* Original	:	2003/11/27 09:00:09    Revision: 1.3      Tag: t20021216_01
19*
20* AUTHOR :	John Meertens
21*			Nico Valster
22*
23* SPECIFICATION: ........
24*
25* DESC   :	generic functions to handle the download of NIC firmware
26*			Local Support Routines for above procedures
27*
28*			Customizable via HCFCFG.H, which is included by HCF.H
29*
30*
31*	DHF is (intended to be) platform-independent.
32*	DHF is a module that provides a number of routines to download firmware
33*	images (the names primary, station, access point, secondary and tertiary
34*	are used or have been used) to volatile or nonvolatile memory
35*	in WaveLAN/IEEE NICs. To achieve this DHF makes use of the WaveLAN/IEEE
36*	WCI as implemented by the HCF-module.
37*
38*	Download to non-volatile memory is used to update a WaveLAN/IEEE NIC to new
39*	firmware. Normally this will be an upgrade to newer firmware, although
40*	downgrading to older firmware is possible too.
41*
42* Note: relative to Asserts, the following can be observed:
43*	Since the IFB is not known inside the routine, the macro HCFASSERT is replaced with MMDASSERT.
44*	Also the line number reported in the assert is raised by FILE_NAME_OFFSET (10000) to discriminate the
45*	DHF Asserts from HCF and MMD asserts.
46*
47***************************************************************************************************************
48*
49*
50* SOFTWARE LICENSE
51*
52* This software is provided subject to the following terms and conditions,
53* which you should read carefully before using the software.  Using this
54* software indicates your acceptance of these terms and conditions.  If you do
55* not agree with these terms and conditions, do not use the software.
56*
57* COPYRIGHT (C) 1999 - 2000 by Lucent Technologies.	All Rights Reserved
58* COPYRIGHT (C) 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
59* All rights reserved.
60*
61* Redistribution and use in source or binary forms, with or without
62* modifications, are permitted provided that the following conditions are met:
63*
64* . Redistributions of source code must retain the above copyright notice, this
65*    list of conditions and the following Disclaimer as comments in the code as
66*    well as in the documentation and/or other materials provided with the
67*    distribution.
68*
69* . Redistributions in binary form must reproduce the above copyright notice,
70*    this list of conditions and the following Disclaimer in the documentation
71*    and/or other materials provided with the distribution.
72*
73* . Neither the name of Agere Systems Inc. nor the names of the contributors
74*    may be used to endorse or promote products derived from this software
75*    without specific prior written permission.
76*
77* Disclaimer
78*
79* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
80* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
81* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
82* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
83* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
84* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
85* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
86* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
88* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
89* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
90* DAMAGE.
91*
92*
93**************************************************************************************************************/
94
95#include "hcf.h"
96#include "hcfdef.h"
97#include "dhf.h"
98#include "mmd.h"
99
100/* to distinguish MMD from HCF asserts by means of line number */
101#undef	FILE_NAME_OFFSET
102#define FILE_NAME_OFFSET MMD_FILE_NAME_OFFSET
103/*-----------------------------------------------------------------------------
104 *
105 * Defines, data structures, and global variables
106 *
107 *---------------------------------------------------------------------------*/
108
109/*                    12345678901234 */
110char signature[14] = "FUPU7D37dhfwci";
111
112/*-----------------------------------------------------------------------------
113 *
114 * LTV-records retrieved from the NIC to:
115 *	- determine compatibility between NIC and image
116 *	- ((setup the buffer size dynamically for non-volatile download (see note below) ))
117 *	- supply plugging information contained in the PDA (H-I only)
118 *
119 *---------------------------------------------------------------------------*/
120
121/* for USB/H1 we needed a smaller value than the CFG_DL_BUF_STRCT reported 8192
122	for the time being it seems simpler to always use 2000 for USB/H1 as well as all other cases rather than
123	using the "fixed anyway" CFG_DL_BUF_STRCT. */
124#define DL_SIZE 2000
125
126/* CFG_IDENTITY_STRCT   	pri_identity	= { LOF(CFG_IDENTITY_STRCT), CFG_PRI_IDENTITY }; */
127CFG_SUP_RANGE_STRCT 	mfi_sup        	= { LOF(CFG_SUP_RANGE_STRCT), CFG_NIC_MFI_SUP_RANGE };
128CFG_SUP_RANGE_STRCT 	cfi_sup        	= { LOF(CFG_SUP_RANGE_STRCT), CFG_NIC_CFI_SUP_RANGE };
129/* Note: could be used rather than the above explained and defined DL_SIZE if need arises
130 * CFG_DL_BUF_STRCT    	dl_buf         	= { LOF(CFG_DL_BUF_STRCT), CFG_DL_BUF };
131*/
132
133/*-----------------------------------------------------------------------------
134 * Array ltv_info stores NIC information (in the form of LTV-records)
135 * needed for download. A NULL record indicates the end of the array.
136 *---------------------------------------------------------------------------*/
137
138/* The LTV_INFO_STRUCT is needed to save the sizes of the structs, because after a GET_INFO()
139 * the len field is changed to the real len of the RID by the called routine.
140 * This is only relevant if the DHF used without reloading the driver/utility.
141 */
142
143LTV_INFO_STRUCT ltv_info[] = {
144	{ (LTVP)&mfi_sup,			LOF(CFG_SUP_RANGE_STRCT) } ,
145	{ (LTVP)&cfi_sup,			LOF(CFG_SUP_RANGE_STRCT) } ,
146	{ (LTVP) NULL, 				0 }
147};
148
149
150/***********************************************************************************************************/
151/***************************************  PROTOTYPES  ******************************************************/
152/***********************************************************************************************************/
153static int				check_comp_fw(memimage *fw);
154
155
156/************************************************************************************************************
157*.SUBMODULE		int check_comp_fw( memimage *fw )
158*.PURPOSE		Checks compatibility of CFI and MFI, NIC as supplier, station/AP firmware image as supplier.
159*
160*.ARGUMENTS
161*   fw         	F/W image to be downloaded
162*
163*.RETURNS
164*   HFC_SUCCESS      	- firmware OK
165*   DHF_ERR_INCOMP_FW
166*
167*.DESCRIPTION
168*   This function uses compatibility and identity information that has been
169*   retrieved from the card which is currently inserted to check whether the
170*   station firmware image to be downloaded is compatible.
171*.ENDDOC				END DOCUMENTATION
172*************************************************************************************************************/
173int
174check_comp_fw(memimage *fw)
175{
176CFG_RANGE20_STRCT  		*p;
177int   					rc = HCF_SUCCESS;
178CFG_RANGE_SPEC_STRCT *i;
179
180	switch (fw->identity->typ) {
181	case CFG_FW_IDENTITY:				/* Station F/W */
182	case COMP_ID_FW_AP_FAKE:			/* ;?is this useful (used to be:  CFG_AP_IDENTITY) */
183		break;
184	default:
185		MMDASSERT(DO_ASSERT, fw->identity->typ) 	/* unknown/unsupported firmware_type: */
186		rc = DHF_ERR_INCOMP_FW;
187		return rc; /* ;? how useful is this anyway,
188					*  till that is sorted out might as well violate my own single exit principle
189					*/
190	}
191	p = fw->compat;
192	i = NULL;
193	while (p->len && i == NULL) {					/* check the MFI ranges */
194		if (p->typ  == CFG_MFI_ACT_RANGES_STA) {
195			i = mmd_check_comp((void *)p, &mfi_sup);
196		}
197		p++;
198	}
199	MMDASSERT(i, 0)	/* MFI: NIC Supplier not compatible with F/W image Actor */
200	if (i) {
201		p = fw->compat;
202		i = NULL;
203		while (p->len && i == NULL) {			/* check the CFI ranges */
204			if (p->typ  == CFG_CFI_ACT_RANGES_STA) {
205				 i = mmd_check_comp((void *)p, &cfi_sup);
206			}
207			p++;
208		}
209		MMDASSERT(i, 0)	/* CFI: NIC Supplier not compatible with F/W image Actor */
210	}
211	if (i == NULL) {
212		rc = DHF_ERR_INCOMP_FW;
213	}
214	return rc;
215} /* check_comp_fw */
216
217
218
219
220
221/*-----------------------------------------------------------------------------
222 *
223 * Exported functions
224 *
225 *---------------------------------------------------------------------------*/
226
227
228
229/*************************************************************************************************************
230*
231*.MODULE 		int dhf_download_binary( void *ifbp, memimage *fw )
232*.PURPOSE		Downloads a complete (primary, station, or access point) firmware image to the NIC.
233*
234*.ARGUMENTS
235*	ifbp		address of the Interface Block
236*   fw         	F/W image to be downloaded
237*
238*.RETURNS
239*   HCF_SUCCESS         	- download completed successfully.
240*   DHF_ERR_INCOMP_FW		- firmware not compatible
241*
242*.DESCRIPTION
243*   Initialize global variables
244*   Connect to the DHF
245*   Check the compatibility of the image (For primary firmware images it is checked first
246* 	whether download is necessary).
247*   If everything's download the firmware.
248*   Disconnect from the DHF.
249*
250*
251*.DIAGRAM
252*
253*.NOTICE:
254	MMDASSERT is unacceptable because some drivers call dhf_download_binary before hcf_connect
255
256* The old comment was:
257*.ENDDOC				END DOCUMENTATION
258*************************************************************************************************************/
259int
260dhf_download_binary(memimage *fw)
261{
262int 			rc = HCF_SUCCESS;
263CFG_PROG_STRCT 	*p;
264int				i;
265
266	/* validate the image */
267	for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++)
268		; /* NOP */
269	if (i != sizeof(signature) 		||
270		 fw->signature[i] != 0x01   	||
271		 /* test for Little/Big Endian Binary flag */
272		 fw->signature[i+1] != (/* HCF_BIG_ENDIAN ? 'B' : */ 'L'))
273		rc = DHF_ERR_INCOMP_FW;
274	else {					/* Little Endian Binary format */
275		fw->codep    = (CFG_PROG_STRCT FAR*)((char *)fw->codep + (hcf_32)fw);
276		fw->identity = (CFG_IDENTITY_STRCT FAR*)((char *)fw->identity + (hcf_32)fw);
277		fw->compat   = (CFG_RANGE20_STRCT FAR*)((char *)fw->compat + (hcf_32)fw);
278		for (i = 0; fw->p[i]; i++)
279			fw->p[i] = ((char *)fw->p[i] + (hcf_32)fw);
280		p = fw->codep;
281		while (p->len) {
282			p->host_addr = (char *)p->host_addr + (hcf_32)fw;
283			p++;
284		}
285	}
286	return rc;
287}   /* dhf_download_binary */
288
289
290/*************************************************************************************************************
291*
292*.MODULE 		int dhf_download_fw( void *ifbp, memimage *fw )
293*.PURPOSE		Downloads a complete (primary or tertiary) firmware image to the NIC.
294*
295*.ARGUMENTS
296*	ifbp		address of the Interface Block
297*   fw     		F/W image to be downloaded
298*
299*.RETURNS
300*	HCF_SUCCESS        	- download completed successfully.
301*	HCF_ERR_NO_NIC     	- no NIC present
302*	DHF_ERR_INCOMP_FW 	- firmware not compatible
303*
304*.DESCRIPTION
305* - check the signature of the image
306* - get the compatibility information from the components on the NIC
307*	  - Primary Firmware Identity
308*	  -	Modem - Firmware I/F
309*	  -	Controller - Firmware I/F
310*!! - if necessary ( i.e. H-I) get the PDA contents from the NIC
311* - check the compatibility of the MFI and CFI of the NIC with the F/W image
312*	Note: the Primary F/W compatibility is only relevant for the "running" HCF and is already verified in
313*	hcf_connect
314*!! -	if necessary ( i.e. H-I)
315*!!	  -	verify the sumcheck of the PDA
316*!!	  -	plug the image (based on the PDA and the default plug records)
317* - loop over all the download LTVs in the image which consists of a sequence of
318*	  - CFG_PROG_VOLATILE/CFG_PROG_NON_VOLATILE
319*	  - 1 or more sequences of CFG_PROG_ADDR, CFG_PROG_DATA,....,CFG_PROG_DATA
320*	  -	CFG_PROG_STOP
321*
322*.DIAGRAM
323*
324*.NOTICE
325* The old comment was:
326*	// Download primary firmware if necessary and allowed. This is done silently (without telling
327*	// the user) and only if the firmware in the download image is newer than the firmware in the
328*	// card.  In Major version 4 of the primary firmware functions of Hermes and Shark were
329*	// combined. Prior to that two separate versions existed. We only have to download primary
330*	// firmware if major version of primary firmware in the NIC < 4.
331*	//		download = pri_identity.version_major < 4;
332*	//		if ( download ) {
333*	//			rc = check_comp_primary( fw );
334*	//		}
335* It is my understanding that Pri Variant 1 must be updated by Pri Variant 2. The test on
336* major version < 4 should amount to the same result but be "principally" less correct
337* In deliberation with the Architecture team, it was decided that this upgrade for old H-I
338* NICs, is an aspect which belongs on the WSU level not on the DHF level
339*
340*.ENDDOC				END DOCUMENTATION
341*************************************************************************************************************/
342int
343dhf_download_fw(void *ifbp, memimage *fw)
344{
345int 				rc = HCF_SUCCESS;
346LTV_INFO_STRUCT_PTR pp = ltv_info;
347CFG_PROG_STRCT 		*p = fw->codep;
348LTVP 				ltvp;
349int					i;
350
351	MMDASSERT(fw != NULL, 0)
352	/* validate the image */
353	for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++)
354		; /* NOP */
355	if (i != sizeof(signature) 		||
356		 fw->signature[i] != 0x01		||
357		 /* check for binary image */
358		 (fw->signature[i+1] != 'C' && fw->signature[i+1] != (/*HCF_BIG_ENDIAN ? 'B' : */ 'L')))
359		 rc = DHF_ERR_INCOMP_FW;
360
361/*	Retrieve all information needed for download from the NIC */
362	while ((rc == HCF_SUCCESS) && ((ltvp = pp->ltvp) != NULL)) {
363		ltvp->len = pp++->len;	/* Set len to original len. This len is changed to real len by GET_INFO() */
364		rc = GET_INFO(ltvp);
365		MMDASSERT(rc == HCF_SUCCESS, rc)
366		MMDASSERT(rc == HCF_SUCCESS, ltvp->typ)
367		MMDASSERT(rc == HCF_SUCCESS, ltvp->len)
368	}
369	if (rc == HCF_SUCCESS)
370		rc = check_comp_fw(fw);
371	if (rc == HCF_SUCCESS) {
372		while (rc == HCF_SUCCESS && p->len) {
373			rc = PUT_INFO(p);
374			p++;
375		}
376	}
377	MMDASSERT(rc == HCF_SUCCESS, rc)
378	return rc;
379}   /* dhf_download_fw */
380