blob: 97d9b3f49114143c74d69f63d6e427d4b8f7537f [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;
26
27 read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
Xenia Ragiadakoufcd9f352013-05-13 20:15:49 +030028 if (bit)
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030029 /* enable EPROM */
30 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020031 else
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030032 /* disable EPROM */
33 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020034
35 force_pci_posting(dev);
36 udelay(EPROM_DELAY);
37}
38
39
Ana Reyf6bd19e2014-03-13 12:36:37 +010040static void eprom_ck_cycle(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -020041{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030042 u8 cmdreg;
43
44 read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
45 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020046 force_pci_posting(dev);
47 udelay(EPROM_DELAY);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030048
49 read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
50 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020051 force_pci_posting(dev);
52 udelay(EPROM_DELAY);
53}
54
55
Chaitanya Hazarey6371f212014-05-27 15:35:09 -070056static void eprom_w(struct net_device *dev, short bit)
Jerry Chuang8fc85982009-11-03 07:17:11 -020057{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030058 u8 cmdreg;
59
60 read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
Xenia Ragiadakoufcd9f352013-05-13 20:15:49 +030061 if (bit)
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030062 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020063 else
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030064 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
Jerry Chuang8fc85982009-11-03 07:17:11 -020065
66 force_pci_posting(dev);
67 udelay(EPROM_DELAY);
68}
69
70
Ana Reyf6bd19e2014-03-13 12:36:37 +010071static short eprom_r(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -020072{
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030073 u8 bit;
Jerry Chuang8fc85982009-11-03 07:17:11 -020074
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030075 read_nic_byte_E(dev, EPROM_CMD, &bit);
Jerry Chuang8fc85982009-11-03 07:17:11 -020076 udelay(EPROM_DELAY);
77
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030078 if (bit & EPROM_R_BIT)
79 return 1;
80
Jerry Chuang8fc85982009-11-03 07:17:11 -020081 return 0;
82}
83
84
Ana Reyf6bd19e2014-03-13 12:36:37 +010085static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
Jerry Chuang8fc85982009-11-03 07:17:11 -020086{
87 int i;
88
Chaitanya Hazarey6371f212014-05-27 15:35:09 -070089 for (i = 0; i < len; i++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -020090 eprom_w(dev, b[i]);
91 eprom_ck_cycle(dev);
92 }
93}
94
95
96u32 eprom_read(struct net_device *dev, u32 addr)
97{
98 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey6371f212014-05-27 15:35:09 -070099 short read_cmd[] = {1, 1, 0};
Jerry Chuang8fc85982009-11-03 07:17:11 -0200100 short addr_str[8];
101 int i;
102 int addr_len;
103 u32 ret;
104
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700105 ret = 0;
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530106 /* enable EPROM programming */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200107 write_nic_byte_E(dev, EPROM_CMD,
108 (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
109 force_pci_posting(dev);
110 udelay(EPROM_DELAY);
111
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700112 if (priv->epromtype == EPROM_93c56) {
113 addr_str[7] = addr & 1;
114 addr_str[6] = addr & (1<<1);
115 addr_str[5] = addr & (1<<2);
116 addr_str[4] = addr & (1<<3);
117 addr_str[3] = addr & (1<<4);
118 addr_str[2] = addr & (1<<5);
119 addr_str[1] = addr & (1<<6);
120 addr_str[0] = addr & (1<<7);
121 addr_len = 8;
122 } else {
123 addr_str[5] = addr & 1;
124 addr_str[4] = addr & (1<<1);
125 addr_str[3] = addr & (1<<2);
126 addr_str[2] = addr & (1<<3);
127 addr_str[1] = addr & (1<<4);
128 addr_str[0] = addr & (1<<5);
129 addr_len = 6;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200130 }
131 eprom_cs(dev, 1);
132 eprom_ck_cycle(dev);
133 eprom_send_bits_string(dev, read_cmd, 3);
134 eprom_send_bits_string(dev, addr_str, addr_len);
135
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530136 /*
137 * keep chip pin D to low state while reading.
138 * I'm unsure if it is necessary, but anyway shouldn't hurt
139 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200140 eprom_w(dev, 0);
141
Chaitanya Hazarey6371f212014-05-27 15:35:09 -0700142 for (i = 0; i < 16; i++) {
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530143 /* eeprom needs a clk cycle between writing opcode&adr
144 * and reading data. (eeprom outs a dummy 0)
145 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200146 eprom_ck_cycle(dev);
147 ret |= (eprom_r(dev)<<(15-i));
148 }
149
150 eprom_cs(dev, 0);
151 eprom_ck_cycle(dev);
152
Sanjeev Sharma2ad99c52014-07-31 11:13:29 +0530153 /* disable EPROM programming */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200154 write_nic_byte_E(dev, EPROM_CMD,
155 (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
156 return ret;
157}