bcm-v4

[Specification

The PCMCIA core serves as a controller core just like the PCI core.

card information

The card information is built up as follows. The CIS always contains blocks of type/length/value tuples where type and length are bytes, and the length is the length of the payload of the tuple. There are functions for parsing this available in Linux.

The MAC address can be found in the CISTPL_FUNCE_LAN_NODE_ID of the FUNCE item.

Other parameters are found within the vendor defined element (0x80) which Broadcom builds up like the FUNCE element, meaning that the first byte of the element is again a subelement type. The subelement types can be found in this table:

subelement type

meaning

0x01

PCI vendor, device ID (possibly chip revision as well if 6 bytes are present instead of 4?)

0x02

Board revision

0x03

PA parameters (8 bytes)

0x04

OEM name (8 byte NUL-padded string, empty on my card)

0x05

default country code (1 byte)

0x06

antennas available (bitfield, 1 byte)

0x07

antenna gain

0x08

board flags (low 16 bits)

0x09

LED information (4 bytes)

The PA parameters are built up as follows:

byte

contents

0

lower byte of pa0b0

1

upper byte of pa0b0

2

lower byte of pa0b1

3

upper byte of pa0b1

4

lower byte of pa0b2

5

upper byte of pa0b2

6

Idle TSSI Target (cf. SPROM)

7

PA Max Power (cf. SPROM)

mapping

The PCMCIA core provides a 0x800 byte long mapping of the core registers. In Linux you can apparently only create a mapping of size 0x1000, but only 0x800 bytes of that are usable. Now, since each core register space is always 0x1000 bytes long this means that you can directly only access the first half of the register space. To access the second part, the memory segment register is used (see below). I set the window's AccessSpeed to 250, but am not sure what the correct value would be, it seemed to work fine.

registers

The PCMCIA core provides the following registers in the CIS, as everything in CIS they are each one byte long

Offset

Function

0x00

core control

0x80

alternative core control

0x2e

address 0

0x30

address 1

0x32

address 2

0x34

memory segment

0x36

SROM control

0x38

SROM data low

0x3a

SROM data high

0x3c

SROM address low

0x3e

SROM address low

Example code to write the memory segment register:

    req.Offset = 0x34;
    req.Action = CS_WRITE;
    req.Value = 1;
    pcmcia_access_configuration_register(pcmcia_device, &req);

address registers

The address registers are used to select the currently mapped core. To map a different core, write the core offset (the usual 0x18000000 + 0x1000*coreidx) to these registers as follows:

register

part of offset

address 0

(offset & 0x0000F000) >> 12

address 1

(offset & 0x00FF0000) >> 16

address 2

(offset & 0xFF000000) >> 24

memory segment register

This register just contains 0 or 1, 0 to access the lower half of the core register space and 1 to access the upper half.

SROM access

As described above, the configuration is actually stored in CIS so there's usually no need to access the SROM unless writing it. The SROM appears to contain 3 currently unknown words of data followed by the CIS information, the last byte is a CRC as in the regular SROM, but here the CRC covers the full 256 words.

SROM control register values:

Value

Meaning

0

idle

1

write

2

read

4

enable write

7

disable write

8

done

To execute an SROM command, write it to the SROM command register and wait until the done bit becomes set (up to 1000 tries).

In order to write the SROM, first enable writing by executing the enable write command.

Then, after waiting 500 milliseconds, write each word of the new contents to the SROM by setting the address low, address high, data low and data high registers and executing the write command. Delay 20 milliseconds after each write.

Finally disable writing again by executing the disable write command, delay 500 milliseconds afterwards.

You can read the SROM similarly, but of course no write enable/disable is necessary.

core control

This register (or the alternative one) is used to initialize the core. The alternative core control register must be used on any chip that is not a 4306 (can be determined the regular way, i.e. ChipCommon registers).

mask

meaning

0x80

core reset

0x04

core irq enable

0x01

core function enable

Instead of enabling interrupts through the PCI core, they have to be enabled through the PCMCIA core. To do this, or the core control (or the alternative core control) register with core irq enable and core function enable. More setup is not required for PCMCIA.


Exported/Archived from the wiki to HTML on 2016-10-27