cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

r8180_93cx6.c (3772B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  This files contains card eeprom (93c46 or 93c56) programming routines,
      4 *  memory is addressed by 16 bits words.
      5 *
      6 *  This is part of rtl8180 OpenSource driver.
      7 *  Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
      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
     23static 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
     42static void eprom_ck_cycle(struct net_device *dev)
     43{
     44	u8 cmdreg;
     45	int err;
     46
     47	err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
     48	if (err)
     49		return;
     50	write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
     51	force_pci_posting(dev);
     52	udelay(EPROM_DELAY);
     53
     54	read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
     55	write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
     56	force_pci_posting(dev);
     57	udelay(EPROM_DELAY);
     58}
     59
     60static void eprom_w(struct net_device *dev, short bit)
     61{
     62	u8 cmdreg;
     63	int err;
     64
     65	err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
     66	if (err)
     67		return;
     68	if (bit)
     69		write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
     70	else
     71		write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
     72
     73	force_pci_posting(dev);
     74	udelay(EPROM_DELAY);
     75}
     76
     77static short eprom_r(struct net_device *dev)
     78{
     79	u8 bit;
     80	int err;
     81
     82	err = read_nic_byte_E(dev, EPROM_CMD, &bit);
     83	if (err)
     84		return err;
     85
     86	udelay(EPROM_DELAY);
     87
     88	if (bit & EPROM_R_BIT)
     89		return 1;
     90
     91	return 0;
     92}
     93
     94static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
     95{
     96	int i;
     97
     98	for (i = 0; i < len; i++) {
     99		eprom_w(dev, b[i]);
    100		eprom_ck_cycle(dev);
    101	}
    102}
    103
    104int eprom_read(struct net_device *dev, u32 addr)
    105{
    106	struct r8192_priv *priv = ieee80211_priv(dev);
    107	short read_cmd[] = {1, 1, 0};
    108	short addr_str[8];
    109	int i;
    110	int addr_len;
    111	u32 ret;
    112	int err;
    113
    114	ret = 0;
    115	/* enable EPROM programming */
    116	write_nic_byte_E(dev, EPROM_CMD,
    117		       (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT));
    118	force_pci_posting(dev);
    119	udelay(EPROM_DELAY);
    120
    121	if (priv->epromtype == EPROM_93c56) {
    122		addr_str[7] = addr & 1;
    123		addr_str[6] = addr & BIT(1);
    124		addr_str[5] = addr & BIT(2);
    125		addr_str[4] = addr & BIT(3);
    126		addr_str[3] = addr & BIT(4);
    127		addr_str[2] = addr & BIT(5);
    128		addr_str[1] = addr & BIT(6);
    129		addr_str[0] = addr & BIT(7);
    130		addr_len = 8;
    131	} else {
    132		addr_str[5] = addr & 1;
    133		addr_str[4] = addr & BIT(1);
    134		addr_str[3] = addr & BIT(2);
    135		addr_str[2] = addr & BIT(3);
    136		addr_str[1] = addr & BIT(4);
    137		addr_str[0] = addr & BIT(5);
    138		addr_len = 6;
    139	}
    140	eprom_cs(dev, 1);
    141	eprom_ck_cycle(dev);
    142	eprom_send_bits_string(dev, read_cmd, 3);
    143	eprom_send_bits_string(dev, addr_str, addr_len);
    144
    145	/*
    146	 * keep chip pin D to low state while reading.
    147	 * I'm unsure if it is necessary, but anyway shouldn't hurt
    148	 */
    149	eprom_w(dev, 0);
    150
    151	for (i = 0; i < 16; i++) {
    152		/* eeprom needs a clk cycle between writing opcode&adr
    153		 * and reading data. (eeprom outs a dummy 0)
    154		 */
    155		eprom_ck_cycle(dev);
    156		err = eprom_r(dev);
    157		if (err < 0)
    158			return err;
    159
    160		ret |= err << (15 - i);
    161	}
    162
    163	eprom_cs(dev, 0);
    164	eprom_ck_cycle(dev);
    165
    166	/* disable EPROM programming */
    167	write_nic_byte_E(dev, EPROM_CMD,
    168		       (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT));
    169	return ret;
    170}