drivers: eth_smsc91x: Implement promiscuous mode
Add the RCR_PRMS field to toggle the promiscuous mode in the Ethernet controller. Register a set_config function that can make use of the field when CONFIG_NET_PROMISCUOUS_MODE is enabled. Signed-off-by: Ambroise Vincent <ambroise.vincent@arm.com>
This commit is contained in:
parent
4f88b831e7
commit
b6af1ac66e
2 changed files with 46 additions and 3 deletions
|
@ -678,7 +678,12 @@ static enum ethernet_hw_caps eth_smsc_get_caps(const struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T;
|
return (ETHERNET_LINK_10BASE_T
|
||||||
|
| ETHERNET_LINK_100BASE_T
|
||||||
|
#if defined(CONFIG_NET_PROMISCUOUS_MODE)
|
||||||
|
| ETHERNET_PROMISC_MODE
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eth_tx(const struct device *dev, struct net_pkt *pkt)
|
static int eth_tx(const struct device *dev, struct net_pkt *pkt)
|
||||||
|
@ -696,6 +701,42 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)
|
||||||
return smsc_send_pkt(sc, tx_buffer, len);
|
return smsc_send_pkt(sc, tx_buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int eth_smsc_set_config(const struct device *dev,
|
||||||
|
enum ethernet_config_type type,
|
||||||
|
const struct ethernet_config *config)
|
||||||
|
{
|
||||||
|
struct eth_context *data = dev->data;
|
||||||
|
struct smsc_data *sc = &data->sc;
|
||||||
|
uint8_t reg_val;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
(void) reg_val;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
#if defined(CONFIG_NET_PROMISCUOUS_MODE)
|
||||||
|
case ETHERNET_CONFIG_TYPE_PROMISC_MODE:
|
||||||
|
SMSC_LOCK(sc);
|
||||||
|
smsc_select_bank(sc, 0);
|
||||||
|
reg_val = smsc_read_1(sc, RCR);
|
||||||
|
if (config->promisc_mode && !(reg_val & RCR_PRMS)) {
|
||||||
|
smsc_write_1(sc, RCR, reg_val | RCR_PRMS);
|
||||||
|
} else if (!config->promisc_mode && (reg_val & RCR_PRMS)) {
|
||||||
|
smsc_write_1(sc, RCR, reg_val & ~RCR_PRMS);
|
||||||
|
} else {
|
||||||
|
ret = -EALREADY;
|
||||||
|
}
|
||||||
|
SMSC_UNLOCK(sc);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = -ENOTSUP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void eth_initialize(struct net_if *iface)
|
static void eth_initialize(struct net_if *iface)
|
||||||
{
|
{
|
||||||
const struct device *dev = net_if_get_device(iface);
|
const struct device *dev = net_if_get_device(iface);
|
||||||
|
@ -725,9 +766,10 @@ static void eth_initialize(struct net_if *iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ethernet_api api_funcs = {
|
static const struct ethernet_api api_funcs = {
|
||||||
.iface_api.init = eth_initialize,
|
.iface_api.init = eth_initialize,
|
||||||
.get_capabilities = eth_smsc_get_caps,
|
.get_capabilities = eth_smsc_get_caps,
|
||||||
.send = eth_tx,
|
.set_config = eth_smsc_set_config,
|
||||||
|
.send = eth_tx,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void eth_smsc_isr(const struct device *dev)
|
static void eth_smsc_isr(const struct device *dev)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
/* Bank 0, Offset 0x4: Receive Control Register */
|
/* Bank 0, Offset 0x4: Receive Control Register */
|
||||||
#define RCR 0x4
|
#define RCR 0x4
|
||||||
|
#define RCR_PRMS 0x0002 /* Promiscuous mode */
|
||||||
#define RCR_RXEN 0x0100 /* Enable/disable receiver */
|
#define RCR_RXEN 0x0100 /* Enable/disable receiver */
|
||||||
#define RCR_STRIP_CRC 0x0200 /* Strip CRC from RX packets */
|
#define RCR_STRIP_CRC 0x0200 /* Strip CRC from RX packets */
|
||||||
#define RCR_SOFT_RST 0x8000 /* Software reset */
|
#define RCR_SOFT_RST 0x8000 /* Software reset */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue