freebsd-nq/sys/i386/isa/pcic.h
1996-09-10 08:32:01 +00:00

182 lines
6.5 KiB
C

/*-
* TODO:
* [1] integrate into current if_ed.c
* [2] parse tuples to find out where to map the shared memory buffer,
* and what to write into the configuration register
* [3] move pcic-specific code into a separate module.
*
* Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
* if_ze.c
*
* Based on the Device driver for National Semiconductor DS8390 ethernet
* adapters by David Greenman. Modifications for PCMCIA by Keith Moore.
* Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
*
* Currently supports only the IBM Credit Card Adapter for Ethernet, but
* could probably work with other PCMCIA cards also, if it were modified
* to get the locations of the PCMCIA configuration option register (COR)
* by parsing the configuration tuples, rather than by hard-coding in
* the value expected by IBM's card.
*
* Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
*
* [1] _Local Area Network Credit Card Adapters Technical Reference_,
* IBM Corp., SC30-3585-00, part # 33G9243.
* [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
* [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
* Order Number 290423-002
* [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
* Interface Controller for Twisted Pair data sheet.
*
*
* Copyright (C) 1993, David Greenman. This software may be used, modified,
* copied, distributed, and sold, in both source and binary form provided
* that the above copyright and these terms are retained. Under no
* circumstances is the author responsible for the proper functioning
* of this software, nor does the author assume any responsibility
* for damages incurred with its use.
*/
#ifndef __PCIC_H__
#define __PCIC_H__
/*****************************************************************************
* pcmcia controller chip (PCIC) support *
* (eventually, move this to a separate file) *
*****************************************************************************/
#include <i386/isa/ic/i82365.h>
/*
* Each PCIC chip (82365SL or clone) can handle two card slots, and there
* can be up to four PCICs in a system. (On some machines, not all of the
* address lines are decoded, so a card may appear to be in more than one
* slot.)
*/
#define MAXSLOT 8
/*
* To access a register on the PCIC for a particular slot, you
* first write the correct OFFSET value for that slot in the
* INDEX register for the PCIC controller. You then read or write
* the value from or to the DATA register for that controller.
*
* The first pair of chips shares I/O addresses for DATA and INDEX,
* as does the second pair. (To the programmer, it looks like each
* pair is a single chip.) The i/o port addresses are hard-wired
* into the PCIC; so the following addresses should be valid for
* any machine that uses this chip.
*/
#define PCIC_INDEX_0 0x3E0 /* index reg, chips 0 and 1 */
#define PCIC_DATA_0 0x3E1 /* data register, chips 0 and 1 */
#define PCIC_INDEX_1 0x3E2 /* index reg, chips 1 and 2 */
#define PCIC_DATA_1 0x3E3 /* data register, chips 1 and 2 */
/*
* Given a slot number, calculate the INDEX and DATA registers
* to talk to that slot. OFFSET is added to the register number
* to address the registers for a particular slot.
*/
#define INDEX(slot) ((slot) < 4 ? PCIC_INDEX_0 : PCIC_INDEX_1)
#define DATA(slot) ((slot) < 4 ? PCIC_DATA_0 : PCIC_DATA_1)
#define OFFSET(slot) ((slot) % 4 * 0x40)
/*
* There are 5 sets (windows) of memory mapping registers on the PCIC chip
* for each slot, numbered 0..4.
*
* They start at 10/50 hex within the chip's register space (not system
* I/O space), and are eight addresses apart. These are actually pairs of
* 8-bit-wide registers (low byte first, then high byte) since the
* address fields are actually 12 bits long. The upper bits are used
* for other things like 8/16-bit select and wait states.
*
* Memory mapping registers include start/stop addresses to define the
* region to be mapped (in terms of system memory addresses), and
* an offset register to allow for translation from system space
* to card space. The lower 12 bits aren't included in these, so memory is
* mapped in 4K chunks.
*/
#define MEM_START_ADDR(window) (((window) * 0x08) + 0x10)
#define MEM_STOP_ADDR(window) (((window) * 0x08) + 0x12)
#define MEM_OFFSET(window) (((window) * 0x08) + 0x14)
/*
* this bit gets set in the address window enable register (PCIC_ADDRWINE)
* to enable a particular address window.
*/
#define MEM_ENABLE_BIT(window) ((1) << (window))
/*
* There are two i/o port addressing windows. I/O ports cannot be
* relocated within system i/o space (unless the card doesn't decode
* all of the address bits); unlike card memory, there is no address
* translation offset.
*/
#define IO_START_ADDR(window) ((window) ? PCIC_IO1_STL : PCIC_IO0_STL)
#define IO_STOP_ADDR(window) ((window) ? PCIC_IO1_SPL : PCIC_IO0_SPL)
#define IO_ENABLE_BIT(window) ((window) ? PCIC_IO1_EN : PCIC_IO0_EN)
#define IO_CS16_BIT(window) ((window) ? PCIC_IO1_CS16 : PCIC_IO0_CS16)
/*
* types of mapped memory
*/
enum memtype { COMMON, ATTRIBUTE };
/*
* read a byte from a pcic register for a particular slot
*/
static inline unsigned char
pcic_getb (int slot, int reg)
{
outb (INDEX(slot), OFFSET (slot) + reg);
return inb (DATA (slot));
}
/*
* write a byte to a pcic register for a particular slot
*/
static inline void
pcic_putb (int slot, int reg, unsigned char val)
{
outb (INDEX(slot), OFFSET (slot) + reg);
outb (DATA (slot), val);
}
/*
* read a word from a pcic register for a particular slot
*/
static inline unsigned short
pcic_getw (int slot, int reg)
{
return pcic_getb (slot, reg) | (pcic_getb (slot, reg+1) << 8);
}
/*
* write a word to a pcic register at a particular slot
*/
static inline void
pcic_putw (int slot, int reg, unsigned short val)
{
pcic_putb (slot, reg, val & 0xff);
pcic_putb (slot, reg + 1, (val >> 8) & 0xff);
}
void pcic_print_regs (int slot);
void pcic_map_memory (int slot, int window, unsigned long sys_addr,
unsigned long card_addr, unsigned long length,
enum memtype type, int width);
void pcic_unmap_memory (int slot, int window);
void pcic_map_io (int slot, int window, unsigned short base,
unsigned short length, unsigned short width);
#ifdef TEST
void pcic_unmap_io (int slot, int window);
#endif /* TEST */
void pcic_map_irq (int slot, int irq);
void pcic_power_on (int slot);
void pcic_power_off (int slot);
void pcic_reset (int slot);
#endif /* __PCIC_H__ */