embox

Форк
0
533 строки · 13.8 Кб
1
/**
2
 * @file fec.c
3
 * @brief
4
 * @author Denis Deryugin <deryugin.denis@gmail.com>
5
 * @version
6
 * @date 2016-08-11
7
 */
8

9
#include "fec.h"
10

11
#include <assert.h>
12
#include <errno.h>
13
#include <string.h>
14

15
#include <hal/cache.h>
16
#include <drivers/common/memory.h>
17

18
#include <hal/reg.h>
19
#include <kernel/irq.h>
20

21
#include <net/inetdevice.h>
22
#include <net/l0/net_entry.h>
23
#include <net/l2/ethernet.h>
24
#include <net/netdevice.h>
25
#include <net/skbuff.h>
26
#include <net/util/show_packet.h>
27
#include <net/mii.h>
28

29
#include <util/log.h>
30

31
#include <embox/unit.h>
32

33
#include <framework/mod/options.h>
34
/* FEC MII MMFR bits definition */
35
#define FEC_MMFR_ST     (1 << 30)
36
#define FEC_MMFR_OP_READ    (2 << 28)
37
#define FEC_MMFR_OP_WRITE   (1 << 28)
38
#define FEC_MMFR_PA(v)      ((v & 0x1f) << 23)
39
#define FEC_MMFR_RA(v)      ((v & 0x1f) << 18)
40
#define FEC_MMFR_TA     (2 << 16)
41
#define FEC_MMFR_DATA(v)    (v & 0xffff)
42

43
static struct fec_priv fec_priv;
44

45
static void fec_reg_dump(const char * title) {
46
	log_debug("%s", title);
47

48
	log_debug("ENET_EIR  %10x %10x", ENET_EIR, REG32_LOAD(ENET_EIR ));
49
	log_debug("ENET_EIMR %10x %10x", ENET_EIMR, REG32_LOAD(ENET_EIMR));
50
	log_debug("ENET_RDAR %10x %10x", ENET_RDAR, REG32_LOAD(ENET_RDAR));
51
	log_debug("ENET_TDAR %10x %10x", ENET_TDAR, REG32_LOAD(ENET_TDAR));
52
	log_debug("ENET_ECR  %10x %10x", ENET_ECR, REG32_LOAD(ENET_ECR ));
53
	log_debug("ENET_MMFR %10x %10x", ENET_MMFR, REG32_LOAD(ENET_MMFR));
54
	log_debug("ENET_MSCR %10x %10x", ENET_MSCR, REG32_LOAD(ENET_MSCR));
55
	log_debug("ENET_MIBC %10x %10x", ENET_MIBC, REG32_LOAD(ENET_MIBC));
56
	log_debug("ENET_RCR  %10x %10x", ENET_RCR, REG32_LOAD(ENET_RCR ));
57
	log_debug("ENET_TCR  %10x %10x", ENET_TCR, REG32_LOAD(ENET_TCR ));
58
	log_debug("ENET_MAC_LOW   %10x %10x", ENET_MAC_LOW, REG32_LOAD(ENET_MAC_LOW  ));
59
	log_debug("ENET_MAC_HI    %10x %10x", ENET_MAC_HI, REG32_LOAD(ENET_MAC_HI   ));
60
	log_debug("ENET_OPD  %10x %10x", ENET_OPD, REG32_LOAD(ENET_OPD));
61
	log_debug("ENET_IAUR %10x %10x", ENET_IAUR, REG32_LOAD(ENET_IAUR));
62
	log_debug("ENET_IALR %10x %10x", ENET_IALR, REG32_LOAD(ENET_IALR));
63
	log_debug("ENET_GAUR %10x %10x", ENET_GAUR, REG32_LOAD(ENET_GAUR));
64
	log_debug("ENET_GALR %10x %10x", ENET_GALR, REG32_LOAD(ENET_GALR));
65
	log_debug("ENET_TFWR %10x %10x", ENET_TFWR, REG32_LOAD(ENET_TFWR));
66
	log_debug("ENET_WTF1 %10x %10x", ENET_WTF1, REG32_LOAD(ENET_WTF1));
67
	log_debug("ENET_WTF2 %10x %10x", ENET_WTF2, REG32_LOAD(ENET_WTF2));
68
	log_debug("ENET_RDSR %10x %10x", ENET_RDSR, REG32_LOAD(ENET_RDSR));
69
	log_debug("ENET_TDSR %10x %10x", ENET_TDSR, REG32_LOAD(ENET_TDSR));
70
	log_debug("ENET_MRBR %10x %10x", ENET_MRBR, REG32_LOAD(ENET_MRBR));
71
}
72

