patch-2.2.12 linux/drivers/net/fc/iph5526_novram.c
Next file: linux/drivers/net/fc/iph5526_scsi.h
Previous file: linux/drivers/net/fc/iph5526_ip.h
Back to the patch index
Back to the overall index
- Lines: 279
- Date:
Wed Aug 25 17:29:48 1999
- Orig file:
v2.2.11/linux/drivers/net/fc/iph5526_novram.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.2.11/linux/drivers/net/fc/iph5526_novram.c linux/drivers/net/fc/iph5526_novram.c
@@ -0,0 +1,278 @@
+/**********************************************************************
+ * Reading the NVRAM on the Interphase 5526 PCI Fibre Channel Card.
+ * All contents in this file : courtesy Interphase Corporation.
+ * Special thanks to Kevin Quick, kquick@iphase.com.
+ **********************************************************************/
+
+#define FF_MAGIC 0x4646
+#define DB_MAGIC 0x4442
+#define DL_MAGIC 0x444d
+
+
+#define CMD_LEN 9
+
+/***********
+ *
+ * Switches and defines for header files.
+ *
+ * The following defines are used to turn on and off
+ * various options in the header files. Primarily useful
+ * for debugging.
+ *
+ ***********/
+
+static const unsigned short novram_default[4] = {
+ FF_MAGIC,
+ DB_MAGIC,
+ DL_MAGIC,
+ 0 };
+
+
+/*
+ * a list of the commands that can be sent to the NOVRAM
+ */
+
+#define NR_EXTEND 0x100
+#define NR_WRITE 0x140
+#define NR_READ 0x180
+#define NR_ERASE 0x1c0
+
+#define EWDS 0x00
+#define WRAL 0x10
+#define ERAL 0x20
+#define EWEN 0x30
+
+/*
+ * Defines for the pins on the NOVRAM
+ */
+
+#define BIT(x) (1 << (x))
+
+#define NVDI_B 31
+#define NVDI BIT(NVDI_B)
+#define NVDO BIT(9)
+#define NVCE BIT(30)
+#define NVSK BIT(29)
+#define NV_MANUAL BIT(28)
+
+/***********
+ *
+ * Include files.
+ *
+ ***********/
+
+#define KeStallExecutionProcessor(x) {volatile int d, p;\
+ for (d=0; d<x; d++) for (p=0; p<10; p++);\
+ }
+
+
+/***********************
+ *
+ * This define ands the value and the current config register and puts
+ * the result in the config register
+ *
+ ***********************/
+
+#define CFG_AND(val) { volatile int t; \
+ t = readl(fi->n_r.ptr_novram_hw_control_reg); \
+ t &= (val); \
+ writel(t, fi->n_r.ptr_novram_hw_control_reg); \
+ }
+
+/***********************
+ *
+ * This define ors the value and the current config register and puts
+ * the result in the config register
+ *
+ ***********************/
+
+#define CFG_OR(val) { volatile int t; \
+ t = readl(fi->n_r.ptr_novram_hw_control_reg); \
+ t |= (val); \
+ writel(t, fi->n_r.ptr_novram_hw_control_reg); \
+ }
+
+/***********************
+ *
+ * Send a command to the NOVRAM, the command is in cmd.
+ *
+ * clear CE and SK. Then assert CE.
+ * Clock each of the command bits out in the correct order with SK
+ * exit with CE still asserted
+ *
+ ***********************/
+
+#define NVRAM_CMD(cmd) { int i; \
+ int c = cmd; \
+ CFG_AND(~(NVCE|NVSK)); \
+ CFG_OR(NVCE); \
+ for (i=0; i<CMD_LEN; i++) { \
+ NVRAM_CLKOUT((c & (1 << (CMD_LEN - 1))) ? 1 : 0);\
+ c <<= 1; } }
+
+/***********************
+ *
+ * clear the CE, this must be used after each command is complete
+ *
+ ***********************/
+
+#define NVRAM_CLR_CE CFG_AND(~NVCE)
+
+/***********************
+ *
+ * clock the data bit in bitval out to the NOVRAM. The bitval must be
+ * a 1 or 0, or the clockout operation is undefined
+ *
+ ***********************/
+
+#define NVRAM_CLKOUT(bitval) {\
+ CFG_AND(~NVDI); \
+ CFG_OR((bitval) << NVDI_B); \
+ KeStallExecutionProcessor(5);\
+ CFG_OR(NVSK); \
+ KeStallExecutionProcessor(5);\
+ CFG_AND( ~NVSK); \
+ }
+
+/***********************
+ *
+ * clock the data bit in and return a 1 or 0, depending on the value
+ * that was received from the NOVRAM
+ *
+ ***********************/
+
+#define NVRAM_CLKIN(val) {\
+ CFG_OR(NVSK); \
+ KeStallExecutionProcessor(5);\
+ CFG_AND(~NVSK); \
+ KeStallExecutionProcessor(5);\
+ val = (readl(fi->n_r.ptr_novram_hw_status_reg) & NVDO) ? 1 : 0; \
+ }
+
+/***********
+ *
+ * Function Prototypes
+ *
+ ***********/
+
+static int iph5526_nr_get(struct fc_info *fi, int addr);
+static void iph5526_nr_do_init(struct fc_info *fi);
+static void iph5526_nr_checksum(struct fc_info *fi);
+
+
+/*******************************************************************
+ *
+ * Local routine: iph5526_nr_do_init
+ * Purpose: initialize novram server
+ * Description:
+ *
+ * iph5526_nr_do_init reads the novram into the temporary holding place.
+ * A checksum is done on the area and the Magic Cookies are checked.
+ * If any of them are bad, the NOVRAM is initialized with the
+ * default values and a warning message is displayed.
+ *
+ *******************************************************************/
+
+static void iph5526_nr_do_init(struct fc_info *fi)
+{
+ int i;
+ unsigned short chksum = 0;
+ int bad = 0;
+
+ for (i=0; i<IPH5526_NOVRAM_SIZE; i++) {
+ fi->n_r.data[i] = iph5526_nr_get(fi, i);
+ chksum += fi->n_r.data[i];
+ }
+
+ if (chksum)
+ bad = 1;
+
+ if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 4] != FF_MAGIC)
+ bad = 1;
+ if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 3] != DB_MAGIC)
+ bad = 1;
+ if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 2] != DL_MAGIC)
+ bad = 1;
+
+ if (bad) {
+ for (i=0; i<IPH5526_NOVRAM_SIZE; i++) {
+ if (i < (IPH5526_NOVRAM_SIZE - 4)) {
+ fi->n_r.data[i] = 0xffff;
+ } else {
+ fi->n_r.data[i] = novram_default[i - (IPH5526_NOVRAM_SIZE - 4)];
+ }
+ }
+ iph5526_nr_checksum(fi);
+ }
+}
+
+
+/*******************************************************************
+ *
+ * Local routine: iph5526_nr_get
+ * Purpose: read a single word of NOVRAM
+ * Description:
+ *
+ * read the 16 bits that make up a word addr of the novram.
+ * The 16 bits of data that are read are returned as the return value
+ *
+ *******************************************************************/
+
+static int iph5526_nr_get(struct fc_info *fi, int addr)
+{
+ int i;
+ int t;
+ int val = 0;
+
+ CFG_OR(NV_MANUAL);
+
+ /*
+ * read the first bit that was clocked with the falling edge of the
+ * the last command data clock
+ */
+
+ NVRAM_CMD(NR_READ + addr);
+
+ /*
+ * Now read the rest of the bits, the next bit read is D1, then D2,
+ * and so on
+ */
+
+ val = 0;
+ for (i=0; i<16; i++) {
+ NVRAM_CLKIN(t);
+ val <<= 1;
+ val |= t;
+ }
+ NVRAM_CLR_CE;
+
+ CFG_OR(NVDI);
+ CFG_AND(~NV_MANUAL);
+
+ return(val);
+}
+
+
+
+
+/*******************************************************************
+ *
+ * Local routine: iph5526_nr_checksum
+ * Purpose: calculate novram checksum on fi->n_r.data
+ * Description:
+ *
+ * calculate a checksum for the novram on the image that is
+ * currently in fi->n_r.data
+ *
+ *******************************************************************/
+
+static void iph5526_nr_checksum(struct fc_info *fi)
+{
+ int i;
+ unsigned short chksum = 0;
+
+ for (i=0; i<(IPH5526_NOVRAM_SIZE - 1); i++)
+ chksum += fi->n_r.data[i];
+
+ fi->n_r.data[i] = -chksum;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)