aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/net/rdc.h
blob: ee1671fdd1f8e52f2f37cb90799706534cdac9d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef _RDC_H
#define _RDC_H

/** @file
 *
 * RDC R6040 network driver
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/if_ether.h>
#include <ipxe/mii.h>

/** RDC BAR size */
#define RDC_BAR_SIZE 256

/** An RDC descriptor */
struct rdc_descriptor {
	/** Flags */
	uint16_t flags;
	/** Length */
	uint16_t len;
	/** Address */
	uint32_t addr;
	/** Next descriptor */
	uint32_t next;
	/** Reserved */
	uint32_t reserved;
} __attribute__ (( packed ));

/** Descriptor is owned by NIC */
#define RDC_FL_OWNED 0x8000

/** Packet OK */
#define RDC_FL_OK 0x4000

/** MAC control register 0 */
#define RDC_MCR0 0x00
#define RDC_MCR0_FD		0x8000	/**< Full duplex */
#define RDC_MCR0_TXEN		0x1000	/**< Transmit enable */
#define RDC_MCR0_PROMISC	0x0020	/**< Promiscuous mode */
#define RDC_MCR0_RXEN		0x0002	/**< Receive enable */

/** MAC control register 1 */
#define RDC_MCR1 0x04
#define RDC_MCR1_RST		0x0001	/**< MAC reset */

/** Maximum time to wait for reset */
#define RDC_RESET_MAX_WAIT_MS 10

/** MAC transmit poll command register */
#define RDC_MTPR 0x14
#define RDC_MTPR_TM2TX		0x0001	/**< Trigger MAC to transmit */

/** MAC receive buffer size register */
#define RDC_MRBSR 0x18

/** MAC MDIO control register */
#define RDC_MMDIO 0x20
#define RDC_MMDIO_MIIWR		0x4000	/**< MDIO write */
#define RDC_MMDIO_MIIRD		0x2000	/**< MDIO read */
#define RDC_MMDIO_PHYAD(x) ( (x) << 8 )	/**< PHY address */
#define RDC_MMDIO_REGAD(x) ( (x) << 0 )	/**< Register address */

/** Maximum time to wait for an MII read or write */
#define RDC_MII_MAX_WAIT_US 2048

/** MAC MDIO read data register */
#define RDC_MMRD 0x24

/** MAC MDIO write data register */
#define RDC_MMWD 0x28

/** MAC transmit descriptor start address */
#define RDC_MTDSA 0x2c

/** MAC receive descriptor start address */
#define RDC_MRDSA 0x34

/** MAC descriptor start address low half */
#define RDC_MxDSA_LO 0x0

/** MAC descriptor start address low half */
#define RDC_MxDSA_HI 0x4

/** MAC interrupt status register */
#define RDC_MISR 0x3c
#define RDC_MIRQ_LINK		0x0200	/**< Link status changed */
#define RDC_MIRQ_TX		0x0010	/**< Transmit complete */
#define RDC_MIRQ_RX_EARLY	0x0008	/**< Receive early interrupt */
#define RDC_MIRQ_RX_EMPTY	0x0002	/**< Receive descriptor unavailable */
#define RDC_MIRQ_RX		0x0001	/**< Receive complete */

/** MAC interrupt enable register */
#define RDC_MIER 0x40

/** MAC address word 0 */
#define RDC_MID0 0x68

/** MAC address word 1 */
#define RDC_MID1 0x6a

/** MAC address word 2 */
#define RDC_MID2 0x6c

/** MAC PHY status change configuration register */
#define RDC_MPSCCR 0x88
#define RDC_MPSCCR_EN		0x8000	/**< PHY status change enable */
#define RDC_MPSCCR_PHYAD(x) ( (x) << 8 ) /**< PHY address */
#define RDC_MPSCCR_SLOW		0x0007	/**< Poll slowly */

/** MAC state machine register */
#define RDC_MACSM 0xac
#define RDC_MACSM_RST		0x0002	/**< Reset state machine */

/** Time to wait after resetting MAC state machine */
#define RDC_MACSM_RESET_DELAY_MS 10

/** A MAC address */
union rdc_mac {
	/** Raw bytes */
	uint8_t raw[ETH_ALEN];
	/** MIDx registers */
	uint16_t mid[ ETH_ALEN / 2 ];
};

/** A descriptor ring */
struct rdc_ring {
	/** Descriptors */
	struct rdc_descriptor *desc;
	/** Descriptor ring DMA mapping */
	struct dma_mapping map;
	/** Producer index */
	unsigned int prod;
	/** Consumer index */
	unsigned int cons;

	/** Number of descriptors */
	unsigned int count;
	/** Start address register 0 */
	unsigned int reg;
};

/**
 * Initialise descriptor ring
 *
 * @v ring		Descriptor ring
 * @v count		Number of descriptors
 * @v reg		Start address register 0
 */
static inline __attribute__ (( always_inline )) void
rdc_init_ring ( struct rdc_ring *ring, unsigned int count, unsigned int reg ) {

	ring->count = count;
	ring->reg = reg;
}

/** Number of transmit descriptors
 *
 * This is a policy decision.
 */
#define RDC_NUM_TX_DESC 16

/** Number of receive descriptors
 *
 * This is a policy decision.
 */
#define RDC_NUM_RX_DESC 8

/** Receive buffer length */
#define RDC_RX_MAX_LEN ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ )

/** An RDC network card */
struct rdc_nic {
	/** Registers */
	void *regs;
	/** DMA device */
	struct dma_device *dma;
	/** MII interface */
	struct mii_interface mdio;
	/** MII device */
	struct mii_device mii;

	/** Transmit descriptor ring */
	struct rdc_ring tx;
	/** Receive descriptor ring */
	struct rdc_ring rx;
	/** Receive I/O buffers */
	struct io_buffer *rx_iobuf[RDC_NUM_RX_DESC];
};

#endif /* _RDC_H */