embox

Форк
0
/
stm32cube_eth_h7.c 
269 строк · 6.8 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @author  Anton Kozlov
6
 * @date    07.08.2014
7
 */
8
#include <util/log.h>
9

10
#include <errno.h>
11
#include <string.h>
12
#include <stdio.h>
13

14
#include <util/math.h>
15
#include <kernel/irq.h>
16
#include <hal/reg.h>
17

18
#include <net/netdevice.h>
19
#include <net/inetdevice.h>
20
#include <net/l0/net_entry.h>
21
#include <net/l2/ethernet.h>
22
#include <net/l3/arp.h>
23
#include <net/util/show_packet.h>
24

25
#include <drivers/net/stm32cube_eth.h>
26

27
#include <embox/unit.h>
28
#include <arm/cpu_cache.h>
29

30
EMBOX_UNIT_INIT(stm32eth_init);
31

32
#define ETH_DMA_TRANSMIT_TIMEOUT                (20U)
33

34
#define STM32ETH_IRQ   OPTION_GET(NUMBER, irq)
35
#define USE_RMII       OPTION_GET(NUMBER, use_rmii)
36

37
static ETH_HandleTypeDef stm32_eth_handler;
38
static ETH_TxPacketConfig TxConfig;
39

40
static ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] \
41
	__attribute__ ((aligned (4))) SRAM_DEVICE_MEM_SECTION;
42

43
static uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] \
44
	 __attribute__ ((aligned (4))) SRAM_NOCACHE_SECTION;
45

46
#if ETH_TXBUFNB == 0
47
#undef  ETH_TXBUFNB
48
#define ETH_TXBUFNB 4
49
#define TX_NO_BUFF  1
50
#endif
51

52
#ifdef TX_NO_BUFF
53
static ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] \
54
	__attribute__ ((aligned (4))) SRAM_DEVICE_MEM_SECTION;
55
#else /* TX_NO_BUFF */
56
static uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] \
57
	__attribute__ ((aligned (4))) SRAM_NOCACHE_SECTION;
58

59
static ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] \
60
	__attribute__ ((aligned (4))) SRAM_DEVICE_MEM_SECTION;
61
#endif /* TX_NO_BUFF */
62

63
static void low_level_init(unsigned char mac[6]) {
64
	memset(&stm32_eth_handler, 0, sizeof(stm32_eth_handler));
65

66
	stm32_eth_handler.Instance = (ETH_TypeDef *) ETH_BASE;
67
	/* Fill ETH_InitStructure parametrs */
68
	stm32_eth_handler.Init.MACAddr = mac;
69
#if USE_RMII
70
	stm32_eth_handler.Init.MediaInterface = HAL_ETH_RMII_MODE;
71
#else
72
	stm32_eth_handler.Init.MediaInterface = HAL_ETH_MII_MODE;
73
#endif
74
	stm32_eth_handler.Init.RxDesc = DMARxDscrTab;
75
	stm32_eth_handler.Init.TxDesc = DMATxDscrTab;
76
	stm32_eth_handler.Init.RxBuffLen = ETH_TX_BUF_SIZE;
77

78
	if (HAL_OK != HAL_ETH_Init(&stm32_eth_handler)) {
79
		log_error("HAL_ETH_Init error\n");
80
	}
81

82
	if (stm32_eth_handler.gState == HAL_ETH_STATE_READY) {
83

84
	}
85
	for (int idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
86
	{
87
		HAL_ETH_DescAssignMemory(&stm32_eth_handler, idx, Rx_Buff[idx], NULL);
88
	}
89

90
	/* Set Tx packet config common parameters */
91
	memset(&TxConfig, 0, sizeof(ETH_TxPacketConfig));
92
	TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
93
	TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
94
	TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
95

96
	ETH_MACConfigTypeDef MACConf;
97
	/* Get MAC Config MAC */
98
	HAL_ETH_GetMACConfig(&stm32_eth_handler, &MACConf);
99
	MACConf.DuplexMode = ETH_FULLDUPLEX_MODE;
100
	MACConf.Speed = ETH_SPEED_100M;
101
	HAL_ETH_SetMACConfig(&stm32_eth_handler, &MACConf);
102

103
	/* (#)Enable MAC and DMA transmission and reception: */
104
	HAL_ETH_Start_IT(&stm32_eth_handler);
105
}
106

107
static uint8_t *low_level_input(int *len) {
108
	uint8_t *buffer;
109

110
	ETH_BufferTypeDef RxBuff;
111
	uint32_t framelength = 0;
112

113
	if (!HAL_ETH_IsRxDataAvailable(&stm32_eth_handler)) {
114
		return NULL;
115
	}
116
	HAL_ETH_GetRxDataBuffer(&stm32_eth_handler, &RxBuff);
117
	HAL_ETH_GetRxDataLength(&stm32_eth_handler, &framelength);
118

119
	/* Build Rx descriptor to be ready for next data reception */
120
	HAL_ETH_BuildRxDescriptors(&stm32_eth_handler);
121

122
	/* Invalidate data cache for ETH Rx Buffers */
123
	//SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff.buffer, framelength);
124

125
	buffer = RxBuff.buffer;
126
	*len = framelength;
127
	return buffer;
128
}
129

130

131
static int stm32eth_xmit(struct net_device *dev, struct sk_buff *skb);
132
static int stm32eth_open(struct net_device *dev);
133
static int stm32eth_set_mac(struct net_device *dev, const void *addr);
134
static const struct net_driver stm32eth_ops = {
135
		.xmit = stm32eth_xmit,
136
		.start = stm32eth_open,
137
		.set_macaddr = stm32eth_set_mac,
138
};
139

140
static int stm32eth_open(struct net_device *dev) {
141
	low_level_init(dev->dev_addr);
142

143
	return 0;
144
}
145

146
static int stm32eth_set_mac(struct net_device *dev, const void *addr) {
147
	ETH_TypeDef *regs = (ETH_TypeDef *) ETH_BASE;
148

149
	memcpy(dev->dev_addr, addr, ETH_ALEN);
150

151
	regs->MACA0HR = ((uint32_t) dev->dev_addr[5] << 8) |
152
	                ((uint32_t) dev->dev_addr[4] << 0);
153

154
	regs->MACA0LR = ((uint32_t) dev->dev_addr[3] << 24) |
155
	                ((uint32_t) dev->dev_addr[2] << 16) |
156
	                ((uint32_t) dev->dev_addr[1] << 8)  |
157
	                ((uint32_t) dev->dev_addr[0] << 0);
158

159
	return ENOERR;
160
}
161

162
#ifdef TX_NO_BUFF
163
static uint8_t Tx_Buff[ETH_TX_BUF_SIZE] \
164
	__attribute__ ((aligned (4))) SRAM_NOCACHE_SECTION;
165
static int stm32eth_xmit(struct net_device *dev, struct sk_buff *skb) {
166
	ETH_BufferTypeDef Txbuffer;
167

168
	show_packet(skb->mac.raw, skb->len, "tx");
169

170
	memcpy((void *)Tx_Buff, skb->mac.raw, skb->len);
171

172
	memset(&Txbuffer, 0, sizeof(Txbuffer));
173
	Txbuffer.buffer = Tx_Buff;
174
	Txbuffer.len = skb->len;
175

176
	TxConfig.Length = skb->len;
177
	TxConfig.TxBuffer = &Txbuffer;
178
	HAL_ETH_Transmit(&stm32_eth_handler, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
179

180
	skb_free(skb);
181

182
	return 0;
183
}
184
#else
185
static int stm32eth_xmit(struct net_device *dev, struct sk_buff *skb) {
186
	__IO ETH_DMADescTypeDef *dma_tx_desc;
187

188
	dma_tx_desc = stm32_eth_handler.TxDesc;
189
	memcpy((void *)dma_tx_desc->Buffer1Addr, skb->mac.raw, skb->len);
190

191
	/* Prepare transmit descriptors to give to DMA */
192
	if (0 != HAL_ETH_TransmitFrame(&stm32_eth_handler, skb->len)) {
193
		log_error("HAL_ETH_TransmitFrame failed\n");
194
		return -1;
195
	}
196
	skb_free(skb);
197

198
	return 0;
199
}
200
#endif
201

202
static irq_return_t stm32eth_interrupt(unsigned int irq_num, void *dev_id) {
203
	struct net_device *nic_p = dev_id;
204
	struct sk_buff *skb;
205
	ETH_HandleTypeDef *heth = &stm32_eth_handler;
206

207
	if (!nic_p) {
208
		return IRQ_NONE;
209
	}
210

211
	/* Packet received */
212
	if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_RI))
213
	{
214
		if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE))
215
		{
216
			uint8_t *buffer;
217
			int len;
218
			/* Receive complete callback */
219
			while (NULL != (buffer = low_level_input(&len))) {
220

221
				/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
222
				skb = skb_alloc(len);
223

224
				if (!skb) {
225
					log_error("skb_alloc failed\n");
226
					continue;
227
				}
228
				/* copy received frame to pbuf chain */
229
				memcpy(skb->mac.raw, buffer, len);
230

231
				skb->dev = nic_p;
232

233
				show_packet(skb->mac.raw, skb->len, "rx");
234

235
				netif_rx(skb);
236
			}
237
			/* Clear the Eth DMA Rx IT pending bits */
238
			__HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
239
		}
240
	}
241

242
	return IRQ_HANDLED;
243
}
244

245
static struct net_device *stm32eth_netdev;
246
static int stm32eth_init(void) {
247
	int res;
248
	struct net_device *nic;
249

250
	nic = (struct net_device *) etherdev_alloc(0);
251
	if (nic == NULL) {
252
		return -ENOMEM;
253
	}
254

255
	nic->drv_ops = &stm32eth_ops;
256
	nic->irq = STM32ETH_IRQ;
257
	nic->base_addr = ETH_BASE;
258

259
	stm32eth_netdev = nic;
260

261
	res = irq_attach(nic->irq, stm32eth_interrupt, 0, stm32eth_netdev, "");
262
	if (res < 0) {
263
		return res;
264
	}
265

266
	return inetdev_register_dev(nic);
267
}
268

269
STATIC_IRQ_ATTACH(STM32ETH_IRQ, stm32eth_interrupt, stm32eth_netdev);
270

271

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

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

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

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