• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    This files contains card eeprom (93c46 or 93c56) programming routines,
3    memory is addressed by 16 bits words.
4 
5    This is part of rtl8180 OpenSource driver.
6    Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
7    Released under the terms of GPL (General Public Licence)
8 
9    Parts of this driver are based on the GPL part of the
10    official realtek driver.
11 
12    Parts of this driver are based on the rtl8180 driver skeleton
13    from Patric Schenke & Andres Salomon.
14 
15    Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16 
17    We want to thank the Authors of those projects and the Ndiswrapper
18    project Authors.
19 */
20 
21 #include "r8180_93cx6.h"
22 
eprom_cs(struct net_device * dev,short bit)23 static void eprom_cs(struct net_device *dev, short bit)
24 {
25 	u8 cmdreg;
26 	int err;
27 
28 	err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
29 	if (err)
30 		return;
31 	if (bit)
32 		/* enable EPROM */
33 		write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT);
34 	else
35 		/* disable EPROM */
36 		write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT);
37 
38 	force_pci_posting(dev);
39 	udelay(EPROM_DELAY);
40 }
41 
42 
eprom_ck_cycle(struct net_device * dev)43 static void eprom_ck_cycle(struct net_device *dev)
44 {
45 	u8 cmdreg;
46 	int err;
47 
48 	err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
49 	if (err)
50 		return;
51 	write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
52 	force_pci_posting(dev);
53 	udelay(EPROM_DELAY);
54 
55 	read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
56 	write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
57 	force_pci_posting(dev);
58 	udelay(EPROM_DELAY);
59 }
60 
61 
eprom_w(struct net_device * dev,short bit)62 static void eprom_w(struct net_device *dev, short bit)
63 {
64 	u8 cmdreg;
65 	int err;
66 
67 	err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
68 	if (err)
69 		return;
70 	if (bit)
71 		write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
72 	else
73 		write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
74 
75 	force_pci_posting(dev);
76 	udelay(EPROM_DELAY);
77 }
78 
79 
eprom_r(struct net_device * dev)80 static short eprom_r(struct net_device *dev)
81 {
82 	u8 bit;
83 	int err;
84 
85 	err = read_nic_byte_E(dev, EPROM_CMD, &bit);
86 	if (err)
87 		return err;
88 
89 	udelay(EPROM_DELAY);
90 
91 	if (bit & EPROM_R_BIT)
92 		return 1;
93 
94 	return 0;
95 }
96 
97 
eprom_send_bits_string(struct net_device * dev,short b[],int len)98 static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
99 {
100 	int i;
101 
102 	for (i = 0; i < len; i++) {
103 		eprom_w(dev, b[i]);
104 		eprom_ck_cycle(dev);
105 	}
106 }
107 
108 
eprom_read(struct net_device * dev,u32 addr)109 int eprom_read(struct net_device *dev, u32 addr)
110 {
111 	struct r8192_priv *priv = ieee80211_priv(dev);
112 	short read_cmd[] = {1, 1, 0};
113 	short addr_str[8];
114 	int i;
115 	int addr_len;
116 	u32 ret;
117 	int err;
118 
119 	ret = 0;
120 	/* enable EPROM programming */
121 	write_nic_byte_E(dev, EPROM_CMD,
122 		       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
123 	force_pci_posting(dev);
124 	udelay(EPROM_DELAY);
125 
126 	if (priv->epromtype == EPROM_93c56) {
127 		addr_str[7] = addr & 1;
128 		addr_str[6] = addr & (1<<1);
129 		addr_str[5] = addr & (1<<2);
130 		addr_str[4] = addr & (1<<3);
131 		addr_str[3] = addr & (1<<4);
132 		addr_str[2] = addr & (1<<5);
133 		addr_str[1] = addr & (1<<6);
134 		addr_str[0] = addr & (1<<7);
135 		addr_len = 8;
136 	} else {
137 		addr_str[5] = addr & 1;
138 		addr_str[4] = addr & (1<<1);
139 		addr_str[3] = addr & (1<<2);
140 		addr_str[2] = addr & (1<<3);
141 		addr_str[1] = addr & (1<<4);
142 		addr_str[0] = addr & (1<<5);
143 		addr_len = 6;
144 	}
145 	eprom_cs(dev, 1);
146 	eprom_ck_cycle(dev);
147 	eprom_send_bits_string(dev, read_cmd, 3);
148 	eprom_send_bits_string(dev, addr_str, addr_len);
149 
150 	/*
151 	 * keep chip pin D to low state while reading.
152 	 * I'm unsure if it is necessary, but anyway shouldn't hurt
153 	 */
154 	eprom_w(dev, 0);
155 
156 	for (i = 0; i < 16; i++) {
157 		/* eeprom needs a clk cycle between writing opcode&adr
158 		 * and reading data. (eeprom outs a dummy 0)
159 		 */
160 		eprom_ck_cycle(dev);
161 		err = eprom_r(dev);
162 		if (err < 0)
163 			return err;
164 
165 		ret |= err<<(15-i);
166 	}
167 
168 	eprom_cs(dev, 0);
169 	eprom_ck_cycle(dev);
170 
171 	/* disable EPROM programming */
172 	write_nic_byte_E(dev, EPROM_CMD,
173 		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
174 	return ret;
175 }
176