73
static void emac_set_macaddr(unsigned char _macaddr[6]) {
74
	uint32_t mac_hi, mac_lo;
75
	const uint8_t *tmp = _macaddr;
76

77
	REG32_STORE(ENET_IAUR, 0);
78
	REG32_STORE(ENET_IALR, 0);
79
	REG32_STORE(ENET_GAUR, 0);
80
	REG32_STORE(ENET_GALR, 0);
81

82
	log_debug("addr = %x:%x:%x:%x:%x:%x", tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5]);
83

84
	mac_hi  = (_macaddr[5] << 16) |
85
	          (_macaddr[4] << 24);
86
	mac_lo  = (_macaddr[3] <<  0) |
87
	          (_macaddr[2] <<  8) |
88
	          (_macaddr[1] << 16) |
89
	          (_macaddr[0] << 24);
90

91
	REG32_STORE(ENET_MAC_LOW, mac_lo);
92
	REG32_STORE(ENET_MAC_HI, mac_hi | 0x8808);
93
}
94

95
static struct fec_buf_desc _tx_desc_ring[TX_BUF_FRAMES] __attribute__ ((aligned(0x10)));
96
static struct fec_buf_desc _rx_desc_ring[RX_BUF_FRAMES] __attribute__ ((aligned(0x10)));
97

98
static uint8_t _tx_buf[TX_BUF_FRAMES][2048] __attribute__ ((aligned(0x10)));
99
static uint8_t _rx_buf[RX_BUF_FRAMES][2048] __attribute__ ((aligned(0x10)));
100

101
static void fec_tbd_init(struct fec_priv *fec)
102
{
103
	unsigned size = TX_BUF_FRAMES * sizeof(struct fec_buf_desc);
104

105
	memset(fec->tbd_base, 0, size);
106

107
	fec->tbd_base[TX_BUF_FRAMES - 1].flags = FLAG_W;
108

109
	dcache_flush(fec->tbd_base, size);
110

111
	fec->tbd_index = 0;
112
	REG32_STORE(ENET_TDSR, ((uint32_t) fec->tbd_base));
113
}
114

115
static void fec_rbd_init(struct fec_priv *fec, int count, int dsize) {
116
	uint32_t size;
117
	int i;
118

119
	/*
120
	 * Reload the RX descriptors with default values and wipe
121
	 * the RX buffers.
122
	 */
123
	size = count * sizeof(struct fec_buf_desc);
124
	for (i = 0; i < count; i++) {
125
		fec->rbd_base[i].data_pointer = (uint32_t)&_rx_buf[i][0];
126
		fec->rbd_base[i].len = 0;
127
		fec->rbd_base[i].flags = FLAG_R;
128
	}
129

130
	/* Mark the last RBD to close the ring. */
131
	fec->rbd_base[count - 1].flags = FLAG_W | FLAG_R;
132

133
	fec->rbd_index = 0;
134

135
	dcache_flush((void *)fec->rbd_base, size);
136

137
	REG32_STORE(ENET_RDSR, (uint32_t)fec->rbd_base);
138
}
139

140
static int fec_xmit(struct net_device *dev, struct sk_buff *skb) {
141
	uint8_t *data;
142
	struct fec_buf_desc *desc;
143
	int res;
144
	ipl_t sp;
145
	struct fec_priv *priv;
146
	int cur_tx_desc;
147

148
	assert(dev);
149
	assert(skb);
150

151
	res = 0;
152

153
	data = (uint8_t*) skb_data_cast_in(skb->data);
154

155
	if (!data) {
156
		log_error("No skb data!\n");
157
		res = -1;
158
		goto out;
159

160
	}
161
	show_packet(data, skb->len, "tx");
162

163
	priv = dev->priv;
164
	dcache_inval(priv, sizeof(struct fec_priv));
165
	assert((uint32_t)priv->tbd_base == REG32_LOAD(ENET_TDSR));
166

167
	sp = ipl_save();
168
	{
169
		cur_tx_desc = priv->tbd_index;
170
		log_debug("Transmitting packet %2d", cur_tx_desc);
171

172
		memcpy(&_tx_buf[cur_tx_desc][0], data, skb->len);
173
		dcache_flush(&_tx_buf[cur_tx_desc][0], skb->len);
174
		//dcache_flush(data, skb->len);
175

176
		desc = &priv->tbd_base[cur_tx_desc];
177
		dcache_inval(desc, sizeof(struct fec_buf_desc));
178
		if (desc->flags & FLAG_R) {
179
			log_error("tx desc still busy");
180
			goto out1;
181
		}
182

183
		desc->data_pointer = (uint32_t)&_tx_buf[cur_tx_desc][0];
184
		//desc->data_pointer = (uint32_t)data;
185
		desc->len          = skb->len;
186
		desc->flags       |= FLAG_L | FLAG_TC | FLAG_R;
187
		dcache_flush(desc, sizeof(struct fec_buf_desc));
188

189
		REG32_LOAD(desc + sizeof(*desc) - 4);
190

191
		REG32_STORE(ENET_TDAR, 1 << 24);
192
		__asm__("nop");
193

194
		int timeout = 0xFFF;
195
		while(--timeout) {
196
			dcache_inval((void*) ENET_TDAR, 4);
197
			if (!(REG32_LOAD(ENET_TDAR))) {
198
				break;
199
			}
200
		}
201

202
		if (timeout == 0) {
203
			log_error("TX timeout ENET_TDAR is not zero...");
204
		}
205

206
		timeout = 0xFFFF;
207
		while(--timeout) {
208
			dcache_inval(desc, sizeof(struct fec_buf_desc));
209
			if (!(desc->flags & FLAG_R)) {
210
				break;
211
			}
212
		}
213
		if (timeout == 0) {
214
			log_error("TX timeout bit READY still set...");
215
		}
216

217
		priv->tbd_index = (priv->tbd_index + 1) % TX_BUF_FRAMES;
218
		dcache_flush(priv, sizeof(struct fec_priv));
219
	}
220
out1:
221
	ipl_restore(sp);
222

223
out:
224
	skb_free(skb);
225
	return res;
226
}
227

