1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Aic94xx SAS/SATA driver access to shared data structures and memory
4 * maps.
5 *
6 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
7 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
8 */
9
10#include <linux/pci.h>
11#include <linux/slab.h>
12#include <linux/delay.h>
13
14#include "aic94xx.h"
15#include "aic94xx_reg.h"
16#include "aic94xx_sds.h"
17
18/* ---------- OCM stuff ---------- */
19
20struct asd_ocm_dir_ent {
21	u8 type;
22	u8 offs[3];
23	u8 _r1;
24	u8 size[3];
25} __attribute__ ((packed));
26
27struct asd_ocm_dir {
28	char sig[2];
29	u8   _r1[2];
30	u8   major;          /* 0 */
31	u8   minor;          /* 0 */
32	u8   _r2;
33	u8   num_de;
34	struct asd_ocm_dir_ent entry[15];
35} __attribute__ ((packed));
36
37#define	OCM_DE_OCM_DIR			0x00
38#define	OCM_DE_WIN_DRVR			0x01
39#define	OCM_DE_BIOS_CHIM		0x02
40#define	OCM_DE_RAID_ENGN		0x03
41#define	OCM_DE_BIOS_INTL		0x04
42#define	OCM_DE_BIOS_CHIM_OSM		0x05
43#define	OCM_DE_BIOS_CHIM_DYNAMIC	0x06
44#define	OCM_DE_ADDC2C_RES0		0x07
45#define	OCM_DE_ADDC2C_RES1		0x08
46#define	OCM_DE_ADDC2C_RES2		0x09
47#define	OCM_DE_ADDC2C_RES3		0x0A
48
49#define OCM_INIT_DIR_ENTRIES	5
50/***************************************************************************
51*  OCM directory default
52***************************************************************************/
53static struct asd_ocm_dir OCMDirInit =
54{
55	.sig = {0x4D, 0x4F},	/* signature */
56	.num_de = OCM_INIT_DIR_ENTRIES,	/* no. of directory entries */
57};
58
59/***************************************************************************
60*  OCM directory Entries default
61***************************************************************************/
62static struct asd_ocm_dir_ent OCMDirEntriesInit[OCM_INIT_DIR_ENTRIES] =
63{
64	{
65		.type = (OCM_DE_ADDC2C_RES0),	/* Entry type  */
66		.offs = {128},			/* Offset */
67		.size = {0, 4},			/* size */
68	},
69	{
70		.type = (OCM_DE_ADDC2C_RES1),	/* Entry type  */
71		.offs = {128, 4},		/* Offset */
72		.size = {0, 4},			/* size */
73	},
74	{
75		.type = (OCM_DE_ADDC2C_RES2),	/* Entry type  */
76		.offs = {128, 8},		/* Offset */
77		.size = {0, 4},			/* size */
78	},
79	{
80		.type = (OCM_DE_ADDC2C_RES3),	/* Entry type  */
81		.offs = {128, 12},		/* Offset */
82		.size = {0, 4},			/* size */
83	},
84	{
85		.type = (OCM_DE_WIN_DRVR),	/* Entry type  */
86		.offs = {128, 16},		/* Offset */
87		.size = {128, 235, 1},		/* size */
88	},
89};
90
91struct asd_bios_chim_struct {
92	char sig[4];
93	u8   major;          /* 1 */
94	u8   minor;          /* 0 */
95	u8   bios_major;
96	u8   bios_minor;
97	__le32  bios_build;
98	u8   flags;
99	u8   pci_slot;
100	__le16  ue_num;
101	__le16  ue_size;
102	u8  _r[14];
103	/* The unit element array is right here.
104	 */
105} __attribute__ ((packed));
106
107/**
108 * asd_read_ocm_seg - read an on chip memory (OCM) segment
109 * @asd_ha: pointer to the host adapter structure
110 * @buffer: where to write the read data
111 * @offs: offset into OCM where to read from
112 * @size: how many bytes to read
113 *
114 * Return the number of bytes not read. Return 0 on success.
115 */
116static int asd_read_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer,
117			    u32 offs, int size)
118{
119	u8 *p = buffer;
120	if (unlikely(asd_ha->iospace))
121		asd_read_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size);
122	else {
123		for ( ; size > 0; size--, offs++, p++)
124			*p = asd_read_ocm_byte(asd_ha, offs);
125	}
126	return size;
127}
128
129static int asd_read_ocm_dir(struct asd_ha_struct *asd_ha,
130			    struct asd_ocm_dir *dir, u32 offs)
131{
132	int err = asd_read_ocm_seg(asd_ha, dir, offs, sizeof(*dir));
133	if (err) {
134		ASD_DPRINTK("couldn't read ocm segment\n");
135		return err;
136	}
137
138	if (dir->sig[0] != 'M' || dir->sig[1] != 'O') {
139		ASD_DPRINTK("no valid dir signature(%c%c) at start of OCM\n",
140			    dir->sig[0], dir->sig[1]);
141		return -ENOENT;
142	}
143	if (dir->major != 0) {
144		asd_printk("unsupported major version of ocm dir:0x%x\n",
145			   dir->major);
146		return -ENOENT;
147	}
148	dir->num_de &= 0xf;
149	return 0;
150}
151
152/**
153 * asd_write_ocm_seg - write an on chip memory (OCM) segment
154 * @asd_ha: pointer to the host adapter structure
155 * @buffer: where to read the write data
156 * @offs: offset into OCM to write to
157 * @size: how many bytes to write
158 *
159 * Return the number of bytes not written. Return 0 on success.
160 */
161static void asd_write_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer,
162			    u32 offs, int size)
163{
164	u8 *p = buffer;
165	if (unlikely(asd_ha->iospace))
166		asd_write_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size);
167	else {
168		for ( ; size > 0; size--, offs++, p++)
169			asd_write_ocm_byte(asd_ha, offs, *p);
170	}
171	return;
172}
173
174#define THREE_TO_NUM(X) ((X)[0] | ((X)[1] << 8) | ((X)[2] << 16))
175
176static int asd_find_dir_entry(struct asd_ocm_dir *dir, u8 type,
177			      u32 *offs, u32 *size)
178{
179	int i;
180	struct asd_ocm_dir_ent *ent;
181
182	for (i = 0; i < dir->num_de; i++) {
183		if (dir->entry[i].type == type)
184			break;
185	}
186	if (i >= dir->num_de)
187		return -ENOENT;
188	ent = &dir->entry[i];
189	*offs = (u32) THREE_TO_NUM(ent->offs);
190	*size = (u32) THREE_TO_NUM(ent->size);
191	return 0;
192}
193
194#define OCM_BIOS_CHIM_DE  2
195#define BC_BIOS_PRESENT   1
196
197static int asd_get_bios_chim(struct asd_ha_struct *asd_ha,
198			     struct asd_ocm_dir *dir)
199{
200	int err;
201	struct asd_bios_chim_struct *bc_struct;
202	u32 offs, size;
203
204	err = asd_find_dir_entry(dir, OCM_BIOS_CHIM_DE, &offs, &size);
205	if (err) {
206		ASD_DPRINTK("couldn't find BIOS_CHIM dir ent\n");
207		goto out;
208	}
209	err = -ENOMEM;
210	bc_struct = kmalloc(sizeof(*bc_struct), GFP_KERNEL);
211	if (!bc_struct) {
212		asd_printk("no memory for bios_chim struct\n");
213		goto out;
214	}
215	err = asd_read_ocm_seg(asd_ha, (void *)bc_struct, offs,
216			       sizeof(*bc_struct));
217	if (err) {
218		ASD_DPRINTK("couldn't read ocm segment\n");
219		goto out2;
220	}
221	if (strncmp(bc_struct->sig, "SOIB", 4)
222	    && strncmp(bc_struct->sig, "IPSA", 4)) {
223		ASD_DPRINTK("BIOS_CHIM entry has no valid sig(%c%c%c%c)\n",
224			    bc_struct->sig[0], bc_struct->sig[1],
225			    bc_struct->sig[2], bc_struct->sig[3]);
226		err = -ENOENT;
227		goto out2;
228	}
229	if (bc_struct->major != 1) {
230		asd_printk("BIOS_CHIM unsupported major version:0x%x\n",
231			   bc_struct->major);
232		err = -ENOENT;
233		goto out2;
234	}
235	if (bc_struct->flags & BC_BIOS_PRESENT) {
236		asd_ha->hw_prof.bios.present = 1;
237		asd_ha->hw_prof.bios.maj = bc_struct->bios_major;
238		asd_ha->hw_prof.bios.min = bc_struct->bios_minor;
239		asd_ha->hw_prof.bios.bld = le32_to_cpu(bc_struct->bios_build);
240		ASD_DPRINTK("BIOS present (%d,%d), %d\n",
241			    asd_ha->hw_prof.bios.maj,
242			    asd_ha->hw_prof.bios.min,
243			    asd_ha->hw_prof.bios.bld);
244	}
245	asd_ha->hw_prof.ue.num = le16_to_cpu(bc_struct->ue_num);
246	asd_ha->hw_prof.ue.size= le16_to_cpu(bc_struct->ue_size);
247	ASD_DPRINTK("ue num:%d, ue size:%d\n", asd_ha->hw_prof.ue.num,
248		    asd_ha->hw_prof.ue.size);
249	size = asd_ha->hw_prof.ue.num * asd_ha->hw_prof.ue.size;
250	if (size > 0) {
251		err = -ENOMEM;
252		asd_ha->hw_prof.ue.area = kmalloc(size, GFP_KERNEL);
253		if (!asd_ha->hw_prof.ue.area)
254			goto out2;
255		err = asd_read_ocm_seg(asd_ha, (void *)asd_ha->hw_prof.ue.area,
256				       offs + sizeof(*bc_struct), size);
257		if (err) {
258			kfree(asd_ha->hw_prof.ue.area);
259			asd_ha->hw_prof.ue.area = NULL;
260			asd_ha->hw_prof.ue.num  = 0;
261			asd_ha->hw_prof.ue.size = 0;
262			ASD_DPRINTK("couldn't read ue entries(%d)\n", err);
263		}
264	}
265out2:
266	kfree(bc_struct);
267out:
268	return err;
269}
270
271static void
272asd_hwi_initialize_ocm_dir (struct asd_ha_struct *asd_ha)
273{
274	int i;
275
276	/* Zero OCM */
277	for (i = 0; i < OCM_MAX_SIZE; i += 4)
278		asd_write_ocm_dword(asd_ha, i, 0);
279
280	/* Write Dir */
281	asd_write_ocm_seg(asd_ha, &OCMDirInit, 0,
282			  sizeof(struct asd_ocm_dir));
283
284	/* Write Dir Entries */
285	for (i = 0; i < OCM_INIT_DIR_ENTRIES; i++)
286		asd_write_ocm_seg(asd_ha, &OCMDirEntriesInit[i],
287				  sizeof(struct asd_ocm_dir) +
288				  (i * sizeof(struct asd_ocm_dir_ent))
289				  , sizeof(struct asd_ocm_dir_ent));
290
291}
292
293static int
294asd_hwi_check_ocm_access (struct asd_ha_struct *asd_ha)
295{
296	struct pci_dev *pcidev = asd_ha->pcidev;
297	u32 reg;
298	int err = 0;
299	u32 v;
300
301	/* check if OCM has been initialized by BIOS */
302	reg = asd_read_reg_dword(asd_ha, EXSICNFGR);
303
304	if (!(reg & OCMINITIALIZED)) {
305		err = pci_read_config_dword(pcidev, PCIC_INTRPT_STAT, &v);
306		if (err) {
307			asd_printk("couldn't access PCIC_INTRPT_STAT of %s\n",
308					pci_name(pcidev));
309			goto out;
310		}
311
312		printk(KERN_INFO "OCM is not initialized by BIOS,"
313		       "reinitialize it and ignore it, current IntrptStatus"
314		       "is 0x%x\n", v);
315
316		if (v)
317			err = pci_write_config_dword(pcidev,
318						     PCIC_INTRPT_STAT, v);
319		if (err) {
320			asd_printk("couldn't write PCIC_INTRPT_STAT of %s\n",
321					pci_name(pcidev));
322			goto out;
323		}
324
325		asd_hwi_initialize_ocm_dir(asd_ha);
326
327	}
328out:
329	return err;
330}
331
332/**
333 * asd_read_ocm - read on chip memory (OCM)
334 * @asd_ha: pointer to the host adapter structure
335 */
336int asd_read_ocm(struct asd_ha_struct *asd_ha)
337{
338	int err;
339	struct asd_ocm_dir *dir;
340
341	if (asd_hwi_check_ocm_access(asd_ha))
342		return -1;
343
344	dir = kmalloc(sizeof(*dir), GFP_KERNEL);
345	if (!dir) {
346		asd_printk("no memory for ocm dir\n");
347		return -ENOMEM;
348	}
349
350	err = asd_read_ocm_dir(asd_ha, dir, 0);
351	if (err)
352		goto out;
353
354	err = asd_get_bios_chim(asd_ha, dir);
355out:
356	kfree(dir);
357	return err;
358}
359
360/* ---------- FLASH stuff ---------- */
361
362#define FLASH_RESET			0xF0
363
364#define ASD_FLASH_SIZE                  0x200000
365#define FLASH_DIR_COOKIE                "*** ADAPTEC FLASH DIRECTORY *** "
366#define FLASH_NEXT_ENTRY_OFFS		0x2000
367#define FLASH_MAX_DIR_ENTRIES		32
368
369#define FLASH_DE_TYPE_MASK              0x3FFFFFFF
370#define FLASH_DE_MS                     0x120
371#define FLASH_DE_CTRL_A_USER            0xE0
372
373struct asd_flash_de {
374	__le32   type;
375	__le32   offs;
376	__le32   pad_size;
377	__le32   image_size;
378	__le32   chksum;
379	u8       _r[12];
380	u8       version[32];
381} __attribute__ ((packed));
382
383struct asd_flash_dir {
384	u8    cookie[32];
385	__le32   rev;		  /* 2 */
386	__le32   chksum;
387	__le32   chksum_antidote;
388	__le32   bld;
389	u8    bld_id[32];	  /* build id data */
390	u8    ver_data[32];	  /* date and time of build */
391	__le32   ae_mask;
392	__le32   v_mask;
393	__le32   oc_mask;
394	u8    _r[20];
395	struct asd_flash_de dir_entry[FLASH_MAX_DIR_ENTRIES];
396} __attribute__ ((packed));
397
398struct asd_manuf_sec {
399	char  sig[2];		  /* 'S', 'M' */
400	u16   offs_next;
401	u8    maj;           /* 0 */
402	u8    min;           /* 0 */
403	u16   chksum;
404	u16   size;
405	u8    _r[6];
406	u8    sas_addr[SAS_ADDR_SIZE];
407	u8    pcba_sn[ASD_PCBA_SN_SIZE];
408	/* Here start the other segments */
409	u8    linked_list[];
410} __attribute__ ((packed));
411
412struct asd_manuf_phy_desc {
413	u8    state;         /* low 4 bits */
414#define MS_PHY_STATE_ENABLED    0
415#define MS_PHY_STATE_REPORTED   1
416#define MS_PHY_STATE_HIDDEN     2
417	u8    phy_id;
418	u16   _r;
419	u8    phy_control_0; /* mode 5 reg 0x160 */
420	u8    phy_control_1; /* mode 5 reg 0x161 */
421	u8    phy_control_2; /* mode 5 reg 0x162 */
422	u8    phy_control_3; /* mode 5 reg 0x163 */
423} __attribute__ ((packed));
424
425struct asd_manuf_phy_param {
426	char  sig[2];		  /* 'P', 'M' */
427	u16   next;
428	u8    maj;           /* 0 */
429	u8    min;           /* 2 */
430	u8    num_phy_desc;  /* 8 */
431	u8    phy_desc_size; /* 8 */
432	u8    _r[3];
433	u8    usage_model_id;
434	u32   _r2;
435	struct asd_manuf_phy_desc phy_desc[ASD_MAX_PHYS];
436} __attribute__ ((packed));
437
438#if 0
439static const char *asd_sb_type[] = {
440	"unknown",
441	"SGPIO",
442	[2 ... 0x7F] = "unknown",
443	[0x80] = "ADPT_I2C",
444	[0x81 ... 0xFF] = "VENDOR_UNIQUExx"
445};
446#endif
447
448struct asd_ms_sb_desc {
449	u8    type;
450	u8    node_desc_index;
451	u8    conn_desc_index;
452	u8    _recvd[];
453} __attribute__ ((packed));
454
455#if 0
456static const char *asd_conn_type[] = {
457	[0 ... 7] = "unknown",
458	"SFF8470",
459	"SFF8482",
460	"SFF8484",
461	[0x80] = "PCIX_DAUGHTER0",
462	[0x81] = "SAS_DAUGHTER0",
463	[0x82 ... 0xFF] = "VENDOR_UNIQUExx"
464};
465
466static const char *asd_conn_location[] = {
467	"unknown",
468	"internal",
469	"external",
470	"board_to_board",
471};
472#endif
473
474struct asd_ms_conn_desc {
475	u8    type;
476	u8    location;
477	u8    num_sideband_desc;
478	u8    size_sideband_desc;
479	u32   _resvd;
480	u8    name[16];
481	struct asd_ms_sb_desc sb_desc[];
482} __attribute__ ((packed));
483
484struct asd_nd_phy_desc {
485	u8    vp_attch_type;
486	u8    attch_specific[];
487} __attribute__ ((packed));
488
489#if 0
490static const char *asd_node_type[] = {
491	"IOP",
492	"IO_CONTROLLER",
493	"EXPANDER",
494	"PORT_MULTIPLIER",
495	"PORT_MULTIPLEXER",
496	"MULTI_DROP_I2C_BUS",
497};
498#endif
499
500struct asd_ms_node_desc {
501	u8    type;
502	u8    num_phy_desc;
503	u8    size_phy_desc;
504	u8    _resvd;
505	u8    name[16];
506	struct asd_nd_phy_desc phy_desc[];
507} __attribute__ ((packed));
508
509struct asd_ms_conn_map {
510	char  sig[2];		  /* 'M', 'C' */
511	__le16 next;
512	u8    maj;		  /* 0 */
513	u8    min;		  /* 0 */
514	__le16 cm_size;		  /* size of this struct */
515	u8    num_conn;
516	u8    conn_size;
517	u8    num_nodes;
518	u8    usage_model_id;
519	u32   _resvd;
520	union {
521		DECLARE_FLEX_ARRAY(struct asd_ms_conn_desc, conn_desc);
522		DECLARE_FLEX_ARRAY(struct asd_ms_node_desc, node_desc);
523	};
524} __attribute__ ((packed));
525
526struct asd_ctrla_phy_entry {
527	u8    sas_addr[SAS_ADDR_SIZE];
528	u8    sas_link_rates;  /* max in hi bits, min in low bits */
529	u8    flags;
530	u8    sata_link_rates;
531	u8    _r[5];
532} __attribute__ ((packed));
533
534struct asd_ctrla_phy_settings {
535	u8    id0;		  /* P'h'y */
536	u8    _r;
537	u16   next;
538	u8    num_phys;	      /* number of PHYs in the PCI function */
539	u8    _r2[3];
540	struct asd_ctrla_phy_entry phy_ent[ASD_MAX_PHYS];
541} __attribute__ ((packed));
542
543struct asd_ll_el {
544	u8   id0;
545	u8   id1;
546	__le16  next;
547	u8   something_here[];
548} __attribute__ ((packed));
549
550static int asd_poll_flash(struct asd_ha_struct *asd_ha)
551{
552	int c;
553	u8 d;
554
555	for (c = 5000; c > 0; c--) {
556		d  = asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar);
557		d ^= asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar);
558		if (!d)
559			return 0;
560		udelay(5);
561	}
562	return -ENOENT;
563}
564
565static int asd_reset_flash(struct asd_ha_struct *asd_ha)
566{
567	int err;
568
569	err = asd_poll_flash(asd_ha);
570	if (err)
571		return err;
572	asd_write_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar, FLASH_RESET);
573	err = asd_poll_flash(asd_ha);
574
575	return err;
576}
577
578static int asd_read_flash_seg(struct asd_ha_struct *asd_ha,
579			      void *buffer, u32 offs, int size)
580{
581	asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs,
582			    size);
583	return 0;
584}
585
586/**
587 * asd_find_flash_dir - finds and reads the flash directory
588 * @asd_ha: pointer to the host adapter structure
589 * @flash_dir: pointer to flash directory structure
590 *
591 * If found, the flash directory segment will be copied to
592 * @flash_dir.  Return 1 if found, 0 if not.
593 */
594static int asd_find_flash_dir(struct asd_ha_struct *asd_ha,
595			      struct asd_flash_dir *flash_dir)
596{
597	u32 v;
598	for (v = 0; v < ASD_FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) {
599		asd_read_flash_seg(asd_ha, flash_dir, v,
600				   sizeof(FLASH_DIR_COOKIE)-1);
601		if (memcmp(flash_dir->cookie, FLASH_DIR_COOKIE,
602			   sizeof(FLASH_DIR_COOKIE)-1) == 0) {
603			asd_ha->hw_prof.flash.dir_offs = v;
604			asd_read_flash_seg(asd_ha, flash_dir, v,
605					   sizeof(*flash_dir));
606			return 1;
607		}
608	}
609	return 0;
610}
611
612static int asd_flash_getid(struct asd_ha_struct *asd_ha)
613{
614	int err = 0;
615	u32 reg;
616
617	reg = asd_read_reg_dword(asd_ha, EXSICNFGR);
618
619	if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR,
620				  &asd_ha->hw_prof.flash.bar)) {
621		asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n",
622			   pci_name(asd_ha->pcidev));
623		return -ENOENT;
624	}
625	asd_ha->hw_prof.flash.present = 1;
626	asd_ha->hw_prof.flash.wide = reg & FLASHW ? 1 : 0;
627	err = asd_reset_flash(asd_ha);
628	if (err) {
629		ASD_DPRINTK("couldn't reset flash(%d)\n", err);
630		return err;
631	}
632	return 0;
633}
634
635static u16 asd_calc_flash_chksum(u16 *p, int size)
636{
637	u16 chksum = 0;
638
639	while (size-- > 0)
640		chksum += *p++;
641
642	return chksum;
643}
644
645
646static int asd_find_flash_de(struct asd_flash_dir *flash_dir, u32 entry_type,
647			     u32 *offs, u32 *size)
648{
649	int i;
650	struct asd_flash_de *de;
651
652	for (i = 0; i < FLASH_MAX_DIR_ENTRIES; i++) {
653		u32 type = le32_to_cpu(flash_dir->dir_entry[i].type);
654
655		type &= FLASH_DE_TYPE_MASK;
656		if (type == entry_type)
657			break;
658	}
659	if (i >= FLASH_MAX_DIR_ENTRIES)
660		return -ENOENT;
661	de = &flash_dir->dir_entry[i];
662	*offs = le32_to_cpu(de->offs);
663	*size = le32_to_cpu(de->pad_size);
664	return 0;
665}
666
667static int asd_validate_ms(struct asd_manuf_sec *ms)
668{
669	if (ms->sig[0] != 'S' || ms->sig[1] != 'M') {
670		ASD_DPRINTK("manuf sec: no valid sig(%c%c)\n",
671			    ms->sig[0], ms->sig[1]);
672		return -ENOENT;
673	}
674	if (ms->maj != 0) {
675		asd_printk("unsupported manuf. sector. major version:%x\n",
676			   ms->maj);
677		return -ENOENT;
678	}
679	ms->offs_next = le16_to_cpu((__force __le16) ms->offs_next);
680	ms->chksum = le16_to_cpu((__force __le16) ms->chksum);
681	ms->size = le16_to_cpu((__force __le16) ms->size);
682
683	if (asd_calc_flash_chksum((u16 *)ms, ms->size/2)) {
684		asd_printk("failed manuf sector checksum\n");
685	}
686
687	return 0;
688}
689
690static int asd_ms_get_sas_addr(struct asd_ha_struct *asd_ha,
691			       struct asd_manuf_sec *ms)
692{
693	memcpy(asd_ha->hw_prof.sas_addr, ms->sas_addr, SAS_ADDR_SIZE);
694	return 0;
695}
696
697static int asd_ms_get_pcba_sn(struct asd_ha_struct *asd_ha,
698			      struct asd_manuf_sec *ms)
699{
700	memcpy(asd_ha->hw_prof.pcba_sn, ms->pcba_sn, ASD_PCBA_SN_SIZE);
701	asd_ha->hw_prof.pcba_sn[ASD_PCBA_SN_SIZE] = '\0';
702	return 0;
703}
704
705/**
706 * asd_find_ll_by_id - find a linked list entry by its id
707 * @start: void pointer to the first element in the linked list
708 * @id0: the first byte of the id  (offs 0)
709 * @id1: the second byte of the id (offs 1)
710 *
711 * @start has to be the _base_ element start, since the
712 * linked list entries's offset is from this pointer.
713 * Some linked list entries use only the first id, in which case
714 * you can pass 0xFF for the second.
715 */
716static void *asd_find_ll_by_id(void * const start, const u8 id0, const u8 id1)
717{
718	struct asd_ll_el *el = start;
719
720	do {
721		switch (id1) {
722		default:
723			if (el->id1 == id1) {
724			fallthrough;
725		case 0xFF:
726				if (el->id0 == id0)
727					return el;
728			}
729		}
730		el = start + le16_to_cpu(el->next);
731	} while (el != start);
732
733	return NULL;
734}
735
736/**
737 * asd_ms_get_phy_params - get phy parameters from the manufacturing sector
738 * @asd_ha: pointer to the host adapter structure
739 * @manuf_sec: pointer to the manufacturing sector
740 *
741 * The manufacturing sector contans also the linked list of sub-segments,
742 * since when it was read, its size was taken from the flash directory,
743 * not from the structure size.
744 *
745 * HIDDEN phys do not count in the total count.  REPORTED phys cannot
746 * be enabled but are reported and counted towards the total.
747 * ENABLED phys are enabled by default and count towards the total.
748 * The absolute total phy number is ASD_MAX_PHYS.  hw_prof->num_phys
749 * merely specifies the number of phys the host adapter decided to
750 * report.  E.g., it is possible for phys 0, 1 and 2 to be HIDDEN,
751 * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENABLED.
752 * In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2
753 * are actually enabled (enabled by default, max number of phys
754 * enableable in this case).
755 */
756static int asd_ms_get_phy_params(struct asd_ha_struct *asd_ha,
757				 struct asd_manuf_sec *manuf_sec)
758{
759	int i;
760	int en_phys = 0;
761	int rep_phys = 0;
762	struct asd_manuf_phy_param *phy_param;
763	struct asd_manuf_phy_param dflt_phy_param;
764
765	phy_param = asd_find_ll_by_id(manuf_sec, 'P', 'M');
766	if (!phy_param) {
767		ASD_DPRINTK("ms: no phy parameters found\n");
768		ASD_DPRINTK("ms: Creating default phy parameters\n");
769		dflt_phy_param.sig[0] = 'P';
770		dflt_phy_param.sig[1] = 'M';
771		dflt_phy_param.maj = 0;
772		dflt_phy_param.min = 2;
773		dflt_phy_param.num_phy_desc = 8;
774		dflt_phy_param.phy_desc_size = sizeof(struct asd_manuf_phy_desc);
775		for (i =0; i < ASD_MAX_PHYS; i++) {
776			dflt_phy_param.phy_desc[i].state = 0;
777			dflt_phy_param.phy_desc[i].phy_id = i;
778			dflt_phy_param.phy_desc[i].phy_control_0 = 0xf6;
779			dflt_phy_param.phy_desc[i].phy_control_1 = 0x10;
780			dflt_phy_param.phy_desc[i].phy_control_2 = 0x43;
781			dflt_phy_param.phy_desc[i].phy_control_3 = 0xeb;
782		}
783
784		phy_param = &dflt_phy_param;
785
786	}
787
788	if (phy_param->maj != 0) {
789		asd_printk("unsupported manuf. phy param major version:0x%x\n",
790			   phy_param->maj);
791		return -ENOENT;
792	}
793
794	ASD_DPRINTK("ms: num_phy_desc: %d\n", phy_param->num_phy_desc);
795	asd_ha->hw_prof.enabled_phys = 0;
796	for (i = 0; i < phy_param->num_phy_desc; i++) {
797		struct asd_manuf_phy_desc *pd = &phy_param->phy_desc[i];
798		switch (pd->state & 0xF) {
799		case MS_PHY_STATE_HIDDEN:
800			ASD_DPRINTK("ms: phy%d: HIDDEN\n", i);
801			continue;
802		case MS_PHY_STATE_REPORTED:
803			ASD_DPRINTK("ms: phy%d: REPORTED\n", i);
804			asd_ha->hw_prof.enabled_phys &= ~(1 << i);
805			rep_phys++;
806			continue;
807		case MS_PHY_STATE_ENABLED:
808			ASD_DPRINTK("ms: phy%d: ENABLED\n", i);
809			asd_ha->hw_prof.enabled_phys |= (1 << i);
810			en_phys++;
811			break;
812		}
813		asd_ha->hw_prof.phy_desc[i].phy_control_0 = pd->phy_control_0;
814		asd_ha->hw_prof.phy_desc[i].phy_control_1 = pd->phy_control_1;
815		asd_ha->hw_prof.phy_desc[i].phy_control_2 = pd->phy_control_2;
816		asd_ha->hw_prof.phy_desc[i].phy_control_3 = pd->phy_control_3;
817	}
818	asd_ha->hw_prof.max_phys = rep_phys + en_phys;
819	asd_ha->hw_prof.num_phys = en_phys;
820	ASD_DPRINTK("ms: max_phys:0x%x, num_phys:0x%x\n",
821		    asd_ha->hw_prof.max_phys, asd_ha->hw_prof.num_phys);
822	ASD_DPRINTK("ms: enabled_phys:0x%x\n", asd_ha->hw_prof.enabled_phys);
823	return 0;
824}
825
826static int asd_ms_get_connector_map(struct asd_ha_struct *asd_ha,
827				    struct asd_manuf_sec *manuf_sec)
828{
829	struct asd_ms_conn_map *cm;
830
831	cm = asd_find_ll_by_id(manuf_sec, 'M', 'C');
832	if (!cm) {
833		ASD_DPRINTK("ms: no connector map found\n");
834		return 0;
835	}
836
837	if (cm->maj != 0) {
838		ASD_DPRINTK("ms: unsupported: connector map major version 0x%x"
839			    "\n", cm->maj);
840		return -ENOENT;
841	}
842
843	/* XXX */
844
845	return 0;
846}
847
848
849/**
850 * asd_process_ms - find and extract information from the manufacturing sector
851 * @asd_ha: pointer to the host adapter structure
852 * @flash_dir: pointer to the flash directory
853 */
854static int asd_process_ms(struct asd_ha_struct *asd_ha,
855			  struct asd_flash_dir *flash_dir)
856{
857	int err;
858	struct asd_manuf_sec *manuf_sec;
859	u32 offs, size;
860
861	err = asd_find_flash_de(flash_dir, FLASH_DE_MS, &offs, &size);
862	if (err) {
863		ASD_DPRINTK("Couldn't find the manuf. sector\n");
864		goto out;
865	}
866
867	if (size == 0)
868		goto out;
869
870	err = -ENOMEM;
871	manuf_sec = kmalloc(size, GFP_KERNEL);
872	if (!manuf_sec) {
873		ASD_DPRINTK("no mem for manuf sector\n");
874		goto out;
875	}
876
877	err = asd_read_flash_seg(asd_ha, (void *)manuf_sec, offs, size);
878	if (err) {
879		ASD_DPRINTK("couldn't read manuf sector at 0x%x, size 0x%x\n",
880			    offs, size);
881		goto out2;
882	}
883
884	err = asd_validate_ms(manuf_sec);
885	if (err) {
886		ASD_DPRINTK("couldn't validate manuf sector\n");
887		goto out2;
888	}
889
890	err = asd_ms_get_sas_addr(asd_ha, manuf_sec);
891	if (err) {
892		ASD_DPRINTK("couldn't read the SAS_ADDR\n");
893		goto out2;
894	}
895	ASD_DPRINTK("manuf sect SAS_ADDR %llx\n",
896		    SAS_ADDR(asd_ha->hw_prof.sas_addr));
897
898	err = asd_ms_get_pcba_sn(asd_ha, manuf_sec);
899	if (err) {
900		ASD_DPRINTK("couldn't read the PCBA SN\n");
901		goto out2;
902	}
903	ASD_DPRINTK("manuf sect PCBA SN %s\n", asd_ha->hw_prof.pcba_sn);
904
905	err = asd_ms_get_phy_params(asd_ha, manuf_sec);
906	if (err) {
907		ASD_DPRINTK("ms: couldn't get phy parameters\n");
908		goto out2;
909	}
910
911	err = asd_ms_get_connector_map(asd_ha, manuf_sec);
912	if (err) {
913		ASD_DPRINTK("ms: couldn't get connector map\n");
914		goto out2;
915	}
916
917out2:
918	kfree(manuf_sec);
919out:
920	return err;
921}
922
923static int asd_process_ctrla_phy_settings(struct asd_ha_struct *asd_ha,
924					  struct asd_ctrla_phy_settings *ps)
925{
926	int i;
927	for (i = 0; i < ps->num_phys; i++) {
928		struct asd_ctrla_phy_entry *pe = &ps->phy_ent[i];
929
930		if (!PHY_ENABLED(asd_ha, i))
931			continue;
932		if (*(u64 *)pe->sas_addr == 0) {
933			asd_ha->hw_prof.enabled_phys &= ~(1 << i);
934			continue;
935		}
936		/* This is the SAS address which should be sent in IDENTIFY. */
937		memcpy(asd_ha->hw_prof.phy_desc[i].sas_addr, pe->sas_addr,
938		       SAS_ADDR_SIZE);
939		asd_ha->hw_prof.phy_desc[i].max_sas_lrate =
940			(pe->sas_link_rates & 0xF0) >> 4;
941		asd_ha->hw_prof.phy_desc[i].min_sas_lrate =
942			(pe->sas_link_rates & 0x0F);
943		asd_ha->hw_prof.phy_desc[i].max_sata_lrate =
944			(pe->sata_link_rates & 0xF0) >> 4;
945		asd_ha->hw_prof.phy_desc[i].min_sata_lrate =
946			(pe->sata_link_rates & 0x0F);
947		asd_ha->hw_prof.phy_desc[i].flags = pe->flags;
948		ASD_DPRINTK("ctrla: phy%d: sas_addr: %llx, sas rate:0x%x-0x%x,"
949			    " sata rate:0x%x-0x%x, flags:0x%x\n",
950			    i,
951			    SAS_ADDR(asd_ha->hw_prof.phy_desc[i].sas_addr),
952			    asd_ha->hw_prof.phy_desc[i].max_sas_lrate,
953			    asd_ha->hw_prof.phy_desc[i].min_sas_lrate,
954			    asd_ha->hw_prof.phy_desc[i].max_sata_lrate,
955			    asd_ha->hw_prof.phy_desc[i].min_sata_lrate,
956			    asd_ha->hw_prof.phy_desc[i].flags);
957	}
958
959	return 0;
960}
961
962/**
963 * asd_process_ctrl_a_user - process CTRL-A user settings
964 * @asd_ha: pointer to the host adapter structure
965 * @flash_dir: pointer to the flash directory
966 */
967static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha,
968				   struct asd_flash_dir *flash_dir)
969{
970	int err, i;
971	u32 offs, size;
972	struct asd_ll_el *el = NULL;
973	struct asd_ctrla_phy_settings *ps;
974	struct asd_ctrla_phy_settings dflt_ps;
975
976	err = asd_find_flash_de(flash_dir, FLASH_DE_CTRL_A_USER, &offs, &size);
977	if (err) {
978		ASD_DPRINTK("couldn't find CTRL-A user settings section\n");
979		ASD_DPRINTK("Creating default CTRL-A user settings section\n");
980
981		dflt_ps.id0 = 'h';
982		dflt_ps.num_phys = 8;
983		for (i =0; i < ASD_MAX_PHYS; i++) {
984			memcpy(dflt_ps.phy_ent[i].sas_addr,
985			       asd_ha->hw_prof.sas_addr, SAS_ADDR_SIZE);
986			dflt_ps.phy_ent[i].sas_link_rates = 0x98;
987			dflt_ps.phy_ent[i].flags = 0x0;
988			dflt_ps.phy_ent[i].sata_link_rates = 0x0;
989		}
990
991		size = sizeof(struct asd_ctrla_phy_settings);
992		ps = &dflt_ps;
993		goto out_process;
994	}
995
996	if (size == 0)
997		goto out;
998
999	err = -ENOMEM;
1000	el = kmalloc(size, GFP_KERNEL);
1001	if (!el) {
1002		ASD_DPRINTK("no mem for ctrla user settings section\n");
1003		goto out;
1004	}
1005
1006	err = asd_read_flash_seg(asd_ha, (void *)el, offs, size);
1007	if (err) {
1008		ASD_DPRINTK("couldn't read ctrla phy settings section\n");
1009		goto out2;
1010	}
1011
1012	err = -ENOENT;
1013	ps = asd_find_ll_by_id(el, 'h', 0xFF);
1014	if (!ps) {
1015		ASD_DPRINTK("couldn't find ctrla phy settings struct\n");
1016		goto out2;
1017	}
1018out_process:
1019	err = asd_process_ctrla_phy_settings(asd_ha, ps);
1020	if (err) {
1021		ASD_DPRINTK("couldn't process ctrla phy settings\n");
1022		goto out2;
1023	}
1024out2:
1025	kfree(el);
1026out:
1027	return err;
1028}
1029
1030/**
1031 * asd_read_flash - read flash memory
1032 * @asd_ha: pointer to the host adapter structure
1033 */
1034int asd_read_flash(struct asd_ha_struct *asd_ha)
1035{
1036	int err;
1037	struct asd_flash_dir *flash_dir;
1038
1039	err = asd_flash_getid(asd_ha);
1040	if (err)
1041		return err;
1042
1043	flash_dir = kmalloc(sizeof(*flash_dir), GFP_KERNEL);
1044	if (!flash_dir)
1045		return -ENOMEM;
1046
1047	err = -ENOENT;
1048	if (!asd_find_flash_dir(asd_ha, flash_dir)) {
1049		ASD_DPRINTK("couldn't find flash directory\n");
1050		goto out;
1051	}
1052
1053	if (le32_to_cpu(flash_dir->rev) != 2) {
1054		asd_printk("unsupported flash dir version:0x%x\n",
1055			   le32_to_cpu(flash_dir->rev));
1056		goto out;
1057	}
1058
1059	err = asd_process_ms(asd_ha, flash_dir);
1060	if (err) {
1061		ASD_DPRINTK("couldn't process manuf sector settings\n");
1062		goto out;
1063	}
1064
1065	err = asd_process_ctrl_a_user(asd_ha, flash_dir);
1066	if (err) {
1067		ASD_DPRINTK("couldn't process CTRL-A user settings\n");
1068		goto out;
1069	}
1070
1071out:
1072	kfree(flash_dir);
1073	return err;
1074}
1075
1076/**
1077 * asd_verify_flash_seg - verify data with flash memory
1078 * @asd_ha: pointer to the host adapter structure
1079 * @src: pointer to the source data to be verified
1080 * @dest_offset: offset from flash memory
1081 * @bytes_to_verify: total bytes to verify
1082 */
1083int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
1084			 const void *src, u32 dest_offset, u32 bytes_to_verify)
1085{
1086	const u8 *src_buf;
1087	u8 flash_char;
1088	int err;
1089	u32 nv_offset, reg, i;
1090
1091	reg = asd_ha->hw_prof.flash.bar;
1092	src_buf = NULL;
1093
1094	err = FLASH_OK;
1095	nv_offset = dest_offset;
1096	src_buf = (const u8 *)src;
1097	for (i = 0; i < bytes_to_verify; i++) {
1098		flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i);
1099		if (flash_char != src_buf[i]) {
1100			err = FAIL_VERIFY;
1101			break;
1102		}
1103	}
1104	return err;
1105}
1106
1107/**
1108 * asd_write_flash_seg - write data into flash memory
1109 * @asd_ha: pointer to the host adapter structure
1110 * @src: pointer to the source data to be written
1111 * @dest_offset: offset from flash memory
1112 * @bytes_to_write: total bytes to write
1113 */
1114int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
1115			const void *src, u32 dest_offset, u32 bytes_to_write)
1116{
1117	const u8 *src_buf;
1118	u32 nv_offset, reg, i;
1119	int err;
1120
1121	reg = asd_ha->hw_prof.flash.bar;
1122	src_buf = NULL;
1123
1124	err = asd_check_flash_type(asd_ha);
1125	if (err) {
1126		ASD_DPRINTK("couldn't find the type of flash. err=%d\n", err);
1127		return err;
1128	}
1129
1130	nv_offset = dest_offset;
1131	err = asd_erase_nv_sector(asd_ha, nv_offset, bytes_to_write);
1132	if (err) {
1133		ASD_DPRINTK("Erase failed at offset:0x%x\n",
1134			nv_offset);
1135		return err;
1136	}
1137
1138	err = asd_reset_flash(asd_ha);
1139	if (err) {
1140		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1141		return err;
1142	}
1143
1144	src_buf = (const u8 *)src;
1145	for (i = 0; i < bytes_to_write; i++) {
1146		/* Setup program command sequence */
1147		switch (asd_ha->hw_prof.flash.method) {
1148		case FLASH_METHOD_A:
1149		{
1150			asd_write_reg_byte(asd_ha,
1151					(reg + 0xAAA), 0xAA);
1152			asd_write_reg_byte(asd_ha,
1153					(reg + 0x555), 0x55);
1154			asd_write_reg_byte(asd_ha,
1155					(reg + 0xAAA), 0xA0);
1156			asd_write_reg_byte(asd_ha,
1157					(reg + nv_offset + i),
1158					(*(src_buf + i)));
1159			break;
1160		}
1161		case FLASH_METHOD_B:
1162		{
1163			asd_write_reg_byte(asd_ha,
1164					(reg + 0x555), 0xAA);
1165			asd_write_reg_byte(asd_ha,
1166					(reg + 0x2AA), 0x55);
1167			asd_write_reg_byte(asd_ha,
1168					(reg + 0x555), 0xA0);
1169			asd_write_reg_byte(asd_ha,
1170					(reg + nv_offset + i),
1171					(*(src_buf + i)));
1172			break;
1173		}
1174		default:
1175			break;
1176		}
1177		if (asd_chk_write_status(asd_ha,
1178				(nv_offset + i), 0) != 0) {
1179			ASD_DPRINTK("aicx: Write failed at offset:0x%x\n",
1180				reg + nv_offset + i);
1181			return FAIL_WRITE_FLASH;
1182		}
1183	}
1184
1185	err = asd_reset_flash(asd_ha);
1186	if (err) {
1187		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1188		return err;
1189	}
1190	return 0;
1191}
1192
1193int asd_chk_write_status(struct asd_ha_struct *asd_ha,
1194	 u32 sector_addr, u8 erase_flag)
1195{
1196	u32 reg;
1197	u32 loop_cnt;
1198	u8  nv_data1, nv_data2;
1199	u8  toggle_bit1;
1200
1201	/*
1202	 * Read from DQ2 requires sector address
1203	 * while it's dont care for DQ6
1204	 */
1205	reg = asd_ha->hw_prof.flash.bar;
1206
1207	for (loop_cnt = 0; loop_cnt < 50000; loop_cnt++) {
1208		nv_data1 = asd_read_reg_byte(asd_ha, reg);
1209		nv_data2 = asd_read_reg_byte(asd_ha, reg);
1210
1211		toggle_bit1 = ((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6)
1212				 ^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6));
1213
1214		if (toggle_bit1 == 0) {
1215			return 0;
1216		} else {
1217			if (nv_data2 & FLASH_STATUS_BIT_MASK_DQ5) {
1218				nv_data1 = asd_read_reg_byte(asd_ha,
1219								reg);
1220				nv_data2 = asd_read_reg_byte(asd_ha,
1221								reg);
1222				toggle_bit1 =
1223				((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6)
1224				^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6));
1225
1226				if (toggle_bit1 == 0)
1227					return 0;
1228			}
1229		}
1230
1231		/*
1232		 * ERASE is a sector-by-sector operation and requires
1233		 * more time to finish while WRITE is byte-byte-byte
1234		 * operation and takes lesser time to finish.
1235		 *
1236		 * For some strange reason a reduced ERASE delay gives different
1237		 * behaviour across different spirit boards. Hence we set
1238		 * a optimum balance of 50mus for ERASE which works well
1239		 * across all boards.
1240		 */
1241		if (erase_flag) {
1242			udelay(FLASH_STATUS_ERASE_DELAY_COUNT);
1243		} else {
1244			udelay(FLASH_STATUS_WRITE_DELAY_COUNT);
1245		}
1246	}
1247	return -1;
1248}
1249
1250/**
1251 * asd_erase_nv_sector - Erase the flash memory sectors.
1252 * @asd_ha: pointer to the host adapter structure
1253 * @flash_addr: pointer to offset from flash memory
1254 * @size: total bytes to erase.
1255 */
1256int asd_erase_nv_sector(struct asd_ha_struct *asd_ha, u32 flash_addr, u32 size)
1257{
1258	u32 reg;
1259	u32 sector_addr;
1260
1261	reg = asd_ha->hw_prof.flash.bar;
1262
1263	/* sector staring address */
1264	sector_addr = flash_addr & FLASH_SECTOR_SIZE_MASK;
1265
1266	/*
1267	 * Erasing an flash sector needs to be done in six consecutive
1268	 * write cyles.
1269	 */
1270	while (sector_addr < flash_addr+size) {
1271		switch (asd_ha->hw_prof.flash.method) {
1272		case FLASH_METHOD_A:
1273			asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA);
1274			asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55);
1275			asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0x80);
1276			asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA);
1277			asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55);
1278			asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30);
1279			break;
1280		case FLASH_METHOD_B:
1281			asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
1282			asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
1283			asd_write_reg_byte(asd_ha, (reg + 0x555), 0x80);
1284			asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
1285			asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
1286			asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30);
1287			break;
1288		default:
1289			break;
1290		}
1291
1292		if (asd_chk_write_status(asd_ha, sector_addr, 1) != 0)
1293			return FAIL_ERASE_FLASH;
1294
1295		sector_addr += FLASH_SECTOR_SIZE;
1296	}
1297
1298	return 0;
1299}
1300
1301int asd_check_flash_type(struct asd_ha_struct *asd_ha)
1302{
1303	u8 manuf_id;
1304	u8 dev_id;
1305	u8 sec_prot;
1306	u32 inc;
1307	u32 reg;
1308	int err;
1309
1310	/* get Flash memory base address */
1311	reg = asd_ha->hw_prof.flash.bar;
1312
1313	/* Determine flash info */
1314	err = asd_reset_flash(asd_ha);
1315	if (err) {
1316		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1317		return err;
1318	}
1319
1320	asd_ha->hw_prof.flash.method = FLASH_METHOD_UNKNOWN;
1321	asd_ha->hw_prof.flash.manuf = FLASH_MANUF_ID_UNKNOWN;
1322	asd_ha->hw_prof.flash.dev_id = FLASH_DEV_ID_UNKNOWN;
1323
1324	/* Get flash info. This would most likely be AMD Am29LV family flash.
1325	 * First try the sequence for word mode.  It is the same as for
1326	 * 008B (byte mode only), 160B (word mode) and 800D (word mode).
1327	 */
1328	inc = asd_ha->hw_prof.flash.wide ? 2 : 1;
1329	asd_write_reg_byte(asd_ha, reg + 0xAAA, 0xAA);
1330	asd_write_reg_byte(asd_ha, reg + 0x555, 0x55);
1331	asd_write_reg_byte(asd_ha, reg + 0xAAA, 0x90);
1332	manuf_id = asd_read_reg_byte(asd_ha, reg);
1333	dev_id = asd_read_reg_byte(asd_ha, reg + inc);
1334	sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc);
1335	/* Get out of autoselect mode. */
1336	err = asd_reset_flash(asd_ha);
1337	if (err) {
1338		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1339		return err;
1340	}
1341	ASD_DPRINTK("Flash MethodA manuf_id(0x%x) dev_id(0x%x) "
1342		"sec_prot(0x%x)\n", manuf_id, dev_id, sec_prot);
1343	err = asd_reset_flash(asd_ha);
1344	if (err != 0)
1345		return err;
1346
1347	switch (manuf_id) {
1348	case FLASH_MANUF_ID_AMD:
1349		switch (sec_prot) {
1350		case FLASH_DEV_ID_AM29LV800DT:
1351		case FLASH_DEV_ID_AM29LV640MT:
1352		case FLASH_DEV_ID_AM29F800B:
1353			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1354			break;
1355		default:
1356			break;
1357		}
1358		break;
1359	case FLASH_MANUF_ID_ST:
1360		switch (sec_prot) {
1361		case FLASH_DEV_ID_STM29W800DT:
1362		case FLASH_DEV_ID_STM29LV640:
1363			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1364			break;
1365		default:
1366			break;
1367		}
1368		break;
1369	case FLASH_MANUF_ID_FUJITSU:
1370		switch (sec_prot) {
1371		case FLASH_DEV_ID_MBM29LV800TE:
1372		case FLASH_DEV_ID_MBM29DL800TA:
1373			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1374			break;
1375		}
1376		break;
1377	case FLASH_MANUF_ID_MACRONIX:
1378		switch (sec_prot) {
1379		case FLASH_DEV_ID_MX29LV800BT:
1380			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1381			break;
1382		}
1383		break;
1384	}
1385
1386	if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN) {
1387		err = asd_reset_flash(asd_ha);
1388		if (err) {
1389			ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1390			return err;
1391		}
1392
1393		/* Issue Unlock sequence for AM29LV008BT */
1394		asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
1395		asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
1396		asd_write_reg_byte(asd_ha, (reg + 0x555), 0x90);
1397		manuf_id = asd_read_reg_byte(asd_ha, reg);
1398		dev_id = asd_read_reg_byte(asd_ha, reg + inc);
1399		sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc);
1400
1401		ASD_DPRINTK("Flash MethodB manuf_id(0x%x) dev_id(0x%x) sec_prot"
1402			"(0x%x)\n", manuf_id, dev_id, sec_prot);
1403
1404		err = asd_reset_flash(asd_ha);
1405		if (err != 0) {
1406			ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1407			return err;
1408		}
1409
1410		switch (manuf_id) {
1411		case FLASH_MANUF_ID_AMD:
1412			switch (dev_id) {
1413			case FLASH_DEV_ID_AM29LV008BT:
1414				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1415				break;
1416			default:
1417				break;
1418			}
1419			break;
1420		case FLASH_MANUF_ID_ST:
1421			switch (dev_id) {
1422			case FLASH_DEV_ID_STM29008:
1423				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1424				break;
1425			default:
1426				break;
1427			}
1428			break;
1429		case FLASH_MANUF_ID_FUJITSU:
1430			switch (dev_id) {
1431			case FLASH_DEV_ID_MBM29LV008TA:
1432				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1433				break;
1434			}
1435			break;
1436		case FLASH_MANUF_ID_INTEL:
1437			switch (dev_id) {
1438			case FLASH_DEV_ID_I28LV00TAT:
1439				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1440				break;
1441			}
1442			break;
1443		case FLASH_MANUF_ID_MACRONIX:
1444			switch (dev_id) {
1445			case FLASH_DEV_ID_I28LV00TAT:
1446				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1447				break;
1448			}
1449			break;
1450		default:
1451			return FAIL_FIND_FLASH_ID;
1452		}
1453	}
1454
1455	if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN)
1456	      return FAIL_FIND_FLASH_ID;
1457
1458	asd_ha->hw_prof.flash.manuf = manuf_id;
1459	asd_ha->hw_prof.flash.dev_id = dev_id;
1460	asd_ha->hw_prof.flash.sec_prot = sec_prot;
1461	return 0;
1462}
1463