1 /* 2 * Copyright (c) 2016-2019 Arm Limited 3 * SPDX-License-Identifier: Apache-2.0 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** 19 * \file lan9118_drv.h 20 * \brief Generic driver for LAN9118 Ethernet controller 21 */ 22 23 #ifndef __LAN9118_ETH_H__ 24 #define __LAN9118_ETH_H__ 25 26 #include <stdbool.h> 27 #include <stdint.h> 28 #include "los_config.h" 29 #include "los_event.h" 30 #include "los_interrupt.h" 31 #include "los_reg.h" 32 #include "stdio.h" 33 #include "los_reg.h" 34 #include "los_arch_context.h" 35 #include "netinet/if_ether.h" 36 #include "lwip/opt.h" 37 #include <lwip/netif.h> 38 #include "lwip/etharp.h" 39 #include "lwip/tcpip.h" 40 #include "lwip/mem.h" 41 #include <lwip/pbuf.h> 42 #include <lwip/netifapi.h> 43 44 #define LAN9118_BASE 0x40200000UL /* Ethernet LAN9118 BASE Address */ 45 #define ETHERNET_IRQn 13 /* Ethernet Interrupt */ 46 #define LAN9118_ETH_MTU_SIZE 1500U /* Ethernet MTU */ 47 48 /** LAN9118 device configuration structure */ 49 struct lan9118_eth_dev_cfg_t { 50 const uint32_t base; /*!< LAN9118 base address */ 51 }; 52 53 /** LAN9118 device data structure */ 54 struct lan9118_eth_dev_data_t { 55 uint32_t state; /*!< Indicates if the LAN9118 driver 56 is initialized and enabled */ 57 void (*wait_ms)(uint32_t); /*!< function pointer to system's millisec delay 58 function, will be used for delays */ 59 uint32_t ongoing_packet_length; /*!< size in bytes of the packet 60 is being sent */ 61 uint32_t ongoing_packet_length_sent; /*!< size in bytes of the packet 62 has been sent */ 63 uint32_t current_rx_size_words; /*!< Data length in words, 64 currently is being read */ 65 }; 66 67 /** LAN9118 device structure */ 68 struct lan9118_eth_dev_t { 69 const struct lan9118_eth_dev_cfg_t* const cfg; /*!< configuration */ 70 struct lan9118_eth_dev_data_t* const data; /*!< data */ 71 }; 72 73 /** 74 * \brief Error code definitions 75 * 76 */ 77 enum lan9118_error_t { 78 LAN9118_ERROR_NONE = 0U, /*!< no error */ 79 LAN9118_ERROR_TIMEOUT = 1U, /*!< timeout */ 80 LAN9118_ERROR_BUSY = 2U, /*!< no error */ 81 LAN9118_ERROR_PARAM = 3U, /*!< invalid parameter */ 82 LAN9118_ERROR_INTERNAL = 4U /*!< internal error */ 83 }; 84 85 /** 86 * \brief Interrupt source definitions 87 * 88 */ 89 enum lan9118_interrupt_source { 90 LAN9118_INTERRUPT_GPIO0 = 0U, 91 LAN9118_INTERRUPT_GPIO1 = 1U, 92 LAN9118_INTERRUPT_GPIO2 = 2U, 93 LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL = 3U, 94 LAN9118_INTERRUPT_RX_STATUS_FIFO_FULL = 4U, 95 /* 5 Reserved according to Datasheet */ 96 LAN9118_INTERRUPT_RX_DROPPED_FRAME = 6U, 97 LAN9118_INTERRUPT_TX_STATUS_FIFO_LEVEL = 7U, 98 LAN9118_INTERRUPT_TX_STATUS_FIFO_FULL = 8U, 99 LAN9118_INTERRUPT_TX_DATA_FIFO_AVAILABLE = 9U, 100 LAN9118_INTERRUPT_TX_DATA_FIFO_OVERRUN = 10U, 101 /* 11, 12 Reserved according to Datasheet */ 102 LAN9118_INTERRUPT_TX_ERROR = 13U, 103 LAN9118_INTERRUPT_RX_ERROR = 14U, 104 LAN9118_INTERRUPT_RX_WATCHDOG_TIMEOUT = 15U, 105 LAN9118_INTERRUPT_TX_STATUS_OVERFLOW = 16U, 106 LAN9118_INTERRUPT_TX_POWER_MANAGEMENT = 17U, 107 LAN9118_INTERRUPT_PHY = 18U, 108 LAN9118_INTERRUPT_GP_TIMER = 19U, 109 LAN9118_INTERRUPT_RX_DMA = 20U, 110 LAN9118_INTERRUPT_TX_IOC = 21U, 111 /* 22 Reserved according to Datasheet*/ 112 LAN9118_INTERRUPT_RX_DROPPED_FRAME_HALF = 23U, 113 LAN9118_INTERRUPT_RX_STOPPED = 24U, 114 LAN9118_INTERRUPT_TX_STOPPED = 25U, 115 /* 26 - 30 Reserved according to Datasheet*/ 116 LAN9118_INTERRUPT_SW = 31U 117 }; 118 119 /** 120 * \brief MAC register offset definitions 121 * 122 */ 123 enum lan9118_mac_reg_offsets_t { 124 LAN9118_MAC_REG_OFFSET_CR = 0x1U, 125 LAN9118_MAC_REG_OFFSET_ADDRH = 0x2U, 126 LAN9118_MAC_REG_OFFSET_ADDRL = 0x3U, 127 LAN9118_MAC_REG_OFFSET_HASHH = 0x4U, 128 LAN9118_MAC_REG_OFFSET_HASHL = 0x5U, 129 LAN9118_MAC_REG_OFFSET_MII_ACC = 0x6U, 130 LAN9118_MAC_REG_OFFSET_MII_DATA = 0x7U, 131 LAN9118_MAC_REG_OFFSET_FLOW = 0x8U, 132 LAN9118_MAC_REG_OFFSET_VLAN1 = 0x9U, 133 LAN9118_MAC_REG_OFFSET_VLAN2 = 0xAU, 134 LAN9118_MAC_REG_OFFSET_WUFF = 0xBU, 135 LAN9118_MAC_REG_OFFSET_WUCSR = 0xCU, 136 }; 137 138 /** 139 * \brief PHY register offset definitions 140 * 141 */ 142 enum phy_reg_offsets_t { 143 LAN9118_PHY_REG_OFFSET_BCTRL = 0U, 144 LAN9118_PHY_REG_OFFSET_BSTATUS = 1U, 145 LAN9118_PHY_REG_OFFSET_ID1 = 2U, 146 LAN9118_PHY_REG_OFFSET_ID2 = 3U, 147 LAN9118_PHY_REG_OFFSET_ANEG_ADV = 4U, 148 LAN9118_PHY_REG_OFFSET_ANEG_LPA = 5U, 149 LAN9118_PHY_REG_OFFSET_ANEG_EXP = 6U, 150 LAN9118_PHY_REG_OFFSET_MCONTROL = 17U, 151 LAN9118_PHY_REG_OFFSET_MSTATUS = 18U, 152 LAN9118_PHY_REG_OFFSET_CSINDICATE = 27U, 153 LAN9118_PHY_REG_OFFSET_INTSRC = 29U, 154 LAN9118_PHY_REG_OFFSET_INTMASK = 30U, 155 LAN9118_PHY_REG_OFFSET_CS = 31U 156 }; 157 158 /** 159 * \brief FIFO Level Interrupt bit definitions 160 * 161 */ 162 enum lan9118_fifo_level_irq_pos_t { 163 LAN9118_FIFO_LEVEL_IRQ_RX_STATUS_POS = 0U, 164 LAN9118_FIFO_LEVEL_IRQ_TX_STATUS_POS = 16U, 165 LAN9118_FIFO_LEVEL_IRQ_TX_DATA_POS = 24U 166 }; 167 168 /** 169 * \brief FIFO Level Interrupt limits 170 * 171 */ 172 #define LAN9118_FIFO_LEVEL_IRQ_MASK 0xFFU 173 #define LAN9118_FIFO_LEVEL_IRQ_LEVEL_MIN 0U 174 #define LAN9118_FIFO_LEVEL_IRQ_LEVEL_MAX LAN9118_FIFO_LEVEL_IRQ_MASK 175 176 /** 177 * \brief Initializes LAN9118 Ethernet controller to a known default state: 178 * - device ID is checked 179 * - global interrupt is enabled, but all irq sources are disabled 180 * - all capabilities are advertised 181 * - 10Mbps able 182 * - 10Mbps with full duplex 183 * - 100Mbps Tx able 184 * - 100Mbps with full duplex 185 * - Symmetric Pause 186 * - Asymmetric Pause 187 * - Establish link enabled 188 * - Rx enabled 189 * - Tx enabled 190 * Init should be called prior to any other process and 191 * it's the caller's responsibility to follow proper call order. 192 * 193 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 194 * \param[in] wait_ms_function function pointer to a millisec delay function 195 * for proper timing of some processes 196 * 197 * \return error code /ref lan9118_error_t 198 */ 199 enum lan9118_error_t lan9118_init(const struct lan9118_eth_dev_t* dev, void (*wait_ms_function)(uint32_t)); 200 201 /** 202 * \brief Reads the MAC register. 203 * 204 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 205 * \param[in] regoffset Register offset 206 * \param[in, out] data Pointer to register will be read 207 * 208 * \return error code /ref lan9118_error_t 209 */ 210 enum lan9118_error_t lan9118_mac_regread(const struct lan9118_eth_dev_t* dev, enum lan9118_mac_reg_offsets_t regoffset, 211 uint32_t* data); 212 213 /** 214 * \brief Writes the MAC register. 215 * 216 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 217 * \param[in] regoffset Register offset 218 * \param[in] data Register value to write 219 * 220 * \return error code /ref lan9118_error_t 221 */ 222 enum lan9118_error_t lan9118_mac_regwrite(const struct lan9118_eth_dev_t* dev, enum lan9118_mac_reg_offsets_t regoffset, 223 uint32_t data); 224 225 /** 226 * \brief Reads the PHY register. 227 * 228 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 229 * \param[in] regoffset Register offset 230 * \param[out] data Register value is read 231 * 232 * \return error code /ref lan9118_error_t 233 */ 234 enum lan9118_error_t lan9118_phy_regread(const struct lan9118_eth_dev_t* dev, enum phy_reg_offsets_t regoffset, \ 235 uint32_t* data); 236 237 /** 238 * \brief Writes the PHY register. 239 * 240 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 241 * \param[in] regoffset Register offset 242 * \param[in] data Register value to write 243 * 244 * \return error code /ref lan9118_error_t 245 */ 246 enum lan9118_error_t lan9118_phy_regwrite(const struct lan9118_eth_dev_t* dev, enum phy_reg_offsets_t regoffset, \ 247 uint32_t data); 248 249 /** 250 * \brief Reads the Ethernet Controller's ID. 251 * 252 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 253 * 254 * \return ID number 255 */ 256 uint32_t lan9118_read_id(const struct lan9118_eth_dev_t* dev); 257 258 /** 259 * \brief Initiates a soft reset, returns failure or success. 260 * 261 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 262 * 263 * \return error code /ref lan9118_error_t 264 */ 265 enum lan9118_error_t lan9118_soft_reset(const struct lan9118_eth_dev_t* dev); 266 267 /** 268 * \brief Sets the Maximum Transmission Unit by Tx fifo size. 269 * Note: The MTU will be smaller than 512 bytes, 270 * which is used by the status. 271 * 272 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 273 * \param[in] val Size of the fifo in kbytes 274 * \ref HW_CFG_REG_TX_FIFO_SIZE_MIN 275 * \ref HW_CFG_REG_TX_FIFO_SIZE_MAX 276 */ 277 void lan9118_set_txfifo(const struct lan9118_eth_dev_t* dev, uint32_t val); 278 279 /** 280 * \brief Sets the FIFO level interrupt for a given source. 281 * 282 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 283 * \param[in] irq_level_pos Bit position of the FIFO to set 284 * \ref lan9118_fifo_level_irq_pos_t 285 * \param[in] level Level of the FIFO, when the FIFO used space is greater 286 * than this value, corresponding interrupt will be generated. 287 * 288 * \return error code /ref lan9118_error_t 289 */ 290 enum lan9118_error_t lan9118_set_fifo_level_irq(const struct lan9118_eth_dev_t* dev, 291 enum lan9118_fifo_level_irq_pos_t irq_level_pos, uint32_t level); 292 293 /** 294 * \brief Waits for EEPROM to be ready to use. 295 * 296 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 297 * 298 * \return error code /ref lan9118_error_t 299 */ 300 enum lan9118_error_t lan9118_wait_eeprom(const struct lan9118_eth_dev_t* dev); 301 302 /** 303 * \brief Initializes irqs by clearing and disabling all interrupt sources 304 * and enable interrupts. Since all interrupt sources are disabled, 305 * interrupt won't be triggered, until interrupt sources won't be 306 * enabled by \ref lan9118_enable_interrupt 307 * 308 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 309 */ 310 void lan9118_init_irqs(const struct lan9118_eth_dev_t* dev); 311 312 /** 313 * \brief Checks PHY ID registers. 314 * 315 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 316 * 317 * \return error code /ref lan9118_error_t 318 */ 319 enum lan9118_error_t lan9118_check_phy(const struct lan9118_eth_dev_t* dev); 320 321 /** 322 * \brief Resets PHY. 323 * 324 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 325 * 326 * \return error code /ref lan9118_error_t 327 */ 328 enum lan9118_error_t lan9118_reset_phy(const struct lan9118_eth_dev_t* dev); 329 330 /** 331 * \brief Advertises all speeds and pauses capabilities. 332 * 333 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 334 */ 335 void lan9118_advertise_cap(const struct lan9118_eth_dev_t* dev); 336 337 /** 338 * \brief Enables transmission. 339 * 340 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 341 */ 342 void lan9118_enable_xmit(const struct lan9118_eth_dev_t* dev); 343 344 /** 345 * \brief Enables MAC Transmitter. 346 * 347 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 348 */ 349 void lan9118_enable_mac_xmit(const struct lan9118_eth_dev_t* dev); 350 351 /** 352 * \brief Enables receiving. 353 * 354 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 355 */ 356 void lan9118_enable_mac_recv(const struct lan9118_eth_dev_t* dev); 357 358 /** 359 * \brief Enables the given interrupt source. 360 * 361 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 362 * \param[in] source Enum of the interrupt source. 363 */ 364 void lan9118_enable_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source); 365 366 /** 367 * \brief Disables the given interrupt source. 368 * 369 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 370 * \param[in] source Enum of the interrupt source. 371 */ 372 void lan9118_disable_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source); 373 374 /** 375 * \brief Disables all interrupt sources. 376 * 377 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 378 */ 379 void lan9118_disable_all_interrupts(const struct lan9118_eth_dev_t* dev); 380 381 /** 382 * \brief Clears the given interrupt source. 383 * 384 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 385 * \param[in] source Enum of the interrupt source. 386 */ 387 void lan9118_clear_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source); 388 389 /** 390 * \brief Clears all interrupt sources. 391 * 392 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 393 */ 394 void lan9118_clear_all_interrupts(const struct lan9118_eth_dev_t* dev); 395 396 /** 397 * \brief Gets the status of the given interrupt source. 398 * 399 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 400 * \param[in] source Enum of the interrupt source. 401 * 402 * \return non-zero if the given interrupt source is triggered, zero otherwise 403 */ 404 int lan9118_get_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source); 405 406 /** 407 * \brief Establishes link 408 * 409 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 410 */ 411 void lan9118_establish_link(const struct lan9118_eth_dev_t* dev); 412 413 /** 414 * \brief Reads the Ethernet Controller's MAC address from its EEPROM. 415 * 416 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 417 * \param[in,out] mac array will include the read MAC address in 418 * 6 bytes hexadecimal format. 419 * It should be allocated by the caller to 6 bytes. 420 * 421 * \return error code /ref lan9118_error_t 422 */ 423 enum lan9118_error_t lan9118_read_mac_address(const struct lan9118_eth_dev_t* dev, char* mac); 424 425 /** 426 * \brief Check device ID. 427 * 428 * \return error code /ref lan9118_error_t 429 */ 430 int lan9118_check_id(const struct lan9118_eth_dev_t* dev); 431 432 /** 433 * \brief Sends data from the given buffer as an Ethernet packet. 434 * The full packet length must be specified at the beginning 435 * of a new packet transmission. 436 * 437 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 438 * \param[in] total_payload_length Length of the ethernet payload. 439 * Should be equal to the sum of passed buffers within a packet. 440 * \param[in] is_new_packet Should be set to true if the input buffer has to 441 * be sent as the start of a new packet or as a full packet. 442 * \param[in] data Pointer to the data buffer to be sent. 443 * \param[in] current_size Size of the data in bytes. 444 * 445 * \return error code /ref lan9118_error_t 446 */ 447 enum lan9118_error_t lan9118_send_by_chunks(const struct lan9118_eth_dev_t* dev, uint32_t total_payload_length, 448 bool is_new_packet, const char* data, uint32_t current_size); 449 450 /** 451 * \brief Reads an incoming Ethernet packet into the given buffer. 452 * Stops reading at packet border. 453 * 454 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 455 * \param[in,out] data Pointer to a pre-allocated input buffer. 456 * Allocating sufficient memory space is the caller's 457 * responsibility, which is typically done by calling 458 * \ref lan9118_peek_next_packet_size. 459 * \param[in] dlen Length of the allocated data in bytes. 460 * 461 * \return Number of bytes read from the Rx FIFO into the given buffer. 462 */ 463 uint32_t lan9118_receive_by_chunks(const struct lan9118_eth_dev_t* dev, char* data, uint32_t dlen); 464 465 /** 466 * \brief Get the used space of Rx fifo in bytes. 467 * 468 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 469 * 470 * \return Data received and waiting for read in bytes 471 */ 472 uint32_t lan9118_get_rxfifo_data_used_space(const struct lan9118_eth_dev_t* dev); 473 474 /** 475 * \brief Gets the size of next unread packet in Rx buffer, using the peak 476 * register, which is not destructive so can be read asynchronously. 477 * Warning: In case of heavy receiving loads, this register may not 478 * be in perfect sync. 479 * 480 * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t 481 * 482 * \return Size of the next packet in bytes, read from the Rx Peek register. 483 */ 484 uint32_t lan9118_peek_next_packet_size(const struct lan9118_eth_dev_t* dev); 485 486 /** \brief Allocates a buf and returns the data from the incoming 487 * packet. 488 * 489 * \return a buf filled with the received packet 490 * (including MAC header) 491 */ 492 struct pbuf* LowLevelInput(void); 493 494 /** 495 * \brief Sends the packet over the link 496 * 497 * That can not be called from an interrupt context. 498 * 499 * @param netif a pre-allocated netif structure 500 * @param buf Packet to be send 501 * @return True if the packet was send successfully, False otherwise 502 */ 503 err_t Lan9118LinkOut(struct netif* netif, struct pbuf* buf); 504 505 /** \brief Packet reception task 506 * 507 * This task is called when a packet is received. It will 508 * pass the packet to the Network Stack. 509 */ 510 void Lan9118PacketRx(void); 511 512 /** \brief interrupt called 513 * 514 * This task is handle rx data. 515 */ 516 void EthernetReceiveHandler(void); 517 518 /** 519 * \brief In this function, the hardware should be initialized. 520 * Called from EthernetifInit(). 521 * 522 * @param netif the already initialized lwip network interface structure 523 * for this ethernetif 524 */ 525 void LowLevelInit(struct netif* netif); 526 527 /** 528 * \brief Init net config 529 * 530 * This task is called when netif_add() 531 */ 532 err_t EthernetifInit(struct netif* netif); 533 534 /** 535 * \brief Init Lan9118 net 536 * 537 */ 538 void Lan9118NetInit(void); 539 540 /** 541 * \brief Init net 542 * 543 */ 544 void NetInit(void); 545 546 #endif /* __LAN9118_ETH_H__ */ 547