194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/******************************************************************************
294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Based on the r8180 driver, which is:
594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * This program is free software; you can redistribute it and/or modify it
794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * under the terms of version 2 of the GNU General Public License as
894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * published by the Free Software Foundation.
994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
1094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * This program is distributed in the hope that it will be useful, but WITHOUT
1194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * more details.
1494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
1594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * You should have received a copy of the GNU General Public License along with
1694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * this program; if not, write to the Free Software Foundation, Inc.,
1794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
1894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
1994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * The full GNU General Public License is included in this distribution in the
2094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * file called LICENSE.
2194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
2294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Contact Information:
2394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * wlanfae <wlanfae@realtek.com>
2494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger******************************************************************************/
2594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rtl_core.h"
2694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rtl_eeprom.h"
2794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
2849aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerstatic void eprom_cs(struct net_device *dev, short bit)
2994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
3094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (bit)
3194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		write_nic_byte(dev, EPROM_CMD,
32a44325f98563c39bc63311db7471b848153e49feLarry Finger			       (1 << EPROM_CS_SHIFT) |
3394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			       read_nic_byte(dev, EPROM_CMD));
3494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	else
35a44325f98563c39bc63311db7471b848153e49feLarry Finger		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)
36a44325f98563c39bc63311db7471b848153e49feLarry Finger			       & ~(1<<EPROM_CS_SHIFT));
3794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
3894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	udelay(EPROM_DELAY);
3994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
4094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
4194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
4249aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerstatic void eprom_ck_cycle(struct net_device *dev)
4394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
4494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	write_nic_byte(dev, EPROM_CMD,
45a44325f98563c39bc63311db7471b848153e49feLarry Finger		       (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD));
4694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	udelay(EPROM_DELAY);
4794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	write_nic_byte(dev, EPROM_CMD,
48a44325f98563c39bc63311db7471b848153e49feLarry Finger		       read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT));
4994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	udelay(EPROM_DELAY);
5094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
5194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
5294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
5349aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerstatic void eprom_w(struct net_device *dev, short bit)
5494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
5594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (bit)
56a44325f98563c39bc63311db7471b848153e49feLarry Finger		write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) |
57a44325f98563c39bc63311db7471b848153e49feLarry Finger			       read_nic_byte(dev, EPROM_CMD));
5894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	else
59a44325f98563c39bc63311db7471b848153e49feLarry Finger		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)
60a44325f98563c39bc63311db7471b848153e49feLarry Finger			       & ~(1<<EPROM_W_SHIFT));
6194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
6294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	udelay(EPROM_DELAY);
6394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
6494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
6594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
6649aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerstatic short eprom_r(struct net_device *dev)
6794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
6894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	short bit;
6994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
70a44325f98563c39bc63311db7471b848153e49feLarry Finger	bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT));
7194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	udelay(EPROM_DELAY);
7294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
7394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (bit)
7494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return 1;
7594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	return 0;
7694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
7794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
7849aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerstatic void eprom_send_bits_string(struct net_device *dev, short b[], int len)
7994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
8094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	int i;
8194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
82a44325f98563c39bc63311db7471b848153e49feLarry Finger	for (i = 0; i < len; i++) {
8394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		eprom_w(dev, b[i]);
8494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		eprom_ck_cycle(dev);
8594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
8694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
8794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
8894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingeru32 eprom_read(struct net_device *dev, u32 addr)
8994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
9094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	struct r8192_priv *priv = rtllib_priv(dev);
91a44325f98563c39bc63311db7471b848153e49feLarry Finger	short read_cmd[] = {1, 1, 0};
9294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	short addr_str[8];
9394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	int i;
9494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	int addr_len;
9594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u32 ret;
9694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
97a44325f98563c39bc63311db7471b848153e49feLarry Finger	ret = 0;
9894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	write_nic_byte(dev, EPROM_CMD,
99a44325f98563c39bc63311db7471b848153e49feLarry Finger		       (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT));
10094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	udelay(EPROM_DELAY);
10194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
102a44325f98563c39bc63311db7471b848153e49feLarry Finger	if (priv->epromtype == EEPROM_93C56) {
103a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[7] = addr & 1;
104a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[6] = addr & (1<<1);
105a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[5] = addr & (1<<2);
106a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[4] = addr & (1<<3);
107a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[3] = addr & (1<<4);
108a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[2] = addr & (1<<5);
109a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[1] = addr & (1<<6);
110a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[0] = addr & (1<<7);
111a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_len = 8;
112a44325f98563c39bc63311db7471b848153e49feLarry Finger	} else {
113a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[5] = addr & 1;
114a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[4] = addr & (1<<1);
115a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[3] = addr & (1<<2);
116a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[2] = addr & (1<<3);
117a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[1] = addr & (1<<4);
118a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_str[0] = addr & (1<<5);
119a44325f98563c39bc63311db7471b848153e49feLarry Finger		addr_len = 6;
12094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
12194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_cs(dev, 1);
12294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_ck_cycle(dev);
12394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_send_bits_string(dev, read_cmd, 3);
12494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_send_bits_string(dev, addr_str, addr_len);
12594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
12694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_w(dev, 0);
12794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
128a44325f98563c39bc63311db7471b848153e49feLarry Finger	for (i = 0; i < 16; i++) {
12994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		eprom_ck_cycle(dev);
13094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		ret |= (eprom_r(dev)<<(15-i));
13194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
13294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
13394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_cs(dev, 0);
13494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	eprom_ck_cycle(dev);
13594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
13694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	write_nic_byte(dev, EPROM_CMD,
13794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
13894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	return ret;
13994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
140