iPXE
3c509.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/io.h>
#include <unistd.h>
#include <ipxe/device.h>
#include <ipxe/isa.h>
#include "3c509.h"

Go to the source code of this file.

Data Structures

struct  t509_device
 A 3c509 device. More...

Functions

 FILE_LICENCE (BSD2)
static void t509bus_remove (struct root_device *rootdev)
 Remove 3c509 root bus.
static void t509_set_drvdata (struct t509_device *t509, void *priv)
 Set 3c509 driver-private data.
static void * t509_get_drvdata (struct t509_device *t509)
 Get 3c509 driver-private data.
static void t509_set_id_port (void)
static void t509_wait_for_id_sequence (void)
static void t509_global_reset (void)
static void t509_reset_tag (void)
static void t509_set_tag (uint8_t tag)
static void t509_select_tag (uint8_t tag)
static void t509_activate (uint16_t ioaddr)
static void t509_deactivate_and_reset_tag (uint16_t ioaddr)
static void t509_load_eeprom_word (uint8_t offset)
static int t509_find_id_port (void)
static void t509_send_id_sequence (void)
static uint16_t t509_id_read_eeprom (int offset)
static int t509_isolate (void)
static void activate_t509_device (struct t509_device *t509)
static void deactivate_t509_device (struct t509_device *t509)
static int legacy_t509_probe (struct nic *nic, void *hwdev)
static void legacy_t509_disable (struct nic *nic, void *hwdev)
static void legacy_t509_set_drvdata (void *hwdev, void *priv)
static void * legacy_t509_get_drvdata (void *hwdev)
static int t509_probe (struct t509_device *t509)
 Probe a 3c509 device.
static void t509_remove (struct t509_device *t509)
 Remove a 3c509 device.
static int t509bus_probe (struct root_device *rootdev)
 Probe 3c509 root bus.
 ISA_ROM ("3c509", "3c509")

Variables

static unsigned int t509_id_port = 0
static unsigned int t509_max_tag = 0
static struct root_driver t509_root_driver
 3c509 bus root device driver
struct root_device t509_root_device __root_device
 3c509 bus root device

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( BSD2 )

◆ t509bus_remove()

void t509bus_remove ( struct root_device * rootdev)
static

Remove 3c509 root bus.

Parameters
rootdev3c509 bus root device

Definition at line 408 of file 3c509.c.

408 {
409 struct t509_device *t509;
410 struct t509_device *tmp;
411
412 list_for_each_entry_safe ( t509, tmp, &rootdev->dev.children,
413 dev.siblings ) {
414 t509_remove ( t509 );
415 list_del ( &t509->dev.siblings );
416 free ( t509 );
417 }
418}
static void t509_remove(struct t509_device *t509)
Remove a 3c509 device.
Definition 3c509.c:327
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
struct device dev
Device chain.
Definition device.h:103
A 3c509 device.
Definition 3c509.c:40
struct device dev
Generic device.
Definition 3c509.c:42

References device::children, root_device::dev, t509_device::dev, free, list_del, list_for_each_entry_safe, device::siblings, t509_remove(), and tmp.

Referenced by t509bus_probe().

◆ t509_set_drvdata()

void t509_set_drvdata ( struct t509_device * t509,
void * priv )
inlinestatic

Set 3c509 driver-private data.

Parameters
t5093c509 device
privPrivate data

Definition at line 61 of file 3c509.c.

61 {
62 t509->priv = priv;
63}
void * priv
Driver-private data.
Definition 3c509.c:52
static struct tlan_private * priv
Definition tlan.c:225

References priv, and t509_device::priv.

Referenced by legacy_t509_set_drvdata().

◆ t509_get_drvdata()

void * t509_get_drvdata ( struct t509_device * t509)
inlinestatic

Get 3c509 driver-private data.

Parameters
t5093c509 device
Return values
privPrivate data

Definition at line 71 of file 3c509.c.

71 {
72 return t509->priv;
73}

