Skip to content

Commit

Permalink
ubnt: Changeset for 1.12.22
Browse files Browse the repository at this point in the history
This commit represents the changeset for the UniFi Dream Machine firmware
release version v1.12.22 compared to Linux v4.19.152 (with public
patches applied).
  • Loading branch information
fabianishere committed Jun 6, 2022
1 parent 6cc28cf commit 171ace5
Show file tree
Hide file tree
Showing 22 changed files with 2,841 additions and 477 deletions.
163 changes: 103 additions & 60 deletions drivers/net/ethernet/al/al_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <linux/u64_stats_sync.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include "../../../gpio/gpiolib.h"
#ifdef CONFIG_ARCH_ALPINE
#include <linux/of_address.h>
#include <linux/of_irq.h>
Expand Down Expand Up @@ -509,6 +510,19 @@ struct al_mod_eth_epe_control_entry parser_control_udp_dis_end_of_parse_entry =
/* ports 1 & 3 are STD */
static const int eth_v4_adv_port_map[4] = {0, 2, 4, 5};

const char *al_mod_gpio_of_names[AL_ETH_GPIO_MAX] = {
"mod-def0",
"los",
"tx-fault",
"tx-disable",
};
const enum gpiod_flags al_mode_gpio_flags[AL_ETH_GPIO_MAX] = {
GPIOD_IN,
GPIOD_IN,
GPIOD_IN,
GPIOD_OUT_LOW,
};

/** Forward declarations */
#ifdef CONFIG_ARCH_ALPINE
static void al_mod_eth_serdes_mode_set(struct al_mod_eth_adapter *adapter);
Expand Down Expand Up @@ -936,27 +950,60 @@ static int al_mod_eth_board_of_led(struct al_mod_eth_adapter *adapter, struct a
return 0;
}

