blob: f35defc36fd9d53587c1fd1a86dc5ec0784f78f0 [file] [log] [blame]
Jerry Chuang8fc85982009-11-03 07:17:11 -02001/*
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.
Andrea Merello559a4c32013-08-26 13:53:30 +02006 Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com>
Jerry Chuang8fc85982009-11-03 07:17:11 -02007 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
Justin P. Mattockffae3052012-04-30 13:45:41 -070017 We want to thank the Authors of those projects and the Ndiswrapper
Jerry Chuang8fc85982009-11-03 07:17:11 -020018 project Authors.
19*/
20
21#include "r8180_93cx6.h"
22
Ana Reyf6bd19e2014-03-13 12:36:37 +010023static void eprom_cs(struct net_device *dev, short bit)
Jerry Chuang8fc85982009-11-03 07:17:11 -020024{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030025 u8 cmdreg;
Salah Triki2fe92622016-05-04 04:42:40 +010026 int err;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030027
Salah Triki2fe92622016-05-04 04:42:40 +010028 err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
29 if (err)
30 return;
Xenia Ragiadakoufcd9f352013-05-13 20:15:49 +030031 if (bit)
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030032 /* enable EPROM */
33 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020034 else
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030035 /* disable EPROM */
36 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020037
38 force_pci_posting(dev);
39 udelay(EPROM_DELAY);
40}
41
42
Ana Reyf6bd19e2014-03-13 12:36:37 +010043static void eprom_ck_cycle(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -020044{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030045 u8 cmdreg;
Salah Triki2fe92622016-05-04 04:42:40 +010046 int err;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030047
Salah Triki2fe92622016-05-04 04:42:40 +010048 err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
49 if (err)
50 return;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030051 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020052 force_pci_posting(dev);
53 udelay(EPROM_DELAY);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030054
55 read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
56 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020057 force_pci_posting(dev);
58 udelay(EPROM_DELAY);
59}
60
61
Chaitanya Hazarey6371f212014-05-27 15:35:09 -070062static void eprom_w(struct net_device *dev, short bit)
Jerry Chuang8fc85982009-11-03 07:17:11 -020063{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030064 u8 cmdreg;
Salah Triki2fe92622016-05-04 04:42:40 +010065 int err;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030066
Salah Triki2fe92622016-05-04 04:42:40 +010067 err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
68 if (err)
69 return;
Xenia Ragiadakoufcd9f352013-05-13 20:15:49 +030070 if (bit)
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030071 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020072 else
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030073 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020074
75 force_pci_posting(dev);
76 udelay(EPROM_DELAY);
77}
78
79
Ana Reyf6bd19e2014-03-13 12:36:37 +010080static short eprom_r(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -020081{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030082 u8 bit;
Salah Triki2fe92622016-05-04 04:42:40 +010083 int err;
Jerry Chuang8fc85982009-11-03 07:17:11 -020084
Salah Triki2fe92622016-05-04 04:42:40 +010085 err = read_nic_byte_E(dev, EPROM_CMD, &bit);
86 if (err)
87 return err;
88
Jerry Chuang8fc85982009-11-03 07:17:11 -020089 udelay(EPROM_DELAY);
90
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030091 if (bit & EPROM_R_BIT)
92 return 1;
93
Jerry Chuang8fc85982009-11-03 07:17:11 -020094 return 0;
95}
96
97
Ana Reyf6bd19e2014-03-13 12:36:37 +010098static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
Jerry Chuang8fc85982009-11-03 07:17:11 -020099{
100 int i;
101
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700102 for (i = 0; i < len; i++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200103 eprom_w(dev, b[i]);
104 eprom_ck_cycle(dev);
105 }
106}
107
108
Salah Triki6ceb65b2016-05-04 04:42:41 +0100109int eprom_read(struct net_device *dev, u32 addr)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200110{
111 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700112 short read_cmd[] = {1, 1, 0};
Jerry Chuang8fc85982009-11-03 07:17:11 -0200113 short addr_str[8];
114 int i;
115 int addr_len;
116 u32 ret;
Salah Triki6ceb65b2016-05-04 04:42:41 +0100117 int err;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200118
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700119 ret = 0;
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530120 /* enable EPROM programming */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200121 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
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700126 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;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200144 }
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
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530150 /*
151 * keep chip pin D to low state while reading.
152 * I'm unsure if it is necessary, but anyway shouldn't hurt
153 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200154 eprom_w(dev, 0);
155
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700156 for (i = 0; i < 16; i++) {
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530157 /* eeprom needs a clk cycle between writing opcode&adr
158 * and reading data. (eeprom outs a dummy 0)
159 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200160 eprom_ck_cycle(dev);
Salah Triki6ceb65b2016-05-04 04:42:41 +0100161 err = eprom_r(dev);
162 if (err < 0)
163 return err;
164
165 ret |= err<<(15-i);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200166 }
167
168 eprom_cs(dev, 0);
169 eprom_ck_cycle(dev);
170
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530171 /* disable EPROM programming */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200172 write_nic_byte_E(dev, EPROM_CMD,
173 (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
174 return ret;
175}