References t509_device::priv.

Referenced by legacy_t509_get_drvdata().

◆ t509_set_id_port()

void t509_set_id_port ( void )
inlinestatic

Definition at line 80 of file 3c509.c.

80 {
81 outb ( 0x00, t509_id_port );
82}
static unsigned int t509_id_port
Definition 3c509.c:36
#define outb(data, io_addr)
Definition io.h:310

References outb, and t509_id_port.

Referenced by t509_find_id_port(), and t509_send_id_sequence().

◆ t509_wait_for_id_sequence()

void t509_wait_for_id_sequence ( void )
inlinestatic

Definition at line 84 of file 3c509.c.

84 {
85 outb ( 0x00, t509_id_port );
86}

References outb, and t509_id_port.

Referenced by deactivate_t509_device(), t509_isolate(), t509_send_id_sequence(), and t509bus_probe().

◆ t509_global_reset()

void t509_global_reset ( void )
inlinestatic

Definition at line 88 of file 3c509.c.

88 {
89 outb ( 0xc0, t509_id_port );
90}

References outb, and t509_id_port.

◆ t509_reset_tag()

void t509_reset_tag ( void )
inlinestatic

Definition at line 92 of file 3c509.c.

92 {
93 outb ( 0xd0, t509_id_port );
94}

References outb, and t509_id_port.

Referenced by t509_isolate().

◆ t509_set_tag()

void t509_set_tag ( uint8_t tag)
inlinestatic

Definition at line 96 of file 3c509.c.

96 {
97 outb ( 0xd0 | tag, t509_id_port );
98}
uint64_t tag
Identity tag.
Definition edd.h:1

References outb, t509_id_port, and tag.

Referenced by deactivate_t509_device(), and t509_isolate().

◆ t509_select_tag()

void t509_select_tag ( uint8_t tag)
inlinestatic

Definition at line 100 of file 3c509.c.

100 {
101 outb ( 0xd8 | tag, t509_id_port );
102}

References outb, t509_id_port, and tag.

Referenced by activate_t509_device(), deactivate_t509_device(), t509_isolate(), and t509bus_probe().

◆ t509_activate()

void t509_activate ( uint16_t ioaddr)
inlinestatic

Definition at line 104 of file 3c509.c.

104 {
105 outb ( 0xe0 | ( ioaddr >> 4 ), t509_id_port );
106}
static unsigned long ioaddr
Definition davicom.c:129

References ioaddr, outb, and t509_id_port.

Referenced by activate_t509_device().

◆ t509_deactivate_and_reset_tag()

void t509_deactivate_and_reset_tag ( uint16_t ioaddr)
inlinestatic

Definition at line 108 of file 3c509.c.

108 {
110}
#define GLOBAL_RESET
Definition 3c509.h:209
#define EP_COMMAND
Definition 3c509.h:109

References EP_COMMAND, GLOBAL_RESET, ioaddr, and outb.

Referenced by deactivate_t509_device().

◆ t509_load_eeprom_word()

void t509_load_eeprom_word ( uint8_t offset)
inlinestatic

Definition at line 112 of file 3c509.c.

112 {
113 outb ( 0x80 | offset, t509_id_port );
114}
uint16_t offset
Offset to command line.
Definition bzimage.h:3

References offset, outb, and t509_id_port.

Referenced by t509_id_read_eeprom().

◆ t509_find_id_port()

int t509_find_id_port ( void )
inlinestatic

Definition at line 120 of file 3c509.c.

120 {
121
126 /* See if anything's listening */
127 outb ( 0xff, t509_id_port );
128 if ( inb ( t509_id_port ) & 0x01 ) {
129 /* Found a suitable port */
130 DBG ( "T509 using ID port at %04x\n", t509_id_port );
131 return 0;
132 }
133 }
134 /* No id port available */
135 DBG ( "T509 found no available ID port\n" );
136 return -ENOENT;
137}
static void t509_set_id_port(void)
Definition 3c509.c:80
#define EP_ID_PORT_INC
Definition 3c509.h:55
#define EP_ID_PORT_START
Definition 3c509.h:54
#define EP_ID_PORT_END
Definition 3c509.h:56
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define ENOENT
No such file or directory.
Definition errno.h:515
#define inb(io_addr)
Definition io.h:283