228
static void fec_mdio_init(struct net_device *dev) {
229
	phy_detect(dev);
230
	phy_autoneg(dev, FEC_SPEED);
231
}
232

233
static void _reset(struct net_device *dev) {
234
	int cnt = 0;
235

236
	fec_reg_dump("ENET dump uboot...");
237

238
	REG32_STORE(ENET_ECR, ENET_RESET);
239
	while(REG32_LOAD(ENET_ECR) & ENET_RESET){
240
		if (cnt ++ > 100000) {
241
			log_error("enet can't be reset");
242
			break;
243
		}
244
	}
245

246
	/* set mii speed */
247
	REG32_STORE(ENET_MSCR, 0x1a);
248

249

250
	/*
251
	 * Set interrupt mask register
252
	 */
253
	/* enable all interrupts */
254
	/* Transmit Frame Interrupt
255
	 * Transmit Buffer Interrupt
256
	 * Receive Frame Interrupt
257
	 * Receive Buffer Interrupt
258
	 */
259
	REG32_STORE(ENET_EIMR, ENET_EIR_RXB | ENET_EIR_RXF);
260
	/* Clear FEC-Lite interrupt event register(IEVENT) */
261
	REG32_STORE(ENET_EIR, 0xffc00000);
262

263
	/* Full-Duplex Enable */
264
	REG32_STORE(ENET_TCR, (1 << 2));
265

266
	/* MAX_FL frame length*/
267

268
	fec_mdio_init(dev);
269

270
	/* Enables 10-Mbit/s mode of the RMII or RGMII ?*/
271
	/* Maximum Receive Buffer Size Register
272
	 * Receive buffer size in bytes. This value, concatenated with the four
273
	 * least-significant bits of this register (which are always zero),
274
	 * is the effective maximum receive buffer size. */
275
	REG32_STORE(ENET_MRBR, 0x5f0);
276

277
	fec_rbd_init(dev->priv, RX_BUF_FRAMES, 0x600);
278

279
	fec_tbd_init(dev->priv);
280

281
	/* Transmit FIFO Write 64 bytes */
282
	REG32_STORE(ENET_TFWR, 0x100);
283

284
	/* Note: this should be last ENET-related init step */
285
	REG32_STORE(ENET_ECR, REG32_LOAD(ENET_ECR) | ENET_ETHEREN);
286

287
	REG32_STORE(ENET_RDAR, (1 << 24));
288
	fec_reg_dump("ENET dump embox...\n");
289
}
290

291
static int fec_open(struct net_device *dev) {
292
	assert(dev);
293

294
	_reset(dev);
295

296
	return 0;
297
}
298

299
static int fec_set_macaddr(struct net_device *dev, const void *addr) {
300
	assert(dev);
301
	assert(addr);
302

303
	emac_set_macaddr((unsigned char *)addr);
304

305
	return 0;
306
}
307

308
static int imx6_receive(struct net_device *dev_id, struct fec_priv *priv) {
309
	struct fec_buf_desc *desc;
310
	struct sk_buff *skb;
311
	int res = 0;
312

313
	desc = &_rx_desc_ring[priv->rbd_index];
314
	dcache_inval(desc, sizeof(struct fec_buf_desc));
315
	if (desc->flags & FLAG_E) {
316
		/* IRQ happened, but buf is empty, so check
317
		 * other buffer frames */
318
		for (int i = 0; i < RX_BUF_FRAMES; i++) {
319
			desc = &_rx_desc_ring[i];
320
			dcache_inval(desc, sizeof(struct fec_buf_desc));
321
			if (!(desc->flags & FLAG_E)) {
322
				log_debug("found frame %d, should be %d", i, priv->rbd_index);
323
				priv->rbd_index = i;
324
				break;
325
			}
326
		}
327
	}
328

329

330
	while(!(desc->flags & FLAG_E)) {
331
		log_debug("Receiving packet %d", priv->rbd_index);
332

333
		priv->rbd_index = (priv->rbd_index + 1) % RX_BUF_FRAMES;
334
		dcache_flush(priv, sizeof(struct fec_priv));
335

336
		skb = skb_alloc(desc->len);
337
		if (!skb) {
338
			log_error("can't allocate skb");
339
			break;
340
		}
341
		dcache_inval((void *)desc->data_pointer, desc->len);
342
		memcpy(skb_data_cast_in(skb->data),
343
				(void*)desc->data_pointer, desc->len);
344
		skb->len = desc->len; /* without CRC */
345
		skb->dev = dev_id;
346

347
		show_packet(skb_data_cast_in(skb->data), skb->len, "rx");
348

349
		netif_rx(skb);
350

351
		desc->flags |= FLAG_R;
352
		dcache_flush(desc, sizeof(struct fec_buf_desc));
353

354
		REG32_STORE(ENET_RDAR, (1 << 24));
355

356
		desc = &_rx_desc_ring[priv->rbd_index];
357
		dcache_inval(desc, sizeof(struct fec_buf_desc));
358
	}
359

360
	return res;
361
}
362

363
static irq_return_t imx6_irq_handler(unsigned int irq_num, void *dev_id) {
364
	uint32_t state;
365
	struct fec_priv *priv;
366

367
	assert(dev_id);
368

369
	priv = ((struct net_device *)dev_id)->priv;
370
	dcache_inval(priv, sizeof(struct fec_priv));
371
	state = REG32_LOAD(ENET_EIR);
372

373
	log_debug("Interrupt mask %#010x", state);
374

375
	if (state & ENET_EIR_EBERR) {
376
		log_error("Ethernet bus error, resetting ENET!");
377
		//REG32_STORE(ENET_ECR, RESET);
378
		_reset(dev_id);
379

380
		return IRQ_HANDLED;
381
	}
382

383
	if (state & (ENET_EIR_RXB | ENET_EIR_RXF)) {
384
		imx6_receive(dev_id, priv);
385
	}
386

387
	REG32_STORE(ENET_EIR, state);
388

389
	return IRQ_HANDLED;
390
}
391

392
/* MII-related definitios */
393
#define FEC_IEVENT_MII          0x00800000
394
#define FEC_MII_DATA_ST		0x40000000	/* Start of frame delimiter */
395
#define FEC_MII_DATA_OP_RD	0x20000000	/* Perform a read operation */
396
#define FEC_MII_DATA_OP_WR	0x10000000	/* Perform a write operation */
397
#define FEC_MII_DATA_PA_MSK	0x0f800000	/* PHY Address field mask */
398
#define FEC_MII_DATA_RA_MSK	0x007c0000	/* PHY Register field mask */
399
#define FEC_MII_DATA_TA		0x00020000	/* Turnaround */
400
#define FEC_MII_DATA_DATAMSK	0x0000ffff	/* PHY data field */
401

402
#define FEC_MII_DATA_RA_SHIFT	18	/* MII Register address bits */
403
#define FEC_MII_DATA_PA_SHIFT	23	/* MII PHY address bits */
404

405
#define FEC_MII_DATA_RA_SHIFT	18	/* MII Register address bits */
406
#define FEC_MII_DATA_PA_SHIFT	23	/* MII PHY address bits */
407
static int fec_mdio_read(struct net_device *dev, uint8_t regAddr) {
408
	struct fec_priv *fec = dev->priv;
409
	uint32_t reg;		/* convenient holder for the PHY register */
410
	uint32_t phy;		/* convenient holder for the PHY */
411
	int val;
412
	int retry = 0;
413

414
	/* Reading from any PHY's register is done by properly
415
	 * programming the FEC's MII data register. */
416
	REG32_STORE(ENET_EIR, FEC_IEVENT_MII);
417
	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
418
	phy = fec->phy_id << FEC_MII_DATA_PA_SHIFT;
419

420
	REG32_STORE(ENET_MMFR, FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD |
421
			FEC_MII_DATA_TA | phy | reg);
422

423
	/* Wait for the related interrupt */
424
	while (!(REG32_LOAD(ENET_EIR) & FEC_IEVENT_MII)) {
425
		if (retry++ > 0xffff) {
426
			log_error("MDIO write failed");
427
			return -1;
428
		}
429
	}
430

431
	/* Clear MII interrupt bit */
432
	REG32_STORE(ENET_EIR, FEC_IEVENT_MII);
433

434
	/* It's now safe to read the PHY's register */
435
	val = REG32_LOAD(ENET_MMFR) & 0xFFFF;
436
	log_debug("reg:%02x val:%#x", regAddr, val);
437
	return val;
438
}
439

440
static int fec_mdio_write(struct net_device *dev, uint8_t regAddr, uint16_t data) {
441
	struct fec_priv *fec = dev->priv;
442
	uint32_t reg;		/* convenient holder for the PHY register */
443
	uint32_t phy;		/* convenient holder for the PHY */
444
	int retry = 0;
445

446
	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
447
	phy = fec->phy_id << FEC_MII_DATA_PA_SHIFT;
448

449
	REG32_STORE(ENET_MMFR, FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
450
		FEC_MII_DATA_TA | phy | reg | data);
451

452
	/* Wait for the MII interrupt */
453
	while (!(REG32_LOAD(ENET_EIR) & FEC_IEVENT_MII)) {
454
		if (retry++ > 0xffff) {
455
			log_error("MDIO write failed");
456
			return -1;
457
		}
458
	}
459

460
	/* Clear MII interrupt bit */
461
	REG32_STORE(ENET_EIR, FEC_IEVENT_MII);
462
	log_debug("reg:%02x val:%#x", regAddr, data);
463

464
	return 0;
465
}
466

467
static void fec_set_phyid(struct net_device *dev, uint8_t phyid) {
468
	struct fec_priv *fec = dev->priv;
469
	fec->phy_id = phyid;
470
}
471

472
static int fec_set_speed(struct net_device *dev, int speed) {
473
	speed = net_to_mbps(speed);
474

475
	if (speed != FEC_SPEED && FEC_SPEED != 0) {
476
		log_error("Can't set %dmbps as driver is configured "
477
				"to force %dmbps", speed, FEC_SPEED);
478
		return -1;
479
	}
480

481
	switch (speed) {
482
	case 1000:
483
		REG32_STORE(ENET_RCR, 0x5ee0000 | ENET_RCR_RGMII_EN);
484
		REG32_STORE(ENET_ECR, 0xF0000100 | ENET_SPEED);
485
		break;
486
	case 100:
487
		REG32_STORE(ENET_RCR, 0x5ee0000 | ENET_RCR_RGMII_EN);
488
		REG32_STORE(ENET_ECR, 0xF0000100);
489
		break;
490
	case 10:
491
		REG32_STORE(ENET_RCR, 0x5ee0000 | ENET_RCR_RMII_10T |
492
				ENET_RCR_RGMII_EN);
493
		REG32_STORE(ENET_ECR, 0xF0000100);
494
		break;
495
	}
496

497
	return 0;
498
}
499

500
static const struct net_driver fec_drv_ops = {
501
	.xmit        = fec_xmit,
502
	.start       = fec_open,
503
	.set_macaddr = fec_set_macaddr,
504
	.mdio_read   = fec_mdio_read,
505
	.mdio_write  = fec_mdio_write,
506
	.set_phyid   = fec_set_phyid,
507
	.set_speed   = fec_set_speed
508
};
509

510
EMBOX_UNIT_INIT(fec_init);
511
static int fec_init(void) {
512
	struct net_device *nic;
513
	int tmp;
514

515
	if (NULL == (nic = etherdev_alloc(0))) {
516
		return -ENOMEM;
517
	}
518

519
	nic->drv_ops = &fec_drv_ops;
520

521
	fec_priv.base_addr = NIC_BASE;
522
	fec_priv.rbd_base =  _rx_desc_ring;
523
	fec_priv.tbd_base =  _tx_desc_ring;
524
	nic->priv = &fec_priv;
525

526
	tmp = irq_attach(ENET_IRQ, imx6_irq_handler, 0, nic, "FEC");
527
	if (tmp)
528
		return tmp;
529

530
	return inetdev_register_dev(nic);
531
}
532

533
PERIPH_MEMORY_DEFINE(fec, NIC_BASE, 0x200);
534

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.