Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
d125e12f60
@ -276,7 +276,7 @@ help:
|
||||
cat README.md
|
||||
|
||||
distclean:
|
||||
rm -rf bin build_dir .ccache .config* dl feeds key-build* logs package/feeds staging_dir tmp
|
||||
rm -rf bin build_dir .ccache .config* dl feeds key-build* logs package/feeds target/linux/feeds staging_dir tmp
|
||||
@$(_SINGLE)$(SUBMAKE) -C scripts/config clean
|
||||
|
||||
ifeq ($(findstring v,$(DEBUG)),)
|
||||
|
@ -97,17 +97,14 @@ else
|
||||
BITS := 32bit
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_arm_v7),y)
|
||||
CONFIGURE_ARGS += --host=armv7-openwrt-linux$(if $(TARGET_SUFFIX),-$(TARGET_SUFFIX))
|
||||
endif
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-lto \
|
||||
--enable-tls \
|
||||
--without-x \
|
||||
--without-mpicc \
|
||||
--without-uiout \
|
||||
--disable-valgrindmi \
|
||||
--disable-tui \
|
||||
--disable-valgrindtk \
|
||||
--without-included-gettext \
|
||||
--with-pagesize=4 \
|
||||
|
||||
define Package/valgrind/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
|
@ -6,9 +6,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git
|
||||
PKG_SOURCE_DATE:=2024-09-14
|
||||
PKG_SOURCE_VERSION:=2ca41d755d93dce53748ee6906318cc7d3829a8c
|
||||
PKG_MIRROR_HASH:=e7447649e044a2759f6768eaec6de330238e6166bc01703979844be94fe2f817
|
||||
PKG_SOURCE_DATE:=2024-10-08
|
||||
PKG_SOURCE_VERSION:=dcbab62272bf5cab2ed857bc655d240970e14f2a
|
||||
PKG_MIRROR_HASH:=e53a3872abf5e35db6baaceb56e6ffa289f8dd9b6226cf8a4d5b87b541179175
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
@ -51,6 +51,7 @@ ALLWIFIBOARDS:= \
|
||||
prpl_haze \
|
||||
qnap_301w \
|
||||
redmi_ax6 \
|
||||
skspruce_wia3300-20 \
|
||||
spectrum_sax1v1k \
|
||||
tplink_eap660hd-v1 \
|
||||
wallys_dr40x9 \
|
||||
@ -177,6 +178,7 @@ $(eval $(call generate-ipq-wifi-package,netgear_wax630,Netgear WAX630))
|
||||
$(eval $(call generate-ipq-wifi-package,qnap_301w,QNAP 301w))
|
||||
$(eval $(call generate-ipq-wifi-package,prpl_haze,prpl Haze))
|
||||
$(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6))
|
||||
$(eval $(call generate-ipq-wifi-package,skspruce_wia3300-20,SKSpruce WIA3300-20))
|
||||
$(eval $(call generate-ipq-wifi-package,spectrum_sax1v1k,Spectrum SAX1V1K))
|
||||
$(eval $(call generate-ipq-wifi-package,tplink_eap660hd-v1,TP-Link EAP660 HD v1))
|
||||
$(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9))
|
||||
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=gpio-button-hotplug
|
||||
PKG_RELEASE:=4
|
||||
PKG_RELEASE:=5
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
@ -373,7 +373,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
nbuttons = of_get_child_count(node);
|
||||
nbuttons = of_get_available_child_count(node);
|
||||
if (nbuttons == 0)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
@ -388,7 +388,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
||||
pdata->rep = !!of_get_property(node, "autorepeat", NULL);
|
||||
of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
|
||||
|
||||
for_each_child_of_node(node, pp) {
|
||||
for_each_available_child_of_node(node, pp) {
|
||||
button = (struct gpio_keys_button *)(&pdata->buttons[i++]);
|
||||
|
||||
if (of_property_read_u32(pp, "linux,code", &button->code)) {
|
||||
|
@ -164,6 +164,7 @@ static int ubnt_ledbar_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device_node *np = client->dev.of_node;
|
||||
struct ubnt_ledbar *ledbar;
|
||||
int err;
|
||||
|
||||
ledbar = devm_kzalloc(&client->dev, sizeof(*ledbar), GFP_KERNEL);
|
||||
if (!ledbar)
|
||||
@ -184,7 +185,9 @@ static int ubnt_ledbar_probe(struct i2c_client *client)
|
||||
|
||||
ledbar->client = client;
|
||||
|
||||
mutex_init(&ledbar->lock);
|
||||
err = devm_mutex_init(&client->dev, &ledbar->lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
i2c_set_clientdata(client, ledbar);
|
||||
|
||||
@ -203,13 +206,6 @@ static int ubnt_ledbar_probe(struct i2c_client *client)
|
||||
return ubnt_ledbar_apply_state(ledbar);
|
||||
}
|
||||
|
||||
static void ubnt_ledbar_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ubnt_ledbar *ledbar = i2c_get_clientdata(client);
|
||||
|
||||
mutex_destroy(&ledbar->lock);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ubnt_ledbar_id[] = {
|
||||
{ "ubnt-ledbar", 0 },
|
||||
{ }
|
||||
@ -228,7 +224,6 @@ static struct i2c_driver ubnt_ledbar_driver = {
|
||||
.of_match_table = of_ubnt_ledbar_match,
|
||||
},
|
||||
.probe = ubnt_ledbar_probe,
|
||||
.remove = ubnt_ledbar_remove,
|
||||
.id_table = ubnt_ledbar_id,
|
||||
};
|
||||
module_i2c_driver(ubnt_ledbar_driver);
|
||||
|
@ -105,6 +105,7 @@ static int rb4xx_gpio_probe(struct platform_device *pdev)
|
||||
struct device *parent = dev->parent;
|
||||
struct rb4xx_gpio *gpio;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
if (!parent)
|
||||
return -ENODEV;
|
||||
@ -117,7 +118,10 @@ static int rb4xx_gpio_probe(struct platform_device *pdev)
|
||||
gpio->cpld = dev_get_drvdata(parent);
|
||||
gpio->dev = dev;
|
||||
gpio->values = 0;
|
||||
mutex_init(&gpio->lock);
|
||||
|
||||
err = devm_mutex_init(&pdev->dev, &gpio->lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gpio->chip.label = "rb4xx-gpio";
|
||||
gpio->chip.parent = dev;
|
||||
@ -134,17 +138,7 @@ static int rb4xx_gpio_probe(struct platform_device *pdev)
|
||||
if (!of_property_read_u32(dev->of_node, "base", &val))
|
||||
gpio->chip.base = val;
|
||||
|
||||
return gpiochip_add_data(&gpio->chip, gpio);
|
||||
}
|
||||
|
||||
static int rb4xx_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rb4xx_gpio *gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&gpio->chip);
|
||||
mutex_destroy(&gpio->lock);
|
||||
|
||||
return 0;
|
||||
return devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
|
||||
}
|
||||
|
||||
static const struct platform_device_id rb4xx_gpio_id_table[] = {
|
||||
@ -155,7 +149,6 @@ MODULE_DEVICE_TABLE(platform, rb4xx_gpio_id_table);
|
||||
|
||||
static struct platform_driver rb4xx_gpio_driver = {
|
||||
.probe = rb4xx_gpio_probe,
|
||||
.remove = rb4xx_gpio_remove,
|
||||
.id_table = rb4xx_gpio_id_table,
|
||||
.driver = {
|
||||
.name = "rb4xx-gpio",
|
||||
|
@ -144,13 +144,19 @@ static int gpio_rb91x_key_probe(struct platform_device *pdev)
|
||||
struct gpio_rb91x_key *drvdata;
|
||||
struct gpio_chip *gc;
|
||||
struct device *dev = &pdev->dev;
|
||||
int err;
|
||||
|
||||
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&drvdata->mutex);
|
||||
mutex_init(&drvdata->poll_mutex);
|
||||
err = devm_mutex_init(dev, &drvdata->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devm_mutex_init(dev, &drvdata->poll_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
drvdata->gpio = devm_gpiod_get(dev, NULL, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(drvdata->gpio))
|
||||
@ -167,8 +173,6 @@ static int gpio_rb91x_key_probe(struct platform_device *pdev)
|
||||
gc->direction_output = gpio_rb91x_key_direction_output;
|
||||
gc->direction_input = gpio_rb91x_key_direction_input;
|
||||
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
|
||||
return devm_gpiochip_add_data(dev, gc, drvdata);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ CONFIG_MFD_CORE=y
|
||||
CONFIG_MFD_RB4XX_CPLD=y
|
||||
CONFIG_MIKROTIK=y
|
||||
CONFIG_MIKROTIK_RB_SYSFS=y
|
||||
CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77=y
|
||||
CONFIG_MTD_NAND_AR934X=y
|
||||
CONFIG_MTD_NAND_CORE=y
|
||||
CONFIG_MTD_NAND_ECC=y
|
||||
|
@ -21,4 +21,11 @@ config NVMEM_LAYOUT_MIKROTIK
|
||||
help
|
||||
This driver exposes MikroTik hard_config via NVMEM layout.
|
||||
|
||||
config MIKROTIK_WLAN_DECOMPRESS_LZ77
|
||||
tristate "Mikrotik factory Wi-Fi caldata LZ77 decompression support"
|
||||
depends on MIKROTIK_RB_SYSFS
|
||||
help
|
||||
Allow Mikrotik LZ77 factory flashed Wi-Fi calibration data to be
|
||||
decompressed
|
||||
|
||||
endif # MIKROTIK
|
||||
|
@ -3,3 +3,4 @@
|
||||
#
|
||||
obj-$(CONFIG_MIKROTIK_RB_SYSFS) += routerboot.o rb_hardconfig.o rb_softconfig.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_MIKROTIK) += rb_nvmem.o
|
||||
obj-$(CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77) += rb_lz77.o
|
||||
|
@ -39,8 +39,9 @@
|
||||
|
||||
#include "rb_hardconfig.h"
|
||||
#include "routerboot.h"
|
||||
#include "rb_lz77.h"
|
||||
|
||||
#define RB_HARDCONFIG_VER "0.07"
|
||||
#define RB_HARDCONFIG_VER "0.08"
|
||||
#define RB_HC_PR_PFX "[rb_hardconfig] "
|
||||
|
||||
/* Bit definitions for hardware options */
|
||||
@ -465,23 +466,24 @@ fail:
|
||||
/*
|
||||
* If the RB_ID_WLAN_DATA payload starts with RB_MAGIC_LZOR, then past
|
||||
* that magic number is a payload that must be appended to the hc_lzor_prefix,
|
||||
* the resulting blob is LZO-compressed. In the LZO decompression result,
|
||||
* the resulting blob is LZO-compressed.
|
||||
* If payload starts with RB_MAGIC_LZ77, a separate (bit level LZ77)
|
||||
* decompression function needs to be used. In the decompressed result,
|
||||
* the RB_MAGIC_ERD magic number (aligned) must be located. Following that
|
||||
* magic, there is one or more routerboot tag node(s) locating the RLE-encoded
|
||||
* calibration data payload.
|
||||
*/
|
||||
static int hc_wlan_data_unpack_lzor(const u16 tag_id, const u8 *inbuf, size_t inlen,
|
||||
void *outbuf, size_t *outlen)
|
||||
static int hc_wlan_data_unpack_lzor_lz77(const u16 tag_id, const u8 *inbuf, size_t inlen,
|
||||
void *outbuf, size_t *outlen, u32 magic)
|
||||
{
|
||||
u16 rle_ofs, rle_len;
|
||||
const u32 *needle;
|
||||
u8 *tempbuf;
|
||||
size_t templen, lzo_len;
|
||||
int ret;
|
||||
|
||||
lzo_len = inlen + sizeof(hc_lzor_prefix);
|
||||
if (lzo_len > *outlen)
|
||||
return -EFBIG;
|
||||
const char lzor[] = "LZOR";
|
||||
const char lz77[] = "LZ77";
|
||||
const char *lz_type;
|
||||
|
||||
/* Temporary buffer same size as the outbuf */
|
||||
templen = *outlen;
|
||||
@ -489,23 +491,50 @@ static int hc_wlan_data_unpack_lzor(const u16 tag_id, const u8 *inbuf, size_t in
|
||||
if (!tempbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Concatenate into the outbuf */
|
||||
memcpy(outbuf, hc_lzor_prefix, sizeof(hc_lzor_prefix));
|
||||
memcpy(outbuf + sizeof(hc_lzor_prefix), inbuf, inlen);
|
||||
lzo_len = inlen;
|
||||
if (magic == RB_MAGIC_LZOR)
|
||||
lzo_len += sizeof(hc_lzor_prefix);
|
||||
if (lzo_len > *outlen)
|
||||
return -EFBIG;
|
||||
|
||||
/* LZO-decompress lzo_len bytes of outbuf into the tempbuf */
|
||||
ret = lzo1x_decompress_safe(outbuf, lzo_len, tempbuf, &templen);
|
||||
if (ret) {
|
||||
if (LZO_E_INPUT_NOT_CONSUMED == ret) {
|
||||
/*
|
||||
* The tag length is always aligned thus the LZO payload may be padded,
|
||||
* which can trigger a spurious error which we ignore here.
|
||||
*/
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: LZO EOF before buffer end - this may be harmless\n");
|
||||
} else {
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: LZO decompression error (%d)\n", ret);
|
||||
switch (magic) {
|
||||
case RB_MAGIC_LZOR:
|
||||
lz_type = lzor;
|
||||
|
||||
/* Concatenate into the outbuf */
|
||||
memcpy(outbuf, hc_lzor_prefix, sizeof(hc_lzor_prefix));
|
||||
memcpy(outbuf + sizeof(hc_lzor_prefix), inbuf, inlen);
|
||||
|
||||
/* LZO-decompress lzo_len bytes of outbuf into the tempbuf */
|
||||
ret = lzo1x_decompress_safe(outbuf, lzo_len, tempbuf, &templen);
|
||||
if (ret) {
|
||||
if (LZO_E_INPUT_NOT_CONSUMED == ret) {
|
||||
/*
|
||||
* The tag length is always aligned thus the LZO payload may be padded,
|
||||
* which can trigger a spurious error which we ignore here.
|
||||
*/
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: LZO EOF before buffer end - this may be harmless\n");
|
||||
} else {
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: LZO decompression error (%d)\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RB_MAGIC_LZ77:
|
||||
lz_type = lz77;
|
||||
/* LZO-decompress lzo_len bytes of inbuf into the tempbuf */
|
||||
ret = rb_lz77_decompress(inbuf, inlen, tempbuf, &templen);
|
||||
if (ret) {
|
||||
pr_err(RB_HC_PR_PFX "LZ77: LZ77 decompress error %d\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pr_debug(RB_HC_PR_PFX "LZ77: decompressed from %zu to %zu\n",
|
||||
inlen, templen);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -516,7 +545,7 @@ static int hc_wlan_data_unpack_lzor(const u16 tag_id, const u8 *inbuf, size_t in
|
||||
needle = (const u32 *)tempbuf;
|
||||
while (RB_MAGIC_ERD != *needle++) {
|
||||
if ((u8 *)needle >= tempbuf+templen) {
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: ERD magic not found\n");
|
||||
pr_warn(RB_HC_PR_PFX "%s: ERD magic not found. Decompressed first word: 0x%08x\n", lz_type, *(u32 *)tempbuf);
|
||||
ret = -ENODATA;
|
||||
goto fail;
|
||||
}
|
||||
@ -526,12 +555,12 @@ static int hc_wlan_data_unpack_lzor(const u16 tag_id, const u8 *inbuf, size_t in
|
||||
/* Past magic. Look for tag node */
|
||||
ret = routerboot_tag_find((u8 *)needle, templen, tag_id, &rle_ofs, &rle_len);
|
||||
if (ret) {
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: no RLE data for id 0x%04x\n", tag_id);
|
||||
pr_debug(RB_HC_PR_PFX "%s: no RLE data for id 0x%04x\n", lz_type, tag_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rle_len > templen) {
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: Invalid RLE data length\n");
|
||||
pr_debug(RB_HC_PR_PFX "%s: Invalid RLE data length\n", lz_type);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@ -539,7 +568,7 @@ static int hc_wlan_data_unpack_lzor(const u16 tag_id, const u8 *inbuf, size_t in
|
||||
/* RLE-decode tempbuf from needle back into the outbuf */
|
||||
ret = routerboot_rle_decode((u8 *)needle+rle_ofs, rle_len, outbuf, outlen);
|
||||
if (ret)
|
||||
pr_debug(RB_HC_PR_PFX "LZOR: RLE decoding error (%d)\n", ret);
|
||||
pr_debug(RB_HC_PR_PFX "%s: RLE decoding error (%d)\n", lz_type, ret);
|
||||
|
||||
fail:
|
||||
kfree(tempbuf);
|
||||
@ -562,11 +591,18 @@ static int hc_wlan_data_unpack(const u16 tag_id, const size_t tofs, size_t tlen,
|
||||
|
||||
ret = -ENODATA;
|
||||
switch (magic) {
|
||||
case RB_MAGIC_LZ77:
|
||||
/* no known instances of lz77 without 8001/8201 data, skip SOLO */
|
||||
if (tag_id == RB_WLAN_ERD_ID_SOLO) {
|
||||
pr_debug(RB_HC_PR_PFX "skipped LZ77 decompress in search for SOLO tag\n");
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
case RB_MAGIC_LZOR:
|
||||
/* Skip magic */
|
||||
lbuf += sizeof(magic);
|
||||
tlen -= sizeof(magic);
|
||||
ret = hc_wlan_data_unpack_lzor(tag_id, lbuf, tlen, outbuf, outlen);
|
||||
ret = hc_wlan_data_unpack_lzor_lz77(tag_id, lbuf, tlen, outbuf, outlen, magic);
|
||||
break;
|
||||
case RB_MAGIC_ERD:
|
||||
/* Skip magic */
|
||||
|
446
target/linux/generic/files/drivers/platform/mikrotik/rb_lz77.c
Normal file
446
target/linux/generic/files/drivers/platform/mikrotik/rb_lz77.c
Normal file
@ -0,0 +1,446 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2023 John Thomson
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/minmax.h>
|
||||
|
||||
#include "rb_lz77.h"
|
||||
|
||||
#define MIKRO_LZ77 "[rb lz77] "
|
||||
|
||||
/*
|
||||
* The maximum number of bits used in a counter.
|
||||
* For the look behind window, long instruction match offsets
|
||||
* up to 6449 have been seen in provided compressed caldata blobs
|
||||
* (that would need 21 counter bits: 4 to 12 + 11 to 0).
|
||||
* conservative value here: 27 provides offset up to 0x8000 bytes
|
||||
* uses a u8 in this code
|
||||
*/
|
||||
#define MIKRO_LZ77_MAX_COUNT_BIT_LEN 27
|
||||
|
||||
enum rb_lz77_instruction {
|
||||
INSTR_ERROR = -1,
|
||||
INSTR_LITERAL_BYTE = 0,
|
||||
/* a (non aligned) byte follows this instruction,
|
||||
* which is directly copied into output
|
||||
*/
|
||||
INSTR_PREVIOUS_OFFSET = 1,
|
||||
/* this group is a match, with a bytes length defined by
|
||||
* following counter bits, starting at bitshift 0,
|
||||
* less the built-in count of 1
|
||||
* using the previous offset as source
|
||||
*/
|
||||
INSTR_LONG = 2
|
||||
/* this group has two counters,
|
||||
* the first counter starts at bitshift 4,
|
||||
* if this counter == 0, this is a non-matching group
|
||||
* the second counter (bytes length) starts at bitshift 4,
|
||||
* less the built-in count of 11+1.
|
||||
* The final match group has this count 0,
|
||||
* and following bits which pad to byte-alignment.
|
||||
*
|
||||
* if this counter > 0, this is a matching group
|
||||
* this first count is the match offset (in bytes)
|
||||
* the second count is the match length (in bytes),
|
||||
* less the built-in count of 2
|
||||
* these groups can source bytes that are part of this group
|
||||
*/
|
||||
};
|
||||
|
||||
struct rb_lz77_instr_opcodes {
|
||||
/* group instruction */
|
||||
enum rb_lz77_instruction instruction;
|
||||
/* if >0, a match group,
|
||||
* which starts at byte output_position - 1*offset
|
||||
*/
|
||||
size_t offset;
|
||||
/* how long the match group is,
|
||||
* or how long the (following counter) non-match group is
|
||||
*/
|
||||
size_t length;
|
||||
/* how many bits were used for this instruction + op code(s) */
|
||||
size_t bits_used;
|
||||
/* input char */
|
||||
u8 *in;
|
||||
/* offset where this instruction started */
|
||||
size_t in_pos;
|
||||
};
|
||||
|
||||
/**
|
||||
* rb_lz77_get_bit
|
||||
*
|
||||
* @in: compressed data ptr
|
||||
* @in_offset_bit: bit offset to extract
|
||||
*
|
||||
* convert the bit offset to byte offset,
|
||||
* shift to modulo of bits per bytes, so that wanted bit is lsb
|
||||
* and to extract only that bit.
|
||||
* Caller is responsible for ensuring that in_offset_bit/8
|
||||
* does not exceed input length
|
||||
*/
|
||||
static inline u8 rb_lz77_get_bit(const u8 *in, const size_t in_offset_bit)
|
||||
{
|
||||
return ((in[in_offset_bit / BITS_PER_BYTE] >>
|
||||
(in_offset_bit % BITS_PER_BYTE)) &
|
||||
1);
|
||||
}
|
||||
|
||||
/**
|
||||
* rb_lz77_get_byte
|
||||
*
|
||||
* @in: compressed data
|
||||
* @in_offset_bit: bit offset to extract byte
|
||||
*/
|
||||
static inline u8 rb_lz77_get_byte(const u8 *in, const size_t in_offset_bit)
|
||||
{
|
||||
u8 buf = 0;
|
||||
int i;
|
||||
|
||||
/* built a reversed byte from (likely) unaligned bits */
|
||||
for (i = 0; i <= 7; ++i)
|
||||
buf += rb_lz77_get_bit(in, in_offset_bit + i) << (7 - i);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* rb_lz77_decode_count - decode bits at given offset as a count
|
||||
*
|
||||
* @in: compressed data
|
||||
* @in_len: length of compressed data
|
||||
* @in_offset_bit: bit offset where count starts
|
||||
* @shift: left shift operand value of first count bit
|
||||
* @count: initial count
|
||||
* @bits_used: how many bits were consumed by this count
|
||||
* @max_bits: maximum bit count for this counter
|
||||
*
|
||||
* Returns the decoded count
|
||||
*/
|
||||
static int rb_lz77_decode_count(const u8 *in, const size_t in_len,
|
||||
const size_t in_offset_bit, u8 shift,
|
||||
size_t count, u8 *bits_used, const u8 max_bits)
|
||||
{
|
||||
size_t pos = in_offset_bit;
|
||||
const size_t max_pos = min(pos + max_bits, in_len * BITS_PER_BYTE);
|
||||
bool up = true;
|
||||
|
||||
*bits_used = 0;
|
||||
pr_debug(MIKRO_LZ77
|
||||
"decode_count inbit: %zu, start shift:%u, initial count:%zu\n",
|
||||
in_offset_bit, shift, count);
|
||||
|
||||
while (true) {
|
||||
/* check the input offset bit does not overflow the minimum of
|
||||
* a reasonable length for this encoded count, and
|
||||
* the end of the input */
|
||||
if (unlikely(pos >= max_pos)) {
|
||||
pr_err(MIKRO_LZ77
|
||||
"max bit index reached before count completed\n");
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
/* if the bit value at offset is set */
|
||||
if (rb_lz77_get_bit(in, pos))
|
||||
count += (1 << shift);
|
||||
|
||||
/* shift increases until we find an unsed bit */
|
||||
else if (up)
|
||||
up = false;
|
||||
|
||||
if (up)
|
||||
++shift;
|
||||
else {
|
||||
if (!shift) {
|
||||
*bits_used = pos - in_offset_bit + 1;
|
||||
return count;
|
||||
}
|
||||
--shift;
|
||||
}
|
||||
|
||||
++pos;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* rb_lz77_decode_instruction
|
||||
*
|
||||
* @in: compressed data
|
||||
* @in_offset_bit: bit offset where instruction starts
|
||||
* @bits_used: how many bits were consumed by this count
|
||||
*
|
||||
* Returns the decoded instruction
|
||||
*/
|
||||
static enum rb_lz77_instruction
|
||||
rb_lz77_decode_instruction(const u8 *in, size_t in_offset_bit, u8 *bits_used)
|
||||
{
|
||||
if (rb_lz77_get_bit(in, in_offset_bit)) {
|
||||
*bits_used = 2;
|
||||
if (rb_lz77_get_bit(in, ++in_offset_bit))
|
||||
return INSTR_LONG;
|
||||
else
|
||||
return INSTR_PREVIOUS_OFFSET;
|
||||
} else {
|
||||
*bits_used = 1;
|
||||
return INSTR_LITERAL_BYTE;
|
||||
}
|
||||
return INSTR_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* rb_lz77_decode_instruction_operators
|
||||
*
|
||||
* @in: compressed data
|
||||
* @in_len: length of compressed data
|
||||
* @in_offset_bit: bit offset where instruction starts
|
||||
* @previous_offset: last used match offset
|
||||
* @opcode: struct to hold instruction & operators
|
||||
*
|
||||
* Returns error code
|
||||
*/
|
||||
static int rb_lz77_decode_instruction_operators(
|
||||
const u8 *in, const size_t in_len, const size_t in_offset_bit,
|
||||
const size_t previous_offset, struct rb_lz77_instr_opcodes *opcode)
|
||||
{
|
||||
enum rb_lz77_instruction instruction;
|
||||
u8 bit_count = 0;
|
||||
u8 bits_used = 0;
|
||||
int offset = 0;
|
||||
int length = 0;
|
||||
|
||||
instruction = rb_lz77_decode_instruction(in, in_offset_bit, &bit_count);
|
||||
|
||||
/* skip bits used by instruction */
|
||||
bits_used += bit_count;
|
||||
|
||||
switch (instruction) {
|
||||
case INSTR_LITERAL_BYTE:
|
||||
/* non-matching char */
|
||||
offset = 0;
|
||||
length = 1;
|
||||
break;
|
||||
|
||||
case INSTR_PREVIOUS_OFFSET:
|
||||
/* matching group uses previous offset */
|
||||
offset = previous_offset;
|
||||
|
||||
length = rb_lz77_decode_count(in, in_len,
|
||||
in_offset_bit + bits_used, 0, 1,
|
||||
&bit_count,
|
||||
MIKRO_LZ77_MAX_COUNT_BIT_LEN);
|
||||
if (unlikely(length < 0))
|
||||
return length;
|
||||
/* skip bits used by count */
|
||||
bits_used += bit_count;
|
||||
break;
|
||||
|
||||
case INSTR_LONG:
|
||||
offset = rb_lz77_decode_count(in, in_len,
|
||||
in_offset_bit + bits_used, 4, 0,
|
||||
&bit_count,
|
||||
MIKRO_LZ77_MAX_COUNT_BIT_LEN);
|
||||
if (unlikely(offset < 0))
|
||||
return offset;
|
||||
|
||||
/* skip bits used by offset count */
|
||||
bits_used += bit_count;
|
||||
|
||||
if (offset == 0) {
|
||||
/* non-matching long group */
|
||||
length = rb_lz77_decode_count(
|
||||
in, in_len, in_offset_bit + bits_used, 4, 12,
|
||||
&bit_count, MIKRO_LZ77_MAX_COUNT_BIT_LEN);
|
||||
if (unlikely(length < 0))
|
||||
return length;
|
||||
/* skip bits used by length count */
|
||||
bits_used += bit_count;
|
||||
} else {
|
||||
/* matching group */
|
||||
length = rb_lz77_decode_count(
|
||||
in, in_len, in_offset_bit + bits_used, 0, 2,
|
||||
&bit_count, MIKRO_LZ77_MAX_COUNT_BIT_LEN);
|
||||
if (unlikely(length < 0))
|
||||
return length;
|
||||
/* skip bits used by length count */
|
||||
bits_used += bit_count;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case INSTR_ERROR:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
opcode->instruction = instruction;
|
||||
opcode->offset = offset;
|
||||
opcode->length = length;
|
||||
opcode->bits_used = bits_used;
|
||||
opcode->in = (u8 *)in;
|
||||
opcode->in_pos = in_offset_bit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rb_lz77_decompress
|
||||
*
|
||||
* @in: compressed data ptr
|
||||
* @in_len: length of compressed data
|
||||
* @out: buffer ptr to decompress into
|
||||
* @out_len: length of decompressed buffer in input,
|
||||
* length of decompressed data in success
|
||||
*
|
||||
* Returns 0 on success, or negative error
|
||||
*/
|
||||
int rb_lz77_decompress(const u8 *in, const size_t in_len, u8 *out,
|
||||
size_t *out_len)
|
||||
{
|
||||
u8 *output_ptr;
|
||||
size_t input_bit = 0;
|
||||
const u8 *output_end = out + *out_len;
|
||||
struct rb_lz77_instr_opcodes *opcode;
|
||||
size_t match_offset = 0;
|
||||
int rc = 0;
|
||||
size_t match_length, partial_count, i;
|
||||
|
||||
output_ptr = out;
|
||||
|
||||
if (unlikely((in_len * BITS_PER_BYTE) > SIZE_MAX)) {
|
||||
pr_err(MIKRO_LZ77 "input longer than expected\n");
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
opcode = kmalloc(sizeof(*opcode), GFP_KERNEL);
|
||||
if (!opcode)
|
||||
return -ENOMEM;
|
||||
|
||||
while (true) {
|
||||
if (unlikely(output_ptr > output_end)) {
|
||||
pr_err(MIKRO_LZ77 "output overrun\n");
|
||||
rc = -EOVERFLOW;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
if (unlikely(input_bit > in_len * BITS_PER_BYTE)) {
|
||||
pr_err(MIKRO_LZ77 "input overrun\n");
|
||||
rc = -ENODATA;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
|
||||
rc = rb_lz77_decode_instruction_operators(in, in_len, input_bit,
|
||||
match_offset, opcode);
|
||||
if (unlikely(rc < 0)) {
|
||||
pr_err(MIKRO_LZ77
|
||||
"instruction operands decode error\n");
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
|
||||
pr_debug(MIKRO_LZ77 "inbit:0x%zx->outbyte:0x%zx", input_bit,
|
||||
output_ptr - out);
|
||||
|
||||
input_bit += opcode->bits_used;
|
||||
switch (opcode->instruction) {
|
||||
case INSTR_LITERAL_BYTE:
|
||||
pr_debug(" short");
|
||||
fallthrough;
|
||||
case INSTR_LONG:
|
||||
if (opcode->offset == 0) {
|
||||
/* this is a non-matching group */
|
||||
pr_debug(" non-match, len: 0x%zx\n",
|
||||
opcode->length);
|
||||
/* test end marker */
|
||||
if (opcode->length == 0xc &&
|
||||
((input_bit +
|
||||
opcode->length * BITS_PER_BYTE) >
|
||||
in_len)) {
|
||||
*out_len = output_ptr - out;
|
||||
pr_debug(
|
||||
MIKRO_LZ77
|
||||
"lz77 decompressed from %zu to %zu\n",
|
||||
in_len, *out_len);
|
||||
rc = 0;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
for (i = opcode->length; i > 0; --i) {
|
||||
*output_ptr =
|
||||
rb_lz77_get_byte(in, input_bit);
|
||||
++output_ptr;
|
||||
input_bit += BITS_PER_BYTE;
|
||||
}
|
||||
/* do no fallthrough if a non-match group */
|
||||
break;
|
||||
}
|
||||
match_offset = opcode->offset;
|
||||
fallthrough;
|
||||
case INSTR_PREVIOUS_OFFSET:
|
||||
match_length = opcode->length;
|
||||
partial_count = 0;
|
||||
|
||||
pr_debug(" match, offset: 0x%zx, len: 0x%zx",
|
||||
opcode->offset, match_length);
|
||||
|
||||
if (unlikely(opcode->offset == 0)) {
|
||||
pr_err(MIKRO_LZ77
|
||||
"match group missing opcode->offset\n");
|
||||
rc = -EBADMSG;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
|
||||
/* overflow */
|
||||
if (unlikely((output_ptr + match_length) >
|
||||
output_end)) {
|
||||
pr_err(MIKRO_LZ77
|
||||
"match group output overflow\n");
|
||||
rc = -ENOBUFS;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
|
||||
/* underflow */
|
||||
if (unlikely((output_ptr - opcode->offset) < out)) {
|
||||
pr_err(MIKRO_LZ77
|
||||
"match group offset underflow\n");
|
||||
rc = -ESPIPE;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
|
||||
/* there are cases where the match (length) includes
|
||||
* data that is a part of the same match
|
||||
*/
|
||||
while (opcode->offset < match_length) {
|
||||
++partial_count;
|
||||
memcpy(output_ptr, output_ptr - opcode->offset,
|
||||
opcode->offset);
|
||||
output_ptr += opcode->offset;
|
||||
match_length -= opcode->offset;
|
||||
}
|
||||
memcpy(output_ptr, output_ptr - opcode->offset,
|
||||
match_length);
|
||||
output_ptr += match_length;
|
||||
if (partial_count)
|
||||
pr_debug(" (%zu partial memcpy)",
|
||||
partial_count);
|
||||
pr_debug("\n");
|
||||
|
||||
break;
|
||||
|
||||
case INSTR_ERROR:
|
||||
rc = -EINVAL;
|
||||
goto free_lz77_struct;
|
||||
}
|
||||
}
|
||||
|
||||
pr_err(MIKRO_LZ77 "decode loop broken\n");
|
||||
rc = -EINVAL;
|
||||
|
||||
free_lz77_struct:
|
||||
kfree(opcode);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rb_lz77_decompress);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Mikrotik Wi-Fi caldata LZ77 decompressor");
|
||||
MODULE_AUTHOR("John Thomson");
|
@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2024 John Thomson
|
||||
*/
|
||||
|
||||
#ifndef __MIKROTIK_WLAN_LZ77_H__
|
||||
#define __MIKROTIK_WLAN_LZ77_H__
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
#ifdef CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77
|
||||
/**
|
||||
* rb_lz77_decompress
|
||||
*
|
||||
* @in: compressed data ptr
|
||||
* @in_len: length of compressed data
|
||||
* @out: buffer ptr to decompress into
|
||||
* @out_len: length of decompressed buffer in input,
|
||||
* length of decompressed data in success
|
||||
*
|
||||
* Returns 0 on success, or negative error
|
||||
*/
|
||||
int rb_lz77_decompress(const u8 *in, const size_t in_len, u8 *out,
|
||||
size_t *out_len);
|
||||
|
||||
#else /* CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 */
|
||||
|
||||
static inline int rb_lz77_decompress(const u8 *in, const size_t in_len, u8 *out,
|
||||
size_t *out_len)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 */
|
||||
#endif /* __MIKROTIK_WLAN_LZ77_H__ */
|
@ -15,6 +15,7 @@
|
||||
#define RB_MAGIC_HARD (('H') | ('a' << 8) | ('r' << 16) | ('d' << 24))
|
||||
#define RB_MAGIC_SOFT (('S') | ('o' << 8) | ('f' << 16) | ('t' << 24))
|
||||
#define RB_MAGIC_LZOR (('L') | ('Z' << 8) | ('O' << 16) | ('R' << 24))
|
||||
#define RB_MAGIC_LZ77 (('L' << 24) | ('Z' << 16) | ('7' << 8) | ('7'))
|
||||
#define RB_MAGIC_ERD (('E' << 16) | ('R' << 8) | ('D'))
|
||||
|
||||
#define RB_ART_SIZE 0x10000
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 9e1a0d2006bc108b239b5bc00b42c2a8cc651217 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 23:58:41 +0100
|
||||
Subject: [PATCH] net: phy: populate host_interfaces when attaching PHY
|
||||
|
||||
Use bitmask of interfaces supported by the MAC for the PHY to choose
|
||||
from if the declared interface mode is among those using a single pair
|
||||
of SerDes lanes.
|
||||
This will allow 2500Base-T PHYs to switch to SGMII on most hosts, which
|
||||
results in half-duplex being supported in case the MAC supports them.
|
||||
Without this change, 2500Base-T PHYs will always operate in 2500Base-X
|
||||
mode with rate-matching, which is not only wasteful in terms of energy
|
||||
consumption, but also limits the supported interface modes to
|
||||
full-duplex only.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -2044,6 +2044,13 @@ int phylink_fwnode_phy_connect(struct ph
|
||||
pl->link_config.interface = pl->link_interface;
|
||||
}
|
||||
|
||||
+ /* Assume SerDes interface modes share the same lanes and allow
|
||||
+ * the PHY to switch between them
|
||||
+ */
|
||||
+ if (test_bit(pl->link_interface, phylink_sfp_interfaces))
|
||||
+ phy_interface_and(phy_dev->host_interfaces, phylink_sfp_interfaces,
|
||||
+ pl->config->supported_interfaces);
|
||||
+
|
||||
ret = phy_attach_direct(pl->netdev, phy_dev, flags,
|
||||
pl->link_interface);
|
||||
phy_device_free(phy_dev);
|
@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -1107,6 +1111,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
|
||||
@@ -1102,6 +1106,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
|
||||
return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int rtlgen_resume(struct phy_device *phydev)
|
||||
{
|
||||
int ret = genphy_resume(phydev);
|
||||
@@ -1382,6 +1405,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1377,6 +1400,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
@ -58,7 +58,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1393,6 +1417,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1388,6 +1412,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
@ -66,7 +66,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1406,6 +1431,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1401,6 +1426,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
@ -74,7 +74,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1419,6 +1445,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1414,6 +1440,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
@ -82,7 +82,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -1430,6 +1457,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1425,6 +1452,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
@ -90,7 +90,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1443,6 +1471,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1438,6 +1466,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
@ -1,26 +0,0 @@
|
||||
From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 22 Apr 2023 01:23:08 +0100
|
||||
Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
|
||||
advertisement
|
||||
|
||||
Use existing generic inline functions to encode local advertisement
|
||||
of 10GbE link modes as well as to decode link-partner advertisement.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 22 +++++-----------------
|
||||
1 file changed, 5 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -910,7 +910,8 @@ static int rtl822x_config_aneg(struct ph
|
||||
|
||||
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
||||
MDIO_AN_10GBT_CTRL_ADV2_5G |
|
||||
- MDIO_AN_10GBT_CTRL_ADV5G,
|
||||
+ MDIO_AN_10GBT_CTRL_ADV5G |
|
||||
+ MDIO_AN_10GBT_CTRL_ADV10G,
|
||||
adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
@ -1,28 +0,0 @@
|
||||
From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 22 Apr 2023 01:25:39 +0100
|
||||
Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
|
||||
advertisement
|
||||
|
||||
Only use link-partner advertisement bits for 10GbE modes if they are
|
||||
actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
|
||||
unless both of them are set.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -950,6 +950,10 @@ static int rtl822x_read_status(struct ph
|
||||
if (lpadv < 0)
|
||||
return lpadv;
|
||||
|
||||
+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
|
||||
+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
|
||||
+ lpadv = 0;
|
||||
+
|
||||
mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
|
||||
lpadv);
|
||||
}
|
@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1085,10 +1085,32 @@ static int rtl8226_match_phy_device(stru
|
||||
@@ -1080,10 +1080,32 @@ static int rtl8226_match_phy_device(stru
|
||||
static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
|
||||
bool is_c45)
|
||||
{
|
@ -12,7 +12,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1287,6 +1287,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
@@ -1282,6 +1282,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
static struct phy_driver realtek_drvs[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00008201),
|
||||
@@ -1453,6 +1498,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1448,6 +1493,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
@ -73,7 +73,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.probe = rtl822x_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1467,6 +1514,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1462,6 +1509,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
@ -82,7 +82,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.probe = rtl822x_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1479,6 +1528,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1474,6 +1523,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
@ -91,7 +91,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.probe = rtl822x_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1493,6 +1544,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1488,6 +1539,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
@ -0,0 +1,117 @@
|
||||
From 66d82d3f04623e9c096e12c10ca51141c345ee84 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 20:59:51 +0100
|
||||
Subject: [PATCH] net: phy: realtek: read duplex and gbit master from PHYSR
|
||||
register
|
||||
|
||||
The PHYSR MMD register is present and defined equally for all RTL82xx
|
||||
Ethernet PHYs.
|
||||
Read duplex and gbit master bits from rtlgen_decode_speed() and rename
|
||||
it to rtlgen_decode_physr().
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 48 ++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 40 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -80,20 +80,24 @@
|
||||
|
||||
#define RTL822X_VND2_GANLPAR 0xa414
|
||||
|
||||
-#define RTL822X_VND2_PHYSR 0xa434
|
||||
-
|
||||
#define RTL8221B_PHYCR1 0xa430
|
||||
#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
||||
#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
|
||||
|
||||
+#define RTL_VND2_PHYSR 0xa434
|
||||
+#define RTL_VND2_PHYSR_LINK BIT(2)
|
||||
+#define RTL_VND2_PHYSR_DUPLEX BIT(3)
|
||||
+#define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4)
|
||||
+#define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9)
|
||||
+#define RTL_VND2_PHYSR_MASTER BIT(11)
|
||||
+#define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
|
||||
+
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
#define RTL9000A_GINMR 0x14
|
||||
#define RTL9000A_GINMR_LINK_STATUS BIT(4)
|
||||
|
||||
-#define RTLGEN_SPEED_MASK 0x0630
|
||||
-
|
||||
#define RTL_GENERIC_PHYID 0x001cc800
|
||||
#define RTL_8211FVD_PHYID 0x001cc878
|
||||
#define RTL_8221B_VB_CG 0x001cc849
|
||||
@@ -661,9 +665,24 @@ static int rtl8366rb_config_init(struct
|
||||
}
|
||||
|
||||
/* get actual speed to cover the downshift case */
|
||||
-static void rtlgen_decode_speed(struct phy_device *phydev, int val)
|
||||
+static void rtlgen_decode_physr(struct phy_device *phydev, int val)
|
||||
{
|
||||
- switch (val & RTLGEN_SPEED_MASK) {
|
||||
+ /* bit 2
|
||||
+ * 0: Link not OK
|
||||
+ * 1: Link OK
|
||||
+ */
|
||||
+ phydev->link = !!(val & RTL_VND2_PHYSR_LINK);
|
||||
+
|
||||
+ /* bit 3
|
||||
+ * 0: Half Duplex
|
||||
+ * 1: Full Duplex
|
||||
+ */
|
||||
+ if (val & RTL_VND2_PHYSR_DUPLEX)
|
||||
+ phydev->duplex = DUPLEX_FULL;
|
||||
+ else
|
||||
+ phydev->duplex = DUPLEX_HALF;
|
||||
+
|
||||
+ switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
|
||||
case 0x0000:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
@@ -685,6 +704,19 @@ static void rtlgen_decode_speed(struct p
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ /* bit 11
|
||||
+ * 0: Slave Mode
|
||||
+ * 1: Master Mode
|
||||
+ */
|
||||
+ if (phydev->speed >= 1000) {
|
||||
+ if (val & RTL_VND2_PHYSR_MASTER)
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
|
||||
+ else
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
|
||||
+ } else {
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int rtlgen_read_status(struct phy_device *phydev)
|
||||
@@ -702,7 +734,7 @@ static int rtlgen_read_status(struct phy
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
- rtlgen_decode_speed(phydev, val);
|
||||
+ rtlgen_decode_physr(phydev, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1030,11 +1062,11 @@ static int rtl822x_c45_read_status(struc
|
||||
return 0;
|
||||
|
||||
/* Read actual speed from vendor register. */
|
||||
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
- rtlgen_decode_speed(phydev, val);
|
||||
+ rtlgen_decode_physr(phydev, val);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
From eaca24de0c0e64145c130759207da32594d2e5d1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 21:05:47 +0100
|
||||
Subject: [PATCH 2/3] net: phy: realtek: change order of calls in C22
|
||||
read_status()
|
||||
|
||||
Always call rtlgen_read_status() first, so genphy_read_status() which
|
||||
is called by it clears bits in case auto-negotiation has not completed.
|
||||
Also clear 10GBT link-partner advertisement bits in case auto-negotiation
|
||||
is disabled or has not completed.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -979,17 +979,25 @@ static void rtl822xb_update_interface(st
|
||||
|
||||
static int rtl822x_read_status(struct phy_device *phydev)
|
||||
{
|
||||
- if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||
- int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
|
||||
+ int lpadv, ret;
|
||||
|
||||
- if (lpadv < 0)
|
||||
- return lpadv;
|
||||
+ ret = rtlgen_read_status(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
|
||||
- lpadv);
|
||||
+ if (phydev->autoneg == AUTONEG_DISABLE ||
|
||||
+ !phydev->autoneg_complete) {
|
||||
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
- return rtlgen_read_status(phydev);
|
||||
+ lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
|
||||
+ if (lpadv < 0)
|
||||
+ return lpadv;
|
||||
+
|
||||
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int rtl822xb_read_status(struct phy_device *phydev)
|
@ -0,0 +1,28 @@
|
||||
From 8b137d1e405dc90300ba577db44c70f0e026636e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 21:09:19 +0100
|
||||
Subject: [PATCH 3/3] net: phy: realtek: clear 1000Base-T link partner
|
||||
advertisement
|
||||
|
||||
Clear 1000Base-T link partner advertisement bits in Clause-45
|
||||
read_status() function in case auto-negotiation is disabled or has not
|
||||
been completed.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1056,6 +1056,10 @@ static int rtl822x_c45_read_status(struc
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ if (phydev->autoneg == AUTONEG_DISABLE ||
|
||||
+ !genphy_c45_aneg_done(phydev))
|
||||
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
+
|
||||
/* Vendor register as C45 has no standardized support for 1000BaseT */
|
||||
if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||
val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
@ -117,6 +117,9 @@ ipq40xx_setup_interfaces()
|
||||
qxwlan,e2600ac-c2)
|
||||
ucidef_set_interfaces_lan_wan "sw-eth1 sw-eth2" "sw-eth3"
|
||||
;;
|
||||
skspruce,wia3300-20)
|
||||
ucidef_set_interfaces_lan_wan "ETH2" "ETH1"
|
||||
;;
|
||||
zte,mf286d)
|
||||
ucidef_set_interfaces_lan_wan "lan2 lan3 lan4" "wan"
|
||||
;;
|
||||
|
@ -0,0 +1,446 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
|
||||
#include "qcom-ipq4019.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/soc/qcom,tcsr.h>
|
||||
|
||||
/ {
|
||||
compatible = "skspruce,wia3300-20", "qcom,ipq4019";
|
||||
model = "SKSpruce WIA3300-20";
|
||||
|
||||
aliases {
|
||||
label-mac-device = &gmac;
|
||||
led-boot = &led_status_red;
|
||||
led-failsafe = &led_status_lime;
|
||||
led-running = &led_status_lime;
|
||||
led-upgrade = &led_status_red;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
pinctrl-0 = <&key_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
pinctrl-0 = <&led_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
led_status_red: led-0 {
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_status_lime: led-1 {
|
||||
color = <LED_COLOR_ID_LIME>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
gpios = <&tlmm 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led-2 {
|
||||
color = <LED_COLOR_ID_LIME>;
|
||||
function = LED_FUNCTION_WLAN_2GHZ;
|
||||
gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy0tpt";
|
||||
};
|
||||
|
||||
led-3 {
|
||||
color = <LED_COLOR_ID_LIME>;
|
||||
function = LED_FUNCTION_WLAN_5GHZ;
|
||||
gpios = <&tlmm 28 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy1tpt";
|
||||
};
|
||||
};
|
||||
|
||||
output-usb-power {
|
||||
compatible = "regulator-output";
|
||||
vout-supply = <®_usb>;
|
||||
};
|
||||
|
||||
reg_usb: regulator-usb {
|
||||
compatible = "regulator-fixed";
|
||||
|
||||
pinctrl-0 = <®_usb_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
enable-active-high;
|
||||
gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-name = "reg_usb";
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
soc {
|
||||
tcsr@1949000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x1949000 0x100>;
|
||||
qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
|
||||
};
|
||||
|
||||
tcsr@194b000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x194b000 0x100>;
|
||||
qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
|
||||
};
|
||||
|
||||
ess_tcsr@1953000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x1953000 0x1000>;
|
||||
qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
|
||||
};
|
||||
|
||||
tcsr@1957000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x1957000 0x100>;
|
||||
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp_dma {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_spi1 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&spi0_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
spi-max-frequency = <24000000>;
|
||||
reg = <0>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "0:SBL1";
|
||||
reg = <0x00000000 0x00040000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@40000 {
|
||||
label = "0:MIBIB";
|
||||
reg = <0x00040000 0x00020000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@60000 {
|
||||
label = "0:QSEE";
|
||||
reg = <0x00060000 0x00060000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@c0000 {
|
||||
label = "0:CDT";
|
||||
reg = <0x000c0000 0x00010000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@d0000 {
|
||||
label = "0:DDRPARAMS";
|
||||
reg = <0x000d0000 0x00010000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@e0000 {
|
||||
compatible = "u-boot,env";
|
||||
label = "0:APPSBLENV";
|
||||
reg = <0x000e0000 0x00010000>;
|
||||
};
|
||||
|
||||
partition@f0000 {
|
||||
label = "0:APPSBL";
|
||||
reg = <0x000f0000 0x00080000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@170000 {
|
||||
label = "0:oldART";
|
||||
reg = <0x00170000 0x00010000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@180000 {
|
||||
label = "0:HLOS";
|
||||
reg = <0x00180000 0x00800000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@980000 {
|
||||
compatible = "denx,fit";
|
||||
label = "firmware";
|
||||
reg = <0x980000 0x35d0000>;
|
||||
};
|
||||
|
||||
partition@3f50000 {
|
||||
label = "0:APPSBL1";
|
||||
reg = <0x03f50000 0x00080000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@3fd0000 {
|
||||
label = "BoardInfo";
|
||||
reg = <0x03fd0000 0x00010000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
macaddr_boardinfo_108a: macaddr@108a {
|
||||
compatible = "mac-base";
|
||||
reg = <0x108a 0x6>;
|
||||
#nvmem-cell-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
partition@3fe0000 {
|
||||
label = "RebootCause";
|
||||
reg = <0x03fe0000 0x00010000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@3ff0000 {
|
||||
label = "0:ART";
|
||||
reg = <0x03ff0000 0x00010000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
precal_art_1000: precal@1000 {
|
||||
reg = <0x1000 0x2f20>;
|
||||
};
|
||||
|
||||
precal_art_5000: precal@5000 {
|
||||
reg = <0x5000 0x2f20>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart1 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&serial0_pins>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&crypto {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cryptobam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ðphy3 {
|
||||
leds {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_LIME>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ðphy4 {
|
||||
leds {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_LIME>;
|
||||
function = LED_FUNCTION_WAN;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gmac {
|
||||
status = "okay";
|
||||
|
||||
nvmem-cells = <&macaddr_boardinfo_108a 0>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&mdio {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
reset-delay-us = <2000>;
|
||||
reset-post-delay-us = <2000>;
|
||||
reset-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
&prng {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qpic_bam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&switch {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&swport4 {
|
||||
status = "okay";
|
||||
|
||||
label = "ETH2";
|
||||
nvmem-cells = <&macaddr_boardinfo_108a 1>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&swport5 {
|
||||
status = "okay";
|
||||
|
||||
label = "ETH1";
|
||||
nvmem-cells = <&macaddr_boardinfo_108a 0>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
key_pins: key_pinmux {
|
||||
gpio {
|
||||
pins = "gpio18";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
led_pins: led_pinmux {
|
||||
gpio {
|
||||
pins = "gpio8", "gpio9", "gpio11", "gpio28";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
drive-open-drain;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
mdio_pins: mdio_pinmux {
|
||||
gpio {
|
||||
pins = "gpio43";
|
||||
function = "gpio";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
output-high;
|
||||
};
|
||||
|
||||
mdc {
|
||||
pins = "gpio7";
|
||||
function = "mdc";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mdio {
|
||||
pins = "gpio6";
|
||||
function = "mdio";
|
||||
drive-strength = <4>;
|
||||
drive-open-drain;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
reg_usb_pins: reg_usb_pinmux {
|
||||
gpio {
|
||||
pins = "gpio25";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
|
||||
serial0_pins: serial0_pinmux {
|
||||
blsp_uart0 {
|
||||
pins = "gpio16", "gpio17";
|
||||
function = "blsp_uart0";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_pins: spi0_pinmux {
|
||||
blsp_spi0 {
|
||||
pins = "gpio13", "gpio14", "gpio15";
|
||||
function = "blsp_spi0";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
gpio {
|
||||
pins = "gpio12";
|
||||
function = "gpio";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&usb2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2_hs_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
status = "okay";
|
||||
|
||||
nvmem-cell-names = "mac-address", "pre-calibration";
|
||||
nvmem-cells = <&macaddr_boardinfo_108a 3>, <&precal_art_1000>;
|
||||
qcom,ath10k-calibration-variant = "SKSpruce_WIA3300-20";
|
||||
};
|
||||
|
||||
&wifi1 {
|
||||
status = "okay";
|
||||
|
||||
nvmem-cell-names = "mac-address", "pre-calibration";
|
||||
nvmem-cells = <&macaddr_boardinfo_108a 4>, <&precal_art_5000>;
|
||||
qcom,ath10k-calibration-variant = "SKSpruce_WIA3300-20";
|
||||
};
|
@ -3,4 +3,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
CONFIG_MTD_UBI_BLOCK=y
|
||||
CONFIG_MTD_UBI_NVMEM=y
|
||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
|
||||
CONFIG_UBIFS_FS=y
|
||||
|
@ -1092,6 +1092,19 @@ define Device/qxwlan_e2600ac-c2
|
||||
endef
|
||||
TARGET_DEVICES += qxwlan_e2600ac-c2
|
||||
|
||||
define Device/skspruce_wia3300-20
|
||||
$(call Device/FitImage)
|
||||
BLOCKSIZE := 64k
|
||||
IMAGE_SIZE := 55104k
|
||||
SOC := qcom-ipq4019
|
||||
DEVICE_VENDOR := SKSpruce
|
||||
DEVICE_MODEL := WIA3300-20
|
||||
DEVICE_PACKAGES := -ath10k-board-qca4019 ipq-wifi-skspruce_wia3300-20
|
||||
IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \
|
||||
append-rootfs | pad-rootfs | check-size | append-metadata
|
||||
endef
|
||||
TARGET_DEVICES +=skspruce_wia3300-20
|
||||
|
||||
define Device/sony_ncp-hg100-cellular
|
||||
$(call Device/FitImage)
|
||||
DEVICE_VENDOR := Sony
|
||||
|
@ -1,5 +1,6 @@
|
||||
CONFIG_MIKROTIK=y
|
||||
CONFIG_MIKROTIK_RB_SYSFS=y
|
||||
CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77=y
|
||||
CONFIG_MTD_ROUTERBOOT_PARTS=y
|
||||
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
|
||||
CONFIG_MTD_SPLIT_MINOR_FW=y
|
||||
|
@ -1,14 +1,15 @@
|
||||
From c14e7c954fd752fbb3da17a8bcf65cd9dbf41186 Mon Sep 17 00:00:00 2001
|
||||
From 656f5fdeb6ee6fa95c28cab3b535e2e09ef59c57 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:05 +0800
|
||||
Subject: [PATCH 01/13] net: phy: mediatek: Re-organize MediaTek ethernet phy
|
||||
Date: Fri, 4 Oct 2024 18:24:05 +0800
|
||||
Subject: [PATCH 1/9] net: phy: mediatek: Re-organize MediaTek ethernet phy
|
||||
drivers
|
||||
|
||||
Re-organize MediaTek ethernet phy driver files and get ready to integrate
|
||||
some common functions and add new 2.5G phy driver.
|
||||
some common functions (and add new 2.5G phy driver).
|
||||
mtk-ge.c: MT7530 Gphy on MT7621 & MT7531 Gphy
|
||||
mtk-ge-soc.c: Built-in Gphy on MT7981 & Built-in switch Gphy on MT7988
|
||||
mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988
|
||||
(mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988
|
||||
--> in another patchset)
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
@ -18,7 +19,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
drivers/net/phy/mediatek/Makefile | 3 +++
|
||||
.../mtk-ge-soc.c} | 0
|
||||
.../phy/{mediatek-ge.c => mediatek/mtk-ge.c} | 0
|
||||
7 files changed, 29 insertions(+), 20 deletions(-)
|
||||
6 files changed, 27 insertions(+), 18 deletions(-)
|
||||
create mode 100644 drivers/net/phy/mediatek/Kconfig
|
||||
create mode 100644 drivers/net/phy/mediatek/Makefile
|
||||
rename drivers/net/phy/{mediatek-ge-soc.c => mediatek/mtk-ge-soc.c} (100%)
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 12054d38fc55adbfa2b40299ad8af3449d882ee2 Mon Sep 17 00:00:00 2001
|
||||
From 61bcabdb69418215ea05bdc48cb88459d757f505 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:06 +0800
|
||||
Subject: [PATCH 02/13] net: phy: mediatek: Fix spelling errors and rearrange
|
||||
Date: Fri, 4 Oct 2024 18:24:06 +0800
|
||||
Subject: [PATCH 2/9] net: phy: mediatek: Fix spelling errors and rearrange
|
||||
variables
|
||||
|
||||
This patch fixes spelling errors which comes from mediatek-ge-soc.c and
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 434e41555c45ec10b19320024163bb009da168bc Mon Sep 17 00:00:00 2001
|
||||
From 16bbd4ecb67ec1899ad8aa1eb1219a6d576cbaaf Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:07 +0800
|
||||
Subject: [PATCH 03/13] net: phy: mediatek: Move LED helper functions into mtk
|
||||
Date: Fri, 4 Oct 2024 18:24:07 +0800
|
||||
Subject: [PATCH 3/9] net: phy: mediatek: Move LED helper functions into mtk
|
||||
phy lib
|
||||
|
||||
This patch creates mtk-phy-lib.c & mtk-phy.h and integrates mtk-ge-soc.c's
|
||||
@ -15,7 +15,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 262 +++----------------------
|
||||
drivers/net/phy/mediatek/mtk-phy-lib.c | 251 +++++++++++++++++++++++
|
||||
drivers/net/phy/mediatek/mtk.h | 82 ++++++++
|
||||
6 files changed, 368 insertions(+), 235 deletions(-)
|
||||
5 files changed, 366 insertions(+), 235 deletions(-)
|
||||
create mode 100644 drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
create mode 100644 drivers/net/phy/mediatek/mtk.h
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 2783929879854d5750ba82e2e203663313362abb Mon Sep 17 00:00:00 2001
|
||||
From 2b118202583eb05a1799d435d2dce974dc3f5b16 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:08 +0800
|
||||
Subject: [PATCH 04/13] net: phy: mediatek: Improve readability of
|
||||
Date: Fri, 4 Oct 2024 18:24:08 +0800
|
||||
Subject: [PATCH 4/9] net: phy: mediatek: Improve readability of
|
||||
mtk-phy-lib.c's mtk_phy_led_hw_ctrl_set()
|
||||
|
||||
This patch removes parens around TRIGGER_NETDEV_RX/TRIGGER_NETDEV_TX in
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 58c1270423ab48464cdc31ef71ffe7f5b2441961 Mon Sep 17 00:00:00 2001
|
||||
From 59e7082cb8c8e89bceb44cc60df156d818c8da96 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:09 +0800
|
||||
Subject: [PATCH 05/13] net: phy: mediatek: Integrate read/write page helper
|
||||
Date: Fri, 4 Oct 2024 18:24:09 +0800
|
||||
Subject: [PATCH 5/9] net: phy: mediatek: Integrate read/write page helper
|
||||
functions
|
||||
|
||||
This patch integrates read/write page helper functions as MTK phy lib.
|
||||
|
@ -1,8 +1,7 @@
|
||||
From 9403f1d54598ae56386a8bf47a5b6b34c884e4f5 Mon Sep 17 00:00:00 2001
|
||||
From 5b605457b93d0979ab623ef2aa6eb456c46e511c Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:10 +0800
|
||||
Subject: [PATCH 06/13] net: phy: mediatek: Hook LED helper functions in
|
||||
mtk-ge.c
|
||||
Date: Fri, 4 Oct 2024 18:24:10 +0800
|
||||
Subject: [PATCH 6/9] net: phy: mediatek: Hook LED helper functions in mtk-ge.c
|
||||
|
||||
We have mtk-phy-lib.c now so that we can use LED helper functions in
|
||||
mtk-ge.c(mt7531 part). It also means that mt7531/mt7981/mt7988's
|
||||
@ -83,14 +82,14 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+}
|
||||
+
|
||||
+static const unsigned long supported_triggers =
|
||||
+ (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_10) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
+ BIT(TRIGGER_NETDEV_RX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX));
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_10) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
+ BIT(TRIGGER_NETDEV_RX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX);
|
||||
+
|
||||
+static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long rules)
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 51ee83602dbb84716180d9b6e43f6bebb0c2d7bd Mon Sep 17 00:00:00 2001
|
||||
From c5ff7bece642dbba601be89e70f78ff037ca084f Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:11 +0800
|
||||
Subject: [PATCH 07/13] net: phy: mediatek: add MT7530 & MT7531's PHY ID macros
|
||||
Date: Fri, 4 Oct 2024 18:24:11 +0800
|
||||
Subject: [PATCH 7/9] net: phy: mediatek: add MT7530 & MT7531's PHY ID macros
|
||||
|
||||
This patch adds MT7530 & MT7531's PHY ID macros in mtk-ge.c so that
|
||||
it follows the same rule of mtk-ge-soc.c.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From e73df692396b0d6bdcb2317299fa1e8e547f3446 Mon Sep 17 00:00:00 2001
|
||||
From dbe70a9353b5095a90af61a051486484765ada6f Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:12 +0800
|
||||
Subject: [PATCH 08/13] net: phy: mediatek: Change mtk-ge-soc.c line wrapping
|
||||
Date: Fri, 4 Oct 2024 18:24:12 +0800
|
||||
Subject: [PATCH 8/9] net: phy: mediatek: Change mtk-ge-soc.c line wrapping
|
||||
|
||||
This patch shrinks mtk-ge-soc.c line wrapping to 80 characters.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 60228de48d8bfde62b4db5945314e6a62079f091 Mon Sep 17 00:00:00 2001
|
||||
From ca024bc7267a8c0439325d352f9b8818ba0f2cf0 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:13 +0800
|
||||
Subject: [PATCH 09/13] net: phy: mediatek: Add token ring access helper
|
||||
Date: Fri, 4 Oct 2024 18:24:13 +0800
|
||||
Subject: [PATCH 9/9] net: phy: mediatek: Add token ring access helper
|
||||
functions in mtk-phy-lib
|
||||
|
||||
This patch adds TR(token ring) manipulations and adds correct
|
||||
|
@ -1,219 +0,0 @@
|
||||
From 3c05195fc2c232cd853fc8cebf55310c4605111d Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:14 +0800
|
||||
Subject: [PATCH 10/13] net: phy: mediatek: Extend 1G TX/RX link pulse time
|
||||
|
||||
We observe that some 10G devices' (mostly Marvell's chips inside) 1G
|
||||
training time violates specification, which may last 2230ms and affect
|
||||
later TX/RX link pulse time. This will invalidate MediaTek series
|
||||
gigabit Ethernet PHYs' hardware auto downshift mechanism.
|
||||
|
||||
Without this patch, if someone is trying to use "4-wire" cable to
|
||||
connect above devices, MediaTek' gigabit Ethernet PHYs may fail
|
||||
to downshift to 100Mbps. (If partner 10G devices' downshift mechanism
|
||||
stops at 1G)
|
||||
|
||||
This patch extends our 1G TX/RX link pulse time so that we can still
|
||||
link up with those 10G devices.
|
||||
|
||||
Tested device:
|
||||
- Netgear GS110EMX's 10G port (Marvell 88X3340P)
|
||||
- QNAP QSW-M408-4C
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 2 +
|
||||
drivers/net/phy/mediatek/mtk-ge.c | 5 +-
|
||||
drivers/net/phy/mediatek/mtk-phy-lib.c | 92 ++++++++++++++++++++++++++
|
||||
drivers/net/phy/mediatek/mtk.h | 21 ++++++
|
||||
4 files changed, 116 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
@@ -1396,6 +1396,7 @@ static struct phy_driver mtk_socphy_driv
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
|
||||
.name = "MediaTek MT7981 PHY",
|
||||
.config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
.config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
.probe = mt7981_phy_probe,
|
||||
@@ -1413,6 +1414,7 @@ static struct phy_driver mtk_socphy_driv
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
|
||||
.name = "MediaTek MT7988 PHY",
|
||||
.config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
.config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
.probe = mt7988_phy_probe,
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
||||
@@ -9,10 +9,6 @@
|
||||
#define MTK_GPHY_ID_MT7530 0x03a29412
|
||||
#define MTK_GPHY_ID_MT7531 0x03a29441
|
||||
|
||||
-#define MTK_PHY_PAGE_EXTENDED_1 0x0001
|
||||
-#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
|
||||
-#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
|
||||
-
|
||||
#define MTK_PHY_PAGE_EXTENDED_2 0x0002
|
||||
#define MTK_PHY_PAGE_EXTENDED_3 0x0003
|
||||
#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11
|
||||
@@ -251,6 +247,7 @@ static struct phy_driver mtk_gephy_drive
|
||||
.name = "MediaTek MT7531 PHY",
|
||||
.probe = mt7531_phy_probe,
|
||||
.config_init = mt7531_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
/* Interrupts are handled by the switch, not the PHY
|
||||
* itself.
|
||||
*/
|
||||
--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
@@ -109,6 +109,108 @@ int mtk_phy_write_page(struct phy_device
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtk_phy_write_page);
|
||||
|
||||
+/* This function deals with the case that 1G AN starts but isn't completed. We
|
||||
+ * set AN_NEW_LP_CNT_LIMIT with different values time after time to let our
|
||||
+ * 1G->100Mbps hardware automatic downshift to fit more partner devices.
|
||||
+ */
|
||||
+static int extend_an_new_lp_cnt_limit(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 reg_val;
|
||||
+ int timeout;
|
||||
+
|
||||
+ /* According to table 28-9 & Figure 28-18 in IEEE 802.3,
|
||||
+ * link_fail_inhibit_timer of 10/100/1000 Mbps devices ranges from 750
|
||||
+ * to "1000ms". Once MTK_PHY_FINAL_SPEED_1000 is set, it means that we
|
||||
+ * enter "FLP LINK GOOD CHECK" state, link_fail_inhibit_timer starts and
|
||||
+ * this PHY's 1G training starts. If 1G training never starts, we do
|
||||
+ * nothing but leave.
|
||||
+ */
|
||||
+ timeout = read_poll_timeout(ret = phy_read_mmd, reg_val,
|
||||
+ (ret < 0) ||
|
||||
+ reg_val & MTK_PHY_FINAL_SPEED_1000,
|
||||
+ 10000, 500000, false, phydev,
|
||||
+ MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
|
||||
+ phydev_dbg(phydev, "%s: Training Indicator: 0x%x\n", __func__, reg_val);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!timeout) {
|
||||
+ /* Once we found MTK_PHY_FINAL_SPEED_1000 is set, no matter 1G
|
||||
+ * AN is completed or not, we'll set AN_NEW_LP_CNT_LIMIT again
|
||||
+ * and again.
|
||||
+ */
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK, 0xf));
|
||||
+ msleep(1500);
|
||||
+
|
||||
+ /* Read phy status again to make sure the following step won't
|
||||
+ * affect normal devices.
|
||||
+ */
|
||||
+ ret = genphy_read_status(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (phydev->link)
|
||||
+ return 0;
|
||||
+
|
||||
+ timeout = read_poll_timeout(mtk_tr_read, reg_val,
|
||||
+ (reg_val & AN_STATE_MASK) !=
|
||||
+ (AN_STATE_TX_DISABLE <<
|
||||
+ AN_STATE_SHIFT),
|
||||
+ 10000, 1000000, false, phydev,
|
||||
+ 0x0, 0xf, 0x2);
|
||||
+ phydev_dbg(phydev, "%s: AN State: 0x%x\n", __func__, reg_val);
|
||||
+ if (!timeout) {
|
||||
+ msleep(625);
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
|
||||
+ AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ 0x8));
|
||||
+ msleep(500);
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
|
||||
+ AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ 0xf));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mtk_gphy_cl22_read_status(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = genphy_read_status(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) {
|
||||
+ ret = phy_read_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
|
||||
+ MTK_PHY_AUX_CTRL_AND_STATUS);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Once LP_DETECTED is set, it means that"ability_match" in
|
||||
+ * IEEE 802.3 Figure 28-18 is set. This happens after we plug in
|
||||
+ * cable. Also, LP_DETECTED will be cleared after AN complete.
|
||||
+ */
|
||||
+ if (!FIELD_GET(MTK_PHY_LP_DETECTED_MASK, ret))
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = phy_read(phydev, MII_CTRL1000);
|
||||
+ if (ret & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) {
|
||||
+ ret = extend_an_new_lp_cnt_limit(phydev);
|
||||
+ phydev_dbg(phydev, "%s: counter limit ret: %d\n", __func__, ret);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mtk_gphy_cl22_read_status);
|
||||
+
|
||||
int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules,
|
||||
unsigned long supported_triggers)
|
||||
--- a/drivers/net/phy/mediatek/mtk.h
|
||||
+++ b/drivers/net/phy/mediatek/mtk.h
|
||||
@@ -10,8 +10,28 @@
|
||||
|
||||
#define MTK_EXT_PAGE_ACCESS 0x1f
|
||||
#define MTK_PHY_PAGE_STANDARD 0x0000
|
||||
+#define MTK_PHY_PAGE_EXTENDED_1 0x0001
|
||||
+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
|
||||
+/* suprv_media_select_RefClk */
|
||||
+#define MTK_PHY_LP_DETECTED_MASK GENMASK(7, 6)
|
||||
+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
|
||||
+
|
||||
#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
|
||||
|
||||
+/* Registers on Token Ring debug nodes */
|
||||
+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x2 */
|
||||
+#define AN_STATE_MASK GENMASK(22, 19)
|
||||
+#define AN_STATE_SHIFT 19
|
||||
+#define AN_STATE_TX_DISABLE 1
|
||||
+
|
||||
+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
|
||||
+#define AN_NEW_LP_CNT_LIMIT_MASK GENMASK(23, 20)
|
||||
+#define AUTO_NP_10XEN BIT(6)
|
||||
+
|
||||
+/* Registers on MDIO_MMD_VEND1 */
|
||||
+#define MTK_PHY_LINK_STATUS_MISC (0xa2)
|
||||
+#define MTK_PHY_FINAL_SPEED_1000 BIT(3)
|
||||
+
|
||||
/* Registers on MDIO_MMD_VEND2 */
|
||||
#define MTK_PHY_LED0_ON_CTRL 0x24
|
||||
#define MTK_PHY_LED1_ON_CTRL 0x26
|
||||
@@ -78,6 +98,7 @@ void __mtk_tr_clr_bits(struct phy_device
|
||||
int mtk_phy_read_page(struct phy_device *phydev);
|
||||
int mtk_phy_write_page(struct phy_device *phydev, int page);
|
||||
|
||||
+int mtk_gphy_cl22_read_status(struct phy_device *phydev);
|
||||
int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules,
|
||||
unsigned long supported_triggers);
|
@ -42,7 +42,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/mediatek/mtk-2p5ge.c
|
||||
@@ -0,0 +1,432 @@
|
||||
@@ -0,0 +1,436 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/firmware.h>
|
||||
@ -59,6 +59,10 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+
|
||||
+#define MTK_2P5GPHY_ID_MT7988 (0x00339c11)
|
||||
+
|
||||
+#define MTK_PHY_PAGE_EXTENDED_1 0x0001
|
||||
+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
|
||||
+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
|
||||
+
|
||||
+#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin"
|
||||
+#define MT7988_2P5GE_PMB_FW_SIZE (0x20000)
|
||||
+#define MT7988_2P5GE_PMB_FW_BASE (0x0f100000)
|
||||
|
@ -1,130 +0,0 @@
|
||||
From 07e90eb1819319a0c34b0cf3a57a4a3878e96e4d Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:16 +0800
|
||||
Subject: [PATCH 12/13] net: phy: mediatek: Fix alignment in callback
|
||||
functions' hook
|
||||
|
||||
Align declarations in mtk_gephy_driver(mtk-ge.c) and
|
||||
mtk_socphy_driver(mtk-ge-soc.c). At first, some of them are
|
||||
".foo<tab>= method_foo", and others are ".bar<space>= method_bar".
|
||||
Use space instead for all of them here in case line is longer than
|
||||
80 chars.
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 40 +++++++++++++--------------
|
||||
drivers/net/phy/mediatek/mtk-ge.c | 34 +++++++++++------------
|
||||
2 files changed, 37 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
@@ -1394,17 +1394,17 @@ static int mt7981_phy_probe(struct phy_d
|
||||
static struct phy_driver mtk_socphy_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
|
||||
- .name = "MediaTek MT7981 PHY",
|
||||
- .config_init = mt798x_phy_config_init,
|
||||
- .read_status = mtk_gphy_cl22_read_status,
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .name = "MediaTek MT7981 PHY",
|
||||
+ .config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
+ .config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
- .probe = mt7981_phy_probe,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
- .read_page = mtk_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
- .led_blink_set = mt798x_phy_led_blink_set,
|
||||
+ .probe = mt7981_phy_probe,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .read_page = mtk_phy_read_page,
|
||||
+ .write_page = mtk_phy_write_page,
|
||||
+ .led_blink_set = mt798x_phy_led_blink_set,
|
||||
.led_brightness_set = mt798x_phy_led_brightness_set,
|
||||
.led_hw_is_supported = mt798x_phy_led_hw_is_supported,
|
||||
.led_hw_control_set = mt798x_phy_led_hw_control_set,
|
||||
@@ -1412,17 +1412,17 @@ static struct phy_driver mtk_socphy_driv
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
|
||||
- .name = "MediaTek MT7988 PHY",
|
||||
- .config_init = mt798x_phy_config_init,
|
||||
- .read_status = mtk_gphy_cl22_read_status,
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .name = "MediaTek MT7988 PHY",
|
||||
+ .config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
+ .config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
- .probe = mt7988_phy_probe,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
- .read_page = mtk_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
- .led_blink_set = mt798x_phy_led_blink_set,
|
||||
+ .probe = mt7988_phy_probe,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .read_page = mtk_phy_read_page,
|
||||
+ .write_page = mtk_phy_write_page,
|
||||
+ .led_blink_set = mt798x_phy_led_blink_set,
|
||||
.led_brightness_set = mt798x_phy_led_brightness_set,
|
||||
.led_hw_is_supported = mt798x_phy_led_hw_is_supported,
|
||||
.led_hw_control_set = mt798x_phy_led_hw_control_set,
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
||||
@@ -230,34 +230,34 @@ static int mt753x_phy_led_hw_control_set
|
||||
static struct phy_driver mtk_gephy_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
|
||||
- .name = "MediaTek MT7530 PHY",
|
||||
- .config_init = mt7530_phy_config_init,
|
||||
+ .name = "MediaTek MT7530 PHY",
|
||||
+ .config_init = mt7530_phy_config_init,
|
||||
/* Interrupts are handled by the switch, not the PHY
|
||||
* itself.
|
||||
*/
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
- .read_page = mtk_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .read_page = mtk_phy_read_page,
|
||||
+ .write_page = mtk_phy_write_page,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
|
||||
- .name = "MediaTek MT7531 PHY",
|
||||
- .probe = mt7531_phy_probe,
|
||||
- .config_init = mt7531_phy_config_init,
|
||||
- .read_status = mtk_gphy_cl22_read_status,
|
||||
+ .name = "MediaTek MT7531 PHY",
|
||||
+ .probe = mt7531_phy_probe,
|
||||
+ .config_init = mt7531_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
/* Interrupts are handled by the switch, not the PHY
|
||||
* itself.
|
||||
*/
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
- .read_page = mtk_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
- .led_blink_set = mt753x_phy_led_blink_set,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .read_page = mtk_phy_read_page,
|
||||
+ .write_page = mtk_phy_write_page,
|
||||
+ .led_blink_set = mt753x_phy_led_blink_set,
|
||||
.led_brightness_set = mt753x_phy_led_brightness_set,
|
||||
.led_hw_is_supported = mt753x_phy_led_hw_is_supported,
|
||||
.led_hw_control_set = mt753x_phy_led_hw_control_set,
|
@ -1,65 +0,0 @@
|
||||
From e59883b637ae317c2ac275b542e8a50670d76e7c Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:17 +0800
|
||||
Subject: [PATCH 13/13] net: phy: mediatek: Remove unnecessary outer parens of
|
||||
"supported_triggers" var
|
||||
|
||||
This patch removes unnecessary outer parens of "supported_triggers" vars
|
||||
in mtk-ge.c & mtk-ge-soc.c to improve readability.
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 16 ++++++++--------
|
||||
drivers/net/phy/mediatek/mtk-ge.c | 16 ++++++++--------
|
||||
2 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
@@ -1224,14 +1224,14 @@ static int mt798x_phy_led_brightness_set
|
||||
}
|
||||
|
||||
static const unsigned long supported_triggers =
|
||||
- (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
- BIT(TRIGGER_NETDEV_LINK) |
|
||||
- BIT(TRIGGER_NETDEV_LINK_10) |
|
||||
- BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
- BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
- BIT(TRIGGER_NETDEV_RX) |
|
||||
- BIT(TRIGGER_NETDEV_TX));
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_10) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
+ BIT(TRIGGER_NETDEV_RX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX);
|
||||
|
||||
static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules)
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
||||
@@ -189,14 +189,14 @@ static int mt753x_phy_led_brightness_set
|
||||
}
|
||||
|
||||
static const unsigned long supported_triggers =
|
||||
- (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
- BIT(TRIGGER_NETDEV_LINK) |
|
||||
- BIT(TRIGGER_NETDEV_LINK_10) |
|
||||
- BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
- BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
- BIT(TRIGGER_NETDEV_RX) |
|
||||
- BIT(TRIGGER_NETDEV_TX));
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_10) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
+ BIT(TRIGGER_NETDEV_RX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX);
|
||||
|
||||
static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules)
|
@ -63,6 +63,7 @@ CONFIG_MMC_SDHCI_XENON=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MIKROTIK=y
|
||||
CONFIG_MIKROTIK_RB_SYSFS=y
|
||||
# CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 is not set
|
||||
CONFIG_MTD_ROUTERBOOT_PARTS=y
|
||||
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
|
||||
CONFIG_MVEBU_GICP=y
|
||||
|
@ -128,6 +128,7 @@ CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MIKROTIK=y
|
||||
CONFIG_MIKROTIK_RB_SYSFS=y
|
||||
# CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 is not set
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
|
Loading…
x
Reference in New Issue
Block a user