Skip to content

Commit

Permalink
Merge branch 'bugfix/dm9051_rcv_mcast_v4.4' into 'release/v4.4'
Browse files Browse the repository at this point in the history
esp_eth: allowed DM9051 to receive multicast packets (v4.4)

See merge request espressif/esp-idf!22865
  • Loading branch information
jack0c committed Mar 23, 2023
2 parents 4ffc7c6 + 88a2afc commit a3f285d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 42 deletions.
32 changes: 12 additions & 20 deletions components/esp_eth/src/dm9051.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

Expand Down Expand Up @@ -105,13 +97,13 @@ extern "C" {

#define TCR_TXREQ (1 << 0) // TX Request. Auto-Clear after Sending Completely

#define RCR_WTDIS (1 << 6) // Watchdog Timer Disable
#define RCR_DIS_LONG (1 << 5) // Discard Long Packet
#define RCR_DIS_CRC (1 << 4) // Discard CRC Error Packet
#define RCR_ALL (1 << 3) // Receive All Multicast
#define RCR_RUNT (1 << 2) // Receive Runt Packet
#define RCR_PRMSC (1 << 1) // Promiscuous Mode
#define RCR_RXEN (1 << 0) // RX Enable
#define RCR_WTDIS (1 << 6) // Watchdog Timer Disable
#define RCR_DIS_LONG (1 << 5) // Discard Long Packet
#define RCR_DIS_CRC (1 << 4) // Discard CRC Error Packet
#define RCR_ALL_MCAST (1 << 3) // Receive All Multicast
#define RCR_RUNT (1 << 2) // Receive Runt Packet
#define RCR_PRMSC (1 << 1) // Promiscuous Mode
#define RCR_RXEN (1 << 0) // RX Enable

#define RSR_RF (1 << 7) // Runt Frame
#define RSR_MF (1 << 6) // Multicast Frame
Expand Down
29 changes: 7 additions & 22 deletions components/esp_eth/src/esp_eth_mac_dm9051.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ static esp_err_t dm9051_setup_default(emac_dm9051_t *emac)
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_WCR, 0x00), err, TAG, "write WCR failed");
/* stop transmitting, enable appending pad, crc for packets */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_TCR, 0x00), err, TAG, "write TCR failed");
/* stop receiving, no promiscuous mode, no runt packet(size < 64bytes), not all multicast packets*/
/* stop receiving, no promiscuous mode, no runt packet(size < 64bytes), receive all multicast packets */
/* discard long packet(size > 1522bytes) and crc error packet, enable watchdog */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_RCR, RCR_DIS_LONG | RCR_DIS_CRC), err, TAG, "write RCR failed");
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_ALL_MCAST), err, TAG, "write RCR failed");
/* retry late collision packet, at most two transmit command can be issued before transmit complete */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_TCR2, TCR2_RLCP), err, TAG, "write TCR2 failed");
/* enable auto transmit */
Expand All @@ -304,12 +304,8 @@ static esp_err_t dm9051_setup_default(emac_dm9051_t *emac)
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_RLENCR, 0x00), err, TAG, "write RLENCR failed");
/* 3K-byte for TX and 13K-byte for RX */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MEMSCR, 0x00), err, TAG, "write MEMSCR failed");
/* reset tx and rx memory pointer */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX | MPTRCR_RST_TX), err, TAG, "write MPTRCR failed");
/* clear network status: wakeup event, tx complete */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END), err, TAG, "write NSR failed");
/* clear interrupt status */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_ISR, ISR_CLR_STATUS), err, TAG, "write ISR failed");
return ESP_OK;
err:
return ret;
Expand Down Expand Up @@ -341,6 +337,10 @@ static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac)
{
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
/* reset tx and rx memory pointer */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX | MPTRCR_RST_TX), err, TAG, "write MPTRCR failed");
/* clear interrupt status */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_ISR, ISR_CLR_STATUS), err, TAG, "write ISR failed");
/* enable only Rx related interrupts as others are processed synchronously */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_IMR, IMR_PAR | IMR_PRI), err, TAG, "write IMR failed");
/* enable rx */
Expand Down Expand Up @@ -514,16 +514,11 @@ static esp_err_t emac_dm9051_get_addr(esp_eth_mac_t *mac, uint8_t *addr)
static esp_err_t emac_dm9051_set_link(esp_eth_mac_t *mac, eth_link_t link)
{
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
uint8_t nsr = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_NSR, &nsr), err, TAG, "read NSR failed");
switch (link) {
case ETH_LINK_UP:
ESP_GOTO_ON_FALSE(nsr & NSR_LINKST, ESP_ERR_INVALID_STATE, err, TAG, "phy is not link up");
ESP_GOTO_ON_ERROR(mac->start(mac), err, TAG, "dm9051 start failed");
break;
case ETH_LINK_DOWN:
ESP_GOTO_ON_FALSE(!(nsr & NSR_LINKST), ESP_ERR_INVALID_STATE, err, TAG, "phy is not link down");
ESP_GOTO_ON_ERROR(mac->stop(mac), err, TAG, "dm9051 stop failed");
break;
default:
Expand All @@ -538,16 +533,11 @@ static esp_err_t emac_dm9051_set_link(esp_eth_mac_t *mac, eth_link_t link)
static esp_err_t emac_dm9051_set_speed(esp_eth_mac_t *mac, eth_speed_t speed)
{
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
uint8_t nsr = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_NSR, &nsr), err, TAG, "read NSR failed");
switch (speed) {
case ETH_SPEED_10M:
ESP_GOTO_ON_FALSE(nsr & NSR_SPEED, ESP_ERR_INVALID_STATE, err, TAG, "phy speed is not at 10Mbps");
ESP_LOGD(TAG, "working in 10Mbps");
break;
case ETH_SPEED_100M:
ESP_GOTO_ON_FALSE(!(nsr & NSR_SPEED), ESP_ERR_INVALID_STATE, err, TAG, "phy speed is not at 100Mbps");
ESP_LOGD(TAG, "working in 100Mbps");
break;
default:
Expand All @@ -562,17 +552,12 @@ static esp_err_t emac_dm9051_set_speed(esp_eth_mac_t *mac, eth_speed_t speed)
static esp_err_t emac_dm9051_set_duplex(esp_eth_mac_t *mac, eth_duplex_t duplex)
{
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
uint8_t ncr = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_NCR, &ncr), err, TAG, "read NCR failed");
switch (duplex) {
case ETH_DUPLEX_HALF:
ESP_LOGD(TAG, "working in half duplex");
ESP_GOTO_ON_FALSE(!(ncr & NCR_FDX), ESP_ERR_INVALID_STATE, err, TAG, "phy is not at half duplex");
break;
case ETH_DUPLEX_FULL:
ESP_LOGD(TAG, "working in full duplex");
ESP_GOTO_ON_FALSE(ncr & NCR_FDX, ESP_ERR_INVALID_STATE, err, TAG, "phy is not at full duplex");
break;
default:
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "unknown duplex");
Expand All @@ -588,7 +573,7 @@ static esp_err_t emac_dm9051_set_promiscuous(esp_eth_mac_t *mac, bool enable)
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
uint8_t rcr = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPDRL, &rcr), err, TAG, "read RCR failed");
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_RCR, &rcr), err, TAG, "read RCR failed");
if (enable) {
rcr |= RCR_PRMSC;
} else {
Expand Down

0 comments on commit a3f285d

Please sign in to comment.