static int al_mod_eth_board_of_sfp_probing(struct al_mod_eth_adapter *adapter, struct al_mod_eth_board_params* params, struct device_node *np)
static int al_mod_eth_board_of_lm(struct al_mod_eth_adapter *adapter, struct al_mod_eth_board_params* params, struct device_node *np)
{
struct device_node *np_10g;
#define OF_NODE_NAME_10G "10g-serial"
#define OF_PROP_NAME_PROBE_1G "sfp_probe_1g"
#define OF_PROP_NAME_PROBE_10G "sfp_probe_10g"
int i = 0, rc;
struct gpio_desc *desc;
char of_gpio_name[32];
enum of_gpio_flags;
struct device_node *np_lm;
#define OF_NODE_NAME_LM "link_manager"
#define OF_PROP_NAME_PROBE_1G "sfp-probe-1g"
#define OF_PROP_NAME_PROBE_10G "sfp-probe-10g"
#define OF_PROP_NAME_ELINK_DET "enhanced-link-detection"

if (NULL == adapter || NULL == np || NULL == params) {
return -EINVAL;
}

np_10g = of_find_child_by_name(np, OF_NODE_NAME_10G);
if (!np_10g) {
netdev_dbg(adapter->netdev, "Unable to find matching node (%s)\n", OF_NODE_NAME_10G);
np_lm = of_find_child_by_name(np, OF_NODE_NAME_LM);
if (!np_lm) {
netdev_dbg(adapter->netdev, "Unable to find matching node (%s)\n", OF_NODE_NAME_LM);
return -EINVAL;
}

adapter->sfp_probe_1g = (of_property_match_string(np_10g, OF_PROP_NAME_PROBE_1G, "disabled") < 0);
adapter->sfp_probe_10g = (of_property_match_string(np_10g, OF_PROP_NAME_PROBE_10G, "disabled") < 0);
adapter->sfp_enhanced_link_detection =
!(of_property_match_string(np_lm, OF_PROP_NAME_ELINK_DET, "enabled") < 0);

rc = 0;
for (i = 0; i < AL_ETH_GPIO_MAX; ++i) {
snprintf(of_gpio_name, sizeof(of_gpio_name), "%s-gpios", al_mod_gpio_of_names[i]);

desc = gpiod_get_from_of_node(np_lm, of_gpio_name, 0, al_mode_gpio_flags[i],
al_mod_gpio_of_names[i]);
if (IS_ERR(desc))
break;

of_node_put(np_10g);
adapter->sfp_gpio_list[i] = desc;
}

if (IS_ERR(desc)) {
int err_idx = i;
pr_debug("Unable to get %s GPIO (rc %ld)\n", al_mod_gpio_of_names[i], PTR_ERR(desc));
adapter->sfp_gpio_init = AL_FALSE;
if (err_idx)
for (i = 0; i < err_idx; ++i)
gpiod_put(adapter->sfp_gpio_list[i]);

} else {
adapter->sfp_gpio_init = AL_TRUE;
pr_info("SFP GPIOs initialized successfully");
}

adapter->sfp_probe_1g = (of_property_match_string(np_lm, OF_PROP_NAME_PROBE_1G, "disabled") < 0);
adapter->sfp_probe_10g = (of_property_match_string(np_lm, OF_PROP_NAME_PROBE_10G, "disabled") < 0);

of_node_put(np_lm);
return 0;
}

Expand Down Expand Up @@ -997,6 +1044,8 @@ static void al_mod_eth_board_params_of_defaults(struct al_mod_eth_adapter *adapt
adapter->sfp_probe_1g = true;
adapter->sfp_probe_10g = true;

/* Disable enhanced link detection by default */
adapter->sfp_enhanced_link_detection = false;
}

static int al_mod_eth_board_params_of_init(struct al_mod_eth_adapter *adapter, struct al_mod_eth_board_params* params) {
Expand Down Expand Up @@ -1030,7 +1079,7 @@ static int al_mod_eth_board_params_of_init(struct al_mod_eth_adapter *adapter, s
al_mod_eth_board_of_led(adapter, params, np_port);

/* LM SFP probing */
al_mod_eth_board_of_sfp_probing(adapter, params, np_port);
al_mod_eth_board_of_lm(adapter, params, np_port);

/* Free resources */
of_node_put(np_port);
Expand Down Expand Up @@ -6253,12 +6302,12 @@ static int al_mod_set_features(struct net_device *dev,
#if defined(CONFIG_ARCH_ALPINE)

static int al_mod_eth_i2c_data_read(void *context, uint8_t bus_id, uint8_t i2c_addr, uint8_t reg_addr,
uint8_t *val, size_t len, al_mod_bool seq)
uint8_t *val, size_t len, size_t block_size)
{
struct i2c_adapter *i2c_adapter;
struct al_mod_eth_adapter *adapter = context;
struct i2c_msg msgs[2] = { 0 };
size_t i2c_ops_cnt;
size_t this_len;
int rc = 0;

msgs[0].addr = i2c_addr;
Expand All @@ -6268,14 +6317,7 @@ static int al_mod_eth_i2c_data_read(void *context, uint8_t bus_id, uint8_t i2c_a
msgs[1].addr = i2c_addr;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = val;

if (likely(seq)) {
msgs[1].len = len;
i2c_ops_cnt = 1;
} else {
msgs[1].len = 1;
i2c_ops_cnt = len;
}
msgs[1].len = len;

i2c_adapter = i2c_get_adapter(bus_id);

Expand All @@ -6288,48 +6330,49 @@ static int al_mod_eth_i2c_data_read(void *context, uint8_t bus_id, uint8_t i2c_a
return -EINVAL;
}

for (; i2c_ops_cnt--; msgs[1].buf++, reg_addr++) {
while (len) {
this_len = len;
if (this_len > block_size)
this_len = block_size;

msgs[1].len = this_len;

if (i2c_transfer(i2c_adapter, msgs, ARRAY_SIZE(msgs)) != ARRAY_SIZE(msgs)) {
netdev_dbg(adapter->netdev, "Failed to write sfp+ parameters\n");
rc = -ETIMEDOUT;
break;
}

msgs[1].buf += this_len;
reg_addr += this_len;
len -= this_len;
}

i2c_put_adapter(i2c_adapter);
return rc;
}

static int al_mod_eth_i2c_data_write(void *context, uint8_t bus_id, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *val, size_t len, al_mod_bool seq)
static int al_mod_eth_i2c_data_write(void *context, uint8_t bus_id, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *val, size_t len, size_t block_size)
{
struct i2c_adapter *i2c_adapter;
struct al_mod_eth_adapter *adapter = context;
struct i2c_msg msgs[1] = { 0 };
uint8_t data_s[2] = { 0 }, *data_d = NULL;
size_t i2c_ops_cnt;
int rc = 0;

msgs[0].addr = i2c_addr;
msgs[0].flags = 0;
if (likely(seq)) {
data_d = kmalloc(1 + len, GFP_KERNEL);
if (NULL == data_d) {
netdev_err(adapter->netdev, "Unable to allocate i2c msg.\n");
return -ENOMEM;
}
msgs[0].len = (1 + len);
msgs[0].buf = data_d;
i2c_ops_cnt = 1;
} else {
msgs[0].len = (1 + 1);
msgs[0].buf = &data_s[0];
i2c_ops_cnt = len;
msgs[0].len = (1 + len);
msgs[0].buf = kmalloc(1 + len, GFP_KERNEL);

if (NULL == msgs[0].buf) {
netdev_err(adapter->netdev, "Unable to allocate i2c msg.\n");
return -ENOMEM;
}

i2c_adapter = i2c_get_adapter(bus_id);

if (i2c_adapter == NULL) {
kfree(data_d);
kfree(msgs[0].buf);
netdev_err(
adapter->netdev,
"Failed to get i2c adapter. "
Expand All @@ -6338,40 +6381,30 @@ static int al_mod_eth_i2c_data_write(void *context, uint8_t bus_id, uint8_t i2c_
return -EINVAL;
}

while (i2c_ops_cnt--) {
if (likely(seq)) {
/* sequential access*/
msgs[0].buf[0] = reg_addr;
memcpy(&msgs[0].buf[1], val, len);
} else {
/* byte-per-byte access */
msgs[0].buf[0] = reg_addr++;
msgs[0].buf[1] = *val++;
}
rc = i2c_transfer(i2c_adapter, msgs, ARRAY_SIZE(msgs));

if (i2c_transfer(i2c_adapter, msgs, ARRAY_SIZE(msgs)) != ARRAY_SIZE(msgs)) {
netdev_dbg(adapter->netdev, "Failed to write sfp+ parameters\n");
rc = -ETIMEDOUT;
break;
}
}
kfree(msgs[0].buf);

i2c_put_adapter(i2c_adapter);
kfree(data_d);

return rc;
if (rc < 0) {
netdev_dbg(adapter->netdev, "Failed to write sfp+ parameters\n");
return rc;
}

return rc == ARRAY_SIZE(msgs) ? len : 0;
}

static int al_mod_eth_i2c_byte_read(void *context, uint8_t bus_id, uint8_t i2c_addr, uint8_t reg_addr,
uint8_t *val)
{

return al_mod_eth_i2c_data_read(context, bus_id, i2c_addr, reg_addr, val, 1, AL_TRUE);
return al_mod_eth_i2c_data_read(context, bus_id, i2c_addr, reg_addr, val, 1, 1);
}

static int al_mod_eth_i2c_byte_write(void *context, uint8_t bus_id, uint8_t i2c_addr, uint8_t reg_addr, uint8_t val)
{
return al_mod_eth_i2c_data_write(context, bus_id, i2c_addr, reg_addr, &val, 1, AL_TRUE);
return al_mod_eth_i2c_data_write(context, bus_id, i2c_addr, reg_addr, &val, 1, 1);
}

static uint8_t al_mod_eth_get_rand_byte(void)
Expand Down Expand Up @@ -6747,6 +6780,10 @@ static void al_mod_eth_lm_config(struct al_mod_eth_adapter *adapter)
params.get_msec = al_mod_eth_systime_msec_get;
params.led_config = &al_mod_eth_lm_led_config;

params.sfp_enhanced_link_detection = adapter->sfp_enhanced_link_detection;
params.sfp_gpio_init = adapter->sfp_gpio_init;
params.sfp_gpio_list = adapter->sfp_gpio_list;

if (adapter->gpio_sfp_present) {
err = gpio_request_one(adapter->gpio_sfp_present, GPIOF_IN, "sfp_present");
if (err) {
Expand Down Expand Up @@ -9767,6 +9804,12 @@ al_mod_eth_remove(struct pci_dev *pdev)
struct al_mod_eth_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *dev = adapter->netdev;

if (adapter->sfp_gpio_init) {
int i;
for (i = 0; i < AL_ETH_GPIO_MAX; ++i)
gpiod_put(adapter->sfp_gpio_list[i]);

}
#ifdef CONFIG_ARCH_ALPINE
/*
* adapter->lm_context.lock was initialized in al_mod_eth_probe
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/al/al_eth.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,10 @@ struct al_mod_eth_adapter {
unsigned int gpio_spd_10g;
unsigned int gpio_spd_25g;
unsigned int gpio_sfp_present;
/* enable enhanced SFP link detection */
bool sfp_enhanced_link_detection;
al_mod_bool sfp_gpio_init;
struct gpio_desc *sfp_gpio_list[AL_ETH_GPIO_MAX];
al_mod_bool kr_fec_enable;

struct work_struct reset_task;
Expand Down
48 changes: 48 additions & 0 deletions drivers/net/ethernet/al/al_mod_eth_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,50 @@ static struct device_attribute dev_attr_sfp_probe_10g = {
.store = al_mod_eth_store_sfp_probe_10g,
};

static ssize_t al_mod_eth_show_sfp_enhanced_link_detection(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct al_mod_eth_adapter *adapter = dev_get_drvdata(dev);

if (NULL == adapter) {
dev_warn(dev, "%s drvdata are not initialized\n", __func__);
return -EINVAL;
}

return sprintf(buf, "%d\n", !!adapter->sfp_enhanced_link_detection);
}

static ssize_t al_mod_eth_store_sfp_enhanced_link_detection(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
struct al_mod_eth_adapter *adapter = dev_get_drvdata(dev);
unsigned long enable;
int err;

if (NULL == adapter) {
dev_warn(dev, "%s drvdata are not initialized\n", __func__);
return -EINVAL;
}


err = kstrtoul(buf, 10, &enable);
if (err < 0)
return err;

adapter->sfp_enhanced_link_detection = !!enable;

if (adapter->up)
dev_warn(dev, "%s this action will take place in the next activation (up)\n",
__func__);
return len;
}

static struct device_attribute dev_attr_sfp_enhanced_link_detection = {
.attr = { .name = "sfp_enhanced_link_detection", .mode = (S_IRUGO | S_IWUSR) },
.show = al_mod_eth_show_sfp_enhanced_link_detection,
.store = al_mod_eth_store_sfp_enhanced_link_detection,
};

static ssize_t al_mod_eth_store_force_1000_base_x(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
Expand Down Expand Up @@ -1306,6 +1350,9 @@ int al_mod_eth_sysfs_init(
if (device_create_file(dev, &dev_attr_sfp_probe_10g))
dev_info(dev, "failed to create sfp_probe_10g sysfs entry");

if (device_create_file(dev, &dev_attr_sfp_enhanced_link_detection))
dev_info(dev, "failed to create dev_attr_sfp_enhanced_link_detection sysfs entry");

if (device_create_file(dev, &dev_attr_force_1000_base_x))
dev_info(dev, "failed to create force_1000_base_x sysfs entry");

Expand Down Expand Up @@ -1428,6 +1475,7 @@ void al_mod_eth_sysfs_terminate(
device_remove_file(dev, &dev_attr_link_training_enable);
device_remove_file(dev, &dev_attr_sfp_probe_1g);
device_remove_file(dev, &dev_attr_sfp_probe_10g);
device_remove_file(dev, &dev_attr_sfp_enhanced_link_detection);
device_remove_file(dev, &dev_attr_force_1000_base_x);
device_remove_file(dev, &dev_attr_intr_moderation_restore_default);
device_remove_file(dev, &dev_attr_flow_steer_config);
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/al/al_mod_hal_eth_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,14 @@ struct al_mod_eth_mac_obj {
al_mod_bool rx,
al_mod_bool tx_start,
al_mod_bool rx_start);

/**
* check if 10GBase-KR is live and kicking.
* @param adapter pointer to the private structure.
*
* @return false if cannot detect 10GBase-KR medium is set. true otherwise
*/
int (*check_10g_base_kr)(struct al_mod_eth_mac_obj *obj);
};

/** Ethernet MAC handle initialization parameters */
Expand Down
Loading

0 comments on commit 171ace5

Please sign in to comment.