References DBG, ENOENT, EP_ID_PORT_END, EP_ID_PORT_INC, EP_ID_PORT_START, inb, outb, t509_id_port, and t509_set_id_port().

Referenced by t509_isolate().

◆ t509_send_id_sequence()

void t509_send_id_sequence ( void )
static

Definition at line 143 of file 3c509.c.

143 {
144 unsigned short lrs_state, i;
145
147 /* Reset IDS on cards */
149 lrs_state = 0xff;
150 for ( i = 0; i < 255; i++ ) {
151 outb ( lrs_state, t509_id_port );
152 lrs_state <<= 1;
153 lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
154 }
155}
static void t509_wait_for_id_sequence(void)
Definition 3c509.c:84

References outb, t509_id_port, t509_set_id_port(), and t509_wait_for_id_sequence().

Referenced by activate_t509_device(), deactivate_t509_device(), t509_isolate(), and t509bus_probe().

◆ t509_id_read_eeprom()

uint16_t t509_id_read_eeprom ( int offset)
static

Definition at line 169 of file 3c509.c.

169 {
170 int i, data = 0;
171
173 /* Do we really need this wait? Won't be noticeable anyway */
174 udelay(10000);
175
176 for ( i = 0; i < 16; i++ ) {
177 data = ( data << 1 ) | ( inw ( t509_id_port ) & 1 );
178 }
179 return data;
180}
static void t509_load_eeprom_word(uint8_t offset)
Definition 3c509.c:112
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define inw(io_addr)
Definition io.h:292
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61

References data, inw, offset, t509_id_port, t509_load_eeprom_word(), and udelay().

Referenced by t509_isolate(), and t509bus_probe().

◆ t509_isolate()

int t509_isolate ( void )
static

Definition at line 186 of file 3c509.c.

186 {
187 unsigned int i;
188 uint16_t contend[3];
189 int rc;
190
191 /* Find a suitable ID port */
192 if ( ( rc = t509_find_id_port() ) != 0 )
193 return rc;
194
195 while ( 1 ) {
196
197 /* All cards are in ID_WAIT state each time we go
198 * through this loop.
199 */
200
201 /* Send the ID sequence */
203
204 /* First time through, reset all tags. On subsequent
205 * iterations, kill off any already-tagged cards
206 */
207 if ( t509_max_tag == 0 ) {
209 } else {
210 t509_select_tag ( 0 );
211 }
212
213 /* Read the manufacturer ID, to see if there are any
214 * more cards
215 */
217 DBG ( "T509 saw %s signs of life\n",
218 t509_max_tag ? "no further" : "no" );
219 break;
220 }
221
222 /* Perform contention selection on the MAC address */
223 for ( i = 0 ; i < 3 ; i++ ) {
224 contend[i] = t509_id_read_eeprom ( i );
225 }
226
227 /* Only one device will still be left alive. Tag it. */
228 ++t509_max_tag;
229 DBG ( "T509 found card %04x%04x%04x, assigning tag %02x\n",
230 contend[0], contend[1], contend[2], t509_max_tag );
232
233 /* Return all cards back to ID_WAIT state */
235 }
236
237 DBG ( "T509 found %d cards using ID port %04x\n",
239 return 0;
240}
static unsigned int t509_max_tag
Definition 3c509.c:37
static void t509_set_tag(uint8_t tag)
Definition 3c509.c:96
static uint16_t t509_id_read_eeprom(int offset)
Definition 3c509.c:169
static int t509_find_id_port(void)
Definition 3c509.c:120
static void t509_send_id_sequence(void)
Definition 3c509.c:143
static void t509_reset_tag(void)
Definition 3c509.c:92
static void t509_select_tag(uint8_t tag)
Definition 3c509.c:100
#define MFG_ID
Definition 3c509.h:364
#define EEPROM_MFG_ID
Definition 3c509.h:91
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11

References DBG, EEPROM_MFG_ID, MFG_ID, rc, t509_find_id_port(), t509_id_port, t509_id_read_eeprom(), t509_max_tag, t509_reset_tag(), t509_select_tag(), t509_send_id_sequence(), t509_set_tag(), and t509_wait_for_id_sequence().

Referenced by t509bus_probe().

◆ activate_t509_device()

void activate_t509_device ( struct t509_device * t509)
inlinestatic

Definition at line 250 of file 3c509.c.

250 {
252 t509_select_tag ( t509->tag );
253 t509_activate ( t509->ioaddr );
254 DBG ( "T509 activated device %02x at ioaddr %04x\n",
255 t509->tag, t509->ioaddr );
256}
static void t509_activate(uint16_t ioaddr)
Definition 3c509.c:104
unsigned int tag
Tag.
Definition 3c509.c:44
uint16_t ioaddr
I/O address.
Definition 3c509.c:46

References DBG, t509_device::ioaddr, t509_activate(), t509_select_tag(), t509_send_id_sequence(), and t509_device::tag.

Referenced by legacy_t509_probe().

◆ deactivate_t509_device()

void deactivate_t509_device ( struct t509_device * t509)
inlinestatic

Definition at line 265 of file 3c509.c.

265 {
267 udelay ( 1000 );
269 t509_select_tag ( 0 );
270 t509_set_tag ( t509->tag );
272 DBG ( "T509 deactivated device at %04x and re-tagged as %02x\n",
273 t509->ioaddr, t509->tag );
274}
static void t509_deactivate_and_reset_tag(uint16_t ioaddr)
Definition 3c509.c:108

References DBG, t509_device::ioaddr, t509_deactivate_and_reset_tag(), t509_select_tag(), t509_send_id_sequence(), t509_set_tag(), t509_wait_for_id_sequence(), t509_device::tag, and udelay().

Referenced by legacy_t509_disable().

◆ legacy_t509_probe()

int legacy_t509_probe ( struct nic * nic,
void * hwdev )
static

Definition at line 280 of file 3c509.c.

280 {
281 struct t509_device *t509 = hwdev;
282
283 /* We could change t509->ioaddr if we wanted to */
284 activate_t509_device ( t509 );
285 nic->ioaddr = t509->ioaddr;
286
287 /* Hand off to generic t5x9 probe routine */
289}
static void activate_t509_device(struct t509_device *t509)
Definition 3c509.c:250
#define PROD_ID
Definition 3c509.h:365
int t5x9_probe(struct nic *nic, uint16_t prod_id_check, uint16_t prod_id_mask)
Definition 3c5x9.c:342
#define ISA_PROD_ID(product)
Definition isa_ids.h:45
#define ISA_PROD_ID_MASK
Definition isa_ids.h:44
Definition nic.h:49
unsigned int ioaddr
Definition nic.h:55

References activate_t509_device(), nic::ioaddr, t509_device::ioaddr, ISA_PROD_ID, ISA_PROD_ID_MASK, PROD_ID, and t5x9_probe().

Referenced by t509_probe().

◆ legacy_t509_disable()

void legacy_t509_disable ( struct nic * nic,
void * hwdev )
static

Definition at line 291 of file 3c509.c.

291 {
292 struct t509_device *t509 = hwdev;
293
294 t5x9_disable ( nic );
295 deactivate_t509_device ( t509 );
296}
static void deactivate_t509_device(struct t509_device *t509)
Definition 3c509.c:265
void t5x9_disable(struct nic *nic)
Definition 3c5x9.c:40

References deactivate_t509_device(), and t5x9_disable().

Referenced by t509_probe(), and t509_remove().

◆ legacy_t509_set_drvdata()

void legacy_t509_set_drvdata ( void * hwdev,
void * priv )
inlinestatic

Definition at line 298 of file 3c509.c.

298 {
299 t509_set_drvdata ( hwdev, priv );
300}
static void t509_set_drvdata(struct t509_device *t509, void *priv)
Set 3c509 driver-private data.
Definition 3c509.c:61

References priv, and t509_set_drvdata().

Referenced by t509_probe().

◆ legacy_t509_get_drvdata()

void * legacy_t509_get_drvdata ( void * hwdev)
inlinestatic

Definition at line 302 of file 3c509.c.

302 {
303 return t509_get_drvdata ( hwdev );
304}
static void * t509_get_drvdata(struct t509_device *t509)
Get 3c509 driver-private data.
Definition 3c509.c:71

References t509_get_drvdata().

Referenced by t509_remove().

◆ t509_probe()

int t509_probe ( struct t509_device * t509)
static

Probe a 3c509 device.

Parameters
t5093c509 device
Return values
rcReturn status code

Searches for a driver for the 3c509 device. If a driver is found, its probe() routine is called.

Definition at line 315 of file 3c509.c.

315 {
316 DBG ( "Adding 3c509 device %02x (I/O %04x)\n",
317 t509->tag, t509->ioaddr );
318 return legacy_probe ( t509, legacy_t509_set_drvdata, &t509->dev,
320}
static void legacy_t509_set_drvdata(void *hwdev, void *priv)
Definition 3c509.c:298
static int legacy_t509_probe(struct nic *nic, void *hwdev)
Definition 3c509.c:280
static void legacy_t509_disable(struct nic *nic, void *hwdev)
Definition 3c509.c:291
int legacy_probe(void *hwdev, void(*set_drvdata)(void *hwdev, void *priv), struct device *dev, int(*probe)(struct nic *nic, void *hwdev), void(*disable)(struct nic *nic, void *hwdev), size_t fake_bss_len)
Definition legacy.c:83

References DBG, t509_device::dev, t509_device::ioaddr, legacy_probe(), legacy_t509_disable(), legacy_t509_probe(), legacy_t509_set_drvdata(), and t509_device::tag.

Referenced by t509bus_probe().

◆ t509_remove()

void t509_remove ( struct t509_device * t509)
static

Remove a 3c509 device.

Parameters
t5093c509 device

Definition at line 327 of file 3c509.c.

327 {
329 DBG ( "Removed 3c509 device %02x\n", t509->tag );
330}
static void * legacy_t509_get_drvdata(void *hwdev)
Definition 3c509.c:302
void legacy_remove(void *hwdev, void *(*get_drvdata)(void *hwdev), void(*disable)(struct nic *nic, void *hwdev))
Definition legacy.c:160

References DBG, legacy_remove(), legacy_t509_disable(), legacy_t509_get_drvdata(), and t509_device::tag.

Referenced by t509bus_remove().

◆ t509bus_probe()

int t509bus_probe ( struct root_device * rootdev)
static

Probe 3c509 root bus.

Parameters
rootdev3c509 bus root device

Scans the 3c509 bus for devices and registers all devices it can find.

Definition at line 340 of file 3c509.c.

340 {
341 struct t509_device *t509 = NULL;
342 unsigned int tag;
343 unsigned int iobase;
344 int rc;
345
346 /* Perform isolation and tagging */
347 if ( ( rc = t509_isolate() ) != 0 )
348 return rc;
349
350 for ( tag = 1 ; tag <= t509_max_tag ; tag++ ) {
351 /* Allocate struct t509_device */
352 if ( ! t509 )
353 t509 = malloc ( sizeof ( *t509 ) );
354 if ( ! t509 ) {
355 rc = -ENOMEM;
356 goto err;
357 }
358 memset ( t509, 0, sizeof ( *t509 ) );
359 t509->tag = tag;
360
361 /* Send the ID sequence */
363
364 /* Select the specified tag */
365 t509_select_tag ( t509->tag );
366
367 /* Read the default I/O address */
369 t509->ioaddr = 0x200 + ( ( iobase & 0x1f ) << 4 );
370
371 /* Send card back to ID_WAIT */
373
374 /* Add to device hierarchy */
375 snprintf ( t509->dev.name, sizeof ( t509->dev.name ),
376 "t509%02x", tag );
378 t509->dev.desc.vendor = MFG_ID;
379 t509->dev.desc.device = PROD_ID;
380 t509->dev.parent = &rootdev->dev;
381 list_add ( &t509->dev.siblings, &rootdev->dev.children );
382 INIT_LIST_HEAD ( &t509->dev.children );
383
384 /* Look for a driver */
385 if ( t509_probe ( t509 ) == 0 ) {
386 /* t509dev registered, we can drop our ref */
387 t509 = NULL;
388 } else {
389 /* Not registered; re-use struct */
390 list_del ( &t509->dev.siblings );
391 }
392 }
393
394 free ( t509 );
395 return 0;
396
397 err:
398 free ( t509 );
399 t509bus_remove ( rootdev );
400 return rc;
401}
static void t509bus_remove(struct root_device *rootdev)
Remove 3c509 root bus.
Definition 3c509.c:408
static int t509_probe(struct t509_device *t509)
Probe a 3c509 device.
Definition 3c509.c:315
static int t509_isolate(void)
Definition 3c509.c:186
#define EEPROM_ADDR_CFG
Definition 3c509.h:92
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define BUS_TYPE_ISA
ISA bus type.
Definition device.h:56
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memset(void *dest, int character, size_t len) __nonnull
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
unsigned int bus_type
Bus type.
Definition device.h:25
unsigned int device
Device ID.
Definition device.h:34
unsigned int vendor
Vendor ID.
Definition device.h:32
struct device_description desc
Device description.
Definition device.h:83
struct device * parent
Bus device.
Definition device.h:89
char name[40]
Name.
Definition device.h:79
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References device_description::bus_type, BUS_TYPE_ISA, device::children, device::desc, root_device::dev, t509_device::dev, device_description::device, EEPROM_ADDR_CFG, ENOMEM, free, INIT_LIST_HEAD, t509_device::ioaddr, list_add, list_del, malloc(), memset(), MFG_ID, device::name, NULL, device::parent, PROD_ID, rc, device::siblings, snprintf(), t509_id_read_eeprom(), t509_isolate(), t509_max_tag, t509_probe(), t509_select_tag(), t509_send_id_sequence(), t509_wait_for_id_sequence(), t509bus_remove(), t509_device::tag, tag, and device_description::vendor.

◆ ISA_ROM()

ISA_ROM ( "3c509" ,
"3c509"  )

Variable Documentation

◆ t509_id_port

◆ t509_max_tag

unsigned int t509_max_tag = 0
static

Definition at line 37 of file 3c509.c.

Referenced by t509_isolate(), and t509bus_probe().

◆ t509_root_driver

struct root_driver t509_root_driver
static
Initial value:
= {
.probe = t509bus_probe,
.remove = t509bus_remove,
}
static int t509bus_probe(struct root_device *rootdev)
Probe 3c509 root bus.
Definition 3c509.c:340

3c509 bus root device driver

Definition at line 421 of file 3c509.c.

421 {
422 .probe = t509bus_probe,
423 .remove = t509bus_remove,
424};

◆ __root_device

struct root_device t509_root_device __root_device
Initial value:
= {
.dev = { .name = "3c509" },
.driver = &t509_root_driver,
}
static struct root_driver t509_root_driver
3c509 bus root device driver
Definition 3c509.c:421

3c509 bus root device

Definition at line 427 of file 3c509.c.

427 {
428 .dev = { .name = "3c509" },
429 .driver = &t509_root_driver,
430};