diff -u -r -N sys/mips/atheros/ar71xx_chip.c sys/mips/atheros/ar71xx_chip.c
--- sys/mips/atheros/ar71xx_chip.c 2018-07-07 20:50:12.824244000 +0200
+++ sys/mips/atheros/ar71xx_chip.c 2018-07-08 03:11:21.359088000 +0200
@@ -147,13 +147,15 @@
void
ar71xx_chip_set_mii_speed(uint32_t unit, uint32_t speed)
{
- uint32_t val, reg, ctrl;
+ uint32_t val;
+ uint32_t reg;
+ uint32_t ctrl;
switch (unit) {
- case 0:
+ case AR71XX_GE0:
reg = AR71XX_MII0_CTRL;
break;
- case 1:
+ case AR71XX_GE1:
reg = AR71XX_MII1_CTRL;
break;
default:
@@ -163,13 +165,13 @@
}
switch (speed) {
- case 10:
+ case AR71XX_GE_SPEED_10:
ctrl = MII_CTRL_SPEED_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
ctrl = MII_CTRL_SPEED_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
ctrl = MII_CTRL_SPEED_1000;
break;
default:
@@ -187,10 +189,12 @@
void
ar71xx_chip_set_mii_if(uint32_t unit, uint32_t mii_mode)
{
- uint32_t val, reg, mii_if;
+ uint32_t val;
+ uint32_t reg;
+ uint32_t mii_if;
switch (unit) {
- case 0:
+ case AR71XX_GE0:
reg = AR71XX_MII0_CTRL;
if (mii_mode == AR71XX_MII_MODE_GMII)
mii_if = MII0_CTRL_IF_GMII;
@@ -206,7 +210,7 @@
return;
}
break;
- case 1:
+ case AR71XX_GE1:
reg = AR71XX_MII1_CTRL;
if (mii_mode == AR71XX_MII_MODE_RGMII)
mii_if = MII1_CTRL_IF_RGMII;
@@ -236,12 +240,12 @@
{
switch (unit) {
- case 0:
+ case AR71XX_GE0:
ar71xx_write_pll(AR71XX_PLL_SEC_CONFIG,
AR71XX_PLL_ETH_INT0_CLK, pll,
AR71XX_PLL_ETH0_SHIFT);
break;
- case 1:
+ case AR71XX_GE1:
ar71xx_write_pll(AR71XX_PLL_SEC_CONFIG,
AR71XX_PLL_ETH_INT1_CLK, pll,
AR71XX_PLL_ETH1_SHIFT);
@@ -282,13 +286,13 @@
uint32_t pll;
switch (speed) {
- case 10:
+ case AR71XX_GE_SPEED_10:
pll = PLL_ETH_INT_CLK_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
pll = PLL_ETH_INT_CLK_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
pll = PLL_ETH_INT_CLK_1000;
break;
default:
diff -u -r -N sys/mips/atheros/ar71xx_cpudef.h sys/mips/atheros/ar71xx_cpudef.h
--- sys/mips/atheros/ar71xx_cpudef.h 2018-07-07 20:50:12.221249000 +0200
+++ sys/mips/atheros/ar71xx_cpudef.h 2018-07-10 18:48:29.187711000 +0200
@@ -82,82 +82,97 @@
extern struct ar71xx_cpu_def * ar71xx_cpu_ops;
-static inline void ar71xx_detect_sys_frequency(void)
+static inline void
+ar71xx_detect_sys_frequency(void)
{
ar71xx_cpu_ops->detect_sys_frequency();
}
-static inline void ar71xx_device_stop(uint32_t mask)
+static inline void
+ar71xx_device_stop(uint32_t mask)
{
ar71xx_cpu_ops->ar71xx_chip_device_stop(mask);
}
-static inline void ar71xx_device_start(uint32_t mask)
+static inline void
+ar71xx_device_start(uint32_t mask)
{
ar71xx_cpu_ops->ar71xx_chip_device_start(mask);
}
-static inline int ar71xx_device_stopped(uint32_t mask)
+static inline int
+ar71xx_device_stopped(uint32_t mask)
{
return ar71xx_cpu_ops->ar71xx_chip_device_stopped(mask);
}
-static inline void ar71xx_device_set_pll_ge(int unit, int speed, uint32_t pll)
+static inline void
+ar71xx_device_set_pll_ge(int unit, int speed, uint32_t pll)
{
ar71xx_cpu_ops->ar71xx_chip_set_pll_ge(unit, speed, pll);
}
-static inline void ar71xx_device_set_mii_speed(int unit, int speed)
+static inline void
+ar71xx_device_set_mii_speed(int unit, int speed)
{
ar71xx_cpu_ops->ar71xx_chip_set_mii_speed(unit, speed);
}
-static inline void ar71xx_device_set_mii_if(int unit, ar71xx_mii_mode mii_cfg)
+static inline void
+ar71xx_device_set_mii_if(int unit, ar71xx_mii_mode mii_cfg)
{
ar71xx_cpu_ops->ar71xx_chip_set_mii_if(unit, mii_cfg);
}
-static inline void ar71xx_device_flush_ddr(ar71xx_flush_ddr_id_t id)
+static inline void
+ar71xx_device_flush_ddr(ar71xx_flush_ddr_id_t id)
{
ar71xx_cpu_ops->ar71xx_chip_ddr_flush(id);
}
-static inline uint32_t ar71xx_device_get_eth_pll(unsigned int unit, int speed)
+static inline uint32_t
+ar71xx_device_get_eth_pll(unsigned int unit, int speed)
{
return (ar71xx_cpu_ops->ar71xx_chip_get_eth_pll(unit, speed));
}
-static inline void ar71xx_init_usb_peripheral(void)
+static inline void
+ar71xx_init_usb_peripheral(void)
{
ar71xx_cpu_ops->ar71xx_chip_init_usb_peripheral();
}
-static inline void ar71xx_reset_ethernet_switch(void)
+static inline void
+ar71xx_reset_ethernet_switch(void)
{
if (ar71xx_cpu_ops->ar71xx_chip_reset_ethernet_switch)
ar71xx_cpu_ops->ar71xx_chip_reset_ethernet_switch();
}
-static inline void ar71xx_reset_wmac(void)
+static inline void
+ar71xx_reset_wmac(void)
{
if (ar71xx_cpu_ops->ar71xx_chip_reset_wmac)
ar71xx_cpu_ops->ar71xx_chip_reset_wmac();
}
-static inline void ar71xx_init_gmac(void)
+static inline void
+ar71xx_init_gmac(void)
{
if (ar71xx_cpu_ops->ar71xx_chip_init_gmac)
ar71xx_cpu_ops->ar71xx_chip_init_gmac();
}
-static inline void ar71xx_reset_nfc(int active)
+static inline void
+ar71xx_reset_nfc(int active)
{
if (ar71xx_cpu_ops->ar71xx_chip_reset_nfc)
ar71xx_cpu_ops->ar71xx_chip_reset_nfc(active);
}
-static inline void ar71xx_gpio_ouput_configure(int gpio, uint8_t func)
+static inline void
+ar71xx_gpio_ouput_configure(int gpio, uint8_t func)
{
if (ar71xx_cpu_ops->ar71xx_chip_gpio_out_configure)
ar71xx_cpu_ops->ar71xx_chip_gpio_out_configure(gpio, func);
@@ -172,12 +187,46 @@
extern uint32_t u_ar71xx_wdt_freq;
extern uint32_t u_ar71xx_mdio_freq;
-static inline uint64_t ar71xx_refclk(void) { return u_ar71xx_refclk; }
-static inline uint64_t ar71xx_cpu_freq(void) { return u_ar71xx_cpu_freq; }
-static inline uint64_t ar71xx_ahb_freq(void) { return u_ar71xx_ahb_freq; }
-static inline uint64_t ar71xx_ddr_freq(void) { return u_ar71xx_ddr_freq; }
-static inline uint64_t ar71xx_uart_freq(void) { return u_ar71xx_uart_freq; }
-static inline uint64_t ar71xx_wdt_freq(void) { return u_ar71xx_wdt_freq; }
-static inline uint64_t ar71xx_mdio_freq(void) { return u_ar71xx_mdio_freq; }
+static inline uint64_t
+ar71xx_refclk(void)
+{
+ return u_ar71xx_refclk;
+}
+
+static inline uint64_t
+ar71xx_cpu_freq(void)
+{
+ return u_ar71xx_cpu_freq;
+}
+
+static inline uint64_t
+ar71xx_ahb_freq(void)
+{
+ return u_ar71xx_ahb_freq;
+}
+
+static inline uint64_t
+ar71xx_ddr_freq(void)
+{
+ return u_ar71xx_ddr_freq;
+}
+
+static inline uint64_t
+ar71xx_uart_freq(void)
+{
+ return u_ar71xx_uart_freq;
+}
+
+static inline uint64_t
+ar71xx_wdt_freq(void)
+{
+ return u_ar71xx_wdt_freq;
+}
+
+static inline uint64_t
+ar71xx_mdio_freq(void)
+{
+ return u_ar71xx_mdio_freq;
+}
#endif
diff -u -r -N sys/mips/atheros/ar71xx_macaddr.c sys/mips/atheros/ar71xx_macaddr.c
--- sys/mips/atheros/ar71xx_macaddr.c 2018-07-07 20:50:15.479230000 +0200
+++ sys/mips/atheros/ar71xx_macaddr.c 2018-07-09 23:49:15.371993000 +0200
@@ -35,6 +35,8 @@
#include <net/ethernet.h>
+#include <sys/bus.h>
+
#include <mips/atheros/ar71xx_macaddr.h>
/*
@@ -61,9 +63,10 @@
int t;
if (dst == NULL || src == NULL)
- return (-1);
+ return (EINVAL);
- /* XXX TODO: validate 'src' is a valid MAC address */
+ if (ETHER_IS_MULTICAST(src) != 0)
+ return (-1);
t = (((uint32_t) src[3]) << 16)
+ (((uint32_t) src[4]) << 8)
@@ -108,3 +111,110 @@
return (0);
}
+
+/*
+ * Initialize MAC Address by hints mechanism.
+ *
+ * Returns 1 if MAC Address exists, 0 if not.
+ */
+int
+ar71xx_mac_addr_hint_init(device_t dev, unsigned char *addr)
+{
+ char dev_id[32];
+ char * mac_addr;
+ uint32_t tmp_addr[ETHER_ADDR_LEN];
+ int count;
+ int i;
+ int local_mac;
+
+ (void)snprintf(dev_id, 32, "hint.%s.%d.macaddr",
+ device_get_name(dev), device_get_unit(dev));
+
+ if ((mac_addr = kern_getenv(dev_id)) != NULL) {
+ /* Have a MAC address; should use it. */
+ device_printf(dev, "Overriding MAC address "
+ "from environment: '%s'\n", mac_addr);
+
+ /* Extract out the MAC address. */
+ count = sscanf(mac_addr,
+ "%x%*c%x%*c%x%*c%x%*c%x%*c%x",
+ &tmp_addr[0], &tmp_addr[1],
+ &tmp_addr[2], &tmp_addr[3],
+ &tmp_addr[4], &tmp_addr[5]);
+
+ /* Valid! */
+ if (count == ETHER_ADDR_LEN) {
+ for (i = 0; i < count; i++)
+ addr[i] = tmp_addr[i];
+
+ local_mac = 1;
+ } else
+ local_mac = 0;
+
+ /* Done! */
+ freeenv(mac_addr);
+ mac_addr = NULL;
+ } else
+ local_mac = 0;
+
+ return (local_mac);
+}
+
+/*
+ * Initialize MAC Address by reading EEPROM.
+ *
+ * Some units (eg the TP-Link WR-1043ND) do not have a convenient
+ * EEPROM location to read the ethernet MAC address from.
+ * OpenWRT simply snaffles it from a fixed location.
+ *
+ * Since multiple units seem to use this feature, include
+ * a method of setting the MAC address based on an flash location
+ * in CPU address space.
+ *
+ * Some vendors have decided to store the mac address as a literal
+ * string of 18 characters in xx:xx:xx:xx:xx:xx format instead of
+ * an array of numbers. Expose a hint to turn on this conversion
+ * feature via strtol().
+ *
+ * Returns 1 if MAC Address exists, 0 if not.
+ */
+int
+ar71xx_mac_addr_eeprom_init(device_t dev, unsigned char *addr)
+{
+ const char *name;
+ int unit;
+ long eeprom_mac_addr;
+ const char *mac_addr;
+ int readascii;
+ int i;
+ int local_mac;
+
+ name = device_get_name(dev);
+ unit = device_get_unit(dev);
+ eeprom_mac_addr = 0;
+
+ if (resource_long_value(name, unit,
+ "eeprommac", &eeprom_mac_addr) == 0) {
+ device_printf(dev, "Overriding MAC from EEPROM\n");
+
+ mac_addr = (const char *)MIPS_PHYS_TO_KSEG1(eeprom_mac_addr);
+ readascii = 0;
+
+ if (resource_int_value(name, unit,
+ "readascii", &readascii) == 0) {
+ device_printf(dev, "Vendor stores MAC in ASCII format\n");
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ addr[i] = strtol(&(mac_addr[i*3]), NULL, 16);
+ }
+ } else {
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ addr[i] = mac_addr[i];
+ }
+ }
+ local_mac = 1;
+ } else
+ local_mac = 0;
+
+ return (local_mac);
+}
diff -u -r -N sys/mips/atheros/ar71xx_macaddr.h sys/mips/atheros/ar71xx_macaddr.h
--- sys/mips/atheros/ar71xx_macaddr.h 2018-07-07 20:50:15.231507000 +0200
+++ sys/mips/atheros/ar71xx_macaddr.h 2018-07-06 23:03:17.000000000 +0200
@@ -35,5 +35,6 @@
extern int ar71xx_mac_addr_init(unsigned char *dst, const unsigned char *src,
int offset, int is_local);
extern int ar71xx_mac_addr_random_init(unsigned char *dst);
-
+extern int ar71xx_mac_addr_hint_init(device_t dev, unsigned char *addr);
+extern int ar71xx_mac_addr_eeprom_init(device_t dev, unsigned char *addr);
#endif /* __ATHEROS_AR71XX_MACADDR_H__ */
diff -u -r -N sys/mips/atheros/ar71xxreg.h sys/mips/atheros/ar71xxreg.h
--- sys/mips/atheros/ar71xxreg.h 2018-07-07 20:50:15.191989000 +0200
+++ sys/mips/atheros/ar71xxreg.h 2018-07-10 01:39:00.458571000 +0200
@@ -31,6 +31,13 @@
#ifndef _AR71XX_REG_H_
#define _AR71XX_REG_H_
+#define AR71XX_GE0 0
+#define AR71XX_GE1 1
+
+#define AR71XX_GE_SPEED_10 10
+#define AR71XX_GE_SPEED_100 100
+#define AR71XX_GE_SPEED_1000 1000
+
/* PCI region */
#define AR71XX_PCI_MEM_BASE 0x10000000
/*
diff -u -r -N sys/mips/atheros/ar724x_chip.c sys/mips/atheros/ar724x_chip.c
--- sys/mips/atheros/ar724x_chip.c 2018-07-07 20:50:12.705614000 +0200
+++ sys/mips/atheros/ar724x_chip.c 2018-07-08 02:57:57.865243000 +0200
@@ -147,10 +147,10 @@
{
switch (unit) {
- case 0:
+ case AR71XX_GE0:
/* XXX TODO */
break;
- case 1:
+ case AR71XX_GE1:
/* XXX TODO */
break;
default:
diff -u -r -N sys/mips/atheros/ar91xx_chip.c sys/mips/atheros/ar91xx_chip.c
--- sys/mips/atheros/ar91xx_chip.c 2018-07-07 20:50:12.710871000 +0200
+++ sys/mips/atheros/ar91xx_chip.c 2018-07-08 02:52:21.980940000 +0200
@@ -120,12 +120,12 @@
{
switch (unit) {
- case 0:
+ case AR71XX_GE0:
ar71xx_write_pll(AR91XX_PLL_REG_ETH_CONFIG,
AR91XX_PLL_REG_ETH0_INT_CLOCK, pll,
AR91XX_ETH0_PLL_SHIFT);
break;
- case 1:
+ case AR71XX_GE1:
ar71xx_write_pll(AR91XX_PLL_REG_ETH_CONFIG,
AR91XX_PLL_REG_ETH1_INT_CLOCK, pll,
AR91XX_ETH1_PLL_SHIFT);
@@ -165,14 +165,14 @@
{
uint32_t pll;
- switch(speed) {
- case 10:
+ switch (speed) {
+ case AR71XX_GE_SPEED_10:
pll = AR91XX_PLL_VAL_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
pll = AR91XX_PLL_VAL_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
pll = AR91XX_PLL_VAL_1000;
break;
default:
diff -u -r -N sys/mips/atheros/ar933x_chip.c sys/mips/atheros/ar933x_chip.c
--- sys/mips/atheros/ar933x_chip.c 2018-07-07 20:50:15.205875000 +0200
+++ sys/mips/atheros/ar933x_chip.c 2018-07-08 03:11:03.367354000 +0200
@@ -179,10 +179,10 @@
{
switch (unit) {
- case 0:
+ case AR71XX_GE0:
/* XXX TODO */
break;
- case 1:
+ case AR71XX_GE1:
/* XXX TODO */
break;
default:
@@ -222,13 +222,13 @@
uint32_t pll;
switch (speed) {
- case 10:
+ case AR71XX_GE_SPEED_10:
pll = AR933X_PLL_VAL_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
pll = AR933X_PLL_VAL_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
pll = AR933X_PLL_VAL_1000;
break;
default:
diff -u -r -N sys/mips/atheros/ar934x_chip.c sys/mips/atheros/ar934x_chip.c
--- sys/mips/atheros/ar934x_chip.c 2018-07-07 20:50:15.208885000 +0200
+++ sys/mips/atheros/ar934x_chip.c 2018-07-08 03:16:39.557796000 +0200
@@ -247,10 +247,10 @@
{
switch (unit) {
- case 0:
+ case AR71XX_GE0:
ATH_WRITE_REG(AR934X_PLL_ETH_XMII_CONTROL_REG, pll);
break;
- case 1:
+ case AR71XX_GE1:
/* XXX nothing */
break;
default:
@@ -293,13 +293,13 @@
uint32_t pll;
switch (speed) {
- case 10:
+ case AR71XX_GE_SPEED_10:
pll = AR934X_PLL_VAL_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
pll = AR934X_PLL_VAL_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
pll = AR934X_PLL_VAL_1000;
break;
default:
diff -u -r -N sys/mips/atheros/if_arge.c sys/mips/atheros/if_arge.c
--- sys/mips/atheros/if_arge.c 2018-07-09 18:58:16.785548000 +0200
+++ sys/mips/atheros/if_arge.c 2018-07-11 22:44:12.383726000 +0200
@@ -55,6 +55,7 @@
#include <net/if.h>
#include <net/if_var.h>
+#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/ethernet.h>
#include <net/if_types.h>
@@ -143,6 +144,7 @@
static void arge_link_task(void *, int);
static void arge_update_link_locked(struct arge_softc *sc);
static void arge_set_pll(struct arge_softc *, int, int);
+static void arge_rxfilter(struct arge_softc *sc);
static int arge_miibus_readreg(device_t, int, int);
static void arge_miibus_statchg(device_t);
static int arge_miibus_writereg(device_t, int, int, int);
@@ -258,10 +260,10 @@
arge_flush_ddr(struct arge_softc *sc)
{
switch (sc->arge_mac_unit) {
- case 0:
+ case AR71XX_GE0:
ar71xx_device_flush_ddr(AR71XX_CPU_DDR_FLUSH_GE0);
break;
- case 1:
+ case AR71XX_GE1:
ar71xx_device_flush_ddr(AR71XX_CPU_DDR_FLUSH_GE1);
break;
default:
@@ -641,15 +643,10 @@
struct arge_softc *sc;
int error = 0, rid, i;
uint32_t hint;
- long eeprom_mac_addr = 0;
int miicfg = 0;
- int readascii = 0;
- int local_mac = 0;
+ int local_mac;
uint8_t local_macaddr[ETHER_ADDR_LEN];
- char * local_macstr;
- char devid_str[32];
- int count;
-
+
sc = device_get_softc(dev);
sc->arge_dev = dev;
sc->arge_mac_unit = device_get_unit(dev);
@@ -662,32 +659,7 @@
* routines, but at the moment the system is booting, the resource hints
* are set to the 'static' map so they're not pulling from kenv.
*/
- snprintf(devid_str, 32, "hint.%s.%d.macaddr",
- device_get_name(dev),
- device_get_unit(dev));
- if ((local_macstr = kern_getenv(devid_str)) != NULL) {
- uint32_t tmpmac[ETHER_ADDR_LEN];
-
- /* Have a MAC address; should use it */
- device_printf(dev, "Overriding MAC address from environment: '%s'\n",
- local_macstr);
-
- /* Extract out the MAC address */
- /* XXX this should all be a generic method */
- count = sscanf(local_macstr, "%x%*c%x%*c%x%*c%x%*c%x%*c%x",
- &tmpmac[0], &tmpmac[1],
- &tmpmac[2], &tmpmac[3],
- &tmpmac[4], &tmpmac[5]);
- if (count == 6) {
- /* Valid! */
- local_mac = 1;
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- local_macaddr[i] = tmpmac[i];
- }
- /* Done! */
- freeenv(local_macstr);
- local_macstr = NULL;
- }
+ local_mac = ar71xx_mac_addr_hint_init(dev, local_macaddr);
/*
* Hardware workarounds.
@@ -726,25 +698,8 @@
* an array of numbers. Expose a hint to turn on this conversion
* feature via strtol()
*/
- if (local_mac == 0 && resource_long_value(device_get_name(dev),
- device_get_unit(dev), "eeprommac", &eeprom_mac_addr) == 0) {
- local_mac = 1;
- int i;
- const char *mac =
- (const char *) MIPS_PHYS_TO_KSEG1(eeprom_mac_addr);
- device_printf(dev, "Overriding MAC from EEPROM\n");
- if (resource_int_value(device_get_name(dev), device_get_unit(dev),
- "readascii", &readascii) == 0) {
- device_printf(dev, "Vendor stores MAC in ASCII format\n");
- for (i = 0; i < 6; i++) {
- local_macaddr[i] = strtol(&(mac[i*3]), NULL, 16);
- }
- } else {
- for (i = 0; i < 6; i++) {
- local_macaddr[i] = mac[i];
- }
- }
- }
+ if (local_mac == 0)
+ local_mac = ar71xx_mac_addr_eeprom_init(dev, local_macaddr);
KASSERT(((sc->arge_mac_unit == 0) || (sc->arge_mac_unit == 1)),
("if_arge: Only MAC0 and MAC1 supported"));
@@ -790,11 +745,11 @@
"media", &hint) != 0)
hint = 0;
- if (hint == 1000)
+ if (hint == AR71XX_GE_SPEED_1000)
sc->arge_media_type = IFM_1000_T;
- else if (hint == 100)
+ else if (hint == AR71XX_GE_SPEED_100)
sc->arge_media_type = IFM_100_TX;
- else if (hint == 10)
+ else if (hint == AR71XX_GE_SPEED_10)
sc->arge_media_type = IFM_10_T;
else
sc->arge_media_type = 0;
@@ -867,8 +822,12 @@
/* If there's a local mac defined, copy that in */
if (local_mac == 1) {
- (void) ar71xx_mac_addr_init(sc->arge_eaddr,
- local_macaddr, 0, 0);
+ if (ar71xx_mac_addr_init(sc->arge_eaddr,
+ local_macaddr, 0, 0) != 0) {
+ device_printf(dev,
+ "Generating random ethernet address.\n");
+ (void) ar71xx_mac_addr_random_init(sc->arge_eaddr);
+ }
} else {
/*
* No MAC address configured. Generate the random one.
@@ -941,6 +900,11 @@
ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x00001fff);
}
+ /*
+ * If bit of AR71XX_MAC_FIFO_RX_FILTMATCH does
+ * not match with AR71XX_MAC_FIFO_RX_FILTMASK
+ * then the frame is dropped.
+ */
ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH,
FIFO_RX_FILTMATCH_DEFAULT);
@@ -1274,21 +1238,21 @@
switch(media) {
case IFM_10_T:
cfg |= MAC_CFG2_IFACE_MODE_10_100;
- if_speed = 10;
+ if_speed = AR71XX_GE_SPEED_10;
break;
case IFM_100_TX:
cfg |= MAC_CFG2_IFACE_MODE_10_100;
ifcontrol |= MAC_IFCONTROL_SPEED;
- if_speed = 100;
+ if_speed = AR71XX_GE_SPEED_100;
break;
case IFM_1000_T:
case IFM_1000_SX:
cfg |= MAC_CFG2_IFACE_MODE_1000;
rx_filtmask |= FIFO_RX_MASK_BYTE_MODE;
- if_speed = 1000;
+ if_speed = AR71XX_GE_SPEED_1000;
break;
default:
- if_speed = 100;
+ if_speed = AR71XX_GE_SPEED_100;
device_printf(sc->arge_dev,
"Unknown media %d\n", media);
}
@@ -1330,11 +1294,11 @@
ARGEDEBUG(sc, ARGE_DBG_PLL, "%s: pll=0x%x\n", __func__, pll);
/* Override if required by platform data */
- if (if_speed == 10 && sc->arge_pllcfg.pll_10 != 0)
+ if (if_speed == AR71XX_GE_SPEED_10 && sc->arge_pllcfg.pll_10 != 0)
pll = sc->arge_pllcfg.pll_10;
- else if (if_speed == 100 && sc->arge_pllcfg.pll_100 != 0)
+ else if (if_speed == AR71XX_GE_SPEED_100 && sc->arge_pllcfg.pll_100 != 0)
pll = sc->arge_pllcfg.pll_100;
- else if (if_speed == 1000 && sc->arge_pllcfg.pll_1000 != 0)
+ else if (if_speed == AR71XX_GE_SPEED_1000 && sc->arge_pllcfg.pll_1000 != 0)
pll = sc->arge_pllcfg.pll_1000;
ARGEDEBUG(sc, ARGE_DBG_PLL, "%s: final pll=0x%x\n", __func__, pll);
@@ -1357,6 +1321,34 @@
#endif
}
+/*
+ * Enable / disable promiscuous, multicast or broadcast flags.
+ */
+static void
+arge_rxfilter(struct arge_softc *sc)
+{
+ struct ifnet *ifp;
+ uint32_t rxcfg;
+
+ ARGE_LOCK_ASSERT(sc);
+
+ ifp = sc->arge_ifp;
+
+ rxcfg = ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK);
+ rxcfg &= ~(FIFO_RX_MASK_BCAST|FIFO_RX_MASK_MCAST);
+
+ if ((ifp->if_flags & IFF_BROADCAST) != 0)
+ rxcfg |= FIFO_RX_MASK_BCAST;
+
+ if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
+ if ((ifp->if_flags & IFF_PROMISC) != 0)
+ rxcfg |= (FIFO_RX_MASK_BCAST|FIFO_RX_MASK_MCAST);
+ if ((ifp->if_flags & IFF_ALLMULTI) != 0)
+ rxcfg |= FIFO_RX_MASK_MCAST;
+ }
+
+ ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, rxcfg);
+}
static void
arge_reset_dma(struct arge_softc *sc)
@@ -1424,7 +1416,22 @@
return;
}
+ /* Setup MAC address */
+ if (ar71xx_mac_addr_init(sc->arge_eaddr,
+ IF_LLADDR(ifp), 0, 0) != 0) {
+ device_printf(sc->arge_dev,
+ "initialization failed: invalid MAC Address\n");
+ arge_stop(sc);
+ return;
+ }
+ ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, (sc->arge_eaddr[2] << 24)
+ | (sc->arge_eaddr[3] << 16) | (sc->arge_eaddr[4] << 8)
+ | sc->arge_eaddr[5]);
+ ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (sc->arge_eaddr[0] << 8)
+ | sc->arge_eaddr[1]);
+ /* Setup rx filter */
+ arge_rxfilter(sc);
/* Init tx descriptors. */
arge_tx_ring_init(sc);
@@ -1738,7 +1745,7 @@
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
if (((ifp->if_flags ^ sc->arge_if_flags)
& (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
- /* XXX: handle promisc & multi flags */
+ arge_rxfilter(sc);
}
} else {
@@ -1755,7 +1762,9 @@
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
- /* XXX: implement SIOCDELMULTI */
+ ARGE_LOCK(sc);
+ arge_rxfilter(sc);
+ ARGE_UNLOCK(sc);
error = 0;
break;
case SIOCGIFMEDIA:
diff -u -r -N--- sys/mips/atheros/qca953x_chip.c sys/mips/atheros/qca953x_chip.car71xxreg.h 2018-07-07 20:50:15.191989000 +0200
---+++ sys/mips/atheros/qca953x_chip.car71xxreg.h 2018-07-07 20:50:13.24820910 01:39:00.458571000 +0200
+++ sys/mips/atheros/qca953x_chip.c 2018-07-08 03:19:45.864113000 +0200@@ -31,6 +31,13 @@
@@ -192,10 +192,10 @@
qca953x_chip_set_pll_ge(int unit, int speed, uint32_t pll)#ifndef _AR71XX_REG_H_
{#define _AR71XX_REG_H_
switch (unit) {
- case 0:
+ case AR71XX_GE0:
ATH_WRITE_REG(QCA953X_PLL_ETH_XMII_CONTROL_REG, pll);
break;
- case 1:
+ case AR71XX_GE1:
/* nothing */
break;
default:
@@ -236,13 +236,13 @@
uint32_t pll;
switch (speed) {+#define AR71XX_GE0 0
- case 10:+#define AR71XX_GE1 1
+ case AR71XX_GE_SPEED_10:
pll = QCA953X_PLL_VAL_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
pll = QCA953X_PLL_VAL_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
pll = QCA953X_PLL_VAL_1000;
break;
default:
diff -u -r -N sys/mips/atheros/qca955x_chip.c sys/mips/atheros/qca955x_chip.c
--- sys/mips/atheros/qca955x_chip.c 2018-07-07 20:50:15.473144000 +0200
+++ sys/mips/atheros/qca955x_chip.c 2018-07-11 01:57:22.190237000 +0200
@@ -184,19 +184,48 @@
static void
qca955x_chip_set_mii_speed(uint32_t unit, uint32_t speed)
{
+ uint32_t reg;
+ uint32_t pll;
- /* XXX TODO */
- return;
+ switch (unit) {
+ case AR71XX_GE0:
+ reg = QCA955X_PLL_ETH_XMII_CONTROL_REG;
+ break;
+ case AR71XX_GE1:
+ reg = QCA955X_PLL_ETH_SGMII_CONTROL_REG;
+ break;
+ default:
+ printf("%s: invalid MII unit set for arge unit: %d\n",
+ __func__, unit);
+ return;
+ }
+
+ switch (speed) {+#define AR71XX_GE_SPEED_10 10
+ cas+#define AR71XX_GE_SPEED_10:100 100
+ pll = QCA955X_PLL_VAL_10;+#define AR71XX_GE_SPEED_1000 1000
+ break;
+ case AR71XX_GE_SPEED_100:
+ pll = QCA955X_PLL_VAL_100;
+ break;
+ case AR71XX_GE_SPEED_1000:
+ pll = QCA955X_PLL_VAL_1000;
+ break;
+ default:
+ printf("%s%d: invalid speed %d\n", __func__, unit, speed);
+ return;
+ }
+
+ ATH_WRITE_REG(reg, pll);
}/* PCI region */
static void#define AR71XX_PCI_MEM_BASE 0x10000000
qca955x_chip_set_pll_ge(int unit, int speed, uint32_t pll)
{
switch (unit) {
- case 0:
+ case AR71XX_GE0:
ATH_WRITE_REG(QCA955X_PLL_ETH_XMII_CONTROL_REG, pll);
break;
- case 1:
+ case AR71XX_GE1:
ATH_WRITE_REG(QCA955X_PLL_ETH_SGMII_CONTROL_REG, pll);
break;
default:
@@ -243,13 +272,13 @@
uint32_t pll;
/*
switch (speed) {
- case 10:
+ case AR71XX_GE_SPEED_10:
pll = QCA955X_PLL_VAL_10;
break;
- case 100:
+ case AR71XX_GE_SPEED_100:
pll = QCA955X_PLL_VAL_100;
break;
- case 1000:
+ case AR71XX_GE_SPEED_1000:
pll = QCA955X_PLL_VAL_1000;
break;
default: