diff options
Diffstat (limited to 'drivers')
308 files changed, 17505 insertions, 3420 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 6742f6c68034..9bff853e85f3 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -1007,7 +1007,7 @@ skip: /* The record may be cleared by others, try read next record */ if (len == -ENOENT) goto skip; - else if (len < sizeof(*rcd)) { + else if (len < 0 || len < sizeof(*rcd)) { rc = -EIO; goto out; } diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 30e84cc600ae..06ea4749ebd9 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1171,7 +1171,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); struct cpc_register_resource *desired_reg; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); - struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; + struct cppc_pcc_data *pcc_ss_data; int ret = 0; if (!cpc_desc || pcc_ss_id < 0) { diff --git a/drivers/bcma/driver_pcie2.c b/drivers/bcma/driver_pcie2.c index b1a6e327cb23..cf889fc62ac7 100644 --- a/drivers/bcma/driver_pcie2.c +++ b/drivers/bcma/driver_pcie2.c @@ -83,7 +83,8 @@ static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2) bcma_core_pcie2_set_ltr_vals(pcie2); /* TODO: - si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */ + *si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); + */ /* enable the LTR */ devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB; diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ccb9975a97fa..ad0477ae820f 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -35,13 +35,13 @@ static inline u64 mb_per_tick(int mbps) struct nullb_cmd { struct list_head list; struct llist_node ll_list; - call_single_data_t csd; + struct __call_single_data csd; struct request *rq; struct bio *bio; unsigned int tag; + blk_status_t error; struct nullb_queue *nq; struct hrtimer timer; - blk_status_t error; }; struct nullb_queue { diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 60e1c7d6986d..45a2f59cd935 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -31,6 +31,16 @@ config BT_HCIBTUSB Say Y here to compile support for Bluetooth USB devices into the kernel or say M to compile it as module (btusb). +config BT_HCIBTUSB_AUTOSUSPEND + bool "Enable USB autosuspend for Bluetooth USB devices by default" + depends on BT_HCIBTUSB + help + Say Y here to enable USB autosuspend for Bluetooth USB devices by + default. + + This can be overridden by passing btusb.enable_autosuspend=[y|n] + on the kernel commandline. + config BT_HCIBTUSB_BCM bool "Broadcom protocol support" depends on BT_HCIBTUSB diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index d513ef4743dc..82437a69f99c 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -302,9 +302,7 @@ static void bluecard_write_wakeup(struct bluecard_info *info) } /* Wait until the command reaches the baseband */ - prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE); - schedule_timeout(HZ/10); - finish_wait(&wq, &wait); + mdelay(100); /* Set baud on baseband */ info->ctrl_reg &= ~0x03; @@ -316,9 +314,7 @@ static void bluecard_write_wakeup(struct bluecard_info *info) outb(info->ctrl_reg, iobase + REG_CONTROL); /* Wait before the next HCI packet can be send */ - prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - finish_wait(&wq, &wait); + mdelay(1000); } if (len == skb->len) { diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c index 663bed63b871..2c9a5fc9137d 100644 --- a/drivers/bluetooth/btqcomsmd.c +++ b/drivers/bluetooth/btqcomsmd.c @@ -88,7 +88,8 @@ static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb) break; } - kfree_skb(skb); + if (!ret) + kfree_skb(skb); return ret; } diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index c8e945d19ffe..20142bc77554 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -31,6 +31,7 @@ #include <linux/errno.h> #include <linux/skbuff.h> +#include <linux/mmc/host.h> #include <linux/mmc/sdio_ids.h> #include <linux/mmc/sdio_func.h> @@ -292,6 +293,14 @@ static int btsdio_probe(struct sdio_func *func, tuple = tuple->next; } + /* BCM43341 devices soldered onto the PCB (non-removable) use an + * uart connection for bluetooth, ignore the BT SDIO interface. + */ + if (func->vendor == SDIO_VENDOR_ID_BROADCOM && + func->device == SDIO_DEVICE_ID_BROADCOM_43341 && + !mmc_card_is_removable(func->card->host)) + return -ENODEV; + data = devm_kzalloc(&func->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f7120c9eb9bd..808c249845db 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -40,6 +40,7 @@ static bool disable_scofix; static bool force_scofix; +static bool enable_autosuspend = IS_ENABLED(CONFIG_BT_HCIBTUSB_AUTOSUSPEND); static bool reset = true; @@ -3213,6 +3214,9 @@ static int btusb_probe(struct usb_interface *intf, } #endif + if (enable_autosuspend) + usb_enable_autosuspend(data->udev); + err = hci_register_dev(hdev); if (err < 0) goto out_free_dev; @@ -3425,6 +3429,9 @@ MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size"); module_param(force_scofix, bool, 0644); MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size"); +module_param(enable_autosuspend, bool, 0644); +MODULE_PARM_DESC(enable_autosuspend, "Enable USB autosuspend by default"); + module_param(reset, bool, 0644); MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 707c2d1b84c7..47fc58c9eb49 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -939,6 +939,7 @@ static const struct acpi_device_id bcm_acpi_match[] = { { "BCM2E65", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, { "BCM2E67", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, { "BCM2E71", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E72", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, { "BCM2E7B", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, { "BCM2E7C", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, { "BCM2E7E", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index e2c078d61730..1b4417a623a4 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -53,9 +53,14 @@ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> #include <linux/gpio/consumer.h> +#include <linux/nvmem-consumer.h> #include "hci_uart.h" +/* Vendor-specific HCI commands */ +#define HCI_VS_WRITE_BD_ADDR 0xfc06 +#define HCI_VS_UPDATE_UART_HCI_BAUDRATE 0xff36 + /* HCILL commands */ #define HCILL_GO_TO_SLEEP_IND 0x30 #define HCILL_GO_TO_SLEEP_ACK 0x31 @@ -86,6 +91,7 @@ struct ll_device { struct serdev_device *serdev; struct gpio_desc *enable_gpio; struct clk *ext_clk; + bdaddr_t bdaddr; }; struct ll_struct { @@ -620,7 +626,7 @@ static int download_firmware(struct ll_device *lldev) case ACTION_SEND_COMMAND: /* action send */ bt_dev_dbg(lldev->hu.hdev, "S"); cmd = (struct hci_command *)action_ptr; - if (cmd->opcode == 0xff36) { + if (cmd->opcode == HCI_VS_UPDATE_UART_HCI_BAUDRATE) { /* ignore remote change * baud rate HCI VS command */ @@ -628,11 +634,11 @@ static int download_firmware(struct ll_device *lldev) break; } if (cmd->prefix != 1) - bt_dev_dbg(lldev->hu.hdev, "command type %d\n", cmd->prefix); + bt_dev_dbg(lldev->hu.hdev, "command type %d", cmd->prefix); skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { - bt_dev_err(lldev->hu.hdev, "send command failed\n"); + bt_dev_err(lldev->hu.hdev, "send command failed"); err = PTR_ERR(skb); goto out_rel_fw; } @@ -659,6 +665,24 @@ out_rel_fw: return err; } +static int ll_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) +{ + bdaddr_t bdaddr_swapped; + struct sk_buff *skb; + + /* HCI_VS_WRITE_BD_ADDR (at least on a CC2560A chip) expects the BD + * address to be MSB first, but bdaddr_t has the convention of being + * LSB first. + */ + baswap(&bdaddr_swapped, bdaddr); + skb = __hci_cmd_sync(hdev, HCI_VS_WRITE_BD_ADDR, sizeof(bdaddr_t), + &bdaddr_swapped, HCI_INIT_TIMEOUT); + if (!IS_ERR(skb)) + kfree_skb(skb); + + return PTR_ERR_OR_ZERO(skb); +} + static int ll_setup(struct hci_uart *hu) { int err, retry = 3; @@ -671,14 +695,20 @@ static int ll_setup(struct hci_uart *hu) lldev = serdev_device_get_drvdata(serdev); + hu->hdev->set_bdaddr = ll_set_bdaddr; + serdev_device_set_flow_control(serdev, true); do { - /* Configure BT_EN to HIGH state */ + /* Reset the Bluetooth device */ gpiod_set_value_cansleep(lldev->enable_gpio, 0); msleep(5); gpiod_set_value_cansleep(lldev->enable_gpio, 1); - msleep(100); + err = serdev_device_wait_for_cts(serdev, true, 200); + if (err) { + bt_dev_err(hu->hdev, "Failed to get CTS"); + return err; + } err = download_firmware(lldev); if (!err) @@ -691,6 +721,18 @@ static int ll_setup(struct hci_uart *hu) if (err) return err; + /* Set BD address if one was specified at probe */ + if (!bacmp(&lldev->bdaddr, BDADDR_NONE)) { + /* This means that there was an error getting the BD address + * during probe, so mark the device as having a bad address. + */ + set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks); + } else if (bacmp(&lldev->bdaddr, BDADDR_ANY)) { + err = ll_set_bdaddr(hu->hdev, &lldev->bdaddr); + if (err) + set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks); + } + /* Operational speed if any */ if (hu->oper_speed) speed = hu->oper_speed; @@ -700,7 +742,12 @@ static int ll_setup(struct hci_uart *hu) speed = 0; if (speed) { - struct sk_buff *skb = __hci_cmd_sync(hu->hdev, 0xff36, sizeof(speed), &speed, HCI_INIT_TIMEOUT); + __le32 speed_le = cpu_to_le32(speed); + struct sk_buff *skb; + + skb = __hci_cmd_sync(hu->hdev, HCI_VS_UPDATE_UART_HCI_BAUDRATE, + sizeof(speed_le), &speed_le, + HCI_INIT_TIMEOUT); if (!IS_ERR(skb)) { kfree_skb(skb); serdev_device_set_baudrate(serdev, speed); @@ -716,6 +763,7 @@ static int hci_ti_probe(struct serdev_device *serdev) { struct hci_uart *hu; struct ll_device *lldev; + struct nvmem_cell *bdaddr_cell; u32 max_speed = 3000000; lldev = devm_kzalloc(&serdev->dev, sizeof(struct ll_device), GFP_KERNEL); @@ -737,6 +785,52 @@ static int hci_ti_probe(struct serdev_device *serdev) of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed); hci_uart_set_speeds(hu, 115200, max_speed); + /* optional BD address from nvram */ + bdaddr_cell = nvmem_cell_get(&serdev->dev, "bd-address"); + if (IS_ERR(bdaddr_cell)) { + int err = PTR_ERR(bdaddr_cell); + + if (err == -EPROBE_DEFER) + return err; + + /* ENOENT means there is no matching nvmem cell and ENOSYS + * means that nvmem is not enabled in the kernel configuration. + */ + if (err != -ENOENT && err != -ENOSYS) { + /* If there was some other error, give userspace a + * chance to fix the problem instead of failing to load + * the driver. Using BDADDR_NONE as a flag that is + * tested later in the setup function. + */ + dev_warn(&serdev->dev, + "Failed to get \"bd-address\" nvmem cell (%d)\n", + err); + bacpy(&lldev->bdaddr, BDADDR_NONE); + } + } else { + bdaddr_t *bdaddr; + size_t len; + + bdaddr = nvmem_cell_read(bdaddr_cell, &len); + nvmem_cell_put(bdaddr_cell); + if (IS_ERR(bdaddr)) { + dev_err(&serdev->dev, "Failed to read nvmem bd-address\n"); + return PTR_ERR(bdaddr); + } + if (len != sizeof(bdaddr_t)) { + dev_err(&serdev->dev, "Invalid nvmem bd-address length\n"); + kfree(bdaddr); + return -EINVAL; + } + + /* As per the device tree bindings, the value from nvmem is + * expected to be MSB first, but in the kernel it is expected + * that bdaddr_t is LSB first. + */ + baswap(&lldev->bdaddr, bdaddr); + kfree(bdaddr); + } + return hci_uart_register_device(hu, &llp); } @@ -748,6 +842,7 @@ static void hci_ti_remove(struct serdev_device *serdev) } static const struct of_device_id hci_ti_of_match[] = { + { .compatible = "ti,cc2560" }, { .compatible = "ti,wl1271-st" }, { .compatible = "ti,wl1273-st" }, { .compatible = "ti,wl1281-st" }, diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index bbd7db7384e6..05ec530b8a3a 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -932,6 +932,9 @@ static int qca_setup(struct hci_uart *hu) if (!ret) { set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); qca_debugfs_init(hdev); + } else if (ret == -ENOENT) { + /* No patch/nvm-config found, run with original fw/config */ + ret = 0; } /* Setup bdaddr */ diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c index 71664b22ec9d..e0e6461b9200 100644 --- a/drivers/bluetooth/hci_serdev.c +++ b/drivers/bluetooth/hci_serdev.c @@ -303,6 +303,7 @@ int hci_uart_register_device(struct hci_uart *hu, hci_set_drvdata(hdev, hu); INIT_WORK(&hu->write_work, hci_uart_write_work); + percpu_init_rwsem(&hu->proto_lock); /* Only when vendor specific setup callback is provided, consider * the manufacturer information valid. This avoids filling in the diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 58d4f4e1ad6a..ca38229b045a 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -22,6 +22,8 @@ #include "cpufreq_governor.h" +#define CPUFREQ_DBS_MIN_SAMPLING_INTERVAL (2 * TICK_NSEC / NSEC_PER_USEC) + static DEFINE_PER_CPU(struct cpu_dbs_info, cpu_dbs); static DEFINE_MUTEX(gov_dbs_data_mutex); @@ -47,11 +49,15 @@ ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf, { struct dbs_data *dbs_data = to_dbs_data(attr_set); struct policy_dbs_info *policy_dbs; + unsigned int sampling_interval; int ret; - ret = sscanf(buf, "%u", &dbs_data->sampling_rate); - if (ret != 1) + + ret = sscanf(buf, "%u", &sampling_interval); + if (ret != 1 || sampling_interval < CPUFREQ_DBS_MIN_SAMPLING_INTERVAL) return -EINVAL; + dbs_data->sampling_rate = sampling_interval; + /* * We are operating under dbs_data->mutex and so the list and its * entries can't be freed concurrently. @@ -430,7 +436,14 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) if (ret) goto free_policy_dbs_info; - dbs_data->sampling_rate = cpufreq_policy_transition_delay_us(policy); + /* + * The sampling interval should not be less than the transition latency + * of the CPU and it also cannot be too small for dbs_update() to work + * correctly. + */ + dbs_data->sampling_rate = max_t(unsigned int, + CPUFREQ_DBS_MIN_SAMPLING_INTERVAL, + cpufreq_policy_transition_delay_us(policy)); if (!have_governor_per_policy()) gov->gdbs_data = dbs_data; diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 628fe899cb48..d9b2c2de49c4 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -226,17 +226,18 @@ static void imx6q_opp_check_speed_grading(struct device *dev) val >>= OCOTP_CFG3_SPEED_SHIFT; val &= 0x3; - if ((val != OCOTP_CFG3_SPEED_1P2GHZ) && - of_machine_is_compatible("fsl,imx6q")) - if (dev_pm_opp_disable(dev, 1200000000)) - dev_warn(dev, "failed to disable 1.2GHz OPP\n"); if (val < OCOTP_CFG3_SPEED_996MHZ) if (dev_pm_opp_disable(dev, 996000000)) dev_warn(dev, "failed to disable 996MHz OPP\n"); - if (of_machine_is_compatible("fsl,imx6q")) { + + if (of_machine_is_compatible("fsl,imx6q") || + of_machine_is_compatible("fsl,imx6qp")) { if (val != OCOTP_CFG3_SPEED_852MHZ) if (dev_pm_opp_disable(dev, 852000000)) dev_warn(dev, "failed to disable 852MHz OPP\n"); + if (val != OCOTP_CFG3_SPEED_1P2GHZ) + if (dev_pm_opp_disable(dev, 1200000000)) + dev_warn(dev, "failed to disable 1.2GHz OPP\n"); } iounmap(base); put_node: diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index fbab271b3bf9..a861b5b4d443 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -708,7 +708,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, unsigned long flags) { struct at_dma_chan *atchan = to_at_dma_chan(chan); - struct data_chunk *first = xt->sgl; + struct data_chunk *first; struct at_desc *desc = NULL; size_t xfer_count; unsigned int dwidth; @@ -720,6 +720,8 @@ atc_prep_dma_interleaved(struct dma_chan *chan, if (unlikely(!xt || xt->numf != 1 || !xt->frame_size)) return NULL; + first = xt->sgl; + dev_info(chan2dev(chan), "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", __func__, &xt->src_start, &xt->dst_start, xt->numf, diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c index d50273fed715..afd5e10f8927 100644 --- a/drivers/dma/dma-jz4740.c +++ b/drivers/dma/dma-jz4740.c @@ -555,7 +555,7 @@ static int jz4740_dma_probe(struct platform_device *pdev) ret = dma_async_device_register(dd); if (ret) - return ret; + goto err_clk; irq = platform_get_irq(pdev, 0); ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); @@ -568,6 +568,8 @@ static int jz4740_dma_probe(struct platform_device *pdev) err_unregister: dma_async_device_unregister(dd); +err_clk: + clk_disable_unprepare(dmadev->clk); return ret; } diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 47edc7fbf91f..ec5f9d2bc820 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -155,6 +155,12 @@ MODULE_PARM_DESC(run, "Run the test (default: false)"); #define PATTERN_COUNT_MASK 0x1f #define PATTERN_MEMSET_IDX 0x01 +/* poor man's completion - we want to use wait_event_freezable() on it */ +struct dmatest_done { + bool done; + wait_queue_head_t *wait; +}; + struct dmatest_thread { struct list_head node; struct dmatest_info *info; @@ -165,6 +171,8 @@ struct dmatest_thread { u8 **dsts; u8 **udsts; enum dma_transaction_type type; + wait_queue_head_t done_wait; + struct dmatest_done test_done; bool done; }; @@ -342,18 +350,25 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start, return error_count; } -/* poor man's completion - we want to use wait_event_freezable() on it */ -struct dmatest_done { - bool done; - wait_queue_head_t *wait; -}; static void dmatest_callback(void *arg) { struct dmatest_done *done = arg; - - done->done = true; - wake_up_all(done->wait); + struct dmatest_thread *thread = + container_of(arg, struct dmatest_thread, done_wait); + if (!thread->done) { + done->done = true; + wake_up_all(done->wait); + } else { + /* + * If thread->done, it means that this callback occurred + * after the parent thread has cleaned up. This can + * happen in the case that driver doesn't implement + * the terminate_all() functionality and a dma operation + * did not occur within the timeout period + */ + WARN(1, "dmatest: Kernel memory may be corrupted!!\n"); + } } static unsigned int min_odd(unsigned int x, unsigned int y) @@ -424,9 +439,8 @@ static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len) */ static int dmatest_func(void *data) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait); struct dmatest_thread *thread = data; - struct dmatest_done done = { .wait = &done_wait }; + struct dmatest_done *done = &thread->test_done; struct dmatest_info *info; struct dmatest_params *params; struct dma_chan *chan; @@ -673,9 +687,9 @@ static int dmatest_func(void *data) continue; } - done.done = false; + done->done = false; tx->callback = dmatest_callback; - tx->callback_param = &done; + tx->callback_param = done; cookie = tx->tx_submit(tx); if (dma_submit_error(cookie)) { @@ -688,21 +702,12 @@ static int dmatest_func(void *data) } dma_async_issue_pending(chan); - wait_event_freezable_timeout(done_wait, done.done, + wait_event_freezable_timeout(thread->done_wait, done->done, msecs_to_jiffies(params->timeout)); status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); - if (!done.done) { - /* - * We're leaving the timed out dma operation with - * dangling pointer to done_wait. To make this - * correct, we'll need to allocate wait_done for - * each test iteration and perform "who's gonna - * free it this time?" dancing. For now, just - * leave it dangling. - */ - WARN(1, "dmatest: Kernel stack may be corrupted!!\n"); + if (!done->done) { dmaengine_unmap_put(um); result("test timed out", total_tests, src_off, dst_off, len, 0); @@ -789,7 +794,7 @@ err_thread_type: dmatest_KBs(runtime, total_len), ret); /* terminate all transfers on specified channels */ - if (ret) + if (ret || failed_tests) dmaengine_terminate_all(chan); thread->done = true; @@ -849,6 +854,8 @@ static int dmatest_add_threads(struct dmatest_info *info, thread->info = info; thread->chan = dtc->chan; thread->type = type; + thread->test_done.wait = &thread->done_wait; + init_waitqueue_head(&thread->done_wait); smp_wmb(); thread->task = kthread_create(dmatest_func, thread, "%s-%s%u", dma_chan_name(chan), op, i); diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 6775f2c74e25..c7568869284e 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -863,11 +863,11 @@ static void fsl_edma_irq_exit( } } -static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma) +static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks) { int i; - for (i = 0; i < DMAMUX_NR; i++) + for (i = 0; i < nr_clocks; i++) clk_disable_unprepare(fsl_edma->muxclk[i]); } @@ -904,25 +904,25 @@ static int fsl_edma_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(fsl_edma->muxbase[i])) + if (IS_ERR(fsl_edma->muxbase[i])) { + /* on error: disable all previously enabled clks */ + fsl_disable_clocks(fsl_edma, i); return PTR_ERR(fsl_edma->muxbase[i]); + } sprintf(clkname, "dmamux%d", i); fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname); if (IS_ERR(fsl_edma->muxclk[i])) { dev_err(&pdev->dev, "Missing DMAMUX block clock.\n"); + /* on error: disable all previously enabled clks */ + fsl_disable_clocks(fsl_edma, i); return PTR_ERR(fsl_edma->muxclk[i]); } ret = clk_prepare_enable(fsl_edma->muxclk[i]); - if (ret) { - /* disable only clks which were enabled on error */ - for (; i >= 0; i--) - clk_disable_unprepare(fsl_edma->muxclk[i]); - - dev_err(&pdev->dev, "DMAMUX clk block failed.\n"); - return ret; - } + if (ret) + /* on error: disable all previously enabled clks */ + fsl_disable_clocks(fsl_edma, i); } @@ -976,7 +976,7 @@ static int fsl_edma_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Can't register Freescale eDMA engine. (%d)\n", ret); - fsl_disable_clocks(fsl_edma); + fsl_disable_clocks(fsl_edma, DMAMUX_NR); return ret; } @@ -985,7 +985,7 @@ static int fsl_edma_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Can't register Freescale eDMA of_dma. (%d)\n", ret); dma_async_device_unregister(&fsl_edma->dma_dev); - fsl_disable_clocks(fsl_edma); + fsl_disable_clocks(fsl_edma, DMAMUX_NR); return ret; } @@ -1015,7 +1015,7 @@ static int fsl_edma_remove(struct platform_device *pdev) fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); of_dma_controller_free(np); dma_async_device_unregister(&fsl_edma->dma_dev); - fsl_disable_clocks(fsl_edma); + fsl_disable_clocks(fsl_edma, DMAMUX_NR); return 0; } diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index 2f31d3d0caa6..7792a9186f9c 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c @@ -390,7 +390,7 @@ static int ioat_dma_self_test(struct ioatdma_device *ioat_dma) if (memcmp(src, dest, IOAT_TEST_SIZE)) { dev_err(dev, "Self-test copy failed compare, disabling\n"); err = -ENODEV; - goto free_resources; + goto unmap_dma; } unmap_dma: diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index c9714072e224..59c82cdcf48d 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c @@ -377,6 +377,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, u8 *ptr; u8 *rx_buf; u8 sum; + u8 rx_byte; int ret = 0, final_ret; len = cros_ec_prepare_tx(ec_dev, ec_msg); @@ -421,25 +422,22 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, if (!ret) { /* Verify that EC can process command */ for (i = 0; i < len; i++) { - switch (rx_buf[i]) { - case EC_SPI_PAST_END: - case EC_SPI_RX_BAD_DATA: - case EC_SPI_NOT_READY: - ret = -EAGAIN; - ec_msg->result = EC_RES_IN_PROGRESS; - default: + rx_byte = rx_buf[i]; + if (rx_byte == EC_SPI_PAST_END || + rx_byte == EC_SPI_RX_BAD_DATA || + rx_byte == EC_SPI_NOT_READY) { + ret = -EREMOTEIO; break; } - if (ret) - break; } - if (!ret) - ret = cros_ec_spi_receive_packet(ec_dev, - ec_msg->insize + sizeof(*response)); - } else { - dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); } + if (!ret) + ret = cros_ec_spi_receive_packet(ec_dev, + ec_msg->insize + sizeof(*response)); + else + dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); + final_ret = terminate_request(ec_dev); spi_bus_unlock(ec_spi->spi->master); @@ -508,6 +506,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, int i, len; u8 *ptr; u8 *rx_buf; + u8 rx_byte; int sum; int ret = 0, final_ret; @@ -544,25 +543,22 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, if (!ret) { /* Verify that EC can process command */ for (i = 0; i < len; i++) { - switch (rx_buf[i]) { - case EC_SPI_PAST_END: - case EC_SPI_RX_BAD_DATA: - case EC_SPI_NOT_READY: - ret = -EAGAIN; - ec_msg->result = EC_RES_IN_PROGRESS; - default: + rx_byte = rx_buf[i]; + if (rx_byte == EC_SPI_PAST_END || + rx_byte == EC_SPI_RX_BAD_DATA || + rx_byte == EC_SPI_NOT_READY) { + ret = -EREMOTEIO; break; } - if (ret) - break; } - if (!ret) - ret = cros_ec_spi_receive_response(ec_dev, - ec_msg->insize + EC_MSG_TX_PROTO_BYTES); - } else { - dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); } + if (!ret) + ret = cros_ec_spi_receive_response(ec_dev, + ec_msg->insize + EC_MSG_TX_PROTO_BYTES); + else + dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); + final_ret = terminate_request(ec_dev); spi_bus_unlock(ec_spi->spi->master); @@ -667,6 +663,7 @@ static int cros_ec_spi_probe(struct spi_device *spi) sizeof(struct ec_response_get_protocol_info); ec_dev->dout_size = sizeof(struct ec_host_request); + ec_spi->last_transfer_ns = ktime_get_ns(); err = cros_ec_register(ec_dev); if (err) { diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index da16bf45fab4..dc94ffc6321a 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c @@ -159,13 +159,18 @@ unsigned int twl4030_audio_get_mclk(void) EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata, - struct device_node *node) + struct device_node *parent) { + struct device_node *node; + if (pdata && pdata->codec) return true; - if (of_find_node_by_name(node, "codec")) + node = of_get_child_by_name(parent, "codec"); + if (node) { + of_node_put(node); return true; + } return false; } diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index d66502d36ba0..dd19f17a1b63 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c @@ -97,12 +97,16 @@ static struct reg_sequence twl6040_patch[] = { }; -static bool twl6040_has_vibra(struct device_node *node) +static bool twl6040_has_vibra(struct device_node *parent) { -#ifdef CONFIG_OF - if (of_find_node_by_name(node, "vibra")) + struct device_node *node; + + node = of_get_child_by_name(parent, "vibra"); + if (node) { + of_node_put(node); return true; -#endif + } + return false; } diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index eda38cbe8530..41f2a9f6851d 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -32,7 +32,7 @@ #include <linux/pci.h> #include <linux/mutex.h> #include <linux/miscdevice.h> -#include <linux/pti.h> +#include <linux/intel-pti.h> #include <linux/slab.h> #include <linux/uaccess.h> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index f80e911b8843..73b605577447 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -1114,7 +1114,7 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs, if (!ops->oobbuf) ops->ooblen = 0; - if (offs < 0 || offs + ops->len >= mtd->size) + if (offs < 0 || offs + ops->len > mtd->size) return -EINVAL; if (ops->ooblen) { diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index e0eb51d8c012..dd56a671ea42 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1763,7 +1763,7 @@ try_dmaread: err = brcmstb_nand_verify_erased_page(mtd, chip, buf, addr); /* erased page bitflips corrected */ - if (err > 0) + if (err >= 0) return err; } diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 484f7fbc3f7d..a8bde6665c24 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -253,9 +253,9 @@ static int gpio_nand_probe(struct platform_device *pdev) goto out_ce; } - gpiomtd->nwp = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); - if (IS_ERR(gpiomtd->nwp)) { - ret = PTR_ERR(gpiomtd->nwp); + gpiomtd->ale = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); + if (IS_ERR(gpiomtd->ale)) { + ret = PTR_ERR(gpiomtd->ale); goto out_ce; } diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 50f8d4a1b983..d4d824ef64e9 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1067,9 +1067,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, return ret; } - /* handle the block mark swapping */ - block_mark_swapping(this, payload_virt, auxiliary_virt); - /* Loop over status bytes, accumulating ECC status. */ status = auxiliary_virt + nfc_geo->auxiliary_status_offset; @@ -1158,6 +1155,9 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, max_bitflips = max_t(unsigned int, max_bitflips, *status); } + /* handle the block mark swapping */ + block_mark_swapping(this, buf, auxiliary_virt); + if (oob_required) { /* * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 8a9b085c2a98..58c705f24f96 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -1431,13 +1431,9 @@ static int bond_option_ad_actor_system_set(struct bonding *bond, { u8 macaddr[ETH_ALEN]; u8 *mac; - int i; if (newval->string) { - i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &macaddr[0], &macaddr[1], &macaddr[2], - &macaddr[3], &macaddr[4], &macaddr[5]); - if (i != ETH_ALEN) + if (!mac_pton(newval->string, macaddr)) goto err; mac = macaddr; } else { diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c index f412aad58253..944901f03f8b 100644 --- a/drivers/net/dsa/lan9303-core.c +++ b/drivers/net/dsa/lan9303-core.c @@ -249,7 +249,6 @@ static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg) return -EIO; } -/* Wait a while until mask & reg == value. Otherwise return timeout. */ static int lan9303_read_wait(struct lan9303 *chip, int offset, u32 mask) { int i; @@ -541,20 +540,19 @@ lan9303_alr_cache_find_mac(struct lan9303 *chip, const u8 *mac_addr) return NULL; } -/* Wait a while until mask & reg == value. Otherwise return timeout. */ -static int lan9303_csr_reg_wait(struct lan9303 *chip, int regno, - int mask, char value) +static int lan9303_csr_reg_wait(struct lan9303 *chip, int regno, u32 mask) { int i; - for (i = 0; i < 0x1000; i++) { + for (i = 0; i < 25; i++) { u32 reg; lan9303_read_switch_reg(chip, regno, ®); - if ((reg & mask) == value) + if (!(reg & mask)) return 0; usleep_range(1000, 2000); } + return -ETIMEDOUT; } @@ -564,8 +562,7 @@ static int lan9303_alr_make_entry_raw(struct lan9303 *chip, u32 dat0, u32 dat1) lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_WR_DAT_1, dat1); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, LAN9303_ALR_CMD_MAKE_ENTRY); - lan9303_csr_reg_wait(chip, LAN9303_SWE_ALR_CMD_STS, ALR_STS_MAKE_PEND, - 0); + lan9303_csr_reg_wait(chip, LAN9303_SWE_ALR_CMD_STS, ALR_STS_MAKE_PEND); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); return 0; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index a74a8fbad53a..7a3ebfd236f5 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -2930,9 +2930,8 @@ void xgbe_dump_rx_desc(struct xgbe_prv_data *pdata, struct xgbe_ring *ring, void xgbe_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx) { struct ethhdr *eth = (struct ethhdr *)skb->data; - unsigned char *buf = skb->data; unsigned char buffer[128]; - unsigned int i, j; + unsigned int i; netdev_dbg(netdev, "\n************** SKB dump ****************\n"); @@ -2943,22 +2942,13 @@ void xgbe_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx) netdev_dbg(netdev, "Src MAC addr: %pM\n", eth->h_source); netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto)); - for (i = 0, j = 0; i < skb->len;) { - j += snprintf(buffer + j, sizeof(buffer) - j, "%02hhx", - buf[i++]); - - if ((i % 32) == 0) { - netdev_dbg(netdev, " %#06x: %s\n", i - 32, buffer); - j = 0; - } else if ((i % 16) == 0) { - buffer[j++] = ' '; - buffer[j++] = ' '; - } else if ((i % 4) == 0) { - buffer[j++] = ' '; - } + for (i = 0; i < skb->len; i += 32) { + unsigned int len = min(skb->len - i, 32U); + + hex_dump_to_buffer(&skb->data[i], len, 32, 1, + buffer, sizeof(buffer), false); + netdev_dbg(netdev, " %#06x: %s\n", i, buffer); } - if (i % 32) - netdev_dbg(netdev, " %#06x: %s\n", i - (i % 32), buffer); netdev_dbg(netdev, "\n************** SKB dump ****************\n"); } diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h index 3c63b16d485f..d9efbc8d783b 100644 --- a/drivers/net/ethernet/arc/emac.h +++ b/drivers/net/ethernet/arc/emac.h @@ -159,6 +159,8 @@ struct arc_emac_priv { unsigned int link; unsigned int duplex; unsigned int speed; + + unsigned int rx_missed_errors; }; /** diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index 3241af1ce718..bd277b0dc615 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c @@ -26,6 +26,8 @@ #include "emac.h" +static void arc_emac_restart(struct net_device *ndev); + /** * arc_emac_tx_avail - Return the number of available slots in the tx ring. * @priv: Pointer to ARC EMAC private data structure. @@ -210,39 +212,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget) continue; } - pktlen = info & LEN_MASK; - stats->rx_packets++; - stats->rx_bytes += pktlen; - skb = rx_buff->skb; - skb_put(skb, pktlen); - skb->dev = ndev; - skb->protocol = eth_type_trans(skb, ndev); - - dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), - dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); - - /* Prepare the BD for next cycle */ - rx_buff->skb = netdev_alloc_skb_ip_align(ndev, - EMAC_BUFFER_SIZE); - if (unlikely(!rx_buff->skb)) { + /* Prepare the BD for next cycle. netif_receive_skb() + * only if new skb was allocated and mapped to avoid holes + * in the RX fifo. + */ + skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE); + if (unlikely(!skb)) { + if (net_ratelimit()) + netdev_err(ndev, "cannot allocate skb\n"); + /* Return ownership to EMAC */ + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); stats->rx_errors++; - /* Because receive_skb is below, increment rx_dropped */ stats->rx_dropped++; continue; } - /* receive_skb only if new skb was allocated to avoid holes */ - netif_receive_skb(skb); - - addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data, + addr = dma_map_single(&ndev->dev, (void *)skb->data, EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); if (dma_mapping_error(&ndev->dev, addr)) { if (net_ratelimit()) - netdev_err(ndev, "cannot dma map\n"); - dev_kfree_skb(rx_buff->skb); + netdev_err(ndev, "cannot map dma buffer\n"); + dev_kfree_skb(skb); + /* Return ownership to EMAC */ + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); stats->rx_errors++; + stats->rx_dropped++; continue; } + + /* unmap previosly mapped skb */ + dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); + + pktlen = info & LEN_MASK; + stats->rx_packets++; + stats->rx_bytes += pktlen; + skb_put(rx_buff->skb, pktlen); + rx_buff->skb->dev = ndev; + rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev); + + netif_receive_skb(rx_buff->skb); + + rx_buff->skb = skb; dma_unmap_addr_set(rx_buff, addr, addr); dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE); @@ -259,6 +270,53 @@ static int arc_emac_rx(struct net_device *ndev, int budget) } /** + * arc_emac_rx_miss_handle - handle R_MISS register + * @ndev: Pointer to the net_device structure. + */ +static void arc_emac_rx_miss_handle(struct net_device *ndev) +{ + struct arc_emac_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + unsigned int miss; + + miss = arc_reg_get(priv, R_MISS); + if (miss) { + stats->rx_errors += miss; + stats->rx_missed_errors += miss; + priv->rx_missed_errors += miss; + } +} + +/** + * arc_emac_rx_stall_check - check RX stall + * @ndev: Pointer to the net_device structure. + * @budget: How many BDs requested to process on 1 call. + * @work_done: How many BDs processed + * + * Under certain conditions EMAC stop reception of incoming packets and + * continuously increment R_MISS register instead of saving data into + * provided buffer. This function detect that condition and restart + * EMAC. + */ +static void arc_emac_rx_stall_check(struct net_device *ndev, + int budget, unsigned int work_done) +{ + struct arc_emac_priv *priv = netdev_priv(ndev); + struct arc_emac_bd *rxbd; + + if (work_done) + priv->rx_missed_errors = 0; + + if (priv->rx_missed_errors && budget) { + rxbd = &priv->rxbd[priv->last_rx_bd]; + if (le32_to_cpu(rxbd->info) & FOR_EMAC) { + arc_emac_restart(ndev); + priv->rx_missed_errors = 0; + } + } +} + +/** * arc_emac_poll - NAPI poll handler. * @napi: Pointer to napi_struct structure. * @budget: How many BDs to process on 1 call. @@ -272,6 +330,7 @@ static int arc_emac_poll(struct napi_struct *napi, int budget) unsigned int work_done; arc_emac_tx_clean(ndev); + arc_emac_rx_miss_handle(ndev); work_done = arc_emac_rx(ndev, budget); if (work_done < budget) { @@ -279,6 +338,8 @@ static int arc_emac_poll(struct napi_struct *napi, int budget) arc_reg_or(priv, R_ENABLE, RXINT_MASK | TXINT_MASK); } + arc_emac_rx_stall_check(ndev, budget, work_done); + return work_done; } @@ -320,6 +381,8 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance) if (status & MSER_MASK) { stats->rx_missed_errors += 0x100; stats->rx_errors += 0x100; + priv->rx_missed_errors += 0x100; + napi_schedule(&priv->napi); } if (status & RXCR_MASK) { @@ -732,6 +795,63 @@ static int arc_emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } +/** + * arc_emac_restart - Restart EMAC + * @ndev: Pointer to net_device structure. + * + * This function do hardware reset of EMAC in order to restore + * network packets reception. + */ +static void arc_emac_restart(struct net_device *ndev) +{ + struct arc_emac_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + int i; + + if (net_ratelimit()) + netdev_warn(ndev, "restarting stalled EMAC\n"); + + netif_stop_queue(ndev); + + /* Disable interrupts */ + arc_reg_clr(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK); + + /* Disable EMAC */ + arc_reg_clr(priv, R_CTRL, EN_MASK); + + /* Return the sk_buff to system */ + arc_free_tx_queue(ndev); + + /* Clean Tx BD's */ + priv->txbd_curr = 0; + priv->txbd_dirty = 0; + memset(priv->txbd, 0, TX_RING_SZ); + + for (i = 0; i < RX_BD_NUM; i++) { + struct arc_emac_bd *rxbd = &priv->rxbd[i]; + unsigned int info = le32_to_cpu(rxbd->info); + + if (!(info & FOR_EMAC)) { + stats->rx_errors++; + stats->rx_dropped++; + } + /* Return ownership to EMAC */ + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); + } + priv->last_rx_bd = 0; + + /* Make sure info is visible to EMAC before enable */ + wmb(); + + /* Enable interrupts */ + arc_reg_set(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK); + + /* Enable EMAC */ + arc_reg_or(priv, R_CTRL, EN_MASK); + + netif_start_queue(ndev); +} + static const struct net_device_ops arc_emac_netdev_ops = { .ndo_open = arc_emac_open, .ndo_stop = arc_emac_stop, diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index d9346e2ac720..1fbbbabe7588 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1716,7 +1716,6 @@ static int bcm_enet_probe(struct platform_device *pdev) struct bcm63xx_enet_platform_data *pd; struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx; struct mii_bus *bus; - const char *clk_name; int i, ret; if (!bcm_enet_shared_base[0]) @@ -1751,20 +1750,8 @@ static int bcm_enet_probe(struct platform_device *pdev) dev->irq = priv->irq = res_irq->start; priv->irq_rx = res_irq_rx->start; priv->irq_tx = res_irq_tx->start; - priv->mac_id = pdev->id; - /* get rx & tx dma channel id for this mac */ - if (priv->mac_id == 0) { - priv->rx_chan = 0; - priv->tx_chan = 1; - clk_name = "enet0"; - } else { - priv->rx_chan = 2; - priv->tx_chan = 3; - clk_name = "enet1"; - } - - priv->mac_clk = devm_clk_get(&pdev->dev, clk_name); + priv->mac_clk = devm_clk_get(&pdev->dev, "enet"); if (IS_ERR(priv->mac_clk)) { ret = PTR_ERR(priv->mac_clk); goto out; @@ -1795,9 +1782,11 @@ static int bcm_enet_probe(struct platform_device *pdev) priv->dma_chan_width = pd->dma_chan_width; priv->dma_has_sram = pd->dma_has_sram; priv->dma_desc_shift = pd->dma_desc_shift; + priv->rx_chan = pd->rx_chan; + priv->tx_chan = pd->tx_chan; } - if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) { + if (priv->has_phy && !priv->use_external_mii) { /* using internal PHY, enable clock */ priv->phy_clk = devm_clk_get(&pdev->dev, "ephy"); if (IS_ERR(priv->phy_clk)) { @@ -1828,7 +1817,7 @@ static int bcm_enet_probe(struct platform_device *pdev) bus->priv = priv; bus->read = bcm_enet_mdio_read_phylib; bus->write = bcm_enet_mdio_write_phylib; - sprintf(bus->id, "%s-%d", pdev->name, priv->mac_id); + sprintf(bus->id, "%s-%d", pdev->name, pdev->id); /* only probe bus where we think the PHY is, because * the mdio read operation return 0 instead of 0xffff diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.h b/drivers/net/ethernet/broadcom/bcm63xx_enet.h index 5a66728d4776..1d3c917eb830 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h @@ -193,9 +193,6 @@ struct bcm_enet_mib_counters { struct bcm_enet_priv { - /* mac id (from platform device id) */ - int mac_id; - /* base remapped address of device */ void __iomem *base; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4c739d5355d2..01b7f2fc249c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2482,8 +2482,7 @@ static void bnx2x_bz_fp(struct bnx2x *bp, int index) */ if (bp->dev->features & NETIF_F_LRO) fp->mode = TPA_MODE_LRO; - else if (bp->dev->features & NETIF_F_GRO && - bnx2x_mtu_allows_gro(bp->dev->mtu)) + else if (bp->dev->features & NETIF_F_GRO_HW) fp->mode = TPA_MODE_GRO; else fp->mode = TPA_MODE_DISABLED; @@ -4874,6 +4873,9 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) */ dev->mtu = new_mtu; + if (!bnx2x_mtu_allows_gro(new_mtu)) + dev->features &= ~NETIF_F_GRO_HW; + if (IS_PF(bp) && SHMEM2_HAS(bp, curr_cfg)) SHMEM2_WR(bp, curr_cfg, CURR_CFG_MET_OS); @@ -4903,10 +4905,13 @@ netdev_features_t bnx2x_fix_features(struct net_device *dev, } /* TPA requires Rx CSUM offloading */ - if (!(features & NETIF_F_RXCSUM)) { + if (!(features & NETIF_F_RXCSUM)) + features &= ~NETIF_F_LRO; + + if (!(features & NETIF_F_GRO) || !bnx2x_mtu_allows_gro(dev->mtu)) + features &= ~NETIF_F_GRO_HW; + if (features & NETIF_F_GRO_HW) features &= ~NETIF_F_LRO; - features &= ~NETIF_F_GRO; - } return features; } @@ -4933,13 +4938,8 @@ int bnx2x_set_features(struct net_device *dev, netdev_features_t features) } } - /* if GRO is changed while LRO is enabled, don't force a reload */ - if ((changes & NETIF_F_GRO) && (features & NETIF_F_LRO)) - changes &= ~NETIF_F_GRO; - - /* if GRO is changed while HW TPA is off, don't force a reload */ - if ((changes & NETIF_F_GRO) && bp->disable_tpa) - changes &= ~NETIF_F_GRO; + /* Don't care about GRO changes */ + changes &= ~NETIF_F_GRO; if (changes) bnx2x_reload = true; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 91e2a7560b48..4d0654813de1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12400,8 +12400,8 @@ static int bnx2x_init_bp(struct bnx2x *bp) /* Set TPA flags */ if (bp->disable_tpa) { - bp->dev->hw_features &= ~NETIF_F_LRO; - bp->dev->features &= ~NETIF_F_LRO; + bp->dev->hw_features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); + bp->dev->features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); } if (CHIP_IS_E1(bp)) @@ -13273,7 +13273,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | - NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | + NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | NETIF_F_GRO_HW | NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX; if (!chip_is_e1x) { dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | @@ -13309,6 +13309,8 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX; dev->features |= NETIF_F_HIGHDMA; + if (dev->features & NETIF_F_LRO) + dev->features &= ~NETIF_F_GRO_HW; /* Add Loopback capability to the device */ dev->hw_features |= NETIF_F_LOOPBACK; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1d865ae201db..9efbdc6f1fcb 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2755,7 +2755,7 @@ void bnxt_set_tpa_flags(struct bnxt *bp) return; if (bp->dev->features & NETIF_F_LRO) bp->flags |= BNXT_FLAG_LRO; - if (bp->dev->features & NETIF_F_GRO) + else if (bp->dev->features & NETIF_F_GRO_HW) bp->flags |= BNXT_FLAG_GRO; } @@ -2843,10 +2843,10 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU); bp->flags &= ~BNXT_FLAG_AGG_RINGS; bp->flags |= BNXT_FLAG_NO_AGG_RINGS | BNXT_FLAG_RX_PAGE_MODE; - bp->dev->hw_features &= ~NETIF_F_LRO; - bp->dev->features &= ~NETIF_F_LRO; bp->rx_dir = DMA_BIDIRECTIONAL; bp->rx_skb_func = bnxt_rx_page_skb; + /* Disable LRO or GRO_HW */ + netdev_update_features(bp->dev); } else { bp->dev->max_mtu = bp->max_mtu; bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE; @@ -6788,6 +6788,15 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev, if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) features &= ~NETIF_F_NTUPLE; + if (bp->flags & BNXT_FLAG_NO_AGG_RINGS) + features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); + + if (!(features & NETIF_F_GRO)) + features &= ~NETIF_F_GRO_HW; + + if (features & NETIF_F_GRO_HW) + features &= ~NETIF_F_LRO; + /* Both CTAG and STAG VLAN accelaration on the RX side have to be * turned on or off together. */ @@ -6821,9 +6830,9 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features) bool update_tpa = false; flags &= ~BNXT_FLAG_ALL_CONFIG_FEATS; - if ((features & NETIF_F_GRO) && !BNXT_CHIP_TYPE_NITRO_A0(bp)) + if (features & NETIF_F_GRO_HW) flags |= BNXT_FLAG_GRO; - if (features & NETIF_F_LRO) + else if (features & NETIF_F_LRO) flags |= BNXT_FLAG_LRO; if (bp->flags & BNXT_FLAG_NO_AGG_RINGS) @@ -7924,8 +7933,8 @@ static int bnxt_get_dflt_rings(struct bnxt *bp, int *max_rx, int *max_tx, if (rc) return rc; bp->flags |= BNXT_FLAG_NO_AGG_RINGS; - bp->dev->hw_features &= ~NETIF_F_LRO; - bp->dev->features &= ~NETIF_F_LRO; + bp->dev->hw_features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); + bp->dev->features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); bnxt_set_ring_params(bp); } @@ -8108,7 +8117,11 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->vlan_features = dev->hw_features | NETIF_F_HIGHDMA; dev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_RX | NETIF_F_HW_VLAN_STAG_TX; + if (!BNXT_CHIP_TYPE_NITRO_A0(bp)) + dev->hw_features |= NETIF_F_GRO_HW; dev->features |= dev->hw_features | NETIF_F_HIGHDMA; + if (dev->features & NETIF_F_GRO_HW) + dev->features &= ~NETIF_F_LRO; dev->priv_flags |= IFF_UNICAST_FLT; #ifdef CONFIG_BNXT_SRIOV diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index de51c2177d03..d09c5a9c53b5 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -14225,7 +14225,9 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) /* Reset PHY, otherwise the read DMA engine will be in a mode that * breaks all requests to 256 bytes. */ - if (tg3_asic_rev(tp) == ASIC_REV_57766) + if (tg3_asic_rev(tp) == ASIC_REV_57766 || + tg3_asic_rev(tp) == ASIC_REV_5717 || + tg3_asic_rev(tp) == ASIC_REV_5719) reset_phy = true; err = tg3_restart_hw(tp, reset_phy); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c index d73fb6a85f8e..336670d00a52 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c @@ -1004,9 +1004,10 @@ int cudbg_collect_rss(struct cudbg_init *pdbg_init, { struct adapter *padap = pdbg_init->adap; struct cudbg_buffer temp_buff = { 0 }; - int rc; + int rc, nentries; - rc = cudbg_get_buff(dbg_buff, RSS_NENTRIES * sizeof(u16), &temp_buff); + nentries = t4_chip_rss_size(padap); + rc = cudbg_get_buff(dbg_buff, nentries * sizeof(u16), &temp_buff); if (rc) return rc; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index b1df2aa6be94..69d0b64e6986 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1528,6 +1528,7 @@ int t4_init_portinfo(struct port_info *pi, int mbox, int port, int pf, int vf, u8 mac[]); int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); void t4_fatal_err(struct adapter *adapter); +unsigned int t4_chip_rss_size(struct adapter *adapter); int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, int start, int n, const u16 *rspq, unsigned int nrspq); int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c index 41c8736314f8..581d628f01cc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c @@ -179,7 +179,7 @@ static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity) len = cudbg_mbytes_to_bytes(len); break; case CUDBG_RSS: - len = RSS_NENTRIES * sizeof(u16); + len = t4_chip_rss_size(adap) * sizeof(u16); break; case CUDBG_RSS_VF_CONF: len = adap->params.arch.vfcount * diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 4956e429ae1d..d3ced0438474 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -2021,11 +2021,12 @@ static int rss_show(struct seq_file *seq, void *v, int idx) static int rss_open(struct inode *inode, struct file *file) { - int ret; - struct seq_tab *p; struct adapter *adap = inode->i_private; + int ret, nentries; + struct seq_tab *p; - p = seq_open_tab(file, RSS_NENTRIES / 8, 8 * sizeof(u16), 0, rss_show); + nentries = t4_chip_rss_size(adap); + p = seq_open_tab(file, nentries / 8, 8 * sizeof(u16), 0, rss_show); if (!p) return -ENOMEM; @@ -2668,10 +2669,14 @@ static const struct file_operations mem_debugfs_fops = { static int tid_info_show(struct seq_file *seq, void *v) { + unsigned int tid_start = 0; struct adapter *adap = seq->private; const struct tid_info *t = &adap->tids; enum chip_type chip = CHELSIO_CHIP_VERSION(adap->params.chip); + if (chip > CHELSIO_T5) + tid_start = t4_read_reg(adap, LE_DB_ACTIVE_TABLE_START_INDEX_A); + if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) { unsigned int sb; seq_printf(seq, "Connections in use: %u\n", @@ -2683,8 +2688,8 @@ static int tid_info_show(struct seq_file *seq, void *v) sb = t4_read_reg(adap, LE_DB_SRVR_START_INDEX_A); if (sb) { - seq_printf(seq, "TID range: 0..%u/%u..%u", sb - 1, - adap->tids.hash_base, + seq_printf(seq, "TID range: %u..%u/%u..%u", tid_start, + sb - 1, adap->tids.hash_base, t->ntids - 1); seq_printf(seq, ", in use: %u/%u\n", atomic_read(&t->tids_in_use), @@ -2709,7 +2714,8 @@ static int tid_info_show(struct seq_file *seq, void *v) seq_printf(seq, "Connections in use: %u\n", atomic_read(&t->conns_in_use)); - seq_printf(seq, "TID range: 0..%u", t->ntids - 1); + seq_printf(seq, "TID range: %u..%u", tid_start, + tid_start + t->ntids - 1); seq_printf(seq, ", in use: %u\n", atomic_read(&t->tids_in_use)); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index d18e708c21c5..44930ca06c4b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -4927,6 +4927,14 @@ void t4_intr_disable(struct adapter *adapter) t4_set_reg_field(adapter, PL_INT_MAP0_A, 1 << pf, 0); } +unsigned int t4_chip_rss_size(struct adapter *adap) +{ + if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5) + return RSS_NENTRIES; + else + return T6_RSS_NENTRIES; +} + /** * t4_config_rss_range - configure a portion of the RSS mapping table * @adapter: the adapter @@ -5065,10 +5073,11 @@ static int rd_rss_row(struct adapter *adap, int row, u32 *val) */ int t4_read_rss(struct adapter *adapter, u16 *map) { + int i, ret, nentries; u32 val; - int i, ret; - for (i = 0; i < RSS_NENTRIES / 2; ++i) { + nentries = t4_chip_rss_size(adapter); + for (i = 0; i < nentries / 2; ++i) { ret = rd_rss_row(adapter, i, &val); if (ret) return ret; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h index 872a91b1930c..361d5032c288 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h @@ -38,21 +38,22 @@ #include <linux/types.h> enum { - NCHAN = 4, /* # of HW channels */ - MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */ - EEPROMSIZE = 17408, /* Serial EEPROM physical size */ - EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */ - EEPROMPFSIZE = 1024, /* EEPROM writable area size for PFn, n>0 */ - RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */ - TCB_SIZE = 128, /* TCB size */ - NMTUS = 16, /* size of MTU table */ - NCCTRL_WIN = 32, /* # of congestion control windows */ - NTX_SCHED = 8, /* # of HW Tx scheduling queues */ - PM_NSTATS = 5, /* # of PM stats */ - T6_PM_NSTATS = 7, /* # of PM stats in T6 */ - MBOX_LEN = 64, /* mailbox size in bytes */ - TRACE_LEN = 112, /* length of trace data and mask */ - FILTER_OPT_LEN = 36, /* filter tuple width for optional components */ + NCHAN = 4, /* # of HW channels */ + MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */ + EEPROMSIZE = 17408,/* Serial EEPROM physical size */ + EEPROMVSIZE = 32768,/* Serial EEPROM virtual address space size */ + EEPROMPFSIZE = 1024, /* EEPROM writable area size for PFn, n>0 */ + RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */ + T6_RSS_NENTRIES = 4096, /* # of entries in RSS mapping table */ + TCB_SIZE = 128, /* TCB size */ + NMTUS = 16, /* size of MTU table */ + NCCTRL_WIN = 32, /* # of congestion control windows */ + NTX_SCHED = 8, /* # of HW Tx scheduling queues */ + PM_NSTATS = 5, /* # of PM stats */ + T6_PM_NSTATS = 7, /* # of PM stats in T6 */ + MBOX_LEN = 64, /* mailbox size in bytes */ + TRACE_LEN = 112, /* length of trace data and mask */ + FILTER_OPT_LEN = 36, /* filter tuple width for optional components */ }; enum { diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h index 60cf9e02de5d..51b18035d691 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -183,6 +183,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x50a9), /* Custom T580-KR */ CH_PCI_ID_TABLE_FENTRY(0x50aa), /* Custom T580-CR */ CH_PCI_ID_TABLE_FENTRY(0x50ab), /* Custom T520-CR */ + CH_PCI_ID_TABLE_FENTRY(0x50ac), /* Custom T540-BT */ /* T6 adapters: */ @@ -206,6 +207,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x6084), /* Custom T64100-CR QSFP28 */ CH_PCI_ID_TABLE_FENTRY(0x6085), /* Custom T6240-SO */ CH_PCI_ID_TABLE_FENTRY(0x6086), /* Custom T6225-SO-CR */ + CH_PCI_ID_TABLE_FENTRY(0x6087), /* Custom T6225-CR */ CH_PCI_DEVICE_ID_TABLE_DEFINE_END; #endif /* __T4_PCI_ID_TBL_H__ */ diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index 6a9527004cb1..9b218f0e5a4c 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h @@ -43,6 +43,8 @@ #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) +#define ENIC_WQ_NAPI_BUDGET 256 + #define ENIC_AIC_LARGE_PKT_DIFF 3 struct enic_msix_entry { diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index d98676e43e03..f202ba72a811 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1500,7 +1500,7 @@ static int enic_poll(struct napi_struct *napi, int budget) unsigned int cq_wq = enic_cq_wq(enic, 0); unsigned int intr = enic_legacy_io_intr(); unsigned int rq_work_to_do = budget; - unsigned int wq_work_to_do = -1; /* no limit */ + unsigned int wq_work_to_do = ENIC_WQ_NAPI_BUDGET; unsigned int work_done, rq_work_done = 0, wq_work_done; int err; @@ -1598,7 +1598,7 @@ static int enic_poll_msix_wq(struct napi_struct *napi, int budget) struct vnic_wq *wq = &enic->wq[wq_index]; unsigned int cq; unsigned int intr; - unsigned int wq_work_to_do = -1; /* clean all desc possible */ + unsigned int wq_work_to_do = ENIC_WQ_NAPI_BUDGET; unsigned int wq_work_done; unsigned int wq_irq; diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index a9e2b32834c5..82e9a8034557 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -278,6 +278,8 @@ struct hnae3_ae_dev { * Set vlan filter config of Ports * set_vf_vlan_filter() * Set vlan filter config of vf + * enable_hw_strip_rxvtag() + * Enable/disable hardware strip vlan tag of packets received */ struct hnae3_ae_ops { int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev); @@ -384,8 +386,16 @@ struct hnae3_ae_ops { u16 vlan_id, bool is_kill); int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid, u16 vlan, u8 qos, __be16 proto); + int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable); void (*reset_event)(struct hnae3_handle *handle, enum hnae3_reset_type reset); + void (*get_channels)(struct hnae3_handle *handle, + struct ethtool_channels *ch); + void (*get_tqps_and_rss_info)(struct hnae3_handle *h, + u16 *free_tqps, u16 *max_rss_size); + int (*set_channels)(struct hnae3_handle *handle, u32 new_tqps_num); + void (*get_flowctrl_adv)(struct hnae3_handle *handle, + u32 *flowctrl_adv); }; struct hnae3_dcb_ops { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index c2c13238db52..320ae8892a68 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -723,6 +723,58 @@ static void hns3_set_txbd_baseinfo(u16 *bdtp_fe_sc_vld_ra_ri, int frag_end) hnae_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_SC_M, HNS3_TXD_SC_S, 0); } +static int hns3_fill_desc_vtags(struct sk_buff *skb, + struct hns3_enet_ring *tx_ring, + u32 *inner_vlan_flag, + u32 *out_vlan_flag, + u16 *inner_vtag, + u16 *out_vtag) +{ +#define HNS3_TX_VLAN_PRIO_SHIFT 13 + + if (skb->protocol == htons(ETH_P_8021Q) && + !(tx_ring->tqp->handle->kinfo.netdev->features & + NETIF_F_HW_VLAN_CTAG_TX)) { + /* When HW VLAN acceleration is turned off, and the stack + * sets the protocol to 802.1q, the driver just need to + * set the protocol to the encapsulated ethertype. + */ + skb->protocol = vlan_get_protocol(skb); + return 0; + } + + if (skb_vlan_tag_present(skb)) { + u16 vlan_tag; + + vlan_tag = skb_vlan_tag_get(skb); + vlan_tag |= (skb->priority & 0x7) << HNS3_TX_VLAN_PRIO_SHIFT; + + /* Based on hw strategy, use out_vtag in two layer tag case, + * and use inner_vtag in one tag case. + */ + if (skb->protocol == htons(ETH_P_8021Q)) { + hnae_set_bit(*out_vlan_flag, HNS3_TXD_OVLAN_B, 1); + *out_vtag = vlan_tag; + } else { + hnae_set_bit(*inner_vlan_flag, HNS3_TXD_VLAN_B, 1); + *inner_vtag = vlan_tag; + } + } else if (skb->protocol == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *vhdr; + int rc; + + rc = skb_cow_head(skb, 0); + if (rc < 0) + return rc; + vhdr = (struct vlan_ethhdr *)skb->data; + vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority & 0x7) + << HNS3_TX_VLAN_PRIO_SHIFT); + } + + skb->protocol = vlan_get_protocol(skb); + return 0; +} + static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, int size, dma_addr_t dma, int frag_end, enum hns_desc_type type) @@ -733,6 +785,8 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, u16 bdtp_fe_sc_vld_ra_ri = 0; u32 type_cs_vlan_tso = 0; struct sk_buff *skb; + u16 inner_vtag = 0; + u16 out_vtag = 0; u32 paylen = 0; u16 mss = 0; __be16 protocol; @@ -756,15 +810,16 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, skb = (struct sk_buff *)priv; paylen = skb->len; + ret = hns3_fill_desc_vtags(skb, ring, &type_cs_vlan_tso, + &ol_type_vlan_len_msec, + &inner_vtag, &out_vtag); + if (unlikely(ret)) + return ret; + if (skb->ip_summed == CHECKSUM_PARTIAL) { skb_reset_mac_len(skb); protocol = skb->protocol; - /* vlan packet*/ - if (protocol == htons(ETH_P_8021Q)) { - protocol = vlan_get_protocol(skb); - skb->protocol = protocol; - } ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto); if (ret) return ret; @@ -790,6 +845,8 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, cpu_to_le32(type_cs_vlan_tso); desc->tx.paylen = cpu_to_le32(paylen); desc->tx.mss = cpu_to_le16(mss); + desc->tx.vlan_tag = cpu_to_le16(inner_vtag); + desc->tx.outer_vlan_tag = cpu_to_le16(out_vtag); } /* move ring pointer to next.*/ @@ -1032,6 +1089,9 @@ static int hns3_nic_set_features(struct net_device *netdev, netdev_features_t features) { struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; + netdev_features_t changed; + int ret; if (features & (NETIF_F_TSO | NETIF_F_TSO6)) { priv->ops.fill_desc = hns3_fill_desc_tso; @@ -1041,6 +1101,17 @@ static int hns3_nic_set_features(struct net_device *netdev, priv->ops.maybe_stop_tx = hns3_nic_maybe_stop_tx; } + changed = netdev->features ^ features; + if (changed & NETIF_F_HW_VLAN_CTAG_RX) { + if (features & NETIF_F_HW_VLAN_CTAG_RX) + ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, true); + else + ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, false); + + if (ret) + return ret; + } + netdev->features = features; return 0; } @@ -1492,6 +1563,7 @@ static void hns3_set_default_feature(struct net_device *netdev) netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL | @@ -1506,6 +1578,7 @@ static void hns3_set_default_feature(struct net_device *netdev) netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL | @@ -2085,6 +2158,22 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring, prefetchw(skb->data); + /* Based on hw strategy, the tag offloaded will be stored at + * ot_vlan_tag in two layer tag case, and stored at vlan_tag + * in one layer tag case. + */ + if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { + u16 vlan_tag; + + vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag); + if (!(vlan_tag & VLAN_VID_MASK)) + vlan_tag = le16_to_cpu(desc->rx.vlan_tag); + if (vlan_tag & VLAN_VID_MASK) + __vlan_hwaccel_put_tag(skb, + htons(ETH_P_8021Q), + vlan_tag); + } + bnum = 1; if (length <= HNS3_RX_HEAD_SIZE) { memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long))); @@ -2651,6 +2740,19 @@ err: return ret; } +static void hns3_put_ring_config(struct hns3_nic_priv *priv) +{ + struct hnae3_handle *h = priv->ae_handle; + int i; + + for (i = 0; i < h->kinfo.num_tqps; i++) { + devm_kfree(priv->dev, priv->ring_data[i].ring); + devm_kfree(priv->dev, + priv->ring_data[i + h->kinfo.num_tqps].ring); + } + devm_kfree(priv->dev, priv->ring_data); +} + static int hns3_alloc_ring_memory(struct hns3_enet_ring *ring) { int ret; @@ -2787,8 +2889,12 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv) h->ae_algo->ops->reset_queue(h, i); hns3_fini_ring(priv->ring_data[i].ring); + devm_kfree(priv->dev, priv->ring_data[i].ring); hns3_fini_ring(priv->ring_data[i + h->kinfo.num_tqps].ring); + devm_kfree(priv->dev, + priv->ring_data[i + h->kinfo.num_tqps].ring); } + devm_kfree(priv->dev, priv->ring_data); return 0; } @@ -3162,6 +3268,115 @@ static int hns3_reset_notify(struct hnae3_handle *handle, return ret; } +static u16 hns3_get_max_available_channels(struct net_device *netdev) +{ + struct hnae3_handle *h = hns3_get_handle(netdev); + u16 free_tqps, max_rss_size, max_tqps; + + h->ae_algo->ops->get_tqps_and_rss_info(h, &free_tqps, &max_rss_size); + max_tqps = h->kinfo.num_tc * max_rss_size; + + return min_t(u16, max_tqps, (free_tqps + h->kinfo.num_tqps)); +} + +static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = hns3_get_handle(netdev); + int ret; + + ret = h->ae_algo->ops->set_channels(h, new_tqp_num); + if (ret) + return ret; + + ret = hns3_get_ring_config(priv); + if (ret) + return ret; + + ret = hns3_nic_init_vector_data(priv); + if (ret) + goto err_uninit_vector; + + ret = hns3_init_all_ring(priv); + if (ret) + goto err_put_ring; + + return 0; + +err_put_ring: + hns3_put_ring_config(priv); +err_uninit_vector: + hns3_nic_uninit_vector_data(priv); + return ret; +} + +static int hns3_adjust_tqps_num(u8 num_tc, u32 new_tqp_num) +{ + return (new_tqp_num / num_tc) * num_tc; +} + +int hns3_set_channels(struct net_device *netdev, + struct ethtool_channels *ch) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = hns3_get_handle(netdev); + struct hnae3_knic_private_info *kinfo = &h->kinfo; + bool if_running = netif_running(netdev); + u32 new_tqp_num = ch->combined_count; + u16 org_tqp_num; + int ret; + + if (ch->rx_count || ch->tx_count) + return -EINVAL; + + if (new_tqp_num > hns3_get_max_available_channels(netdev) || + new_tqp_num < kinfo->num_tc) { + dev_err(&netdev->dev, + "Change tqps fail, the tqp range is from %d to %d", + kinfo->num_tc, + hns3_get_max_available_channels(netdev)); + return -EINVAL; + } + + new_tqp_num = hns3_adjust_tqps_num(kinfo->num_tc, new_tqp_num); + if (kinfo->num_tqps == new_tqp_num) + return 0; + + if (if_running) + dev_close(netdev); + + hns3_clear_all_ring(h); + + ret = hns3_nic_uninit_vector_data(priv); + if (ret) { + dev_err(&netdev->dev, + "Unbind vector with tqp fail, nothing is changed"); + goto open_netdev; + } + + hns3_uninit_all_ring(priv); + + org_tqp_num = h->kinfo.num_tqps; + ret = hns3_modify_tqp_num(netdev, new_tqp_num); + if (ret) { + ret = hns3_modify_tqp_num(netdev, org_tqp_num); + if (ret) { + /* If revert to old tqp failed, fatal error occurred */ + dev_err(&netdev->dev, + "Revert to old tqp num fail, ret=%d", ret); + return ret; + } + dev_info(&netdev->dev, + "Change tqp num fail, Revert to old tqp num"); + } + +open_netdev: + if (if_running) + dev_open(netdev); + + return ret; +} + static const struct hnae3_client_ops client_ops = { .init_instance = hns3_client_init, .uninit_instance = hns3_client_uninit, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 8a9de759957b..a2a7ea3e9a3a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -595,6 +595,8 @@ static inline void hns3_write_reg(void __iomem *base, u32 reg, u32 value) (((struct hns3_nic_priv *)netdev_priv(ndev))->ae_handle) void hns3_ethtool_set_ops(struct net_device *netdev); +int hns3_set_channels(struct net_device *netdev, + struct ethtool_channels *ch); bool hns3_clean_tx_ring(struct hns3_enet_ring *ring, int budget); int hns3_init_all_ring(struct hns3_nic_priv *priv); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 65a69b439457..2ae4d39798c1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -559,10 +559,23 @@ static void hns3_get_pauseparam(struct net_device *netdev, ¶m->rx_pause, ¶m->tx_pause); } +static int hns3_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *param) +{ + struct hnae3_handle *h = hns3_get_handle(netdev); + + if (h->ae_algo->ops->set_pauseparam) + return h->ae_algo->ops->set_pauseparam(h, param->autoneg, + param->rx_pause, + param->tx_pause); + return -EOPNOTSUPP; +} + static int hns3_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct hnae3_handle *h = hns3_get_handle(netdev); + u32 flowctrl_adv = 0; u32 supported_caps; u32 advertised_caps; u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN; @@ -638,6 +651,8 @@ static int hns3_get_link_ksettings(struct net_device *netdev, if (!cmd->base.autoneg) advertised_caps &= ~HNS3_LM_AUTONEG_BIT; + advertised_caps &= ~HNS3_LM_PAUSE_BIT; + /* now, map driver link modes to ethtool link modes */ hns3_driv_to_eth_caps(supported_caps, cmd, false); hns3_driv_to_eth_caps(advertised_caps, cmd, true); @@ -650,6 +665,18 @@ static int hns3_get_link_ksettings(struct net_device *netdev, /* 4.mdio_support */ cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22; + /* 5.get flow control setttings */ + if (h->ae_algo->ops->get_flowctrl_adv) + h->ae_algo->ops->get_flowctrl_adv(h, &flowctrl_adv); + + if (flowctrl_adv & ADVERTISED_Pause) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + Pause); + + if (flowctrl_adv & ADVERTISED_Asym_Pause) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + Asym_Pause); + return 0; } @@ -730,7 +757,7 @@ static int hns3_get_rxnfc(struct net_device *netdev, switch (cmd->cmd) { case ETHTOOL_GRXRINGS: - cmd->data = h->kinfo.num_tc * h->kinfo.rss_size; + cmd->data = h->kinfo.rss_size; break; case ETHTOOL_GRXFH: return h->ae_algo->ops->get_rss_tuple(h, cmd); @@ -849,6 +876,15 @@ static int hns3_nway_reset(struct net_device *netdev) return genphy_restart_aneg(phy); } +void hns3_get_channels(struct net_device *netdev, + struct ethtool_channels *ch) +{ + struct hnae3_handle *h = hns3_get_handle(netdev); + + if (h->ae_algo->ops->get_channels) + h->ae_algo->ops->get_channels(h, ch); +} + static const struct ethtool_ops hns3vf_ethtool_ops = { .get_drvinfo = hns3_get_drvinfo, .get_ringparam = hns3_get_ringparam, @@ -871,6 +907,7 @@ static const struct ethtool_ops hns3_ethtool_ops = { .get_ringparam = hns3_get_ringparam, .set_ringparam = hns3_set_ringparam, .get_pauseparam = hns3_get_pauseparam, + .set_pauseparam = hns3_set_pauseparam, .get_strings = hns3_get_strings, .get_ethtool_stats = hns3_get_stats, .get_sset_count = hns3_get_sset_count, @@ -883,6 +920,8 @@ static const struct ethtool_ops hns3_ethtool_ops = { .get_link_ksettings = hns3_get_link_ksettings, .set_link_ksettings = hns3_set_link_ksettings, .nway_reset = hns3_nway_reset, + .get_channels = hns3_get_channels, + .set_channels = hns3_set_channels, }; void hns3_ethtool_set_ops(struct net_device *netdev) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index ce5ed8845042..f5baba216e48 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -180,6 +180,10 @@ enum hclge_opcode_type { /* Promisuous mode command */ HCLGE_OPC_CFG_PROMISC_MODE = 0x0E01, + /* Vlan offload command */ + HCLGE_OPC_VLAN_PORT_TX_CFG = 0x0F01, + HCLGE_OPC_VLAN_PORT_RX_CFG = 0x0F02, + /* Interrupts cmd */ HCLGE_OPC_ADD_RING_TO_VECTOR = 0x1503, HCLGE_OPC_DEL_RING_TO_VECTOR = 0x1504, @@ -191,6 +195,7 @@ enum hclge_opcode_type { HCLGE_OPC_MAC_VLAN_INSERT = 0x1003, HCLGE_OPC_MAC_ETHTYPE_ADD = 0x1010, HCLGE_OPC_MAC_ETHTYPE_REMOVE = 0x1011, + HCLGE_OPC_MAC_VLAN_MASK_SET = 0x1012, /* Multicast linear table cmd */ HCLGE_OPC_MTA_MAC_MODE_CFG = 0x1020, @@ -399,6 +404,8 @@ struct hclge_pf_res_cmd { #define HCLGE_CFG_MAC_ADDR_H_M GENMASK(15, 0) #define HCLGE_CFG_DEFAULT_SPEED_S 16 #define HCLGE_CFG_DEFAULT_SPEED_M GENMASK(23, 16) +#define HCLGE_CFG_RSS_SIZE_S 24 +#define HCLGE_CFG_RSS_SIZE_M GENMASK(31, 24) struct hclge_cfg_param_cmd { __le32 offset; @@ -587,6 +594,15 @@ struct hclge_mac_vlan_tbl_entry_cmd { u8 rsv2[6]; }; +#define HCLGE_VLAN_MASK_EN_B 0x0 +struct hclge_mac_vlan_mask_entry_cmd { + u8 rsv0[2]; + u8 vlan_mask; + u8 rsv1; + u8 mac_mask[6]; + u8 rsv2[14]; +}; + #define HCLGE_CFG_MTA_MAC_SEL_S 0x0 #define HCLGE_CFG_MTA_MAC_SEL_M GENMASK(1, 0) #define HCLGE_CFG_MTA_MAC_EN_B 0x7 @@ -658,6 +674,47 @@ struct hclge_vlan_filter_vf_cfg_cmd { u8 vf_bitmap[16]; }; +#define HCLGE_ACCEPT_TAG_B 0 +#define HCLGE_ACCEPT_UNTAG_B 1 +#define HCLGE_PORT_INS_TAG1_EN_B 2 +#define HCLGE_PORT_INS_TAG2_EN_B 3 +#define HCLGE_CFG_NIC_ROCE_SEL_B 4 +struct hclge_vport_vtag_tx_cfg_cmd { + u8 vport_vlan_cfg; + u8 vf_offset; + u8 rsv1[2]; + __le16 def_vlan_tag1; + __le16 def_vlan_tag2; + u8 vf_bitmap[8]; + u8 rsv2[8]; +}; + +#define HCLGE_REM_TAG1_EN_B 0 +#define HCLGE_REM_TAG2_EN_B 1 +#define HCLGE_SHOW_TAG1_EN_B 2 +#define HCLGE_SHOW_TAG2_EN_B 3 +struct hclge_vport_vtag_rx_cfg_cmd { + u8 vport_vlan_cfg; + u8 vf_offset; + u8 rsv1[6]; + u8 vf_bitmap[8]; + u8 rsv2[8]; +}; + +struct hclge_tx_vlan_type_cfg_cmd { + __le16 ot_vlan_type; + __le16 in_vlan_type; + u8 rsv[20]; +}; + +struct hclge_rx_vlan_type_cfg_cmd { + __le16 ot_fst_vlan_type; + __le16 ot_sec_vlan_type; + __le16 in_fst_vlan_type; + __le16 in_sec_vlan_type; + u8 rsv[16]; +}; + struct hclge_cfg_com_tqp_queue_cmd { __le16 tqp_id; __le16 stream_id; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index e97fd6654e5e..0874acf5ef39 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -982,6 +982,10 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) cfg->default_speed = hnae_get_field(__le32_to_cpu(req->param[3]), HCLGE_CFG_DEFAULT_SPEED_M, HCLGE_CFG_DEFAULT_SPEED_S); + cfg->rss_size_max = hnae_get_field(__le32_to_cpu(req->param[3]), + HCLGE_CFG_RSS_SIZE_M, + HCLGE_CFG_RSS_SIZE_S); + for (i = 0; i < ETH_ALEN; i++) cfg->mac_addr[i] = (mac_addr_tmp >> (8 * i)) & 0xff; @@ -1059,7 +1063,7 @@ static int hclge_configure(struct hclge_dev *hdev) hdev->num_vmdq_vport = cfg.vmdq_vport_num; hdev->base_tqp_pid = 0; - hdev->rss_size_max = 1; + hdev->rss_size_max = cfg.rss_size_max; hdev->rx_buf_len = cfg.rx_buf_len; ether_addr_copy(hdev->hw.mac.mac_addr, cfg.mac_addr); hdev->hw.mac.media_type = cfg.media_type; @@ -1096,10 +1100,7 @@ static int hclge_configure(struct hclge_dev *hdev) for (i = 0; i < hdev->tm_info.num_tc; i++) hnae_set_bit(hdev->hw_tc_map, i, 1); - if (!hdev->num_vmdq_vport && !hdev->num_req_vfs) - hdev->tx_sch_mode = HCLGE_FLAG_TC_BASE_SCH_MODE; - else - hdev->tx_sch_mode = HCLGE_FLAG_VNET_BASE_SCH_MODE; + hdev->tx_sch_mode = HCLGE_FLAG_TC_BASE_SCH_MODE; return ret; } @@ -2133,28 +2134,6 @@ static int hclge_query_mac_an_speed_dup(struct hclge_dev *hdev, int *speed, return 0; } -static int hclge_query_autoneg_result(struct hclge_dev *hdev) -{ - struct hclge_mac *mac = &hdev->hw.mac; - struct hclge_query_an_speed_dup_cmd *req; - struct hclge_desc desc; - int ret; - - req = (struct hclge_query_an_speed_dup_cmd *)desc.data; - - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_AN_RESULT, true); - ret = hclge_cmd_send(&hdev->hw, &desc, 1); - if (ret) { - dev_err(&hdev->pdev->dev, - "autoneg result query cmd failed %d.\n", ret); - return ret; - } - - mac->autoneg = hnae_get_bit(req->an_syn_dup_speed, HCLGE_QUERY_AN_B); - - return 0; -} - static int hclge_set_autoneg_en(struct hclge_dev *hdev, bool enable) { struct hclge_config_auto_neg_cmd *req; @@ -2190,15 +2169,42 @@ static int hclge_get_autoneg(struct hnae3_handle *handle) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; + struct phy_device *phydev = hdev->hw.mac.phydev; - hclge_query_autoneg_result(hdev); + if (phydev) + return phydev->autoneg; return hdev->hw.mac.autoneg; } +static int hclge_set_default_mac_vlan_mask(struct hclge_dev *hdev, + bool mask_vlan, + u8 *mac_mask) +{ + struct hclge_mac_vlan_mask_entry_cmd *req; + struct hclge_desc desc; + int status; + + req = (struct hclge_mac_vlan_mask_entry_cmd *)desc.data; + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_MASK_SET, false); + + hnae_set_bit(req->vlan_mask, HCLGE_VLAN_MASK_EN_B, + mask_vlan ? 1 : 0); + ether_addr_copy(req->mac_mask, mac_mask); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) + dev_err(&hdev->pdev->dev, + "Config mac_vlan_mask failed for cmd_send, ret =%d\n", + status); + + return status; +} + static int hclge_mac_init(struct hclge_dev *hdev) { struct hclge_mac *mac = &hdev->hw.mac; + u8 mac_mask[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int ret; ret = hclge_cfg_mac_speed_dup(hdev, hdev->hw.mac.speed, HCLGE_MAC_FULL); @@ -2224,7 +2230,19 @@ static int hclge_mac_init(struct hclge_dev *hdev) return ret; } - return hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc); + ret = hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc); + if (ret) { + dev_err(&hdev->pdev->dev, + "set mta filter mode fail ret=%d\n", ret); + return ret; + } + + ret = hclge_set_default_mac_vlan_mask(hdev, true, mac_mask); + if (ret) + dev_err(&hdev->pdev->dev, + "set default mac_vlan_mask fail ret=%d\n", ret); + + return ret; } static void hclge_mbx_task_schedule(struct hclge_dev *hdev) @@ -4339,27 +4357,185 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, return hclge_set_vf_vlan_common(hdev, vfid, false, vlan, qos, proto); } +static int hclge_set_vlan_tx_offload_cfg(struct hclge_vport *vport) +{ + struct hclge_tx_vtag_cfg *vcfg = &vport->txvlan_cfg; + struct hclge_vport_vtag_tx_cfg_cmd *req; + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int status; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_PORT_TX_CFG, false); + + req = (struct hclge_vport_vtag_tx_cfg_cmd *)desc.data; + req->def_vlan_tag1 = cpu_to_le16(vcfg->default_tag1); + req->def_vlan_tag2 = cpu_to_le16(vcfg->default_tag2); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_ACCEPT_TAG_B, + vcfg->accept_tag ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_ACCEPT_UNTAG_B, + vcfg->accept_untag ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_PORT_INS_TAG1_EN_B, + vcfg->insert_tag1_en ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_PORT_INS_TAG2_EN_B, + vcfg->insert_tag2_en ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_CFG_NIC_ROCE_SEL_B, 0); + + req->vf_offset = vport->vport_id / HCLGE_VF_NUM_PER_CMD; + req->vf_bitmap[req->vf_offset] = + 1 << (vport->vport_id % HCLGE_VF_NUM_PER_BYTE); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) + dev_err(&hdev->pdev->dev, + "Send port txvlan cfg command fail, ret =%d\n", + status); + + return status; +} + +static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport) +{ + struct hclge_rx_vtag_cfg *vcfg = &vport->rxvlan_cfg; + struct hclge_vport_vtag_rx_cfg_cmd *req; + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int status; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_PORT_RX_CFG, false); + + req = (struct hclge_vport_vtag_rx_cfg_cmd *)desc.data; + hnae_set_bit(req->vport_vlan_cfg, HCLGE_REM_TAG1_EN_B, + vcfg->strip_tag1_en ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_REM_TAG2_EN_B, + vcfg->strip_tag2_en ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_SHOW_TAG1_EN_B, + vcfg->vlan1_vlan_prionly ? 1 : 0); + hnae_set_bit(req->vport_vlan_cfg, HCLGE_SHOW_TAG2_EN_B, + vcfg->vlan2_vlan_prionly ? 1 : 0); + + req->vf_offset = vport->vport_id / HCLGE_VF_NUM_PER_CMD; + req->vf_bitmap[req->vf_offset] = + 1 << (vport->vport_id % HCLGE_VF_NUM_PER_BYTE); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) + dev_err(&hdev->pdev->dev, + "Send port rxvlan cfg command fail, ret =%d\n", + status); + + return status; +} + +static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev) +{ + struct hclge_rx_vlan_type_cfg_cmd *rx_req; + struct hclge_tx_vlan_type_cfg_cmd *tx_req; + struct hclge_desc desc; + int status; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_TYPE_ID, false); + rx_req = (struct hclge_rx_vlan_type_cfg_cmd *)desc.data; + rx_req->ot_fst_vlan_type = + cpu_to_le16(hdev->vlan_type_cfg.rx_ot_fst_vlan_type); + rx_req->ot_sec_vlan_type = + cpu_to_le16(hdev->vlan_type_cfg.rx_ot_sec_vlan_type); + rx_req->in_fst_vlan_type = + cpu_to_le16(hdev->vlan_type_cfg.rx_in_fst_vlan_type); + rx_req->in_sec_vlan_type = + cpu_to_le16(hdev->vlan_type_cfg.rx_in_sec_vlan_type); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) { + dev_err(&hdev->pdev->dev, + "Send rxvlan protocol type command fail, ret =%d\n", + status); + return status; + } + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_INSERT, false); + + tx_req = (struct hclge_tx_vlan_type_cfg_cmd *)&desc.data; + tx_req->ot_vlan_type = cpu_to_le16(hdev->vlan_type_cfg.tx_ot_vlan_type); + tx_req->in_vlan_type = cpu_to_le16(hdev->vlan_type_cfg.tx_in_vlan_type); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) + dev_err(&hdev->pdev->dev, + "Send txvlan protocol type command fail, ret =%d\n", + status); + + return status; +} + static int hclge_init_vlan_config(struct hclge_dev *hdev) { -#define HCLGE_VLAN_TYPE_VF_TABLE 0 -#define HCLGE_VLAN_TYPE_PORT_TABLE 1 +#define HCLGE_FILTER_TYPE_VF 0 +#define HCLGE_FILTER_TYPE_PORT 1 +#define HCLGE_DEF_VLAN_TYPE 0x8100 + struct hnae3_handle *handle; + struct hclge_vport *vport; int ret; + int i; - ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_VF_TABLE, - true); + ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, true); if (ret) return ret; - ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_PORT_TABLE, - true); + ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, true); if (ret) return ret; + hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; + hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE; + hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; + hdev->vlan_type_cfg.rx_ot_sec_vlan_type = HCLGE_DEF_VLAN_TYPE; + hdev->vlan_type_cfg.tx_ot_vlan_type = HCLGE_DEF_VLAN_TYPE; + hdev->vlan_type_cfg.tx_in_vlan_type = HCLGE_DEF_VLAN_TYPE; + + ret = hclge_set_vlan_protocol_type(hdev); + if (ret) + return ret; + + for (i = 0; i < hdev->num_alloc_vport; i++) { + vport = &hdev->vport[i]; + vport->txvlan_cfg.accept_tag = true; + vport->txvlan_cfg.accept_untag = true; + vport->txvlan_cfg.insert_tag1_en = false; + vport->txvlan_cfg.insert_tag2_en = false; + vport->txvlan_cfg.default_tag1 = 0; + vport->txvlan_cfg.default_tag2 = 0; + + ret = hclge_set_vlan_tx_offload_cfg(vport); + if (ret) + return ret; + + vport->rxvlan_cfg.strip_tag1_en = false; + vport->rxvlan_cfg.strip_tag2_en = true; + vport->rxvlan_cfg.vlan1_vlan_prionly = false; + vport->rxvlan_cfg.vlan2_vlan_prionly = false; + + ret = hclge_set_vlan_rx_offload_cfg(vport); + if (ret) + return ret; + } + handle = &hdev->vport[0].nic; return hclge_set_port_vlan_filter(handle, htons(ETH_P_8021Q), 0, false); } +static int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + + vport->rxvlan_cfg.strip_tag1_en = false; + vport->rxvlan_cfg.strip_tag2_en = enable; + vport->rxvlan_cfg.vlan1_vlan_prionly = false; + vport->rxvlan_cfg.vlan2_vlan_prionly = false; + + return hclge_set_vlan_rx_offload_cfg(vport); +} + static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu) { struct hclge_vport *vport = hclge_get_vport(handle); @@ -4481,6 +4657,103 @@ static u32 hclge_get_fw_version(struct hnae3_handle *handle) return hdev->fw_version; } +static void hclge_get_flowctrl_adv(struct hnae3_handle *handle, + u32 *flowctrl_adv) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct phy_device *phydev = hdev->hw.mac.phydev; + + if (!phydev) + return; + + *flowctrl_adv |= (phydev->advertising & ADVERTISED_Pause) | + (phydev->advertising & ADVERTISED_Asym_Pause); +} + +static void hclge_set_flowctrl_adv(struct hclge_dev *hdev, u32 rx_en, u32 tx_en) +{ + struct phy_device *phydev = hdev->hw.mac.phydev; + + if (!phydev) + return; + + phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); + + if (rx_en) + phydev->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause; + + if (tx_en) + phydev->advertising ^= ADVERTISED_Asym_Pause; +} + +static int hclge_cfg_pauseparam(struct hclge_dev *hdev, u32 rx_en, u32 tx_en) +{ + enum hclge_fc_mode fc_mode; + int ret; + + if (rx_en && tx_en) + fc_mode = HCLGE_FC_FULL; + else if (rx_en && !tx_en) + fc_mode = HCLGE_FC_RX_PAUSE; + else if (!rx_en && tx_en) + fc_mode = HCLGE_FC_TX_PAUSE; + else + fc_mode = HCLGE_FC_NONE; + + if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) { + hdev->fc_mode_last_time = fc_mode; + return 0; + } + + ret = hclge_mac_pause_en_cfg(hdev, tx_en, rx_en); + if (ret) { + dev_err(&hdev->pdev->dev, "configure pauseparam error, ret = %d.\n", + ret); + return ret; + } + + hdev->tm_info.fc_mode = fc_mode; + + return 0; +} + +int hclge_cfg_flowctrl(struct hclge_dev *hdev) +{ + struct phy_device *phydev = hdev->hw.mac.phydev; + u16 remote_advertising = 0; + u16 local_advertising = 0; + u32 rx_pause, tx_pause; + u8 flowctl; + + if (!phydev->link || !phydev->autoneg) + return 0; + + if (phydev->advertising & ADVERTISED_Pause) + local_advertising = ADVERTISE_PAUSE_CAP; + + if (phydev->advertising & ADVERTISED_Asym_Pause) + local_advertising |= ADVERTISE_PAUSE_ASYM; + + if (phydev->pause) + remote_advertising = LPA_PAUSE_CAP; + + if (phydev->asym_pause) + remote_advertising |= LPA_PAUSE_ASYM; + + flowctl = mii_resolve_flowctrl_fdx(local_advertising, + remote_advertising); + tx_pause = flowctl & FLOW_CTRL_TX; + rx_pause = flowctl & FLOW_CTRL_RX; + + if (phydev->duplex == HCLGE_MAC_HALF) { + tx_pause = 0; + rx_pause = 0; + } + + return hclge_cfg_pauseparam(hdev, rx_pause, tx_pause); +} + static void hclge_get_pauseparam(struct hnae3_handle *handle, u32 *auto_neg, u32 *rx_en, u32 *tx_en) { @@ -4510,6 +4783,41 @@ static void hclge_get_pauseparam(struct hnae3_handle *handle, u32 *auto_neg, } } +static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg, + u32 rx_en, u32 tx_en) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct phy_device *phydev = hdev->hw.mac.phydev; + u32 fc_autoneg; + + /* Only support flow control negotiation for netdev with + * phy attached for now. + */ + if (!phydev) + return -EOPNOTSUPP; + + fc_autoneg = hclge_get_autoneg(handle); + if (auto_neg != fc_autoneg) { + dev_info(&hdev->pdev->dev, + "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n"); + return -EOPNOTSUPP; + } + + if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) { + dev_info(&hdev->pdev->dev, + "Priority flow control enabled. Cannot set link flow control.\n"); + return -EOPNOTSUPP; + } + + hclge_set_flowctrl_adv(hdev, rx_en, tx_en); + + if (!fc_autoneg) + return hclge_cfg_pauseparam(hdev, rx_en, tx_en); + + return phy_start_aneg(phydev); +} + static void hclge_get_ksettings_an_result(struct hnae3_handle *handle, u8 *auto_neg, u32 *speed, u8 *duplex) { @@ -5002,6 +5310,136 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) ae_dev->priv = NULL; } +static u32 hclge_get_max_channels(struct hnae3_handle *handle) +{ + struct hnae3_knic_private_info *kinfo = &handle->kinfo; + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + + return min_t(u32, hdev->rss_size_max * kinfo->num_tc, hdev->num_tqps); +} + +static void hclge_get_channels(struct hnae3_handle *handle, + struct ethtool_channels *ch) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + + ch->max_combined = hclge_get_max_channels(handle); + ch->other_count = 1; + ch->max_other = 1; + ch->combined_count = vport->alloc_tqps; +} + +static void hclge_get_tqps_and_rss_info(struct hnae3_handle *handle, + u16 *free_tqps, u16 *max_rss_size) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + u16 temp_tqps = 0; + int i; + + for (i = 0; i < hdev->num_tqps; i++) { + if (!hdev->htqp[i].alloced) + temp_tqps++; + } + *free_tqps = temp_tqps; + *max_rss_size = hdev->rss_size_max; +} + +static void hclge_release_tqp(struct hclge_vport *vport) +{ + struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; + struct hclge_dev *hdev = vport->back; + int i; + + for (i = 0; i < kinfo->num_tqps; i++) { + struct hclge_tqp *tqp = + container_of(kinfo->tqp[i], struct hclge_tqp, q); + + tqp->q.handle = NULL; + tqp->q.tqp_index = 0; + tqp->alloced = false; + } + + devm_kfree(&hdev->pdev->dev, kinfo->tqp); + kinfo->tqp = NULL; +} + +static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; + struct hclge_dev *hdev = vport->back; + int cur_rss_size = kinfo->rss_size; + int cur_tqps = kinfo->num_tqps; + u16 tc_offset[HCLGE_MAX_TC_NUM]; + u16 tc_valid[HCLGE_MAX_TC_NUM]; + u16 tc_size[HCLGE_MAX_TC_NUM]; + u16 roundup_size; + u32 *rss_indir; + int ret, i; + + hclge_release_tqp(vport); + + ret = hclge_knic_setup(vport, new_tqps_num); + if (ret) { + dev_err(&hdev->pdev->dev, "setup nic fail, ret =%d\n", ret); + return ret; + } + + ret = hclge_map_tqp_to_vport(hdev, vport); + if (ret) { + dev_err(&hdev->pdev->dev, "map vport tqp fail, ret =%d\n", ret); + return ret; + } + + ret = hclge_tm_schd_init(hdev); + if (ret) { + dev_err(&hdev->pdev->dev, "tm schd init fail, ret =%d\n", ret); + return ret; + } + + roundup_size = roundup_pow_of_two(kinfo->rss_size); + roundup_size = ilog2(roundup_size); + /* Set the RSS TC mode according to the new RSS size */ + for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { + tc_valid[i] = 0; + + if (!(hdev->hw_tc_map & BIT(i))) + continue; + + tc_valid[i] = 1; + tc_size[i] = roundup_size; + tc_offset[i] = kinfo->rss_size * i; + } + ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset); + if (ret) + return ret; + + /* Reinitializes the rss indirect table according to the new RSS size */ + rss_indir = kcalloc(HCLGE_RSS_IND_TBL_SIZE, sizeof(u32), GFP_KERNEL); + if (!rss_indir) + return -ENOMEM; + + for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) + rss_indir[i] = i % kinfo->rss_size; + + ret = hclge_set_rss(handle, rss_indir, NULL, 0); + if (ret) + dev_err(&hdev->pdev->dev, "set rss indir table fail, ret=%d\n", + ret); + + kfree(rss_indir); + + if (!ret) + dev_info(&hdev->pdev->dev, + "Channels changed, rss_size from %d to %d, tqps from %d to %d", + cur_rss_size, kinfo->rss_size, + cur_tqps, kinfo->rss_size * kinfo->num_tc); + + return ret; +} + static const struct hnae3_ae_ops hclge_ops = { .init_ae_dev = hclge_init_ae_dev, .uninit_ae_dev = hclge_uninit_ae_dev, @@ -5035,6 +5473,7 @@ static const struct hnae3_ae_ops hclge_ops = { .set_autoneg = hclge_set_autoneg, .get_autoneg = hclge_get_autoneg, .get_pauseparam = hclge_get_pauseparam, + .set_pauseparam = hclge_set_pauseparam, .set_mtu = hclge_set_mtu, .reset_queue = hclge_reset_tqp, .get_stats = hclge_get_stats, @@ -5045,7 +5484,12 @@ static const struct hnae3_ae_ops hclge_ops = { .get_mdix_mode = hclge_get_mdix_mode, .set_vlan_filter = hclge_set_port_vlan_filter, .set_vf_vlan_filter = hclge_set_vf_vlan_filter, + .enable_hw_strip_rxvtag = hclge_en_hw_strip_rxvtag, .reset_event = hclge_reset_event, + .get_tqps_and_rss_info = hclge_get_tqps_and_rss_info, + .set_channels = hclge_set_channels, + .get_channels = hclge_get_channels, + .get_flowctrl_adv = hclge_get_flowctrl_adv, }; static struct hnae3_ae_algo ae_algo = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index fb043b54583d..28cc063306c4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -79,6 +79,10 @@ #define HCLGE_PHY_MDIX_STATUS_B (6) #define HCLGE_PHY_SPEED_DUP_RESOLVE_B (11) +/* Factor used to calculate offset and bitmap of VF num */ +#define HCLGE_VF_NUM_PER_CMD 64 +#define HCLGE_VF_NUM_PER_BYTE 8 + /* Reset related Registers */ #define HCLGE_MISC_RESET_STS_REG 0x20700 #define HCLGE_GLOBAL_RESET_REG 0x20A00 @@ -220,6 +224,7 @@ struct hclge_cfg { u8 tc_num; u16 tqp_desc_num; u16 rx_buf_len; + u16 rss_size_max; u8 phy_addr; u8 media_type; u8 mac_addr[ETH_ALEN]; @@ -423,6 +428,15 @@ struct hclge_hw_stats { struct hclge_32_bit_stats all_32_bit_stats; }; +struct hclge_vlan_type_cfg { + u16 rx_ot_fst_vlan_type; + u16 rx_ot_sec_vlan_type; + u16 rx_in_fst_vlan_type; + u16 rx_in_sec_vlan_type; + u16 tx_ot_vlan_type; + u16 tx_in_vlan_type; +}; + struct hclge_dev { struct pci_dev *pdev; struct hnae3_ae_dev *ae_dev; @@ -509,6 +523,26 @@ struct hclge_dev { enum hclge_mta_dmac_sel_type mta_mac_sel_type; bool enable_mta; /* Mutilcast filter enable */ bool accept_mta_mc; /* Whether accept mta filter multicast */ + + struct hclge_vlan_type_cfg vlan_type_cfg; +}; + +/* VPort level vlan tag configuration for TX direction */ +struct hclge_tx_vtag_cfg { + bool accept_tag; /* Whether accept tagged packet from host */ + bool accept_untag; /* Whether accept untagged packet from host */ + bool insert_tag1_en; /* Whether insert inner vlan tag */ + bool insert_tag2_en; /* Whether insert outer vlan tag */ + u16 default_tag1; /* The default inner vlan tag to insert */ + u16 default_tag2; /* The default outer vlan tag to insert */ +}; + +/* VPort level vlan tag configuration for RX direction */ +struct hclge_rx_vtag_cfg { + bool strip_tag1_en; /* Whether strip inner vlan tag */ + bool strip_tag2_en; /* Whether strip outer vlan tag */ + bool vlan1_vlan_prionly;/* Inner VLAN Tag up to descriptor Enable */ + bool vlan2_vlan_prionly;/* Outer VLAN Tag up to descriptor Enable */ }; struct hclge_vport { @@ -523,6 +557,9 @@ struct hclge_vport { u16 bw_limit; /* VSI BW Limit (0 = disabled) */ u8 dwrr; + struct hclge_tx_vtag_cfg txvlan_cfg; + struct hclge_rx_vtag_cfg rxvlan_cfg; + int vport_id; struct hclge_dev *back; /* Back reference to associated dev */ struct hnae3_handle nic; @@ -565,4 +602,5 @@ int hclge_rss_init_hw(struct hclge_dev *hdev); void hclge_mbx_handler(struct hclge_dev *hdev); void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id); +int hclge_cfg_flowctrl(struct hclge_dev *hdev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c index 7069e9408d7d..c1dea3a47bdd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c @@ -17,6 +17,7 @@ #define HCLGE_PHY_SUPPORTED_FEATURES (SUPPORTED_Autoneg | \ SUPPORTED_TP | \ SUPPORTED_Pause | \ + SUPPORTED_Asym_Pause | \ PHY_10BT_FEATURES | \ PHY_100BT_FEATURES | \ PHY_1000BT_FEATURES) @@ -183,6 +184,10 @@ static void hclge_mac_adjust_link(struct net_device *netdev) ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); if (ret) netdev_err(netdev, "failed to adjust link.\n"); + + ret = hclge_cfg_flowctrl(hdev); + if (ret) + netdev_err(netdev, "failed to configure flow control.\n"); } int hclge_mac_start_phy(struct hclge_dev *hdev) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index 7bfa2e5497cb..ea9355d82560 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -23,8 +23,8 @@ enum hclge_shaper_level { HCLGE_SHAPER_LVL_PF = 1, }; -#define HCLGE_SHAPER_BS_U_DEF 1 -#define HCLGE_SHAPER_BS_S_DEF 4 +#define HCLGE_SHAPER_BS_U_DEF 5 +#define HCLGE_SHAPER_BS_S_DEF 20 #define HCLGE_ETHER_MAX_RATE 100000 @@ -112,7 +112,7 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, return 0; } -static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) +int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) { struct hclge_desc desc; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h index bf59961918ab..16f413956f17 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -118,4 +118,5 @@ void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc); int hclge_tm_dwrr_cfg(struct hclge_dev *hdev); int hclge_tm_map_cfg(struct hclge_dev *hdev); int hclge_tm_init_hw(struct hclge_dev *hdev); +int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); #endif diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 7feff2450ed6..71ddad13baf4 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -199,18 +199,18 @@ static void __emac_set_multicast_list(struct emac_instance *dev); static inline int emac_phy_supports_gige(int phy_mode) { - return phy_mode == PHY_MODE_GMII || - phy_mode == PHY_MODE_RGMII || - phy_mode == PHY_MODE_SGMII || - phy_mode == PHY_MODE_TBI || - phy_mode == PHY_MODE_RTBI; + return phy_interface_mode_is_rgmii(phy_mode) || + phy_mode == PHY_INTERFACE_MODE_GMII || + phy_mode == PHY_INTERFACE_MODE_SGMII || + phy_mode == PHY_INTERFACE_MODE_TBI || + phy_mode == PHY_INTERFACE_MODE_RTBI; } static inline int emac_phy_gpcs(int phy_mode) { - return phy_mode == PHY_MODE_SGMII || - phy_mode == PHY_MODE_TBI || - phy_mode == PHY_MODE_RTBI; + return phy_mode == PHY_INTERFACE_MODE_SGMII || + phy_mode == PHY_INTERFACE_MODE_TBI || + phy_mode == PHY_INTERFACE_MODE_RTBI; } static inline void emac_tx_enable(struct emac_instance *dev) @@ -2865,7 +2865,7 @@ static int emac_init_config(struct emac_instance *dev) /* PHY mode needs some decoding */ dev->phy_mode = of_get_phy_mode(np); if (dev->phy_mode < 0) - dev->phy_mode = PHY_MODE_NA; + dev->phy_mode = PHY_INTERFACE_MODE_NA; /* Check EMAC version */ if (of_device_is_compatible(np, "ibm,emac4sync")) { @@ -3168,7 +3168,7 @@ static int emac_probe(struct platform_device *ofdev) printk(KERN_INFO "%s: EMAC-%d %pOF, MAC %pM\n", ndev->name, dev->cell_index, np, ndev->dev_addr); - if (dev->phy_mode == PHY_MODE_SGMII) + if (dev->phy_mode == PHY_INTERFACE_MODE_SGMII) printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name); if (dev->phy.address >= 0) diff --git a/drivers/net/ethernet/ibm/emac/emac.h b/drivers/net/ethernet/ibm/emac/emac.h index 5afcc27ceebb..bc14dcf27b6b 100644 --- a/drivers/net/ethernet/ibm/emac/emac.h +++ b/drivers/net/ethernet/ibm/emac/emac.h @@ -104,19 +104,6 @@ struct emac_regs { } u1; }; -/* - * PHY mode settings (EMAC <-> ZMII/RGMII bridge <-> PHY) - */ -#define PHY_MODE_NA PHY_INTERFACE_MODE_NA -#define PHY_MODE_MII PHY_INTERFACE_MODE_MII -#define PHY_MODE_RMII PHY_INTERFACE_MODE_RMII -#define PHY_MODE_SMII PHY_INTERFACE_MODE_SMII -#define PHY_MODE_RGMII PHY_INTERFACE_MODE_RGMII -#define PHY_MODE_TBI PHY_INTERFACE_MODE_TBI -#define PHY_MODE_GMII PHY_INTERFACE_MODE_GMII -#define PHY_MODE_RTBI PHY_INTERFACE_MODE_RTBI -#define PHY_MODE_SGMII PHY_INTERFACE_MODE_SGMII - /* EMACx_MR0 */ #define EMAC_MR0_RXI 0x80000000 #define EMAC_MR0_TXI 0x40000000 diff --git a/drivers/net/ethernet/ibm/emac/phy.c b/drivers/net/ethernet/ibm/emac/phy.c index 35865d05fccd..aa070c063e48 100644 --- a/drivers/net/ethernet/ibm/emac/phy.c +++ b/drivers/net/ethernet/ibm/emac/phy.c @@ -96,7 +96,7 @@ int emac_mii_reset_gpcs(struct mii_phy *phy) if ((val & BMCR_ISOLATE) && limit > 0) gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE); - if (limit > 0 && phy->mode == PHY_MODE_SGMII) { + if (limit > 0 && phy->mode == PHY_INTERFACE_MODE_SGMII) { /* Configure GPCS interface to recommended setting for SGMII */ gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */ gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */ @@ -313,16 +313,16 @@ static int cis8201_init(struct mii_phy *phy) epcr &= ~EPCR_MODE_MASK; switch (phy->mode) { - case PHY_MODE_TBI: + case PHY_INTERFACE_MODE_TBI: epcr |= EPCR_TBI_MODE; break; - case PHY_MODE_RTBI: + case PHY_INTERFACE_MODE_RTBI: epcr |= EPCR_RTBI_MODE; break; - case PHY_MODE_GMII: + case PHY_INTERFACE_MODE_GMII: epcr |= EPCR_GMII_MODE; break; - case PHY_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII: default: epcr |= EPCR_RGMII_MODE; } diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index c4a1ac38bba8..00f5999de3cf 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -52,43 +52,28 @@ /* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */ static inline int rgmii_valid_mode(int phy_mode) { - return phy_mode == PHY_MODE_GMII || - phy_mode == PHY_MODE_MII || - phy_mode == PHY_MODE_RGMII || - phy_mode == PHY_MODE_TBI || - phy_mode == PHY_MODE_RTBI; -} - -static inline const char *rgmii_mode_name(int mode) -{ - switch (mode) { - case PHY_MODE_RGMII: - return "RGMII"; - case PHY_MODE_TBI: - return "TBI"; - case PHY_MODE_GMII: - return "GMII"; - case PHY_MODE_MII: - return "MII"; - case PHY_MODE_RTBI: - return "RTBI"; - default: - BUG(); - } + return phy_interface_mode_is_rgmii(phy_mode) || + phy_mode == PHY_INTERFACE_MODE_GMII || + phy_mode == PHY_INTERFACE_MODE_MII || + phy_mode == PHY_INTERFACE_MODE_TBI || + phy_mode == PHY_INTERFACE_MODE_RTBI; } static inline u32 rgmii_mode_mask(int mode, int input) { switch (mode) { - case PHY_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: return RGMII_FER_RGMII(input); - case PHY_MODE_TBI: + case PHY_INTERFACE_MODE_TBI: return RGMII_FER_TBI(input); - case PHY_MODE_GMII: + case PHY_INTERFACE_MODE_GMII: return RGMII_FER_GMII(input); - case PHY_MODE_MII: + case PHY_INTERFACE_MODE_MII: return RGMII_FER_MII(input); - case PHY_MODE_RTBI: + case PHY_INTERFACE_MODE_RTBI: return RGMII_FER_RTBI(input); default: BUG(); @@ -115,7 +100,7 @@ int rgmii_attach(struct platform_device *ofdev, int input, int mode) out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); printk(KERN_NOTICE "%pOF: input %d in %s mode\n", - ofdev->dev.of_node, input, rgmii_mode_name(mode)); + ofdev->dev.of_node, input, phy_modes(mode)); ++dev->users; diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index 89c42d362292..fdcc734541fe 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -49,20 +49,20 @@ */ static inline int zmii_valid_mode(int mode) { - return mode == PHY_MODE_MII || - mode == PHY_MODE_RMII || - mode == PHY_MODE_SMII || - mode == PHY_MODE_NA; + return mode == PHY_INTERFACE_MODE_MII || + mode == PHY_INTERFACE_MODE_RMII || + mode == PHY_INTERFACE_MODE_SMII || + mode == PHY_INTERFACE_MODE_NA; } static inline const char *zmii_mode_name(int mode) { switch (mode) { - case PHY_MODE_MII: + case PHY_INTERFACE_MODE_MII: return "MII"; - case PHY_MODE_RMII: + case PHY_INTERFACE_MODE_RMII: return "RMII"; - case PHY_MODE_SMII: + case PHY_INTERFACE_MODE_SMII: return "SMII"; default: BUG(); @@ -72,11 +72,11 @@ static inline const char *zmii_mode_name(int mode) static inline u32 zmii_mode_mask(int mode, int input) { switch (mode) { - case PHY_MODE_MII: + case PHY_INTERFACE_MODE_MII: return ZMII_FER_MII(input); - case PHY_MODE_RMII: + case PHY_INTERFACE_MODE_RMII: return ZMII_FER_RMII(input); - case PHY_MODE_SMII: + case PHY_INTERFACE_MODE_SMII: return ZMII_FER_SMII(input); default: return 0; @@ -106,27 +106,27 @@ int zmii_attach(struct platform_device *ofdev, int input, int *mode) * Please, always specify PHY mode in your board port to avoid * any surprises. */ - if (dev->mode == PHY_MODE_NA) { - if (*mode == PHY_MODE_NA) { + if (dev->mode == PHY_INTERFACE_MODE_NA) { + if (*mode == PHY_INTERFACE_MODE_NA) { u32 r = dev->fer_save; ZMII_DBG(dev, "autodetecting mode, FER = 0x%08x" NL, r); if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1))) - dev->mode = PHY_MODE_MII; + dev->mode = PHY_INTERFACE_MODE_MII; else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1))) - dev->mode = PHY_MODE_RMII; + dev->mode = PHY_INTERFACE_MODE_RMII; else - dev->mode = PHY_MODE_SMII; - } else + dev->mode = PHY_INTERFACE_MODE_SMII; + } else { dev->mode = *mode; - + } printk(KERN_NOTICE "%pOF: bridge in %s mode\n", ofdev->dev.of_node, zmii_mode_name(dev->mode)); } else { /* All inputs must use the same mode */ - if (*mode != PHY_MODE_NA && *mode != dev->mode) { + if (*mode != PHY_INTERFACE_MODE_NA && *mode != dev->mode) { printk(KERN_ERR "%pOF: invalid mode %d specified for input %d\n", ofdev->dev.of_node, *mode, input); @@ -246,7 +246,7 @@ static int zmii_probe(struct platform_device *ofdev) mutex_init(&dev->lock); dev->ofdev = ofdev; - dev->mode = PHY_MODE_NA; + dev->mode = PHY_INTERFACE_MODE_NA; rc = -ENXIO; if (of_address_to_resource(np, 0, ®s)) { diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 1dc4aef37d3a..6911b7cc06c5 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -59,6 +59,7 @@ #include <linux/mm.h> #include <linux/ethtool.h> #include <linux/proc_fs.h> +#include <linux/if_arp.h> #include <linux/in.h> #include <linux/ip.h> #include <linux/ipv6.h> @@ -1153,6 +1154,9 @@ static int build_hdr_data(u8 hdr_field, struct sk_buff *skb, hdr_len[2] = tcp_hdrlen(skb); else if (ipv6_hdr(skb)->nexthdr == IPPROTO_UDP) hdr_len[2] = sizeof(struct udphdr); + } else if (skb->protocol == htons(ETH_P_ARP)) { + hdr_len[1] = arp_hdr_len(skb->dev); + hdr_len[2] = 0; } memset(hdr_data, 0, 120); @@ -1386,7 +1390,8 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) /* determine if l2/3/4 headers are sent to firmware */ if ((*hdrs >> 7) & 1 && (skb->protocol == htons(ETH_P_IP) || - skb->protocol == htons(ETH_P_IPV6))) { + skb->protocol == htons(ETH_P_IPV6) || + skb->protocol == htons(ETH_P_ARP))) { build_hdr_descs_arr(tx_buff, &num_entries, *hdrs); tx_crq.v1.n_crq_elem = num_entries; tx_buff->indir_arr[0] = tx_crq; @@ -4285,7 +4290,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) } netdev = alloc_etherdev_mq(sizeof(struct ibmvnic_adapter), - IBMVNIC_MAX_TX_QUEUES); + IBMVNIC_MAX_QUEUES); if (!netdev) return -ENOMEM; diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index 4487f1e2c266..2df79fdd800b 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h @@ -39,7 +39,7 @@ #define IBMVNIC_RX_WEIGHT 16 /* when changing this, update IBMVNIC_IO_ENTITLEMENT_DEFAULT */ #define IBMVNIC_BUFFS_PER_POOL 100 -#define IBMVNIC_MAX_TX_QUEUES 5 +#define IBMVNIC_MAX_QUEUES 10 #define IBMVNIC_TSO_BUF_SZ 65536 #define IBMVNIC_TSO_BUFS 64 diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index bc93b69cfd1e..a539263cd79c 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1214,6 +1214,10 @@ static void mvneta_port_disable(struct mvneta_port *pp) val &= ~MVNETA_GMAC0_PORT_ENABLE; mvreg_write(pp, MVNETA_GMAC_CTRL_0, val); + pp->link = 0; + pp->duplex = -1; + pp->speed = 0; + udelay(200); } @@ -1958,9 +1962,9 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo, if (!mvneta_rxq_desc_is_first_last(rx_status) || (rx_status & MVNETA_RXD_ERR_SUMMARY)) { + mvneta_rx_error(pp, rx_desc); err_drop_frame: dev->stats.rx_errors++; - mvneta_rx_error(pp, rx_desc); /* leave the descriptor untouched */ continue; } @@ -3011,7 +3015,7 @@ static void mvneta_cleanup_rxqs(struct mvneta_port *pp) { int queue; - for (queue = 0; queue < txq_number; queue++) + for (queue = 0; queue < rxq_number; queue++) mvneta_rxq_deinit(pp, &pp->rxqs[queue]); } diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 54adfd967858..29826dd15204 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -1952,20 +1952,23 @@ static int mtk_hw_init(struct mtk_eth *eth) } regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); - /* Set GE2 driving and slew rate */ - regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00); + if (eth->pctl) { + /* Set GE2 driving and slew rate */ + regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00); - /* set GE2 TDSEL */ - regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5); + /* set GE2 TDSEL */ + regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5); - /* set GE2 TUNE */ - regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); - - /* GE1, Force 1000M/FD, FC ON */ - mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0)); + /* set GE2 TUNE */ + regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); + } - /* GE2, Force 1000M/FD, FC ON */ - mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1)); + /* Set linkdown as the default for each GMAC. Its own MCR would be set + * up with the more appropriate value when mtk_phy_link_adjust call is + * being invoked. + */ + for (i = 0; i < MTK_MAC_COUNT; i++) + mtk_w32(eth, 0, MTK_MAC_MCR(i)); /* Indicates CDM to parse the MTK special tag from CPU * which also is working out for untag packets. @@ -2537,11 +2540,13 @@ static int mtk_probe(struct platform_device *pdev) } } - eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "mediatek,pctl"); - if (IS_ERR(eth->pctl)) { - dev_err(&pdev->dev, "no pctl regmap found\n"); - return PTR_ERR(eth->pctl); + if (eth->soc->required_pctl) { + eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "mediatek,pctl"); + if (IS_ERR(eth->pctl)) { + dev_err(&pdev->dev, "no pctl regmap found\n"); + return PTR_ERR(eth->pctl); + } } for (i = 0; i < 3; i++) { @@ -2667,17 +2672,20 @@ static int mtk_remove(struct platform_device *pdev) static const struct mtk_soc_data mt2701_data = { .caps = MTK_GMAC1_TRGMII, - .required_clks = MT7623_CLKS_BITMAP + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, }; static const struct mtk_soc_data mt7622_data = { .caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW, - .required_clks = MT7622_CLKS_BITMAP + .required_clks = MT7622_CLKS_BITMAP, + .required_pctl = false, }; static const struct mtk_soc_data mt7623_data = { .caps = MTK_GMAC1_TRGMII, - .required_clks = MT7623_CLKS_BITMAP + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, }; const struct of_device_id of_mtk_match[] = { diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index a3af4660de81..672b8c353c47 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -573,10 +573,13 @@ struct mtk_rx_ring { * @caps Flags shown the extra capability for the SoC * @required_clks Flags shown the bitmap for required clocks on * the target SoC + * @required_pctl A bool value to show whether the SoC requires + * the extra setup for those pins used by GMAC. */ struct mtk_soc_data { u32 caps; u32 required_clks; + bool required_pctl; }; /* currently no SoC has more than 2 macs */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 1fffdebbc9e8..e9a1fbcc4adf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -362,7 +362,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, case MLX5_CMD_OP_QUERY_VPORT_COUNTER: case MLX5_CMD_OP_ALLOC_Q_COUNTER: case MLX5_CMD_OP_QUERY_Q_COUNTER: - case MLX5_CMD_OP_SET_RATE_LIMIT: + case MLX5_CMD_OP_SET_PP_RATE_LIMIT: case MLX5_CMD_OP_QUERY_RATE_LIMIT: case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: @@ -505,7 +505,7 @@ const char *mlx5_command_str(int command) MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER); MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER); MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER); - MLX5_COMMAND_STR_CASE(SET_RATE_LIMIT); + MLX5_COMMAND_STR_CASE(SET_PP_RATE_LIMIT); MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT); MLX5_COMMAND_STR_CASE(CREATE_SCHEDULING_ELEMENT); MLX5_COMMAND_STR_CASE(DESTROY_SCHEDULING_ELEMENT); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index c0872b3284cb..543060c305a0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -82,6 +82,9 @@ max_t(u32, MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(mdev), req) #define MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 6) #define MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 8) +#define MLX5E_MPWQE_STRIDE_SZ(mdev, cqe_cmprs) \ + (cqe_cmprs ? MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : \ + MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev)) #define MLX5_MPWRQ_LOG_WQE_SZ 18 #define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \ @@ -590,6 +593,7 @@ struct mlx5e_channel { struct mlx5_core_dev *mdev; struct hwtstamp_config *tstamp; int ix; + int cpu; }; struct mlx5e_channels { @@ -935,8 +939,9 @@ void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode); void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode); -void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, - struct mlx5e_params *params, u8 rq_type); +void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, + struct mlx5e_params *params, + u8 rq_type); static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index c6d90b6dd80e..9bcf38f4123b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -274,6 +274,7 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, struct ieee_ets *ets) { + bool have_ets_tc = false; int bw_sum = 0; int i; @@ -288,11 +289,14 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, } /* Validate Bandwidth Sum */ - for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) - if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { + have_ets_tc = true; bw_sum += ets->tc_tx_bw[i]; + } + } - if (bw_sum != 0 && bw_sum != 100) { + if (have_ets_tc && bw_sum != 100) { netdev_err(netdev, "Failed to validate ETS: BW sum is illegal\n"); return -EINVAL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 23425f028405..8f05efa5c829 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -1523,8 +1523,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val new_channels.params = priv->channels.params; MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val); - mlx5e_set_rq_type_params(priv->mdev, &new_channels.params, - new_channels.params.rq_wq_type); + new_channels.params.mpwqe_log_stride_sz = + MLX5E_MPWQE_STRIDE_SZ(priv->mdev, new_val); + new_channels.params.mpwqe_log_num_strides = + MLX5_MPWRQ_LOG_WQE_SZ - new_channels.params.mpwqe_log_stride_sz; if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { priv->channels.params = new_channels.params; @@ -1536,6 +1538,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val return err; mlx5e_switch_priv_channels(priv, &new_channels, NULL); + mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n", + MLX5E_GET_PFLAG(&priv->channels.params, + MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF"); + return 0; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 0f5c012de52e..3aa1c90e7c86 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -71,11 +71,6 @@ struct mlx5e_channel_param { struct mlx5e_cq_param icosq_cq; }; -static int mlx5e_get_node(struct mlx5e_priv *priv, int ix) -{ - return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix); -} - static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) { return MLX5_CAP_GEN(mdev, striding_rq) && @@ -83,8 +78,8 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) MLX5_CAP_ETH(mdev, reg_umr_sq); } -void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, - struct mlx5e_params *params, u8 rq_type) +void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, + struct mlx5e_params *params, u8 rq_type) { params->rq_wq_type = rq_type; params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; @@ -93,10 +88,8 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, params->log_rq_size = is_kdump_kernel() ? MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW : MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW; - params->mpwqe_log_stride_sz = - MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS) ? - MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : - MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev); + params->mpwqe_log_stride_sz = MLX5E_MPWQE_STRIDE_SZ(mdev, + MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); params->mpwqe_log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ - params->mpwqe_log_stride_sz; break; @@ -120,13 +113,14 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); } -static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, struct mlx5e_params *params) +static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, + struct mlx5e_params *params) { u8 rq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) && !params->xdp_prog && !MLX5_IPSEC_DEV(mdev) ? MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ : MLX5_WQ_TYPE_LINKED_LIST; - mlx5e_set_rq_type_params(mdev, params, rq_type); + mlx5e_init_rq_type_params(mdev, params, rq_type); } static void mlx5e_update_carrier(struct mlx5e_priv *priv) @@ -444,17 +438,16 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int wq_sz = mlx5_wq_ll_get_size(&rq->wq); int mtt_sz = mlx5e_get_wqe_mtt_sz(); int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1; - int node = mlx5e_get_node(c->priv, c->ix); int i; rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info), - GFP_KERNEL, node); + GFP_KERNEL, cpu_to_node(c->cpu)); if (!rq->mpwqe.info) goto err_out; /* We allocate more than mtt_sz as we will align the pointer */ - rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, - GFP_KERNEL, node); + rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL, + cpu_to_node(c->cpu)); if (unlikely(!rq->mpwqe.mtt_no_align)) goto err_free_wqe_info; @@ -562,7 +555,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, int err; int i; - rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); + rqp->wq.db_numa_node = cpu_to_node(c->cpu); err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq, &rq->wq_ctrl); @@ -629,8 +622,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, default: /* MLX5_WQ_TYPE_LINKED_LIST */ rq->wqe.frag_info = kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info), - GFP_KERNEL, - mlx5e_get_node(c->priv, c->ix)); + GFP_KERNEL, cpu_to_node(c->cpu)); if (!rq->wqe.frag_info) { err = -ENOMEM; goto err_rq_wq_destroy; @@ -1000,13 +992,13 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c, sq->uar_map = mdev->mlx5e_res.bfreg.map; sq->min_inline_mode = params->tx_min_inline_mode; - param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); + param->wq.db_numa_node = cpu_to_node(c->cpu); err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); if (err) return err; sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; - err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix)); + err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu)); if (err) goto err_sq_wq_destroy; @@ -1053,13 +1045,13 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c, sq->channel = c; sq->uar_map = mdev->mlx5e_res.bfreg.map; - param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); + param->wq.db_numa_node = cpu_to_node(c->cpu); err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); if (err) return err; sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; - err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix)); + err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu)); if (err) goto err_sq_wq_destroy; @@ -1126,13 +1118,13 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, if (MLX5_IPSEC_DEV(c->priv->mdev)) set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state); - param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); + param->wq.db_numa_node = cpu_to_node(c->cpu); err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); if (err) return err; sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; - err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix)); + err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu)); if (err) goto err_sq_wq_destroy; @@ -1504,8 +1496,8 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c, struct mlx5_core_dev *mdev = c->priv->mdev; int err; - param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix); - param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); + param->wq.buf_numa_node = cpu_to_node(c->cpu); + param->wq.db_numa_node = cpu_to_node(c->cpu); param->eq_ix = c->ix; err = mlx5e_alloc_cq_common(mdev, param, cq); @@ -1604,6 +1596,11 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq) mlx5e_free_cq(cq); } +static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix) +{ + return cpumask_first(priv->mdev->priv.irq_info[ix].mask); +} + static int mlx5e_open_tx_cqs(struct mlx5e_channel *c, struct mlx5e_params *params, struct mlx5e_channel_param *cparam) @@ -1752,12 +1749,13 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, { struct mlx5e_cq_moder icocq_moder = {0, 0}; struct net_device *netdev = priv->netdev; + int cpu = mlx5e_get_cpu(priv, ix); struct mlx5e_channel *c; unsigned int irq; int err; int eqn; - c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix)); + c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); if (!c) return -ENOMEM; @@ -1765,6 +1763,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, c->mdev = priv->mdev; c->tstamp = &priv->tstamp; c->ix = ix; + c->cpu = cpu; c->pdev = &priv->mdev->pdev->dev; c->netdev = priv->netdev; c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key); @@ -1853,8 +1852,7 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c) for (tc = 0; tc < c->num_tc; tc++) mlx5e_activate_txqsq(&c->sq[tc]); mlx5e_activate_rq(&c->rq); - netif_set_xps_queue(c->netdev, - mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix); + netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix); } static void mlx5e_deactivate_channel(struct mlx5e_channel *c) @@ -3679,6 +3677,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, struct sk_buff *skb, netdev_features_t features) { + unsigned int offset = 0; struct udphdr *udph; u8 proto; u16 port; @@ -3688,7 +3687,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, proto = ip_hdr(skb)->protocol; break; case htons(ETH_P_IPV6): - proto = ipv6_hdr(skb)->nexthdr; + proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL); break; default: goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index 60771865c99c..e7e7cef2bde4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -466,7 +466,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr) break; case MLX5_EVENT_TYPE_CQ_ERROR: cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff; - mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrom 0x%x\n", + mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n", cqn, eqe->data.cq_err.syndrome); mlx5_cq_event(dev, cqn, eqe->type); break; @@ -775,7 +775,7 @@ err1: return err; } -int mlx5_stop_eqs(struct mlx5_core_dev *dev) +void mlx5_stop_eqs(struct mlx5_core_dev *dev) { struct mlx5_eq_table *table = &dev->priv.eq_table; int err; @@ -784,22 +784,26 @@ int mlx5_stop_eqs(struct mlx5_core_dev *dev) if (MLX5_CAP_GEN(dev, pg)) { err = mlx5_destroy_unmap_eq(dev, &table->pfault_eq); if (err) - return err; + mlx5_core_err(dev, "failed to destroy page fault eq, err(%d)\n", + err); } #endif err = mlx5_destroy_unmap_eq(dev, &table->pages_eq); if (err) - return err; + mlx5_core_err(dev, "failed to destroy pages eq, err(%d)\n", + err); - mlx5_destroy_unmap_eq(dev, &table->async_eq); + err = mlx5_destroy_unmap_eq(dev, &table->async_eq); + if (err) + mlx5_core_err(dev, "failed to destroy async eq, err(%d)\n", + err); mlx5_cmd_use_polling(dev); err = mlx5_destroy_unmap_eq(dev, &table->cmd_eq); if (err) - mlx5_cmd_use_events(dev); - - return err; + mlx5_core_err(dev, "failed to destroy command eq, err(%d)\n", + err); } int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c index 3c11d6e2160a..14962969c5ba 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c @@ -66,6 +66,9 @@ static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size, u8 actual_size; int err; + if (!size) + return -EINVAL; + if (!fdev->mdev) return -ENOTCONN; @@ -95,6 +98,9 @@ static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size, u8 actual_size; int err; + if (!size) + return -EINVAL; + if (!fdev->mdev) return -ENOTCONN; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index c70fd663a633..dfaad9ecb2b8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -174,6 +174,8 @@ static void del_hw_fte(struct fs_node *node); static void del_sw_flow_table(struct fs_node *node); static void del_sw_flow_group(struct fs_node *node); static void del_sw_fte(struct fs_node *node); +static void del_sw_prio(struct fs_node *node); +static void del_sw_ns(struct fs_node *node); /* Delete rule (destination) is special case that * requires to lock the FTE for all the deletion process. */ @@ -408,6 +410,16 @@ static inline struct mlx5_core_dev *get_dev(struct fs_node *node) return NULL; } +static void del_sw_ns(struct fs_node *node) +{ + kfree(node); +} + +static void del_sw_prio(struct fs_node *node) +{ + kfree(node); +} + static void del_hw_flow_table(struct fs_node *node) { struct mlx5_flow_table *ft; @@ -2064,7 +2076,7 @@ static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns, return ERR_PTR(-ENOMEM); fs_prio->node.type = FS_TYPE_PRIO; - tree_init_node(&fs_prio->node, NULL, NULL); + tree_init_node(&fs_prio->node, NULL, del_sw_prio); tree_add_node(&fs_prio->node, &ns->node); fs_prio->num_levels = num_levels; fs_prio->prio = prio; @@ -2090,7 +2102,7 @@ static struct mlx5_flow_namespace *fs_create_namespace(struct fs_prio *prio) return ERR_PTR(-ENOMEM); fs_init_namespace(ns); - tree_init_node(&ns->node, NULL, NULL); + tree_init_node(&ns->node, NULL, del_sw_ns); tree_add_node(&ns->node, &prio->node); list_add_tail(&ns->node.list, &prio->node.children); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index 1a0e797ad001..21d29f7936f6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c @@ -241,7 +241,7 @@ static void print_health_info(struct mlx5_core_dev *dev) u32 fw; int i; - /* If the syndrom is 0, the device is OK and no need to print buffer */ + /* If the syndrome is 0, the device is OK and no need to print buffer */ if (!ioread8(&h->synd)) return; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index d2a66dc4adc6..8812d7208e8f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c @@ -57,7 +57,7 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, struct mlx5e_params *params) { /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */ - mlx5e_set_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); + mlx5e_init_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); /* RQ size in ipoib by default is 512 */ params->log_rq_size = is_kdump_kernel() ? diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 5f323442cc5a..8a89c7e8cd63 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -317,9 +317,6 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) { struct mlx5_priv *priv = &dev->priv; struct mlx5_eq_table *table = &priv->eq_table; - struct irq_affinity irqdesc = { - .pre_vectors = MLX5_EQ_VEC_COMP_BASE, - }; int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq); int nvec; @@ -333,10 +330,9 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) if (!priv->irq_info) goto err_free_msix; - nvec = pci_alloc_irq_vectors_affinity(dev->pdev, + nvec = pci_alloc_irq_vectors(dev->pdev, MLX5_EQ_VEC_COMP_BASE + 1, nvec, - PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, - &irqdesc); + PCI_IRQ_MSIX); if (nvec < 0) return nvec; @@ -622,6 +618,63 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev) return (u64)timer_l | (u64)timer_h1 << 32; } +static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) +{ + struct mlx5_priv *priv = &mdev->priv; + int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i); + + if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { + mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); + return -ENOMEM; + } + + cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), + priv->irq_info[i].mask); + + if (IS_ENABLED(CONFIG_SMP) && + irq_set_affinity_hint(irq, priv->irq_info[i].mask)) + mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); + + return 0; +} + +static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) +{ + struct mlx5_priv *priv = &mdev->priv; + int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i); + + irq_set_affinity_hint(irq, NULL); + free_cpumask_var(priv->irq_info[i].mask); +} + +static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev) +{ + int err; + int i; + + for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) { + err = mlx5_irq_set_affinity_hint(mdev, i); + if (err) + goto err_out; + } + + return 0; + +err_out: + for (i--; i >= 0; i--) + mlx5_irq_clear_affinity_hint(mdev, i); + + return err; +} + +static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev) +{ + int i; + + for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) + mlx5_irq_clear_affinity_hint(mdev, i); +} + int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, unsigned int *irqn) { @@ -1097,6 +1150,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, goto err_stop_eqs; } + err = mlx5_irq_set_affinity_hints(dev); + if (err) { + dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n"); + goto err_affinity_hints; + } + err = mlx5_init_fs(dev); if (err) { dev_err(&pdev->dev, "Failed to init flow steering\n"); @@ -1154,6 +1213,9 @@ err_sriov: mlx5_cleanup_fs(dev); err_fs: + mlx5_irq_clear_affinity_hints(dev); + +err_affinity_hints: free_comp_eqs(dev); err_stop_eqs: @@ -1222,6 +1284,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, mlx5_sriov_detach(dev); mlx5_cleanup_fs(dev); + mlx5_irq_clear_affinity_hints(dev); free_comp_eqs(dev); mlx5_stop_eqs(dev); mlx5_put_uars_page(dev, priv->uar); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c index db9e665ab104..889130edb715 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c @@ -213,8 +213,8 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev, err_cmd: memset(din, 0, sizeof(din)); memset(dout, 0, sizeof(dout)); - MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP); - MLX5_SET(destroy_qp_in, in, qpn, qp->qpn); + MLX5_SET(destroy_qp_in, din, opcode, MLX5_CMD_OP_DESTROY_QP); + MLX5_SET(destroy_qp_in, din, qpn, qp->qpn); mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout)); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rl.c b/drivers/net/ethernet/mellanox/mlx5/core/rl.c index e651e4c02867..d3c33e9eea72 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/rl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/rl.c @@ -125,16 +125,16 @@ static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table, return ret_entry; } -static int mlx5_set_rate_limit_cmd(struct mlx5_core_dev *dev, +static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev, u32 rate, u16 index) { - u32 in[MLX5_ST_SZ_DW(set_rate_limit_in)] = {0}; - u32 out[MLX5_ST_SZ_DW(set_rate_limit_out)] = {0}; + u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {0}; + u32 out[MLX5_ST_SZ_DW(set_pp_rate_limit_out)] = {0}; - MLX5_SET(set_rate_limit_in, in, opcode, - MLX5_CMD_OP_SET_RATE_LIMIT); - MLX5_SET(set_rate_limit_in, in, rate_limit_index, index); - MLX5_SET(set_rate_limit_in, in, rate_limit, rate); + MLX5_SET(set_pp_rate_limit_in, in, opcode, + MLX5_CMD_OP_SET_PP_RATE_LIMIT); + MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, index); + MLX5_SET(set_pp_rate_limit_in, in, rate_limit, rate); return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); } @@ -173,7 +173,7 @@ int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index) entry->refcount++; } else { /* new rate limit */ - err = mlx5_set_rate_limit_cmd(dev, rate, entry->index); + err = mlx5_set_pp_rate_limit_cmd(dev, rate, entry->index); if (err) { mlx5_core_err(dev, "Failed configuring rate: %u (%d)\n", rate, err); @@ -209,7 +209,7 @@ void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, u32 rate) entry->refcount--; if (!entry->refcount) { /* need to remove rate */ - mlx5_set_rate_limit_cmd(dev, 0, entry->index); + mlx5_set_pp_rate_limit_cmd(dev, 0, entry->index); entry->rate = 0; } @@ -262,8 +262,8 @@ void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev) /* Clear all configured rates */ for (i = 0; i < table->max_size; i++) if (table->rl_entry[i].rate) - mlx5_set_rate_limit_cmd(dev, 0, - table->rl_entry[i].index); + mlx5_set_pp_rate_limit_cmd(dev, 0, + table->rl_entry[i].index); kfree(dev->priv.rl_table.rl_entry); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c index 07a9ba6cfc70..2f74953e4561 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c @@ -71,9 +71,9 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; struct mlx5e_vxlan *vxlan; - spin_lock(&vxlan_db->lock); + spin_lock_bh(&vxlan_db->lock); vxlan = radix_tree_lookup(&vxlan_db->tree, port); - spin_unlock(&vxlan_db->lock); + spin_unlock_bh(&vxlan_db->lock); return vxlan; } @@ -88,8 +88,12 @@ static void mlx5e_vxlan_add_port(struct work_struct *work) struct mlx5e_vxlan *vxlan; int err; - if (mlx5e_vxlan_lookup_port(priv, port)) + mutex_lock(&priv->state_lock); + vxlan = mlx5e_vxlan_lookup_port(priv, port); + if (vxlan) { + atomic_inc(&vxlan->refcount); goto free_work; + } if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) goto free_work; @@ -99,10 +103,11 @@ static void mlx5e_vxlan_add_port(struct work_struct *work) goto err_delete_port; vxlan->udp_port = port; + atomic_set(&vxlan->refcount, 1); - spin_lock_irq(&vxlan_db->lock); + spin_lock_bh(&vxlan_db->lock); err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan); - spin_unlock_irq(&vxlan_db->lock); + spin_unlock_bh(&vxlan_db->lock); if (err) goto err_free; @@ -113,35 +118,39 @@ err_free: err_delete_port: mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); free_work: + mutex_unlock(&priv->state_lock); kfree(vxlan_work); } -static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) +static void mlx5e_vxlan_del_port(struct work_struct *work) { + struct mlx5e_vxlan_work *vxlan_work = + container_of(work, struct mlx5e_vxlan_work, work); + struct mlx5e_priv *priv = vxlan_work->priv; struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; + u16 port = vxlan_work->port; struct mlx5e_vxlan *vxlan; + bool remove = false; - spin_lock_irq(&vxlan_db->lock); - vxlan = radix_tree_delete(&vxlan_db->tree, port); - spin_unlock_irq(&vxlan_db->lock); - + mutex_lock(&priv->state_lock); + spin_lock_bh(&vxlan_db->lock); + vxlan = radix_tree_lookup(&vxlan_db->tree, port); if (!vxlan) - return; - - mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port); - - kfree(vxlan); -} + goto out_unlock; -static void mlx5e_vxlan_del_port(struct work_struct *work) -{ - struct mlx5e_vxlan_work *vxlan_work = - container_of(work, struct mlx5e_vxlan_work, work); - struct mlx5e_priv *priv = vxlan_work->priv; - u16 port = vxlan_work->port; + if (atomic_dec_and_test(&vxlan->refcount)) { + radix_tree_delete(&vxlan_db->tree, port); + remove = true; + } - __mlx5e_vxlan_core_del_port(priv, port); +out_unlock: + spin_unlock_bh(&vxlan_db->lock); + if (remove) { + mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); + kfree(vxlan); + } + mutex_unlock(&priv->state_lock); kfree(vxlan_work); } @@ -171,12 +180,11 @@ void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) struct mlx5e_vxlan *vxlan; unsigned int port = 0; - spin_lock_irq(&vxlan_db->lock); + /* Lockless since we are the only radix-tree consumers, wq is disabled */ while (radix_tree_gang_lookup(&vxlan_db->tree, (void **)&vxlan, port, 1)) { port = vxlan->udp_port; - spin_unlock_irq(&vxlan_db->lock); - __mlx5e_vxlan_core_del_port(priv, (u16)port); - spin_lock_irq(&vxlan_db->lock); + radix_tree_delete(&vxlan_db->tree, port); + mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); + kfree(vxlan); } - spin_unlock_irq(&vxlan_db->lock); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h index 5def12c048e3..5ef6ae7d568a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h @@ -36,6 +36,7 @@ #include "en.h" struct mlx5e_vxlan { + atomic_t refcount; u16 udp_port; }; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 72ef4f8025f0..be657b8533f0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -2436,25 +2436,16 @@ static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp) rhashtable_destroy(&mlxsw_sp->router->neigh_ht); } -static int mlxsw_sp_neigh_rif_flush(struct mlxsw_sp *mlxsw_sp, - const struct mlxsw_sp_rif *rif) -{ - char rauht_pl[MLXSW_REG_RAUHT_LEN]; - - mlxsw_reg_rauht_pack(rauht_pl, MLXSW_REG_RAUHT_OP_WRITE_DELETE_ALL, - rif->rif_index, rif->addr); - return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); -} - static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_rif *rif) { struct mlxsw_sp_neigh_entry *neigh_entry, *tmp; - mlxsw_sp_neigh_rif_flush(mlxsw_sp, rif); list_for_each_entry_safe(neigh_entry, tmp, &rif->neigh_list, - rif_list_node) + rif_list_node) { + mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, false); mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); + } } enum mlxsw_sp_nexthop_type { diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 2fe96f1f3fe5..bd6e9014bc74 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -28,6 +28,7 @@ #include <linux/spi/spi.h> #include <linux/gpio.h> #include <linux/of_gpio.h> +#include <linux/of_net.h> #include "ks8851.h" @@ -407,15 +408,23 @@ static void ks8851_read_mac_addr(struct net_device *dev) * @ks: The device structure * * Get or create the initial mac address for the device and then set that - * into the station address register. If there is an EEPROM present, then + * into the station address register. A mac address supplied in the device + * tree takes precedence. Otherwise, if there is an EEPROM present, then * we try that. If no valid mac address is found we use eth_random_addr() * to create a new one. */ static void ks8851_init_mac(struct ks8851_net *ks) { struct net_device *dev = ks->netdev; + const u8 *mac_addr; + + mac_addr = of_get_mac_address(ks->spidev->dev.of_node); + if (mac_addr) { + memcpy(dev->dev_addr, mac_addr, ETH_ALEN); + ks8851_write_mac_addr(dev); + return; + } - /* first, try reading what we've got already */ if (ks->rc_ccr & CCR_EEPROM) { ks8851_read_mac_addr(dev); if (is_valid_ether_addr(dev->dev_addr)) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index 4f6553f01178..4b63167906ca 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -84,11 +84,41 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn) return nfp_net_ebpf_capable(nn) ? "BPF" : ""; } +static int +nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) +{ + int err; + + nn->app_priv = kzalloc(sizeof(struct nfp_bpf_vnic), GFP_KERNEL); + if (!nn->app_priv) + return -ENOMEM; + + err = nfp_app_nic_vnic_alloc(app, nn, id); + if (err) + goto err_free_priv; + + return 0; +err_free_priv: + kfree(nn->app_priv); + return err; +} + +static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn) +{ + struct nfp_bpf_vnic *bv = nn->app_priv; + + WARN_ON(bv->tc_prog); + kfree(bv); +} + static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) { struct tc_cls_bpf_offload *cls_bpf = type_data; struct nfp_net *nn = cb_priv; + struct bpf_prog *oldprog; + struct nfp_bpf_vnic *bv; + int err; if (type != TC_SETUP_CLSBPF || !tc_can_offload(nn->dp.netdev) || @@ -96,8 +126,6 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, cls_bpf->common.protocol != htons(ETH_P_ALL) || cls_bpf->common.chain_index) return -EOPNOTSUPP; - if (nn->dp.bpf_offload_xdp) - return -EBUSY; /* Only support TC direct action */ if (!cls_bpf->exts_integrated || @@ -106,16 +134,25 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, return -EOPNOTSUPP; } - switch (cls_bpf->command) { - case TC_CLSBPF_REPLACE: - return nfp_net_bpf_offload(nn, cls_bpf->prog, true); - case TC_CLSBPF_ADD: - return nfp_net_bpf_offload(nn, cls_bpf->prog, false); - case TC_CLSBPF_DESTROY: - return nfp_net_bpf_offload(nn, NULL, true); - default: + if (cls_bpf->command != TC_CLSBPF_OFFLOAD) return -EOPNOTSUPP; + + bv = nn->app_priv; + oldprog = cls_bpf->oldprog; + + /* Don't remove if oldprog doesn't match driver's state */ + if (bv->tc_prog != oldprog) { + oldprog = NULL; + if (!cls_bpf->prog) + return 0; } + + err = nfp_net_bpf_offload(nn, cls_bpf->prog, oldprog); + if (err) + return err; + + bv->tc_prog = cls_bpf->prog; + return 0; } static int nfp_bpf_setup_tc_block(struct net_device *netdev, @@ -276,7 +313,8 @@ const struct nfp_app_type app_bpf = { .extra_cap = nfp_bpf_extra_cap, - .vnic_alloc = nfp_app_nic_vnic_alloc, + .vnic_alloc = nfp_bpf_vnic_alloc, + .vnic_free = nfp_bpf_vnic_free, .setup_tc = nfp_bpf_setup_tc, .tc_busy = nfp_bpf_tc_busy, diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index f49669bf6b44..aae1be9ed056 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -228,6 +228,14 @@ struct nfp_prog { struct list_head insns; }; +/** + * struct nfp_bpf_vnic - per-vNIC BPF priv structure + * @tc_prog: currently loaded cls_bpf program + */ +struct nfp_bpf_vnic { + struct bpf_prog *tc_prog; +}; + int nfp_bpf_jit(struct nfp_prog *prog); extern const struct bpf_ext_analyzer_ops nfp_bpf_analyzer_ops; diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index ca74c517f626..b3567a596fc1 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -81,6 +81,9 @@ static bool nfp_fl_netdev_is_tunnel_type(struct net_device *out_dev, if (!strcmp(out_dev->rtnl_link_ops->kind, "vxlan")) return tun_type == NFP_FL_TUNNEL_VXLAN; + if (!strcmp(out_dev->rtnl_link_ops->kind, "geneve")) + return tun_type == NFP_FL_TUNNEL_GENEVE; + return false; } @@ -136,11 +139,23 @@ nfp_fl_output(struct nfp_fl_output *output, const struct tc_action *action, return 0; } -static bool nfp_fl_supported_tun_port(const struct tc_action *action) +static enum nfp_flower_tun_type +nfp_fl_get_tun_from_act_l4_port(struct nfp_app *app, + const struct tc_action *action) { struct ip_tunnel_info *tun = tcf_tunnel_info(action); - - return tun->key.tp_dst == htons(NFP_FL_VXLAN_PORT); + struct nfp_flower_priv *priv = app->priv; + + switch (tun->key.tp_dst) { + case htons(NFP_FL_VXLAN_PORT): + return NFP_FL_TUNNEL_VXLAN; + case htons(NFP_FL_GENEVE_PORT): + if (priv->flower_ext_feats & NFP_FL_FEATS_GENEVE) + return NFP_FL_TUNNEL_GENEVE; + /* FALLTHROUGH */ + default: + return NFP_FL_TUNNEL_NONE; + } } static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char *act_data, int act_len) @@ -165,38 +180,33 @@ static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char *act_data, int act_len) } static int -nfp_fl_set_vxlan(struct nfp_fl_set_vxlan *set_vxlan, - const struct tc_action *action, - struct nfp_fl_pre_tunnel *pre_tun) +nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, + const struct tc_action *action, + struct nfp_fl_pre_tunnel *pre_tun, + enum nfp_flower_tun_type tun_type) { - struct ip_tunnel_info *vxlan = tcf_tunnel_info(action); - size_t act_size = sizeof(struct nfp_fl_set_vxlan); - u32 tmp_set_vxlan_type_index = 0; + size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun); + struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); + u32 tmp_set_ip_tun_type_index = 0; /* Currently support one pre-tunnel so index is always 0. */ int pretun_idx = 0; - if (vxlan->options_len) { - /* Do not support options e.g. vxlan gpe. */ + if (ip_tun->options_len) return -EOPNOTSUPP; - } - set_vxlan->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; - set_vxlan->head.len_lw = act_size >> NFP_FL_LW_SIZ; + set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; + set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ; /* Set tunnel type and pre-tunnel index. */ - tmp_set_vxlan_type_index |= - FIELD_PREP(NFP_FL_IPV4_TUNNEL_TYPE, NFP_FL_TUNNEL_VXLAN) | + tmp_set_ip_tun_type_index |= + FIELD_PREP(NFP_FL_IPV4_TUNNEL_TYPE, tun_type) | FIELD_PREP(NFP_FL_IPV4_PRE_TUN_INDEX, pretun_idx); - set_vxlan->tun_type_index = cpu_to_be32(tmp_set_vxlan_type_index); - - set_vxlan->tun_id = vxlan->key.tun_id; - set_vxlan->tun_flags = vxlan->key.tun_flags; - set_vxlan->ipv4_ttl = vxlan->key.ttl; - set_vxlan->ipv4_tos = vxlan->key.tos; + set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index); + set_tun->tun_id = ip_tun->key.tun_id; /* Complete pre_tunnel action. */ - pre_tun->ipv4_dst = vxlan->key.u.ipv4.dst; + pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst; return 0; } @@ -433,8 +443,8 @@ nfp_flower_loop_action(const struct tc_action *a, struct net_device *netdev, enum nfp_flower_tun_type *tun_type, int *tun_out_cnt) { + struct nfp_fl_set_ipv4_udp_tun *set_tun; struct nfp_fl_pre_tunnel *pre_tun; - struct nfp_fl_set_vxlan *s_vxl; struct nfp_fl_push_vlan *psh_v; struct nfp_fl_pop_vlan *pop_v; struct nfp_fl_output *output; @@ -482,26 +492,29 @@ nfp_flower_loop_action(const struct tc_action *a, nfp_fl_push_vlan(psh_v, a); *a_len += sizeof(struct nfp_fl_push_vlan); - } else if (is_tcf_tunnel_set(a) && nfp_fl_supported_tun_port(a)) { + } else if (is_tcf_tunnel_set(a)) { + struct nfp_repr *repr = netdev_priv(netdev); + *tun_type = nfp_fl_get_tun_from_act_l4_port(repr->app, a); + if (*tun_type == NFP_FL_TUNNEL_NONE) + return -EOPNOTSUPP; + /* Pre-tunnel action is required for tunnel encap. * This checks for next hop entries on NFP. * If none, the packet falls back before applying other actions. */ if (*a_len + sizeof(struct nfp_fl_pre_tunnel) + - sizeof(struct nfp_fl_set_vxlan) > NFP_FL_MAX_A_SIZ) + sizeof(struct nfp_fl_set_ipv4_udp_tun) > NFP_FL_MAX_A_SIZ) return -EOPNOTSUPP; - *tun_type = NFP_FL_TUNNEL_VXLAN; pre_tun = nfp_fl_pre_tunnel(nfp_fl->action_data, *a_len); nfp_fl->meta.shortcut = cpu_to_be32(NFP_FL_SC_ACT_NULL); *a_len += sizeof(struct nfp_fl_pre_tunnel); - s_vxl = (struct nfp_fl_set_vxlan *)&nfp_fl->action_data[*a_len]; - err = nfp_fl_set_vxlan(s_vxl, a, pre_tun); + set_tun = (void *)&nfp_fl->action_data[*a_len]; + err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type); if (err) return err; - - *a_len += sizeof(struct nfp_fl_set_vxlan); + *a_len += sizeof(struct nfp_fl_set_ipv4_udp_tun); } else if (is_tcf_tunnel_release(a)) { /* Tunnel decap is handled by default so accept action. */ return 0; diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index d6b63c8f14da..992d2eec1019 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -41,7 +41,7 @@ #include "../nfp_app.h" #include "../nfpcore/nfp_cpp.h" -#define NFP_FLOWER_LAYER_META BIT(0) +#define NFP_FLOWER_LAYER_EXT_META BIT(0) #define NFP_FLOWER_LAYER_PORT BIT(1) #define NFP_FLOWER_LAYER_MAC BIT(2) #define NFP_FLOWER_LAYER_TP BIT(3) @@ -50,6 +50,8 @@ #define NFP_FLOWER_LAYER_CT BIT(6) #define NFP_FLOWER_LAYER_VXLAN BIT(7) +#define NFP_FLOWER_LAYER2_GENEVE BIT(5) + #define NFP_FLOWER_MASK_VLAN_PRIO GENMASK(15, 13) #define NFP_FLOWER_MASK_VLAN_CFI BIT(12) #define NFP_FLOWER_MASK_VLAN_VID GENMASK(11, 0) @@ -105,6 +107,7 @@ enum nfp_flower_tun_type { NFP_FL_TUNNEL_NONE = 0, NFP_FL_TUNNEL_VXLAN = 2, + NFP_FL_TUNNEL_GENEVE = 4, }; struct nfp_fl_act_head { @@ -170,16 +173,13 @@ struct nfp_fl_pre_tunnel { __be32 extra[3]; }; -struct nfp_fl_set_vxlan { +struct nfp_fl_set_ipv4_udp_tun { struct nfp_fl_act_head head; __be16 reserved; - __be64 tun_id; + __be64 tun_id __packed; __be32 tun_type_index; - __be16 tun_flags; - u8 ipv4_ttl; - u8 ipv4_tos; - __be32 extra[2]; -} __packed; + __be32 extra[3]; +}; /* Metadata with L2 (1W/4B) * ---------------------------------------------------------------- @@ -198,6 +198,18 @@ struct nfp_flower_meta_tci { __be16 tci; }; +/* Extended metadata for additional key_layers (1W/4B) + * ---------------------------------------------------------------- + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | nfp_flow_key_layer2 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct nfp_flower_ext_meta { + __be32 nfp_flow_key_layer2; +}; + /* Port details (1W/4B) * ---------------------------------------------------------------- * 3 2 1 @@ -296,7 +308,7 @@ struct nfp_flower_ipv6 { struct in6_addr ipv6_dst; }; -/* Flow Frame VXLAN --> Tunnel details (4W/16B) +/* Flow Frame IPv4 UDP TUNNEL --> Tunnel details (4W/16B) * ----------------------------------------------------------------- * 3 2 1 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 @@ -305,22 +317,17 @@ struct nfp_flower_ipv6 { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ipv4_addr_dst | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | tun_flags | tos | ttl | + * | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | gpe_flags | Reserved | Next Protocol | + * | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VNI | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -struct nfp_flower_vxlan { +struct nfp_flower_ipv4_udp_tun { __be32 ip_src; __be32 ip_dst; - __be16 tun_flags; - u8 tos; - u8 ttl; - u8 gpe_flags; - u8 reserved[2]; - u8 nxt_proto; + __be32 reserved[2]; __be32 tun_id; }; diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 8fcc90c0d2d3..63160e9754d4 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -381,7 +381,7 @@ static int nfp_flower_init(struct nfp_app *app) { const struct nfp_pf *pf = app->pf; struct nfp_flower_priv *app_priv; - u64 version; + u64 version, features; int err; if (!pf->eth_tbl) { @@ -424,6 +424,14 @@ static int nfp_flower_init(struct nfp_app *app) if (err) goto err_free_app_priv; + /* Extract the extra features supported by the firmware. */ + features = nfp_rtsym_read_le(app->pf->rtbl, + "_abi_flower_extra_features", &err); + if (err) + app_priv->flower_ext_feats = 0; + else + app_priv->flower_ext_feats = features; + return 0; err_free_app_priv: diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index e6b26c5ae6e0..6e3937a0b708 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -34,6 +34,8 @@ #ifndef __NFP_FLOWER_H__ #define __NFP_FLOWER_H__ 1 +#include "cmsg.h" + #include <linux/circ_buf.h> #include <linux/hashtable.h> #include <linux/time64.h> @@ -58,6 +60,10 @@ struct nfp_app; #define NFP_FL_MASK_ID_LOCATION 1 #define NFP_FL_VXLAN_PORT 4789 +#define NFP_FL_GENEVE_PORT 6081 + +/* Extra features bitmap. */ +#define NFP_FL_FEATS_GENEVE BIT(0) struct nfp_fl_mask_id { struct circ_buf mask_id_free_list; @@ -77,6 +83,7 @@ struct nfp_fl_stats_id { * @nn: Pointer to vNIC * @mask_id_seed: Seed used for mask hash table * @flower_version: HW version of flower + * @flower_ext_feats: Bitmap of extra features the HW supports * @stats_ids: List of free stats ids * @mask_ids: List of free mask ids * @mask_table: Hash table used to store masks @@ -101,6 +108,7 @@ struct nfp_flower_priv { struct nfp_net *nn; u32 mask_id_seed; u64 flower_version; + u64 flower_ext_feats; struct nfp_fl_stats_id stats_ids; struct nfp_fl_mask_id mask_ids; DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS); @@ -172,7 +180,8 @@ int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev, int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, struct nfp_fl_key_ls *key_ls, struct net_device *netdev, - struct nfp_fl_payload *nfp_flow); + struct nfp_fl_payload *nfp_flow, + enum nfp_flower_tun_type tun_type); int nfp_flower_compile_action(struct tc_cls_flower_offload *flow, struct net_device *netdev, struct nfp_fl_payload *nfp_flow); diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index 1f2b879e12d4..37c2ecae2a7a 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -67,6 +67,12 @@ nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *frame, } } +static void +nfp_flower_compile_ext_meta(struct nfp_flower_ext_meta *frame, u32 key_ext) +{ + frame->nfp_flow_key_layer2 = cpu_to_be32(key_ext); +} + static int nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port, bool mask_version, enum nfp_flower_tun_type tun_type) @@ -216,16 +222,15 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame, } static void -nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame, - struct tc_cls_flower_offload *flow, - bool mask_version, __be32 *tun_dst) +nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame, + struct tc_cls_flower_offload *flow, + bool mask_version) { struct fl_flow_key *target = mask_version ? flow->mask : flow->key; - struct flow_dissector_key_ipv4_addrs *vxlan_ips; + struct flow_dissector_key_ipv4_addrs *tun_ips; struct flow_dissector_key_keyid *vni; - /* Wildcard TOS/TTL/GPE_FLAGS/NXT_PROTO for now. */ - memset(frame, 0, sizeof(struct nfp_flower_vxlan)); + memset(frame, 0, sizeof(struct nfp_flower_ipv4_udp_tun)); if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) { @@ -240,31 +245,26 @@ nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame, if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) { - vxlan_ips = + tun_ips = skb_flow_dissector_target(flow->dissector, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, target); - frame->ip_src = vxlan_ips->src; - frame->ip_dst = vxlan_ips->dst; - *tun_dst = vxlan_ips->dst; + frame->ip_src = tun_ips->src; + frame->ip_dst = tun_ips->dst; } } int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, struct nfp_fl_key_ls *key_ls, struct net_device *netdev, - struct nfp_fl_payload *nfp_flow) + struct nfp_fl_payload *nfp_flow, + enum nfp_flower_tun_type tun_type) { - enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE; - __be32 tun_dst, tun_dst_mask = 0; struct nfp_repr *netdev_repr; int err; u8 *ext; u8 *msk; - if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) - tun_type = NFP_FL_TUNNEL_VXLAN; - memset(nfp_flow->unmasked_data, 0, key_ls->key_size); memset(nfp_flow->mask_data, 0, key_ls->key_size); @@ -280,6 +280,16 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, ext += sizeof(struct nfp_flower_meta_tci); msk += sizeof(struct nfp_flower_meta_tci); + /* Populate Extended Metadata if Required. */ + if (NFP_FLOWER_LAYER_EXT_META & key_ls->key_layer) { + nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)ext, + key_ls->key_layer_two); + nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)msk, + key_ls->key_layer_two); + ext += sizeof(struct nfp_flower_ext_meta); + msk += sizeof(struct nfp_flower_ext_meta); + } + /* Populate Exact Port data. */ err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext, nfp_repr_get_port_id(netdev), @@ -341,15 +351,17 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, msk += sizeof(struct nfp_flower_ipv6); } - if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) { + if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN || + key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE) { + __be32 tun_dst; + /* Populate Exact VXLAN Data. */ - nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)ext, - flow, false, &tun_dst); + nfp_flower_compile_ipv4_udp_tun((void *)ext, flow, false); /* Populate Mask VXLAN Data. */ - nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)msk, - flow, true, &tun_dst_mask); - ext += sizeof(struct nfp_flower_vxlan); - msk += sizeof(struct nfp_flower_vxlan); + nfp_flower_compile_ipv4_udp_tun((void *)msk, flow, true); + tun_dst = ((struct nfp_flower_ipv4_udp_tun *)ext)->ip_dst; + ext += sizeof(struct nfp_flower_ipv4_udp_tun); + msk += sizeof(struct nfp_flower_ipv4_udp_tun); /* Configure tunnel end point MAC. */ if (nfp_netdev_is_nfp_repr(netdev)) { diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 98fb1cba3ed9..837134a9137c 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -130,12 +130,15 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f) } static int -nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, +nfp_flower_calculate_key_layers(struct nfp_app *app, + struct nfp_fl_key_ls *ret_key_ls, struct tc_cls_flower_offload *flow, - bool egress) + bool egress, + enum nfp_flower_tun_type *tun_type) { struct flow_dissector_key_basic *mask_basic = NULL; struct flow_dissector_key_basic *key_basic = NULL; + struct nfp_flower_priv *priv = app->priv; u32 key_layer_two; u8 key_layer; int key_size; @@ -197,12 +200,27 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, FLOW_DISSECTOR_KEY_ENC_PORTS, flow->key); - if (mask_enc_ports->dst != cpu_to_be16(~0) || - enc_ports->dst != htons(NFP_FL_VXLAN_PORT)) + if (mask_enc_ports->dst != cpu_to_be16(~0)) return -EOPNOTSUPP; - key_layer |= NFP_FLOWER_LAYER_VXLAN; - key_size += sizeof(struct nfp_flower_vxlan); + switch (enc_ports->dst) { + case htons(NFP_FL_VXLAN_PORT): + *tun_type = NFP_FL_TUNNEL_VXLAN; + key_layer |= NFP_FLOWER_LAYER_VXLAN; + key_size += sizeof(struct nfp_flower_ipv4_udp_tun); + break; + case htons(NFP_FL_GENEVE_PORT): + if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE)) + return -EOPNOTSUPP; + *tun_type = NFP_FL_TUNNEL_GENEVE; + key_layer |= NFP_FLOWER_LAYER_EXT_META; + key_size += sizeof(struct nfp_flower_ext_meta); + key_layer_two |= NFP_FLOWER_LAYER2_GENEVE; + key_size += sizeof(struct nfp_flower_ipv4_udp_tun); + break; + default: + return -EOPNOTSUPP; + } } else if (egress) { /* Reject non tunnel matches offloaded to egress repr. */ return -EOPNOTSUPP; @@ -330,6 +348,7 @@ static int nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, struct tc_cls_flower_offload *flow, bool egress) { + enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE; struct nfp_flower_priv *priv = app->priv; struct nfp_fl_payload *flow_pay; struct nfp_fl_key_ls *key_layer; @@ -339,7 +358,8 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, if (!key_layer) return -ENOMEM; - err = nfp_flower_calculate_key_layers(key_layer, flow, egress); + err = nfp_flower_calculate_key_layers(app, key_layer, flow, egress, + &tun_type); if (err) goto err_free_key_ls; @@ -349,7 +369,8 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, goto err_free_key_ls; } - err = nfp_flower_compile_flow_match(flow, key_layer, netdev, flow_pay); + err = nfp_flower_compile_flow_match(flow, key_layer, netdev, flow_pay, + tun_type); if (err) goto err_destroy_flow; diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index cadea673a40f..49d6d789459e 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -824,7 +824,7 @@ struct fe_priv { */ union ring_type get_tx, put_tx, last_tx; struct nv_skb_map *get_tx_ctx, *put_tx_ctx; - struct nv_skb_map *first_tx_ctx, *last_tx_ctx; + struct nv_skb_map *last_tx_ctx; struct nv_skb_map *tx_skb; union ring_type tx_ring; @@ -1939,7 +1939,8 @@ static void nv_init_tx(struct net_device *dev) np->last_tx.orig = &np->tx_ring.orig[np->tx_ring_size-1]; else np->last_tx.ex = &np->tx_ring.ex[np->tx_ring_size-1]; - np->get_tx_ctx = np->put_tx_ctx = np->first_tx_ctx = np->tx_skb; + np->get_tx_ctx = np->tx_skb; + np->put_tx_ctx = np->tx_skb; np->last_tx_ctx = &np->tx_skb[np->tx_ring_size-1]; netdev_reset_queue(np->dev); np->tx_pkts_in_progress = 0; @@ -2251,7 +2252,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(put_tx++ == np->last_tx.orig)) put_tx = np->tx_ring.orig; if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; + np->put_tx_ctx = np->tx_skb; } while (size); /* setup the fragments */ @@ -2277,7 +2278,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) do { nv_unmap_txskb(np, start_tx_ctx); if (unlikely(tmp_tx_ctx++ == np->last_tx_ctx)) - tmp_tx_ctx = np->first_tx_ctx; + tmp_tx_ctx = np->tx_skb; } while (tmp_tx_ctx != np->put_tx_ctx); dev_kfree_skb_any(skb); np->put_tx_ctx = start_tx_ctx; @@ -2297,7 +2298,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(put_tx++ == np->last_tx.orig)) put_tx = np->tx_ring.orig; if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; + np->put_tx_ctx = np->tx_skb; } while (frag_size); } @@ -2306,7 +2307,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) else prev_tx = put_tx - 1; - if (unlikely(np->put_tx_ctx == np->first_tx_ctx)) + if (unlikely(np->put_tx_ctx == np->tx_skb)) prev_tx_ctx = np->last_tx_ctx; else prev_tx_ctx = np->put_tx_ctx - 1; @@ -2409,7 +2410,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, if (unlikely(put_tx++ == np->last_tx.ex)) put_tx = np->tx_ring.ex; if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; + np->put_tx_ctx = np->tx_skb; } while (size); /* setup the fragments */ @@ -2435,7 +2436,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, do { nv_unmap_txskb(np, start_tx_ctx); if (unlikely(tmp_tx_ctx++ == np->last_tx_ctx)) - tmp_tx_ctx = np->first_tx_ctx; + tmp_tx_ctx = np->tx_skb; } while (tmp_tx_ctx != np->put_tx_ctx); dev_kfree_skb_any(skb); np->put_tx_ctx = start_tx_ctx; @@ -2455,7 +2456,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, if (unlikely(put_tx++ == np->last_tx.ex)) put_tx = np->tx_ring.ex; if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; + np->put_tx_ctx = np->tx_skb; } while (frag_size); } @@ -2464,7 +2465,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, else prev_tx = put_tx - 1; - if (unlikely(np->put_tx_ctx == np->first_tx_ctx)) + if (unlikely(np->put_tx_ctx == np->tx_skb)) prev_tx_ctx = np->last_tx_ctx; else prev_tx_ctx = np->put_tx_ctx - 1; @@ -2600,7 +2601,7 @@ static int nv_tx_done(struct net_device *dev, int limit) if (unlikely(np->get_tx.orig++ == np->last_tx.orig)) np->get_tx.orig = np->tx_ring.orig; if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx)) - np->get_tx_ctx = np->first_tx_ctx; + np->get_tx_ctx = np->tx_skb; } netdev_completed_queue(np->dev, tx_work, bytes_compl); @@ -2654,7 +2655,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) if (unlikely(np->get_tx.ex++ == np->last_tx.ex)) np->get_tx.ex = np->tx_ring.ex; if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx)) - np->get_tx_ctx = np->first_tx_ctx; + np->get_tx_ctx = np->tx_skb; } netdev_completed_queue(np->dev, tx_work, bytes_cleaned); diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index c9a55b774935..07a2eb3781b1 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -212,9 +212,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) - != ETH_ALEN) { + if (!mac_pton(maddr, addr)) { dev_warn(&pdev->dev, "can't parse mac address, not configuring\n"); return -EINVAL; diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h index a3a70ade411f..8a336517baac 100644 --- a/drivers/net/ethernet/qlogic/qede/qede.h +++ b/drivers/net/ethernet/qlogic/qede/qede.h @@ -494,6 +494,8 @@ int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid); void qede_vlan_mark_nonconfigured(struct qede_dev *edev); int qede_configure_vlan_filters(struct qede_dev *edev); +netdev_features_t qede_fix_features(struct net_device *dev, + netdev_features_t features); int qede_set_features(struct net_device *dev, netdev_features_t features); void qede_set_rx_mode(struct net_device *ndev); void qede_config_rx_mode(struct net_device *ndev); diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c index dae741270022..4ca3847fffd4 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c @@ -940,6 +940,9 @@ int qede_change_mtu(struct net_device *ndev, int new_mtu) DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), "Configuring MTU size of %d\n", new_mtu); + if (new_mtu > PAGE_SIZE) + ndev->features &= ~NETIF_F_GRO_HW; + /* Set the mtu field and re-start the interface if needed */ args.u.mtu = new_mtu; args.func = &qede_update_mtu; diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index c1a0708a7d7c..77aa826227e5 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -895,19 +895,26 @@ static void qede_set_features_reload(struct qede_dev *edev, edev->ndev->features = args->u.features; } +netdev_features_t qede_fix_features(struct net_device *dev, + netdev_features_t features) +{ + struct qede_dev *edev = netdev_priv(dev); + + if (edev->xdp_prog || edev->ndev->mtu > PAGE_SIZE || + !(features & NETIF_F_GRO)) + features &= ~NETIF_F_GRO_HW; + + return features; +} + int qede_set_features(struct net_device *dev, netdev_features_t features) { struct qede_dev *edev = netdev_priv(dev); netdev_features_t changes = features ^ dev->features; bool need_reload = false; - /* No action needed if hardware GRO is disabled during driver load */ - if (changes & NETIF_F_GRO) { - if (dev->features & NETIF_F_GRO) - need_reload = !edev->gro_disable; - else - need_reload = edev->gro_disable; - } + if (changes & NETIF_F_GRO_HW) + need_reload = true; if (need_reload) { struct qede_reload_args args; diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 57332b3e5e64..90d79ae2a48f 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -545,6 +545,7 @@ static const struct net_device_ops qede_netdev_ops = { #endif .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid, + .ndo_fix_features = qede_fix_features, .ndo_set_features = qede_set_features, .ndo_get_stats64 = qede_get_stats64, #ifdef CONFIG_QED_SRIOV @@ -572,6 +573,7 @@ static const struct net_device_ops qede_netdev_vf_ops = { .ndo_change_mtu = qede_change_mtu, .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid, + .ndo_fix_features = qede_fix_features, .ndo_set_features = qede_set_features, .ndo_get_stats64 = qede_get_stats64, .ndo_udp_tunnel_add = qede_udp_tunnel_add, @@ -589,6 +591,7 @@ static const struct net_device_ops qede_netdev_vf_xdp_ops = { .ndo_change_mtu = qede_change_mtu, .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid, + .ndo_fix_features = qede_fix_features, .ndo_set_features = qede_set_features, .ndo_get_stats64 = qede_get_stats64, .ndo_udp_tunnel_add = qede_udp_tunnel_add, @@ -676,7 +679,7 @@ static void qede_init_ndev(struct qede_dev *edev) ndev->priv_flags |= IFF_UNICAST_FLT; /* user-changeble features */ - hw_features = NETIF_F_GRO | NETIF_F_SG | + hw_features = NETIF_F_GRO | NETIF_F_GRO_HW | NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6; @@ -1228,18 +1231,9 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq) dma_addr_t mapping; int i; - /* Don't perform FW aggregations in case of XDP */ - if (edev->xdp_prog) - edev->gro_disable = 1; - if (edev->gro_disable) return 0; - if (edev->ndev->mtu > PAGE_SIZE) { - edev->gro_disable = 1; - return 0; - } - for (i = 0; i < ETH_TPA_MAX_AGGS_NUM; i++) { struct qede_agg_info *tpa_info = &rxq->tpa_info[i]; struct sw_rx_data *replace_buf = &tpa_info->buffer; @@ -1269,6 +1263,7 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq) err: qede_free_sge_mem(edev, rxq); edev->gro_disable = 1; + edev->ndev->features &= ~NETIF_F_GRO_HW; return -ENOMEM; } @@ -1511,7 +1506,7 @@ static void qede_init_fp(struct qede_dev *edev) edev->ndev->name, queue_id); } - edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO); + edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO_HW); } static int qede_set_real_num_queues(struct qede_dev *edev) diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index 70c92b649b29..38c924bdd32e 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -253,18 +253,18 @@ static int emac_open(struct net_device *netdev) return ret; } - ret = emac_mac_up(adpt); + ret = adpt->phy.open(adpt); if (ret) { emac_mac_rx_tx_rings_free_all(adpt); free_irq(irq->irq, irq); return ret; } - ret = adpt->phy.open(adpt); + ret = emac_mac_up(adpt); if (ret) { - emac_mac_down(adpt); emac_mac_rx_tx_rings_free_all(adpt); free_irq(irq->irq, irq); + adpt->phy.close(adpt); return ret; } diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 1f64c7f60943..8ae467db9162 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -233,7 +233,7 @@ static int efx_ef10_get_vf_index(struct efx_nic *efx) static int efx_ef10_init_datapath_caps(struct efx_nic *efx) { - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V3_OUT_LEN); + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V4_OUT_LEN); struct efx_ef10_nic_data *nic_data = efx->nic_data; size_t outlen; int rc; @@ -306,6 +306,19 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx) efx->vi_stride); } + if (outlen >= MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) { + efx->num_mac_stats = MCDI_WORD(outbuf, + GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS); + netif_dbg(efx, probe, efx->net_dev, + "firmware reports num_mac_stats = %u\n", + efx->num_mac_stats); + } else { + /* leave num_mac_stats as the default value, MC_CMD_MAC_NSTATS */ + netif_dbg(efx, probe, efx->net_dev, + "firmware did not report num_mac_stats, assuming %u\n", + efx->num_mac_stats); + } + return 0; } @@ -1630,6 +1643,29 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { EF10_DMA_STAT(tx_bad, VADAPTER_TX_BAD_PACKETS), EF10_DMA_STAT(tx_bad_bytes, VADAPTER_TX_BAD_BYTES), EF10_DMA_STAT(tx_overflow, VADAPTER_TX_OVERFLOW), + EF10_DMA_STAT(fec_uncorrected_errors, FEC_UNCORRECTED_ERRORS), + EF10_DMA_STAT(fec_corrected_errors, FEC_CORRECTED_ERRORS), + EF10_DMA_STAT(fec_corrected_symbols_lane0, FEC_CORRECTED_SYMBOLS_LANE0), + EF10_DMA_STAT(fec_corrected_symbols_lane1, FEC_CORRECTED_SYMBOLS_LANE1), + EF10_DMA_STAT(fec_corrected_symbols_lane2, FEC_CORRECTED_SYMBOLS_LANE2), + EF10_DMA_STAT(fec_corrected_symbols_lane3, FEC_CORRECTED_SYMBOLS_LANE3), + EF10_DMA_STAT(ctpio_dmabuf_start, CTPIO_DMABUF_START), + EF10_DMA_STAT(ctpio_vi_busy_fallback, CTPIO_VI_BUSY_FALLBACK), + EF10_DMA_STAT(ctpio_long_write_success, CTPIO_LONG_WRITE_SUCCESS), + EF10_DMA_STAT(ctpio_missing_dbell_fail, CTPIO_MISSING_DBELL_FAIL), + EF10_DMA_STAT(ctpio_overflow_fail, CTPIO_OVERFLOW_FAIL), + EF10_DMA_STAT(ctpio_underflow_fail, CTPIO_UNDERFLOW_FAIL), + EF10_DMA_STAT(ctpio_timeout_fail, CTPIO_TIMEOUT_FAIL), + EF10_DMA_STAT(ctpio_noncontig_wr_fail, CTPIO_NONCONTIG_WR_FAIL), + EF10_DMA_STAT(ctpio_frm_clobber_fail, CTPIO_FRM_CLOBBER_FAIL), + EF10_DMA_STAT(ctpio_invalid_wr_fail, CTPIO_INVALID_WR_FAIL), + EF10_DMA_STAT(ctpio_vi_clobber_fallback, CTPIO_VI_CLOBBER_FALLBACK), + EF10_DMA_STAT(ctpio_unqualified_fallback, CTPIO_UNQUALIFIED_FALLBACK), + EF10_DMA_STAT(ctpio_runt_fallback, CTPIO_RUNT_FALLBACK), + EF10_DMA_STAT(ctpio_success, CTPIO_SUCCESS), + EF10_DMA_STAT(ctpio_fallback, CTPIO_FALLBACK), + EF10_DMA_STAT(ctpio_poison, CTPIO_POISON), + EF10_DMA_STAT(ctpio_erase, CTPIO_ERASE), }; #define HUNT_COMMON_STAT_MASK ((1ULL << EF10_STAT_port_tx_bytes) | \ @@ -1705,6 +1741,43 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { (1ULL << EF10_STAT_port_rx_dp_hlb_fetch) | \ (1ULL << EF10_STAT_port_rx_dp_hlb_wait)) +/* These statistics are only provided if the NIC supports MC_CMD_MAC_STATS_V2, + * indicated by returning a value >= MC_CMD_MAC_NSTATS_V2 in + * MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS. + * These bits are in the second u64 of the raw mask. + */ +#define EF10_FEC_STAT_MASK ( \ + (1ULL << (EF10_STAT_fec_uncorrected_errors - 64)) | \ + (1ULL << (EF10_STAT_fec_corrected_errors - 64)) | \ + (1ULL << (EF10_STAT_fec_corrected_symbols_lane0 - 64)) | \ + (1ULL << (EF10_STAT_fec_corrected_symbols_lane1 - 64)) | \ + (1ULL << (EF10_STAT_fec_corrected_symbols_lane2 - 64)) | \ + (1ULL << (EF10_STAT_fec_corrected_symbols_lane3 - 64))) + +/* These statistics are only provided if the NIC supports MC_CMD_MAC_STATS_V3, + * indicated by returning a value >= MC_CMD_MAC_NSTATS_V3 in + * MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS. + * These bits are in the second u64 of the raw mask. + */ +#define EF10_CTPIO_STAT_MASK ( \ + (1ULL << (EF10_STAT_ctpio_dmabuf_start - 64)) | \ + (1ULL << (EF10_STAT_ctpio_vi_busy_fallback - 64)) | \ + (1ULL << (EF10_STAT_ctpio_long_write_success - 64)) | \ + (1ULL << (EF10_STAT_ctpio_missing_dbell_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_overflow_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_underflow_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_timeout_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_noncontig_wr_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_frm_clobber_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_invalid_wr_fail - 64)) | \ + (1ULL << (EF10_STAT_ctpio_vi_clobber_fallback - 64)) | \ + (1ULL << (EF10_STAT_ctpio_unqualified_fallback - 64)) | \ + (1ULL << (EF10_STAT_ctpio_runt_fallback - 64)) | \ + (1ULL << (EF10_STAT_ctpio_success - 64)) | \ + (1ULL << (EF10_STAT_ctpio_fallback - 64)) | \ + (1ULL << (EF10_STAT_ctpio_poison - 64)) | \ + (1ULL << (EF10_STAT_ctpio_erase - 64))) + static u64 efx_ef10_raw_stat_mask(struct efx_nic *efx) { u64 raw_mask = HUNT_COMMON_STAT_MASK; @@ -1743,10 +1816,22 @@ static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask) if (nic_data->datapath_caps & (1 << MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN)) { raw_mask[0] |= ~((1ULL << EF10_STAT_rx_unicast) - 1); - raw_mask[1] = (1ULL << (EF10_STAT_COUNT - 63)) - 1; + raw_mask[1] = (1ULL << (EF10_STAT_V1_COUNT - 64)) - 1; } else { raw_mask[1] = 0; } + /* Only show FEC stats when NIC supports MC_CMD_MAC_STATS_V2 */ + if (efx->num_mac_stats >= MC_CMD_MAC_NSTATS_V2) + raw_mask[1] |= EF10_FEC_STAT_MASK; + + /* CTPIO stats appear in V3. Only show them on devices that actually + * support CTPIO. Although this driver doesn't use CTPIO others might, + * and we may be reporting the stats for the underlying port. + */ + if (efx->num_mac_stats >= MC_CMD_MAC_NSTATS_V3 && + (nic_data->datapath_caps2 & + (1 << MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_LBN))) + raw_mask[1] |= EF10_CTPIO_STAT_MASK; #if BITS_PER_LONG == 64 BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 2); @@ -1850,7 +1935,7 @@ static int efx_ef10_try_update_nic_stats_pf(struct efx_nic *efx) dma_stats = efx->stats_buffer.addr; - generation_end = dma_stats[MC_CMD_MAC_GENERATION_END]; + generation_end = dma_stats[efx->num_mac_stats - 1]; if (generation_end == EFX_MC_STATS_GENERATION_INVALID) return 0; rmb(); @@ -1898,7 +1983,7 @@ static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx) DECLARE_BITMAP(mask, EF10_STAT_COUNT); __le64 generation_start, generation_end; u64 *stats = nic_data->stats; - u32 dma_len = MC_CMD_MAC_NSTATS * sizeof(u64); + u32 dma_len = efx->num_mac_stats * sizeof(u64); struct efx_buffer stats_buf; __le64 *dma_stats; int rc; @@ -1923,7 +2008,7 @@ static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx) } dma_stats = stats_buf.addr; - dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; + dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID; MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, stats_buf.dma_addr); MCDI_POPULATE_DWORD_1(inbuf, MAC_STATS_IN_CMD, @@ -1942,7 +2027,7 @@ static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx) goto out; } - generation_end = dma_stats[MC_CMD_MAC_GENERATION_END]; + generation_end = dma_stats[efx->num_mac_stats - 1]; if (generation_end == EFX_MC_STATS_GENERATION_INVALID) { WARN_ON_ONCE(1); goto out; diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 7bcbedce07a5..3780161de5a1 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -2983,6 +2983,8 @@ static int efx_init_struct(struct efx_nic *efx, efx->type->rx_ts_offset - efx->type->rx_prefix_size; spin_lock_init(&efx->stats_lock); efx->vi_stride = EFX_DEFAULT_VI_STRIDE; + efx->num_mac_stats = MC_CMD_MAC_NSTATS; + BUILD_BUG_ON(MC_CMD_MAC_NSTATS - 1 != MC_CMD_MAC_GENERATION_END); mutex_init(&efx->mac_lock); efx->phy_op = &efx_dummy_phy_operations; efx->mdio.dev = net_dev; diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index 91fb54fd03d9..869d76f8f589 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -114,6 +114,8 @@ #define MCDI_HEADER_XFLAGS_WIDTH 8 /* Request response using event */ #define MCDI_HEADER_XFLAGS_EVREQ 0x01 +/* Request (and signal) early doorbell return */ +#define MCDI_HEADER_XFLAGS_DBRET 0x02 /* Maximum number of payload bytes */ #define MCDI_CTL_SDU_LEN_MAX_V1 0xfc @@ -123,7 +125,7 @@ /* The MC can generate events for two reasons: - * - To complete a shared memory request if XFLAGS_EVREQ was set + * - To advance a shared memory request if XFLAGS_EVREQ was set * - As a notification (link state, i2c event), controlled * via MC_CMD_LOG_CTRL * @@ -279,6 +281,17 @@ /* Returned by MC_CMD_TESTASSERT if the action that should * have caused an assertion failed to do so. */ #define MC_CMD_ERR_UNREACHABLE 0x1016 +/* This command needs to be processed in the background but there were no + * resources to do so. Send it again after a command has completed. */ +#define MC_CMD_ERR_QUEUE_FULL 0x1017 +/* The operation could not be completed because the PCIe link has gone + * away. This error code is never expected to be returned over the TLP + * transport. */ +#define MC_CMD_ERR_NO_PCIE 0x1018 +/* The operation could not be completed because the datapath has gone + * away. This is distinct from MC_CMD_ERR_DATAPATH_DISABLED in that the + * datapath absence may be temporary*/ +#define MC_CMD_ERR_NO_DATAPATH 0x1019 #define MC_CMD_ERR_CODE_OFST 0 @@ -360,6 +373,7 @@ /* enum: Fatal. */ #define MCDI_EVENT_LEVEL_FATAL 0x3 #define MCDI_EVENT_DATA_OFST 0 +#define MCDI_EVENT_DATA_LEN 4 #define MCDI_EVENT_CMDDONE_SEQ_LBN 0 #define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8 #define MCDI_EVENT_CMDDONE_DATALEN_LBN 8 @@ -370,6 +384,8 @@ #define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16 #define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 #define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 +/* enum: Link is down or link speed could not be determined */ +#define MCDI_EVENT_LINKCHANGE_SPEED_UNKNOWN 0x0 /* enum: 100Mbs */ #define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 /* enum: 1Gbs */ @@ -378,6 +394,12 @@ #define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 /* enum: 40Gbs */ #define MCDI_EVENT_LINKCHANGE_SPEED_40G 0x4 +/* enum: 25Gbs */ +#define MCDI_EVENT_LINKCHANGE_SPEED_25G 0x5 +/* enum: 50Gbs */ +#define MCDI_EVENT_LINKCHANGE_SPEED_50G 0x6 +/* enum: 100Gbs */ +#define MCDI_EVENT_LINKCHANGE_SPEED_100G 0x7 #define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 #define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 #define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 @@ -456,8 +478,63 @@ #define MCDI_EVENT_AOE_DDR_ECC_STATUS 0xa /* enum: PTP status update */ #define MCDI_EVENT_AOE_PTP_STATUS 0xb +/* enum: FPGA header incorrect */ +#define MCDI_EVENT_AOE_FPGA_LOAD_HEADER_ERR 0xc +/* enum: FPGA Powered Off due to error in powering up FPGA */ +#define MCDI_EVENT_AOE_FPGA_POWER_OFF 0xd +/* enum: AOE FPGA load failed due to MC to MUM communication failure */ +#define MCDI_EVENT_AOE_FPGA_LOAD_FAILED 0xe +/* enum: Notify that invalid flash type detected */ +#define MCDI_EVENT_AOE_INVALID_FPGA_FLASH_TYPE 0xf +/* enum: Notify that the attempt to run FPGA Controller firmware timedout */ +#define MCDI_EVENT_AOE_FC_RUN_TIMEDOUT 0x10 +/* enum: Failure to probe one or more FPGA boot flash chips */ +#define MCDI_EVENT_AOE_FPGA_BOOT_FLASH_INVALID 0x11 +/* enum: FPGA boot-flash contains an invalid image header */ +#define MCDI_EVENT_AOE_FPGA_BOOT_FLASH_HDR_INVALID 0x12 +/* enum: Failed to program clocks required by the FPGA */ +#define MCDI_EVENT_AOE_FPGA_CLOCKS_PROGRAM_FAILED 0x13 +/* enum: Notify that FPGA Controller is alive to serve MCDI requests */ +#define MCDI_EVENT_AOE_FC_RUNNING 0x14 #define MCDI_EVENT_AOE_ERR_DATA_LBN 8 #define MCDI_EVENT_AOE_ERR_DATA_WIDTH 8 +#define MCDI_EVENT_AOE_ERR_FC_ASSERT_INFO_LBN 8 +#define MCDI_EVENT_AOE_ERR_FC_ASSERT_INFO_WIDTH 8 +/* enum: FC Assert happened, but the register information is not available */ +#define MCDI_EVENT_AOE_ERR_FC_ASSERT_SEEN 0x0 +/* enum: The register information for FC Assert is ready for readinng by driver + */ +#define MCDI_EVENT_AOE_ERR_FC_ASSERT_DATA_READY 0x1 +#define MCDI_EVENT_AOE_ERR_CODE_FPGA_HEADER_VERIFY_FAILED_LBN 8 +#define MCDI_EVENT_AOE_ERR_CODE_FPGA_HEADER_VERIFY_FAILED_WIDTH 8 +/* enum: Reading from NV failed */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_NV_READ_FAIL 0x0 +/* enum: Invalid Magic Number if FPGA header */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_MAGIC_FAIL 0x1 +/* enum: Invalid Silicon type detected in header */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_SILICON_TYPE 0x2 +/* enum: Unsupported VRatio */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_VRATIO 0x3 +/* enum: Unsupported DDR Type */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_TYPE 0x4 +/* enum: DDR Voltage out of supported range */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_VOLTAGE 0x5 +/* enum: Unsupported DDR speed */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_SPEED 0x6 +/* enum: Unsupported DDR size */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_SIZE 0x7 +/* enum: Unsupported DDR rank */ +#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_RANK 0x8 +#define MCDI_EVENT_AOE_ERR_CODE_INVALID_FPGA_FLASH_TYPE_INFO_LBN 8 +#define MCDI_EVENT_AOE_ERR_CODE_INVALID_FPGA_FLASH_TYPE_INFO_WIDTH 8 +/* enum: Primary boot flash */ +#define MCDI_EVENT_AOE_FLASH_TYPE_BOOT_PRIMARY 0x0 +/* enum: Secondary boot flash */ +#define MCDI_EVENT_AOE_FLASH_TYPE_BOOT_SECONDARY 0x1 +#define MCDI_EVENT_AOE_ERR_CODE_FPGA_POWER_OFF_LBN 8 +#define MCDI_EVENT_AOE_ERR_CODE_FPGA_POWER_OFF_WIDTH 8 +#define MCDI_EVENT_AOE_ERR_CODE_FPGA_LOAD_FAILED_LBN 8 +#define MCDI_EVENT_AOE_ERR_CODE_FPGA_LOAD_FAILED_WIDTH 8 #define MCDI_EVENT_RX_ERR_RXQ_LBN 0 #define MCDI_EVENT_RX_ERR_RXQ_WIDTH 12 #define MCDI_EVENT_RX_ERR_TYPE_LBN 12 @@ -480,6 +557,22 @@ #define MCDI_EVENT_MUM_WATCHDOG 0x3 #define MCDI_EVENT_MUM_ERR_DATA_LBN 8 #define MCDI_EVENT_MUM_ERR_DATA_WIDTH 8 +#define MCDI_EVENT_DBRET_SEQ_LBN 0 +#define MCDI_EVENT_DBRET_SEQ_WIDTH 8 +#define MCDI_EVENT_SUC_ERR_TYPE_LBN 0 +#define MCDI_EVENT_SUC_ERR_TYPE_WIDTH 8 +/* enum: Corrupted or bad SUC application. */ +#define MCDI_EVENT_SUC_BAD_APP 0x1 +/* enum: SUC application reported an assert. */ +#define MCDI_EVENT_SUC_ASSERT 0x2 +/* enum: SUC application reported an exception. */ +#define MCDI_EVENT_SUC_EXCEPTION 0x3 +/* enum: SUC watchdog timer expired. */ +#define MCDI_EVENT_SUC_WATCHDOG 0x4 +#define MCDI_EVENT_SUC_ERR_ADDRESS_LBN 8 +#define MCDI_EVENT_SUC_ERR_ADDRESS_WIDTH 24 +#define MCDI_EVENT_SUC_ERR_DATA_LBN 8 +#define MCDI_EVENT_SUC_ERR_DATA_WIDTH 24 #define MCDI_EVENT_DATA_LBN 0 #define MCDI_EVENT_DATA_WIDTH 32 #define MCDI_EVENT_SRC_LBN 36 @@ -552,73 +645,99 @@ * been processed and it may now resend the command */ #define MCDI_EVENT_CODE_PROXY_RESPONSE 0x1d +/* enum: MCDI command accepted. New commands can be issued but this command is + * not done yet. + */ +#define MCDI_EVENT_CODE_DBRET 0x1e +/* enum: The MC has detected a fault on the SUC */ +#define MCDI_EVENT_CODE_SUC 0x1f /* enum: Artificial event generated by host and posted via MC for test * purposes. */ #define MCDI_EVENT_CODE_TESTGEN 0xfa #define MCDI_EVENT_CMDDONE_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_DATA_LEN 4 #define MCDI_EVENT_CMDDONE_DATA_LBN 0 #define MCDI_EVENT_CMDDONE_DATA_WIDTH 32 #define MCDI_EVENT_LINKCHANGE_DATA_OFST 0 +#define MCDI_EVENT_LINKCHANGE_DATA_LEN 4 #define MCDI_EVENT_LINKCHANGE_DATA_LBN 0 #define MCDI_EVENT_LINKCHANGE_DATA_WIDTH 32 #define MCDI_EVENT_SENSOREVT_DATA_OFST 0 +#define MCDI_EVENT_SENSOREVT_DATA_LEN 4 #define MCDI_EVENT_SENSOREVT_DATA_LBN 0 #define MCDI_EVENT_SENSOREVT_DATA_WIDTH 32 #define MCDI_EVENT_MAC_STATS_DMA_GENERATION_OFST 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LEN 4 #define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0 #define MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32 #define MCDI_EVENT_TX_ERR_DATA_OFST 0 +#define MCDI_EVENT_TX_ERR_DATA_LEN 4 #define MCDI_EVENT_TX_ERR_DATA_LBN 0 #define MCDI_EVENT_TX_ERR_DATA_WIDTH 32 /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the seconds field of * timestamp */ #define MCDI_EVENT_PTP_SECONDS_OFST 0 +#define MCDI_EVENT_PTP_SECONDS_LEN 4 #define MCDI_EVENT_PTP_SECONDS_LBN 0 #define MCDI_EVENT_PTP_SECONDS_WIDTH 32 /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the major field of * timestamp */ #define MCDI_EVENT_PTP_MAJOR_OFST 0 +#define MCDI_EVENT_PTP_MAJOR_LEN 4 #define MCDI_EVENT_PTP_MAJOR_LBN 0 #define MCDI_EVENT_PTP_MAJOR_WIDTH 32 /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the nanoseconds field * of timestamp */ #define MCDI_EVENT_PTP_NANOSECONDS_OFST 0 +#define MCDI_EVENT_PTP_NANOSECONDS_LEN 4 #define MCDI_EVENT_PTP_NANOSECONDS_LBN 0 #define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32 /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the minor field of * timestamp */ #define MCDI_EVENT_PTP_MINOR_OFST 0 +#define MCDI_EVENT_PTP_MINOR_LEN 4 #define MCDI_EVENT_PTP_MINOR_LBN 0 #define MCDI_EVENT_PTP_MINOR_WIDTH 32 /* For CODE_PTP_RX events, the lowest four bytes of sourceUUID from PTP packet */ #define MCDI_EVENT_PTP_UUID_OFST 0 +#define MCDI_EVENT_PTP_UUID_LEN 4 #define MCDI_EVENT_PTP_UUID_LBN 0 #define MCDI_EVENT_PTP_UUID_WIDTH 32 #define MCDI_EVENT_RX_ERR_DATA_OFST 0 +#define MCDI_EVENT_RX_ERR_DATA_LEN 4 #define MCDI_EVENT_RX_ERR_DATA_LBN 0 #define MCDI_EVENT_RX_ERR_DATA_WIDTH 32 #define MCDI_EVENT_PAR_ERR_DATA_OFST 0 +#define MCDI_EVENT_PAR_ERR_DATA_LEN 4 #define MCDI_EVENT_PAR_ERR_DATA_LBN 0 #define MCDI_EVENT_PAR_ERR_DATA_WIDTH 32 #define MCDI_EVENT_ECC_CORR_ERR_DATA_OFST 0 +#define MCDI_EVENT_ECC_CORR_ERR_DATA_LEN 4 #define MCDI_EVENT_ECC_CORR_ERR_DATA_LBN 0 #define MCDI_EVENT_ECC_CORR_ERR_DATA_WIDTH 32 #define MCDI_EVENT_ECC_FATAL_ERR_DATA_OFST 0 +#define MCDI_EVENT_ECC_FATAL_ERR_DATA_LEN 4 #define MCDI_EVENT_ECC_FATAL_ERR_DATA_LBN 0 #define MCDI_EVENT_ECC_FATAL_ERR_DATA_WIDTH 32 /* For CODE_PTP_TIME events, the major value of the PTP clock */ #define MCDI_EVENT_PTP_TIME_MAJOR_OFST 0 +#define MCDI_EVENT_PTP_TIME_MAJOR_LEN 4 #define MCDI_EVENT_PTP_TIME_MAJOR_LBN 0 #define MCDI_EVENT_PTP_TIME_MAJOR_WIDTH 32 /* For CODE_PTP_TIME events, bits 19-26 of the minor value of the PTP clock */ #define MCDI_EVENT_PTP_TIME_MINOR_26_19_LBN 36 #define MCDI_EVENT_PTP_TIME_MINOR_26_19_WIDTH 8 +/* For CODE_PTP_TIME events, most significant bits of the minor value of the + * PTP clock. This is a more generic equivalent of PTP_TIME_MINOR_26_19. + */ +#define MCDI_EVENT_PTP_TIME_MINOR_MS_8BITS_LBN 36 +#define MCDI_EVENT_PTP_TIME_MINOR_MS_8BITS_WIDTH 8 /* For CODE_PTP_TIME events where report sync status is enabled, indicates * whether the NIC clock has ever been set */ @@ -634,10 +753,17 @@ */ #define MCDI_EVENT_PTP_TIME_MINOR_26_21_LBN 38 #define MCDI_EVENT_PTP_TIME_MINOR_26_21_WIDTH 6 +/* For CODE_PTP_TIME events, most significant bits of the minor value of the + * PTP clock. This is a more generic equivalent of PTP_TIME_MINOR_26_21. + */ +#define MCDI_EVENT_PTP_TIME_MINOR_MS_6BITS_LBN 38 +#define MCDI_EVENT_PTP_TIME_MINOR_MS_6BITS_WIDTH 6 #define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_OFST 0 +#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_LEN 4 #define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_LBN 0 #define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_WIDTH 32 #define MCDI_EVENT_PROXY_RESPONSE_HANDLE_OFST 0 +#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_LEN 4 #define MCDI_EVENT_PROXY_RESPONSE_HANDLE_LBN 0 #define MCDI_EVENT_PROXY_RESPONSE_HANDLE_WIDTH 32 /* Zero means that the request has been completed or authorized, and the driver @@ -646,6 +772,10 @@ */ #define MCDI_EVENT_PROXY_RESPONSE_RC_LBN 36 #define MCDI_EVENT_PROXY_RESPONSE_RC_WIDTH 8 +#define MCDI_EVENT_DBRET_DATA_OFST 0 +#define MCDI_EVENT_DBRET_DATA_LEN 4 +#define MCDI_EVENT_DBRET_DATA_LBN 0 +#define MCDI_EVENT_DBRET_DATA_WIDTH 32 /* FCDI_EVENT structuredef */ #define FCDI_EVENT_LEN 8 @@ -662,6 +792,7 @@ /* enum: Fatal. */ #define FCDI_EVENT_LEVEL_FATAL 0x3 #define FCDI_EVENT_DATA_OFST 0 +#define FCDI_EVENT_DATA_LEN 4 #define FCDI_EVENT_LINK_STATE_STATUS_LBN 0 #define FCDI_EVENT_LINK_STATE_STATUS_WIDTH 1 #define FCDI_EVENT_LINK_DOWN 0x0 /* enum */ @@ -701,6 +832,7 @@ #define FCDI_EVENT_REBOOT_FC_FW 0x0 /* enum */ #define FCDI_EVENT_REBOOT_FC_BOOTLOADER 0x1 /* enum */ #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_OFST 0 +#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_LEN 4 #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_LBN 0 #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_WIDTH 32 #define FCDI_EVENT_ASSERT_TYPE_LBN 36 @@ -708,12 +840,15 @@ #define FCDI_EVENT_DDR_TEST_RESULT_STATUS_CODE_LBN 36 #define FCDI_EVENT_DDR_TEST_RESULT_STATUS_CODE_WIDTH 8 #define FCDI_EVENT_DDR_TEST_RESULT_RESULT_OFST 0 +#define FCDI_EVENT_DDR_TEST_RESULT_RESULT_LEN 4 #define FCDI_EVENT_DDR_TEST_RESULT_RESULT_LBN 0 #define FCDI_EVENT_DDR_TEST_RESULT_RESULT_WIDTH 32 #define FCDI_EVENT_LINK_STATE_DATA_OFST 0 +#define FCDI_EVENT_LINK_STATE_DATA_LEN 4 #define FCDI_EVENT_LINK_STATE_DATA_LBN 0 #define FCDI_EVENT_LINK_STATE_DATA_WIDTH 32 #define FCDI_EVENT_PTP_STATE_OFST 0 +#define FCDI_EVENT_PTP_STATE_LEN 4 #define FCDI_EVENT_PTP_UNDEFINED 0x0 /* enum */ #define FCDI_EVENT_PTP_SETUP_FAILED 0x1 /* enum */ #define FCDI_EVENT_PTP_OPERATIONAL 0x2 /* enum */ @@ -722,6 +857,7 @@ #define FCDI_EVENT_DDR_ECC_STATUS_BANK_ID_LBN 36 #define FCDI_EVENT_DDR_ECC_STATUS_BANK_ID_WIDTH 8 #define FCDI_EVENT_DDR_ECC_STATUS_STATUS_OFST 0 +#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_LEN 4 #define FCDI_EVENT_DDR_ECC_STATUS_STATUS_LBN 0 #define FCDI_EVENT_DDR_ECC_STATUS_STATUS_WIDTH 32 /* Index of MC port being referred to */ @@ -729,9 +865,11 @@ #define FCDI_EVENT_PORT_CONFIG_SRC_WIDTH 8 /* FC Port index that matches the MC port index in SRC */ #define FCDI_EVENT_PORT_CONFIG_DATA_OFST 0 +#define FCDI_EVENT_PORT_CONFIG_DATA_LEN 4 #define FCDI_EVENT_PORT_CONFIG_DATA_LBN 0 #define FCDI_EVENT_PORT_CONFIG_DATA_WIDTH 32 #define FCDI_EVENT_BOOT_RESULT_OFST 0 +#define FCDI_EVENT_BOOT_RESULT_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_AOE/MC_CMD_AOE_OUT_INFO/FC_BOOT_RESULT */ #define FCDI_EVENT_BOOT_RESULT_LBN 0 @@ -748,14 +886,17 @@ #define FCDI_EXTENDED_EVENT_PPS_LEN(num) (8+8*(num)) /* Number of timestamps following */ #define FCDI_EXTENDED_EVENT_PPS_COUNT_OFST 0 +#define FCDI_EXTENDED_EVENT_PPS_COUNT_LEN 4 #define FCDI_EXTENDED_EVENT_PPS_COUNT_LBN 0 #define FCDI_EXTENDED_EVENT_PPS_COUNT_WIDTH 32 /* Seconds field of a timestamp record */ #define FCDI_EXTENDED_EVENT_PPS_SECONDS_OFST 8 +#define FCDI_EXTENDED_EVENT_PPS_SECONDS_LEN 4 #define FCDI_EXTENDED_EVENT_PPS_SECONDS_LBN 64 #define FCDI_EXTENDED_EVENT_PPS_SECONDS_WIDTH 32 /* Nanoseconds field of a timestamp record */ #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_OFST 12 +#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_LEN 4 #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_LBN 96 #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_WIDTH 32 /* Timestamp records comprising the event */ @@ -783,6 +924,7 @@ /* enum: Fatal. */ #define MUM_EVENT_LEVEL_FATAL 0x3 #define MUM_EVENT_DATA_OFST 0 +#define MUM_EVENT_DATA_LEN 4 #define MUM_EVENT_SENSOR_ID_LBN 0 #define MUM_EVENT_SENSOR_ID_WIDTH 8 /* Enum values, see field(s): */ @@ -820,18 +962,23 @@ /* enum: Link fault has been asserted, or has cleared. */ #define MUM_EVENT_CODE_QSFP_LASI_INTERRUPT 0x4 #define MUM_EVENT_SENSOR_DATA_OFST 0 +#define MUM_EVENT_SENSOR_DATA_LEN 4 #define MUM_EVENT_SENSOR_DATA_LBN 0 #define MUM_EVENT_SENSOR_DATA_WIDTH 32 #define MUM_EVENT_PORT_PHY_FLAGS_OFST 0 +#define MUM_EVENT_PORT_PHY_FLAGS_LEN 4 #define MUM_EVENT_PORT_PHY_FLAGS_LBN 0 #define MUM_EVENT_PORT_PHY_FLAGS_WIDTH 32 #define MUM_EVENT_PORT_PHY_COPPER_LEN_OFST 0 +#define MUM_EVENT_PORT_PHY_COPPER_LEN_LEN 4 #define MUM_EVENT_PORT_PHY_COPPER_LEN_LBN 0 #define MUM_EVENT_PORT_PHY_COPPER_LEN_WIDTH 32 #define MUM_EVENT_PORT_PHY_CAPS_OFST 0 +#define MUM_EVENT_PORT_PHY_CAPS_LEN 4 #define MUM_EVENT_PORT_PHY_CAPS_LBN 0 #define MUM_EVENT_PORT_PHY_CAPS_WIDTH 32 #define MUM_EVENT_PORT_PHY_TECH_OFST 0 +#define MUM_EVENT_PORT_PHY_TECH_LEN 4 #define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_UNKNOWN 0x0 /* enum */ #define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_OPTICAL 0x1 /* enum */ #define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_PASSIVE 0x2 /* enum */ @@ -864,7 +1011,9 @@ /* MC_CMD_READ32_IN msgrequest */ #define MC_CMD_READ32_IN_LEN 8 #define MC_CMD_READ32_IN_ADDR_OFST 0 +#define MC_CMD_READ32_IN_ADDR_LEN 4 #define MC_CMD_READ32_IN_NUMWORDS_OFST 4 +#define MC_CMD_READ32_IN_NUMWORDS_LEN 4 /* MC_CMD_READ32_OUT msgresponse */ #define MC_CMD_READ32_OUT_LENMIN 4 @@ -882,13 +1031,14 @@ */ #define MC_CMD_WRITE32 0x2 -#define MC_CMD_0x2_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x2_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_WRITE32_IN msgrequest */ #define MC_CMD_WRITE32_IN_LENMIN 8 #define MC_CMD_WRITE32_IN_LENMAX 252 #define MC_CMD_WRITE32_IN_LEN(num) (4+4*(num)) #define MC_CMD_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_WRITE32_IN_ADDR_LEN 4 #define MC_CMD_WRITE32_IN_BUFFER_OFST 4 #define MC_CMD_WRITE32_IN_BUFFER_LEN 4 #define MC_CMD_WRITE32_IN_BUFFER_MINNUM 1 @@ -915,6 +1065,7 @@ * is a bitfield, with each bit as documented below. */ #define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 +#define MC_CMD_COPYCODE_IN_SRC_ADDR_LEN 4 /* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT (see below) */ #define MC_CMD_COPYCODE_HUNT_NO_MAGIC_ADDR 0x10000 /* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT and @@ -940,9 +1091,12 @@ #define MC_CMD_COPYCODE_IN_BOOT_MAGIC_DISABLE_XIP_WIDTH 1 /* Destination address */ #define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4 +#define MC_CMD_COPYCODE_IN_DEST_ADDR_LEN 4 #define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8 +#define MC_CMD_COPYCODE_IN_NUMWORDS_LEN 4 /* Address of where to jump after copy. */ #define MC_CMD_COPYCODE_IN_JUMP_OFST 12 +#define MC_CMD_COPYCODE_IN_JUMP_LEN 4 /* enum: Control should return to the caller rather than jumping */ #define MC_CMD_COPYCODE_JUMP_NONE 0x1 @@ -956,12 +1110,13 @@ */ #define MC_CMD_SET_FUNC 0x4 -#define MC_CMD_0x4_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x4_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_SET_FUNC_IN msgrequest */ #define MC_CMD_SET_FUNC_IN_LEN 4 /* Set function */ #define MC_CMD_SET_FUNC_IN_FUNC_OFST 0 +#define MC_CMD_SET_FUNC_IN_FUNC_LEN 4 /* MC_CMD_SET_FUNC_OUT msgresponse */ #define MC_CMD_SET_FUNC_OUT_LEN 0 @@ -973,7 +1128,7 @@ */ #define MC_CMD_GET_BOOT_STATUS 0x5 -#define MC_CMD_0x5_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x5_PRIVILEGE_CTG SRIOV_CTG_GENERAL /* MC_CMD_GET_BOOT_STATUS_IN msgrequest */ #define MC_CMD_GET_BOOT_STATUS_IN_LEN 0 @@ -982,9 +1137,11 @@ #define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8 /* ?? */ #define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_LEN 4 /* enum: indicates that the MC wasn't flash booted */ #define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_NULL 0xdeadbeef #define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_LEN 4 #define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0 #define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1 #define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_LBN 1 @@ -1007,11 +1164,13 @@ #define MC_CMD_GET_ASSERTS_IN_LEN 4 /* Set to clear assertion */ #define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0 +#define MC_CMD_GET_ASSERTS_IN_CLEAR_LEN 4 /* MC_CMD_GET_ASSERTS_OUT msgresponse */ #define MC_CMD_GET_ASSERTS_OUT_LEN 140 /* Assertion status flag. */ #define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0 +#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_LEN 4 /* enum: No assertions have failed. */ #define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum: A system-level assertion has failed. */ @@ -1024,6 +1183,7 @@ #define MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP 0x5 /* Failing PC value */ #define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4 +#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_LEN 4 /* Saved GP regs */ #define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8 #define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4 @@ -1034,7 +1194,9 @@ #define MC_CMD_GET_ASSERTS_REG_NO_DATA 0xda7a1057 /* Failing thread address */ #define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132 +#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_LEN 4 #define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136 +#define MC_CMD_GET_ASSERTS_OUT_RESERVED_LEN 4 /***********************************/ @@ -1050,12 +1212,14 @@ #define MC_CMD_LOG_CTRL_IN_LEN 8 /* Log destination */ #define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_LEN 4 /* enum: UART. */ #define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum: Event queue. */ #define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* Legacy argument. Must be zero. */ #define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_LEN 4 /* MC_CMD_LOG_CTRL_OUT msgresponse */ #define MC_CMD_LOG_CTRL_OUT_LEN 0 @@ -1076,23 +1240,29 @@ #define MC_CMD_GET_VERSION_EXT_IN_LEN 4 /* placeholder, set to 0 */ #define MC_CMD_GET_VERSION_EXT_IN_EXT_FLAGS_OFST 0 +#define MC_CMD_GET_VERSION_EXT_IN_EXT_FLAGS_LEN 4 /* MC_CMD_GET_VERSION_V0_OUT msgresponse: deprecated version format */ #define MC_CMD_GET_VERSION_V0_OUT_LEN 4 #define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_LEN 4 /* enum: Reserved version number to indicate "any" version. */ #define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum: Bootrom version value for Siena. */ #define MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM 0xb0070000 /* enum: Bootrom version value for Huntington. */ #define MC_CMD_GET_VERSION_OUT_FIRMWARE_HUNT_BOOTROM 0xb0070001 +/* enum: Bootrom version value for Medford2. */ +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_MEDFORD2_BOOTROM 0xb0070002 /* MC_CMD_GET_VERSION_OUT msgresponse */ #define MC_CMD_GET_VERSION_OUT_LEN 32 /* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */ +/* MC_CMD_GET_VERSION_OUT_FIRMWARE_LEN 4 */ /* Enum values, see field(s): */ /* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */ #define MC_CMD_GET_VERSION_OUT_PCOL_OFST 4 +#define MC_CMD_GET_VERSION_OUT_PCOL_LEN 4 /* 128bit mask of functions supported by the current firmware */ #define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8 #define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16 @@ -1104,9 +1274,11 @@ /* MC_CMD_GET_VERSION_EXT_OUT msgresponse */ #define MC_CMD_GET_VERSION_EXT_OUT_LEN 48 /* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */ +/* MC_CMD_GET_VERSION_OUT_FIRMWARE_LEN 4 */ /* Enum values, see field(s): */ /* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */ #define MC_CMD_GET_VERSION_EXT_OUT_PCOL_OFST 4 +#define MC_CMD_GET_VERSION_EXT_OUT_PCOL_LEN 4 /* 128bit mask of functions supported by the current firmware */ #define MC_CMD_GET_VERSION_EXT_OUT_SUPPORTED_FUNCS_OFST 8 #define MC_CMD_GET_VERSION_EXT_OUT_SUPPORTED_FUNCS_LEN 16 @@ -1136,41 +1308,54 @@ #define MC_CMD_PTP_OP_ENABLE 0x1 /* enum: Disable PTP packet timestamping operation. */ #define MC_CMD_PTP_OP_DISABLE 0x2 -/* enum: Send a PTP packet. */ +/* enum: Send a PTP packet. This operation is used on Siena and Huntington. + * From Medford onwards it is not supported: on those platforms PTP transmit + * timestamping is done using the fast path. + */ #define MC_CMD_PTP_OP_TRANSMIT 0x3 /* enum: Read the current NIC time. */ #define MC_CMD_PTP_OP_READ_NIC_TIME 0x4 -/* enum: Get the current PTP status. */ +/* enum: Get the current PTP status. Note that the clock frequency returned (in + * Hz) is rounded to the nearest MHz (e.g. 666000000 for 666666666). + */ #define MC_CMD_PTP_OP_STATUS 0x5 /* enum: Adjust the PTP NIC's time. */ #define MC_CMD_PTP_OP_ADJUST 0x6 /* enum: Synchronize host and NIC time. */ #define MC_CMD_PTP_OP_SYNCHRONIZE 0x7 -/* enum: Basic manufacturing tests. */ +/* enum: Basic manufacturing tests. Siena PTP adapters only. */ #define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8 -/* enum: Packet based manufacturing tests. */ +/* enum: Packet based manufacturing tests. Siena PTP adapters only. */ #define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9 /* enum: Reset some of the PTP related statistics */ #define MC_CMD_PTP_OP_RESET_STATS 0xa /* enum: Debug operations to MC. */ #define MC_CMD_PTP_OP_DEBUG 0xb -/* enum: Read an FPGA register */ +/* enum: Read an FPGA register. Siena PTP adapters only. */ #define MC_CMD_PTP_OP_FPGAREAD 0xc -/* enum: Write an FPGA register */ +/* enum: Write an FPGA register. Siena PTP adapters only. */ #define MC_CMD_PTP_OP_FPGAWRITE 0xd /* enum: Apply an offset to the NIC clock */ #define MC_CMD_PTP_OP_CLOCK_OFFSET_ADJUST 0xe -/* enum: Change Apply an offset to the NIC clock */ +/* enum: Change the frequency correction applied to the NIC clock */ #define MC_CMD_PTP_OP_CLOCK_FREQ_ADJUST 0xf -/* enum: Set the MC packet filter VLAN tags for received PTP packets */ +/* enum: Set the MC packet filter VLAN tags for received PTP packets. + * Deprecated for Huntington onwards. + */ #define MC_CMD_PTP_OP_RX_SET_VLAN_FILTER 0x10 -/* enum: Set the MC packet filter UUID for received PTP packets */ +/* enum: Set the MC packet filter UUID for received PTP packets. Deprecated for + * Huntington onwards. + */ #define MC_CMD_PTP_OP_RX_SET_UUID_FILTER 0x11 -/* enum: Set the MC packet filter Domain for received PTP packets */ +/* enum: Set the MC packet filter Domain for received PTP packets. Deprecated + * for Huntington onwards. + */ #define MC_CMD_PTP_OP_RX_SET_DOMAIN_FILTER 0x12 -/* enum: Set the clock source */ +/* enum: Set the clock source. Required for snapper tests on Huntington and + * Medford. Not implemented for Siena or Medford2. + */ #define MC_CMD_PTP_OP_SET_CLK_SRC 0x13 -/* enum: Reset value of Timer Reg. */ +/* enum: Reset value of Timer Reg. Not implemented. */ #define MC_CMD_PTP_OP_RST_CLK 0x14 /* enum: Enable the forwarding of PPS events to the host */ #define MC_CMD_PTP_OP_PPS_ENABLE 0x15 @@ -1191,7 +1376,7 @@ /* enum: Unsubscribe to stop receiving time events */ #define MC_CMD_PTP_OP_TIME_EVENT_UNSUBSCRIBE 0x19 /* enum: PPS based manfacturing tests. Requires PPS output to be looped to PPS - * input on the same NIC. + * input on the same NIC. Siena PTP adapters only. */ #define MC_CMD_PTP_OP_MANFTEST_PPS 0x1a /* enum: Set the PTP sync status. Status is used by firmware to report to event @@ -1204,11 +1389,15 @@ /* MC_CMD_PTP_IN_ENABLE msgrequest */ #define MC_CMD_PTP_IN_ENABLE_LEN 16 #define MC_CMD_PTP_IN_CMD_OFST 0 +#define MC_CMD_PTP_IN_CMD_LEN 4 #define MC_CMD_PTP_IN_PERIPH_ID_OFST 4 -/* Event queue for PTP events */ +#define MC_CMD_PTP_IN_PERIPH_ID_LEN 4 +/* Not used. Events are always sent to function relative queue 0. */ #define MC_CMD_PTP_IN_ENABLE_QUEUE_OFST 8 -/* PTP timestamping mode */ +#define MC_CMD_PTP_IN_ENABLE_QUEUE_LEN 4 +/* PTP timestamping mode. Not used from Huntington onwards. */ #define MC_CMD_PTP_IN_ENABLE_MODE_OFST 12 +#define MC_CMD_PTP_IN_ENABLE_MODE_LEN 4 /* enum: PTP, version 1 */ #define MC_CMD_PTP_MODE_V1 0x0 /* enum: PTP, version 1, with VLAN headers - deprecated */ @@ -1225,16 +1414,21 @@ /* MC_CMD_PTP_IN_DISABLE msgrequest */ #define MC_CMD_PTP_IN_DISABLE_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_TRANSMIT msgrequest */ #define MC_CMD_PTP_IN_TRANSMIT_LENMIN 13 #define MC_CMD_PTP_IN_TRANSMIT_LENMAX 252 #define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num)) /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Transmit packet length */ #define MC_CMD_PTP_IN_TRANSMIT_LENGTH_OFST 8 +#define MC_CMD_PTP_IN_TRANSMIT_LENGTH_LEN 4 /* Transmit packet data */ #define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12 #define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1 @@ -1244,17 +1438,30 @@ /* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */ #define MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ + +/* MC_CMD_PTP_IN_READ_NIC_TIME_V2 msgrequest */ +#define MC_CMD_PTP_IN_READ_NIC_TIME_V2_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_STATUS msgrequest */ #define MC_CMD_PTP_IN_STATUS_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_ADJUST msgrequest */ #define MC_CMD_PTP_IN_ADJUST_LEN 24 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Frequency adjustment 40 bit fixed point ns */ #define MC_CMD_PTP_IN_ADJUST_FREQ_OFST 8 #define MC_CMD_PTP_IN_ADJUST_FREQ_LEN 8 @@ -1262,21 +1469,67 @@ #define MC_CMD_PTP_IN_ADJUST_FREQ_HI_OFST 12 /* enum: Number of fractional bits in frequency adjustment */ #define MC_CMD_PTP_IN_ADJUST_BITS 0x28 +/* enum: Number of fractional bits in frequency adjustment when FP44_FREQ_ADJ + * is indicated in the MC_CMD_PTP_OUT_GET_ATTRIBUTES command CAPABILITIES + * field. + */ +#define MC_CMD_PTP_IN_ADJUST_BITS_FP44 0x2c /* Time adjustment in seconds */ #define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16 +#define MC_CMD_PTP_IN_ADJUST_SECONDS_LEN 4 /* Time adjustment major value */ #define MC_CMD_PTP_IN_ADJUST_MAJOR_OFST 16 +#define MC_CMD_PTP_IN_ADJUST_MAJOR_LEN 4 /* Time adjustment in nanoseconds */ #define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20 +#define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_LEN 4 /* Time adjustment minor value */ #define MC_CMD_PTP_IN_ADJUST_MINOR_OFST 20 +#define MC_CMD_PTP_IN_ADJUST_MINOR_LEN 4 + +/* MC_CMD_PTP_IN_ADJUST_V2 msgrequest */ +#define MC_CMD_PTP_IN_ADJUST_V2_LEN 28 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ +/* Frequency adjustment 40 bit fixed point ns */ +#define MC_CMD_PTP_IN_ADJUST_V2_FREQ_OFST 8 +#define MC_CMD_PTP_IN_ADJUST_V2_FREQ_LEN 8 +#define MC_CMD_PTP_IN_ADJUST_V2_FREQ_LO_OFST 8 +#define MC_CMD_PTP_IN_ADJUST_V2_FREQ_HI_OFST 12 +/* enum: Number of fractional bits in frequency adjustment */ +/* MC_CMD_PTP_IN_ADJUST_BITS 0x28 */ +/* enum: Number of fractional bits in frequency adjustment when FP44_FREQ_ADJ + * is indicated in the MC_CMD_PTP_OUT_GET_ATTRIBUTES command CAPABILITIES + * field. + */ +/* MC_CMD_PTP_IN_ADJUST_BITS_FP44 0x2c */ +/* Time adjustment in seconds */ +#define MC_CMD_PTP_IN_ADJUST_V2_SECONDS_OFST 16 +#define MC_CMD_PTP_IN_ADJUST_V2_SECONDS_LEN 4 +/* Time adjustment major value */ +#define MC_CMD_PTP_IN_ADJUST_V2_MAJOR_OFST 16 +#define MC_CMD_PTP_IN_ADJUST_V2_MAJOR_LEN 4 +/* Time adjustment in nanoseconds */ +#define MC_CMD_PTP_IN_ADJUST_V2_NANOSECONDS_OFST 20 +#define MC_CMD_PTP_IN_ADJUST_V2_NANOSECONDS_LEN 4 +/* Time adjustment minor value */ +#define MC_CMD_PTP_IN_ADJUST_V2_MINOR_OFST 20 +#define MC_CMD_PTP_IN_ADJUST_V2_MINOR_LEN 4 +/* Upper 32bits of major time offset adjustment */ +#define MC_CMD_PTP_IN_ADJUST_V2_MAJOR_HI_OFST 24 +#define MC_CMD_PTP_IN_ADJUST_V2_MAJOR_HI_LEN 4 /* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */ #define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Number of time readings to capture */ #define MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_OFST 8 +#define MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_LEN 4 /* Host address in which to write "synchronization started" indication (64 * bits) */ @@ -1288,42 +1541,59 @@ /* MC_CMD_PTP_IN_MANFTEST_BASIC msgrequest */ #define MC_CMD_PTP_IN_MANFTEST_BASIC_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_MANFTEST_PACKET msgrequest */ #define MC_CMD_PTP_IN_MANFTEST_PACKET_LEN 12 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Enable or disable packet testing */ #define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8 +#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_LEN 4 /* MC_CMD_PTP_IN_RESET_STATS msgrequest */ #define MC_CMD_PTP_IN_RESET_STATS_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* Reset PTP statistics */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_DEBUG msgrequest */ #define MC_CMD_PTP_IN_DEBUG_LEN 12 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Debug operations */ #define MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_OFST 8 +#define MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_LEN 4 /* MC_CMD_PTP_IN_FPGAREAD msgrequest */ #define MC_CMD_PTP_IN_FPGAREAD_LEN 16 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ #define MC_CMD_PTP_IN_FPGAREAD_ADDR_OFST 8 +#define MC_CMD_PTP_IN_FPGAREAD_ADDR_LEN 4 #define MC_CMD_PTP_IN_FPGAREAD_NUMBYTES_OFST 12 +#define MC_CMD_PTP_IN_FPGAREAD_NUMBYTES_LEN 4 /* MC_CMD_PTP_IN_FPGAWRITE msgrequest */ #define MC_CMD_PTP_IN_FPGAWRITE_LENMIN 13 #define MC_CMD_PTP_IN_FPGAWRITE_LENMAX 252 #define MC_CMD_PTP_IN_FPGAWRITE_LEN(num) (12+1*(num)) /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ #define MC_CMD_PTP_IN_FPGAWRITE_ADDR_OFST 8 +#define MC_CMD_PTP_IN_FPGAWRITE_ADDR_LEN 4 #define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_OFST 12 #define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_LEN 1 #define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_MINNUM 1 @@ -1332,34 +1602,67 @@ /* MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST msgrequest */ #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_LEN 16 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Time adjustment in seconds */ #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_SECONDS_OFST 8 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_SECONDS_LEN 4 /* Time adjustment major value */ #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MAJOR_OFST 8 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MAJOR_LEN 4 /* Time adjustment in nanoseconds */ #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_NANOSECONDS_OFST 12 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_NANOSECONDS_LEN 4 /* Time adjustment minor value */ #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MINOR_OFST 12 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MINOR_LEN 4 + +/* MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2 msgrequest */ +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_LEN 20 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ +/* Time adjustment in seconds */ +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_SECONDS_OFST 8 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_SECONDS_LEN 4 +/* Time adjustment major value */ +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_MAJOR_OFST 8 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_MAJOR_LEN 4 +/* Time adjustment in nanoseconds */ +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_NANOSECONDS_OFST 12 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_NANOSECONDS_LEN 4 +/* Time adjustment minor value */ +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_MINOR_OFST 12 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_MINOR_LEN 4 +/* Upper 32bits of major time offset adjustment */ +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_MAJOR_HI_OFST 16 +#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_V2_MAJOR_HI_LEN 4 /* MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST msgrequest */ #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_LEN 16 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Frequency adjustment 40 bit fixed point ns */ #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_OFST 8 #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_LEN 8 #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_LO_OFST 8 #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_HI_OFST 12 -/* enum: Number of fractional bits in frequency adjustment */ -/* MC_CMD_PTP_IN_ADJUST_BITS 0x28 */ +/* Enum values, see field(s): */ +/* MC_CMD_PTP/MC_CMD_PTP_IN_ADJUST/FREQ */ /* MC_CMD_PTP_IN_RX_SET_VLAN_FILTER msgrequest */ #define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_LEN 24 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Number of VLAN tags, 0 if not VLAN */ #define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_NUM_VLAN_TAGS_OFST 8 +#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_NUM_VLAN_TAGS_LEN 4 /* Set of VLAN tags to filter against */ #define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_OFST 12 #define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_LEN 4 @@ -1368,9 +1671,12 @@ /* MC_CMD_PTP_IN_RX_SET_UUID_FILTER msgrequest */ #define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_LEN 20 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* 1 to enable UUID filtering, 0 to disable */ #define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_ENABLE_OFST 8 +#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_ENABLE_LEN 4 /* UUID to filter against */ #define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_OFST 12 #define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_LEN 8 @@ -1380,18 +1686,25 @@ /* MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER msgrequest */ #define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_LEN 16 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* 1 to enable Domain filtering, 0 to disable */ #define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_ENABLE_OFST 8 +#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_ENABLE_LEN 4 /* Domain number to filter against */ #define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_DOMAIN_OFST 12 +#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_DOMAIN_LEN 4 /* MC_CMD_PTP_IN_SET_CLK_SRC msgrequest */ #define MC_CMD_PTP_IN_SET_CLK_SRC_LEN 12 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Set the clock source. */ #define MC_CMD_PTP_IN_SET_CLK_SRC_CLK_OFST 8 +#define MC_CMD_PTP_IN_SET_CLK_SRC_CLK_LEN 4 /* enum: Internal. */ #define MC_CMD_PTP_CLK_SRC_INTERNAL 0x0 /* enum: External. */ @@ -1400,42 +1713,56 @@ /* MC_CMD_PTP_IN_RST_CLK msgrequest */ #define MC_CMD_PTP_IN_RST_CLK_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* Reset value of Timer Reg. */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_PPS_ENABLE msgrequest */ #define MC_CMD_PTP_IN_PPS_ENABLE_LEN 12 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* Enable or disable */ #define MC_CMD_PTP_IN_PPS_ENABLE_OP_OFST 4 +#define MC_CMD_PTP_IN_PPS_ENABLE_OP_LEN 4 /* enum: Enable */ #define MC_CMD_PTP_ENABLE_PPS 0x0 /* enum: Disable */ #define MC_CMD_PTP_DISABLE_PPS 0x1 -/* Queue id to send events back */ +/* Not used. Events are always sent to function relative queue 0. */ #define MC_CMD_PTP_IN_PPS_ENABLE_QUEUE_ID_OFST 8 +#define MC_CMD_PTP_IN_PPS_ENABLE_QUEUE_ID_LEN 4 /* MC_CMD_PTP_IN_GET_TIME_FORMAT msgrequest */ #define MC_CMD_PTP_IN_GET_TIME_FORMAT_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_GET_ATTRIBUTES msgrequest */ #define MC_CMD_PTP_IN_GET_ATTRIBUTES_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS msgrequest */ #define MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS_LEN 8 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE msgrequest */ #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_LEN 12 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Original field containing queue ID. Now extended to include flags. */ #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_OFST 8 +#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_LEN 4 #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_LBN 0 #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_WIDTH 16 #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_LBN 31 @@ -1444,29 +1771,39 @@ /* MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE msgrequest */ #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_LEN 16 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* Unsubscribe options */ #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL_OFST 8 +#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL_LEN 4 /* enum: Unsubscribe a single queue */ #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_SINGLE 0x0 /* enum: Unsubscribe all queues */ #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_ALL 0x1 /* Event queue ID */ #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE_OFST 12 +#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE_LEN 4 /* MC_CMD_PTP_IN_MANFTEST_PPS msgrequest */ #define MC_CMD_PTP_IN_MANFTEST_PPS_LEN 12 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* 1 to enable PPS test mode, 0 to disable and return result. */ #define MC_CMD_PTP_IN_MANFTEST_PPS_TEST_ENABLE_OFST 8 +#define MC_CMD_PTP_IN_MANFTEST_PPS_TEST_ENABLE_LEN 4 /* MC_CMD_PTP_IN_SET_SYNC_STATUS msgrequest */ #define MC_CMD_PTP_IN_SET_SYNC_STATUS_LEN 24 /* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_CMD_LEN 4 */ /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ /* NIC - Host System Clock Synchronization status */ #define MC_CMD_PTP_IN_SET_SYNC_STATUS_STATUS_OFST 8 +#define MC_CMD_PTP_IN_SET_SYNC_STATUS_STATUS_LEN 4 /* enum: Host System clock and NIC clock are not in sync */ #define MC_CMD_PTP_IN_SET_SYNC_STATUS_NOT_IN_SYNC 0x0 /* enum: Host System clock and NIC clock are synchronized */ @@ -1475,8 +1812,11 @@ * no longer in sync. */ #define MC_CMD_PTP_IN_SET_SYNC_STATUS_TIMEOUT_OFST 12 +#define MC_CMD_PTP_IN_SET_SYNC_STATUS_TIMEOUT_LEN 4 #define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED0_OFST 16 +#define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED0_LEN 4 #define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED1_OFST 20 +#define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED1_LEN 4 /* MC_CMD_PTP_OUT msgresponse */ #define MC_CMD_PTP_OUT_LEN 0 @@ -1485,12 +1825,16 @@ #define MC_CMD_PTP_OUT_TRANSMIT_LEN 8 /* Value of seconds timestamp */ #define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_LEN 4 /* Timestamp major value */ #define MC_CMD_PTP_OUT_TRANSMIT_MAJOR_OFST 0 +#define MC_CMD_PTP_OUT_TRANSMIT_MAJOR_LEN 4 /* Value of nanoseconds timestamp */ #define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4 +#define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_LEN 4 /* Timestamp minor value */ #define MC_CMD_PTP_OUT_TRANSMIT_MINOR_OFST 4 +#define MC_CMD_PTP_OUT_TRANSMIT_MINOR_LEN 4 /* MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE msgresponse */ #define MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE_LEN 0 @@ -1502,47 +1846,85 @@ #define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8 /* Value of seconds timestamp */ #define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_LEN 4 /* Timestamp major value */ #define MC_CMD_PTP_OUT_READ_NIC_TIME_MAJOR_OFST 0 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_MAJOR_LEN 4 /* Value of nanoseconds timestamp */ #define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_LEN 4 /* Timestamp minor value */ #define MC_CMD_PTP_OUT_READ_NIC_TIME_MINOR_OFST 4 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_MINOR_LEN 4 + +/* MC_CMD_PTP_OUT_READ_NIC_TIME_V2 msgresponse */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_LEN 12 +/* Value of seconds timestamp */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_SECONDS_LEN 4 +/* Timestamp major value */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_MAJOR_OFST 0 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_MAJOR_LEN 4 +/* Value of nanoseconds timestamp */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_NANOSECONDS_OFST 4 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_NANOSECONDS_LEN 4 +/* Timestamp minor value */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_MINOR_OFST 4 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_MINOR_LEN 4 +/* Upper 32bits of major timestamp value */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_MAJOR_HI_OFST 8 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_V2_MAJOR_HI_LEN 4 /* MC_CMD_PTP_OUT_STATUS msgresponse */ #define MC_CMD_PTP_OUT_STATUS_LEN 64 /* Frequency of NIC's hardware clock */ #define MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_OFST 0 +#define MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_LEN 4 /* Number of packets transmitted and timestamped */ #define MC_CMD_PTP_OUT_STATUS_STATS_TX_OFST 4 +#define MC_CMD_PTP_OUT_STATUS_STATS_TX_LEN 4 /* Number of packets received and timestamped */ #define MC_CMD_PTP_OUT_STATUS_STATS_RX_OFST 8 +#define MC_CMD_PTP_OUT_STATUS_STATS_RX_LEN 4 /* Number of packets timestamped by the FPGA */ #define MC_CMD_PTP_OUT_STATUS_STATS_TS_OFST 12 +#define MC_CMD_PTP_OUT_STATUS_STATS_TS_LEN 4 /* Number of packets filter matched */ #define MC_CMD_PTP_OUT_STATUS_STATS_FM_OFST 16 +#define MC_CMD_PTP_OUT_STATUS_STATS_FM_LEN 4 /* Number of packets not filter matched */ #define MC_CMD_PTP_OUT_STATUS_STATS_NFM_OFST 20 +#define MC_CMD_PTP_OUT_STATUS_STATS_NFM_LEN 4 /* Number of PPS overflows (noise on input?) */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_LEN 4 /* Number of PPS bad periods */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_LEN 4 /* Minimum period of PPS pulse in nanoseconds */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_LEN 4 /* Maximum period of PPS pulse in nanoseconds */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_LEN 4 /* Last period of PPS pulse in nanoseconds */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_LEN 4 /* Mean period of PPS pulse in nanoseconds */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_LEN 4 /* Minimum offset of PPS pulse in nanoseconds (signed) */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_LEN 4 /* Maximum offset of PPS pulse in nanoseconds (signed) */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_LEN 4 /* Last offset of PPS pulse in nanoseconds (signed) */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_LEN 4 /* Mean offset of PPS pulse in nanoseconds (signed) */ #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_LEN 4 /* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20 @@ -1555,23 +1937,31 @@ #define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12 /* Host time immediately before NIC's hardware clock read */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_LEN 4 /* Value of seconds timestamp */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_LEN 4 /* Timestamp major value */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_MAJOR_OFST 4 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_MAJOR_LEN 4 /* Value of nanoseconds timestamp */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_LEN 4 /* Timestamp minor value */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_MINOR_OFST 8 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_MINOR_LEN 4 /* Host time immediately after NIC's hardware clock read */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_LEN 4 /* Number of nanoseconds waited after reading NIC's hardware clock */ #define MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_OFST 16 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_LEN 4 /* MC_CMD_PTP_OUT_MANFTEST_BASIC msgresponse */ #define MC_CMD_PTP_OUT_MANFTEST_BASIC_LEN 8 /* Results of testing */ #define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_LEN 4 /* enum: Successful test */ #define MC_CMD_PTP_MANF_SUCCESS 0x0 /* enum: FPGA load failed */ @@ -1604,15 +1994,19 @@ #define MC_CMD_PTP_MANF_CLOCK_READ 0xe /* Presence of external oscillator */ #define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4 +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_LEN 4 /* MC_CMD_PTP_OUT_MANFTEST_PACKET msgresponse */ #define MC_CMD_PTP_OUT_MANFTEST_PACKET_LEN 12 /* Results of testing */ #define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_LEN 4 /* Number of packets received by FPGA */ #define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_OFST 4 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_LEN 4 /* Number of packets received by Siena filters */ #define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_OFST 8 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_LEN 4 /* MC_CMD_PTP_OUT_FPGAREAD msgresponse */ #define MC_CMD_PTP_OUT_FPGAREAD_LENMIN 1 @@ -1628,9 +2022,11 @@ /* Time format required/used by for this NIC. Applies to all PTP MCDI * operations that pass times between the host and firmware. If this operation * is not supported (older firmware) a format of seconds and nanoseconds should - * be assumed. + * be assumed. Note this enum is deprecated. Do not add to it- use the + * TIME_FORMAT field in MC_CMD_PTP_OUT_GET_ATTRIBUTES instead. */ #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_FORMAT_OFST 0 +#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_FORMAT_LEN 4 /* enum: Times are in seconds and nanoseconds */ #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_NANOSECONDS 0x0 /* enum: Major register has units of 16 second per tick, minor 8 ns per tick */ @@ -1646,12 +2042,16 @@ * be assumed. */ #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_TIME_FORMAT_OFST 0 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_TIME_FORMAT_LEN 4 /* enum: Times are in seconds and nanoseconds */ #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS 0x0 /* enum: Major register has units of 16 second per tick, minor 8 ns per tick */ #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_16SECONDS_8NANOSECONDS 0x1 /* enum: Major register has units of seconds, minor 2^-27s per tick */ #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_27FRACTION 0x2 +/* enum: Major register units are seconds, minor units are quarter nanoseconds + */ +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_QTR_NANOSECONDS 0x3 /* Minimum acceptable value for a corrected synchronization timeset. When * comparing host and NIC clock times, the MC returns a set of samples that * contain the host start and end time, the MC time when the host start was @@ -1660,46 +2060,66 @@ * end and start times minus the time that the MC waited for host end. */ #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SYNC_WINDOW_MIN_OFST 4 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SYNC_WINDOW_MIN_LEN 4 /* Various PTP capabilities */ #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_CAPABILITIES_OFST 8 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_CAPABILITIES_LEN 4 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_LBN 0 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_WIDTH 1 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RX_TSTAMP_OOB_LBN 1 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RX_TSTAMP_OOB_WIDTH 1 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_64BIT_SECONDS_LBN 2 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_64BIT_SECONDS_WIDTH 1 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_LBN 3 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_WIDTH 1 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED0_OFST 12 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED0_LEN 4 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED1_OFST 16 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED1_LEN 4 #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED2_OFST 20 +#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED2_LEN 4 /* MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS msgresponse */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_LEN 16 /* Uncorrected error on PTP transmit timestamps in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT_OFST 0 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT_LEN 4 /* Uncorrected error on PTP receive timestamps in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE_OFST 4 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE_LEN 4 /* Uncorrected error on PPS output in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT_OFST 8 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT_LEN 4 /* Uncorrected error on PPS input in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN_OFST 12 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN_LEN 4 /* MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2 msgresponse */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_LEN 24 /* Uncorrected error on PTP transmit timestamps in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PTP_TX_OFST 0 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PTP_TX_LEN 4 /* Uncorrected error on PTP receive timestamps in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PTP_RX_OFST 4 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PTP_RX_LEN 4 /* Uncorrected error on PPS output in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PPS_OUT_OFST 8 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PPS_OUT_LEN 4 /* Uncorrected error on PPS input in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PPS_IN_OFST 12 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_PPS_IN_LEN 4 /* Uncorrected error on non-PTP transmit timestamps in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_GENERAL_TX_OFST 16 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_GENERAL_TX_LEN 4 /* Uncorrected error on non-PTP receive timestamps in NIC clock format */ #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_GENERAL_RX_OFST 20 +#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_GENERAL_RX_LEN 4 /* MC_CMD_PTP_OUT_MANFTEST_PPS msgresponse */ #define MC_CMD_PTP_OUT_MANFTEST_PPS_LEN 4 /* Results of testing */ #define MC_CMD_PTP_OUT_MANFTEST_PPS_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_OUT_MANFTEST_PPS_TEST_RESULT_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_PTP_OUT_MANFTEST_BASIC/TEST_RESULT */ @@ -1713,14 +2133,17 @@ */ #define MC_CMD_CSR_READ32 0xc -#define MC_CMD_0xc_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xc_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_CSR_READ32_IN msgrequest */ #define MC_CMD_CSR_READ32_IN_LEN 12 /* Address */ #define MC_CMD_CSR_READ32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_READ32_IN_ADDR_LEN 4 #define MC_CMD_CSR_READ32_IN_STEP_OFST 4 +#define MC_CMD_CSR_READ32_IN_STEP_LEN 4 #define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8 +#define MC_CMD_CSR_READ32_IN_NUMWORDS_LEN 4 /* MC_CMD_CSR_READ32_OUT msgresponse */ #define MC_CMD_CSR_READ32_OUT_LENMIN 4 @@ -1739,7 +2162,7 @@ */ #define MC_CMD_CSR_WRITE32 0xd -#define MC_CMD_0xd_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xd_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_CSR_WRITE32_IN msgrequest */ #define MC_CMD_CSR_WRITE32_IN_LENMIN 12 @@ -1747,7 +2170,9 @@ #define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num)) /* Address */ #define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_WRITE32_IN_ADDR_LEN 4 #define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4 +#define MC_CMD_CSR_WRITE32_IN_STEP_LEN 4 #define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8 #define MC_CMD_CSR_WRITE32_IN_BUFFER_LEN 4 #define MC_CMD_CSR_WRITE32_IN_BUFFER_MINNUM 1 @@ -1756,6 +2181,7 @@ /* MC_CMD_CSR_WRITE32_OUT msgresponse */ #define MC_CMD_CSR_WRITE32_OUT_LEN 4 #define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0 +#define MC_CMD_CSR_WRITE32_OUT_STATUS_LEN 4 /***********************************/ @@ -1776,6 +2202,7 @@ * sensors. */ #define MC_CMD_HP_IN_SUBCMD_OFST 0 +#define MC_CMD_HP_IN_SUBCMD_LEN 4 /* enum: OCSD (Option Card Sensor Data) sub-command. */ #define MC_CMD_HP_IN_OCSD_SUBCMD 0x0 /* enum: Last known valid HP sub-command. */ @@ -1790,10 +2217,12 @@ * NULL.) */ #define MC_CMD_HP_IN_OCSD_INTERVAL_OFST 12 +#define MC_CMD_HP_IN_OCSD_INTERVAL_LEN 4 /* MC_CMD_HP_OUT msgresponse */ #define MC_CMD_HP_OUT_LEN 4 #define MC_CMD_HP_OUT_OCSD_STATUS_OFST 0 +#define MC_CMD_HP_OUT_OCSD_STATUS_LEN 4 /* enum: OCSD stopped for this card. */ #define MC_CMD_HP_OUT_OCSD_STOPPED 0x1 /* enum: OCSD was successfully started with the address provided. */ @@ -1838,29 +2267,35 @@ * external devices. */ #define MC_CMD_MDIO_READ_IN_BUS_OFST 0 +#define MC_CMD_MDIO_READ_IN_BUS_LEN 4 /* enum: Internal. */ #define MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum: External. */ #define MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* Port address */ #define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_READ_IN_PRTAD_LEN 4 /* Device Address or clause 22. */ #define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8 +#define MC_CMD_MDIO_READ_IN_DEVAD_LEN 4 /* enum: By default all the MCDI MDIO operations perform clause45 mode. If you * want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22. */ #define MC_CMD_MDIO_CLAUSE22 0x20 /* Address */ #define MC_CMD_MDIO_READ_IN_ADDR_OFST 12 +#define MC_CMD_MDIO_READ_IN_ADDR_LEN 4 /* MC_CMD_MDIO_READ_OUT msgresponse */ #define MC_CMD_MDIO_READ_OUT_LEN 8 /* Value */ #define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0 +#define MC_CMD_MDIO_READ_OUT_VALUE_LEN 4 /* Status the MDIO commands return the raw status bits from the MDIO block. A * "good" transaction should have the DONE bit set and all other bits clear. */ #define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4 +#define MC_CMD_MDIO_READ_OUT_STATUS_LEN 4 /* enum: Good. */ #define MC_CMD_MDIO_STATUS_GOOD 0x8 @@ -1879,22 +2314,27 @@ * external devices. */ #define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0 +#define MC_CMD_MDIO_WRITE_IN_BUS_LEN 4 /* enum: Internal. */ /* MC_CMD_MDIO_BUS_INTERNAL 0x0 */ /* enum: External. */ /* MC_CMD_MDIO_BUS_EXTERNAL 0x1 */ /* Port address */ #define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_WRITE_IN_PRTAD_LEN 4 /* Device Address or clause 22. */ #define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8 +#define MC_CMD_MDIO_WRITE_IN_DEVAD_LEN 4 /* enum: By default all the MCDI MDIO operations perform clause45 mode. If you * want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22. */ /* MC_CMD_MDIO_CLAUSE22 0x20 */ /* Address */ #define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12 +#define MC_CMD_MDIO_WRITE_IN_ADDR_LEN 4 /* Value */ #define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16 +#define MC_CMD_MDIO_WRITE_IN_VALUE_LEN 4 /* MC_CMD_MDIO_WRITE_OUT msgresponse */ #define MC_CMD_MDIO_WRITE_OUT_LEN 4 @@ -1902,6 +2342,7 @@ * "good" transaction should have the DONE bit set and all other bits clear. */ #define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0 +#define MC_CMD_MDIO_WRITE_OUT_STATUS_LEN 4 /* enum: Good. */ /* MC_CMD_MDIO_STATUS_GOOD 0x8 */ @@ -1912,7 +2353,7 @@ */ #define MC_CMD_DBI_WRITE 0x12 -#define MC_CMD_0x12_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x12_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_DBI_WRITE_IN msgrequest */ #define MC_CMD_DBI_WRITE_IN_LENMIN 12 @@ -1932,9 +2373,11 @@ /* MC_CMD_DBIWROP_TYPEDEF structuredef */ #define MC_CMD_DBIWROP_TYPEDEF_LEN 12 #define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LEN 4 #define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0 #define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32 #define MC_CMD_DBIWROP_TYPEDEF_PARMS_OFST 4 +#define MC_CMD_DBIWROP_TYPEDEF_PARMS_LEN 4 #define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_LBN 16 #define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_WIDTH 16 #define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_LBN 15 @@ -1944,6 +2387,7 @@ #define MC_CMD_DBIWROP_TYPEDEF_PARMS_LBN 32 #define MC_CMD_DBIWROP_TYPEDEF_PARMS_WIDTH 32 #define MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_LEN 4 #define MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64 #define MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32 @@ -1959,13 +2403,16 @@ #define MC_CMD_PORT_READ32_IN_LEN 4 /* Address */ #define MC_CMD_PORT_READ32_IN_ADDR_OFST 0 +#define MC_CMD_PORT_READ32_IN_ADDR_LEN 4 /* MC_CMD_PORT_READ32_OUT msgresponse */ #define MC_CMD_PORT_READ32_OUT_LEN 8 /* Value */ #define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ32_OUT_VALUE_LEN 4 /* Status */ #define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4 +#define MC_CMD_PORT_READ32_OUT_STATUS_LEN 4 /***********************************/ @@ -1979,13 +2426,16 @@ #define MC_CMD_PORT_WRITE32_IN_LEN 8 /* Address */ #define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE32_IN_ADDR_LEN 4 /* Value */ #define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4 +#define MC_CMD_PORT_WRITE32_IN_VALUE_LEN 4 /* MC_CMD_PORT_WRITE32_OUT msgresponse */ #define MC_CMD_PORT_WRITE32_OUT_LEN 4 /* Status */ #define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0 +#define MC_CMD_PORT_WRITE32_OUT_STATUS_LEN 4 /***********************************/ @@ -1999,6 +2449,7 @@ #define MC_CMD_PORT_READ128_IN_LEN 4 /* Address */ #define MC_CMD_PORT_READ128_IN_ADDR_OFST 0 +#define MC_CMD_PORT_READ128_IN_ADDR_LEN 4 /* MC_CMD_PORT_READ128_OUT msgresponse */ #define MC_CMD_PORT_READ128_OUT_LEN 20 @@ -2007,6 +2458,7 @@ #define MC_CMD_PORT_READ128_OUT_VALUE_LEN 16 /* Status */ #define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16 +#define MC_CMD_PORT_READ128_OUT_STATUS_LEN 4 /***********************************/ @@ -2020,6 +2472,7 @@ #define MC_CMD_PORT_WRITE128_IN_LEN 20 /* Address */ #define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE128_IN_ADDR_LEN 4 /* Value */ #define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4 #define MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16 @@ -2028,6 +2481,7 @@ #define MC_CMD_PORT_WRITE128_OUT_LEN 4 /* Status */ #define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0 +#define MC_CMD_PORT_WRITE128_OUT_STATUS_LEN 4 /* MC_CMD_CAPABILITIES structuredef */ #define MC_CMD_CAPABILITIES_LEN 4 @@ -2072,24 +2526,54 @@ #define MC_CMD_GET_BOARD_CFG_OUT_LENMAX 136 #define MC_CMD_GET_BOARD_CFG_OUT_LEN(num) (72+2*(num)) #define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_LEN 4 #define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4 #define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32 -/* See MC_CMD_CAPABILITIES */ +/* Capabilities for Siena Port0 (see struct MC_CMD_CAPABILITIES). Unused on + * EF10 and later (use MC_CMD_GET_CAPABILITIES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36 -/* See MC_CMD_CAPABILITIES */ +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_LEN 4 +/* Capabilities for Siena Port1 (see struct MC_CMD_CAPABILITIES). Unused on + * EF10 and later (use MC_CMD_GET_CAPABILITIES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40 +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_LEN 4 +/* Base MAC address for Siena Port0. Unused on EF10 and later (use + * MC_CMD_GET_MAC_ADDRESSES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44 #define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6 +/* Base MAC address for Siena Port1. Unused on EF10 and later (use + * MC_CMD_GET_MAC_ADDRESSES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50 #define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6 +/* Size of MAC address pool for Siena Port0. Unused on EF10 and later (use + * MC_CMD_GET_MAC_ADDRESSES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_LEN 4 +/* Size of MAC address pool for Siena Port1. Unused on EF10 and later (use + * MC_CMD_GET_MAC_ADDRESSES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_LEN 4 +/* Increment between addresses in MAC address pool for Siena Port0. Unused on + * EF10 and later (use MC_CMD_GET_MAC_ADDRESSES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_LEN 4 +/* Increment between addresses in MAC address pool for Siena Port1. Unused on + * EF10 and later (use MC_CMD_GET_MAC_ADDRESSES). + */ #define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68 -/* This field contains a 16-bit value for each of the types of NVRAM area. The - * values are defined in the firmware/mc/platform/.c file for a specific board - * type, but otherwise have no meaning to the MC; they are used by the driver - * to manage selection of appropriate firmware updates. +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_LEN 4 +/* Siena only. This field contains a 16-bit value for each of the types of + * NVRAM area. The values are defined in the firmware/mc/platform/.c file for a + * specific board type, but otherwise have no meaning to the MC; they are used + * by the driver to manage selection of appropriate firmware updates. Unused on + * EF10 and later (use MC_CMD_NVRAM_METADATA). */ #define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72 #define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2 @@ -2103,7 +2587,7 @@ */ #define MC_CMD_DBI_READX 0x19 -#define MC_CMD_0x19_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x19_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_DBI_READX_IN msgrequest */ #define MC_CMD_DBI_READX_IN_LENMIN 8 @@ -2130,9 +2614,11 @@ /* MC_CMD_DBIRDOP_TYPEDEF structuredef */ #define MC_CMD_DBIRDOP_TYPEDEF_LEN 8 #define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_OFST 0 +#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_LEN 4 #define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_LBN 0 #define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_WIDTH 32 #define MC_CMD_DBIRDOP_TYPEDEF_PARMS_OFST 4 +#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_LEN 4 #define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_LBN 16 #define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_WIDTH 16 #define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_LBN 15 @@ -2149,7 +2635,7 @@ */ #define MC_CMD_SET_RAND_SEED 0x1a -#define MC_CMD_0x1a_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x1a_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_SET_RAND_SEED_IN msgrequest */ #define MC_CMD_SET_RAND_SEED_IN_LEN 16 @@ -2198,14 +2684,17 @@ #define MC_CMD_DRV_ATTACH_IN_LEN 12 /* new state to set if UPDATE=1 */ #define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0 +#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_LEN 4 #define MC_CMD_DRV_ATTACH_LBN 0 #define MC_CMD_DRV_ATTACH_WIDTH 1 #define MC_CMD_DRV_PREBOOT_LBN 1 #define MC_CMD_DRV_PREBOOT_WIDTH 1 /* 1 to set new state, or 0 to just report the existing state */ #define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 +#define MC_CMD_DRV_ATTACH_IN_UPDATE_LEN 4 /* preferred datapath firmware (for Huntington; ignored for Siena) */ #define MC_CMD_DRV_ATTACH_IN_FIRMWARE_ID_OFST 8 +#define MC_CMD_DRV_ATTACH_IN_FIRMWARE_ID_LEN 4 /* enum: Prefer to use full featured firmware */ #define MC_CMD_FW_FULL_FEATURED 0x0 /* enum: Prefer to use firmware with fewer features but lower latency */ @@ -2229,13 +2718,16 @@ #define MC_CMD_DRV_ATTACH_OUT_LEN 4 /* previous or existing state, see the bitmask at NEW_STATE */ #define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0 +#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_LEN 4 /* MC_CMD_DRV_ATTACH_EXT_OUT msgresponse */ #define MC_CMD_DRV_ATTACH_EXT_OUT_LEN 8 /* previous or existing state, see the bitmask at NEW_STATE */ #define MC_CMD_DRV_ATTACH_EXT_OUT_OLD_STATE_OFST 0 +#define MC_CMD_DRV_ATTACH_EXT_OUT_OLD_STATE_LEN 4 /* Flags associated with this function */ #define MC_CMD_DRV_ATTACH_EXT_OUT_FUNC_FLAGS_OFST 4 +#define MC_CMD_DRV_ATTACH_EXT_OUT_FUNC_FLAGS_LEN 4 /* enum: Labels the lowest-numbered function visible to the OS */ #define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY 0x0 /* enum: The function can control the link state of the physical port it is @@ -2260,6 +2752,7 @@ #define MC_CMD_SHMUART_IN_LEN 4 /* ??? */ #define MC_CMD_SHMUART_IN_FLAG_OFST 0 +#define MC_CMD_SHMUART_IN_FLAG_LEN 4 /* MC_CMD_SHMUART_OUT msgresponse */ #define MC_CMD_SHMUART_OUT_LEN 0 @@ -2297,6 +2790,7 @@ * (TBD). */ #define MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0 +#define MC_CMD_ENTITY_RESET_IN_FLAG_LEN 4 #define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0 #define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1 @@ -2314,8 +2808,10 @@ #define MC_CMD_PCIE_CREDITS_IN_LEN 8 /* poll period. 0 is disabled */ #define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0 +#define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_LEN 4 /* wipe statistics */ #define MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4 +#define MC_CMD_PCIE_CREDITS_IN_WIPE_LEN 4 /* MC_CMD_PCIE_CREDITS_OUT msgresponse */ #define MC_CMD_PCIE_CREDITS_OUT_LEN 16 @@ -2346,31 +2842,54 @@ /* MC_CMD_RXD_MONITOR_IN msgrequest */ #define MC_CMD_RXD_MONITOR_IN_LEN 12 #define MC_CMD_RXD_MONITOR_IN_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_IN_QID_LEN 4 #define MC_CMD_RXD_MONITOR_IN_POLL_PERIOD_OFST 4 +#define MC_CMD_RXD_MONITOR_IN_POLL_PERIOD_LEN 4 #define MC_CMD_RXD_MONITOR_IN_WIPE_OFST 8 +#define MC_CMD_RXD_MONITOR_IN_WIPE_LEN 4 /* MC_CMD_RXD_MONITOR_OUT msgresponse */ #define MC_CMD_RXD_MONITOR_OUT_LEN 80 #define MC_CMD_RXD_MONITOR_OUT_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_OUT_QID_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_FILL_OFST 4 +#define MC_CMD_RXD_MONITOR_OUT_RING_FILL_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_FILL_OFST 8 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_FILL_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_1_OFST 12 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_1_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_2_OFST 16 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_2_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_4_OFST 20 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_4_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_8_OFST 24 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_8_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_16_OFST 28 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_16_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_32_OFST 32 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_32_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_64_OFST 36 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_64_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_128_OFST 40 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_128_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_LT_256_OFST 44 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_256_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_RING_GE_256_OFST 48 +#define MC_CMD_RXD_MONITOR_OUT_RING_GE_256_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_1_OFST 52 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_1_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_2_OFST 56 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_2_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_4_OFST 60 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_4_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_8_OFST 64 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_8_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_16_OFST 68 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_16_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_32_OFST 72 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_32_LEN 4 #define MC_CMD_RXD_MONITOR_OUT_CACHE_GE_32_OFST 76 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_GE_32_LEN 4 /***********************************/ @@ -2379,13 +2898,14 @@ */ #define MC_CMD_PUTS 0x23 -#define MC_CMD_0x23_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x23_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_PUTS_IN msgrequest */ #define MC_CMD_PUTS_IN_LENMIN 13 #define MC_CMD_PUTS_IN_LENMAX 252 #define MC_CMD_PUTS_IN_LEN(num) (12+1*(num)) #define MC_CMD_PUTS_IN_DEST_OFST 0 +#define MC_CMD_PUTS_IN_DEST_LEN 4 #define MC_CMD_PUTS_IN_UART_LBN 0 #define MC_CMD_PUTS_IN_UART_WIDTH 1 #define MC_CMD_PUTS_IN_PORT_LBN 1 @@ -2417,6 +2937,7 @@ #define MC_CMD_GET_PHY_CFG_OUT_LEN 72 /* flags */ #define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_LEN 4 #define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0 #define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1 #define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN 1 @@ -2433,8 +2954,10 @@ #define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1 /* ?? */ #define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4 +#define MC_CMD_GET_PHY_CFG_OUT_TYPE_LEN 4 /* Bitmask of supported capabilities */ #define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8 +#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_LEN 4 #define MC_CMD_PHY_CAP_10HDX_LBN 1 #define MC_CMD_PHY_CAP_10HDX_WIDTH 1 #define MC_CMD_PHY_CAP_10FDX_LBN 2 @@ -2459,17 +2982,39 @@ #define MC_CMD_PHY_CAP_40000FDX_WIDTH 1 #define MC_CMD_PHY_CAP_DDM_LBN 12 #define MC_CMD_PHY_CAP_DDM_WIDTH 1 +#define MC_CMD_PHY_CAP_100000FDX_LBN 13 +#define MC_CMD_PHY_CAP_100000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_25000FDX_LBN 14 +#define MC_CMD_PHY_CAP_25000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_50000FDX_LBN 15 +#define MC_CMD_PHY_CAP_50000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_BASER_FEC_LBN 16 +#define MC_CMD_PHY_CAP_BASER_FEC_WIDTH 1 +#define MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN 17 +#define MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_WIDTH 1 +#define MC_CMD_PHY_CAP_RS_FEC_LBN 18 +#define MC_CMD_PHY_CAP_RS_FEC_WIDTH 1 +#define MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN 19 +#define MC_CMD_PHY_CAP_RS_FEC_REQUESTED_WIDTH 1 +#define MC_CMD_PHY_CAP_25G_BASER_FEC_LBN 20 +#define MC_CMD_PHY_CAP_25G_BASER_FEC_WIDTH 1 +#define MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN 21 +#define MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_WIDTH 1 /* ?? */ #define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12 +#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_LEN 4 /* ?? */ #define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16 +#define MC_CMD_GET_PHY_CFG_OUT_PRT_LEN 4 /* ?? */ #define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20 +#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_LEN 4 /* ?? */ #define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24 #define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20 /* ?? */ #define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44 +#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_LEN 4 /* enum: Xaui. */ #define MC_CMD_MEDIA_XAUI 0x1 /* enum: CX4. */ @@ -2485,6 +3030,7 @@ /* enum: QSFP+. */ #define MC_CMD_MEDIA_QSFP_PLUS 0x7 #define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 +#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_LEN 4 /* enum: Native clause 22 */ #define MC_CMD_MMD_CLAUSE22 0x0 #define MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */ @@ -2515,6 +3061,7 @@ #define MC_CMD_START_BIST_IN_LEN 4 /* Type of test. */ #define MC_CMD_START_BIST_IN_TYPE_OFST 0 +#define MC_CMD_START_BIST_IN_TYPE_LEN 4 /* enum: Run the PHY's short cable BIST. */ #define MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum: Run the PHY's long cable BIST. */ @@ -2556,6 +3103,7 @@ #define MC_CMD_POLL_BIST_OUT_LEN 8 /* result */ #define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 +#define MC_CMD_POLL_BIST_OUT_RESULT_LEN 4 /* enum: Running. */ #define MC_CMD_POLL_BIST_RUNNING 0x1 /* enum: Passed. */ @@ -2565,19 +3113,26 @@ /* enum: Timed-out. */ #define MC_CMD_POLL_BIST_TIMEOUT 0x4 #define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4 +#define MC_CMD_POLL_BIST_OUT_PRIVATE_LEN 4 /* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */ #define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36 /* result */ /* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* MC_CMD_POLL_BIST_OUT_RESULT_LEN 4 */ /* Enum values, see field(s): */ /* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_LEN 4 #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_LEN 4 #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_LEN 4 #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_LEN 4 /* Status of each channel A */ #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_LEN 4 /* enum: Ok. */ #define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum: Open. */ @@ -2590,14 +3145,17 @@ #define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* Status of each channel B */ #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_LEN 4 /* Enum values, see field(s): */ /* CABLE_STATUS_A */ /* Status of each channel C */ #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_LEN 4 /* Enum values, see field(s): */ /* CABLE_STATUS_A */ /* Status of each channel D */ #define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_LEN 4 /* Enum values, see field(s): */ /* CABLE_STATUS_A */ @@ -2605,9 +3163,11 @@ #define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8 /* result */ /* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* MC_CMD_POLL_BIST_OUT_RESULT_LEN 4 */ /* Enum values, see field(s): */ /* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ #define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4 +#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_LEN 4 /* enum: Complete. */ #define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum: Bus switch off I2C write. */ @@ -2631,9 +3191,11 @@ #define MC_CMD_POLL_BIST_OUT_MEM_LEN 36 /* result */ /* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* MC_CMD_POLL_BIST_OUT_RESULT_LEN 4 */ /* Enum values, see field(s): */ /* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ #define MC_CMD_POLL_BIST_OUT_MEM_TEST_OFST 4 +#define MC_CMD_POLL_BIST_OUT_MEM_TEST_LEN 4 /* enum: Test has completed. */ #define MC_CMD_POLL_BIST_MEM_COMPLETE 0x0 /* enum: RAM test - walk ones. */ @@ -2650,8 +3212,10 @@ #define MC_CMD_POLL_BIST_MEM_ECC 0x6 /* Failure address, only valid if result is POLL_BIST_FAILED */ #define MC_CMD_POLL_BIST_OUT_MEM_ADDR_OFST 8 +#define MC_CMD_POLL_BIST_OUT_MEM_ADDR_LEN 4 /* Bus or address space to which the failure address corresponds */ #define MC_CMD_POLL_BIST_OUT_MEM_BUS_OFST 12 +#define MC_CMD_POLL_BIST_OUT_MEM_BUS_LEN 4 /* enum: MC MIPS bus. */ #define MC_CMD_POLL_BIST_MEM_BUS_MC 0x0 /* enum: CSR IREG bus. */ @@ -2672,14 +3236,19 @@ #define MC_CMD_POLL_BIST_MEM_BUS_DICPU_RX1 0x8 /* Pattern written to RAM / register */ #define MC_CMD_POLL_BIST_OUT_MEM_EXPECT_OFST 16 +#define MC_CMD_POLL_BIST_OUT_MEM_EXPECT_LEN 4 /* Actual value read from RAM / register */ #define MC_CMD_POLL_BIST_OUT_MEM_ACTUAL_OFST 20 +#define MC_CMD_POLL_BIST_OUT_MEM_ACTUAL_LEN 4 /* ECC error mask */ #define MC_CMD_POLL_BIST_OUT_MEM_ECC_OFST 24 +#define MC_CMD_POLL_BIST_OUT_MEM_ECC_LEN 4 /* ECC parity error mask */ #define MC_CMD_POLL_BIST_OUT_MEM_ECC_PARITY_OFST 28 +#define MC_CMD_POLL_BIST_OUT_MEM_ECC_PARITY_LEN 4 /* ECC fatal error mask */ #define MC_CMD_POLL_BIST_OUT_MEM_ECC_FATAL_OFST 32 +#define MC_CMD_POLL_BIST_OUT_MEM_ECC_FATAL_LEN 4 /***********************************/ @@ -2831,6 +3400,143 @@ /* Enum values, see field(s): */ /* 100M */ +/* MC_CMD_GET_LOOPBACK_MODES_OUT_V2 msgresponse: Supported loopback modes for + * newer NICs with 25G/50G/100G support + */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN 64 +/* Supported loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_LO_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_HI_OFST 4 +/* enum: None. */ +/* MC_CMD_LOOPBACK_NONE 0x0 */ +/* enum: Data. */ +/* MC_CMD_LOOPBACK_DATA 0x1 */ +/* enum: GMAC. */ +/* MC_CMD_LOOPBACK_GMAC 0x2 */ +/* enum: XGMII. */ +/* MC_CMD_LOOPBACK_XGMII 0x3 */ +/* enum: XGXS. */ +/* MC_CMD_LOOPBACK_XGXS 0x4 */ +/* enum: XAUI. */ +/* MC_CMD_LOOPBACK_XAUI 0x5 */ +/* enum: GMII. */ +/* MC_CMD_LOOPBACK_GMII 0x6 */ +/* enum: SGMII. */ +/* MC_CMD_LOOPBACK_SGMII 0x7 */ +/* enum: XGBR. */ +/* MC_CMD_LOOPBACK_XGBR 0x8 */ +/* enum: XFI. */ +/* MC_CMD_LOOPBACK_XFI 0x9 */ +/* enum: XAUI Far. */ +/* MC_CMD_LOOPBACK_XAUI_FAR 0xa */ +/* enum: GMII Far. */ +/* MC_CMD_LOOPBACK_GMII_FAR 0xb */ +/* enum: SGMII Far. */ +/* MC_CMD_LOOPBACK_SGMII_FAR 0xc */ +/* enum: XFI Far. */ +/* MC_CMD_LOOPBACK_XFI_FAR 0xd */ +/* enum: GPhy. */ +/* MC_CMD_LOOPBACK_GPHY 0xe */ +/* enum: PhyXS. */ +/* MC_CMD_LOOPBACK_PHYXS 0xf */ +/* enum: PCS. */ +/* MC_CMD_LOOPBACK_PCS 0x10 */ +/* enum: PMA-PMD. */ +/* MC_CMD_LOOPBACK_PMAPMD 0x11 */ +/* enum: Cross-Port. */ +/* MC_CMD_LOOPBACK_XPORT 0x12 */ +/* enum: XGMII-Wireside. */ +/* MC_CMD_LOOPBACK_XGMII_WS 0x13 */ +/* enum: XAUI Wireside. */ +/* MC_CMD_LOOPBACK_XAUI_WS 0x14 */ +/* enum: XAUI Wireside Far. */ +/* MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 */ +/* enum: XAUI Wireside near. */ +/* MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 */ +/* enum: GMII Wireside. */ +/* MC_CMD_LOOPBACK_GMII_WS 0x17 */ +/* enum: XFI Wireside. */ +/* MC_CMD_LOOPBACK_XFI_WS 0x18 */ +/* enum: XFI Wireside Far. */ +/* MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 */ +/* enum: PhyXS Wireside. */ +/* MC_CMD_LOOPBACK_PHYXS_WS 0x1a */ +/* enum: PMA lanes MAC-Serdes. */ +/* MC_CMD_LOOPBACK_PMA_INT 0x1b */ +/* enum: KR Serdes Parallel (Encoder). */ +/* MC_CMD_LOOPBACK_SD_NEAR 0x1c */ +/* enum: KR Serdes Serial. */ +/* MC_CMD_LOOPBACK_SD_FAR 0x1d */ +/* enum: PMA lanes MAC-Serdes Wireside. */ +/* MC_CMD_LOOPBACK_PMA_INT_WS 0x1e */ +/* enum: KR Serdes Parallel Wireside (Full PCS). */ +/* MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f */ +/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */ +/* MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20 */ +/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */ +/* MC_CMD_LOOPBACK_SD_FEP_WS 0x21 */ +/* enum: KR Serdes Serial Wireside. */ +/* MC_CMD_LOOPBACK_SD_FES_WS 0x22 */ +/* enum: Near side of AOE Siena side port */ +/* MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 */ +/* enum: Medford Wireside datapath loopback */ +/* MC_CMD_LOOPBACK_DATA_WS 0x24 */ +/* enum: Force link up without setting up any physical loopback (snapper use + * only) + */ +/* MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25 */ +/* Supported loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_LO_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_HI_OFST 12 +/* Enum values, see field(s): */ +/* 100M */ +/* Supported loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_10G_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_10G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_10G_LO_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_10G_HI_OFST 20 +/* Enum values, see field(s): */ +/* 100M */ +/* Supported loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_SUGGESTED_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_SUGGESTED_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_SUGGESTED_LO_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_SUGGESTED_HI_OFST 28 +/* Enum values, see field(s): */ +/* 100M */ +/* Supported loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_40G_OFST 32 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_40G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_40G_LO_OFST 32 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_40G_HI_OFST 36 +/* Enum values, see field(s): */ +/* 100M */ +/* Supported 25G loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_OFST 40 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_LO_OFST 40 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_HI_OFST 44 +/* Enum values, see field(s): */ +/* 100M */ +/* Supported 50 loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_OFST 48 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_LO_OFST 48 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_HI_OFST 52 +/* Enum values, see field(s): */ +/* 100M */ +/* Supported 100G loopbacks. */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_OFST 56 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_LO_OFST 56 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_HI_OFST 60 +/* Enum values, see field(s): */ +/* 100M */ + /***********************************/ /* MC_CMD_GET_LINK @@ -2848,17 +3554,22 @@ #define MC_CMD_GET_LINK_OUT_LEN 28 /* near-side advertised capabilities */ #define MC_CMD_GET_LINK_OUT_CAP_OFST 0 +#define MC_CMD_GET_LINK_OUT_CAP_LEN 4 /* link-partner advertised capabilities */ #define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 +#define MC_CMD_GET_LINK_OUT_LP_CAP_LEN 4 /* Autonegotiated speed in mbit/s. The link may still be down even if this * reads non-zero. */ #define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8 +#define MC_CMD_GET_LINK_OUT_LINK_SPEED_LEN 4 /* Current loopback setting. */ #define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12 +#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ #define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16 +#define MC_CMD_GET_LINK_OUT_FLAGS_LEN 4 #define MC_CMD_GET_LINK_OUT_LINK_UP_LBN 0 #define MC_CMD_GET_LINK_OUT_LINK_UP_WIDTH 1 #define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN 1 @@ -2873,9 +3584,11 @@ #define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_WIDTH 1 /* This returns the negotiated flow control value. */ #define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 +#define MC_CMD_GET_LINK_OUT_FCNTL_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */ #define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24 +#define MC_CMD_GET_LINK_OUT_MAC_FAULT_LEN 4 #define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 #define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 #define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 @@ -2899,8 +3612,10 @@ #define MC_CMD_SET_LINK_IN_LEN 16 /* ??? */ #define MC_CMD_SET_LINK_IN_CAP_OFST 0 +#define MC_CMD_SET_LINK_IN_CAP_LEN 4 /* Flags */ #define MC_CMD_SET_LINK_IN_FLAGS_OFST 4 +#define MC_CMD_SET_LINK_IN_FLAGS_LEN 4 #define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0 #define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1 #define MC_CMD_SET_LINK_IN_POWEROFF_LBN 1 @@ -2909,12 +3624,14 @@ #define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1 /* Loopback mode. */ #define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8 +#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ /* A loopback speed of "0" is supported, and means (choose any available * speed). */ #define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12 +#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_LEN 4 /* MC_CMD_SET_LINK_OUT msgresponse */ #define MC_CMD_SET_LINK_OUT_LEN 0 @@ -2932,6 +3649,7 @@ #define MC_CMD_SET_ID_LED_IN_LEN 4 /* Set LED state. */ #define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 +#define MC_CMD_SET_ID_LED_IN_STATE_LEN 4 #define MC_CMD_LED_OFF 0x0 /* enum */ #define MC_CMD_LED_ON 0x1 /* enum */ #define MC_CMD_LED_DEFAULT 0x2 /* enum */ @@ -2954,17 +3672,21 @@ * EtherII, VLAN, bug16011 padding). */ #define MC_CMD_SET_MAC_IN_MTU_OFST 0 +#define MC_CMD_SET_MAC_IN_MTU_LEN 4 #define MC_CMD_SET_MAC_IN_DRAIN_OFST 4 +#define MC_CMD_SET_MAC_IN_DRAIN_LEN 4 #define MC_CMD_SET_MAC_IN_ADDR_OFST 8 #define MC_CMD_SET_MAC_IN_ADDR_LEN 8 #define MC_CMD_SET_MAC_IN_ADDR_LO_OFST 8 #define MC_CMD_SET_MAC_IN_ADDR_HI_OFST 12 #define MC_CMD_SET_MAC_IN_REJECT_OFST 16 +#define MC_CMD_SET_MAC_IN_REJECT_LEN 4 #define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0 #define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1 #define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1 #define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1 #define MC_CMD_SET_MAC_IN_FCNTL_OFST 20 +#define MC_CMD_SET_MAC_IN_FCNTL_LEN 4 /* enum: Flow control is off. */ #define MC_CMD_FCNTL_OFF 0x0 /* enum: Respond to flow control. */ @@ -2978,6 +3700,7 @@ /* enum: Issue flow control. */ #define MC_CMD_FCNTL_GENERATE 0x5 #define MC_CMD_SET_MAC_IN_FLAGS_OFST 24 +#define MC_CMD_SET_MAC_IN_FLAGS_LEN 4 #define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_LBN 0 #define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_WIDTH 1 @@ -2987,17 +3710,21 @@ * EtherII, VLAN, bug16011 padding). */ #define MC_CMD_SET_MAC_EXT_IN_MTU_OFST 0 +#define MC_CMD_SET_MAC_EXT_IN_MTU_LEN 4 #define MC_CMD_SET_MAC_EXT_IN_DRAIN_OFST 4 +#define MC_CMD_SET_MAC_EXT_IN_DRAIN_LEN 4 #define MC_CMD_SET_MAC_EXT_IN_ADDR_OFST 8 #define MC_CMD_SET_MAC_EXT_IN_ADDR_LEN 8 #define MC_CMD_SET_MAC_EXT_IN_ADDR_LO_OFST 8 #define MC_CMD_SET_MAC_EXT_IN_ADDR_HI_OFST 12 #define MC_CMD_SET_MAC_EXT_IN_REJECT_OFST 16 +#define MC_CMD_SET_MAC_EXT_IN_REJECT_LEN 4 #define MC_CMD_SET_MAC_EXT_IN_REJECT_UNCST_LBN 0 #define MC_CMD_SET_MAC_EXT_IN_REJECT_UNCST_WIDTH 1 #define MC_CMD_SET_MAC_EXT_IN_REJECT_BRDCST_LBN 1 #define MC_CMD_SET_MAC_EXT_IN_REJECT_BRDCST_WIDTH 1 #define MC_CMD_SET_MAC_EXT_IN_FCNTL_OFST 20 +#define MC_CMD_SET_MAC_EXT_IN_FCNTL_LEN 4 /* enum: Flow control is off. */ /* MC_CMD_FCNTL_OFF 0x0 */ /* enum: Respond to flow control. */ @@ -3011,6 +3738,7 @@ /* enum: Issue flow control. */ /* MC_CMD_FCNTL_GENERATE 0x5 */ #define MC_CMD_SET_MAC_EXT_IN_FLAGS_OFST 24 +#define MC_CMD_SET_MAC_EXT_IN_FLAGS_LEN 4 #define MC_CMD_SET_MAC_EXT_IN_FLAG_INCLUDE_FCS_LBN 0 #define MC_CMD_SET_MAC_EXT_IN_FLAG_INCLUDE_FCS_WIDTH 1 /* Select which parameters to configure. A parameter will only be modified if @@ -3019,6 +3747,7 @@ * set). */ #define MC_CMD_SET_MAC_EXT_IN_CONTROL_OFST 28 +#define MC_CMD_SET_MAC_EXT_IN_CONTROL_LEN 4 #define MC_CMD_SET_MAC_EXT_IN_CFG_MTU_LBN 0 #define MC_CMD_SET_MAC_EXT_IN_CFG_MTU_WIDTH 1 #define MC_CMD_SET_MAC_EXT_IN_CFG_DRAIN_LBN 1 @@ -3040,6 +3769,7 @@ * to 0. */ #define MC_CMD_SET_MAC_V2_OUT_MTU_OFST 0 +#define MC_CMD_SET_MAC_V2_OUT_MTU_LEN 4 /***********************************/ @@ -3144,6 +3874,7 @@ #define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0 #define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4 #define MC_CMD_MAC_STATS_IN_CMD_OFST 8 +#define MC_CMD_MAC_STATS_IN_CMD_LEN 4 #define MC_CMD_MAC_STATS_IN_DMA_LBN 0 #define MC_CMD_MAC_STATS_IN_DMA_WIDTH 1 #define MC_CMD_MAC_STATS_IN_CLEAR_LBN 1 @@ -3158,9 +3889,16 @@ #define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_WIDTH 1 #define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16 #define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16 +/* DMA length. Should be set to MAC_STATS_NUM_STATS * sizeof(uint64_t), as + * returned by MC_CMD_GET_CAPABILITIES_V4_OUT. For legacy firmware not + * supporting MC_CMD_GET_CAPABILITIES_V4_OUT, DMA_LEN should be set to + * MC_CMD_MAC_NSTATS * sizeof(uint64_t) + */ #define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 +#define MC_CMD_MAC_STATS_IN_DMA_LEN_LEN 4 /* port id so vadapter stats can be provided */ #define MC_CMD_MAC_STATS_IN_PORT_ID_OFST 16 +#define MC_CMD_MAC_STATS_IN_PORT_ID_LEN 4 /* MC_CMD_MAC_STATS_OUT_DMA msgresponse */ #define MC_CMD_MAC_STATS_OUT_DMA_LEN 0 @@ -3305,9 +4043,126 @@ #define MC_CMD_GMAC_DMABUF_START 0x40 /* enum: End of GMAC stats buffer space, for Siena only. */ #define MC_CMD_GMAC_DMABUF_END 0x5f -#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */ +/* enum: GENERATION_END value, used together with GENERATION_START to verify + * consistency of DMAd data. For legacy firmware / drivers without extended + * stats (more precisely, when DMA_LEN == MC_CMD_MAC_NSTATS * + * sizeof(uint64_t)), this entry holds the GENERATION_END value. Otherwise, + * this value is invalid/ reserved and GENERATION_END is written as the last + * 64-bit word of the DMA buffer (at DMA_LEN - sizeof(uint64_t)). Note that + * this is consistent with the legacy behaviour, in the sense that entry 96 is + * the last 64-bit word in the buffer when DMA_LEN == MC_CMD_MAC_NSTATS * + * sizeof(uint64_t). See SF-109306-TC, Section 9.2 for details. + */ +#define MC_CMD_MAC_GENERATION_END 0x60 #define MC_CMD_MAC_NSTATS 0x61 /* enum */ +/* MC_CMD_MAC_STATS_V2_OUT_DMA msgresponse */ +#define MC_CMD_MAC_STATS_V2_OUT_DMA_LEN 0 + +/* MC_CMD_MAC_STATS_V2_OUT_NO_DMA msgresponse */ +#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS_V2*64))>>3) +#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_LEN 8 +#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_LO_OFST 0 +#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_HI_OFST 4 +#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V2 +/* enum: Start of FEC stats buffer space, Medford2 and up */ +#define MC_CMD_MAC_FEC_DMABUF_START 0x61 +/* enum: Number of uncorrected FEC codewords on link (RS-FEC only for Medford2) + */ +#define MC_CMD_MAC_FEC_UNCORRECTED_ERRORS 0x61 +/* enum: Number of corrected FEC codewords on link (RS-FEC only for Medford2) + */ +#define MC_CMD_MAC_FEC_CORRECTED_ERRORS 0x62 +/* enum: Number of corrected 10-bit symbol errors, lane 0 (RS-FEC only) */ +#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE0 0x63 +/* enum: Number of corrected 10-bit symbol errors, lane 1 (RS-FEC only) */ +#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE1 0x64 +/* enum: Number of corrected 10-bit symbol errors, lane 2 (RS-FEC only) */ +#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE2 0x65 +/* enum: Number of corrected 10-bit symbol errors, lane 3 (RS-FEC only) */ +#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE3 0x66 +/* enum: This includes the space at offset 103 which is the final + * GENERATION_END in a MAC_STATS_V2 response and otherwise unused. + */ +#define MC_CMD_MAC_NSTATS_V2 0x68 +/* Other enum values, see field(s): */ +/* MC_CMD_MAC_STATS_OUT_NO_DMA/STATISTICS */ + +/* MC_CMD_MAC_STATS_V3_OUT_DMA msgresponse */ +#define MC_CMD_MAC_STATS_V3_OUT_DMA_LEN 0 + +/* MC_CMD_MAC_STATS_V3_OUT_NO_DMA msgresponse */ +#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS_V3*64))>>3) +#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_LEN 8 +#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_LO_OFST 0 +#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_HI_OFST 4 +#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V3 +/* enum: Start of CTPIO stats buffer space, Medford2 and up */ +#define MC_CMD_MAC_CTPIO_DMABUF_START 0x68 +/* enum: Number of CTPIO fallbacks because a DMA packet was in progress on the + * target VI + */ +#define MC_CMD_MAC_CTPIO_VI_BUSY_FALLBACK 0x68 +/* enum: Number of times a CTPIO send wrote beyond frame end (informational + * only) + */ +#define MC_CMD_MAC_CTPIO_LONG_WRITE_SUCCESS 0x69 +/* enum: Number of CTPIO failures because the TX doorbell was written before + * the end of the frame data + */ +#define MC_CMD_MAC_CTPIO_MISSING_DBELL_FAIL 0x6a +/* enum: Number of CTPIO failures because the internal FIFO overflowed */ +#define MC_CMD_MAC_CTPIO_OVERFLOW_FAIL 0x6b +/* enum: Number of CTPIO failures because the host did not deliver data fast + * enough to avoid MAC underflow + */ +#define MC_CMD_MAC_CTPIO_UNDERFLOW_FAIL 0x6c +/* enum: Number of CTPIO failures because the host did not deliver all the + * frame data within the timeout + */ +#define MC_CMD_MAC_CTPIO_TIMEOUT_FAIL 0x6d +/* enum: Number of CTPIO failures because the frame data arrived out of order + * or with gaps + */ +#define MC_CMD_MAC_CTPIO_NONCONTIG_WR_FAIL 0x6e +/* enum: Number of CTPIO failures because the host started a new frame before + * completing the previous one + */ +#define MC_CMD_MAC_CTPIO_FRM_CLOBBER_FAIL 0x6f +/* enum: Number of CTPIO failures because a write was not a multiple of 32 bits + * or not 32-bit aligned + */ +#define MC_CMD_MAC_CTPIO_INVALID_WR_FAIL 0x70 +/* enum: Number of CTPIO fallbacks because another VI on the same port was + * sending a CTPIO frame + */ +#define MC_CMD_MAC_CTPIO_VI_CLOBBER_FALLBACK 0x71 +/* enum: Number of CTPIO fallbacks because target VI did not have CTPIO enabled + */ +#define MC_CMD_MAC_CTPIO_UNQUALIFIED_FALLBACK 0x72 +/* enum: Number of CTPIO fallbacks because length in header was less than 29 + * bytes + */ +#define MC_CMD_MAC_CTPIO_RUNT_FALLBACK 0x73 +/* enum: Total number of successful CTPIO sends on this port */ +#define MC_CMD_MAC_CTPIO_SUCCESS 0x74 +/* enum: Total number of CTPIO fallbacks on this port */ +#define MC_CMD_MAC_CTPIO_FALLBACK 0x75 +/* enum: Total number of CTPIO poisoned frames on this port, whether erased or + * not + */ +#define MC_CMD_MAC_CTPIO_POISON 0x76 +/* enum: Total number of CTPIO erased frames on this port */ +#define MC_CMD_MAC_CTPIO_ERASE 0x77 +/* enum: This includes the space at offset 120 which is the final + * GENERATION_END in a MAC_STATS_V3 response and otherwise unused. + */ +#define MC_CMD_MAC_NSTATS_V3 0x79 +/* Other enum values, see field(s): */ +/* MC_CMD_MAC_STATS_V2_OUT_NO_DMA/STATISTICS */ + /***********************************/ /* MC_CMD_SRIOV @@ -3318,21 +4173,28 @@ /* MC_CMD_SRIOV_IN msgrequest */ #define MC_CMD_SRIOV_IN_LEN 12 #define MC_CMD_SRIOV_IN_ENABLE_OFST 0 +#define MC_CMD_SRIOV_IN_ENABLE_LEN 4 #define MC_CMD_SRIOV_IN_VI_BASE_OFST 4 +#define MC_CMD_SRIOV_IN_VI_BASE_LEN 4 #define MC_CMD_SRIOV_IN_VF_COUNT_OFST 8 +#define MC_CMD_SRIOV_IN_VF_COUNT_LEN 4 /* MC_CMD_SRIOV_OUT msgresponse */ #define MC_CMD_SRIOV_OUT_LEN 8 #define MC_CMD_SRIOV_OUT_VI_SCALE_OFST 0 +#define MC_CMD_SRIOV_OUT_VI_SCALE_LEN 4 #define MC_CMD_SRIOV_OUT_VF_TOTAL_OFST 4 +#define MC_CMD_SRIOV_OUT_VF_TOTAL_LEN 4 /* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */ #define MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32 /* this is only used for the first record */ #define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LEN 4 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_OFST 4 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_LEN 4 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_LBN 32 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_WIDTH 32 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_OFST 8 @@ -3342,6 +4204,7 @@ #define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LBN 64 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_WIDTH 64 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_OFST 16 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_LEN 4 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE 0x100 /* enum */ #define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_LBN 128 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_WIDTH 32 @@ -3352,6 +4215,7 @@ #define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LBN 160 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_WIDTH 64 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_OFST 28 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_LEN 4 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_LBN 224 #define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_WIDTH 32 @@ -3403,10 +4267,12 @@ /* MC_CMD_WOL_FILTER_SET_IN msgrequest */ #define MC_CMD_WOL_FILTER_SET_IN_LEN 192 #define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 +#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 #define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */ #define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */ /* A type value of 1 is unused. */ #define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 +#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 /* enum: Magic */ #define MC_CMD_WOL_TYPE_MAGIC 0x0 /* enum: MS Windows Magic */ @@ -3428,7 +4294,9 @@ /* MC_CMD_WOL_FILTER_SET_IN_MAGIC msgrequest */ #define MC_CMD_WOL_FILTER_SET_IN_MAGIC_LEN 16 /* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 */ /* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 */ #define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST 8 #define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LEN 8 #define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LO_OFST 8 @@ -3437,9 +4305,13 @@ /* MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN msgrequest */ #define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_LEN 20 /* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 */ /* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 */ #define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_LEN 4 #define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST 12 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_LEN 4 #define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST 16 #define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_LEN 2 #define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST 18 @@ -3448,7 +4320,9 @@ /* MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN msgrequest */ #define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_LEN 44 /* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 */ /* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 */ #define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST 8 #define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_LEN 16 #define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST 24 @@ -3461,7 +4335,9 @@ /* MC_CMD_WOL_FILTER_SET_IN_BITMAP msgrequest */ #define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN 187 /* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 */ /* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 */ #define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST 8 #define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_LEN 48 #define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_OFST 56 @@ -3476,8 +4352,11 @@ /* MC_CMD_WOL_FILTER_SET_IN_LINK msgrequest */ #define MC_CMD_WOL_FILTER_SET_IN_LINK_LEN 12 /* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 */ /* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 */ #define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_LEN 4 #define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0 #define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1 #define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1 @@ -3486,6 +4365,7 @@ /* MC_CMD_WOL_FILTER_SET_OUT msgresponse */ #define MC_CMD_WOL_FILTER_SET_OUT_LEN 4 #define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0 +#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_LEN 4 /***********************************/ @@ -3499,6 +4379,7 @@ /* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */ #define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4 #define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0 +#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_LEN 4 /* MC_CMD_WOL_FILTER_REMOVE_OUT msgresponse */ #define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0 @@ -3516,6 +4397,7 @@ /* MC_CMD_WOL_FILTER_RESET_IN msgrequest */ #define MC_CMD_WOL_FILTER_RESET_IN_LEN 4 #define MC_CMD_WOL_FILTER_RESET_IN_MASK_OFST 0 +#define MC_CMD_WOL_FILTER_RESET_IN_MASK_LEN 4 #define MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS 0x1 /* enum */ #define MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS 0x2 /* enum */ @@ -3556,6 +4438,7 @@ #define MC_CMD_NVRAM_TYPES_OUT_LEN 4 /* Bit mask of supported types. */ #define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0 +#define MC_CMD_NVRAM_TYPES_OUT_TYPES_LEN 4 /* enum: Disabled callisto. */ #define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum: MC firmware. */ @@ -3612,47 +4495,65 @@ /* MC_CMD_NVRAM_INFO_IN msgrequest */ #define MC_CMD_NVRAM_INFO_IN_LEN 4 #define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_INFO_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ /* MC_CMD_NVRAM_INFO_OUT msgresponse */ #define MC_CMD_NVRAM_INFO_OUT_LEN 24 #define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0 +#define MC_CMD_NVRAM_INFO_OUT_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4 +#define MC_CMD_NVRAM_INFO_OUT_SIZE_LEN 4 #define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8 +#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_LEN 4 #define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12 +#define MC_CMD_NVRAM_INFO_OUT_FLAGS_LEN 4 #define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0 #define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1 #define MC_CMD_NVRAM_INFO_OUT_TLV_LBN 1 #define MC_CMD_NVRAM_INFO_OUT_TLV_WIDTH 1 +#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_LBN 5 +#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_WIDTH 1 #define MC_CMD_NVRAM_INFO_OUT_CMAC_LBN 6 #define MC_CMD_NVRAM_INFO_OUT_CMAC_WIDTH 1 #define MC_CMD_NVRAM_INFO_OUT_A_B_LBN 7 #define MC_CMD_NVRAM_INFO_OUT_A_B_WIDTH 1 #define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16 +#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_LEN 4 #define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20 +#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_LEN 4 /* MC_CMD_NVRAM_INFO_V2_OUT msgresponse */ #define MC_CMD_NVRAM_INFO_V2_OUT_LEN 28 #define MC_CMD_NVRAM_INFO_V2_OUT_TYPE_OFST 0 +#define MC_CMD_NVRAM_INFO_V2_OUT_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_INFO_V2_OUT_SIZE_OFST 4 +#define MC_CMD_NVRAM_INFO_V2_OUT_SIZE_LEN 4 #define MC_CMD_NVRAM_INFO_V2_OUT_ERASESIZE_OFST 8 +#define MC_CMD_NVRAM_INFO_V2_OUT_ERASESIZE_LEN 4 #define MC_CMD_NVRAM_INFO_V2_OUT_FLAGS_OFST 12 +#define MC_CMD_NVRAM_INFO_V2_OUT_FLAGS_LEN 4 #define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_LBN 0 #define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_WIDTH 1 #define MC_CMD_NVRAM_INFO_V2_OUT_TLV_LBN 1 #define MC_CMD_NVRAM_INFO_V2_OUT_TLV_WIDTH 1 +#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_LBN 5 +#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_WIDTH 1 #define MC_CMD_NVRAM_INFO_V2_OUT_A_B_LBN 7 #define MC_CMD_NVRAM_INFO_V2_OUT_A_B_WIDTH 1 #define MC_CMD_NVRAM_INFO_V2_OUT_PHYSDEV_OFST 16 +#define MC_CMD_NVRAM_INFO_V2_OUT_PHYSDEV_LEN 4 #define MC_CMD_NVRAM_INFO_V2_OUT_PHYSADDR_OFST 20 +#define MC_CMD_NVRAM_INFO_V2_OUT_PHYSADDR_LEN 4 /* Writes must be multiples of this size. Added to support the MUM on Sorrento. */ #define MC_CMD_NVRAM_INFO_V2_OUT_WRITESIZE_OFST 24 +#define MC_CMD_NVRAM_INFO_V2_OUT_WRITESIZE_LEN 4 /***********************************/ @@ -3670,6 +4571,7 @@ */ #define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4 #define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ @@ -3680,9 +4582,11 @@ */ #define MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN 8 #define MC_CMD_NVRAM_UPDATE_START_V2_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_UPDATE_START_V2_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAGS_OFST 4 +#define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAGS_LEN 4 #define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT_LBN 0 #define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT_WIDTH 1 @@ -3703,20 +4607,26 @@ /* MC_CMD_NVRAM_READ_IN msgrequest */ #define MC_CMD_NVRAM_READ_IN_LEN 12 #define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_READ_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_READ_IN_OFFSET_LEN 4 /* amount to read in bytes */ #define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8 +#define MC_CMD_NVRAM_READ_IN_LENGTH_LEN 4 /* MC_CMD_NVRAM_READ_IN_V2 msgrequest */ #define MC_CMD_NVRAM_READ_IN_V2_LEN 16 #define MC_CMD_NVRAM_READ_IN_V2_TYPE_OFST 0 +#define MC_CMD_NVRAM_READ_IN_V2_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_READ_IN_V2_OFFSET_OFST 4 +#define MC_CMD_NVRAM_READ_IN_V2_OFFSET_LEN 4 /* amount to read in bytes */ #define MC_CMD_NVRAM_READ_IN_V2_LENGTH_OFST 8 +#define MC_CMD_NVRAM_READ_IN_V2_LENGTH_LEN 4 /* Optional control info. If a partition is stored with an A/B versioning * scheme (i.e. in more than one physical partition in NVRAM) the host can set * this to control which underlying physical partition is used to read data @@ -3726,6 +4636,7 @@ * verifying by reading with MODE=TARGET_BACKUP. */ #define MC_CMD_NVRAM_READ_IN_V2_MODE_OFST 12 +#define MC_CMD_NVRAM_READ_IN_V2_MODE_LEN 4 /* enum: Same as omitting MODE: caller sees data in current partition unless it * holds the write lock in which case it sees data in the partition it is * updating. @@ -3765,10 +4676,13 @@ #define MC_CMD_NVRAM_WRITE_IN_LENMAX 252 #define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num)) #define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_WRITE_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_WRITE_IN_OFFSET_LEN 4 #define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8 +#define MC_CMD_NVRAM_WRITE_IN_LENGTH_LEN 4 #define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12 #define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1 #define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1 @@ -3791,10 +4705,13 @@ /* MC_CMD_NVRAM_ERASE_IN msgrequest */ #define MC_CMD_NVRAM_ERASE_IN_LEN 12 #define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_ERASE_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_ERASE_IN_OFFSET_LEN 4 #define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8 +#define MC_CMD_NVRAM_ERASE_IN_LENGTH_LEN 4 /* MC_CMD_NVRAM_ERASE_OUT msgresponse */ #define MC_CMD_NVRAM_ERASE_OUT_LEN 0 @@ -3815,9 +4732,11 @@ */ #define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8 #define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4 +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_LEN 4 /* MC_CMD_NVRAM_UPDATE_FINISH_V2_IN msgrequest: Extended NVRAM_UPDATE_FINISH * request with additional flags indicating version of NVRAM_UPDATE commands in @@ -3826,10 +4745,13 @@ */ #define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN 12 #define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ #define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_REBOOT_OFST 4 +#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_REBOOT_LEN 4 #define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAGS_OFST 8 +#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAGS_LEN 4 #define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT_LBN 0 #define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT_WIDTH 1 @@ -3848,16 +4770,19 @@ * This process takes a few seconds to complete. So is likely to take more than * the MCDI timeout. Hence signature verification is initiated when * MC_CMD_NVRAM_UPDATE_FINISH_V2_IN is received by the firmware, however, the - * MCDI command returns immediately with error code EAGAIN. Subsequent - * NVRAM_UPDATE_FINISH_V2_IN requests also return EAGAIN if the verification is - * in progress. Once the verification has completed, this response payload - * includes the results of the signature verification. Note that the nvram lock - * in firmware is only released after the verification has completed and the - * host has read back the result code from firmware. + * MCDI command is run in a background MCDI processing thread. This response + * payload includes the results of the signature verification. Note that the + * per-partition nvram lock in firmware is only released after the verification + * has completed. */ #define MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN 4 /* Result of nvram update completion processing */ #define MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE_OFST 0 +#define MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE_LEN 4 +/* enum: Invalid return code; only non-zero values are defined. Defined as + * unknown for backwards compatibility with NVRAM_UPDATE_FINISH_OUT. + */ +#define MC_CMD_NVRAM_VERIFY_RC_UNKNOWN 0x0 /* enum: Verify succeeded without any errors. */ #define MC_CMD_NVRAM_VERIFY_RC_SUCCESS 0x1 /* enum: CMS format verification failed due to an internal error. */ @@ -3884,6 +4809,12 @@ * Trusted approver's list. */ #define MC_CMD_NVRAM_VERIFY_RC_NO_SIGNATURE_MATCH 0xb +/* enum: The image contains a test-signed certificate, but the adapter accepts + * only production signed images. + */ +#define MC_CMD_NVRAM_VERIFY_RC_REJECT_TEST_SIGNED 0xc +/* enum: The image has a lower security level than the current firmware. */ +#define MC_CMD_NVRAM_VERIFY_RC_SECURITY_LEVEL_DOWNGRADE 0xd /***********************************/ @@ -3911,6 +4842,7 @@ /* MC_CMD_REBOOT_IN msgrequest */ #define MC_CMD_REBOOT_IN_LEN 4 #define MC_CMD_REBOOT_IN_FLAGS_OFST 0 +#define MC_CMD_REBOOT_IN_FLAGS_LEN 4 #define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 0x1 /* enum */ /* MC_CMD_REBOOT_OUT msgresponse */ @@ -3947,11 +4879,12 @@ */ #define MC_CMD_REBOOT_MODE 0x3f -#define MC_CMD_0x3f_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x3f_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_REBOOT_MODE_IN msgrequest */ #define MC_CMD_REBOOT_MODE_IN_LEN 4 #define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0 +#define MC_CMD_REBOOT_MODE_IN_VALUE_LEN 4 /* enum: Normal. */ #define MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum: Power-on Reset. */ @@ -3966,6 +4899,7 @@ /* MC_CMD_REBOOT_MODE_OUT msgresponse */ #define MC_CMD_REBOOT_MODE_OUT_LEN 4 #define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0 +#define MC_CMD_REBOOT_MODE_OUT_VALUE_LEN 4 /***********************************/ @@ -4001,7 +4935,7 @@ */ #define MC_CMD_SENSOR_INFO 0x41 -#define MC_CMD_0x41_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x41_PRIVILEGE_CTG SRIOV_CTG_GENERAL /* MC_CMD_SENSOR_INFO_IN msgrequest */ #define MC_CMD_SENSOR_INFO_IN_LEN 0 @@ -4015,12 +4949,14 @@ * Page 1 contains sensors 32 to 62 (sensor 63 is the next page bit). etc. */ #define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_OFST 0 +#define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_LEN 4 /* MC_CMD_SENSOR_INFO_OUT msgresponse */ #define MC_CMD_SENSOR_INFO_OUT_LENMIN 4 #define MC_CMD_SENSOR_INFO_OUT_LENMAX 252 #define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num)) #define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 +#define MC_CMD_SENSOR_INFO_OUT_MASK_LEN 4 /* enum: Controller temperature: degC */ #define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 /* enum: Phy common temperature: degC */ @@ -4183,6 +5119,20 @@ #define MC_CMD_SENSOR_BOARD_FRONT_TEMP 0x4f /* enum: Board temperature (back): degC */ #define MC_CMD_SENSOR_BOARD_BACK_TEMP 0x50 +/* enum: 1.8v power current: mA */ +#define MC_CMD_SENSOR_IN_I1V8 0x51 +/* enum: 2.5v power current: mA */ +#define MC_CMD_SENSOR_IN_I2V5 0x52 +/* enum: 3.3v power current: mA */ +#define MC_CMD_SENSOR_IN_I3V3 0x53 +/* enum: 12v power current: mA */ +#define MC_CMD_SENSOR_IN_I12V0 0x54 +/* enum: 1.3v power: mV */ +#define MC_CMD_SENSOR_IN_1V3 0x55 +/* enum: 1.3v power current: mA */ +#define MC_CMD_SENSOR_IN_I1V3 0x56 +/* enum: Not a sensor: reserved for the next page flag */ +#define MC_CMD_SENSOR_PAGE2_NEXT 0x5f /* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */ #define MC_CMD_SENSOR_ENTRY_OFST 4 #define MC_CMD_SENSOR_ENTRY_LEN 8 @@ -4196,6 +5146,7 @@ #define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX 252 #define MC_CMD_SENSOR_INFO_EXT_OUT_LEN(num) (4+8*(num)) #define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_OFST 0 +#define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_SENSOR_INFO_OUT */ #define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_LBN 31 @@ -4247,7 +5198,7 @@ */ #define MC_CMD_READ_SENSORS 0x42 -#define MC_CMD_0x42_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x42_PRIVILEGE_CTG SRIOV_CTG_GENERAL /* MC_CMD_READ_SENSORS_IN msgrequest */ #define MC_CMD_READ_SENSORS_IN_LEN 8 @@ -4266,6 +5217,7 @@ #define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_HI_OFST 4 /* Size in bytes of host buffer. */ #define MC_CMD_READ_SENSORS_EXT_IN_LENGTH_OFST 8 +#define MC_CMD_READ_SENSORS_EXT_IN_LENGTH_LEN 4 /* MC_CMD_READ_SENSORS_OUT msgresponse */ #define MC_CMD_READ_SENSORS_OUT_LEN 0 @@ -4319,6 +5271,7 @@ /* MC_CMD_GET_PHY_STATE_OUT msgresponse */ #define MC_CMD_GET_PHY_STATE_OUT_LEN 4 #define MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0 +#define MC_CMD_GET_PHY_STATE_OUT_STATE_LEN 4 /* enum: Ok. */ #define MC_CMD_PHY_STATE_OK 0x1 /* enum: Faulty. */ @@ -4355,6 +5308,7 @@ /* MC_CMD_WOL_FILTER_GET_OUT msgresponse */ #define MC_CMD_WOL_FILTER_GET_OUT_LEN 4 #define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0 +#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_LEN 4 /***********************************/ @@ -4371,6 +5325,7 @@ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX 252 #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN(num) (4+4*(num)) #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4 #define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */ #define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 /* enum */ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 @@ -4381,13 +5336,16 @@ /* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP msgrequest */ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN 14 /* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4 */ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_OFST 4 #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_LEN 6 #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP_OFST 10 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP_LEN 4 /* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS msgrequest */ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN 42 /* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4 */ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_OFST 4 #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_LEN 6 #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_OFST 10 @@ -4398,6 +5356,7 @@ /* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT msgresponse */ #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4 #define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_LEN 4 /***********************************/ @@ -4412,7 +5371,9 @@ /* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */ #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8 #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4 #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_LEN 4 /* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT msgresponse */ #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0 @@ -4451,6 +5412,7 @@ #define MC_CMD_TESTASSERT_V2_IN_LEN 4 /* How to provoke the assertion */ #define MC_CMD_TESTASSERT_V2_IN_TYPE_OFST 0 +#define MC_CMD_TESTASSERT_V2_IN_TYPE_LEN 4 /* enum: Assert using the FAIL_ASSERTION_WITH_USEFUL_VALUES macro. Unless * you're testing firmware, this is what you want. */ @@ -4486,6 +5448,7 @@ #define MC_CMD_WORKAROUND_IN_LEN 8 /* The enums here must correspond with those in MC_CMD_GET_WORKAROUND. */ #define MC_CMD_WORKAROUND_IN_TYPE_OFST 0 +#define MC_CMD_WORKAROUND_IN_TYPE_LEN 4 /* enum: Bug 17230 work around. */ #define MC_CMD_WORKAROUND_BUG17230 0x1 /* enum: Bug 35388 work around (unsafe EVQ writes). */ @@ -4514,6 +5477,7 @@ * the workaround */ #define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4 +#define MC_CMD_WORKAROUND_IN_ENABLED_LEN 4 /* MC_CMD_WORKAROUND_OUT msgresponse */ #define MC_CMD_WORKAROUND_OUT_LEN 0 @@ -4523,6 +5487,7 @@ */ #define MC_CMD_WORKAROUND_EXT_OUT_LEN 4 #define MC_CMD_WORKAROUND_EXT_OUT_FLAGS_OFST 0 +#define MC_CMD_WORKAROUND_EXT_OUT_FLAGS_LEN 4 #define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN 0 #define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_WIDTH 1 @@ -4543,6 +5508,7 @@ /* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */ #define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 #define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_LEN 4 /* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */ #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5 @@ -4550,6 +5516,7 @@ #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num)) /* in bytes */ #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_LEN 4 #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4 #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1 #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1 @@ -4568,12 +5535,14 @@ /* MC_CMD_NVRAM_TEST_IN msgrequest */ #define MC_CMD_NVRAM_TEST_IN_LEN 4 #define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_TEST_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ /* MC_CMD_NVRAM_TEST_OUT msgresponse */ #define MC_CMD_NVRAM_TEST_OUT_LEN 4 #define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0 +#define MC_CMD_NVRAM_TEST_OUT_RESULT_LEN 4 /* enum: Passed. */ #define MC_CMD_NVRAM_TEST_PASS 0x0 /* enum: Failed. */ @@ -4594,12 +5563,16 @@ #define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16 /* 0-6 low->high de-emph. */ #define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_LEN 4 /* 0-8 low->high ref.V */ #define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_LEN 4 /* 0-8 0-8 low->high boost */ #define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_LEN 4 /* 0-8 low->high ref.V */ #define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_LEN 4 /* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */ #define MC_CMD_MRSFP_TWEAK_IN_READ_ONLY_LEN 0 @@ -4608,10 +5581,13 @@ #define MC_CMD_MRSFP_TWEAK_OUT_LEN 12 /* input bits */ #define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_LEN 4 /* output bits */ #define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_LEN 4 /* direction */ #define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_LEN 4 /* enum: Out. */ #define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum: In. */ @@ -4626,21 +5602,26 @@ */ #define MC_CMD_SENSOR_SET_LIMS 0x4e -#define MC_CMD_0x4e_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x4e_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */ #define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20 #define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0 +#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */ /* interpretation is is sensor-specific. */ #define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4 +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_LEN 4 /* interpretation is is sensor-specific. */ #define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_LEN 4 /* interpretation is is sensor-specific. */ #define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12 +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_LEN 4 /* interpretation is is sensor-specific. */ #define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_LEN 4 /* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */ #define MC_CMD_SENSOR_SET_LIMS_OUT_LEN 0 @@ -4657,9 +5638,13 @@ /* MC_CMD_GET_RESOURCE_LIMITS_OUT msgresponse */ #define MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN 16 #define MC_CMD_GET_RESOURCE_LIMITS_OUT_BUFTBL_OFST 0 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_BUFTBL_LEN 4 #define MC_CMD_GET_RESOURCE_LIMITS_OUT_EVQ_OFST 4 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_EVQ_LEN 4 #define MC_CMD_GET_RESOURCE_LIMITS_OUT_RXQ_OFST 8 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_RXQ_LEN 4 #define MC_CMD_GET_RESOURCE_LIMITS_OUT_TXQ_OFST 12 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_TXQ_LEN 4 /***********************************/ @@ -4680,6 +5665,7 @@ #define MC_CMD_NVRAM_PARTITIONS_OUT_LEN(num) (4+4*(num)) /* total number of partitions */ #define MC_CMD_NVRAM_PARTITIONS_OUT_NUM_PARTITIONS_OFST 0 +#define MC_CMD_NVRAM_PARTITIONS_OUT_NUM_PARTITIONS_LEN 4 /* type ID code for each of NUM_PARTITIONS partitions */ #define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_OFST 4 #define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_LEN 4 @@ -4700,6 +5686,7 @@ #define MC_CMD_NVRAM_METADATA_IN_LEN 4 /* Partition type ID code */ #define MC_CMD_NVRAM_METADATA_IN_TYPE_OFST 0 +#define MC_CMD_NVRAM_METADATA_IN_TYPE_LEN 4 /* MC_CMD_NVRAM_METADATA_OUT msgresponse */ #define MC_CMD_NVRAM_METADATA_OUT_LENMIN 20 @@ -4707,7 +5694,9 @@ #define MC_CMD_NVRAM_METADATA_OUT_LEN(num) (20+1*(num)) /* Partition type ID code */ #define MC_CMD_NVRAM_METADATA_OUT_TYPE_OFST 0 +#define MC_CMD_NVRAM_METADATA_OUT_TYPE_LEN 4 #define MC_CMD_NVRAM_METADATA_OUT_FLAGS_OFST 4 +#define MC_CMD_NVRAM_METADATA_OUT_FLAGS_LEN 4 #define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN 0 #define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_WIDTH 1 #define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_LBN 1 @@ -4716,6 +5705,7 @@ #define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_WIDTH 1 /* Subtype ID code for content of this partition */ #define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_OFST 8 +#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_LEN 4 /* 1st component of W.X.Y.Z version number for content of this partition */ #define MC_CMD_NVRAM_METADATA_OUT_VERSION_W_OFST 12 #define MC_CMD_NVRAM_METADATA_OUT_VERSION_W_LEN 2 @@ -4756,8 +5746,10 @@ #define MC_CMD_GET_MAC_ADDRESSES_OUT_RESERVED_LEN 2 /* Number of allocated MAC addresses */ #define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_COUNT_OFST 8 +#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_COUNT_LEN 4 /* Spacing of allocated MAC addresses */ #define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_STRIDE_OFST 12 +#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_STRIDE_LEN 4 /***********************************/ @@ -4772,6 +5764,7 @@ #define MC_CMD_CLP_IN_LEN 4 /* Sub operation */ #define MC_CMD_CLP_IN_OP_OFST 0 +#define MC_CMD_CLP_IN_OP_LEN 4 /* enum: Return to factory default settings */ #define MC_CMD_CLP_OP_DEFAULT 0x1 /* enum: Set MAC address */ @@ -4789,6 +5782,7 @@ /* MC_CMD_CLP_IN_DEFAULT msgrequest */ #define MC_CMD_CLP_IN_DEFAULT_LEN 4 /* MC_CMD_CLP_IN_OP_OFST 0 */ +/* MC_CMD_CLP_IN_OP_LEN 4 */ /* MC_CMD_CLP_OUT_DEFAULT msgresponse */ #define MC_CMD_CLP_OUT_DEFAULT_LEN 0 @@ -4796,6 +5790,7 @@ /* MC_CMD_CLP_IN_SET_MAC msgrequest */ #define MC_CMD_CLP_IN_SET_MAC_LEN 12 /* MC_CMD_CLP_IN_OP_OFST 0 */ +/* MC_CMD_CLP_IN_OP_LEN 4 */ /* MAC address assigned to port */ #define MC_CMD_CLP_IN_SET_MAC_ADDR_OFST 4 #define MC_CMD_CLP_IN_SET_MAC_ADDR_LEN 6 @@ -4809,6 +5804,7 @@ /* MC_CMD_CLP_IN_GET_MAC msgrequest */ #define MC_CMD_CLP_IN_GET_MAC_LEN 4 /* MC_CMD_CLP_IN_OP_OFST 0 */ +/* MC_CMD_CLP_IN_OP_LEN 4 */ /* MC_CMD_CLP_OUT_GET_MAC msgresponse */ #define MC_CMD_CLP_OUT_GET_MAC_LEN 8 @@ -4822,6 +5818,7 @@ /* MC_CMD_CLP_IN_SET_BOOT msgrequest */ #define MC_CMD_CLP_IN_SET_BOOT_LEN 5 /* MC_CMD_CLP_IN_OP_OFST 0 */ +/* MC_CMD_CLP_IN_OP_LEN 4 */ /* Boot flag */ #define MC_CMD_CLP_IN_SET_BOOT_FLAG_OFST 4 #define MC_CMD_CLP_IN_SET_BOOT_FLAG_LEN 1 @@ -4832,6 +5829,7 @@ /* MC_CMD_CLP_IN_GET_BOOT msgrequest */ #define MC_CMD_CLP_IN_GET_BOOT_LEN 4 /* MC_CMD_CLP_IN_OP_OFST 0 */ +/* MC_CMD_CLP_IN_OP_LEN 4 */ /* MC_CMD_CLP_OUT_GET_BOOT msgresponse */ #define MC_CMD_CLP_OUT_GET_BOOT_LEN 4 @@ -4849,11 +5847,12 @@ */ #define MC_CMD_MUM 0x57 -#define MC_CMD_0x57_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x57_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_MUM_IN msgrequest */ #define MC_CMD_MUM_IN_LEN 4 #define MC_CMD_MUM_IN_OP_HDR_OFST 0 +#define MC_CMD_MUM_IN_OP_HDR_LEN 4 #define MC_CMD_MUM_IN_OP_LBN 0 #define MC_CMD_MUM_IN_OP_WIDTH 8 /* enum: NULL MCDI command to MUM */ @@ -4893,26 +5892,32 @@ #define MC_CMD_MUM_IN_NULL_LEN 4 /* MUM cmd header */ #define MC_CMD_MUM_IN_CMD_OFST 0 +#define MC_CMD_MUM_IN_CMD_LEN 4 /* MC_CMD_MUM_IN_GET_VERSION msgrequest */ #define MC_CMD_MUM_IN_GET_VERSION_LEN 4 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* MC_CMD_MUM_IN_READ msgrequest */ #define MC_CMD_MUM_IN_READ_LEN 16 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* ID of (device connected to MUM) to read from registers of */ #define MC_CMD_MUM_IN_READ_DEVICE_OFST 4 +#define MC_CMD_MUM_IN_READ_DEVICE_LEN 4 /* enum: Hittite HMC1035 clock generator on Sorrento board */ #define MC_CMD_MUM_DEV_HITTITE 0x1 /* enum: Hittite HMC1035 clock generator for NIC-side on Sorrento board */ #define MC_CMD_MUM_DEV_HITTITE_NIC 0x2 /* 32-bit address to read from */ #define MC_CMD_MUM_IN_READ_ADDR_OFST 8 +#define MC_CMD_MUM_IN_READ_ADDR_LEN 4 /* Number of words to read. */ #define MC_CMD_MUM_IN_READ_NUMWORDS_OFST 12 +#define MC_CMD_MUM_IN_READ_NUMWORDS_LEN 4 /* MC_CMD_MUM_IN_WRITE msgrequest */ #define MC_CMD_MUM_IN_WRITE_LENMIN 16 @@ -4920,12 +5925,15 @@ #define MC_CMD_MUM_IN_WRITE_LEN(num) (12+4*(num)) /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* ID of (device connected to MUM) to write to registers of */ #define MC_CMD_MUM_IN_WRITE_DEVICE_OFST 4 +#define MC_CMD_MUM_IN_WRITE_DEVICE_LEN 4 /* enum: Hittite HMC1035 clock generator on Sorrento board */ /* MC_CMD_MUM_DEV_HITTITE 0x1 */ /* 32-bit address to write to */ #define MC_CMD_MUM_IN_WRITE_ADDR_OFST 8 +#define MC_CMD_MUM_IN_WRITE_ADDR_LEN 4 /* Words to write */ #define MC_CMD_MUM_IN_WRITE_BUFFER_OFST 12 #define MC_CMD_MUM_IN_WRITE_BUFFER_LEN 4 @@ -4938,12 +5946,16 @@ #define MC_CMD_MUM_IN_RAW_CMD_LEN(num) (16+1*(num)) /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* MUM I2C cmd code */ #define MC_CMD_MUM_IN_RAW_CMD_CMD_CODE_OFST 4 +#define MC_CMD_MUM_IN_RAW_CMD_CMD_CODE_LEN 4 /* Number of bytes to write */ #define MC_CMD_MUM_IN_RAW_CMD_NUM_WRITE_OFST 8 +#define MC_CMD_MUM_IN_RAW_CMD_NUM_WRITE_LEN 4 /* Number of bytes to read */ #define MC_CMD_MUM_IN_RAW_CMD_NUM_READ_OFST 12 +#define MC_CMD_MUM_IN_RAW_CMD_NUM_READ_LEN 4 /* Bytes to write */ #define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_OFST 16 #define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_LEN 1 @@ -4954,21 +5966,28 @@ #define MC_CMD_MUM_IN_LOG_LEN 8 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_LOG_OP_OFST 4 +#define MC_CMD_MUM_IN_LOG_OP_LEN 4 #define MC_CMD_MUM_IN_LOG_OP_UART 0x1 /* enum */ /* MC_CMD_MUM_IN_LOG_OP_UART msgrequest */ #define MC_CMD_MUM_IN_LOG_OP_UART_LEN 12 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* MC_CMD_MUM_IN_LOG_OP_OFST 4 */ +/* MC_CMD_MUM_IN_LOG_OP_LEN 4 */ /* Enable/disable debug output to UART */ #define MC_CMD_MUM_IN_LOG_OP_UART_ENABLE_OFST 8 +#define MC_CMD_MUM_IN_LOG_OP_UART_ENABLE_LEN 4 /* MC_CMD_MUM_IN_GPIO msgrequest */ #define MC_CMD_MUM_IN_GPIO_LEN 8 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_HDR_LEN 4 #define MC_CMD_MUM_IN_GPIO_OPCODE_LBN 0 #define MC_CMD_MUM_IN_GPIO_OPCODE_WIDTH 8 #define MC_CMD_MUM_IN_GPIO_IN_READ 0x0 /* enum */ @@ -4981,40 +6000,56 @@ /* MC_CMD_MUM_IN_GPIO_IN_READ msgrequest */ #define MC_CMD_MUM_IN_GPIO_IN_READ_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_IN_READ_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_IN_READ_HDR_LEN 4 /* MC_CMD_MUM_IN_GPIO_OUT_WRITE msgrequest */ #define MC_CMD_MUM_IN_GPIO_OUT_WRITE_LEN 16 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OUT_WRITE_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_HDR_LEN 4 /* The first 32-bit word to be written to the GPIO OUT register. */ #define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK1_OFST 8 +#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK1_LEN 4 /* The second 32-bit word to be written to the GPIO OUT register. */ #define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK2_OFST 12 +#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK2_LEN 4 /* MC_CMD_MUM_IN_GPIO_OUT_READ msgrequest */ #define MC_CMD_MUM_IN_GPIO_OUT_READ_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OUT_READ_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OUT_READ_HDR_LEN 4 /* MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE msgrequest */ #define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_LEN 16 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_HDR_LEN 4 /* The first 32-bit word to be written to the GPIO OUT ENABLE register. */ #define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK1_OFST 8 +#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK1_LEN 4 /* The second 32-bit word to be written to the GPIO OUT ENABLE register. */ #define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK2_OFST 12 +#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK2_LEN 4 /* MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ msgrequest */ #define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_HDR_LEN 4 /* MC_CMD_MUM_IN_GPIO_OP msgrequest */ #define MC_CMD_MUM_IN_GPIO_OP_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OP_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OP_HDR_LEN 4 #define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_LBN 8 #define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_WIDTH 8 #define MC_CMD_MUM_IN_GPIO_OP_OUT_READ 0x0 /* enum */ @@ -5027,26 +6062,34 @@ /* MC_CMD_MUM_IN_GPIO_OP_OUT_READ msgrequest */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_HDR_LEN 4 /* MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE msgrequest */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_HDR_LEN 4 #define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_LBN 24 #define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_WIDTH 8 /* MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG msgrequest */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_HDR_LEN 4 #define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_LBN 24 #define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_WIDTH 8 /* MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE msgrequest */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_LEN 8 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_HDR_OFST 4 +#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_HDR_LEN 4 #define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_LBN 24 #define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_WIDTH 8 @@ -5054,7 +6097,9 @@ #define MC_CMD_MUM_IN_READ_SENSORS_LEN 8 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_READ_SENSORS_PARAMS_OFST 4 +#define MC_CMD_MUM_IN_READ_SENSORS_PARAMS_LEN 4 #define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_LBN 0 #define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_WIDTH 8 #define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_LBN 8 @@ -5064,13 +6109,16 @@ #define MC_CMD_MUM_IN_PROGRAM_CLOCKS_LEN 12 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* Bit-mask of clocks to be programmed */ #define MC_CMD_MUM_IN_PROGRAM_CLOCKS_MASK_OFST 4 +#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_MASK_LEN 4 #define MC_CMD_MUM_CLOCK_ID_FPGA 0x0 /* enum */ #define MC_CMD_MUM_CLOCK_ID_DDR 0x1 /* enum */ #define MC_CMD_MUM_CLOCK_ID_NIC 0x2 /* enum */ /* Control flags for clock programming */ #define MC_CMD_MUM_IN_PROGRAM_CLOCKS_FLAGS_OFST 8 +#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_FLAGS_LEN 4 #define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_LBN 0 #define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_WIDTH 1 #define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_NIC_FROM_FPGA_LBN 1 @@ -5082,19 +6130,24 @@ #define MC_CMD_MUM_IN_FPGA_LOAD_LEN 8 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* Enable/Disable FPGA config from flash */ #define MC_CMD_MUM_IN_FPGA_LOAD_ENABLE_OFST 4 +#define MC_CMD_MUM_IN_FPGA_LOAD_ENABLE_LEN 4 /* MC_CMD_MUM_IN_READ_ATB_SENSOR msgrequest */ #define MC_CMD_MUM_IN_READ_ATB_SENSOR_LEN 4 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* MC_CMD_MUM_IN_QSFP msgrequest */ #define MC_CMD_MUM_IN_QSFP_LEN 12 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_OPCODE_LBN 0 #define MC_CMD_MUM_IN_QSFP_OPCODE_WIDTH 4 #define MC_CMD_MUM_IN_QSFP_INIT 0x0 /* enum */ @@ -5104,52 +6157,77 @@ #define MC_CMD_MUM_IN_QSFP_FILL_STATS 0x4 /* enum */ #define MC_CMD_MUM_IN_QSFP_POLL_BIST 0x5 /* enum */ #define MC_CMD_MUM_IN_QSFP_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_IDX_LEN 4 /* MC_CMD_MUM_IN_QSFP_INIT msgrequest */ #define MC_CMD_MUM_IN_QSFP_INIT_LEN 16 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_INIT_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_INIT_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_INIT_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_INIT_IDX_LEN 4 #define MC_CMD_MUM_IN_QSFP_INIT_CAGE_OFST 12 +#define MC_CMD_MUM_IN_QSFP_INIT_CAGE_LEN 4 /* MC_CMD_MUM_IN_QSFP_RECONFIGURE msgrequest */ #define MC_CMD_MUM_IN_QSFP_RECONFIGURE_LEN 24 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_RECONFIGURE_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_RECONFIGURE_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_IDX_LEN 4 #define MC_CMD_MUM_IN_QSFP_RECONFIGURE_TX_DISABLE_OFST 12 +#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_TX_DISABLE_LEN 4 #define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LANES_OFST 16 +#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LANES_LEN 4 #define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LINK_SPEED_OFST 20 +#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LINK_SPEED_LEN 4 /* MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP msgrequest */ #define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_LEN 12 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_IDX_LEN 4 /* MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO msgrequest */ #define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_LEN 16 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_IDX_LEN 4 #define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_PAGE_OFST 12 +#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_PAGE_LEN 4 /* MC_CMD_MUM_IN_QSFP_FILL_STATS msgrequest */ #define MC_CMD_MUM_IN_QSFP_FILL_STATS_LEN 12 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_FILL_STATS_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_FILL_STATS_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_FILL_STATS_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_FILL_STATS_IDX_LEN 4 /* MC_CMD_MUM_IN_QSFP_POLL_BIST msgrequest */ #define MC_CMD_MUM_IN_QSFP_POLL_BIST_LEN 12 /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ #define MC_CMD_MUM_IN_QSFP_POLL_BIST_HDR_OFST 4 +#define MC_CMD_MUM_IN_QSFP_POLL_BIST_HDR_LEN 4 #define MC_CMD_MUM_IN_QSFP_POLL_BIST_IDX_OFST 8 +#define MC_CMD_MUM_IN_QSFP_POLL_BIST_IDX_LEN 4 /* MC_CMD_MUM_IN_READ_DDR_INFO msgrequest */ #define MC_CMD_MUM_IN_READ_DDR_INFO_LEN 4 /* MUM cmd header */ /* MC_CMD_MUM_IN_CMD_OFST 0 */ +/* MC_CMD_MUM_IN_CMD_LEN 4 */ /* MC_CMD_MUM_OUT msgresponse */ #define MC_CMD_MUM_OUT_LEN 0 @@ -5160,6 +6238,7 @@ /* MC_CMD_MUM_OUT_GET_VERSION msgresponse */ #define MC_CMD_MUM_OUT_GET_VERSION_LEN 12 #define MC_CMD_MUM_OUT_GET_VERSION_FIRMWARE_OFST 0 +#define MC_CMD_MUM_OUT_GET_VERSION_FIRMWARE_LEN 4 #define MC_CMD_MUM_OUT_GET_VERSION_VERSION_OFST 4 #define MC_CMD_MUM_OUT_GET_VERSION_VERSION_LEN 8 #define MC_CMD_MUM_OUT_GET_VERSION_VERSION_LO_OFST 4 @@ -5197,8 +6276,10 @@ #define MC_CMD_MUM_OUT_GPIO_IN_READ_LEN 8 /* The first 32-bit word read from the GPIO IN register. */ #define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK1_OFST 0 +#define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK1_LEN 4 /* The second 32-bit word read from the GPIO IN register. */ #define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK2_OFST 4 +#define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK2_LEN 4 /* MC_CMD_MUM_OUT_GPIO_OUT_WRITE msgresponse */ #define MC_CMD_MUM_OUT_GPIO_OUT_WRITE_LEN 0 @@ -5207,8 +6288,10 @@ #define MC_CMD_MUM_OUT_GPIO_OUT_READ_LEN 8 /* The first 32-bit word read from the GPIO OUT register. */ #define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK1_OFST 0 +#define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK1_LEN 4 /* The second 32-bit word read from the GPIO OUT register. */ #define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK2_OFST 4 +#define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK2_LEN 4 /* MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_WRITE msgresponse */ #define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_WRITE_LEN 0 @@ -5216,11 +6299,14 @@ /* MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ msgresponse */ #define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_LEN 8 #define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK1_OFST 0 +#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK1_LEN 4 #define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK2_OFST 4 +#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK2_LEN 4 /* MC_CMD_MUM_OUT_GPIO_OP_OUT_READ msgresponse */ #define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_LEN 4 #define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_BIT_READ_OFST 0 +#define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_BIT_READ_LEN 4 /* MC_CMD_MUM_OUT_GPIO_OP_OUT_WRITE msgresponse */ #define MC_CMD_MUM_OUT_GPIO_OP_OUT_WRITE_LEN 0 @@ -5249,6 +6335,7 @@ /* MC_CMD_MUM_OUT_PROGRAM_CLOCKS msgresponse */ #define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_LEN 4 #define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_OK_MASK_OFST 0 +#define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_OK_MASK_LEN 4 /* MC_CMD_MUM_OUT_FPGA_LOAD msgresponse */ #define MC_CMD_MUM_OUT_FPGA_LOAD_LEN 0 @@ -5256,6 +6343,7 @@ /* MC_CMD_MUM_OUT_READ_ATB_SENSOR msgresponse */ #define MC_CMD_MUM_OUT_READ_ATB_SENSOR_LEN 4 #define MC_CMD_MUM_OUT_READ_ATB_SENSOR_RESULT_OFST 0 +#define MC_CMD_MUM_OUT_READ_ATB_SENSOR_RESULT_LEN 4 /* MC_CMD_MUM_OUT_QSFP_INIT msgresponse */ #define MC_CMD_MUM_OUT_QSFP_INIT_LEN 0 @@ -5263,7 +6351,9 @@ /* MC_CMD_MUM_OUT_QSFP_RECONFIGURE msgresponse */ #define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_LEN 8 #define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LP_CAP_OFST 0 +#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LP_CAP_LEN 4 #define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_FLAGS_OFST 4 +#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_FLAGS_LEN 4 #define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_LBN 0 #define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_WIDTH 1 #define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_LBN 1 @@ -5272,6 +6362,7 @@ /* MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP msgresponse */ #define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_LEN 4 #define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_PORT_PHY_LP_CAP_OFST 0 +#define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_PORT_PHY_LP_CAP_LEN 4 /* MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO msgresponse */ #define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMIN 5 @@ -5279,6 +6370,7 @@ #define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LEN(num) (4+1*(num)) /* in bytes */ #define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATALEN_OFST 0 +#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATALEN_LEN 4 #define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_OFST 4 #define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_LEN 1 #define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MINNUM 1 @@ -5287,11 +6379,14 @@ /* MC_CMD_MUM_OUT_QSFP_FILL_STATS msgresponse */ #define MC_CMD_MUM_OUT_QSFP_FILL_STATS_LEN 8 #define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PMA_PMD_LINK_UP_OFST 0 +#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PMA_PMD_LINK_UP_LEN 4 #define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PCS_LINK_UP_OFST 4 +#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PCS_LINK_UP_LEN 4 /* MC_CMD_MUM_OUT_QSFP_POLL_BIST msgresponse */ #define MC_CMD_MUM_OUT_QSFP_POLL_BIST_LEN 4 #define MC_CMD_MUM_OUT_QSFP_POLL_BIST_TEST_OFST 0 +#define MC_CMD_MUM_OUT_QSFP_POLL_BIST_TEST_LEN 4 /* MC_CMD_MUM_OUT_READ_DDR_INFO msgresponse */ #define MC_CMD_MUM_OUT_READ_DDR_INFO_LENMIN 24 @@ -5299,12 +6394,14 @@ #define MC_CMD_MUM_OUT_READ_DDR_INFO_LEN(num) (8+8*(num)) /* Discrete (soldered) DDR resistor strap info */ #define MC_CMD_MUM_OUT_READ_DDR_INFO_DISCRETE_DDR_INFO_OFST 0 +#define MC_CMD_MUM_OUT_READ_DDR_INFO_DISCRETE_DDR_INFO_LEN 4 #define MC_CMD_MUM_OUT_READ_DDR_INFO_VRATIO_LBN 0 #define MC_CMD_MUM_OUT_READ_DDR_INFO_VRATIO_WIDTH 16 #define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED1_LBN 16 #define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED1_WIDTH 16 /* Number of SODIMM info records */ #define MC_CMD_MUM_OUT_READ_DDR_INFO_NUM_RECORDS_OFST 4 +#define MC_CMD_MUM_OUT_READ_DDR_INFO_NUM_RECORDS_LEN 4 /* Array of SODIMM info records */ #define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_OFST 8 #define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_LEN 8 @@ -5365,6 +6462,7 @@ /* EVB_PORT_ID structuredef */ #define EVB_PORT_ID_LEN 4 #define EVB_PORT_ID_PORT_ID_OFST 0 +#define EVB_PORT_ID_PORT_ID_LEN 4 /* enum: An invalid port handle. */ #define EVB_PORT_ID_NULL 0x0 /* enum: The port assigned to this function.. */ @@ -5460,6 +6558,10 @@ #define NVRAM_PARTITION_TYPE_FC_LOG 0xb04 /* enum: MUM firmware partition */ #define NVRAM_PARTITION_TYPE_MUM_FIRMWARE 0xc00 +/* enum: SUC firmware partition (this is intentionally an alias of + * MUM_FIRMWARE) + */ +#define NVRAM_PARTITION_TYPE_SUC_FIRMWARE 0xc00 /* enum: MUM Non-volatile log output partition. */ #define NVRAM_PARTITION_TYPE_MUM_LOG 0xc01 /* enum: MUM Application table partition. */ @@ -5474,8 +6576,8 @@ #define NVRAM_PARTITION_TYPE_MUM_FUSELOCK 0xc06 /* enum: UEFI expansion ROM if separate from PXE */ #define NVRAM_PARTITION_TYPE_EXPANSION_UEFI 0xd00 -/* enum: Spare partition 0 */ -#define NVRAM_PARTITION_TYPE_SPARE_0 0x1000 +/* enum: Used by the expansion ROM for logging */ +#define NVRAM_PARTITION_TYPE_PXE_LOG 0x1000 /* enum: Used for XIP code of shmbooted images */ #define NVRAM_PARTITION_TYPE_XIP_SCRATCH 0x1100 /* enum: Spare partition 2 */ @@ -5488,6 +6590,27 @@ #define NVRAM_PARTITION_TYPE_SPARE_4 0x1400 /* enum: Spare partition 5 */ #define NVRAM_PARTITION_TYPE_SPARE_5 0x1500 +/* enum: Partition for reporting MC status. See mc_flash_layout.h + * medford_mc_status_hdr_t for layout on Medford. + */ +#define NVRAM_PARTITION_TYPE_STATUS 0x1600 +/* enum: Spare partition 13 */ +#define NVRAM_PARTITION_TYPE_SPARE_13 0x1700 +/* enum: Spare partition 14 */ +#define NVRAM_PARTITION_TYPE_SPARE_14 0x1800 +/* enum: Spare partition 15 */ +#define NVRAM_PARTITION_TYPE_SPARE_15 0x1900 +/* enum: Spare partition 16 */ +#define NVRAM_PARTITION_TYPE_SPARE_16 0x1a00 +/* enum: Factory defaults for dynamic configuration */ +#define NVRAM_PARTITION_TYPE_DYNCONFIG_DEFAULTS 0x1b00 +/* enum: Factory defaults for expansion ROM configuration */ +#define NVRAM_PARTITION_TYPE_ROMCONFIG_DEFAULTS 0x1c00 +/* enum: Field Replaceable Unit inventory information for use on IPMI + * platforms. See SF-119124-PS. The STATIC_CONFIG partition may contain a + * subset of the information stored in this partition. + */ +#define NVRAM_PARTITION_TYPE_FRU_INFORMATION 0x1d00 /* enum: Start of reserved value range (firmware may use for any purpose) */ #define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MIN 0xff00 /* enum: End of reserved value range (firmware may use for any purpose) */ @@ -5502,6 +6625,7 @@ /* LICENSED_APP_ID structuredef */ #define LICENSED_APP_ID_LEN 4 #define LICENSED_APP_ID_ID_OFST 0 +#define LICENSED_APP_ID_ID_LEN 4 /* enum: OpenOnload */ #define LICENSED_APP_ID_ONLOAD 0x1 /* enum: PTP timestamping */ @@ -5526,6 +6650,14 @@ #define LICENSED_APP_ID_SOLARCAPTURE_TAP 0x400 /* enum: Capture SolarSystem 40G */ #define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM_40G 0x800 +/* enum: Capture SolarSystem 1G */ +#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM_1G 0x1000 +/* enum: ScaleOut Onload */ +#define LICENSED_APP_ID_SCALEOUT_ONLOAD 0x2000 +/* enum: SCS Network Analytics Dashboard */ +#define LICENSED_APP_ID_DSHBRD 0x4000 +/* enum: SolarCapture Trading Analytics */ +#define LICENSED_APP_ID_SCATRD 0x8000 #define LICENSED_APP_ID_ID_LBN 0 #define LICENSED_APP_ID_ID_WIDTH 32 @@ -5590,6 +6722,14 @@ #define LICENSED_V3_APPS_SOLARCAPTURE_TAP_WIDTH 1 #define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_40G_LBN 11 #define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_40G_WIDTH 1 +#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_1G_LBN 12 +#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_1G_WIDTH 1 +#define LICENSED_V3_APPS_SCALEOUT_ONLOAD_LBN 13 +#define LICENSED_V3_APPS_SCALEOUT_ONLOAD_WIDTH 1 +#define LICENSED_V3_APPS_DSHBRD_LBN 14 +#define LICENSED_V3_APPS_DSHBRD_WIDTH 1 +#define LICENSED_V3_APPS_SCATRD_LBN 15 +#define LICENSED_V3_APPS_SCATRD_WIDTH 1 #define LICENSED_V3_APPS_MASK_LBN 0 #define LICENSED_V3_APPS_MASK_WIDTH 64 @@ -5636,6 +6776,18 @@ #define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LEN 1 /* enum: This is a TX completion event, not a timestamp */ #define TX_TIMESTAMP_EVENT_TX_EV_COMPLETION 0x0 +/* enum: This is a TX completion event for a CTPIO transmit. The event format + * is the same as for TX_EV_COMPLETION. + */ +#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_COMPLETION 0x11 +/* enum: This is the low part of a TX timestamp for a CTPIO transmission. The + * event format is the same as for TX_EV_TSTAMP_LO + */ +#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_TS_LO 0x12 +/* enum: This is the high part of a TX timestamp for a CTPIO transmission. The + * event format is the same as for TX_EV_TSTAMP_HI + */ +#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_TS_HI 0x13 /* enum: This is the low part of a TX timestamp event */ #define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO 0x51 /* enum: This is the high part of a TX timestamp event */ @@ -5669,6 +6821,19 @@ #define RSS_MODE_HASH_SELECTOR_LBN 0 #define RSS_MODE_HASH_SELECTOR_WIDTH 8 +/* CTPIO_STATS_MAP structuredef */ +#define CTPIO_STATS_MAP_LEN 4 +/* The (function relative) VI number */ +#define CTPIO_STATS_MAP_VI_OFST 0 +#define CTPIO_STATS_MAP_VI_LEN 2 +#define CTPIO_STATS_MAP_VI_LBN 0 +#define CTPIO_STATS_MAP_VI_WIDTH 16 +/* The target bucket for the VI */ +#define CTPIO_STATS_MAP_BUCKET_OFST 2 +#define CTPIO_STATS_MAP_BUCKET_LEN 2 +#define CTPIO_STATS_MAP_BUCKET_LBN 16 +#define CTPIO_STATS_MAP_BUCKET_WIDTH 16 + /***********************************/ /* MC_CMD_READ_REGS @@ -5676,7 +6841,7 @@ */ #define MC_CMD_READ_REGS 0x50 -#define MC_CMD_0x50_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x50_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_READ_REGS_IN msgrequest */ #define MC_CMD_READ_REGS_IN_LEN 0 @@ -5709,17 +6874,22 @@ #define MC_CMD_INIT_EVQ_IN_LEN(num) (36+8*(num)) /* Size, in entries */ #define MC_CMD_INIT_EVQ_IN_SIZE_OFST 0 +#define MC_CMD_INIT_EVQ_IN_SIZE_LEN 4 /* Desired instance. Must be set to a specific instance, which is a function * local queue index. */ #define MC_CMD_INIT_EVQ_IN_INSTANCE_OFST 4 +#define MC_CMD_INIT_EVQ_IN_INSTANCE_LEN 4 /* The initial timer value. The load value is ignored if the timer mode is DIS. */ #define MC_CMD_INIT_EVQ_IN_TMR_LOAD_OFST 8 +#define MC_CMD_INIT_EVQ_IN_TMR_LOAD_LEN 4 /* The reload value is ignored in one-shot modes */ #define MC_CMD_INIT_EVQ_IN_TMR_RELOAD_OFST 12 +#define MC_CMD_INIT_EVQ_IN_TMR_RELOAD_LEN 4 /* tbd */ #define MC_CMD_INIT_EVQ_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_EVQ_IN_FLAGS_LEN 4 #define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_LBN 0 #define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_WIDTH 1 #define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_LBN 1 @@ -5735,6 +6905,7 @@ #define MC_CMD_INIT_EVQ_IN_FLAG_USE_TIMER_LBN 6 #define MC_CMD_INIT_EVQ_IN_FLAG_USE_TIMER_WIDTH 1 #define MC_CMD_INIT_EVQ_IN_TMR_MODE_OFST 20 +#define MC_CMD_INIT_EVQ_IN_TMR_MODE_LEN 4 /* enum: Disabled */ #define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS 0x0 /* enum: Immediate */ @@ -5745,13 +6916,16 @@ #define MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF 0x3 /* Target EVQ for wakeups if in wakeup mode. */ #define MC_CMD_INIT_EVQ_IN_TARGET_EVQ_OFST 24 +#define MC_CMD_INIT_EVQ_IN_TARGET_EVQ_LEN 4 /* Target interrupt if in interrupting mode (note union with target EVQ). Use * MC_CMD_RESOURCE_INSTANCE_ANY unless a specific one required for test * purposes. */ #define MC_CMD_INIT_EVQ_IN_IRQ_NUM_OFST 24 +#define MC_CMD_INIT_EVQ_IN_IRQ_NUM_LEN 4 /* Event Counter Mode. */ #define MC_CMD_INIT_EVQ_IN_COUNT_MODE_OFST 28 +#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_LEN 4 /* enum: Disabled */ #define MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS 0x0 /* enum: Disabled */ @@ -5762,6 +6936,7 @@ #define MC_CMD_INIT_EVQ_IN_COUNT_MODE_RXTX 0x3 /* Event queue packet count threshold. */ #define MC_CMD_INIT_EVQ_IN_COUNT_THRSHLD_OFST 32 +#define MC_CMD_INIT_EVQ_IN_COUNT_THRSHLD_LEN 4 /* 64-bit address of 4k of 4k-aligned host memory buffer */ #define MC_CMD_INIT_EVQ_IN_DMA_ADDR_OFST 36 #define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LEN 8 @@ -5774,6 +6949,7 @@ #define MC_CMD_INIT_EVQ_OUT_LEN 4 /* Only valid if INTRFLAG was true */ #define MC_CMD_INIT_EVQ_OUT_IRQ_OFST 0 +#define MC_CMD_INIT_EVQ_OUT_IRQ_LEN 4 /* MC_CMD_INIT_EVQ_V2_IN msgrequest */ #define MC_CMD_INIT_EVQ_V2_IN_LENMIN 44 @@ -5781,17 +6957,22 @@ #define MC_CMD_INIT_EVQ_V2_IN_LEN(num) (36+8*(num)) /* Size, in entries */ #define MC_CMD_INIT_EVQ_V2_IN_SIZE_OFST 0 +#define MC_CMD_INIT_EVQ_V2_IN_SIZE_LEN 4 /* Desired instance. Must be set to a specific instance, which is a function * local queue index. */ #define MC_CMD_INIT_EVQ_V2_IN_INSTANCE_OFST 4 +#define MC_CMD_INIT_EVQ_V2_IN_INSTANCE_LEN 4 /* The initial timer value. The load value is ignored if the timer mode is DIS. */ #define MC_CMD_INIT_EVQ_V2_IN_TMR_LOAD_OFST 8 +#define MC_CMD_INIT_EVQ_V2_IN_TMR_LOAD_LEN 4 /* The reload value is ignored in one-shot modes */ #define MC_CMD_INIT_EVQ_V2_IN_TMR_RELOAD_OFST 12 +#define MC_CMD_INIT_EVQ_V2_IN_TMR_RELOAD_LEN 4 /* tbd */ #define MC_CMD_INIT_EVQ_V2_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_EVQ_V2_IN_FLAGS_LEN 4 #define MC_CMD_INIT_EVQ_V2_IN_FLAG_INTERRUPTING_LBN 0 #define MC_CMD_INIT_EVQ_V2_IN_FLAG_INTERRUPTING_WIDTH 1 #define MC_CMD_INIT_EVQ_V2_IN_FLAG_RPTR_DOS_LBN 1 @@ -5828,6 +7009,7 @@ */ #define MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO 0x3 #define MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_OFST 20 +#define MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_LEN 4 /* enum: Disabled */ #define MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_DIS 0x0 /* enum: Immediate */ @@ -5838,13 +7020,16 @@ #define MC_CMD_INIT_EVQ_V2_IN_TMR_INT_HLDOFF 0x3 /* Target EVQ for wakeups if in wakeup mode. */ #define MC_CMD_INIT_EVQ_V2_IN_TARGET_EVQ_OFST 24 +#define MC_CMD_INIT_EVQ_V2_IN_TARGET_EVQ_LEN 4 /* Target interrupt if in interrupting mode (note union with target EVQ). Use * MC_CMD_RESOURCE_INSTANCE_ANY unless a specific one required for test * purposes. */ #define MC_CMD_INIT_EVQ_V2_IN_IRQ_NUM_OFST 24 +#define MC_CMD_INIT_EVQ_V2_IN_IRQ_NUM_LEN 4 /* Event Counter Mode. */ #define MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_OFST 28 +#define MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_LEN 4 /* enum: Disabled */ #define MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_DIS 0x0 /* enum: Disabled */ @@ -5855,6 +7040,7 @@ #define MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_RXTX 0x3 /* Event queue packet count threshold. */ #define MC_CMD_INIT_EVQ_V2_IN_COUNT_THRSHLD_OFST 32 +#define MC_CMD_INIT_EVQ_V2_IN_COUNT_THRSHLD_LEN 4 /* 64-bit address of 4k of 4k-aligned host memory buffer */ #define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_OFST 36 #define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_LEN 8 @@ -5867,8 +7053,10 @@ #define MC_CMD_INIT_EVQ_V2_OUT_LEN 8 /* Only valid if INTRFLAG was true */ #define MC_CMD_INIT_EVQ_V2_OUT_IRQ_OFST 0 +#define MC_CMD_INIT_EVQ_V2_OUT_IRQ_LEN 4 /* Actual configuration applied on the card */ #define MC_CMD_INIT_EVQ_V2_OUT_FLAGS_OFST 4 +#define MC_CMD_INIT_EVQ_V2_OUT_FLAGS_LEN 4 #define MC_CMD_INIT_EVQ_V2_OUT_FLAG_CUT_THRU_LBN 0 #define MC_CMD_INIT_EVQ_V2_OUT_FLAG_CUT_THRU_WIDTH 1 #define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RX_MERGE_LBN 1 @@ -5916,17 +7104,22 @@ #define MC_CMD_INIT_RXQ_IN_LEN(num) (28+8*(num)) /* Size, in entries */ #define MC_CMD_INIT_RXQ_IN_SIZE_OFST 0 +#define MC_CMD_INIT_RXQ_IN_SIZE_LEN 4 /* The EVQ to send events to. This is an index originally specified to INIT_EVQ */ #define MC_CMD_INIT_RXQ_IN_TARGET_EVQ_OFST 4 +#define MC_CMD_INIT_RXQ_IN_TARGET_EVQ_LEN 4 /* The value to put in the event data. Check hardware spec. for valid range. */ #define MC_CMD_INIT_RXQ_IN_LABEL_OFST 8 +#define MC_CMD_INIT_RXQ_IN_LABEL_LEN 4 /* Desired instance. Must be set to a specific instance, which is a function * local queue index. */ #define MC_CMD_INIT_RXQ_IN_INSTANCE_OFST 12 +#define MC_CMD_INIT_RXQ_IN_INSTANCE_LEN 4 /* There will be more flags here. */ #define MC_CMD_INIT_RXQ_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_RXQ_IN_FLAGS_LEN 4 #define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_LBN 0 #define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_WIDTH 1 #define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_LBN 1 @@ -5945,8 +7138,10 @@ #define MC_CMD_INIT_RXQ_IN_UNUSED_WIDTH 1 /* Owner ID to use if in buffer mode (zero if physical) */ #define MC_CMD_INIT_RXQ_IN_OWNER_ID_OFST 20 +#define MC_CMD_INIT_RXQ_IN_OWNER_ID_LEN 4 /* The port ID associated with the v-adaptor which should contain this DMAQ. */ #define MC_CMD_INIT_RXQ_IN_PORT_ID_OFST 24 +#define MC_CMD_INIT_RXQ_IN_PORT_ID_LEN 4 /* 64-bit address of 4k of 4k-aligned host memory buffer */ #define MC_CMD_INIT_RXQ_IN_DMA_ADDR_OFST 28 #define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LEN 8 @@ -5961,17 +7156,22 @@ #define MC_CMD_INIT_RXQ_EXT_IN_LEN 544 /* Size, in entries */ #define MC_CMD_INIT_RXQ_EXT_IN_SIZE_OFST 0 +#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_LEN 4 /* The EVQ to send events to. This is an index originally specified to INIT_EVQ */ #define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_OFST 4 +#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_LEN 4 /* The value to put in the event data. Check hardware spec. for valid range. */ #define MC_CMD_INIT_RXQ_EXT_IN_LABEL_OFST 8 +#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_LEN 4 /* Desired instance. Must be set to a specific instance, which is a function * local queue index. */ #define MC_CMD_INIT_RXQ_EXT_IN_INSTANCE_OFST 12 +#define MC_CMD_INIT_RXQ_EXT_IN_INSTANCE_LEN 4 /* There will be more flags here. */ #define MC_CMD_INIT_RXQ_EXT_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_RXQ_EXT_IN_FLAGS_LEN 4 #define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0 #define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1 #define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_LBN 1 @@ -6007,8 +7207,10 @@ #define MC_CMD_INIT_RXQ_EXT_IN_FLAG_FORCE_EV_MERGING_WIDTH 1 /* Owner ID to use if in buffer mode (zero if physical) */ #define MC_CMD_INIT_RXQ_EXT_IN_OWNER_ID_OFST 20 +#define MC_CMD_INIT_RXQ_EXT_IN_OWNER_ID_LEN 4 /* The port ID associated with the v-adaptor which should contain this DMAQ. */ #define MC_CMD_INIT_RXQ_EXT_IN_PORT_ID_OFST 24 +#define MC_CMD_INIT_RXQ_EXT_IN_PORT_ID_LEN 4 /* 64-bit address of 4k of 4k-aligned host memory buffer */ #define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_OFST 28 #define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_LEN 8 @@ -6017,6 +7219,7 @@ #define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_NUM 64 /* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */ #define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_OFST 540 +#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_LEN 4 /* MC_CMD_INIT_RXQ_OUT msgresponse */ #define MC_CMD_INIT_RXQ_OUT_LEN 0 @@ -6040,18 +7243,23 @@ #define MC_CMD_INIT_TXQ_IN_LEN(num) (28+8*(num)) /* Size, in entries */ #define MC_CMD_INIT_TXQ_IN_SIZE_OFST 0 +#define MC_CMD_INIT_TXQ_IN_SIZE_LEN 4 /* The EVQ to send events to. This is an index originally specified to * INIT_EVQ. */ #define MC_CMD_INIT_TXQ_IN_TARGET_EVQ_OFST 4 +#define MC_CMD_INIT_TXQ_IN_TARGET_EVQ_LEN 4 /* The value to put in the event data. Check hardware spec. for valid range. */ #define MC_CMD_INIT_TXQ_IN_LABEL_OFST 8 +#define MC_CMD_INIT_TXQ_IN_LABEL_LEN 4 /* Desired instance. Must be set to a specific instance, which is a function * local queue index. */ #define MC_CMD_INIT_TXQ_IN_INSTANCE_OFST 12 +#define MC_CMD_INIT_TXQ_IN_INSTANCE_LEN 4 /* There will be more flags here. */ #define MC_CMD_INIT_TXQ_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_TXQ_IN_FLAGS_LEN 4 #define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_LBN 0 #define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_WIDTH 1 #define MC_CMD_INIT_TXQ_IN_FLAG_IP_CSUM_DIS_LBN 1 @@ -6072,8 +7280,10 @@ #define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1 /* Owner ID to use if in buffer mode (zero if physical) */ #define MC_CMD_INIT_TXQ_IN_OWNER_ID_OFST 20 +#define MC_CMD_INIT_TXQ_IN_OWNER_ID_LEN 4 /* The port ID associated with the v-adaptor which should contain this DMAQ. */ #define MC_CMD_INIT_TXQ_IN_PORT_ID_OFST 24 +#define MC_CMD_INIT_TXQ_IN_PORT_ID_LEN 4 /* 64-bit address of 4k of 4k-aligned host memory buffer */ #define MC_CMD_INIT_TXQ_IN_DMA_ADDR_OFST 28 #define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LEN 8 @@ -6088,18 +7298,23 @@ #define MC_CMD_INIT_TXQ_EXT_IN_LEN 544 /* Size, in entries */ #define MC_CMD_INIT_TXQ_EXT_IN_SIZE_OFST 0 +#define MC_CMD_INIT_TXQ_EXT_IN_SIZE_LEN 4 /* The EVQ to send events to. This is an index originally specified to * INIT_EVQ. */ #define MC_CMD_INIT_TXQ_EXT_IN_TARGET_EVQ_OFST 4 +#define MC_CMD_INIT_TXQ_EXT_IN_TARGET_EVQ_LEN 4 /* The value to put in the event data. Check hardware spec. for valid range. */ #define MC_CMD_INIT_TXQ_EXT_IN_LABEL_OFST 8 +#define MC_CMD_INIT_TXQ_EXT_IN_LABEL_LEN 4 /* Desired instance. Must be set to a specific instance, which is a function * local queue index. */ #define MC_CMD_INIT_TXQ_EXT_IN_INSTANCE_OFST 12 +#define MC_CMD_INIT_TXQ_EXT_IN_INSTANCE_LEN 4 /* There will be more flags here. */ #define MC_CMD_INIT_TXQ_EXT_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_TXQ_EXT_IN_FLAGS_LEN 4 #define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0 #define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1 #define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_LBN 1 @@ -6122,10 +7337,14 @@ #define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TSOV2_EN_WIDTH 1 #define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_LBN 13 #define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_WIDTH 1 +#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_UTHRESH_LBN 14 +#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_UTHRESH_WIDTH 1 /* Owner ID to use if in buffer mode (zero if physical) */ #define MC_CMD_INIT_TXQ_EXT_IN_OWNER_ID_OFST 20 +#define MC_CMD_INIT_TXQ_EXT_IN_OWNER_ID_LEN 4 /* The port ID associated with the v-adaptor which should contain this DMAQ. */ #define MC_CMD_INIT_TXQ_EXT_IN_PORT_ID_OFST 24 +#define MC_CMD_INIT_TXQ_EXT_IN_PORT_ID_LEN 4 /* 64-bit address of 4k of 4k-aligned host memory buffer */ #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_OFST 28 #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_LEN 8 @@ -6135,6 +7354,7 @@ #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM 64 /* Flags related to Qbb flow control mode. */ #define MC_CMD_INIT_TXQ_EXT_IN_QBB_FLAGS_OFST 540 +#define MC_CMD_INIT_TXQ_EXT_IN_QBB_FLAGS_LEN 4 #define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_LBN 0 #define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_WIDTH 1 #define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_LBN 1 @@ -6161,6 +7381,7 @@ * passed to INIT_EVQ */ #define MC_CMD_FINI_EVQ_IN_INSTANCE_OFST 0 +#define MC_CMD_FINI_EVQ_IN_INSTANCE_LEN 4 /* MC_CMD_FINI_EVQ_OUT msgresponse */ #define MC_CMD_FINI_EVQ_OUT_LEN 0 @@ -6178,6 +7399,7 @@ #define MC_CMD_FINI_RXQ_IN_LEN 4 /* Instance of RXQ to destroy */ #define MC_CMD_FINI_RXQ_IN_INSTANCE_OFST 0 +#define MC_CMD_FINI_RXQ_IN_INSTANCE_LEN 4 /* MC_CMD_FINI_RXQ_OUT msgresponse */ #define MC_CMD_FINI_RXQ_OUT_LEN 0 @@ -6195,6 +7417,7 @@ #define MC_CMD_FINI_TXQ_IN_LEN 4 /* Instance of TXQ to destroy */ #define MC_CMD_FINI_TXQ_IN_INSTANCE_OFST 0 +#define MC_CMD_FINI_TXQ_IN_INSTANCE_LEN 4 /* MC_CMD_FINI_TXQ_OUT msgresponse */ #define MC_CMD_FINI_TXQ_OUT_LEN 0 @@ -6212,6 +7435,7 @@ #define MC_CMD_DRIVER_EVENT_IN_LEN 12 /* Handle of target EVQ */ #define MC_CMD_DRIVER_EVENT_IN_EVQ_OFST 0 +#define MC_CMD_DRIVER_EVENT_IN_EVQ_LEN 4 /* Bits 0 - 63 of event */ #define MC_CMD_DRIVER_EVENT_IN_DATA_OFST 4 #define MC_CMD_DRIVER_EVENT_IN_DATA_LEN 8 @@ -6237,6 +7461,7 @@ #define MC_CMD_PROXY_CMD_IN_LEN 4 /* The handle of the target function. */ #define MC_CMD_PROXY_CMD_IN_TARGET_OFST 0 +#define MC_CMD_PROXY_CMD_IN_TARGET_LEN 4 #define MC_CMD_PROXY_CMD_IN_TARGET_PF_LBN 0 #define MC_CMD_PROXY_CMD_IN_TARGET_PF_WIDTH 16 #define MC_CMD_PROXY_CMD_IN_TARGET_VF_LBN 16 @@ -6252,6 +7477,7 @@ #define MC_PROXY_STATUS_BUFFER_LEN 16 /* Handle allocated by the firmware for this proxy transaction */ #define MC_PROXY_STATUS_BUFFER_HANDLE_OFST 0 +#define MC_PROXY_STATUS_BUFFER_HANDLE_LEN 4 /* enum: An invalid handle. */ #define MC_PROXY_STATUS_BUFFER_HANDLE_INVALID 0x0 #define MC_PROXY_STATUS_BUFFER_HANDLE_LBN 0 @@ -6282,6 +7508,7 @@ * elevated privilege mask granted to the requesting function. */ #define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_OFST 12 +#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_LEN 4 #define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_LBN 96 #define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_WIDTH 32 @@ -6298,6 +7525,7 @@ /* MC_CMD_PROXY_CONFIGURE_IN msgrequest */ #define MC_CMD_PROXY_CONFIGURE_IN_LEN 108 #define MC_CMD_PROXY_CONFIGURE_IN_FLAGS_OFST 0 +#define MC_CMD_PROXY_CONFIGURE_IN_FLAGS_LEN 4 #define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_LBN 0 #define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_WIDTH 1 /* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS @@ -6309,6 +7537,7 @@ #define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_HI_OFST 8 /* Must be a power of 2 */ #define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BLOCK_SIZE_OFST 12 +#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BLOCK_SIZE_LEN 4 /* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS * of blocks, each of the size REPLY_BLOCK_SIZE. */ @@ -6318,6 +7547,7 @@ #define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_HI_OFST 20 /* Must be a power of 2 */ #define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BLOCK_SIZE_OFST 24 +#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BLOCK_SIZE_LEN 4 /* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS * of blocks, each of the size STATUS_BLOCK_SIZE. This buffer is only needed if * host intends to complete proxied operations by using MC_CMD_PROXY_CMD. @@ -6328,8 +7558,10 @@ #define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_HI_OFST 32 /* Must be a power of 2, or zero if this buffer is not provided */ #define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BLOCK_SIZE_OFST 36 +#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BLOCK_SIZE_LEN 4 /* Applies to all three buffers */ #define MC_CMD_PROXY_CONFIGURE_IN_NUM_BLOCKS_OFST 40 +#define MC_CMD_PROXY_CONFIGURE_IN_NUM_BLOCKS_LEN 4 /* A bit mask defining which MCDI operations may be proxied */ #define MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_OFST 44 #define MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_LEN 64 @@ -6337,6 +7569,7 @@ /* MC_CMD_PROXY_CONFIGURE_EXT_IN msgrequest */ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_LEN 112 #define MC_CMD_PROXY_CONFIGURE_EXT_IN_FLAGS_OFST 0 +#define MC_CMD_PROXY_CONFIGURE_EXT_IN_FLAGS_LEN 4 #define MC_CMD_PROXY_CONFIGURE_EXT_IN_ENABLE_LBN 0 #define MC_CMD_PROXY_CONFIGURE_EXT_IN_ENABLE_WIDTH 1 /* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS @@ -6348,6 +7581,7 @@ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_STATUS_BUFF_ADDR_HI_OFST 8 /* Must be a power of 2 */ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_STATUS_BLOCK_SIZE_OFST 12 +#define MC_CMD_PROXY_CONFIGURE_EXT_IN_STATUS_BLOCK_SIZE_LEN 4 /* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS * of blocks, each of the size REPLY_BLOCK_SIZE. */ @@ -6357,6 +7591,7 @@ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_REQUEST_BUFF_ADDR_HI_OFST 20 /* Must be a power of 2 */ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_REQUEST_BLOCK_SIZE_OFST 24 +#define MC_CMD_PROXY_CONFIGURE_EXT_IN_REQUEST_BLOCK_SIZE_LEN 4 /* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS * of blocks, each of the size STATUS_BLOCK_SIZE. This buffer is only needed if * host intends to complete proxied operations by using MC_CMD_PROXY_CMD. @@ -6367,12 +7602,15 @@ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_REPLY_BUFF_ADDR_HI_OFST 32 /* Must be a power of 2, or zero if this buffer is not provided */ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_REPLY_BLOCK_SIZE_OFST 36 +#define MC_CMD_PROXY_CONFIGURE_EXT_IN_REPLY_BLOCK_SIZE_LEN 4 /* Applies to all three buffers */ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_NUM_BLOCKS_OFST 40 +#define MC_CMD_PROXY_CONFIGURE_EXT_IN_NUM_BLOCKS_LEN 4 /* A bit mask defining which MCDI operations may be proxied */ #define MC_CMD_PROXY_CONFIGURE_EXT_IN_ALLOWED_MCDI_MASK_OFST 44 #define MC_CMD_PROXY_CONFIGURE_EXT_IN_ALLOWED_MCDI_MASK_LEN 64 #define MC_CMD_PROXY_CONFIGURE_EXT_IN_RESERVED_OFST 108 +#define MC_CMD_PROXY_CONFIGURE_EXT_IN_RESERVED_LEN 4 /* MC_CMD_PROXY_CONFIGURE_OUT msgresponse */ #define MC_CMD_PROXY_CONFIGURE_OUT_LEN 0 @@ -6392,7 +7630,9 @@ /* MC_CMD_PROXY_COMPLETE_IN msgrequest */ #define MC_CMD_PROXY_COMPLETE_IN_LEN 12 #define MC_CMD_PROXY_COMPLETE_IN_BLOCK_INDEX_OFST 0 +#define MC_CMD_PROXY_COMPLETE_IN_BLOCK_INDEX_LEN 4 #define MC_CMD_PROXY_COMPLETE_IN_STATUS_OFST 4 +#define MC_CMD_PROXY_COMPLETE_IN_STATUS_LEN 4 /* enum: The operation has been completed by using MC_CMD_PROXY_CMD, the reply * is stored in the REPLY_BUFF. */ @@ -6408,6 +7648,7 @@ */ #define MC_CMD_PROXY_COMPLETE_IN_TIMEDOUT 0x3 #define MC_CMD_PROXY_COMPLETE_IN_HANDLE_OFST 8 +#define MC_CMD_PROXY_COMPLETE_IN_HANDLE_LEN 4 /* MC_CMD_PROXY_COMPLETE_OUT msgresponse */ #define MC_CMD_PROXY_COMPLETE_OUT_LEN 0 @@ -6427,17 +7668,22 @@ #define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_LEN 8 /* Owner ID to use */ #define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_OWNER_OFST 0 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_OWNER_LEN 4 /* Size of buffer table pages to use, in bytes (note that only a few values are * legal on any specific hardware). */ #define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_PAGE_SIZE_OFST 4 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_PAGE_SIZE_LEN 4 /* MC_CMD_ALLOC_BUFTBL_CHUNK_OUT msgresponse */ #define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_LEN 12 #define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_HANDLE_OFST 0 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_HANDLE_LEN 4 #define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_NUMENTRIES_OFST 4 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_NUMENTRIES_LEN 4 /* Buffer table IDs for use in DMA descriptors. */ #define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_ID_OFST 8 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_ID_LEN 4 /***********************************/ @@ -6453,10 +7699,13 @@ #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 268 #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num)) #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_LEN 4 /* ID */ #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_FIRSTID_OFST 4 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_FIRSTID_LEN 4 /* Num entries */ #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 8 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_NUMENTRIES_LEN 4 /* Buffer table entry address */ #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_OFST 12 #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LEN 8 @@ -6479,48 +7728,11 @@ /* MC_CMD_FREE_BUFTBL_CHUNK_IN msgrequest */ #define MC_CMD_FREE_BUFTBL_CHUNK_IN_LEN 4 #define MC_CMD_FREE_BUFTBL_CHUNK_IN_HANDLE_OFST 0 +#define MC_CMD_FREE_BUFTBL_CHUNK_IN_HANDLE_LEN 4 /* MC_CMD_FREE_BUFTBL_CHUNK_OUT msgresponse */ #define MC_CMD_FREE_BUFTBL_CHUNK_OUT_LEN 0 -/* PORT_CONFIG_ENTRY structuredef */ -#define PORT_CONFIG_ENTRY_LEN 16 -/* External port number (label) */ -#define PORT_CONFIG_ENTRY_EXT_NUMBER_OFST 0 -#define PORT_CONFIG_ENTRY_EXT_NUMBER_LEN 1 -#define PORT_CONFIG_ENTRY_EXT_NUMBER_LBN 0 -#define PORT_CONFIG_ENTRY_EXT_NUMBER_WIDTH 8 -/* Port core location */ -#define PORT_CONFIG_ENTRY_CORE_OFST 1 -#define PORT_CONFIG_ENTRY_CORE_LEN 1 -#define PORT_CONFIG_ENTRY_STANDALONE 0x0 /* enum */ -#define PORT_CONFIG_ENTRY_MASTER 0x1 /* enum */ -#define PORT_CONFIG_ENTRY_SLAVE 0x2 /* enum */ -#define PORT_CONFIG_ENTRY_CORE_LBN 8 -#define PORT_CONFIG_ENTRY_CORE_WIDTH 8 -/* Internal number (HW resource) relative to the core */ -#define PORT_CONFIG_ENTRY_INT_NUMBER_OFST 2 -#define PORT_CONFIG_ENTRY_INT_NUMBER_LEN 1 -#define PORT_CONFIG_ENTRY_INT_NUMBER_LBN 16 -#define PORT_CONFIG_ENTRY_INT_NUMBER_WIDTH 8 -/* Reserved */ -#define PORT_CONFIG_ENTRY_RSVD_OFST 3 -#define PORT_CONFIG_ENTRY_RSVD_LEN 1 -#define PORT_CONFIG_ENTRY_RSVD_LBN 24 -#define PORT_CONFIG_ENTRY_RSVD_WIDTH 8 -/* Bitmask of KR lanes used by the port */ -#define PORT_CONFIG_ENTRY_LANES_OFST 4 -#define PORT_CONFIG_ENTRY_LANES_LBN 32 -#define PORT_CONFIG_ENTRY_LANES_WIDTH 32 -/* Port capabilities (MC_CMD_PHY_CAP_*) */ -#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_OFST 8 -#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_LBN 64 -#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_WIDTH 32 -/* Reserved (align to 16 bytes) */ -#define PORT_CONFIG_ENTRY_RSVD2_OFST 12 -#define PORT_CONFIG_ENTRY_RSVD2_LBN 96 -#define PORT_CONFIG_ENTRY_RSVD2_WIDTH 32 - /***********************************/ /* MC_CMD_FILTER_OP @@ -6534,6 +7746,7 @@ #define MC_CMD_FILTER_OP_IN_LEN 108 /* identifies the type of operation requested */ #define MC_CMD_FILTER_OP_IN_OP_OFST 0 +#define MC_CMD_FILTER_OP_IN_OP_LEN 4 /* enum: single-recipient filter insert */ #define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0 /* enum: single-recipient filter remove */ @@ -6554,8 +7767,10 @@ /* The port ID associated with the v-adaptor which should contain this filter. */ #define MC_CMD_FILTER_OP_IN_PORT_ID_OFST 12 +#define MC_CMD_FILTER_OP_IN_PORT_ID_LEN 4 /* fields to include in match criteria */ #define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 16 +#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_LEN 4 #define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_LBN 0 #define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_WIDTH 1 #define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_LBN 1 @@ -6586,6 +7801,7 @@ #define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1 /* receive destination */ #define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 20 +#define MC_CMD_FILTER_OP_IN_RX_DEST_LEN 4 /* enum: drop packets */ #define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0 /* enum: receive to host */ @@ -6598,8 +7814,10 @@ #define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4 /* receive queue handle (for multiple queue modes, this is the base queue) */ #define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 24 +#define MC_CMD_FILTER_OP_IN_RX_QUEUE_LEN 4 /* receive mode */ #define MC_CMD_FILTER_OP_IN_RX_MODE_OFST 28 +#define MC_CMD_FILTER_OP_IN_RX_MODE_LEN 4 /* enum: receive to just the specified queue */ #define MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE 0x0 /* enum: receive to multiple queues using RSS context */ @@ -6614,13 +7832,16 @@ * MC_CMD_DOT1P_MAPPING_ALLOC. */ #define MC_CMD_FILTER_OP_IN_RX_CONTEXT_OFST 32 +#define MC_CMD_FILTER_OP_IN_RX_CONTEXT_LEN 4 /* transmit domain (reserved; set to 0) */ #define MC_CMD_FILTER_OP_IN_TX_DOMAIN_OFST 36 +#define MC_CMD_FILTER_OP_IN_TX_DOMAIN_LEN 4 /* transmit destination (either set the MAC and/or PM bits for explicit * control, or set this field to TX_DEST_DEFAULT for sensible default * behaviour) */ #define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 40 +#define MC_CMD_FILTER_OP_IN_TX_DEST_LEN 4 /* enum: request default behaviour (based on filter type) */ #define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT 0xffffffff #define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0 @@ -6653,8 +7874,10 @@ #define MC_CMD_FILTER_OP_IN_IP_PROTO_LEN 2 /* Firmware defined register 0 to match (reserved; set to 0) */ #define MC_CMD_FILTER_OP_IN_FWDEF0_OFST 68 +#define MC_CMD_FILTER_OP_IN_FWDEF0_LEN 4 /* Firmware defined register 1 to match (reserved; set to 0) */ #define MC_CMD_FILTER_OP_IN_FWDEF1_OFST 72 +#define MC_CMD_FILTER_OP_IN_FWDEF1_LEN 4 /* source IP address to match (as bytes in network order; set last 12 bytes to * 0 for IPv4 address) */ @@ -6673,6 +7896,7 @@ #define MC_CMD_FILTER_OP_EXT_IN_LEN 172 /* identifies the type of operation requested */ #define MC_CMD_FILTER_OP_EXT_IN_OP_OFST 0 +#define MC_CMD_FILTER_OP_EXT_IN_OP_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_FILTER_OP_IN/OP */ /* filter handle (for remove / unsubscribe operations) */ @@ -6683,8 +7907,10 @@ /* The port ID associated with the v-adaptor which should contain this filter. */ #define MC_CMD_FILTER_OP_EXT_IN_PORT_ID_OFST 12 +#define MC_CMD_FILTER_OP_EXT_IN_PORT_ID_LEN 4 /* fields to include in match criteria */ #define MC_CMD_FILTER_OP_EXT_IN_MATCH_FIELDS_OFST 16 +#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FIELDS_LEN 4 #define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_LBN 0 #define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_WIDTH 1 #define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_LBN 1 @@ -6743,6 +7969,7 @@ #define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1 /* receive destination */ #define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_OFST 20 +#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_LEN 4 /* enum: drop packets */ #define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_DROP 0x0 /* enum: receive to host */ @@ -6755,8 +7982,10 @@ #define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX1 0x4 /* receive queue handle (for multiple queue modes, this is the base queue) */ #define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_OFST 24 +#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_LEN 4 /* receive mode */ #define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_OFST 28 +#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_LEN 4 /* enum: receive to just the specified queue */ #define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_SIMPLE 0x0 /* enum: receive to multiple queues using RSS context */ @@ -6771,13 +8000,16 @@ * MC_CMD_DOT1P_MAPPING_ALLOC. */ #define MC_CMD_FILTER_OP_EXT_IN_RX_CONTEXT_OFST 32 +#define MC_CMD_FILTER_OP_EXT_IN_RX_CONTEXT_LEN 4 /* transmit domain (reserved; set to 0) */ #define MC_CMD_FILTER_OP_EXT_IN_TX_DOMAIN_OFST 36 +#define MC_CMD_FILTER_OP_EXT_IN_TX_DOMAIN_LEN 4 /* transmit destination (either set the MAC and/or PM bits for explicit * control, or set this field to TX_DEST_DEFAULT for sensible default * behaviour) */ #define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_OFST 40 +#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_LEN 4 /* enum: request default behaviour (based on filter type) */ #define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_DEFAULT 0xffffffff #define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_LBN 0 @@ -6810,11 +8042,13 @@ #define MC_CMD_FILTER_OP_EXT_IN_IP_PROTO_LEN 2 /* Firmware defined register 0 to match (reserved; set to 0) */ #define MC_CMD_FILTER_OP_EXT_IN_FWDEF0_OFST 68 +#define MC_CMD_FILTER_OP_EXT_IN_FWDEF0_LEN 4 /* VNI (for VXLAN/Geneve, when IP protocol is UDP) or VSID (for NVGRE, when IP * protocol is GRE) to match (as bytes in network order; set last byte to 0 for * VXLAN/NVGRE, or 1 for Geneve) */ #define MC_CMD_FILTER_OP_EXT_IN_VNI_OR_VSID_OFST 72 +#define MC_CMD_FILTER_OP_EXT_IN_VNI_OR_VSID_LEN 4 #define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_LBN 0 #define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_WIDTH 24 #define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_LBN 24 @@ -6880,10 +8114,12 @@ * to 0) */ #define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF0_OFST 132 +#define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF0_LEN 4 /* VXLAN/NVGRE inner frame Firmware defined register 1 to match (reserved; set * to 0) */ #define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF1_OFST 136 +#define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF1_LEN 4 /* VXLAN/NVGRE inner frame source IP address to match (as bytes in network * order; set last 12 bytes to 0 for IPv4 address) */ @@ -6899,6 +8135,7 @@ #define MC_CMD_FILTER_OP_OUT_LEN 12 /* identifies the type of operation requested */ #define MC_CMD_FILTER_OP_OUT_OP_OFST 0 +#define MC_CMD_FILTER_OP_OUT_OP_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_FILTER_OP_IN/OP */ /* Returned filter handle (for insert / subscribe operations). Note that these @@ -6918,6 +8155,7 @@ #define MC_CMD_FILTER_OP_EXT_OUT_LEN 12 /* identifies the type of operation requested */ #define MC_CMD_FILTER_OP_EXT_OUT_OP_OFST 0 +#define MC_CMD_FILTER_OP_EXT_OUT_OP_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_FILTER_OP_EXT_IN/OP */ /* Returned filter handle (for insert / subscribe operations). Note that these @@ -6944,6 +8182,7 @@ #define MC_CMD_GET_PARSER_DISP_INFO_IN_LEN 4 /* identifies the type of operation requested */ #define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_OFST 0 +#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_LEN 4 /* enum: read the list of supported RX filter matches */ #define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES 0x1 /* enum: read flags indicating restrictions on filter insertion for the calling @@ -6966,10 +8205,12 @@ #define MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(num) (8+4*(num)) /* identifies the type of operation requested */ #define MC_CMD_GET_PARSER_DISP_INFO_OUT_OP_OFST 0 +#define MC_CMD_GET_PARSER_DISP_INFO_OUT_OP_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */ /* number of supported match types */ #define MC_CMD_GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES_OFST 4 +#define MC_CMD_GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES_LEN 4 /* array of supported match types (valid MATCH_FIELDS values for * MC_CMD_FILTER_OP) sorted in decreasing priority order */ @@ -6982,10 +8223,12 @@ #define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_LEN 8 /* identifies the type of operation requested */ #define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_OP_OFST 0 +#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_OP_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */ /* bitfield of filter insertion restrictions */ #define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_RESTRICTION_FLAGS_OFST 4 +#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_RESTRICTION_FLAGS_LEN 4 #define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_LBN 0 #define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_WIDTH 1 @@ -7005,11 +8248,16 @@ #define MC_CMD_PARSER_DISP_RW_IN_LEN 32 /* identifies the target of the operation */ #define MC_CMD_PARSER_DISP_RW_IN_TARGET_OFST 0 +#define MC_CMD_PARSER_DISP_RW_IN_TARGET_LEN 4 /* enum: RX dispatcher CPU */ #define MC_CMD_PARSER_DISP_RW_IN_RX_DICPU 0x0 /* enum: TX dispatcher CPU */ #define MC_CMD_PARSER_DISP_RW_IN_TX_DICPU 0x1 -/* enum: Lookup engine (with original metadata format) */ +/* enum: Lookup engine (with original metadata format). Deprecated; used only + * by cmdclient as a fallback for very old Huntington firmware, and not + * supported in firmware beyond v6.4.0.1005. Use LUE_VERSIONED_METADATA + * instead. + */ #define MC_CMD_PARSER_DISP_RW_IN_LUE 0x2 /* enum: Lookup engine (with requested metadata format) */ #define MC_CMD_PARSER_DISP_RW_IN_LUE_VERSIONED_METADATA 0x3 @@ -7021,26 +8269,33 @@ #define MC_CMD_PARSER_DISP_RW_IN_MISC_STATE 0x5 /* identifies the type of operation requested */ #define MC_CMD_PARSER_DISP_RW_IN_OP_OFST 4 -/* enum: read a word of DICPU DMEM or a LUE entry */ +#define MC_CMD_PARSER_DISP_RW_IN_OP_LEN 4 +/* enum: Read a word of DICPU DMEM or a LUE entry */ #define MC_CMD_PARSER_DISP_RW_IN_READ 0x0 -/* enum: write a word of DICPU DMEM or a LUE entry */ +/* enum: Write a word of DICPU DMEM or a LUE entry. */ #define MC_CMD_PARSER_DISP_RW_IN_WRITE 0x1 -/* enum: read-modify-write a word of DICPU DMEM (not valid for LUE) */ +/* enum: Read-modify-write a word of DICPU DMEM (not valid for LUE). */ #define MC_CMD_PARSER_DISP_RW_IN_RMW 0x2 /* data memory address (DICPU targets) or LUE index (LUE targets) */ #define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_OFST 8 +#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_LEN 4 /* selector (for MISC_STATE target) */ #define MC_CMD_PARSER_DISP_RW_IN_SELECTOR_OFST 8 +#define MC_CMD_PARSER_DISP_RW_IN_SELECTOR_LEN 4 /* enum: Port to datapath mapping */ #define MC_CMD_PARSER_DISP_RW_IN_PORT_DP_MAPPING 0x1 /* value to write (for DMEM writes) */ #define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_OFST 12 +#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_LEN 4 /* XOR value (for DMEM read-modify-writes: new = (old & mask) ^ value) */ #define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_XOR_VALUE_OFST 12 +#define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_XOR_VALUE_LEN 4 /* AND mask (for DMEM read-modify-writes: new = (old & mask) ^ value) */ #define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_AND_MASK_OFST 16 +#define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_AND_MASK_LEN 4 /* metadata format (for LUE reads using LUE_VERSIONED_METADATA) */ #define MC_CMD_PARSER_DISP_RW_IN_LUE_READ_METADATA_VERSION_OFST 12 +#define MC_CMD_PARSER_DISP_RW_IN_LUE_READ_METADATA_VERSION_LEN 4 /* value to write (for LUE writes) */ #define MC_CMD_PARSER_DISP_RW_IN_LUE_WRITE_VALUE_OFST 12 #define MC_CMD_PARSER_DISP_RW_IN_LUE_WRITE_VALUE_LEN 20 @@ -7049,6 +8304,7 @@ #define MC_CMD_PARSER_DISP_RW_OUT_LEN 52 /* value read (for DMEM reads) */ #define MC_CMD_PARSER_DISP_RW_OUT_DMEM_READ_VALUE_OFST 0 +#define MC_CMD_PARSER_DISP_RW_OUT_DMEM_READ_VALUE_LEN 4 /* value read (for LUE reads) */ #define MC_CMD_PARSER_DISP_RW_OUT_LUE_READ_VALUE_OFST 0 #define MC_CMD_PARSER_DISP_RW_OUT_LUE_READ_VALUE_LEN 20 @@ -7093,6 +8349,7 @@ #define MC_CMD_SET_PF_COUNT_IN_LEN 4 /* New number of PFs on the device. */ #define MC_CMD_SET_PF_COUNT_IN_PF_COUNT_OFST 0 +#define MC_CMD_SET_PF_COUNT_IN_PF_COUNT_LEN 4 /* MC_CMD_SET_PF_COUNT_OUT msgresponse */ #define MC_CMD_SET_PF_COUNT_OUT_LEN 0 @@ -7113,6 +8370,7 @@ #define MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN 4 /* Identifies the port assignment for this function. */ #define MC_CMD_GET_PORT_ASSIGNMENT_OUT_PORT_OFST 0 +#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_PORT_LEN 4 /***********************************/ @@ -7127,6 +8385,7 @@ #define MC_CMD_SET_PORT_ASSIGNMENT_IN_LEN 4 /* Identifies the port assignment for this function. */ #define MC_CMD_SET_PORT_ASSIGNMENT_IN_PORT_OFST 0 +#define MC_CMD_SET_PORT_ASSIGNMENT_IN_PORT_LEN 4 /* MC_CMD_SET_PORT_ASSIGNMENT_OUT msgresponse */ #define MC_CMD_SET_PORT_ASSIGNMENT_OUT_LEN 0 @@ -7144,8 +8403,10 @@ #define MC_CMD_ALLOC_VIS_IN_LEN 8 /* The minimum number of VIs that is acceptable */ #define MC_CMD_ALLOC_VIS_IN_MIN_VI_COUNT_OFST 0 +#define MC_CMD_ALLOC_VIS_IN_MIN_VI_COUNT_LEN 4 /* The maximum number of VIs that would be useful */ #define MC_CMD_ALLOC_VIS_IN_MAX_VI_COUNT_OFST 4 +#define MC_CMD_ALLOC_VIS_IN_MAX_VI_COUNT_LEN 4 /* MC_CMD_ALLOC_VIS_OUT msgresponse: Huntington-compatible VI_ALLOC request. * Use extended version in new code. @@ -7153,21 +8414,26 @@ #define MC_CMD_ALLOC_VIS_OUT_LEN 8 /* The number of VIs allocated on this function */ #define MC_CMD_ALLOC_VIS_OUT_VI_COUNT_OFST 0 +#define MC_CMD_ALLOC_VIS_OUT_VI_COUNT_LEN 4 /* The base absolute VI number allocated to this function. Required to * correctly interpret wakeup events. */ #define MC_CMD_ALLOC_VIS_OUT_VI_BASE_OFST 4 +#define MC_CMD_ALLOC_VIS_OUT_VI_BASE_LEN 4 /* MC_CMD_ALLOC_VIS_EXT_OUT msgresponse */ #define MC_CMD_ALLOC_VIS_EXT_OUT_LEN 12 /* The number of VIs allocated on this function */ #define MC_CMD_ALLOC_VIS_EXT_OUT_VI_COUNT_OFST 0 +#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_COUNT_LEN 4 /* The base absolute VI number allocated to this function. Required to * correctly interpret wakeup events. */ #define MC_CMD_ALLOC_VIS_EXT_OUT_VI_BASE_OFST 4 +#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_BASE_LEN 4 /* Function's port vi_shift value (always 0 on Huntington) */ #define MC_CMD_ALLOC_VIS_EXT_OUT_VI_SHIFT_OFST 8 +#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_SHIFT_LEN 4 /***********************************/ @@ -7201,15 +8467,20 @@ #define MC_CMD_GET_SRIOV_CFG_OUT_LEN 20 /* Number of VFs currently enabled. */ #define MC_CMD_GET_SRIOV_CFG_OUT_VF_CURRENT_OFST 0 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_CURRENT_LEN 4 /* Max number of VFs before sriov stride and offset may need to be changed. */ #define MC_CMD_GET_SRIOV_CFG_OUT_VF_MAX_OFST 4 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_MAX_LEN 4 #define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_OFST 8 +#define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_LEN 4 #define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_LBN 0 #define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_WIDTH 1 /* RID offset of first VF from PF. */ #define MC_CMD_GET_SRIOV_CFG_OUT_VF_OFFSET_OFST 12 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_OFFSET_LEN 4 /* RID offset of each subsequent VF from the previous. */ #define MC_CMD_GET_SRIOV_CFG_OUT_VF_STRIDE_OFST 16 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_STRIDE_LEN 4 /***********************************/ @@ -7224,19 +8495,24 @@ #define MC_CMD_SET_SRIOV_CFG_IN_LEN 20 /* Number of VFs currently enabled. */ #define MC_CMD_SET_SRIOV_CFG_IN_VF_CURRENT_OFST 0 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_CURRENT_LEN 4 /* Max number of VFs before sriov stride and offset may need to be changed. */ #define MC_CMD_SET_SRIOV_CFG_IN_VF_MAX_OFST 4 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_MAX_LEN 4 #define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_OFST 8 +#define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_LEN 4 #define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_LBN 0 #define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_WIDTH 1 /* RID offset of first VF from PF, or 0 for no change, or * MC_CMD_RESOURCE_INSTANCE_ANY to allow the system to allocate an offset. */ #define MC_CMD_SET_SRIOV_CFG_IN_VF_OFFSET_OFST 12 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_OFFSET_LEN 4 /* RID offset of each subsequent VF from the previous, 0 for no change, or * MC_CMD_RESOURCE_INSTANCE_ANY to allow the system to allocate a stride. */ #define MC_CMD_SET_SRIOV_CFG_IN_VF_STRIDE_OFST 16 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_STRIDE_LEN 4 /* MC_CMD_SET_SRIOV_CFG_OUT msgresponse */ #define MC_CMD_SET_SRIOV_CFG_OUT_LEN 0 @@ -7258,12 +8534,15 @@ #define MC_CMD_GET_VI_ALLOC_INFO_OUT_LEN 12 /* The number of VIs allocated on this function */ #define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_COUNT_OFST 0 +#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_COUNT_LEN 4 /* The base absolute VI number allocated to this function. Required to * correctly interpret wakeup events. */ #define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_BASE_OFST 4 +#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_BASE_LEN 4 /* Function's port vi_shift value (always 0 on Huntington) */ #define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_SHIFT_OFST 8 +#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_SHIFT_LEN 4 /***********************************/ @@ -7278,6 +8557,7 @@ #define MC_CMD_DUMP_VI_STATE_IN_LEN 4 /* The VI number to query. */ #define MC_CMD_DUMP_VI_STATE_IN_VI_NUMBER_OFST 0 +#define MC_CMD_DUMP_VI_STATE_IN_VI_NUMBER_LEN 4 /* MC_CMD_DUMP_VI_STATE_OUT msgresponse */ #define MC_CMD_DUMP_VI_STATE_OUT_LEN 96 @@ -7311,6 +8591,7 @@ #define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_HI_OFST 24 /* Combined metadata field. */ #define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_OFST 28 +#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_LEN 4 #define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_LBN 0 #define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_WIDTH 16 #define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_LBN 16 @@ -7392,6 +8673,7 @@ #define MC_CMD_ALLOC_PIOBUF_OUT_LEN 4 /* Handle for allocated push I/O buffer. */ #define MC_CMD_ALLOC_PIOBUF_OUT_PIOBUF_HANDLE_OFST 0 +#define MC_CMD_ALLOC_PIOBUF_OUT_PIOBUF_HANDLE_LEN 4 /***********************************/ @@ -7406,6 +8688,7 @@ #define MC_CMD_FREE_PIOBUF_IN_LEN 4 /* Handle for allocated push I/O buffer. */ #define MC_CMD_FREE_PIOBUF_IN_PIOBUF_HANDLE_OFST 0 +#define MC_CMD_FREE_PIOBUF_IN_PIOBUF_HANDLE_LEN 4 /* MC_CMD_FREE_PIOBUF_OUT msgresponse */ #define MC_CMD_FREE_PIOBUF_OUT_LEN 0 @@ -7423,6 +8706,7 @@ #define MC_CMD_GET_VI_TLP_PROCESSING_IN_LEN 4 /* VI number to get information for. */ #define MC_CMD_GET_VI_TLP_PROCESSING_IN_INSTANCE_OFST 0 +#define MC_CMD_GET_VI_TLP_PROCESSING_IN_INSTANCE_LEN 4 /* MC_CMD_GET_VI_TLP_PROCESSING_OUT msgresponse */ #define MC_CMD_GET_VI_TLP_PROCESSING_OUT_LEN 4 @@ -7445,6 +8729,7 @@ #define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_ON_LBN 19 #define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_ON_WIDTH 1 #define MC_CMD_GET_VI_TLP_PROCESSING_OUT_DATA_OFST 0 +#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_DATA_LEN 4 /***********************************/ @@ -7459,6 +8744,7 @@ #define MC_CMD_SET_VI_TLP_PROCESSING_IN_LEN 8 /* VI number to set information for. */ #define MC_CMD_SET_VI_TLP_PROCESSING_IN_INSTANCE_OFST 0 +#define MC_CMD_SET_VI_TLP_PROCESSING_IN_INSTANCE_LEN 4 /* Transaction processing steering hint 1 for use with the Rx Queue. */ #define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG1_RX_OFST 4 #define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG1_RX_LEN 1 @@ -7478,6 +8764,7 @@ #define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_ON_LBN 51 #define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_ON_WIDTH 1 #define MC_CMD_SET_VI_TLP_PROCESSING_IN_DATA_OFST 4 +#define MC_CMD_SET_VI_TLP_PROCESSING_IN_DATA_LEN 4 /* MC_CMD_SET_VI_TLP_PROCESSING_OUT msgresponse */ #define MC_CMD_SET_VI_TLP_PROCESSING_OUT_LEN 0 @@ -7494,6 +8781,7 @@ /* MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN msgrequest */ #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_LEN 4 #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0 +#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_LEN 4 /* enum: MISC. */ #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_MISC 0x0 /* enum: IDO. */ @@ -7506,10 +8794,12 @@ /* MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT msgresponse */ #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_LEN 8 #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_GLOBAL_CATEGORY_OFST 0 +#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_GLOBAL_CATEGORY_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN/TLP_GLOBAL_CATEGORY */ /* Amalgamated TLP info word. */ #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_WORD_OFST 4 +#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_WORD_LEN 4 #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_LBN 0 #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_WIDTH 1 #define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_LBN 1 @@ -7557,10 +8847,12 @@ /* MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN msgrequest */ #define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_LEN 8 #define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0 +#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_GET_TLP_PROCESSING_GLOBALS/MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN/TLP_GLOBAL_CATEGORY */ /* Amalgamated TLP info word. */ #define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_WORD_OFST 4 +#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_WORD_LEN 4 #define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_LBN 0 #define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_WIDTH 1 #define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_LBN 0 @@ -7627,6 +8919,7 @@ * in a command from the host.) */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_OFST 0 +#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_LEN 4 #define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IDLE 0x0 /* enum */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_RESET 0x1 /* enum */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IMEMS 0x2 /* enum */ @@ -7636,6 +8929,7 @@ * mc_flash_layout.h.) */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_OFST 4 +#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_LEN 4 /* enum: Valid in phase 2 (PHASE_IMEMS) only */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_TEXT 0x0 /* enum: Valid in phase 2 (PHASE_IMEMS) only */ @@ -7672,12 +8966,14 @@ #define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_ALL 0xffffffff /* Chunk ID, or CHUNK_ID_LAST or CHUNK_ID_ABORT */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_OFST 8 +#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LEN 4 /* enum: Last chunk, containing checksum rather than data */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LAST 0xffffffff /* enum: Abort download of this item */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_ABORT 0xfffffffe /* Length of this chunk in bytes */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_OFST 12 +#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_LEN 4 /* Data for this chunk */ #define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_OFST 16 #define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_LEN 4 @@ -7688,8 +8984,10 @@ #define MC_CMD_SATELLITE_DOWNLOAD_OUT_LEN 8 /* Same as MC_CMD_ERR field, but included as 0 in success cases */ #define MC_CMD_SATELLITE_DOWNLOAD_OUT_RESULT_OFST 0 +#define MC_CMD_SATELLITE_DOWNLOAD_OUT_RESULT_LEN 4 /* Extra status information */ #define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_OFST 4 +#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_LEN 4 /* enum: Code download OK, completed. */ #define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_COMPLETE 0x0 /* enum: Code download aborted as requested. */ @@ -7726,6 +9024,7 @@ #define MC_CMD_GET_CAPABILITIES_OUT_LEN 20 /* First word of flags. */ #define MC_CMD_GET_CAPABILITIES_OUT_FLAGS1_OFST 0 +#define MC_CMD_GET_CAPABILITIES_OUT_FLAGS1_LEN 4 #define MC_CMD_GET_CAPABILITIES_OUT_VPORT_RECONFIGURE_LBN 3 #define MC_CMD_GET_CAPABILITIES_OUT_VPORT_RECONFIGURE_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_OUT_TX_STRIPING_LBN 4 @@ -7793,6 +9092,8 @@ #define MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY 0x1 /* enum: Packed stream RXDP firmware */ #define MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM 0x2 +/* enum: Rules engine RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_RULES_ENGINE 0x5 /* enum: BIST RXDP firmware */ #define MC_CMD_GET_CAPABILITIES_OUT_RXDP_BIST 0x10a /* enum: RXDP Test firmware image 1 */ @@ -7813,6 +9114,8 @@ #define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 /* enum: RXDP Test firmware image 9 */ #define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b +/* enum: RXDP Test firmware image 10 */ +#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_SLOW 0x10c /* TxDPCPU firmware id. */ #define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_OFST 6 #define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_LEN 2 @@ -7822,6 +9125,8 @@ #define MC_CMD_GET_CAPABILITIES_OUT_TXDP_LOW_LATENCY 0x1 /* enum: High packet rate TXDP firmware */ #define MC_CMD_GET_CAPABILITIES_OUT_TXDP_HIGH_PACKET_RATE 0x3 +/* enum: Rules engine TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_RULES_ENGINE 0x5 /* enum: BIST TXDP firmware */ #define MC_CMD_GET_CAPABILITIES_OUT_TXDP_BIST 0x12d /* enum: TXDP Test firmware image 1 */ @@ -7848,7 +9153,9 @@ * (Huntington development only) */ #define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 -/* enum: Virtual switching (full feature) RX PD production firmware */ +/* enum: Full featured RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ #define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_VSWITCH 0x3 /* enum: siena_compat variant RX PD firmware using PM rather than MAC * (Huntington development only) @@ -7864,6 +9171,8 @@ #define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 /* enum: Rules engine RX PD production firmware */ #define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 /* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ #define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe /* enum: RX PD firmware parsing but not filtering network overlay tunnel @@ -7888,7 +9197,9 @@ * (Huntington development only) */ #define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 -/* enum: Virtual switching (full feature) TX PD production firmware */ +/* enum: Full featured TX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ #define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_VSWITCH 0x3 /* enum: siena_compat variant TX PD firmware using PM rather than MAC * (Huntington development only) @@ -7901,12 +9212,16 @@ #define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 /* enum: Rules engine TX PD production firmware */ #define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 /* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ #define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe /* Hardware capabilities of NIC */ #define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_OFST 12 +#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_LEN 4 /* Licensed capabilities */ #define MC_CMD_GET_CAPABILITIES_OUT_LICENSE_CAPABILITIES_OFST 16 +#define MC_CMD_GET_CAPABILITIES_OUT_LICENSE_CAPABILITIES_LEN 4 /* MC_CMD_GET_CAPABILITIES_V2_IN msgrequest */ #define MC_CMD_GET_CAPABILITIES_V2_IN_LEN 0 @@ -7915,6 +9230,7 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_LEN 72 /* First word of flags. */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS1_OFST 0 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS1_LEN 4 #define MC_CMD_GET_CAPABILITIES_V2_OUT_VPORT_RECONFIGURE_LBN 3 #define MC_CMD_GET_CAPABILITIES_V2_OUT_VPORT_RECONFIGURE_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_STRIPING_LBN 4 @@ -7982,6 +9298,8 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_LOW_LATENCY 0x1 /* enum: Packed stream RXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_PACKED_STREAM 0x2 +/* enum: Rules engine RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_RULES_ENGINE 0x5 /* enum: BIST RXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_BIST 0x10a /* enum: RXDP Test firmware image 1 */ @@ -8002,6 +9320,8 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 /* enum: RXDP Test firmware image 9 */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b +/* enum: RXDP Test firmware image 10 */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_SLOW 0x10c /* TxDPCPU firmware id. */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_DPCPU_FW_ID_OFST 6 #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_DPCPU_FW_ID_LEN 2 @@ -8011,6 +9331,8 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_LOW_LATENCY 0x1 /* enum: High packet rate TXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_HIGH_PACKET_RATE 0x3 +/* enum: Rules engine TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_RULES_ENGINE 0x5 /* enum: BIST TXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_BIST 0x12d /* enum: TXDP Test firmware image 1 */ @@ -8037,7 +9359,9 @@ * (Huntington development only) */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 -/* enum: Virtual switching (full feature) RX PD production firmware */ +/* enum: Full featured RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_VSWITCH 0x3 /* enum: siena_compat variant RX PD firmware using PM rather than MAC * (Huntington development only) @@ -8053,6 +9377,8 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 /* enum: Rules engine RX PD production firmware */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 /* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe /* enum: RX PD firmware parsing but not filtering network overlay tunnel @@ -8077,7 +9403,9 @@ * (Huntington development only) */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 -/* enum: Virtual switching (full feature) TX PD production firmware */ +/* enum: Full featured TX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_VSWITCH 0x3 /* enum: siena_compat variant TX PD firmware using PM rather than MAC * (Huntington development only) @@ -8090,14 +9418,19 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 /* enum: Rules engine TX PD production firmware */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 /* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe /* Hardware capabilities of NIC */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_HW_CAPABILITIES_OFST 12 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_HW_CAPABILITIES_LEN 4 /* Licensed capabilities */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_LICENSE_CAPABILITIES_OFST 16 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_LICENSE_CAPABILITIES_LEN 4 /* Second word of flags. Not present on older firmware (check the length). */ #define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS2_OFST 20 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS2_LEN 4 #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_LBN 0 #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_ENCAP_LBN 1 @@ -8124,6 +9457,18 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_SNIFF_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12 #define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_BACKGROUND_LBN 13 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_BACKGROUND_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_DB_RETURN_LBN 14 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_DB_RETURN_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_CTPIO_LBN 15 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_CTPIO_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_SUPPORT_LBN 16 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_SUPPORT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_LBN 17 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18 +#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1 /* Number of FATSOv2 contexts per datapath supported by this NIC. Not present * on older firmware (check the length). */ @@ -8181,9 +9526,10 @@ #define MC_CMD_GET_CAPABILITIES_V2_OUT_SIZE_PIO_BUFF_LEN 2 /* MC_CMD_GET_CAPABILITIES_V3_OUT msgresponse */ -#define MC_CMD_GET_CAPABILITIES_V3_OUT_LEN 73 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_LEN 76 /* First word of flags. */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS1_OFST 0 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS1_LEN 4 #define MC_CMD_GET_CAPABILITIES_V3_OUT_VPORT_RECONFIGURE_LBN 3 #define MC_CMD_GET_CAPABILITIES_V3_OUT_VPORT_RECONFIGURE_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_STRIPING_LBN 4 @@ -8251,6 +9597,8 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_LOW_LATENCY 0x1 /* enum: Packed stream RXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_PACKED_STREAM 0x2 +/* enum: Rules engine RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_RULES_ENGINE 0x5 /* enum: BIST RXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_BIST 0x10a /* enum: RXDP Test firmware image 1 */ @@ -8271,6 +9619,8 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 /* enum: RXDP Test firmware image 9 */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b +/* enum: RXDP Test firmware image 10 */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_SLOW 0x10c /* TxDPCPU firmware id. */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_DPCPU_FW_ID_OFST 6 #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_DPCPU_FW_ID_LEN 2 @@ -8280,6 +9630,8 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_LOW_LATENCY 0x1 /* enum: High packet rate TXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_HIGH_PACKET_RATE 0x3 +/* enum: Rules engine TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_RULES_ENGINE 0x5 /* enum: BIST TXDP firmware */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_BIST 0x12d /* enum: TXDP Test firmware image 1 */ @@ -8306,7 +9658,9 @@ * (Huntington development only) */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 -/* enum: Virtual switching (full feature) RX PD production firmware */ +/* enum: Full featured RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_VSWITCH 0x3 /* enum: siena_compat variant RX PD firmware using PM rather than MAC * (Huntington development only) @@ -8322,6 +9676,8 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 /* enum: Rules engine RX PD production firmware */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 /* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe /* enum: RX PD firmware parsing but not filtering network overlay tunnel @@ -8346,7 +9702,9 @@ * (Huntington development only) */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 -/* enum: Virtual switching (full feature) TX PD production firmware */ +/* enum: Full featured TX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_VSWITCH 0x3 /* enum: siena_compat variant TX PD firmware using PM rather than MAC * (Huntington development only) @@ -8359,14 +9717,19 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 /* enum: Rules engine TX PD production firmware */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 /* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe /* Hardware capabilities of NIC */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_HW_CAPABILITIES_OFST 12 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_HW_CAPABILITIES_LEN 4 /* Licensed capabilities */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_LICENSE_CAPABILITIES_OFST 16 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_LICENSE_CAPABILITIES_LEN 4 /* Second word of flags. Not present on older firmware (check the length). */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS2_OFST 20 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS2_LEN 4 #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_LBN 0 #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_ENCAP_LBN 1 @@ -8393,6 +9756,18 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_SNIFF_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12 #define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_BACKGROUND_LBN 13 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_BACKGROUND_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_DB_RETURN_LBN 14 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_DB_RETURN_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_CTPIO_LBN 15 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_CTPIO_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_SUPPORT_LBN 16 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_SUPPORT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_LBN 17 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1 /* Number of FATSOv2 contexts per datapath supported by this NIC. Not present * on older firmware (check the length). */ @@ -8463,6 +9838,348 @@ #define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K 0x1 /* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */ #define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K 0x2 +/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing + * (SF-115995-SW) in the present configuration of firmware and port mode. + */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1 +/* Number of buffers per adapter that can be used for VFIFO Stuffing + * (SF-115995-SW) in the present configuration of firmware and port mode. + */ +#define MC_CMD_GET_CAPABILITIES_V3_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74 +#define MC_CMD_GET_CAPABILITIES_V3_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2 + +/* MC_CMD_GET_CAPABILITIES_V4_OUT msgresponse */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_LEN 78 +/* First word of flags. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS1_OFST 0 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS1_LEN 4 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VPORT_RECONFIGURE_LBN 3 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VPORT_RECONFIGURE_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_STRIPING_LBN 4 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_STRIPING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_QUERY_LBN 5 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_QUERY_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_DRV_ATTACH_PREBOOT_LBN 7 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_DRV_ATTACH_PREBOOT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_FORCE_EVENT_MERGING_LBN 8 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_SET_MAC_ENHANCED_LBN 9 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_SET_MAC_ENHANCED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_SECURITY_FILTERING_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_ADDITIONAL_RSS_MODES_LBN 13 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_ADDITIONAL_RSS_MODES_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_QBB_LBN 14 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_QBB_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_RSS_LIMITED_LBN 16 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_RSS_LIMITED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_LBN 17 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_INCLUDE_FCS_LBN 18 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_INCLUDE_FCS_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VLAN_INSERTION_LBN 19 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VLAN_INSERTION_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_VLAN_STRIPPING_LBN 20 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_VLAN_STRIPPING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_LBN 21 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_0_LBN 22 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_0_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_14_LBN 23 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_14_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_TIMESTAMP_LBN 24 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_TIMESTAMP_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_BATCHING_LBN 25 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_BATCHING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCAST_FILTER_CHAINING_LBN 26 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCAST_FILTER_CHAINING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PM_AND_RXDP_COUNTERS_LBN 27 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DISABLE_SCATTER_LBN 28 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DISABLE_SCATTER_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_LBN 30 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VXLAN_NVGRE_LBN 31 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VXLAN_NVGRE_WIDTH 1 +/* RxDPCPU firmware id. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DPCPU_FW_ID_OFST 4 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DPCPU_FW_ID_LEN 2 +/* enum: Standard RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP 0x0 +/* enum: Low latency RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_LOW_LATENCY 0x1 +/* enum: Packed stream RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_PACKED_STREAM 0x2 +/* enum: Rules engine RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_RULES_ENGINE 0x5 +/* enum: BIST RXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_BIST 0x10a +/* enum: RXDP Test firmware image 1 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101 +/* enum: RXDP Test firmware image 2 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102 +/* enum: RXDP Test firmware image 3 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103 +/* enum: RXDP Test firmware image 4 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104 +/* enum: RXDP Test firmware image 5 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_BACKPRESSURE 0x105 +/* enum: RXDP Test firmware image 6 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106 +/* enum: RXDP Test firmware image 7 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107 +/* enum: RXDP Test firmware image 8 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 +/* enum: RXDP Test firmware image 9 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b +/* enum: RXDP Test firmware image 10 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_SLOW 0x10c +/* TxDPCPU firmware id. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DPCPU_FW_ID_OFST 6 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DPCPU_FW_ID_LEN 2 +/* enum: Standard TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP 0x0 +/* enum: Low latency TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_LOW_LATENCY 0x1 +/* enum: High packet rate TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_HIGH_PACKET_RATE 0x3 +/* enum: Rules engine TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_RULES_ENGINE 0x5 +/* enum: BIST TXDP firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_BIST 0x12d +/* enum: TXDP Test firmware image 1 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_TSO_EDIT 0x101 +/* enum: TXDP Test firmware image 2 */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102 +/* enum: TXDP CSR bus test firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_CSR 0x103 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_OFST 8 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_LEN 2 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_LBN 0 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_WIDTH 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_TYPE_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4 +/* enum: reserved value - do not use (may indicate alternative interpretation + * of REV field in future) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RESERVED 0x0 +/* enum: Trivial RX PD firmware for early Huntington development (Huntington + * development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1 +/* enum: RX PD firmware with approximately Siena-compatible behaviour + * (Huntington development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 +/* enum: Full featured RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_VSWITCH 0x3 +/* enum: siena_compat variant RX PD firmware using PM rather than MAC + * (Huntington development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 +/* enum: Low latency RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5 +/* enum: Packed stream RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6 +/* enum: RX PD firmware handling layer 2 only for high packet rate performance + * tests (Medford development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 +/* enum: Rules engine RX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 +/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe +/* enum: RX PD firmware parsing but not filtering network overlay tunnel + * encapsulations (Medford development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_OFST 10 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_LEN 2 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_LBN 0 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_WIDTH 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_TYPE_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4 +/* enum: reserved value - do not use (may indicate alternative interpretation + * of REV field in future) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RESERVED 0x0 +/* enum: Trivial TX PD firmware for early Huntington development (Huntington + * development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1 +/* enum: TX PD firmware with approximately Siena-compatible behaviour + * (Huntington development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 +/* enum: Full featured TX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 +/* enum: (deprecated original name for the FULL_FEATURED variant) */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_VSWITCH 0x3 +/* enum: siena_compat variant TX PD firmware using PM rather than MAC + * (Huntington development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */ +/* enum: TX PD firmware handling layer 2 only for high packet rate performance + * tests (Medford development only) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 +/* enum: Rules engine TX PD production firmware */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 +/* enum: reserved value - do not use (bug69716) */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 +/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe +/* Hardware capabilities of NIC */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_HW_CAPABILITIES_OFST 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_HW_CAPABILITIES_LEN 4 +/* Licensed capabilities */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_LICENSE_CAPABILITIES_OFST 16 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_LICENSE_CAPABILITIES_LEN 4 +/* Second word of flags. Not present on older firmware (check the length). */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS2_OFST 20 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS2_LEN 4 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_LBN 0 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_ENCAP_LBN 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_ENCAP_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVQ_TIMER_CTRL_LBN 2 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVQ_TIMER_CTRL_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVENT_CUT_THROUGH_LBN 3 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVENT_CUT_THROUGH_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_CUT_THROUGH_LBN 4 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_CUT_THROUGH_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VFIFO_ULL_MODE_LBN 5 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VFIFO_ULL_MODE_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_V2_LBN 7 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_V2_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_TIMESTAMPING_LBN 8 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_TIMESTAMPING_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TIMESTAMP_LBN 9 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TIMESTAMP_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_SNIFF_LBN 10 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_SNIFF_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_SNIFF_LBN 11 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_SNIFF_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_BACKGROUND_LBN 13 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_BACKGROUND_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_DB_RETURN_LBN 14 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_DB_RETURN_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_LBN 15 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_SUPPORT_LBN 16 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_SUPPORT_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_LBN 17 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1 +/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present + * on older firmware (check the length). + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2 +/* One byte per PF containing the number of the external port assigned to this + * PF, indexed by PF number. Special values indicate that a PF is either not + * present or not assigned. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_OFST 26 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16 +/* enum: The caller is not permitted to access information on this PF. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_ACCESS_NOT_PERMITTED 0xff +/* enum: PF does not exist. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_PRESENT 0xfe +/* enum: PF does exist but is not assigned to any external port. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_ASSIGNED 0xfd +/* enum: This value indicates that PF is assigned, but it cannot be expressed + * in this field. It is intended for a possible future situation where a more + * complex scheme of PFs to ports mapping is being used. The future driver + * should look for a new field supporting the new scheme. The current/old + * driver should treat this value as PF_NOT_ASSIGNED. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc +/* One byte per PF containing the number of its VFs, indexed by PF number. A + * special value indicates that a PF is not present. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_OFST 42 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_LEN 1 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_NUM 16 +/* enum: The caller is not permitted to access information on this PF. */ +/* MC_CMD_GET_CAPABILITIES_V4_OUT_ACCESS_NOT_PERMITTED 0xff */ +/* enum: PF does not exist. */ +/* MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_PRESENT 0xfe */ +/* Number of VIs available for each external port */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_OFST 58 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_LEN 2 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_NUM 4 +/* Size of RX descriptor cache expressed as binary logarithm The actual size + * equals (2 ^ RX_DESC_CACHE_SIZE) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DESC_CACHE_SIZE_OFST 66 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DESC_CACHE_SIZE_LEN 1 +/* Size of TX descriptor cache expressed as binary logarithm The actual size + * equals (2 ^ TX_DESC_CACHE_SIZE) + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DESC_CACHE_SIZE_OFST 67 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DESC_CACHE_SIZE_LEN 1 +/* Total number of available PIO buffers */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_PIO_BUFFS_OFST 68 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_PIO_BUFFS_LEN 2 +/* Size of a single PIO buffer */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_SIZE_PIO_BUFF_OFST 70 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_SIZE_PIO_BUFF_LEN 2 +/* On chips later than Medford the amount of address space assigned to each VI + * is configurable. This is a global setting that the driver must query to + * discover the VI to address mapping. Cut-through PIO (CTPIO) is not available + * with 8k VI windows. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_OFST 72 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_LEN 1 +/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k. + * CTPIO is not mapped. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_8K 0x0 +/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_16K 0x1 +/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_64K 0x2 +/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing + * (SF-115995-SW) in the present configuration of firmware and port mode. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1 +/* Number of buffers per adapter that can be used for VFIFO Stuffing + * (SF-115995-SW) in the present configuration of firmware and port mode. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2 +/* Entry count in the MAC stats array, including the final GENERATION_END + * entry. For MAC stats DMA, drivers should allocate a buffer large enough to + * hold at least this many 64-bit stats values, if they wish to receive all + * available stats. If the buffer is shorter than MAC_STATS_NUM_STATS * 8, the + * stats array returned will be truncated. + */ +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS_OFST 76 +#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS_LEN 2 /***********************************/ @@ -8502,6 +10219,7 @@ #define MC_CMD_TCM_BUCKET_ALLOC_OUT_LEN 4 /* the bucket id */ #define MC_CMD_TCM_BUCKET_ALLOC_OUT_BUCKET_OFST 0 +#define MC_CMD_TCM_BUCKET_ALLOC_OUT_BUCKET_LEN 4 /***********************************/ @@ -8516,6 +10234,7 @@ #define MC_CMD_TCM_BUCKET_FREE_IN_LEN 4 /* the bucket id */ #define MC_CMD_TCM_BUCKET_FREE_IN_BUCKET_OFST 0 +#define MC_CMD_TCM_BUCKET_FREE_IN_BUCKET_LEN 4 /* MC_CMD_TCM_BUCKET_FREE_OUT msgresponse */ #define MC_CMD_TCM_BUCKET_FREE_OUT_LEN 0 @@ -8533,17 +10252,22 @@ #define MC_CMD_TCM_BUCKET_INIT_IN_LEN 8 /* the bucket id */ #define MC_CMD_TCM_BUCKET_INIT_IN_BUCKET_OFST 0 +#define MC_CMD_TCM_BUCKET_INIT_IN_BUCKET_LEN 4 /* the rate in mbps */ #define MC_CMD_TCM_BUCKET_INIT_IN_RATE_OFST 4 +#define MC_CMD_TCM_BUCKET_INIT_IN_RATE_LEN 4 /* MC_CMD_TCM_BUCKET_INIT_EXT_IN msgrequest */ #define MC_CMD_TCM_BUCKET_INIT_EXT_IN_LEN 12 /* the bucket id */ #define MC_CMD_TCM_BUCKET_INIT_EXT_IN_BUCKET_OFST 0 +#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_BUCKET_LEN 4 /* the rate in mbps */ #define MC_CMD_TCM_BUCKET_INIT_EXT_IN_RATE_OFST 4 +#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_RATE_LEN 4 /* the desired maximum fill level */ #define MC_CMD_TCM_BUCKET_INIT_EXT_IN_MAX_FILL_OFST 8 +#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_MAX_FILL_LEN 4 /* MC_CMD_TCM_BUCKET_INIT_OUT msgresponse */ #define MC_CMD_TCM_BUCKET_INIT_OUT_LEN 0 @@ -8561,10 +10285,13 @@ #define MC_CMD_TCM_TXQ_INIT_IN_LEN 28 /* the txq id */ #define MC_CMD_TCM_TXQ_INIT_IN_QID_OFST 0 +#define MC_CMD_TCM_TXQ_INIT_IN_QID_LEN 4 /* the static priority associated with the txq */ #define MC_CMD_TCM_TXQ_INIT_IN_LABEL_OFST 4 +#define MC_CMD_TCM_TXQ_INIT_IN_LABEL_LEN 4 /* bitmask of the priority queues this txq is inserted into when inserted. */ #define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_OFST 8 +#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_LEN 4 #define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_LBN 0 #define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_WIDTH 1 #define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_LBN 1 @@ -8573,25 +10300,32 @@ #define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_WIDTH 1 /* the reaction point (RP) bucket */ #define MC_CMD_TCM_TXQ_INIT_IN_RP_BKT_OFST 12 +#define MC_CMD_TCM_TXQ_INIT_IN_RP_BKT_LEN 4 /* an already reserved bucket (typically set to bucket associated with outer * vswitch) */ #define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT1_OFST 16 +#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT1_LEN 4 /* an already reserved bucket (typically set to bucket associated with inner * vswitch) */ #define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT2_OFST 20 +#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT2_LEN 4 /* the min bucket (typically for ETS/minimum bandwidth) */ #define MC_CMD_TCM_TXQ_INIT_IN_MIN_BKT_OFST 24 +#define MC_CMD_TCM_TXQ_INIT_IN_MIN_BKT_LEN 4 /* MC_CMD_TCM_TXQ_INIT_EXT_IN msgrequest */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_LEN 32 /* the txq id */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_QID_OFST 0 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_QID_LEN 4 /* the static priority associated with the txq */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_NORMAL_OFST 4 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_NORMAL_LEN 4 /* bitmask of the priority queues this txq is inserted into when inserted. */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAGS_OFST 8 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAGS_LEN 4 #define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_LBN 0 #define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_WIDTH 1 #define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_LBN 1 @@ -8600,18 +10334,23 @@ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_WIDTH 1 /* the reaction point (RP) bucket */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_RP_BKT_OFST 12 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_RP_BKT_LEN 4 /* an already reserved bucket (typically set to bucket associated with outer * vswitch) */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT1_OFST 16 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT1_LEN 4 /* an already reserved bucket (typically set to bucket associated with inner * vswitch) */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT2_OFST 20 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT2_LEN 4 /* the min bucket (typically for ETS/minimum bandwidth) */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_MIN_BKT_OFST 24 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MIN_BKT_LEN 4 /* the static priority associated with the txq */ #define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_GUARANTEED_OFST 28 +#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_GUARANTEED_LEN 4 /* MC_CMD_TCM_TXQ_INIT_OUT msgresponse */ #define MC_CMD_TCM_TXQ_INIT_OUT_LEN 0 @@ -8629,8 +10368,10 @@ #define MC_CMD_LINK_PIOBUF_IN_LEN 8 /* Handle for allocated push I/O buffer. */ #define MC_CMD_LINK_PIOBUF_IN_PIOBUF_HANDLE_OFST 0 +#define MC_CMD_LINK_PIOBUF_IN_PIOBUF_HANDLE_LEN 4 /* Function Local Instance (VI) number. */ #define MC_CMD_LINK_PIOBUF_IN_TXQ_INSTANCE_OFST 4 +#define MC_CMD_LINK_PIOBUF_IN_TXQ_INSTANCE_LEN 4 /* MC_CMD_LINK_PIOBUF_OUT msgresponse */ #define MC_CMD_LINK_PIOBUF_OUT_LEN 0 @@ -8648,6 +10389,7 @@ #define MC_CMD_UNLINK_PIOBUF_IN_LEN 4 /* Function Local Instance (VI) number. */ #define MC_CMD_UNLINK_PIOBUF_IN_TXQ_INSTANCE_OFST 0 +#define MC_CMD_UNLINK_PIOBUF_IN_TXQ_INSTANCE_LEN 4 /* MC_CMD_UNLINK_PIOBUF_OUT msgresponse */ #define MC_CMD_UNLINK_PIOBUF_OUT_LEN 0 @@ -8665,8 +10407,10 @@ #define MC_CMD_VSWITCH_ALLOC_IN_LEN 16 /* The port to connect to the v-switch's upstream port. */ #define MC_CMD_VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID_LEN 4 /* The type of v-switch to create. */ #define MC_CMD_VSWITCH_ALLOC_IN_TYPE_OFST 4 +#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_LEN 4 /* enum: VLAN */ #define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN 0x1 /* enum: VEB */ @@ -8679,6 +10423,7 @@ #define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_TEST 0x5 /* Flags controlling v-port creation */ #define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_OFST 8 +#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_LEN 4 #define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_LBN 0 #define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1 /* The number of VLAN tags to allow for attached v-ports. For VLAN aggregators, @@ -8689,6 +10434,7 @@ * v-ports with this number of tags. */ #define MC_CMD_VSWITCH_ALLOC_IN_NUM_VLAN_TAGS_OFST 12 +#define MC_CMD_VSWITCH_ALLOC_IN_NUM_VLAN_TAGS_LEN 4 /* MC_CMD_VSWITCH_ALLOC_OUT msgresponse */ #define MC_CMD_VSWITCH_ALLOC_OUT_LEN 0 @@ -8706,6 +10452,7 @@ #define MC_CMD_VSWITCH_FREE_IN_LEN 4 /* The port to which the v-switch is connected. */ #define MC_CMD_VSWITCH_FREE_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VSWITCH_FREE_IN_UPSTREAM_PORT_ID_LEN 4 /* MC_CMD_VSWITCH_FREE_OUT msgresponse */ #define MC_CMD_VSWITCH_FREE_OUT_LEN 0 @@ -8725,6 +10472,7 @@ #define MC_CMD_VSWITCH_QUERY_IN_LEN 4 /* The port to which the v-switch is connected. */ #define MC_CMD_VSWITCH_QUERY_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VSWITCH_QUERY_IN_UPSTREAM_PORT_ID_LEN 4 /* MC_CMD_VSWITCH_QUERY_OUT msgresponse */ #define MC_CMD_VSWITCH_QUERY_OUT_LEN 0 @@ -8742,8 +10490,10 @@ #define MC_CMD_VPORT_ALLOC_IN_LEN 20 /* The port to which the v-switch is connected. */ #define MC_CMD_VPORT_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VPORT_ALLOC_IN_UPSTREAM_PORT_ID_LEN 4 /* The type of the new v-port. */ #define MC_CMD_VPORT_ALLOC_IN_TYPE_OFST 4 +#define MC_CMD_VPORT_ALLOC_IN_TYPE_LEN 4 /* enum: VLAN (obsolete) */ #define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VLAN 0x1 /* enum: VEB (obsolete) */ @@ -8764,6 +10514,7 @@ #define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST 0x6 /* Flags controlling v-port creation */ #define MC_CMD_VPORT_ALLOC_IN_FLAGS_OFST 8 +#define MC_CMD_VPORT_ALLOC_IN_FLAGS_LEN 4 #define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_LBN 0 #define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1 #define MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_LBN 1 @@ -8773,8 +10524,10 @@ * v-switch. */ #define MC_CMD_VPORT_ALLOC_IN_NUM_VLAN_TAGS_OFST 12 +#define MC_CMD_VPORT_ALLOC_IN_NUM_VLAN_TAGS_LEN 4 /* The actual VLAN tags to insert/remove */ #define MC_CMD_VPORT_ALLOC_IN_VLAN_TAGS_OFST 16 +#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAGS_LEN 4 #define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_LBN 0 #define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_WIDTH 16 #define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_LBN 16 @@ -8784,6 +10537,7 @@ #define MC_CMD_VPORT_ALLOC_OUT_LEN 4 /* The handle of the new v-port */ #define MC_CMD_VPORT_ALLOC_OUT_VPORT_ID_OFST 0 +#define MC_CMD_VPORT_ALLOC_OUT_VPORT_ID_LEN 4 /***********************************/ @@ -8798,6 +10552,7 @@ #define MC_CMD_VPORT_FREE_IN_LEN 4 /* The handle of the v-port */ #define MC_CMD_VPORT_FREE_IN_VPORT_ID_OFST 0 +#define MC_CMD_VPORT_FREE_IN_VPORT_ID_LEN 4 /* MC_CMD_VPORT_FREE_OUT msgresponse */ #define MC_CMD_VPORT_FREE_OUT_LEN 0 @@ -8815,18 +10570,23 @@ #define MC_CMD_VADAPTOR_ALLOC_IN_LEN 30 /* The port to connect to the v-adaptor's port. */ #define MC_CMD_VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID_LEN 4 /* Flags controlling v-adaptor creation */ #define MC_CMD_VADAPTOR_ALLOC_IN_FLAGS_OFST 8 +#define MC_CMD_VADAPTOR_ALLOC_IN_FLAGS_LEN 4 #define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_LBN 0 #define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_WIDTH 1 #define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 1 #define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1 /* The number of VLAN tags to strip on receive */ #define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLANS_OFST 12 +#define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLANS_LEN 4 /* The number of VLAN tags to transparently insert/remove. */ #define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLAN_TAGS_OFST 16 +#define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLAN_TAGS_LEN 4 /* The actual VLAN tags to insert/remove */ #define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAGS_OFST 20 +#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAGS_LEN 4 #define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_LBN 0 #define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_WIDTH 16 #define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_LBN 16 @@ -8853,6 +10613,7 @@ #define MC_CMD_VADAPTOR_FREE_IN_LEN 4 /* The port to which the v-adaptor is connected. */ #define MC_CMD_VADAPTOR_FREE_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VADAPTOR_FREE_IN_UPSTREAM_PORT_ID_LEN 4 /* MC_CMD_VADAPTOR_FREE_OUT msgresponse */ #define MC_CMD_VADAPTOR_FREE_OUT_LEN 0 @@ -8870,6 +10631,7 @@ #define MC_CMD_VADAPTOR_SET_MAC_IN_LEN 10 /* The port to which the v-adaptor is connected. */ #define MC_CMD_VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID_LEN 4 /* The new MAC address to assign to this v-adaptor */ #define MC_CMD_VADAPTOR_SET_MAC_IN_MACADDR_OFST 4 #define MC_CMD_VADAPTOR_SET_MAC_IN_MACADDR_LEN 6 @@ -8890,6 +10652,7 @@ #define MC_CMD_VADAPTOR_GET_MAC_IN_LEN 4 /* The port to which the v-adaptor is connected. */ #define MC_CMD_VADAPTOR_GET_MAC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VADAPTOR_GET_MAC_IN_UPSTREAM_PORT_ID_LEN 4 /* MC_CMD_VADAPTOR_GET_MAC_OUT msgresponse */ #define MC_CMD_VADAPTOR_GET_MAC_OUT_LEN 6 @@ -8910,15 +10673,19 @@ #define MC_CMD_VADAPTOR_QUERY_IN_LEN 4 /* The port to which the v-adaptor is connected. */ #define MC_CMD_VADAPTOR_QUERY_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_VADAPTOR_QUERY_IN_UPSTREAM_PORT_ID_LEN 4 /* MC_CMD_VADAPTOR_QUERY_OUT msgresponse */ #define MC_CMD_VADAPTOR_QUERY_OUT_LEN 12 /* The EVB port flags as defined at MC_CMD_VPORT_ALLOC. */ #define MC_CMD_VADAPTOR_QUERY_OUT_PORT_FLAGS_OFST 0 +#define MC_CMD_VADAPTOR_QUERY_OUT_PORT_FLAGS_LEN 4 /* The v-adaptor flags as defined at MC_CMD_VADAPTOR_ALLOC. */ #define MC_CMD_VADAPTOR_QUERY_OUT_VADAPTOR_FLAGS_OFST 4 +#define MC_CMD_VADAPTOR_QUERY_OUT_VADAPTOR_FLAGS_LEN 4 /* The number of VLAN tags that may still be added */ #define MC_CMD_VADAPTOR_QUERY_OUT_NUM_AVAILABLE_VLAN_TAGS_OFST 8 +#define MC_CMD_VADAPTOR_QUERY_OUT_NUM_AVAILABLE_VLAN_TAGS_LEN 4 /***********************************/ @@ -8933,8 +10700,10 @@ #define MC_CMD_EVB_PORT_ASSIGN_IN_LEN 8 /* The port to assign. */ #define MC_CMD_EVB_PORT_ASSIGN_IN_PORT_ID_OFST 0 +#define MC_CMD_EVB_PORT_ASSIGN_IN_PORT_ID_LEN 4 /* The target function to modify. */ #define MC_CMD_EVB_PORT_ASSIGN_IN_FUNCTION_OFST 4 +#define MC_CMD_EVB_PORT_ASSIGN_IN_FUNCTION_LEN 4 #define MC_CMD_EVB_PORT_ASSIGN_IN_PF_LBN 0 #define MC_CMD_EVB_PORT_ASSIGN_IN_PF_WIDTH 16 #define MC_CMD_EVB_PORT_ASSIGN_IN_VF_LBN 16 @@ -8955,9 +10724,13 @@ /* MC_CMD_RDWR_A64_REGIONS_IN msgrequest */ #define MC_CMD_RDWR_A64_REGIONS_IN_LEN 17 #define MC_CMD_RDWR_A64_REGIONS_IN_REGION0_OFST 0 +#define MC_CMD_RDWR_A64_REGIONS_IN_REGION0_LEN 4 #define MC_CMD_RDWR_A64_REGIONS_IN_REGION1_OFST 4 +#define MC_CMD_RDWR_A64_REGIONS_IN_REGION1_LEN 4 #define MC_CMD_RDWR_A64_REGIONS_IN_REGION2_OFST 8 +#define MC_CMD_RDWR_A64_REGIONS_IN_REGION2_LEN 4 #define MC_CMD_RDWR_A64_REGIONS_IN_REGION3_OFST 12 +#define MC_CMD_RDWR_A64_REGIONS_IN_REGION3_LEN 4 /* Write enable bits 0-3, set to write, clear to read. */ #define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_LBN 128 #define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_WIDTH 4 @@ -8969,9 +10742,13 @@ */ #define MC_CMD_RDWR_A64_REGIONS_OUT_LEN 16 #define MC_CMD_RDWR_A64_REGIONS_OUT_REGION0_OFST 0 +#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION0_LEN 4 #define MC_CMD_RDWR_A64_REGIONS_OUT_REGION1_OFST 4 +#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION1_LEN 4 #define MC_CMD_RDWR_A64_REGIONS_OUT_REGION2_OFST 8 +#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION2_LEN 4 #define MC_CMD_RDWR_A64_REGIONS_OUT_REGION3_OFST 12 +#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION3_LEN 4 /***********************************/ @@ -8986,11 +10763,13 @@ #define MC_CMD_ONLOAD_STACK_ALLOC_IN_LEN 4 /* The handle of the owning upstream port */ #define MC_CMD_ONLOAD_STACK_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_ONLOAD_STACK_ALLOC_IN_UPSTREAM_PORT_ID_LEN 4 /* MC_CMD_ONLOAD_STACK_ALLOC_OUT msgresponse */ #define MC_CMD_ONLOAD_STACK_ALLOC_OUT_LEN 4 /* The handle of the new Onload stack */ #define MC_CMD_ONLOAD_STACK_ALLOC_OUT_ONLOAD_STACK_ID_OFST 0 +#define MC_CMD_ONLOAD_STACK_ALLOC_OUT_ONLOAD_STACK_ID_LEN 4 /***********************************/ @@ -9005,6 +10784,7 @@ #define MC_CMD_ONLOAD_STACK_FREE_IN_LEN 4 /* The handle of the Onload stack */ #define MC_CMD_ONLOAD_STACK_FREE_IN_ONLOAD_STACK_ID_OFST 0 +#define MC_CMD_ONLOAD_STACK_FREE_IN_ONLOAD_STACK_ID_LEN 4 /* MC_CMD_ONLOAD_STACK_FREE_OUT msgresponse */ #define MC_CMD_ONLOAD_STACK_FREE_OUT_LEN 0 @@ -9022,8 +10802,10 @@ #define MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN 12 /* The handle of the owning upstream port */ #define MC_CMD_RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID_LEN 4 /* The type of context to allocate */ #define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_OFST 4 +#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_LEN 4 /* enum: Allocate a context for exclusive use. The key and indirection table * must be explicitly configured. */ @@ -9037,6 +10819,7 @@ * in the indirection table will be in the range 0 to NUM_QUEUES-1. */ #define MC_CMD_RSS_CONTEXT_ALLOC_IN_NUM_QUEUES_OFST 8 +#define MC_CMD_RSS_CONTEXT_ALLOC_IN_NUM_QUEUES_LEN 4 /* MC_CMD_RSS_CONTEXT_ALLOC_OUT msgresponse */ #define MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN 4 @@ -9045,6 +10828,7 @@ * handle. */ #define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_LEN 4 /* enum: guaranteed invalid RSS context handle value */ #define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_INVALID 0xffffffff @@ -9061,6 +10845,7 @@ #define MC_CMD_RSS_CONTEXT_FREE_IN_LEN 4 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID_LEN 4 /* MC_CMD_RSS_CONTEXT_FREE_OUT msgresponse */ #define MC_CMD_RSS_CONTEXT_FREE_OUT_LEN 0 @@ -9078,6 +10863,7 @@ #define MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN 44 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID_LEN 4 /* The 40-byte Toeplitz hash key (TBD endianness issues?) */ #define MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_OFST 4 #define MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN 40 @@ -9098,6 +10884,7 @@ #define MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN 4 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID_LEN 4 /* MC_CMD_RSS_CONTEXT_GET_KEY_OUT msgresponse */ #define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN 44 @@ -9118,6 +10905,7 @@ #define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN 132 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID_LEN 4 /* The 128-byte indirection table (1 byte per entry) */ #define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_OFST 4 #define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN 128 @@ -9138,6 +10926,7 @@ #define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN 4 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID_LEN 4 /* MC_CMD_RSS_CONTEXT_GET_TABLE_OUT msgresponse */ #define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN 132 @@ -9158,6 +10947,7 @@ #define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN 8 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID_LEN 4 /* Hash control flags. The _EN bits are always supported, but new modes are * available when ADDITIONAL_RSS_MODES is reported by MC_CMD_GET_CAPABILITIES: * in this case, the MODE fields may be set to non-zero values, and will take @@ -9171,6 +10961,7 @@ * particular packet type.) */ #define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_FLAGS_OFST 4 +#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_FLAGS_LEN 4 #define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_LBN 0 #define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_WIDTH 1 #define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_LBN 1 @@ -9210,6 +11001,7 @@ #define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_LEN 4 /* The handle of the RSS context */ #define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_RSS_CONTEXT_ID_OFST 0 +#define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_RSS_CONTEXT_ID_LEN 4 /* MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT msgresponse */ #define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN 8 @@ -9227,6 +11019,7 @@ * always be used for a SET regardless of old/new driver vs. old/new firmware. */ #define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_OFST 4 +#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_LEN 4 #define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_LBN 0 #define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_WIDTH 1 #define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_LBN 1 @@ -9263,11 +11056,13 @@ #define MC_CMD_DOT1P_MAPPING_ALLOC_IN_LEN 8 /* The handle of the owning upstream port */ #define MC_CMD_DOT1P_MAPPING_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0 +#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_UPSTREAM_PORT_ID_LEN 4 /* Number of queues spanned by this mapping, in the range 1-64; valid fixed * offsets in the mapping table will be in the range 0 to NUM_QUEUES-1, and * referenced RSS contexts must span no more than this number. */ #define MC_CMD_DOT1P_MAPPING_ALLOC_IN_NUM_QUEUES_OFST 4 +#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_NUM_QUEUES_LEN 4 /* MC_CMD_DOT1P_MAPPING_ALLOC_OUT msgresponse */ #define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_LEN 4 @@ -9276,6 +11071,7 @@ * handle. */ #define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_OFST 0 +#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_LEN 4 /* enum: guaranteed invalid .1p mapping handle value */ #define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_INVALID 0xffffffff @@ -9292,6 +11088,7 @@ #define MC_CMD_DOT1P_MAPPING_FREE_IN_LEN 4 /* The handle of the .1p mapping */ #define MC_CMD_DOT1P_MAPPING_FREE_IN_DOT1P_MAPPING_ID_OFST 0 +#define MC_CMD_DOT1P_MAPPING_FREE_IN_DOT1P_MAPPING_ID_LEN 4 /* MC_CMD_DOT1P_MAPPING_FREE_OUT msgresponse */ #define MC_CMD_DOT1P_MAPPING_FREE_OUT_LEN 0 @@ -9309,6 +11106,7 @@ #define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_LEN 36 /* The handle of the .1p mapping */ #define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_DOT1P_MAPPING_ID_OFST 0 +#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_DOT1P_MAPPING_ID_LEN 4 /* Per-priority mappings (1 32-bit word per entry - an offset or RSS context * handle) */ @@ -9331,6 +11129,7 @@ #define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_LEN 4 /* The handle of the .1p mapping */ #define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_DOT1P_MAPPING_ID_OFST 0 +#define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_DOT1P_MAPPING_ID_LEN 4 /* MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT msgresponse */ #define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_LEN 36 @@ -9356,10 +11155,13 @@ #define MC_CMD_GET_VECTOR_CFG_OUT_LEN 12 /* Base absolute interrupt vector number. */ #define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_OFST 0 +#define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_LEN 4 /* Number of interrupt vectors allocate to this PF. */ #define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_OFST 4 +#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_LEN 4 /* Number of interrupt vectors to allocate per VF. */ #define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_OFST 8 +#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_LEN 4 /***********************************/ @@ -9376,10 +11178,13 @@ * let the system find a suitable base. */ #define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_OFST 0 +#define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_LEN 4 /* Number of interrupt vectors allocate to this PF. */ #define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_OFST 4 +#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_LEN 4 /* Number of interrupt vectors to allocate per VF. */ #define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_OFST 8 +#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_LEN 4 /* MC_CMD_SET_VECTOR_CFG_OUT msgresponse */ #define MC_CMD_SET_VECTOR_CFG_OUT_LEN 0 @@ -9397,6 +11202,7 @@ #define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN 10 /* The handle of the v-port */ #define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID_OFST 0 +#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID_LEN 4 /* MAC address to add */ #define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_MACADDR_OFST 4 #define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_MACADDR_LEN 6 @@ -9417,6 +11223,7 @@ #define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN 10 /* The handle of the v-port */ #define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID_OFST 0 +#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID_LEN 4 /* MAC address to add */ #define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_MACADDR_OFST 4 #define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_MACADDR_LEN 6 @@ -9437,6 +11244,7 @@ #define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN 4 /* The handle of the v-port */ #define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID_OFST 0 +#define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID_LEN 4 /* MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT msgresponse */ #define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN 4 @@ -9444,6 +11252,7 @@ #define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LEN(num) (4+6*(num)) /* The number of MAC addresses returned */ #define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT_OFST 0 +#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT_LEN 4 /* Array of MAC addresses */ #define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_OFST 4 #define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_LEN 6 @@ -9465,8 +11274,10 @@ #define MC_CMD_VPORT_RECONFIGURE_IN_LEN 44 /* The handle of the v-port */ #define MC_CMD_VPORT_RECONFIGURE_IN_VPORT_ID_OFST 0 +#define MC_CMD_VPORT_RECONFIGURE_IN_VPORT_ID_LEN 4 /* Flags requesting what should be changed. */ #define MC_CMD_VPORT_RECONFIGURE_IN_FLAGS_OFST 4 +#define MC_CMD_VPORT_RECONFIGURE_IN_FLAGS_LEN 4 #define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS_LBN 0 #define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS_WIDTH 1 #define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_MACADDRS_LBN 1 @@ -9476,14 +11287,17 @@ * v-switch. */ #define MC_CMD_VPORT_RECONFIGURE_IN_NUM_VLAN_TAGS_OFST 8 +#define MC_CMD_VPORT_RECONFIGURE_IN_NUM_VLAN_TAGS_LEN 4 /* The actual VLAN tags to insert/remove */ #define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAGS_OFST 12 +#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAGS_LEN 4 #define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_0_LBN 0 #define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_0_WIDTH 16 #define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_1_LBN 16 #define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_1_WIDTH 16 /* The number of MAC addresses to add */ #define MC_CMD_VPORT_RECONFIGURE_IN_NUM_MACADDRS_OFST 16 +#define MC_CMD_VPORT_RECONFIGURE_IN_NUM_MACADDRS_LEN 4 /* MAC addresses to add */ #define MC_CMD_VPORT_RECONFIGURE_IN_MACADDRS_OFST 20 #define MC_CMD_VPORT_RECONFIGURE_IN_MACADDRS_LEN 6 @@ -9492,6 +11306,7 @@ /* MC_CMD_VPORT_RECONFIGURE_OUT msgresponse */ #define MC_CMD_VPORT_RECONFIGURE_OUT_LEN 4 #define MC_CMD_VPORT_RECONFIGURE_OUT_FLAGS_OFST 0 +#define MC_CMD_VPORT_RECONFIGURE_OUT_FLAGS_LEN 4 #define MC_CMD_VPORT_RECONFIGURE_OUT_RESET_DONE_LBN 0 #define MC_CMD_VPORT_RECONFIGURE_OUT_RESET_DONE_WIDTH 1 @@ -9508,15 +11323,18 @@ #define MC_CMD_EVB_PORT_QUERY_IN_LEN 4 /* The handle of the v-port */ #define MC_CMD_EVB_PORT_QUERY_IN_PORT_ID_OFST 0 +#define MC_CMD_EVB_PORT_QUERY_IN_PORT_ID_LEN 4 /* MC_CMD_EVB_PORT_QUERY_OUT msgresponse */ #define MC_CMD_EVB_PORT_QUERY_OUT_LEN 8 /* The EVB port flags as defined at MC_CMD_VPORT_ALLOC. */ #define MC_CMD_EVB_PORT_QUERY_OUT_PORT_FLAGS_OFST 0 +#define MC_CMD_EVB_PORT_QUERY_OUT_PORT_FLAGS_LEN 4 /* The number of VLAN tags that may be used on a v-adaptor connected to this * EVB port. */ #define MC_CMD_EVB_PORT_QUERY_OUT_NUM_AVAILABLE_VLAN_TAGS_OFST 4 +#define MC_CMD_EVB_PORT_QUERY_OUT_NUM_AVAILABLE_VLAN_TAGS_LEN 4 /***********************************/ @@ -9528,14 +11346,16 @@ */ #define MC_CMD_DUMP_BUFTBL_ENTRIES 0xab -#define MC_CMD_0xab_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xab_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_DUMP_BUFTBL_ENTRIES_IN msgrequest */ #define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_LEN 8 /* Index of the first buffer table entry. */ #define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_FIRSTID_OFST 0 +#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_FIRSTID_LEN 4 /* Number of buffer table entries to dump. */ #define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 4 +#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_NUMENTRIES_LEN 4 /* MC_CMD_DUMP_BUFTBL_ENTRIES_OUT msgresponse */ #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMIN 12 @@ -9559,6 +11379,7 @@ /* MC_CMD_SET_RXDP_CONFIG_IN msgrequest */ #define MC_CMD_SET_RXDP_CONFIG_IN_LEN 4 #define MC_CMD_SET_RXDP_CONFIG_IN_DATA_OFST 0 +#define MC_CMD_SET_RXDP_CONFIG_IN_DATA_LEN 4 #define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_LBN 0 #define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_WIDTH 1 #define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_LBN 1 @@ -9588,6 +11409,7 @@ /* MC_CMD_GET_RXDP_CONFIG_OUT msgresponse */ #define MC_CMD_GET_RXDP_CONFIG_OUT_LEN 4 #define MC_CMD_GET_RXDP_CONFIG_OUT_DATA_OFST 0 +#define MC_CMD_GET_RXDP_CONFIG_OUT_DATA_LEN 4 #define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_LBN 0 #define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_WIDTH 1 #define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_LEN_LBN 1 @@ -9611,8 +11433,10 @@ #define MC_CMD_GET_CLOCK_OUT_LEN 8 /* System frequency, MHz */ #define MC_CMD_GET_CLOCK_OUT_SYS_FREQ_OFST 0 +#define MC_CMD_GET_CLOCK_OUT_SYS_FREQ_LEN 4 /* DPCPU frequency, MHz */ #define MC_CMD_GET_CLOCK_OUT_DPCPU_FREQ_OFST 4 +#define MC_CMD_GET_CLOCK_OUT_DPCPU_FREQ_LEN 4 /***********************************/ @@ -9621,36 +11445,43 @@ */ #define MC_CMD_SET_CLOCK 0xad -#define MC_CMD_0xad_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xad_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_SET_CLOCK_IN msgrequest */ #define MC_CMD_SET_CLOCK_IN_LEN 28 /* Requested frequency in MHz for system clock domain */ #define MC_CMD_SET_CLOCK_IN_SYS_FREQ_OFST 0 +#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_LEN 4 /* enum: Leave the system clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_SYS_DOMAIN_DONT_CHANGE 0x0 /* Requested frequency in MHz for inter-core clock domain */ #define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_OFST 4 +#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_LEN 4 /* enum: Leave the inter-core clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_ICORE_DOMAIN_DONT_CHANGE 0x0 /* Requested frequency in MHz for DPCPU clock domain */ #define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_OFST 8 +#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_LEN 4 /* enum: Leave the DPCPU clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_DPCPU_DOMAIN_DONT_CHANGE 0x0 /* Requested frequency in MHz for PCS clock domain */ #define MC_CMD_SET_CLOCK_IN_PCS_FREQ_OFST 12 +#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_LEN 4 /* enum: Leave the PCS clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_PCS_DOMAIN_DONT_CHANGE 0x0 /* Requested frequency in MHz for MC clock domain */ #define MC_CMD_SET_CLOCK_IN_MC_FREQ_OFST 16 +#define MC_CMD_SET_CLOCK_IN_MC_FREQ_LEN 4 /* enum: Leave the MC clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_MC_DOMAIN_DONT_CHANGE 0x0 /* Requested frequency in MHz for rmon clock domain */ #define MC_CMD_SET_CLOCK_IN_RMON_FREQ_OFST 20 +#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_LEN 4 /* enum: Leave the rmon clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_RMON_DOMAIN_DONT_CHANGE 0x0 /* Requested frequency in MHz for vswitch clock domain */ #define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_OFST 24 +#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_LEN 4 /* enum: Leave the vswitch clock domain frequency unchanged */ #define MC_CMD_SET_CLOCK_IN_VSWITCH_DOMAIN_DONT_CHANGE 0x0 @@ -9658,30 +11489,37 @@ #define MC_CMD_SET_CLOCK_OUT_LEN 28 /* Resulting system frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_OFST 0 +#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_LEN 4 /* enum: The system clock domain doesn't exist */ #define MC_CMD_SET_CLOCK_OUT_SYS_DOMAIN_UNSUPPORTED 0x0 /* Resulting inter-core frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_OFST 4 +#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_LEN 4 /* enum: The inter-core clock domain doesn't exist / isn't used */ #define MC_CMD_SET_CLOCK_OUT_ICORE_DOMAIN_UNSUPPORTED 0x0 /* Resulting DPCPU frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_OFST 8 +#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_LEN 4 /* enum: The dpcpu clock domain doesn't exist */ #define MC_CMD_SET_CLOCK_OUT_DPCPU_DOMAIN_UNSUPPORTED 0x0 /* Resulting PCS frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_OFST 12 +#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_LEN 4 /* enum: The PCS clock domain doesn't exist / isn't controlled */ #define MC_CMD_SET_CLOCK_OUT_PCS_DOMAIN_UNSUPPORTED 0x0 /* Resulting MC frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_MC_FREQ_OFST 16 +#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_LEN 4 /* enum: The MC clock domain doesn't exist / isn't controlled */ #define MC_CMD_SET_CLOCK_OUT_MC_DOMAIN_UNSUPPORTED 0x0 /* Resulting rmon frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_OFST 20 +#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_LEN 4 /* enum: The rmon clock domain doesn't exist / isn't controlled */ #define MC_CMD_SET_CLOCK_OUT_RMON_DOMAIN_UNSUPPORTED 0x0 /* Resulting vswitch frequency in MHz */ #define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_OFST 24 +#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_LEN 4 /* enum: The vswitch clock domain doesn't exist / isn't controlled */ #define MC_CMD_SET_CLOCK_OUT_VSWITCH_DOMAIN_UNSUPPORTED 0x0 @@ -9692,11 +11530,12 @@ */ #define MC_CMD_DPCPU_RPC 0xae -#define MC_CMD_0xae_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xae_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_DPCPU_RPC_IN msgrequest */ #define MC_CMD_DPCPU_RPC_IN_LEN 36 #define MC_CMD_DPCPU_RPC_IN_CPU_OFST 0 +#define MC_CMD_DPCPU_RPC_IN_CPU_LEN 4 /* enum: RxDPCPU0 */ #define MC_CMD_DPCPU_RPC_IN_DPCPU_RX0 0x0 /* enum: TxDPCPU0 */ @@ -9761,12 +11600,15 @@ #define MC_CMD_DPCPU_RPC_IN_WDATA_LEN 24 /* Register data to write. Only valid in write/write-read. */ #define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_DATA_OFST 16 +#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_DATA_LEN 4 /* Register address. */ #define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_ADDRESS_OFST 20 +#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_ADDRESS_LEN 4 /* MC_CMD_DPCPU_RPC_OUT msgresponse */ #define MC_CMD_DPCPU_RPC_OUT_LEN 36 #define MC_CMD_DPCPU_RPC_OUT_RC_OFST 0 +#define MC_CMD_DPCPU_RPC_OUT_RC_LEN 4 /* DATA */ #define MC_CMD_DPCPU_RPC_OUT_DATA_OFST 4 #define MC_CMD_DPCPU_RPC_OUT_DATA_LEN 32 @@ -9777,9 +11619,13 @@ #define MC_CMD_DPCPU_RPC_OUT_RDATA_OFST 12 #define MC_CMD_DPCPU_RPC_OUT_RDATA_LEN 24 #define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_1_OFST 12 +#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_1_LEN 4 #define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_2_OFST 16 +#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_2_LEN 4 #define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_3_OFST 20 +#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_3_LEN 4 #define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_4_OFST 24 +#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_4_LEN 4 /***********************************/ @@ -9794,6 +11640,7 @@ #define MC_CMD_TRIGGER_INTERRUPT_IN_LEN 4 /* Interrupt level relative to base for function. */ #define MC_CMD_TRIGGER_INTERRUPT_IN_INTR_LEVEL_OFST 0 +#define MC_CMD_TRIGGER_INTERRUPT_IN_INTR_LEVEL_LEN 4 /* MC_CMD_TRIGGER_INTERRUPT_OUT msgresponse */ #define MC_CMD_TRIGGER_INTERRUPT_OUT_LEN 0 @@ -9811,6 +11658,7 @@ #define MC_CMD_SHMBOOT_OP_IN_LEN 4 /* Identifies the operation to perform */ #define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_OFST 0 +#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_LEN 4 /* enum: Copy slave_data section to the slave core. (Greenport only) */ #define MC_CMD_SHMBOOT_OP_IN_PUSH_SLAVE_DATA 0x0 @@ -9824,13 +11672,16 @@ */ #define MC_CMD_CAP_BLK_READ 0xe7 -#define MC_CMD_0xe7_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xe7_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_CAP_BLK_READ_IN msgrequest */ #define MC_CMD_CAP_BLK_READ_IN_LEN 12 #define MC_CMD_CAP_BLK_READ_IN_CAP_REG_OFST 0 +#define MC_CMD_CAP_BLK_READ_IN_CAP_REG_LEN 4 #define MC_CMD_CAP_BLK_READ_IN_ADDR_OFST 4 +#define MC_CMD_CAP_BLK_READ_IN_ADDR_LEN 4 #define MC_CMD_CAP_BLK_READ_IN_COUNT_OFST 8 +#define MC_CMD_CAP_BLK_READ_IN_COUNT_LEN 4 /* MC_CMD_CAP_BLK_READ_OUT msgresponse */ #define MC_CMD_CAP_BLK_READ_OUT_LENMIN 8 @@ -9850,53 +11701,77 @@ */ #define MC_CMD_DUMP_DO 0xe8 -#define MC_CMD_0xe8_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xe8_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_DUMP_DO_IN msgrequest */ #define MC_CMD_DUMP_DO_IN_LEN 52 #define MC_CMD_DUMP_DO_IN_PADDING_OFST 0 +#define MC_CMD_DUMP_DO_IN_PADDING_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_OFST 4 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM 0x0 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_DEFAULT 0x1 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_NVRAM 0x1 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY 0x2 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY_MLI 0x3 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_UART 0x4 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 12 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 16 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_LEN 4 #define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_PAGE_SIZE 0x1000 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_LEN 4 #define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_LEN 4 /* enum: The uart port this command was received over (if using a uart * transport) */ #define MC_CMD_DUMP_DO_IN_UART_PORT_SRC 0xff #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24 +#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_NVRAM_DUMP_PARTITION 0x1 /* enum */ #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */ #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 36 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_OFST 40 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 36 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 40 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 36 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 40 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 44 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_UART_PORT_OFST 36 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_UART_PORT_LEN 4 #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_SIZE_OFST 48 +#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_SIZE_LEN 4 /* MC_CMD_DUMP_DO_OUT msgresponse */ #define MC_CMD_DUMP_DO_OUT_LEN 4 #define MC_CMD_DUMP_DO_OUT_DUMPFILE_SIZE_OFST 0 +#define MC_CMD_DUMP_DO_OUT_DUMPFILE_SIZE_LEN 4 /***********************************/ @@ -9905,41 +11780,64 @@ */ #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED 0xe9 -#define MC_CMD_0xe9_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xe9_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN msgrequest */ #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_LEN 52 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_ENABLE_OFST 0 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_ENABLE_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_OFST 4 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC */ #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */ #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 12 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 16 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_SIZE_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_OFST 28 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPFILE_DST */ #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */ #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 36 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_OFST 40 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 36 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 40 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 36 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 40 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 44 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_UART_PORT_OFST 36 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_UART_PORT_LEN 4 #define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_SIZE_OFST 48 +#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_SIZE_LEN 4 /***********************************/ @@ -9950,17 +11848,20 @@ */ #define MC_CMD_SET_PSU 0xea -#define MC_CMD_0xea_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xea_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_SET_PSU_IN msgrequest */ #define MC_CMD_SET_PSU_IN_LEN 12 #define MC_CMD_SET_PSU_IN_PARAM_OFST 0 +#define MC_CMD_SET_PSU_IN_PARAM_LEN 4 #define MC_CMD_SET_PSU_IN_PARAM_SUPPLY_VOLTAGE 0x0 /* enum */ #define MC_CMD_SET_PSU_IN_RAIL_OFST 4 +#define MC_CMD_SET_PSU_IN_RAIL_LEN 4 #define MC_CMD_SET_PSU_IN_RAIL_0V9 0x0 /* enum */ #define MC_CMD_SET_PSU_IN_RAIL_1V2 0x1 /* enum */ /* desired value, eg voltage in mV */ #define MC_CMD_SET_PSU_IN_VALUE_OFST 8 +#define MC_CMD_SET_PSU_IN_VALUE_LEN 4 /* MC_CMD_SET_PSU_OUT msgresponse */ #define MC_CMD_SET_PSU_OUT_LEN 0 @@ -9980,7 +11881,9 @@ /* MC_CMD_GET_FUNCTION_INFO_OUT msgresponse */ #define MC_CMD_GET_FUNCTION_INFO_OUT_LEN 8 #define MC_CMD_GET_FUNCTION_INFO_OUT_PF_OFST 0 +#define MC_CMD_GET_FUNCTION_INFO_OUT_PF_LEN 4 #define MC_CMD_GET_FUNCTION_INFO_OUT_VF_OFST 4 +#define MC_CMD_GET_FUNCTION_INFO_OUT_VF_LEN 4 /***********************************/ @@ -10016,12 +11919,16 @@ #define MC_CMD_UART_SEND_DATA_OUT_LEN(num) (16+1*(num)) /* CRC32 over OFFSET, LENGTH, RESERVED, DATA */ #define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_OFST 0 +#define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_LEN 4 /* Offset at which to write the data */ #define MC_CMD_UART_SEND_DATA_OUT_OFFSET_OFST 4 +#define MC_CMD_UART_SEND_DATA_OUT_OFFSET_LEN 4 /* Length of data */ #define MC_CMD_UART_SEND_DATA_OUT_LENGTH_OFST 8 +#define MC_CMD_UART_SEND_DATA_OUT_LENGTH_LEN 4 /* Reserved for future use */ #define MC_CMD_UART_SEND_DATA_OUT_RESERVED_OFST 12 +#define MC_CMD_UART_SEND_DATA_OUT_RESERVED_LEN 4 #define MC_CMD_UART_SEND_DATA_OUT_DATA_OFST 16 #define MC_CMD_UART_SEND_DATA_OUT_DATA_LEN 1 #define MC_CMD_UART_SEND_DATA_OUT_DATA_MINNUM 0 @@ -10044,12 +11951,16 @@ #define MC_CMD_UART_RECV_DATA_OUT_LEN 16 /* CRC32 over OFFSET, LENGTH, RESERVED */ #define MC_CMD_UART_RECV_DATA_OUT_CHECKSUM_OFST 0 +#define MC_CMD_UART_RECV_DATA_OUT_CHECKSUM_LEN 4 /* Offset from which to read the data */ #define MC_CMD_UART_RECV_DATA_OUT_OFFSET_OFST 4 +#define MC_CMD_UART_RECV_DATA_OUT_OFFSET_LEN 4 /* Length of data */ #define MC_CMD_UART_RECV_DATA_OUT_LENGTH_OFST 8 +#define MC_CMD_UART_RECV_DATA_OUT_LENGTH_LEN 4 /* Reserved for future use */ #define MC_CMD_UART_RECV_DATA_OUT_RESERVED_OFST 12 +#define MC_CMD_UART_RECV_DATA_OUT_RESERVED_LEN 4 /* MC_CMD_UART_RECV_DATA_IN msgresponse */ #define MC_CMD_UART_RECV_DATA_IN_LENMIN 16 @@ -10057,12 +11968,16 @@ #define MC_CMD_UART_RECV_DATA_IN_LEN(num) (16+1*(num)) /* CRC32 over RESERVED1, RESERVED2, RESERVED3, DATA */ #define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_OFST 0 +#define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_LEN 4 /* Offset at which to write the data */ #define MC_CMD_UART_RECV_DATA_IN_RESERVED1_OFST 4 +#define MC_CMD_UART_RECV_DATA_IN_RESERVED1_LEN 4 /* Length of data */ #define MC_CMD_UART_RECV_DATA_IN_RESERVED2_OFST 8 +#define MC_CMD_UART_RECV_DATA_IN_RESERVED2_LEN 4 /* Reserved for future use */ #define MC_CMD_UART_RECV_DATA_IN_RESERVED3_OFST 12 +#define MC_CMD_UART_RECV_DATA_IN_RESERVED3_LEN 4 #define MC_CMD_UART_RECV_DATA_IN_DATA_OFST 16 #define MC_CMD_UART_RECV_DATA_IN_DATA_LEN 1 #define MC_CMD_UART_RECV_DATA_IN_DATA_MINNUM 0 @@ -10075,14 +11990,16 @@ */ #define MC_CMD_READ_FUSES 0xf0 -#define MC_CMD_0xf0_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0xf0_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_READ_FUSES_IN msgrequest */ #define MC_CMD_READ_FUSES_IN_LEN 8 /* Offset in OTP to read */ #define MC_CMD_READ_FUSES_IN_OFFSET_OFST 0 +#define MC_CMD_READ_FUSES_IN_OFFSET_LEN 4 /* Length of data to read in bytes */ #define MC_CMD_READ_FUSES_IN_LENGTH_OFST 4 +#define MC_CMD_READ_FUSES_IN_LENGTH_LEN 4 /* MC_CMD_READ_FUSES_OUT msgresponse */ #define MC_CMD_READ_FUSES_OUT_LENMIN 4 @@ -10090,6 +12007,7 @@ #define MC_CMD_READ_FUSES_OUT_LEN(num) (4+1*(num)) /* Length of returned OTP data in bytes */ #define MC_CMD_READ_FUSES_OUT_LENGTH_OFST 0 +#define MC_CMD_READ_FUSES_OUT_LENGTH_LEN 4 /* Returned data */ #define MC_CMD_READ_FUSES_OUT_DATA_OFST 4 #define MC_CMD_READ_FUSES_OUT_DATA_LEN 1 @@ -10197,6 +12115,60 @@ #define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_EQC 0x9 /* enum: CTLE EQ Resistor (0-7, Medford) */ #define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_EQRES 0xa +/* enum: CTLE gain (0-31, Medford2) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_GAIN 0xb +/* enum: CTLE pole (0-31, Medford2) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_POLE 0xc +/* enum: CTLE peaking (0-31, Medford2) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_PEAK 0xd +/* enum: DFE Tap1 - even path (Medford2 - 6 bit signed (-29 - +29)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_EVEN 0xe +/* enum: DFE Tap1 - odd path (Medford2 - 6 bit signed (-29 - +29)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_ODD 0xf +/* enum: DFE Tap2 (Medford2 - 6 bit signed (-20 - +20)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x10 +/* enum: DFE Tap3 (Medford2 - 6 bit signed (-20 - +20)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x11 +/* enum: DFE Tap4 (Medford2 - 6 bit signed (-20 - +20)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x12 +/* enum: DFE Tap5 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x13 +/* enum: DFE Tap6 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP6 0x14 +/* enum: DFE Tap7 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP7 0x15 +/* enum: DFE Tap8 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP8 0x16 +/* enum: DFE Tap9 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP9 0x17 +/* enum: DFE Tap10 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP10 0x18 +/* enum: DFE Tap11 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP11 0x19 +/* enum: DFE Tap12 (Medford2 - 6 bit signed (-24 - +24)) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP12 0x1a +/* enum: I/Q clk offset (Medford2 - 4 bit signed (-5 - +5))) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_IQ_OFF 0x1b +/* enum: Negative h1 polarity data sampler offset calibration code, even path + * (Medford2 - 6 bit signed (-29 - +29))) + */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1N_OFF_EVEN 0x1c +/* enum: Negative h1 polarity data sampler offset calibration code, odd path + * (Medford2 - 6 bit signed (-29 - +29))) + */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1N_OFF_ODD 0x1d +/* enum: Positive h1 polarity data sampler offset calibration code, even path + * (Medford2 - 6 bit signed (-29 - +29))) + */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1P_OFF_EVEN 0x1e +/* enum: Positive h1 polarity data sampler offset calibration code, odd path + * (Medford2 - 6 bit signed (-29 - +29))) + */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1P_OFF_ODD 0x1f +/* enum: CDR calibration loop code (Medford2) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_PVT 0x20 +/* enum: CDR integral loop code (Medford2) */ +#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_INTEG 0x21 #define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8 #define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 3 #define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */ @@ -10268,7 +12240,7 @@ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63 #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0 #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8 -/* enum: TX Amplitude (Huntington, Medford) */ +/* enum: TX Amplitude (Huntington, Medford, Medford2) */ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV 0x0 /* enum: De-Emphasis Tap1 Magnitude (0-7) (Huntington) */ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_MODE 0x1 @@ -10290,9 +12262,9 @@ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_RT_SET 0x9 /* enum: TX Amplitude Fine control (Medford) */ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV_FINE 0xa -/* enum: Pre-shoot Tap (Medford) */ +/* enum: Pre-shoot Tap (Medford, Medford2) */ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_ADV 0xb -/* enum: De-emphasis Tap (Medford) */ +/* enum: De-emphasis Tap (Medford, Medford2) */ #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_DLY 0xc #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8 #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3 @@ -10361,7 +12333,24 @@ /* Align the arguments to 32 bits */ #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1 #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3 +/* Port-relative lane to scan eye on */ #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LANE_OFST 4 +#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LANE_LEN 4 + +/* MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN msgrequest */ +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LEN 12 +/* Requested operation */ +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_OP_OFST 0 +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_OP_LEN 1 +/* Align the arguments to 32 bits */ +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_OFST 1 +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_LEN 3 +/* Port-relative lane to scan eye on */ +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_OFST 4 +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_LEN 4 +/* Scan duration / cycle count */ +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_BER_OFST 8 +#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_BER_LEN 4 /* MC_CMD_KR_TUNE_START_EYE_PLOT_OUT msgresponse */ #define MC_CMD_KR_TUNE_START_EYE_PLOT_OUT_LEN 0 @@ -10393,10 +12382,12 @@ #define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_OFST 1 #define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_LEN 3 #define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_OFST 4 +#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_LEN 4 /* MC_CMD_KR_TUNE_READ_FOM_OUT msgresponse */ #define MC_CMD_KR_TUNE_READ_FOM_OUT_LEN 4 #define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_OFST 0 +#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_LEN 4 /***********************************/ @@ -10594,6 +12585,7 @@ #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1 #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3 #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LANE_OFST 4 +#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LANE_LEN 4 /* MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT msgresponse */ #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT_LEN 0 @@ -10636,6 +12628,7 @@ #define MC_CMD_LICENSING_IN_LEN 4 /* identifies the type of operation requested */ #define MC_CMD_LICENSING_IN_OP_OFST 0 +#define MC_CMD_LICENSING_IN_OP_LEN 4 /* enum: re-read and apply licenses after a license key partition update; note * that this operation returns a zero-length response */ @@ -10647,23 +12640,30 @@ #define MC_CMD_LICENSING_OUT_LEN 28 /* count of application keys which are valid */ #define MC_CMD_LICENSING_OUT_VALID_APP_KEYS_OFST 0 +#define MC_CMD_LICENSING_OUT_VALID_APP_KEYS_LEN 4 /* sum of UNVERIFIABLE_APP_KEYS + WRONG_NODE_APP_KEYS (for compatibility with * MC_CMD_FC_OP_LICENSE) */ #define MC_CMD_LICENSING_OUT_INVALID_APP_KEYS_OFST 4 +#define MC_CMD_LICENSING_OUT_INVALID_APP_KEYS_LEN 4 /* count of application keys which are invalid due to being blacklisted */ #define MC_CMD_LICENSING_OUT_BLACKLISTED_APP_KEYS_OFST 8 +#define MC_CMD_LICENSING_OUT_BLACKLISTED_APP_KEYS_LEN 4 /* count of application keys which are invalid due to being unverifiable */ #define MC_CMD_LICENSING_OUT_UNVERIFIABLE_APP_KEYS_OFST 12 +#define MC_CMD_LICENSING_OUT_UNVERIFIABLE_APP_KEYS_LEN 4 /* count of application keys which are invalid due to being for the wrong node */ #define MC_CMD_LICENSING_OUT_WRONG_NODE_APP_KEYS_OFST 16 +#define MC_CMD_LICENSING_OUT_WRONG_NODE_APP_KEYS_LEN 4 /* licensing state (for diagnostics; the exact meaning of the bits in this * field are private to the firmware) */ #define MC_CMD_LICENSING_OUT_LICENSING_STATE_OFST 20 +#define MC_CMD_LICENSING_OUT_LICENSING_STATE_LEN 4 /* licensing subsystem self-test report (for manftest) */ #define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_OFST 24 +#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_LEN 4 /* enum: licensing subsystem self-test failed */ #define MC_CMD_LICENSING_OUT_SELF_TEST_FAIL 0x0 /* enum: licensing subsystem self-test passed */ @@ -10683,6 +12683,7 @@ #define MC_CMD_LICENSING_V3_IN_LEN 4 /* identifies the type of operation requested */ #define MC_CMD_LICENSING_V3_IN_OP_OFST 0 +#define MC_CMD_LICENSING_V3_IN_OP_LEN 4 /* enum: re-read and apply licenses after a license key partition update; note * that this operation returns a zero-length response */ @@ -10696,20 +12697,26 @@ #define MC_CMD_LICENSING_V3_OUT_LEN 88 /* count of keys which are valid */ #define MC_CMD_LICENSING_V3_OUT_VALID_KEYS_OFST 0 +#define MC_CMD_LICENSING_V3_OUT_VALID_KEYS_LEN 4 /* sum of UNVERIFIABLE_KEYS + WRONG_NODE_KEYS (for compatibility with * MC_CMD_FC_OP_LICENSE) */ #define MC_CMD_LICENSING_V3_OUT_INVALID_KEYS_OFST 4 +#define MC_CMD_LICENSING_V3_OUT_INVALID_KEYS_LEN 4 /* count of keys which are invalid due to being unverifiable */ #define MC_CMD_LICENSING_V3_OUT_UNVERIFIABLE_KEYS_OFST 8 +#define MC_CMD_LICENSING_V3_OUT_UNVERIFIABLE_KEYS_LEN 4 /* count of keys which are invalid due to being for the wrong node */ #define MC_CMD_LICENSING_V3_OUT_WRONG_NODE_KEYS_OFST 12 +#define MC_CMD_LICENSING_V3_OUT_WRONG_NODE_KEYS_LEN 4 /* licensing state (for diagnostics; the exact meaning of the bits in this * field are private to the firmware) */ #define MC_CMD_LICENSING_V3_OUT_LICENSING_STATE_OFST 16 +#define MC_CMD_LICENSING_V3_OUT_LICENSING_STATE_LEN 4 /* licensing subsystem self-test report (for manftest) */ #define MC_CMD_LICENSING_V3_OUT_LICENSING_SELF_TEST_OFST 20 +#define MC_CMD_LICENSING_V3_OUT_LICENSING_SELF_TEST_LEN 4 /* enum: licensing subsystem self-test failed */ #define MC_CMD_LICENSING_V3_OUT_SELF_TEST_FAIL 0x0 /* enum: licensing subsystem self-test passed */ @@ -10750,8 +12757,10 @@ #define MC_CMD_LICENSING_GET_ID_V3_OUT_LEN(num) (8+1*(num)) /* type of license (eg 3) */ #define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_TYPE_OFST 0 +#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_TYPE_LEN 4 /* length of the license ID (in bytes) */ #define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH_OFST 4 +#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH_LEN 4 /* the unique license ID of the adapter */ #define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST 8 #define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_LEN 1 @@ -10789,11 +12798,13 @@ #define MC_CMD_GET_LICENSED_APP_STATE_IN_LEN 4 /* application ID to query (LICENSED_APP_ID_xxx) */ #define MC_CMD_GET_LICENSED_APP_STATE_IN_APP_ID_OFST 0 +#define MC_CMD_GET_LICENSED_APP_STATE_IN_APP_ID_LEN 4 /* MC_CMD_GET_LICENSED_APP_STATE_OUT msgresponse */ #define MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN 4 /* state of this application */ #define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_OFST 0 +#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_LEN 4 /* enum: no (or invalid) license is present for the application */ #define MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED 0x0 /* enum: a valid license is present for the application */ @@ -10824,6 +12835,7 @@ #define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN 4 /* state of this application */ #define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_STATE_OFST 0 +#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_STATE_LEN 4 /* enum: no (or invalid) license is present for the application */ #define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED 0x0 /* enum: a valid license is present for the application */ @@ -10874,8 +12886,10 @@ #define MC_CMD_LICENSED_APP_OP_IN_LEN(num) (8+4*(num)) /* application ID */ #define MC_CMD_LICENSED_APP_OP_IN_APP_ID_OFST 0 +#define MC_CMD_LICENSED_APP_OP_IN_APP_ID_LEN 4 /* the type of operation requested */ #define MC_CMD_LICENSED_APP_OP_IN_OP_OFST 4 +#define MC_CMD_LICENSED_APP_OP_IN_OP_LEN 4 /* enum: validate application */ #define MC_CMD_LICENSED_APP_OP_IN_OP_VALIDATE 0x0 /* enum: mask application */ @@ -10900,8 +12914,10 @@ #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_LEN 72 /* application ID */ #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_APP_ID_OFST 0 +#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_APP_ID_LEN 4 /* the type of operation requested */ #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_OP_OFST 4 +#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_OP_LEN 4 /* validation challenge */ #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_OFST 8 #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_LEN 64 @@ -10910,6 +12926,7 @@ #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_LEN 68 /* feature expiry (time_t) */ #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_EXPIRY_OFST 0 +#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_EXPIRY_LEN 4 /* validation response */ #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_OFST 4 #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_LEN 64 @@ -10918,10 +12935,13 @@ #define MC_CMD_LICENSED_APP_OP_MASK_IN_LEN 12 /* application ID */ #define MC_CMD_LICENSED_APP_OP_MASK_IN_APP_ID_OFST 0 +#define MC_CMD_LICENSED_APP_OP_MASK_IN_APP_ID_LEN 4 /* the type of operation requested */ #define MC_CMD_LICENSED_APP_OP_MASK_IN_OP_OFST 4 +#define MC_CMD_LICENSED_APP_OP_MASK_IN_OP_LEN 4 /* flag */ #define MC_CMD_LICENSED_APP_OP_MASK_IN_FLAG_OFST 8 +#define MC_CMD_LICENSED_APP_OP_MASK_IN_FLAG_LEN 4 /* MC_CMD_LICENSED_APP_OP_MASK_OUT msgresponse */ #define MC_CMD_LICENSED_APP_OP_MASK_OUT_LEN 0 @@ -10959,8 +12979,10 @@ #define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_RESPONSE_LEN 96 /* application expiry time */ #define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_TIME_OFST 96 +#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_TIME_LEN 4 /* application expiry units */ #define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNITS_OFST 100 +#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNITS_LEN 4 /* enum: expiry units are accounting units */ #define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNIT_ACC 0x0 /* enum: expiry units are calendar days */ @@ -10984,7 +13006,7 @@ */ #define MC_CMD_LICENSED_V3_MASK_FEATURES 0xd5 -#define MC_CMD_0xd5_PRIVILEGE_CTG SRIOV_CTG_GENERAL +#define MC_CMD_0xd5_PRIVILEGE_CTG SRIOV_CTG_ADMIN /* MC_CMD_LICENSED_V3_MASK_FEATURES_IN msgrequest */ #define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_LEN 12 @@ -10995,6 +13017,7 @@ #define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_MASK_HI_OFST 4 /* whether to turn on or turn off the masked features */ #define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_FLAG_OFST 8 +#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_FLAG_LEN 4 /* enum: turn the features off */ #define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_OFF 0x0 /* enum: turn the features back on */ @@ -11014,12 +13037,13 @@ */ #define MC_CMD_LICENSING_V3_TEMPORARY 0xd6 -#define MC_CMD_0xd6_PRIVILEGE_CTG SRIOV_CTG_GENERAL +#define MC_CMD_0xd6_PRIVILEGE_CTG SRIOV_CTG_ADMIN /* MC_CMD_LICENSING_V3_TEMPORARY_IN msgrequest */ #define MC_CMD_LICENSING_V3_TEMPORARY_IN_LEN 4 /* operation code */ #define MC_CMD_LICENSING_V3_TEMPORARY_IN_OP_OFST 0 +#define MC_CMD_LICENSING_V3_TEMPORARY_IN_OP_LEN 4 /* enum: install a new license, overwriting any existing temporary license. * This is an asynchronous operation owing to the time taken to validate an * ECDSA license @@ -11037,6 +13061,7 @@ /* MC_CMD_LICENSING_V3_TEMPORARY_IN_SET msgrequest */ #define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_LEN 164 #define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_OP_OFST 0 +#define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_OP_LEN 4 /* ECDSA license and signature */ #define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_LICENSE_OFST 4 #define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_LICENSE_LEN 160 @@ -11044,15 +13069,18 @@ /* MC_CMD_LICENSING_V3_TEMPORARY_IN_CLEAR msgrequest */ #define MC_CMD_LICENSING_V3_TEMPORARY_IN_CLEAR_LEN 4 #define MC_CMD_LICENSING_V3_TEMPORARY_IN_CLEAR_OP_OFST 0 +#define MC_CMD_LICENSING_V3_TEMPORARY_IN_CLEAR_OP_LEN 4 /* MC_CMD_LICENSING_V3_TEMPORARY_IN_STATUS msgrequest */ #define MC_CMD_LICENSING_V3_TEMPORARY_IN_STATUS_LEN 4 #define MC_CMD_LICENSING_V3_TEMPORARY_IN_STATUS_OP_OFST 0 +#define MC_CMD_LICENSING_V3_TEMPORARY_IN_STATUS_OP_LEN 4 /* MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS msgresponse */ #define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_LEN 12 /* status code */ #define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_STATUS_OFST 0 +#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_STATUS_LEN 4 /* enum: finished validating and installing license */ #define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_OK 0x0 /* enum: license validation and installation in progress */ @@ -11084,14 +13112,17 @@ #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_LEN 16 /* configuration flags */ #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0 +#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_LEN 4 #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0 #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1 #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_LBN 1 #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_WIDTH 1 /* receive queue handle (for RSS mode, this is the base queue) */ #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4 +#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_QUEUE_LEN 4 /* receive mode */ #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8 +#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_LEN 4 /* enum: receive to just the specified queue */ #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0 /* enum: receive to multiple queues using RSS context */ @@ -11101,6 +13132,7 @@ * of 0xFFFFFFFF is guaranteed never to be a valid handle. */ #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12 +#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_LEN 4 /* MC_CMD_SET_PORT_SNIFF_CONFIG_OUT msgresponse */ #define MC_CMD_SET_PORT_SNIFF_CONFIG_OUT_LEN 0 @@ -11123,20 +13155,24 @@ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_LEN 16 /* configuration flags */ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_LEN 4 #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0 #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1 #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_LBN 1 #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_WIDTH 1 /* receiving queue handle (for RSS mode, this is the base queue) */ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4 +#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_LEN 4 /* receive mode */ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8 +#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_LEN 4 /* enum: receiving to just the specified queue */ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0 /* enum: receiving to multiple queues using RSS context */ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1 /* RSS context (for RX_MODE_RSS) */ #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12 +#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_LEN 4 /***********************************/ @@ -11153,6 +13189,7 @@ #define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LEN(num) (8+4*(num)) /* the type of configuration setting to change */ #define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0 +#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TYPE_LEN 4 /* enum: Per-TXQ enable for multicast UDP destination lookup for possible * internal loopback. (ENTITY is a queue handle, VALUE is a single boolean.) */ @@ -11166,6 +13203,7 @@ * on the type of configuration setting being changed */ #define MC_CMD_SET_PARSER_DISP_CONFIG_IN_ENTITY_OFST 4 +#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_ENTITY_LEN 4 /* new value: the details depend on the type of configuration setting being * changed */ @@ -11190,12 +13228,14 @@ #define MC_CMD_GET_PARSER_DISP_CONFIG_IN_LEN 8 /* the type of configuration setting to read */ #define MC_CMD_GET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0 +#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_SET_PARSER_DISP_CONFIG/MC_CMD_SET_PARSER_DISP_CONFIG_IN/TYPE */ /* handle for the entity to query: queue handle, EVB port ID, etc. depending on * the type of configuration setting being read */ #define MC_CMD_GET_PARSER_DISP_CONFIG_IN_ENTITY_OFST 4 +#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_ENTITY_LEN 4 /* MC_CMD_GET_PARSER_DISP_CONFIG_OUT msgresponse */ #define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMIN 4 @@ -11228,12 +13268,15 @@ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_LEN 16 /* configuration flags */ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0 +#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_FLAGS_LEN 4 #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0 #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1 /* receive queue handle (for RSS mode, this is the base queue) */ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4 +#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_QUEUE_LEN 4 /* receive mode */ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8 +#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_LEN 4 /* enum: receive to just the specified queue */ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0 /* enum: receive to multiple queues using RSS context */ @@ -11243,6 +13286,7 @@ * of 0xFFFFFFFF is guaranteed never to be a valid handle. */ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12 +#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_LEN 4 /* MC_CMD_SET_TX_PORT_SNIFF_CONFIG_OUT msgresponse */ #define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_OUT_LEN 0 @@ -11265,18 +13309,22 @@ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_LEN 16 /* configuration flags */ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_FLAGS_LEN 4 #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0 #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1 /* receiving queue handle (for RSS mode, this is the base queue) */ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4 +#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_LEN 4 /* receive mode */ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8 +#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_LEN 4 /* enum: receiving to just the specified queue */ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0 /* enum: receiving to multiple queues using RSS context */ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1 /* RSS context (for RX_MODE_RSS) */ #define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12 +#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_LEN 4 /***********************************/ @@ -11291,16 +13339,22 @@ #define MC_CMD_RMON_STATS_RX_ERRORS_IN_LEN 8 /* The rx queue to get stats for. */ #define MC_CMD_RMON_STATS_RX_ERRORS_IN_RX_QUEUE_OFST 0 +#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RX_QUEUE_LEN 4 #define MC_CMD_RMON_STATS_RX_ERRORS_IN_FLAGS_OFST 4 +#define MC_CMD_RMON_STATS_RX_ERRORS_IN_FLAGS_LEN 4 #define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_LBN 0 #define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_WIDTH 1 /* MC_CMD_RMON_STATS_RX_ERRORS_OUT msgresponse */ #define MC_CMD_RMON_STATS_RX_ERRORS_OUT_LEN 16 #define MC_CMD_RMON_STATS_RX_ERRORS_OUT_CRC_ERRORS_OFST 0 +#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_CRC_ERRORS_LEN 4 #define MC_CMD_RMON_STATS_RX_ERRORS_OUT_TRUNC_ERRORS_OFST 4 +#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_TRUNC_ERRORS_LEN 4 #define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_NO_DESC_DROPS_OFST 8 +#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_NO_DESC_DROPS_LEN 4 #define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_ABORT_OFST 12 +#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_ABORT_LEN 4 /***********************************/ @@ -11309,6 +13363,8 @@ */ #define MC_CMD_GET_PCIE_RESOURCE_INFO 0xfd +#define MC_CMD_0xfd_PRIVILEGE_CTG SRIOV_CTG_GENERAL + /* MC_CMD_GET_PCIE_RESOURCE_INFO_IN msgrequest */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_IN_LEN 0 @@ -11316,20 +13372,27 @@ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_LEN 28 /* The maximum number of PFs the device can expose */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PFS_OFST 0 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PFS_LEN 4 /* The maximum number of VFs the device can expose in total */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VFS_OFST 4 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VFS_LEN 4 /* The maximum number of MSI-X vectors the device can provide in total */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VECTORS_OFST 8 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VECTORS_LEN 4 /* the number of MSI-X vectors the device will allocate by default to each PF */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_PF_VECTORS_OFST 12 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_PF_VECTORS_LEN 4 /* the number of MSI-X vectors the device will allocate by default to each VF */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_VF_VECTORS_OFST 16 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_VF_VECTORS_LEN 4 /* the maximum number of MSI-X vectors the device can allocate to any one PF */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PF_VECTORS_OFST 20 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PF_VECTORS_LEN 4 /* the maximum number of MSI-X vectors the device can allocate to any one VF */ #define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VF_VECTORS_OFST 24 +#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VF_VECTORS_LEN 4 /***********************************/ @@ -11347,10 +13410,13 @@ #define MC_CMD_GET_PORT_MODES_OUT_LEN 12 /* Bitmask of port modes available on the board (indexed by TLV_PORT_MODE_*) */ #define MC_CMD_GET_PORT_MODES_OUT_MODES_OFST 0 +#define MC_CMD_GET_PORT_MODES_OUT_MODES_LEN 4 /* Default (canonical) board mode */ #define MC_CMD_GET_PORT_MODES_OUT_DEFAULT_MODE_OFST 4 +#define MC_CMD_GET_PORT_MODES_OUT_DEFAULT_MODE_LEN 4 /* Current board mode */ #define MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST 8 +#define MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_LEN 4 /***********************************/ @@ -11359,21 +13425,26 @@ */ #define MC_CMD_READ_ATB 0x100 -#define MC_CMD_0x100_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x100_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_READ_ATB_IN msgrequest */ #define MC_CMD_READ_ATB_IN_LEN 16 #define MC_CMD_READ_ATB_IN_SIGNAL_BUS_OFST 0 +#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_LEN 4 #define MC_CMD_READ_ATB_IN_BUS_CCOM 0x0 /* enum */ #define MC_CMD_READ_ATB_IN_BUS_CKR 0x1 /* enum */ #define MC_CMD_READ_ATB_IN_BUS_CPCIE 0x8 /* enum */ #define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_OFST 4 +#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_LEN 4 #define MC_CMD_READ_ATB_IN_SIGNAL_SEL_OFST 8 +#define MC_CMD_READ_ATB_IN_SIGNAL_SEL_LEN 4 #define MC_CMD_READ_ATB_IN_SETTLING_TIME_US_OFST 12 +#define MC_CMD_READ_ATB_IN_SETTLING_TIME_US_LEN 4 /* MC_CMD_READ_ATB_OUT msgresponse */ #define MC_CMD_READ_ATB_OUT_LEN 4 #define MC_CMD_READ_ATB_OUT_SAMPLE_MV_OFST 0 +#define MC_CMD_READ_ATB_OUT_SAMPLE_MV_LEN 4 /***********************************/ @@ -11390,7 +13461,9 @@ /* Each workaround is represented by a single bit according to the enums below. */ #define MC_CMD_GET_WORKAROUNDS_OUT_IMPLEMENTED_OFST 0 +#define MC_CMD_GET_WORKAROUNDS_OUT_IMPLEMENTED_LEN 4 #define MC_CMD_GET_WORKAROUNDS_OUT_ENABLED_OFST 4 +#define MC_CMD_GET_WORKAROUNDS_OUT_ENABLED_LEN 4 /* enum: Bug 17230 work around. */ #define MC_CMD_GET_WORKAROUNDS_OUT_BUG17230 0x2 /* enum: Bug 35388 work around (unsafe EVQ writes). */ @@ -11425,6 +13498,7 @@ * 1,3 = 0x00030001 */ #define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_OFST 0 +#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_LEN 4 #define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_LBN 0 #define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_WIDTH 16 #define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_LBN 16 @@ -11434,6 +13508,7 @@ * set to 1. */ #define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_OFST 4 +#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_LEN 4 #define MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN 0x1 /* enum */ #define MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK 0x2 /* enum */ #define MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD 0x4 /* enum */ @@ -11460,6 +13535,10 @@ * only a set of permitted VLANs. See the vPort flag FLAG_VLAN_RESTRICT. */ #define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNRESTRICTED_VLAN 0x2000 +/* enum: Privilege for insecure commands. Commands that belong to this group + * are not permitted on secure adapters regardless of the privilege mask. + */ +#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE 0x4000 /* enum: Set this bit to indicate that a new privilege mask is to be set, * otherwise the command will only read the existing mask. */ @@ -11469,6 +13548,7 @@ #define MC_CMD_PRIVILEGE_MASK_OUT_LEN 4 /* For an admin function, always all the privileges are reported. */ #define MC_CMD_PRIVILEGE_MASK_OUT_OLD_MASK_OFST 0 +#define MC_CMD_PRIVILEGE_MASK_OUT_OLD_MASK_LEN 4 /***********************************/ @@ -11485,12 +13565,14 @@ * e.g. VF 1,3 = 0x00030001 */ #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_OFST 0 +#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_LEN 4 #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_LBN 0 #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_WIDTH 16 #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_LBN 16 #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_WIDTH 16 /* New link state mode to be set */ #define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4 +#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_LEN 4 #define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */ #define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */ #define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */ @@ -11501,11 +13583,12 @@ /* MC_CMD_LINK_STATE_MODE_OUT msgresponse */ #define MC_CMD_LINK_STATE_MODE_OUT_LEN 4 #define MC_CMD_LINK_STATE_MODE_OUT_OLD_MODE_OFST 0 +#define MC_CMD_LINK_STATE_MODE_OUT_OLD_MODE_LEN 4 /***********************************/ /* MC_CMD_GET_SNAPSHOT_LENGTH - * Obtain the curent range of allowable values for the SNAPSHOT_LENGTH + * Obtain the current range of allowable values for the SNAPSHOT_LENGTH * parameter to MC_CMD_INIT_RXQ. */ #define MC_CMD_GET_SNAPSHOT_LENGTH 0x101 @@ -11519,8 +13602,10 @@ #define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_LEN 8 /* Minimum acceptable snapshot length. */ #define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MIN_OFST 0 +#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MIN_LEN 4 /* Maximum acceptable snapshot length. */ #define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MAX_OFST 4 +#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MAX_LEN 4 /***********************************/ @@ -11529,7 +13614,7 @@ */ #define MC_CMD_FUSE_DIAGS 0x102 -#define MC_CMD_0x102_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x102_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_FUSE_DIAGS_IN msgrequest */ #define MC_CMD_FUSE_DIAGS_IN_LEN 0 @@ -11538,28 +13623,40 @@ #define MC_CMD_FUSE_DIAGS_OUT_LEN 48 /* Total number of mismatched bits between pairs in area 0 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA0_MISMATCH_BITS_OFST 0 +#define MC_CMD_FUSE_DIAGS_OUT_AREA0_MISMATCH_BITS_LEN 4 /* Total number of unexpectedly clear (set in B but not A) bits in area 0 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_A_BAD_BITS_OFST 4 +#define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_A_BAD_BITS_LEN 4 /* Total number of unexpectedly clear (set in A but not B) bits in area 0 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_B_BAD_BITS_OFST 8 +#define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_B_BAD_BITS_LEN 4 /* Checksum of data after logical OR of pairs in area 0 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA0_CHECKSUM_OFST 12 +#define MC_CMD_FUSE_DIAGS_OUT_AREA0_CHECKSUM_LEN 4 /* Total number of mismatched bits between pairs in area 1 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA1_MISMATCH_BITS_OFST 16 +#define MC_CMD_FUSE_DIAGS_OUT_AREA1_MISMATCH_BITS_LEN 4 /* Total number of unexpectedly clear (set in B but not A) bits in area 1 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_A_BAD_BITS_OFST 20 +#define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_A_BAD_BITS_LEN 4 /* Total number of unexpectedly clear (set in A but not B) bits in area 1 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_B_BAD_BITS_OFST 24 +#define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_B_BAD_BITS_LEN 4 /* Checksum of data after logical OR of pairs in area 1 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA1_CHECKSUM_OFST 28 +#define MC_CMD_FUSE_DIAGS_OUT_AREA1_CHECKSUM_LEN 4 /* Total number of mismatched bits between pairs in area 2 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA2_MISMATCH_BITS_OFST 32 +#define MC_CMD_FUSE_DIAGS_OUT_AREA2_MISMATCH_BITS_LEN 4 /* Total number of unexpectedly clear (set in B but not A) bits in area 2 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_A_BAD_BITS_OFST 36 +#define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_A_BAD_BITS_LEN 4 /* Total number of unexpectedly clear (set in A but not B) bits in area 2 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_B_BAD_BITS_OFST 40 +#define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_B_BAD_BITS_LEN 4 /* Checksum of data after logical OR of pairs in area 2 */ #define MC_CMD_FUSE_DIAGS_OUT_AREA2_CHECKSUM_OFST 44 +#define MC_CMD_FUSE_DIAGS_OUT_AREA2_CHECKSUM_LEN 4 /***********************************/ @@ -11576,6 +13673,7 @@ #define MC_CMD_PRIVILEGE_MODIFY_IN_LEN 16 /* The groups of functions to have their privilege masks modified. */ #define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_OFST 0 +#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_LEN 4 #define MC_CMD_PRIVILEGE_MODIFY_IN_NONE 0x0 /* enum */ #define MC_CMD_PRIVILEGE_MODIFY_IN_ALL 0x1 /* enum */ #define MC_CMD_PRIVILEGE_MODIFY_IN_PFS_ONLY 0x2 /* enum */ @@ -11584,6 +13682,7 @@ #define MC_CMD_PRIVILEGE_MODIFY_IN_ONE 0x5 /* enum */ /* For VFS_OF_PF specify the PF, for ONE specify the target function */ #define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_OFST 4 +#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_LEN 4 #define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_LBN 0 #define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_WIDTH 16 #define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_LBN 16 @@ -11592,10 +13691,12 @@ * refer to the command MC_CMD_PRIVILEGE_MASK */ #define MC_CMD_PRIVILEGE_MODIFY_IN_ADD_MASK_OFST 8 +#define MC_CMD_PRIVILEGE_MODIFY_IN_ADD_MASK_LEN 4 /* Privileges to be removed from the target functions. For privilege * definitions refer to the command MC_CMD_PRIVILEGE_MASK */ #define MC_CMD_PRIVILEGE_MODIFY_IN_REMOVE_MASK_OFST 12 +#define MC_CMD_PRIVILEGE_MODIFY_IN_REMOVE_MASK_LEN 4 /* MC_CMD_PRIVILEGE_MODIFY_OUT msgresponse */ #define MC_CMD_PRIVILEGE_MODIFY_OUT_LEN 0 @@ -11613,8 +13714,10 @@ #define MC_CMD_XPM_READ_BYTES_IN_LEN 8 /* Start address (byte) */ #define MC_CMD_XPM_READ_BYTES_IN_ADDR_OFST 0 +#define MC_CMD_XPM_READ_BYTES_IN_ADDR_LEN 4 /* Count (bytes) */ #define MC_CMD_XPM_READ_BYTES_IN_COUNT_OFST 4 +#define MC_CMD_XPM_READ_BYTES_IN_COUNT_LEN 4 /* MC_CMD_XPM_READ_BYTES_OUT msgresponse */ #define MC_CMD_XPM_READ_BYTES_OUT_LENMIN 0 @@ -11633,7 +13736,7 @@ */ #define MC_CMD_XPM_WRITE_BYTES 0x104 -#define MC_CMD_0x104_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x104_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_WRITE_BYTES_IN msgrequest */ #define MC_CMD_XPM_WRITE_BYTES_IN_LENMIN 8 @@ -11641,8 +13744,10 @@ #define MC_CMD_XPM_WRITE_BYTES_IN_LEN(num) (8+1*(num)) /* Start address (byte) */ #define MC_CMD_XPM_WRITE_BYTES_IN_ADDR_OFST 0 +#define MC_CMD_XPM_WRITE_BYTES_IN_ADDR_LEN 4 /* Count (bytes) */ #define MC_CMD_XPM_WRITE_BYTES_IN_COUNT_OFST 4 +#define MC_CMD_XPM_WRITE_BYTES_IN_COUNT_LEN 4 /* Data */ #define MC_CMD_XPM_WRITE_BYTES_IN_DATA_OFST 8 #define MC_CMD_XPM_WRITE_BYTES_IN_DATA_LEN 1 @@ -11659,14 +13764,16 @@ */ #define MC_CMD_XPM_READ_SECTOR 0x105 -#define MC_CMD_0x105_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x105_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_READ_SECTOR_IN msgrequest */ #define MC_CMD_XPM_READ_SECTOR_IN_LEN 8 /* Sector index */ #define MC_CMD_XPM_READ_SECTOR_IN_INDEX_OFST 0 +#define MC_CMD_XPM_READ_SECTOR_IN_INDEX_LEN 4 /* Sector size */ #define MC_CMD_XPM_READ_SECTOR_IN_SIZE_OFST 4 +#define MC_CMD_XPM_READ_SECTOR_IN_SIZE_LEN 4 /* MC_CMD_XPM_READ_SECTOR_OUT msgresponse */ #define MC_CMD_XPM_READ_SECTOR_OUT_LENMIN 4 @@ -11674,9 +13781,11 @@ #define MC_CMD_XPM_READ_SECTOR_OUT_LEN(num) (4+1*(num)) /* Sector type */ #define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_OFST 0 +#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_LEN 4 #define MC_CMD_XPM_READ_SECTOR_OUT_BLANK 0x0 /* enum */ #define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_128 0x1 /* enum */ #define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_256 0x2 /* enum */ +#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_DATA 0x3 /* enum */ #define MC_CMD_XPM_READ_SECTOR_OUT_INVALID 0xff /* enum */ /* Sector data */ #define MC_CMD_XPM_READ_SECTOR_OUT_DATA_OFST 4 @@ -11691,7 +13800,7 @@ */ #define MC_CMD_XPM_WRITE_SECTOR 0x106 -#define MC_CMD_0x106_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x106_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_WRITE_SECTOR_IN msgrequest */ #define MC_CMD_XPM_WRITE_SECTOR_IN_LENMIN 12 @@ -11708,10 +13817,12 @@ #define MC_CMD_XPM_WRITE_SECTOR_IN_RESERVED_LEN 3 /* Sector type */ #define MC_CMD_XPM_WRITE_SECTOR_IN_TYPE_OFST 4 +#define MC_CMD_XPM_WRITE_SECTOR_IN_TYPE_LEN 4 /* Enum values, see field(s): */ /* MC_CMD_XPM_READ_SECTOR/MC_CMD_XPM_READ_SECTOR_OUT/TYPE */ /* Sector size */ #define MC_CMD_XPM_WRITE_SECTOR_IN_SIZE_OFST 8 +#define MC_CMD_XPM_WRITE_SECTOR_IN_SIZE_LEN 4 /* Sector data */ #define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_OFST 12 #define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_LEN 1 @@ -11722,6 +13833,7 @@ #define MC_CMD_XPM_WRITE_SECTOR_OUT_LEN 4 /* New sector index */ #define MC_CMD_XPM_WRITE_SECTOR_OUT_INDEX_OFST 0 +#define MC_CMD_XPM_WRITE_SECTOR_OUT_INDEX_LEN 4 /***********************************/ @@ -11730,12 +13842,13 @@ */ #define MC_CMD_XPM_INVALIDATE_SECTOR 0x107 -#define MC_CMD_0x107_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x107_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_INVALIDATE_SECTOR_IN msgrequest */ #define MC_CMD_XPM_INVALIDATE_SECTOR_IN_LEN 4 /* Sector index */ #define MC_CMD_XPM_INVALIDATE_SECTOR_IN_INDEX_OFST 0 +#define MC_CMD_XPM_INVALIDATE_SECTOR_IN_INDEX_LEN 4 /* MC_CMD_XPM_INVALIDATE_SECTOR_OUT msgresponse */ #define MC_CMD_XPM_INVALIDATE_SECTOR_OUT_LEN 0 @@ -11747,14 +13860,16 @@ */ #define MC_CMD_XPM_BLANK_CHECK 0x108 -#define MC_CMD_0x108_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x108_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_BLANK_CHECK_IN msgrequest */ #define MC_CMD_XPM_BLANK_CHECK_IN_LEN 8 /* Start address (byte) */ #define MC_CMD_XPM_BLANK_CHECK_IN_ADDR_OFST 0 +#define MC_CMD_XPM_BLANK_CHECK_IN_ADDR_LEN 4 /* Count (bytes) */ #define MC_CMD_XPM_BLANK_CHECK_IN_COUNT_OFST 4 +#define MC_CMD_XPM_BLANK_CHECK_IN_COUNT_LEN 4 /* MC_CMD_XPM_BLANK_CHECK_OUT msgresponse */ #define MC_CMD_XPM_BLANK_CHECK_OUT_LENMIN 4 @@ -11762,6 +13877,7 @@ #define MC_CMD_XPM_BLANK_CHECK_OUT_LEN(num) (4+2*(num)) /* Total number of bad (non-blank) locations */ #define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_COUNT_OFST 0 +#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_COUNT_LEN 4 /* Addresses of bad locations (may be less than BAD_COUNT, if all cannot fit * into MCDI response) */ @@ -11777,14 +13893,16 @@ */ #define MC_CMD_XPM_REPAIR 0x109 -#define MC_CMD_0x109_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x109_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_REPAIR_IN msgrequest */ #define MC_CMD_XPM_REPAIR_IN_LEN 8 /* Start address (byte) */ #define MC_CMD_XPM_REPAIR_IN_ADDR_OFST 0 +#define MC_CMD_XPM_REPAIR_IN_ADDR_LEN 4 /* Count (bytes) */ #define MC_CMD_XPM_REPAIR_IN_COUNT_OFST 4 +#define MC_CMD_XPM_REPAIR_IN_COUNT_LEN 4 /* MC_CMD_XPM_REPAIR_OUT msgresponse */ #define MC_CMD_XPM_REPAIR_OUT_LEN 0 @@ -11797,7 +13915,7 @@ */ #define MC_CMD_XPM_DECODER_TEST 0x10a -#define MC_CMD_0x10a_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x10a_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_DECODER_TEST_IN msgrequest */ #define MC_CMD_XPM_DECODER_TEST_IN_LEN 0 @@ -11816,7 +13934,7 @@ */ #define MC_CMD_XPM_WRITE_TEST 0x10b -#define MC_CMD_0x10b_PRIVILEGE_CTG SRIOV_CTG_ADMIN +#define MC_CMD_0x10b_PRIVILEGE_CTG SRIOV_CTG_INSECURE /* MC_CMD_XPM_WRITE_TEST_IN msgrequest */ #define MC_CMD_XPM_WRITE_TEST_IN_LEN 0 @@ -11842,10 +13960,13 @@ #define MC_CMD_EXEC_SIGNED_IN_LEN 28 /* the length of code to include in the CMAC */ #define MC_CMD_EXEC_SIGNED_IN_CODELEN_OFST 0 +#define MC_CMD_EXEC_SIGNED_IN_CODELEN_LEN 4 /* the length of date to include in the CMAC */ #define MC_CMD_EXEC_SIGNED_IN_DATALEN_OFST 4 +#define MC_CMD_EXEC_SIGNED_IN_DATALEN_LEN 4 /* the XPM sector containing the key to use */ #define MC_CMD_EXEC_SIGNED_IN_KEYSECTOR_OFST 8 +#define MC_CMD_EXEC_SIGNED_IN_KEYSECTOR_LEN 4 /* the expected CMAC value */ #define MC_CMD_EXEC_SIGNED_IN_CMAC_OFST 12 #define MC_CMD_EXEC_SIGNED_IN_CMAC_LEN 16 @@ -11868,11 +13989,34 @@ #define MC_CMD_PREPARE_SIGNED_IN_LEN 4 /* the length of data area to clear */ #define MC_CMD_PREPARE_SIGNED_IN_DATALEN_OFST 0 +#define MC_CMD_PREPARE_SIGNED_IN_DATALEN_LEN 4 /* MC_CMD_PREPARE_SIGNED_OUT msgresponse */ #define MC_CMD_PREPARE_SIGNED_OUT_LEN 0 +/* TUNNEL_ENCAP_UDP_PORT_ENTRY structuredef */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_LEN 4 +/* UDP port (the standard ports are named below but any port may be used) */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_OFST 0 +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LEN 2 +/* enum: the IANA allocated UDP port for VXLAN */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_VXLAN_UDP_PORT 0x12b5 +/* enum: the IANA allocated UDP port for Geneve */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_GENEVE_UDP_PORT 0x17c1 +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LBN 0 +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_WIDTH 16 +/* tunnel encapsulation protocol (only those named below are supported) */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_OFST 2 +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LEN 2 +/* enum: This port will be used for VXLAN on both IPv4 and IPv6 */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN 0x0 +/* enum: This port will be used for Geneve on both IPv4 and IPv6 */ +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE 0x1 +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LBN 16 +#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_WIDTH 16 + + /***********************************/ /* MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS * Configure UDP ports for tunnel encapsulation hardware acceleration. The @@ -11913,27 +14057,6 @@ #define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN 0 #define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_WIDTH 1 -/* TUNNEL_ENCAP_UDP_PORT_ENTRY structuredef */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_LEN 4 -/* UDP port (the standard ports are named below but any port may be used) */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_OFST 0 -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LEN 2 -/* enum: the IANA allocated UDP port for VXLAN */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_VXLAN_UDP_PORT 0x12b5 -/* enum: the IANA allocated UDP port for Geneve */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_GENEVE_UDP_PORT 0x17c1 -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LBN 0 -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_WIDTH 16 -/* tunnel encapsulation protocol (only those named below are supported) */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_OFST 2 -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LEN 2 -/* enum: VXLAN */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN 0x0 -/* enum: Geneve */ -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE 0x1 -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LBN 16 -#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_WIDTH 16 - /***********************************/ /* MC_CMD_RX_BALANCING @@ -11950,12 +14073,16 @@ #define MC_CMD_RX_BALANCING_IN_LEN 16 /* The RX port whose upconverter table will be modified */ #define MC_CMD_RX_BALANCING_IN_PORT_OFST 0 +#define MC_CMD_RX_BALANCING_IN_PORT_LEN 4 /* The VLAN priority associated to the table index and vFIFO */ #define MC_CMD_RX_BALANCING_IN_PRIORITY_OFST 4 +#define MC_CMD_RX_BALANCING_IN_PRIORITY_LEN 4 /* The resulting bit of SRC^DST for indexing the table */ #define MC_CMD_RX_BALANCING_IN_SRC_DST_OFST 8 +#define MC_CMD_RX_BALANCING_IN_SRC_DST_LEN 4 /* The RX engine to which the vFIFO in the table entry will point to */ #define MC_CMD_RX_BALANCING_IN_ENG_OFST 12 +#define MC_CMD_RX_BALANCING_IN_ENG_LEN 4 /* MC_CMD_RX_BALANCING_OUT msgresponse */ #define MC_CMD_RX_BALANCING_OUT_LEN 0 @@ -11976,8 +14103,10 @@ #define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LEN(num) (8+1*(num)) /* The tag to be appended */ #define MC_CMD_NVRAM_PRIVATE_APPEND_IN_TAG_OFST 0 +#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_TAG_LEN 4 /* The length of the data */ #define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LENGTH_OFST 4 +#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LENGTH_LEN 4 /* The data to be contained in the TLV structure */ #define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_OFST 8 #define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_LEN 1 @@ -12002,6 +14131,7 @@ #define MC_CMD_XPM_VERIFY_CONTENTS_IN_LEN 4 /* Data type to be checked */ #define MC_CMD_XPM_VERIFY_CONTENTS_IN_DATA_TYPE_OFST 0 +#define MC_CMD_XPM_VERIFY_CONTENTS_IN_DATA_TYPE_LEN 4 /* MC_CMD_XPM_VERIFY_CONTENTS_OUT msgresponse */ #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_LENMIN 12 @@ -12009,10 +14139,13 @@ #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_LEN(num) (12+1*(num)) /* Number of sectors found (test builds only) */ #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_NUM_SECTORS_OFST 0 +#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_NUM_SECTORS_LEN 4 /* Number of bytes found (test builds only) */ #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_NUM_BYTES_OFST 4 +#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_NUM_BYTES_LEN 4 /* Length of signature */ #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIG_LENGTH_OFST 8 +#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIG_LENGTH_LEN 4 /* Signature */ #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_OFST 12 #define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_LEN 1 @@ -12037,12 +14170,16 @@ #define MC_CMD_SET_EVQ_TMR_IN_LEN 16 /* Function-relative queue instance */ #define MC_CMD_SET_EVQ_TMR_IN_INSTANCE_OFST 0 +#define MC_CMD_SET_EVQ_TMR_IN_INSTANCE_LEN 4 /* Requested value for timer load (in nanoseconds) */ #define MC_CMD_SET_EVQ_TMR_IN_TMR_LOAD_REQ_NS_OFST 4 +#define MC_CMD_SET_EVQ_TMR_IN_TMR_LOAD_REQ_NS_LEN 4 /* Requested value for timer reload (in nanoseconds) */ #define MC_CMD_SET_EVQ_TMR_IN_TMR_RELOAD_REQ_NS_OFST 8 +#define MC_CMD_SET_EVQ_TMR_IN_TMR_RELOAD_REQ_NS_LEN 4 /* Timer mode. Meanings as per EVQ_TMR_REG.TC_TIMER_VAL */ #define MC_CMD_SET_EVQ_TMR_IN_TMR_MODE_OFST 12 +#define MC_CMD_SET_EVQ_TMR_IN_TMR_MODE_LEN 4 #define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_DIS 0x0 /* enum */ #define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_IMMED_START 0x1 /* enum */ #define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_TRIG_START 0x2 /* enum */ @@ -12052,8 +14189,10 @@ #define MC_CMD_SET_EVQ_TMR_OUT_LEN 8 /* Actual value for timer load (in nanoseconds) */ #define MC_CMD_SET_EVQ_TMR_OUT_TMR_LOAD_ACT_NS_OFST 0 +#define MC_CMD_SET_EVQ_TMR_OUT_TMR_LOAD_ACT_NS_LEN 4 /* Actual value for timer reload (in nanoseconds) */ #define MC_CMD_SET_EVQ_TMR_OUT_TMR_RELOAD_ACT_NS_OFST 4 +#define MC_CMD_SET_EVQ_TMR_OUT_TMR_RELOAD_ACT_NS_LEN 4 /***********************************/ @@ -12071,29 +14210,35 @@ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_LEN 36 /* Reserved for future use. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_FLAGS_LEN 4 /* For timers updated via writes to EVQ_TMR_REG, this is the time interval (in * nanoseconds) for each increment of the timer load/reload count. The * requested duration of a timer is this value multiplied by the timer * load/reload count. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_NS_PER_COUNT_OFST 4 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_NS_PER_COUNT_LEN 4 /* For timers updated via writes to EVQ_TMR_REG, this is the maximum value * allowed for timer load/reload counts. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_MAX_COUNT_OFST 8 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_MAX_COUNT_LEN 4 /* For timers updated via writes to EVQ_TMR_REG, timer load/reload counts not a * multiple of this step size will be rounded in an implementation defined * manner. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_STEP_OFST 12 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_STEP_LEN 4 /* Maximum timer duration (in nanoseconds) for timers updated via MCDI. Only * meaningful if MC_CMD_SET_EVQ_TMR is implemented. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_MCDI_TMR_MAX_NS_OFST 16 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_MCDI_TMR_MAX_NS_LEN 4 /* Timer durations requested via MCDI that are not a multiple of this step size * will be rounded up. Only meaningful if MC_CMD_SET_EVQ_TMR is implemented. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_MCDI_TMR_STEP_NS_OFST 20 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_MCDI_TMR_STEP_NS_LEN 4 /* For timers updated using the bug35388 workaround, this is the time interval * (in nanoseconds) for each increment of the timer load/reload count. The * requested duration of a timer is this value multiplied by the timer @@ -12101,17 +14246,20 @@ * is enabled. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_NS_PER_COUNT_OFST 24 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_NS_PER_COUNT_LEN 4 /* For timers updated using the bug35388 workaround, this is the maximum value * allowed for timer load/reload counts. This field is only meaningful if the * bug35388 workaround is enabled. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_MAX_COUNT_OFST 28 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_MAX_COUNT_LEN 4 /* For timers updated using the bug35388 workaround, timer load/reload counts * not a multiple of this step size will be rounded in an implementation * defined manner. This field is only meaningful if the bug35388 workaround is * enabled. */ #define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_STEP_OFST 32 +#define MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_STEP_LEN 4 /***********************************/ @@ -12129,19 +14277,24 @@ * local queue index. */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INSTANCE_OFST 0 +#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INSTANCE_LEN 4 /* Will the common pool be used as TX_vFIFO_ULL (1) */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_MODE_OFST 4 +#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_MODE_LEN 4 #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_ENABLED 0x1 /* enum */ /* enum: Using this interface without TX_vFIFO_ULL is not supported for now */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_DISABLED 0x0 /* Number of buffers to reserve for the common pool */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_SIZE_OFST 8 +#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_SIZE_LEN 4 /* TX datapath to which the Common Pool is connected to. */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INGRESS_OFST 12 +#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INGRESS_LEN 4 /* enum: Extracts information from function */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_USE_FUNCTION_VALUE -0x1 /* Network port or RX Engine to which the common pool connects. */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_EGRESS_OFST 16 +#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_EGRESS_LEN 4 /* enum: Extracts information from function */ /* MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_USE_FUNCTION_VALUE -0x1 */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT0 0x0 /* enum */ @@ -12157,6 +14310,7 @@ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT_LEN 4 /* ID of the common pool allocated */ #define MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT_CP_ID_OFST 0 +#define MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT_CP_ID_LEN 4 /***********************************/ @@ -12173,8 +14327,10 @@ /* Common pool previously allocated to which the new vFIFO will be associated */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_CP_OFST 0 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_CP_LEN 4 /* Port or RX engine to associate the vFIFO egress */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_EGRESS_OFST 4 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_EGRESS_LEN 4 /* enum: Extracts information from common pool */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_USE_CP_VALUE -0x1 #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT0 0x0 /* enum */ @@ -12187,12 +14343,15 @@ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_RX_ENGINE1 0x5 /* Minimum number of buffers that the pool must have */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_SIZE_OFST 8 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_SIZE_LEN 4 /* enum: Do not check the space available */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_NO_MINIMUM 0x0 /* Will the vFIFO be used as TX_vFIFO_ULL */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_MODE_OFST 12 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_MODE_LEN 4 /* Network priority of the vFIFO,if applicable */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PRIORITY_OFST 16 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PRIORITY_LEN 4 /* enum: Search for the lowest unused priority */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_LOWEST_AVAILABLE -0x1 @@ -12200,8 +14359,10 @@ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_LEN 8 /* Short vFIFO ID */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_VID_OFST 0 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_VID_LEN 4 /* Network priority of the vFIFO */ #define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_PRIORITY_OFST 4 +#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_PRIORITY_LEN 4 /***********************************/ @@ -12217,6 +14378,7 @@ #define MC_CMD_TEARDOWN_TX_VFIFO_VF_IN_LEN 4 /* Short vFIFO ID */ #define MC_CMD_TEARDOWN_TX_VFIFO_VF_IN_VFIFO_OFST 0 +#define MC_CMD_TEARDOWN_TX_VFIFO_VF_IN_VFIFO_LEN 4 /* MC_CMD_TEARDOWN_TX_VFIFO_VF_OUT msgresponse */ #define MC_CMD_TEARDOWN_TX_VFIFO_VF_OUT_LEN 0 @@ -12235,6 +14397,7 @@ #define MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN_LEN 4 /* Common pool ID given when pool allocated */ #define MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN_POOL_ID_OFST 0 +#define MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN_POOL_ID_LEN 4 /* MC_CMD_DEALLOCATE_TX_VFIFO_CP_OUT msgresponse */ #define MC_CMD_DEALLOCATE_TX_VFIFO_CP_OUT_LEN 0 @@ -12256,8 +14419,10 @@ #define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_OUT_LEN 8 /* Available buffers for the ENG to NET vFIFOs. */ #define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_OUT_NET_OFST 0 +#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_OUT_NET_LEN 4 /* Available buffers for the ENG to ENG and NET to ENG vFIFOs. */ #define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_OUT_ENG_OFST 4 +#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_OUT_ENG_LEN 4 #endif /* MCDI_PCOL_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c index 6e1f282b2976..65ee1a468170 100644 --- a/drivers/net/ethernet/sfc/mcdi_port.c +++ b/drivers/net/ethernet/sfc/mcdi_port.c @@ -1087,7 +1087,7 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, int period = action == EFX_STATS_ENABLE ? 1000 : 0; dma_addr_t dma_addr = efx->stats_buffer.dma_addr; u32 dma_len = action != EFX_STATS_DISABLE ? - MC_CMD_MAC_NSTATS * sizeof(u64) : 0; + efx->num_mac_stats * sizeof(u64) : 0; BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); @@ -1121,7 +1121,7 @@ void efx_mcdi_mac_start_stats(struct efx_nic *efx) { __le64 *dma_stats = efx->stats_buffer.addr; - dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; + dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID; efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0); } @@ -1139,10 +1139,10 @@ void efx_mcdi_mac_pull_stats(struct efx_nic *efx) __le64 *dma_stats = efx->stats_buffer.addr; int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS; - dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; + dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID; efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0); - while (dma_stats[MC_CMD_MAC_GENERATION_END] == + while (dma_stats[efx->num_mac_stats - 1] == EFX_MC_STATS_GENERATION_INVALID && attempts-- != 0) udelay(EFX_MAC_STATS_WAIT_US); @@ -1167,7 +1167,7 @@ int efx_mcdi_port_probe(struct efx_nic *efx) /* Allocate buffer for stats */ rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer, - MC_CMD_MAC_NSTATS * sizeof(u64), GFP_KERNEL); + efx->num_mac_stats * sizeof(u64), GFP_KERNEL); if (rc) return rc; netif_dbg(efx, probe, efx->net_dev, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 6b8730a24513..4cedc5c4c6d9 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -774,6 +774,8 @@ struct vfdi_status; * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock * @fixed_features: Features which cannot be turned off + * @num_mac_stats: Number of MAC stats reported by firmware (MAC_STATS_NUM_STATS + * field of %MC_CMD_GET_CAPABILITIES_V4 response, or %MC_CMD_MAC_NSTATS) * @stats_buffer: DMA buffer for statistics * @phy_type: PHY type * @phy_op: PHY interface @@ -922,6 +924,7 @@ struct efx_nic { netdev_features_t fixed_features; + u16 num_mac_stats; struct efx_buffer stats_buffer; u64 rx_nodesc_drops_total; u64 rx_nodesc_drops_while_down; diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 7b51b6371724..763052214525 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -325,6 +325,30 @@ enum { EF10_STAT_tx_bad, EF10_STAT_tx_bad_bytes, EF10_STAT_tx_overflow, + EF10_STAT_V1_COUNT, + EF10_STAT_fec_uncorrected_errors = EF10_STAT_V1_COUNT, + EF10_STAT_fec_corrected_errors, + EF10_STAT_fec_corrected_symbols_lane0, + EF10_STAT_fec_corrected_symbols_lane1, + EF10_STAT_fec_corrected_symbols_lane2, + EF10_STAT_fec_corrected_symbols_lane3, + EF10_STAT_ctpio_dmabuf_start, + EF10_STAT_ctpio_vi_busy_fallback, + EF10_STAT_ctpio_long_write_success, + EF10_STAT_ctpio_missing_dbell_fail, + EF10_STAT_ctpio_overflow_fail, + EF10_STAT_ctpio_underflow_fail, + EF10_STAT_ctpio_timeout_fail, + EF10_STAT_ctpio_noncontig_wr_fail, + EF10_STAT_ctpio_frm_clobber_fail, + EF10_STAT_ctpio_invalid_wr_fail, + EF10_STAT_ctpio_vi_clobber_fallback, + EF10_STAT_ctpio_unqualified_fallback, + EF10_STAT_ctpio_runt_fallback, + EF10_STAT_ctpio_success, + EF10_STAT_ctpio_fallback, + EF10_STAT_ctpio_poison, + EF10_STAT_ctpio_erase, EF10_STAT_COUNT }; diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 22d49ebb347c..ae8645ae4492 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -555,7 +555,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) dma_stats = efx->stats_buffer.addr; - generation_end = dma_stats[MC_CMD_MAC_GENERATION_END]; + generation_end = dma_stats[efx->num_mac_stats - 1]; if (generation_end == EFX_MC_STATS_GENERATION_INVALID) return 0; rmb(); diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e1e5ac053760..ce2ea2d491ac 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -409,7 +409,7 @@ struct stmmac_desc_ops { /* get timestamp value */ u64(*get_timestamp) (void *desc, u32 ats); /* get rx timestamp status */ - int (*get_rx_timestamp_status) (void *desc, u32 ats); + int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats); /* Display ring */ void (*display_ring)(void *head, unsigned int size, bool rx); /* set MSS via context descriptor */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index 4b286e27c4ca..7e089bf906b4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -258,7 +258,8 @@ static int dwmac4_rx_check_timestamp(void *desc) return ret; } -static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, void *next_desc, + u32 ats) { struct dma_desc *p = (struct dma_desc *)desc; int ret = -EINVAL; @@ -270,7 +271,7 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) /* Check if timestamp is OK from context descriptor */ do { - ret = dwmac4_rx_check_timestamp(desc); + ret = dwmac4_rx_check_timestamp(next_desc); if (ret < 0) goto exit; i++; diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 7546b3664113..2a828a312814 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -400,7 +400,8 @@ static u64 enh_desc_get_timestamp(void *desc, u32 ats) return ns; } -static int enh_desc_get_rx_timestamp_status(void *desc, u32 ats) +static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc, + u32 ats) { if (ats) { struct dma_extended_desc *p = (struct dma_extended_desc *)desc; diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index f817f8f36569..db4cee57bb24 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -265,7 +265,7 @@ static u64 ndesc_get_timestamp(void *desc, u32 ats) return ns; } -static int ndesc_get_rx_timestamp_status(void *desc, u32 ats) +static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats) { struct dma_desc *p = (struct dma_desc *)desc; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 721b61655261..08c19ebd5306 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c @@ -34,6 +34,7 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, { u32 value = readl(ioaddr + PTP_TCR); unsigned long data; + u32 reg_value; /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second * formula = (1/ptp_clock) * 1000000000 @@ -50,10 +51,11 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, data &= PTP_SSIR_SSINC_MASK; + reg_value = data; if (gmac4) - data = data << GMAC4_PTP_SSIR_SSINC_SHIFT; + reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT; - writel(data, ioaddr + PTP_SSIR); + writel(reg_value, ioaddr + PTP_SSIR); return data; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c52a9963c19d..0323d672e1c5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -482,7 +482,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, desc = np; /* Check if timestamp is available */ - if (priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) { + if (priv->hw->desc->get_rx_timestamp_status(p, np, priv->adv_ts)) { ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); shhwtstamp = skb_hwtstamps(skb); diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c index d655a4261e98..eb1c6b03c329 100644 --- a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c +++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c @@ -333,9 +333,8 @@ void xlgmac_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx) { struct ethhdr *eth = (struct ethhdr *)skb->data; - unsigned char *buf = skb->data; unsigned char buffer[128]; - unsigned int i, j; + unsigned int i; netdev_dbg(netdev, "\n************** SKB dump ****************\n"); @@ -346,22 +345,13 @@ void xlgmac_print_pkt(struct net_device *netdev, netdev_dbg(netdev, "Src MAC addr: %pM\n", eth->h_source); netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto)); - for (i = 0, j = 0; i < skb->len;) { - j += snprintf(buffer + j, sizeof(buffer) - j, "%02hhx", - buf[i++]); - - if ((i % 32) == 0) { - netdev_dbg(netdev, " %#06x: %s\n", i - 32, buffer); - j = 0; - } else if ((i % 16) == 0) { - buffer[j++] = ' '; - buffer[j++] = ' '; - } else if ((i % 4) == 0) { - buffer[j++] = ' '; - } + for (i = 0; i < skb->len; i += 32) { + unsigned int len = min(skb->len - i, 32U); + + hex_dump_to_buffer(&skb->data[i], len, 32, 1, + buffer, sizeof(buffer), false); + netdev_dbg(netdev, " %#06x: %s\n", i, buffer); } - if (i % 32) - netdev_dbg(netdev, " %#06x: %s\n", i - (i % 32), buffer); netdev_dbg(netdev, "\n************** SKB dump ****************\n"); } diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index b718a02a6bb6..667c44f68dbc 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1638,19 +1638,16 @@ static __net_init int geneve_init_net(struct net *net) return 0; } -static void __net_exit geneve_exit_net(struct net *net) +static void geneve_destroy_tunnels(struct net *net, struct list_head *head) { struct geneve_net *gn = net_generic(net, geneve_net_id); struct geneve_dev *geneve, *next; struct net_device *dev, *aux; - LIST_HEAD(list); - - rtnl_lock(); /* gather any geneve devices that were moved into this ns */ for_each_netdev_safe(net, dev, aux) if (dev->rtnl_link_ops == &geneve_link_ops) - unregister_netdevice_queue(dev, &list); + unregister_netdevice_queue(dev, head); /* now gather any other geneve devices that were created in this ns */ list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) { @@ -1658,18 +1655,29 @@ static void __net_exit geneve_exit_net(struct net *net) * to the list by the previous loop. */ if (!net_eq(dev_net(geneve->dev), net)) - unregister_netdevice_queue(geneve->dev, &list); + unregister_netdevice_queue(geneve->dev, head); } + WARN_ON_ONCE(!list_empty(&gn->sock_list)); +} + +static void __net_exit geneve_exit_batch_net(struct list_head *net_list) +{ + struct net *net; + LIST_HEAD(list); + + rtnl_lock(); + list_for_each_entry(net, net_list, exit_list) + geneve_destroy_tunnels(net, &list); + /* unregister the devices gathered above */ unregister_netdevice_many(&list); rtnl_unlock(); - WARN_ON_ONCE(!list_empty(&gn->sock_list)); } static struct pernet_operations geneve_net_ops = { .init = geneve_init_net, - .exit = geneve_exit_net, + .exit_batch = geneve_exit_batch_net, .id = &geneve_net_id, .size = sizeof(struct geneve_net), }; diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c index 078d2c37a6c1..a243fa7ae02f 100644 --- a/drivers/net/netdevsim/bpf.c +++ b/drivers/net/netdevsim/bpf.c @@ -107,7 +107,7 @@ int nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, struct tc_cls_bpf_offload *cls_bpf = type_data; struct bpf_prog *prog = cls_bpf->prog; struct netdevsim *ns = cb_priv; - bool skip_sw; + struct bpf_prog *oldprog; if (type != TC_SETUP_CLSBPF || !tc_can_offload(ns->netdev) || @@ -115,27 +115,27 @@ int nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, cls_bpf->common.chain_index) return -EOPNOTSUPP; - skip_sw = cls_bpf->gen_flags & TCA_CLS_FLAGS_SKIP_SW; - - if (nsim_xdp_offload_active(ns)) - return -EBUSY; - if (!ns->bpf_tc_accept) return -EOPNOTSUPP; /* Note: progs without skip_sw will probably not be dev bound */ if (prog && !prog->aux->offload && !ns->bpf_tc_non_bound_accept) return -EOPNOTSUPP; - switch (cls_bpf->command) { - case TC_CLSBPF_REPLACE: - return nsim_bpf_offload(ns, prog, true); - case TC_CLSBPF_ADD: - return nsim_bpf_offload(ns, prog, false); - case TC_CLSBPF_DESTROY: - return nsim_bpf_offload(ns, NULL, true); - default: + if (cls_bpf->command != TC_CLSBPF_OFFLOAD) return -EOPNOTSUPP; + + oldprog = cls_bpf->oldprog; + + /* Don't remove if oldprog doesn't match driver's state */ + if (ns->bpf_offloaded != oldprog) { + oldprog = NULL; + if (!cls_bpf->prog) + return 0; + if (ns->bpf_offloaded) + return -EBUSY; } + + return nsim_bpf_offload(ns, cls_bpf->prog, oldprog); } int nsim_bpf_disable_tc(struct netdevsim *ns) @@ -201,7 +201,6 @@ static int nsim_bpf_create_prog(struct netdevsim *ns, struct bpf_prog *prog) { struct nsim_bpf_bound_prog *state; char name[16]; - int err; state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) @@ -214,10 +213,9 @@ static int nsim_bpf_create_prog(struct netdevsim *ns, struct bpf_prog *prog) /* Program id is not populated yet when we create the state. */ sprintf(name, "%u", ns->prog_id_gen++); state->ddir = debugfs_create_dir(name, ns->ddir_bpf_bound_progs); - if (IS_ERR(state->ddir)) { - err = PTR_ERR(state->ddir); + if (IS_ERR_OR_NULL(state->ddir)) { kfree(state); - return err; + return -ENOMEM; } debugfs_create_u32("id", 0400, state->ddir, &prog->aux->id); @@ -349,6 +347,8 @@ int nsim_bpf_init(struct netdevsim *ns) &ns->bpf_bind_verifier_delay); ns->ddir_bpf_bound_progs = debugfs_create_dir("bpf_bound_progs", ns->ddir); + if (IS_ERR_OR_NULL(ns->ddir_bpf_bound_progs)) + return -ENOMEM; ns->bpf_tc_accept = true; debugfs_create_bool("bpf_tc_accept", 0600, ns->ddir, diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index eb8c679fca9f..3fd567928f3d 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -139,7 +139,7 @@ static void nsim_dev_release(struct device *dev) free_netdev(ns->netdev); } -struct device_type nsim_dev_type = { +static struct device_type nsim_dev_type = { .groups = nsim_dev_attr_groups, .release = nsim_dev_release, }; @@ -151,6 +151,8 @@ static int nsim_init(struct net_device *dev) ns->netdev = dev; ns->ddir = debugfs_create_dir(netdev_name(dev), nsim_ddir); + if (IS_ERR_OR_NULL(ns->ddir)) + return -ENOMEM; err = nsim_bpf_init(ns); if (err) @@ -469,8 +471,8 @@ static int __init nsim_module_init(void) int err; nsim_ddir = debugfs_create_dir(DRV_NAME, NULL); - if (IS_ERR(nsim_ddir)) - return PTR_ERR(nsim_ddir); + if (IS_ERR_OR_NULL(nsim_ddir)) + return -ENOMEM; err = bus_register(&nsim_bus); if (err) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 2fc026dc170a..342325a89d5f 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -879,6 +879,8 @@ static int m88e1510_config_init(struct phy_device *phydev) /* SGMII-to-Copper mode initialization */ if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + u32 pause; + /* Select page 18 */ err = marvell_set_page(phydev, 18); if (err < 0) @@ -902,6 +904,16 @@ static int m88e1510_config_init(struct phy_device *phydev) err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); if (err < 0) return err; + + /* There appears to be a bug in the 88e1512 when used in + * SGMII to copper mode, where the AN advertisment register + * clears the pause bits each time a negotiation occurs. + * This means we can never be truely sure what was advertised, + * so disable Pause support. + */ + pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause; + phydev->supported &= ~pause; + phydev->advertising &= ~pause; } return m88e1121_config_init(phydev); @@ -2070,7 +2082,8 @@ static struct phy_driver marvell_drivers[] = { .flags = PHY_HAS_INTERRUPT, .probe = marvell_probe, .config_init = &m88e1145_config_init, - .config_aneg = &marvell_config_aneg, + .config_aneg = &m88e1101_config_aneg, + .read_status = &genphy_read_status, .ack_interrupt = &marvell_ack_interrupt, .config_intr = &marvell_config_intr, .resume = &genphy_resume, diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index bfd3090fb055..07c6048200c6 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c @@ -194,8 +194,11 @@ static int xgene_mdio_reset(struct xgene_mdio_pdata *pdata) } ret = xgene_enet_ecc_init(pdata); - if (ret) + if (ret) { + if (pdata->dev->of_node) + clk_disable_unprepare(pdata->clk); return ret; + } xgene_gmac_reset(pdata); return 0; @@ -388,8 +391,10 @@ static int xgene_mdio_probe(struct platform_device *pdev) return ret; mdio_bus = mdiobus_alloc(); - if (!mdio_bus) - return -ENOMEM; + if (!mdio_bus) { + ret = -ENOMEM; + goto out_clk; + } mdio_bus->name = "APM X-Gene MDIO bus"; @@ -418,7 +423,7 @@ static int xgene_mdio_probe(struct platform_device *pdev) mdio_bus->phy_mask = ~0; ret = mdiobus_register(mdio_bus); if (ret) - goto out; + goto out_mdiobus; acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1, acpi_register_phy, NULL, mdio_bus, NULL); @@ -426,16 +431,20 @@ static int xgene_mdio_probe(struct platform_device *pdev) } if (ret) - goto out; + goto out_mdiobus; pdata->mdio_bus = mdio_bus; xgene_mdio_status = true; return 0; -out: +out_mdiobus: mdiobus_free(mdio_bus); +out_clk: + if (dev->of_node) + clk_disable_unprepare(pdata->clk); + return ret; } diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index 843c1dde93e4..c924700cf37b 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -126,7 +126,7 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value) gpiod_set_value(mdiodev->reset, value); - d = value ? mdiodev->reset_delay : mdiodev->reset_post_delay; + d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay; if (d) usleep_range(d, d + max_t(unsigned int, d / 10, 100)); } diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index f7a777475762..2ec140ec7923 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -725,6 +725,9 @@ int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) phy_interface_mode_is_8023z(pl->link_interface)))) return -EINVAL; + if (pl->phydev) + return -EBUSY; + /* Use PHY device/driver interface */ if (pl->link_interface == PHY_INTERFACE_MODE_NA) { pl->link_interface = phy->interface; diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 19b9cc51079e..82090ae7ced1 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2155,6 +2155,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, } ndst = &rt->dst; + if (skb_dst(skb)) { + int mtu = dst_mtu(ndst) - VXLAN_HEADROOM; + + skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, + skb, mtu); + } + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), @@ -2190,6 +2197,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, goto out_unlock; } + if (skb_dst(skb)) { + int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM; + + skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, + skb, mtu); + } + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip6_dst_hoplimit(ndst); skb_scrub_packet(skb, xnet); @@ -3103,6 +3117,11 @@ static void vxlan_config_apply(struct net_device *dev, max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); + if (max_mtu < ETH_MIN_MTU) + max_mtu = ETH_MIN_MTU; + + if (!changelink && !conf->mtu) + dev->mtu = max_mtu; } if (dev->mtu > max_mtu) @@ -3692,18 +3711,16 @@ static __net_init int vxlan_init_net(struct net *net) return 0; } -static void __net_exit vxlan_exit_net(struct net *net) +static void vxlan_destroy_tunnels(struct net *net, struct list_head *head) { struct vxlan_net *vn = net_generic(net, vxlan_net_id); struct vxlan_dev *vxlan, *next; struct net_device *dev, *aux; unsigned int h; - LIST_HEAD(list); - rtnl_lock(); for_each_netdev_safe(net, dev, aux) if (dev->rtnl_link_ops == &vxlan_link_ops) - unregister_netdevice_queue(dev, &list); + unregister_netdevice_queue(dev, head); list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) { /* If vxlan->dev is in the same netns, it has already been added @@ -3711,20 +3728,30 @@ static void __net_exit vxlan_exit_net(struct net *net) */ if (!net_eq(dev_net(vxlan->dev), net)) { gro_cells_destroy(&vxlan->gro_cells); - unregister_netdevice_queue(vxlan->dev, &list); + unregister_netdevice_queue(vxlan->dev, head); } } - unregister_netdevice_many(&list); - rtnl_unlock(); - for (h = 0; h < PORT_HASH_SIZE; ++h) WARN_ON_ONCE(!hlist_empty(&vn->sock_list[h])); } +static void __net_exit vxlan_exit_batch_net(struct list_head *net_list) +{ + struct net *net; + LIST_HEAD(list); + + rtnl_lock(); + list_for_each_entry(net, net_list, exit_list) + vxlan_destroy_tunnels(net, &list); + + unregister_netdevice_many(&list); + rtnl_unlock(); +} + static struct pernet_operations vxlan_net_ops = { .init = vxlan_init_net, - .exit = vxlan_exit_net, + .exit_batch = vxlan_exit_batch_net, .id = &vxlan_net_id, .size = sizeof(struct vxlan_net), }; diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index 87f56d0e17a6..deb5ae21a559 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig @@ -47,12 +47,19 @@ config ATH10K_DEBUG config ATH10K_DEBUGFS bool "Atheros ath10k debugfs support" depends on ATH10K && DEBUG_FS - select RELAY ---help--- Enabled debugfs support If unsure, say Y to make it easier to debug problems. +config ATH10K_SPECTRAL + bool "Atheros ath10k spectral scan support" + depends on ATH10K_DEBUGFS + select RELAY + default n + ---help--- + Say Y to enable access to the FFT/spectral data via debugfs. + config ATH10K_TRACING bool "Atheros ath10k tracing support" depends on ATH10K diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile index 9492177e9063..8d9a59b7144e 100644 --- a/drivers/net/wireless/ath/ath10k/Makefile +++ b/drivers/net/wireless/ath/ath10k/Makefile @@ -15,7 +15,7 @@ ath10k_core-y += mac.o \ p2p.o \ swap.o -ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o +ath10k_core-$(CONFIG_ATH10K_SPECTRAL) += spectral.o ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o ath10k_core-$(CONFIG_THERMAL) += thermal.o diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index b29fdbd21ead..6d065f8d7f78 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -75,6 +75,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA9887_HW_1_0_VERSION, @@ -99,6 +102,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA6174_HW_2_1_VERSION, @@ -122,6 +128,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA6174_HW_2_1_VERSION, @@ -145,6 +154,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA6174_HW_3_0_VERSION, @@ -168,6 +180,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA6174_HW_3_2_VERSION, @@ -194,6 +209,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA99X0_HW_2_0_DEV_VERSION, @@ -223,6 +241,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 11, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA9984_HW_1_0_DEV_VERSION, @@ -257,6 +278,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 1560, .vht160_mcs_tx_highest = 1560, .n_cipher_suites = 11, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA9888_HW_2_0_DEV_VERSION, @@ -290,6 +314,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 780, .vht160_mcs_tx_highest = 780, .n_cipher_suites = 11, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA9377_HW_1_0_DEV_VERSION, @@ -313,6 +340,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA9377_HW_1_1_DEV_VERSION, @@ -338,6 +368,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 8, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, }, { .id = QCA4019_HW_1_0_DEV_VERSION, @@ -368,6 +401,27 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .vht160_mcs_rx_highest = 0, .vht160_mcs_tx_highest = 0, .n_cipher_suites = 11, + .num_peers = TARGET_TLV_NUM_PEERS, + .ast_skid_limit = 0x10, + .num_wds_entries = 0x20, + }, + { + .id = WCN3990_HW_1_0_DEV_VERSION, + .dev_id = 0, + .name = "wcn3990 hw1.0", + .continuous_frag_desc = true, + .tx_chain_mask = 0x7, + .rx_chain_mask = 0x7, + .max_spatial_stream = 4, + .fw = { + .dir = WCN3990_HW_1_0_FW_DIR, + }, + .sw_decrypt_mcast_mgmt = true, + .hw_ops = &wcn3990_ops, + .decap_align_bytes = 1, + .num_peers = TARGET_HL_10_TLV_NUM_PEERS, + .ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT, + .num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES, }, }; @@ -390,6 +444,7 @@ static const char *const ath10k_core_fw_feature_str[] = { [ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war", [ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast", [ATH10K_FW_FEATURE_NO_PS] = "no-ps", + [ATH10K_FW_FEATURE_MGMT_TX_BY_REF] = "mgmt-tx-by-reference", }; static unsigned int ath10k_core_get_fw_feature_str(char *buf, @@ -860,6 +915,28 @@ static int ath10k_core_check_smbios(struct ath10k *ar) return 0; } +static int ath10k_core_check_dt(struct ath10k *ar) +{ + struct device_node *node; + const char *variant = NULL; + + node = ar->dev->of_node; + if (!node) + return -ENOENT; + + of_property_read_string(node, "qcom,ath10k-calibration-variant", + &variant); + if (!variant) + return -ENODATA; + + if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0) + ath10k_dbg(ar, ATH10K_DBG_BOOT, + "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", + variant); + + return 0; +} + static int ath10k_download_and_run_otp(struct ath10k *ar) { u32 result, address = ar->hw_params.patch_load_addr; @@ -1231,19 +1308,19 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name, /* strlen(',variant=') + strlen(ar->id.bdf_ext) */ char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 }; + if (ar->id.bdf_ext[0] != '\0') + scnprintf(variant, sizeof(variant), ",variant=%s", + ar->id.bdf_ext); + if (ar->id.bmi_ids_valid) { scnprintf(name, name_len, - "bus=%s,bmi-chip-id=%d,bmi-board-id=%d", + "bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s", ath10k_bus_str(ar->hif.bus), ar->id.bmi_chip_id, - ar->id.bmi_board_id); + ar->id.bmi_board_id, variant); goto out; } - if (ar->id.bdf_ext[0] != '\0') - scnprintf(variant, sizeof(variant), ",variant=%s", - ar->id.bdf_ext); - scnprintf(name, name_len, "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s", ath10k_bus_str(ar->hif.bus), @@ -2343,7 +2420,11 @@ static int ath10k_core_probe_fw(struct ath10k *ar) ret = ath10k_core_check_smbios(ar); if (ret) - ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n"); + ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n"); + + ret = ath10k_core_check_dt(ar); + if (ret) + ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n"); ret = ath10k_core_fetch_board_file(ar); if (ret) { diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 643041ef3271..631df2137e25 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -67,7 +67,6 @@ /* NAPI poll budget */ #define ATH10K_NAPI_BUDGET 64 -#define ATH10K_NAPI_QUOTA_LIMIT 60 /* SMBIOS type containing Board Data File Name Extension */ #define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8 @@ -364,11 +363,11 @@ struct ath10k_sta { struct rate_info txrate; struct work_struct update_wk; + u64 rx_duration; #ifdef CONFIG_MAC80211_DEBUGFS /* protected by conf_mutex */ bool aggr_mode; - u64 rx_duration; #endif }; @@ -463,7 +462,7 @@ struct ath10k_fw_crash_data { bool crashed_since_read; guid_t guid; - struct timespec timestamp; + struct timespec64 timestamp; __le32 registers[REG_DUMP_COUNT_QCA988X]; struct ath10k_ce_crash_data ce_crash_data[CE_COUNT_MAX]; }; @@ -488,7 +487,6 @@ struct ath10k_debug { /* protected by conf_mutex */ u64 fw_dbglog_mask; u32 fw_dbglog_level; - u32 pktlog_filter; u32 reg_addr; u32 nf_cal_period; void *cal_data; @@ -615,6 +613,9 @@ enum ath10k_fw_features { /* Firmware does not support power save in station mode. */ ATH10K_FW_FEATURE_NO_PS = 17, + /* Firmware allows management tx by reference instead of by value. */ + ATH10K_FW_FEATURE_MGMT_TX_BY_REF = 18, + /* keep last */ ATH10K_FW_FEATURE_COUNT, }; @@ -963,6 +964,7 @@ struct ath10k { } spectral; #endif + u32 pktlog_filter; struct { /* protected by conf_mutex */ struct ath10k_fw_components utf_mode_fw; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index df514507d3f1..181fd8e2e615 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -720,7 +720,7 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) crash_data->crashed_since_read = true; guid_gen(&crash_data->guid); - getnstimeofday(&crash_data->timestamp); + ktime_get_real_ts64(&crash_data->timestamp); return crash_data; } @@ -1950,14 +1950,14 @@ int ath10k_debug_start(struct ath10k *ar) ret); } - if (ar->debug.pktlog_filter) { + if (ar->pktlog_filter) { ret = ath10k_wmi_pdev_pktlog_enable(ar, - ar->debug.pktlog_filter); + ar->pktlog_filter); if (ret) /* not serious */ ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n", - ar->debug.pktlog_filter, ret); + ar->pktlog_filter, ret); } else { ret = ath10k_wmi_pdev_pktlog_disable(ar); if (ret) @@ -2097,12 +2097,12 @@ static ssize_t ath10k_write_pktlog_filter(struct file *file, mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_ON) { - ar->debug.pktlog_filter = filter; + ar->pktlog_filter = filter; ret = count; goto out; } - if (filter == ar->debug.pktlog_filter) { + if (filter == ar->pktlog_filter) { ret = count; goto out; } @@ -2111,7 +2111,7 @@ static ssize_t ath10k_write_pktlog_filter(struct file *file, ret = ath10k_wmi_pdev_pktlog_enable(ar, filter); if (ret) { ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n", - ar->debug.pktlog_filter, ret); + ar->pktlog_filter, ret); goto out; } } else { @@ -2122,7 +2122,7 @@ static ssize_t ath10k_write_pktlog_filter(struct file *file, } } - ar->debug.pktlog_filter = filter; + ar->pktlog_filter = filter; ret = count; out: @@ -2139,7 +2139,7 @@ static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf, mutex_lock(&ar->conf_mutex); len = scnprintf(buf, sizeof(buf) - len, "%08x\n", - ar->debug.pktlog_filter); + ar->pktlog_filter); mutex_unlock(&ar->conf_mutex); return simple_read_from_buffer(ubuf, count, ppos, buf, len); diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 548ad5483a4a..5e662994c49a 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -51,7 +51,8 @@ enum ath10k_pktlog_filter { ATH10K_PKTLOG_RCFIND = 0x000000004, ATH10K_PKTLOG_RCUPDATE = 0x000000008, ATH10K_PKTLOG_DBG_PRINT = 0x000000010, - ATH10K_PKTLOG_ANY = 0x00000001f, + ATH10K_PKTLOG_PEER_STATS = 0x000000040, + ATH10K_PKTLOG_ANY = 0x00000005f, }; enum ath10k_dbg_aggr_mode { @@ -60,6 +61,21 @@ enum ath10k_dbg_aggr_mode { ATH10K_DBG_AGGR_MODE_MAX, }; +/* Types of packet log events */ +enum ath_pktlog_type { + ATH_PKTLOG_TYPE_TX_CTRL = 1, + ATH_PKTLOG_TYPE_TX_STAT, +}; + +struct ath10k_pktlog_hdr { + __le16 flags; + __le16 missed_cnt; + __le16 log_type; /* Type of log information foll this header */ + __le16 size; /* Size of variable length log information in bytes */ + __le32 timestamp; + u8 payload[0]; +} __packed; + /* FIXME: How to calculate the buffer size sanely? */ #define ATH10K_FW_STATS_BUF_SIZE (1024 * 1024) @@ -190,9 +206,6 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct dentry *dir); void ath10k_sta_update_rx_duration(struct ath10k *ar, struct ath10k_fw_stats *stats); -void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo); #else static inline void ath10k_sta_update_rx_duration(struct ath10k *ar, diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c index d59ac6b83340..ff96f70d2282 100644 --- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c @@ -65,33 +65,6 @@ void ath10k_sta_update_rx_duration(struct ath10k *ar, ath10k_sta_update_stats_rx_duration(ar, stats); } -void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo) -{ - struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; - struct ath10k *ar = arsta->arvif->ar; - - if (!ath10k_peer_stats_enabled(ar)) - return; - - sinfo->rx_duration = arsta->rx_duration; - sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION; - - if (!arsta->txrate.legacy && !arsta->txrate.nss) - return; - - if (arsta->txrate.legacy) { - sinfo->txrate.legacy = arsta->txrate.legacy; - } else { - sinfo->txrate.mcs = arsta->txrate.mcs; - sinfo->txrate.nss = arsta->txrate.nss; - sinfo->txrate.bw = arsta->txrate.bw; - } - sinfo->txrate.flags = arsta->txrate.flags; - sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE; -} - static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 6305308422c4..7bd93d627f6b 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -1497,6 +1497,23 @@ struct htt_peer_tx_stats { u8 payload[0]; } __packed; +#define ATH10K_10_2_TX_STATS_OFFSET 136 +#define PEER_STATS_FOR_NO_OF_PPDUS 4 + +struct ath10k_10_2_peer_tx_stats { + u8 ratecode[PEER_STATS_FOR_NO_OF_PPDUS]; + u8 success_pkts[PEER_STATS_FOR_NO_OF_PPDUS]; + __le16 success_bytes[PEER_STATS_FOR_NO_OF_PPDUS]; + u8 retry_pkts[PEER_STATS_FOR_NO_OF_PPDUS]; + __le16 retry_bytes[PEER_STATS_FOR_NO_OF_PPDUS]; + u8 failed_pkts[PEER_STATS_FOR_NO_OF_PPDUS]; + __le16 failed_bytes[PEER_STATS_FOR_NO_OF_PPDUS]; + u8 flags[PEER_STATS_FOR_NO_OF_PPDUS]; + __le32 tx_duration; + u8 tx_ppdu_cnt; + u8 peer_id; +} __packed; + union htt_rx_pn_t { /* WEP: 24-bit PN */ u32 pn24; @@ -1695,7 +1712,7 @@ struct ath10k_htt { /* This is used to group tx/rx completions separately and process them * in batches to reduce cache stalls */ - struct sk_buff_head rx_compl_q; + struct sk_buff_head rx_msdus_q; struct sk_buff_head rx_in_ord_compl_q; struct sk_buff_head tx_fetch_ind_q; diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 7d295ee71534..620ed7dca836 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -227,7 +227,7 @@ void ath10k_htt_rx_free(struct ath10k_htt *htt) { del_timer_sync(&htt->rx_ring.refill_retry_timer); - skb_queue_purge(&htt->rx_compl_q); + skb_queue_purge(&htt->rx_msdus_q); skb_queue_purge(&htt->rx_in_ord_compl_q); skb_queue_purge(&htt->tx_fetch_ind_q); @@ -515,7 +515,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) htt->rx_ring.sw_rd_idx.msdu_payld = 0; hash_init(htt->rx_ring.skb_table); - skb_queue_head_init(&htt->rx_compl_q); + skb_queue_head_init(&htt->rx_msdus_q); skb_queue_head_init(&htt->rx_in_ord_compl_q); skb_queue_head_init(&htt->tx_fetch_ind_q); atomic_set(&htt->num_mpdus_ready, 0); @@ -974,16 +974,25 @@ static char *ath10k_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size) return out; } -static void ath10k_process_rx(struct ath10k *ar, - struct ieee80211_rx_status *rx_status, - struct sk_buff *skb) +static void ath10k_htt_rx_h_queue_msdu(struct ath10k *ar, + struct ieee80211_rx_status *rx_status, + struct sk_buff *skb) +{ + struct ieee80211_rx_status *status; + + status = IEEE80211_SKB_RXCB(skb); + *status = *rx_status; + + __skb_queue_tail(&ar->htt.rx_msdus_q, skb); +} + +static void ath10k_process_rx(struct ath10k *ar, struct sk_buff *skb) { struct ieee80211_rx_status *status; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; char tid[32]; status = IEEE80211_SKB_RXCB(skb); - *status = *rx_status; ath10k_dbg(ar, ATH10K_DBG_DATA, "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", @@ -1517,7 +1526,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, } } -static void ath10k_htt_rx_h_deliver(struct ath10k *ar, +static void ath10k_htt_rx_h_enqueue(struct ath10k *ar, struct sk_buff_head *amsdu, struct ieee80211_rx_status *status) { @@ -1540,7 +1549,7 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, status->flag |= RX_FLAG_ALLOW_SAME_PN; } - ath10k_process_rx(ar, status, msdu); + ath10k_htt_rx_h_queue_msdu(ar, status, msdu); } } @@ -1652,7 +1661,7 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) struct ath10k *ar = htt->ar; struct ieee80211_rx_status *rx_status = &htt->rx_status; struct sk_buff_head amsdu; - int ret, num_msdus; + int ret; __skb_queue_head_init(&amsdu); @@ -1674,7 +1683,6 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) return ret; } - num_msdus = skb_queue_len(&amsdu); ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); /* only for ret = 1 indicates chained msdus */ @@ -1683,9 +1691,9 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); - ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); + ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); - return num_msdus; + return 0; } static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt, @@ -1893,15 +1901,14 @@ static void ath10k_htt_rx_h_rx_offload_prot(struct ieee80211_rx_status *status, RX_FLAG_MMIC_STRIPPED; } -static int ath10k_htt_rx_h_rx_offload(struct ath10k *ar, - struct sk_buff_head *list) +static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar, + struct sk_buff_head *list) { struct ath10k_htt *htt = &ar->htt; struct ieee80211_rx_status *status = &htt->rx_status; struct htt_rx_offload_msdu *rx; struct sk_buff *msdu; size_t offset; - int num_msdu = 0; while ((msdu = __skb_dequeue(list))) { /* Offloaded frames don't have Rx descriptor. Instead they have @@ -1940,10 +1947,8 @@ static int ath10k_htt_rx_h_rx_offload(struct ath10k *ar, ath10k_htt_rx_h_rx_offload_prot(status, msdu); ath10k_htt_rx_h_channel(ar, status, NULL, rx->vdev_id); - ath10k_process_rx(ar, status, msdu); - num_msdu++; + ath10k_htt_rx_h_queue_msdu(ar, status, msdu); } - return num_msdu; } static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) @@ -1959,7 +1964,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) u8 tid; bool offload; bool frag; - int ret, num_msdus = 0; + int ret; lockdep_assert_held(&htt->rx_ring.lock); @@ -2001,7 +2006,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) * separately. */ if (offload) - num_msdus = ath10k_htt_rx_h_rx_offload(ar, &list); + ath10k_htt_rx_h_rx_offload(ar, &list); while (!skb_queue_empty(&list)) { __skb_queue_head_init(&amsdu); @@ -2014,11 +2019,10 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) * better to report something than nothing though. This * should still give an idea about rx rate to the user. */ - num_msdus += skb_queue_len(&amsdu); ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); ath10k_htt_rx_h_filter(ar, &amsdu, status); ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); - ath10k_htt_rx_h_deliver(ar, &amsdu, status); + ath10k_htt_rx_h_enqueue(ar, &amsdu, status); break; case -EAGAIN: /* fall through */ @@ -2030,7 +2034,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) return -EIO; } } - return num_msdus; + return ret; } static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar, @@ -2449,6 +2453,62 @@ out: rcu_read_unlock(); } +static void ath10k_fetch_10_2_tx_stats(struct ath10k *ar, u8 *data) +{ + struct ath10k_pktlog_hdr *hdr = (struct ath10k_pktlog_hdr *)data; + struct ath10k_per_peer_tx_stats *p_tx_stats = &ar->peer_tx_stats; + struct ath10k_10_2_peer_tx_stats *tx_stats; + struct ieee80211_sta *sta; + struct ath10k_peer *peer; + u16 log_type = __le16_to_cpu(hdr->log_type); + u32 peer_id = 0, i; + + if (log_type != ATH_PKTLOG_TYPE_TX_STAT) + return; + + tx_stats = (struct ath10k_10_2_peer_tx_stats *)((hdr->payload) + + ATH10K_10_2_TX_STATS_OFFSET); + + if (!tx_stats->tx_ppdu_cnt) + return; + + peer_id = tx_stats->peer_id; + + rcu_read_lock(); + spin_lock_bh(&ar->data_lock); + peer = ath10k_peer_find_by_id(ar, peer_id); + if (!peer) { + ath10k_warn(ar, "Invalid peer id %d in peer stats buffer\n", + peer_id); + goto out; + } + + sta = peer->sta; + for (i = 0; i < tx_stats->tx_ppdu_cnt; i++) { + p_tx_stats->succ_bytes = + __le16_to_cpu(tx_stats->success_bytes[i]); + p_tx_stats->retry_bytes = + __le16_to_cpu(tx_stats->retry_bytes[i]); + p_tx_stats->failed_bytes = + __le16_to_cpu(tx_stats->failed_bytes[i]); + p_tx_stats->ratecode = tx_stats->ratecode[i]; + p_tx_stats->flags = tx_stats->flags[i]; + p_tx_stats->succ_pkts = tx_stats->success_pkts[i]; + p_tx_stats->retry_pkts = tx_stats->retry_pkts[i]; + p_tx_stats->failed_pkts = tx_stats->failed_pkts[i]; + + ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats); + } + spin_unlock_bh(&ar->data_lock); + rcu_read_unlock(); + + return; + +out: + spin_unlock_bh(&ar->data_lock); + rcu_read_unlock(); +} + bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) { struct ath10k_htt *htt = &ar->htt; @@ -2566,6 +2626,10 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) skb->len - offsetof(struct htt_resp, pktlog_msg.payload)); + + if (ath10k_peer_stats_enabled(ar)) + ath10k_fetch_10_2_tx_stats(ar, + resp->pktlog_msg.payload); break; } case HTT_T2H_MSG_TYPE_RX_FLUSH: { @@ -2631,6 +2695,24 @@ void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar, } EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler); +static int ath10k_htt_rx_deliver_msdu(struct ath10k *ar, int quota, int budget) +{ + struct sk_buff *skb; + + while (quota < budget) { + if (skb_queue_empty(&ar->htt.rx_msdus_q)) + break; + + skb = __skb_dequeue(&ar->htt.rx_msdus_q); + if (!skb) + break; + ath10k_process_rx(ar, skb); + quota++; + } + + return quota; +} + int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget) { struct ath10k_htt *htt = &ar->htt; @@ -2638,63 +2720,44 @@ int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget) struct sk_buff_head tx_ind_q; struct sk_buff *skb; unsigned long flags; - int quota = 0, done, num_rx_msdus; + int quota = 0, done, ret; bool resched_napi = false; __skb_queue_head_init(&tx_ind_q); - /* Since in-ord-ind can deliver more than 1 A-MSDU in single event, - * process it first to utilize full available quota. + /* Process pending frames before dequeuing more data + * from hardware. */ - while (quota < budget) { - if (skb_queue_empty(&htt->rx_in_ord_compl_q)) - break; - - skb = __skb_dequeue(&htt->rx_in_ord_compl_q); - if (!skb) { - resched_napi = true; - goto exit; - } + quota = ath10k_htt_rx_deliver_msdu(ar, quota, budget); + if (quota == budget) { + resched_napi = true; + goto exit; + } + while ((skb = __skb_dequeue(&htt->rx_in_ord_compl_q))) { spin_lock_bh(&htt->rx_ring.lock); - num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb); + ret = ath10k_htt_rx_in_ord_ind(ar, skb); spin_unlock_bh(&htt->rx_ring.lock); - if (num_rx_msdus < 0) { - resched_napi = true; - goto exit; - } dev_kfree_skb_any(skb); - if (num_rx_msdus > 0) - quota += num_rx_msdus; - - if ((quota > ATH10K_NAPI_QUOTA_LIMIT) && - !skb_queue_empty(&htt->rx_in_ord_compl_q)) { + if (ret == -EIO) { resched_napi = true; goto exit; } } - while (quota < budget) { - /* no more data to receive */ - if (!atomic_read(&htt->num_mpdus_ready)) - break; - - num_rx_msdus = ath10k_htt_rx_handle_amsdu(htt); - if (num_rx_msdus < 0) { + while (atomic_read(&htt->num_mpdus_ready)) { + ret = ath10k_htt_rx_handle_amsdu(htt); + if (ret == -EIO) { resched_napi = true; goto exit; } - - quota += num_rx_msdus; atomic_dec(&htt->num_mpdus_ready); - if ((quota > ATH10K_NAPI_QUOTA_LIMIT) && - atomic_read(&htt->num_mpdus_ready)) { - resched_napi = true; - goto exit; - } } + /* Deliver received data after processing data from hardware */ + quota = ath10k_htt_rx_deliver_msdu(ar, quota, budget); + /* From NAPI documentation: * The napi poll() function may also process TX completions, in which * case if it processes the entire TX ring then it should count that diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c index 88955bbe20bd..c31eea632777 100644 --- a/drivers/net/wireless/ath/ath10k/hw.c +++ b/drivers/net/wireless/ath/ath10k/hw.c @@ -931,3 +931,5 @@ const struct ath10k_hw_ops qca6174_ops = { .set_coverage_class = ath10k_hw_qca988x_set_coverage_class, .enable_pll_clk = ath10k_hw_qca6174_enable_pll_clock, }; + +const struct ath10k_hw_ops wcn3990_ops = {}; diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 05f26e5858ad..90ad39bdeec4 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -128,6 +128,10 @@ enum qca9377_chip_id_rev { #define QCA4019_HW_1_0_BOARD_DATA_FILE "board.bin" #define QCA4019_HW_1_0_PATCH_LOAD_ADDR 0x1234 +/* WCN3990 1.0 definitions */ +#define WCN3990_HW_1_0_DEV_VERSION ATH10K_HW_WCN3990 +#define WCN3990_HW_1_0_FW_DIR ATH10K_FW_DIR "/WCN3990/hw3.0" + #define ATH10K_FW_FILE_BASE "firmware" #define ATH10K_FW_API_MAX 6 #define ATH10K_FW_API_MIN 2 @@ -553,6 +557,10 @@ struct ath10k_hw_params { /* Number of ciphers supported (i.e First N) in cipher_suites array */ int n_cipher_suites; + + u32 num_peers; + u32 ast_skid_limit; + u32 num_wds_entries; }; struct htt_rx_desc; @@ -567,6 +575,7 @@ struct ath10k_hw_ops { extern const struct ath10k_hw_ops qca988x_ops; extern const struct ath10k_hw_ops qca99x0_ops; extern const struct ath10k_hw_ops qca6174_ops; +extern const struct ath10k_hw_ops wcn3990_ops; extern const struct ath10k_hw_clk_params qca6174_clk[]; @@ -663,6 +672,11 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw, #define TARGET_TLV_NUM_MSDU_DESC (1024 + 32) #define TARGET_TLV_NUM_WOW_PATTERNS 22 +/* Target specific defines for WMI-HL-1.0 firmware */ +#define TARGET_HL_10_TLV_NUM_PEERS 14 +#define TARGET_HL_10_TLV_AST_SKID_LIMIT 6 +#define TARGET_HL_10_TLV_NUM_WDS_ENTRIES 2 + /* Diagnostic Window */ #define CE_DIAG_PIPE 7 diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 0a947eef348d..75726f12a31c 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2563,7 +2563,7 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar, } break; case WMI_VDEV_TYPE_STA: - if (vif->bss_conf.qos) + if (sta->wme) arg->peer_flags |= arvif->ar->wmi.peer_flags->qos; break; case WMI_VDEV_TYPE_IBSS: @@ -3574,7 +3574,9 @@ ath10k_mac_tx_h_get_txpath(struct ath10k *ar, return ATH10K_MAC_TX_HTT; case ATH10K_HW_TXRX_MGMT: if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, - ar->running_fw->fw_file.fw_features)) + ar->running_fw->fw_file.fw_features) || + test_bit(WMI_SERVICE_MGMT_TX_WMI, + ar->wmi.svc_map)) return ATH10K_MAC_TX_WMI_MGMT; else if (ar->htt.target_version_major >= 3) return ATH10K_MAC_TX_HTT; @@ -6201,6 +6203,16 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, "mac vdev %d peer delete %pM sta %pK (sta gone)\n", arvif->vdev_id, sta->addr, sta); + if (sta->tdls) { + ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, + sta, + WMI_TDLS_PEER_STATE_TEARDOWN); + if (ret) + ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n", + sta->addr, + WMI_TDLS_PEER_STATE_TEARDOWN, ret); + } + ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); if (ret) ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n", @@ -7536,6 +7548,16 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, arvif->vdev_id, ret); } + if (ath10k_peer_stats_enabled(ar)) { + ar->pktlog_filter |= ATH10K_PKTLOG_PEER_STATS; + ret = ath10k_wmi_pdev_pktlog_enable(ar, + ar->pktlog_filter); + if (ret) { + ath10k_warn(ar, "failed to enable pktlog %d\n", ret); + goto err_stop; + } + } + mutex_unlock(&ar->conf_mutex); return 0; @@ -7620,6 +7642,34 @@ static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw, peer->removed = true; } +static void ath10k_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; + struct ath10k *ar = arsta->arvif->ar; + + if (!ath10k_peer_stats_enabled(ar)) + return; + + sinfo->rx_duration = arsta->rx_duration; + sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION; + + if (!arsta->txrate.legacy && !arsta->txrate.nss) + return; + + if (arsta->txrate.legacy) { + sinfo->txrate.legacy = arsta->txrate.legacy; + } else { + sinfo->txrate.mcs = arsta->txrate.mcs; + sinfo->txrate.nss = arsta->txrate.nss; + sinfo->txrate.bw = arsta->txrate.bw; + } + sinfo->txrate.flags = arsta->txrate.flags; + sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE; +} + static const struct ieee80211_ops ath10k_ops = { .tx = ath10k_mac_op_tx, .wake_tx_queue = ath10k_mac_op_wake_tx_queue, @@ -7661,6 +7711,7 @@ static const struct ieee80211_ops ath10k_ops = { .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx, .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx, .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove, + .sta_statistics = ath10k_sta_statistics, CFG80211_TESTMODE_CMD(ath10k_tm_cmd) @@ -7671,7 +7722,6 @@ static const struct ieee80211_ops ath10k_ops = { #endif #ifdef CONFIG_MAC80211_DEBUGFS .sta_add_debugfs = ath10k_sta_add_debugfs, - .sta_statistics = ath10k_sta_statistics, #endif }; @@ -8329,15 +8379,6 @@ int ath10k_mac_register(struct ath10k *ar) ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); } - /* Current wake_tx_queue implementation imposes a significant - * performance penalty in some setups. The tx scheduling code needs - * more work anyway so disable the wake_tx_queue unless firmware - * supports the pull-push mechanism. - */ - if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, - ar->running_fw->fw_file.fw_features)) - ar->ops->wake_tx_queue = NULL; - ret = ath10k_mac_init_rd(ar); if (ret) { ath10k_err(ar, "failed to derive regdom: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath10k/spectral.h b/drivers/net/wireless/ath/ath10k/spectral.h index 89b0ad769d4f..b2a2e8ae04b8 100644 --- a/drivers/net/wireless/ath/ath10k/spectral.h +++ b/drivers/net/wireless/ath/ath10k/spectral.h @@ -44,7 +44,7 @@ enum ath10k_spectral_mode { SPECTRAL_MANUAL, }; -#ifdef CONFIG_ATH10K_DEBUGFS +#ifdef CONFIG_ATH10K_SPECTRAL int ath10k_spectral_process_fft(struct ath10k *ar, struct wmi_phyerr_ev_arg *phyerr, @@ -85,6 +85,6 @@ static inline void ath10k_spectral_destroy(struct ath10k *ar) { } -#endif /* CONFIG_ATH10K_DEBUGFS */ +#endif /* CONFIG_ATH10K_SPECTRAL */ #endif /* SPECTRAL_H */ diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h index 2fc3f24ff1ca..41eef942ab2c 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h @@ -377,6 +377,7 @@ ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); struct sk_buff *skb; int ret; + u32 mgmt_tx_cmdid; if (!ar->wmi.ops->gen_mgmt_tx) return -EOPNOTSUPP; @@ -385,7 +386,13 @@ ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) if (IS_ERR(skb)) return PTR_ERR(skb); - ret = ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->mgmt_tx_cmdid); + if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF, + ar->running_fw->fw_file.fw_features)) + mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_send_cmdid; + else + mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_cmdid; + + ret = ath10k_wmi_cmd_send(ar, skb, mgmt_tx_cmdid); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 7616c1c4bbd3..8d53063bd503 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -917,33 +917,69 @@ ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len, return -ENOMEM; } +struct wmi_tlv_svc_rdy_parse { + const struct hal_reg_capabilities *reg; + const struct wmi_tlv_svc_rdy_ev *ev; + const __le32 *svc_bmap; + const struct wlan_host_mem_req *mem_reqs; + bool svc_bmap_done; + bool dbs_hw_mode_done; +}; + +static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len, + const void *ptr, void *data) +{ + struct wmi_tlv_svc_rdy_parse *svc_rdy = data; + + switch (tag) { + case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT: + svc_rdy->ev = ptr; + break; + case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES: + svc_rdy->reg = ptr; + break; + case WMI_TLV_TAG_ARRAY_STRUCT: + svc_rdy->mem_reqs = ptr; + break; + case WMI_TLV_TAG_ARRAY_UINT32: + if (!svc_rdy->svc_bmap_done) { + svc_rdy->svc_bmap_done = true; + svc_rdy->svc_bmap = ptr; + } else if (!svc_rdy->dbs_hw_mode_done) { + svc_rdy->dbs_hw_mode_done = true; + } + break; + default: + break; + } + return 0; +} + static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb, struct wmi_svc_rdy_ev_arg *arg) { - const void **tb; const struct hal_reg_capabilities *reg; const struct wmi_tlv_svc_rdy_ev *ev; const __le32 *svc_bmap; const struct wlan_host_mem_req *mem_reqs; + struct wmi_tlv_svc_rdy_parse svc_rdy = { }; int ret; - tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); - if (IS_ERR(tb)) { - ret = PTR_ERR(tb); + ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, + ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy); + if (ret) { ath10k_warn(ar, "failed to parse tlv: %d\n", ret); return ret; } - ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]; - reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]; - svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32]; - mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT]; + ev = svc_rdy.ev; + reg = svc_rdy.reg; + svc_bmap = svc_rdy.svc_bmap; + mem_reqs = svc_rdy.mem_reqs; - if (!ev || !reg || !svc_bmap || !mem_reqs) { - kfree(tb); + if (!ev || !reg || !svc_bmap || !mem_reqs) return -EPROTO; - } /* This is an internal ABI compatibility check for WMI TLV so check it * here instead of the generic WMI code. @@ -961,7 +997,6 @@ static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar, __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 || __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 || __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) { - kfree(tb); return -ENOTSUPP; } @@ -982,12 +1017,10 @@ static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar, ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs), ath10k_wmi_tlv_parse_mem_reqs, arg); if (ret) { - kfree(tb); ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret); return ret; } - kfree(tb); return 0; } @@ -1406,7 +1439,10 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); - cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS); + + cfg->num_peers = __cpu_to_le32(ar->hw_params.num_peers); + cfg->ast_skid_limit = __cpu_to_le32(ar->hw_params.ast_skid_limit); + cfg->num_wds_entries = __cpu_to_le32(ar->hw_params.num_wds_entries); if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) { cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); @@ -1418,7 +1454,6 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) cfg->num_peer_keys = __cpu_to_le32(2); cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS); - cfg->ast_skid_limit = __cpu_to_le32(0x10); cfg->tx_chain_mask = __cpu_to_le32(0x7); cfg->rx_chain_mask = __cpu_to_le32(0x7); cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64); @@ -1434,7 +1469,6 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) cfg->num_mcast_table_elems = __cpu_to_le32(0); cfg->mcast2ucast_mode = __cpu_to_le32(0); cfg->tx_dbg_log_size = __cpu_to_le32(0x400); - cfg->num_wds_entries = __cpu_to_le32(0x20); cfg->dma_burst_size = __cpu_to_le32(0); cfg->mac_aggr_delim = __cpu_to_le32(0); cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0); @@ -2450,6 +2484,82 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask) } static struct sk_buff * +ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) +{ + struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); + struct wmi_tlv_mgmt_tx_cmd *cmd; + struct wmi_tlv *tlv; + struct ieee80211_hdr *hdr; + struct sk_buff *skb; + void *ptr; + int len; + u32 buf_len = msdu->len; + u16 fc; + struct ath10k_vif *arvif; + dma_addr_t mgmt_frame_dma; + u32 vdev_id; + + if (!cb->vif) + return ERR_PTR(-EINVAL); + + hdr = (struct ieee80211_hdr *)msdu->data; + fc = le16_to_cpu(hdr->frame_control); + arvif = (void *)cb->vif->drv_priv; + vdev_id = arvif->vdev_id; + + if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) + return ERR_PTR(-EINVAL); + + len = sizeof(*cmd) + 2 * sizeof(*tlv); + + if ((ieee80211_is_action(hdr->frame_control) || + ieee80211_is_deauth(hdr->frame_control) || + ieee80211_is_disassoc(hdr->frame_control)) && + ieee80211_has_protected(hdr->frame_control)) { + len += IEEE80211_CCMP_MIC_LEN; + buf_len += IEEE80211_CCMP_MIC_LEN; + } + + buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN); + buf_len = round_up(buf_len, 4); + + len += buf_len; + len = round_up(len, 4); + skb = ath10k_wmi_alloc_skb(ar, len); + if (!skb) + return ERR_PTR(-ENOMEM); + + ptr = (void *)skb->data; + tlv = ptr; + tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD); + tlv->len = __cpu_to_le16(sizeof(*cmd)); + cmd = (void *)tlv->value; + cmd->vdev_id = __cpu_to_le32(vdev_id); + cmd->desc_id = 0; + cmd->chanfreq = 0; + cmd->buf_len = __cpu_to_le32(buf_len); + cmd->frame_len = __cpu_to_le32(msdu->len); + mgmt_frame_dma = dma_map_single(arvif->ar->dev, msdu->data, + msdu->len, DMA_TO_DEVICE); + if (!mgmt_frame_dma) + return ERR_PTR(-ENOMEM); + + cmd->paddr = __cpu_to_le64(mgmt_frame_dma); + + ptr += sizeof(*tlv); + ptr += sizeof(*cmd); + + tlv = ptr; + tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); + tlv->len = __cpu_to_le16(buf_len); + + ptr += sizeof(*tlv); + memcpy(ptr, msdu->data, buf_len); + + return skb; +} + +static struct sk_buff * ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar, enum wmi_force_fw_hang_type type, u32 delay_ms) @@ -3258,6 +3368,7 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = { .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID, .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID, .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID, + .mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD, .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID, .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID, .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID, @@ -3592,6 +3703,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, /* .gen_mgmt_tx = not implemented; HTT is used */ + .gen_mgmt_tx = ath10k_wmi_tlv_op_gen_mgmt_tx, .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index 22cf011e839a..4faaa64a40d5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -22,6 +22,7 @@ #define WMI_TLV_CMD_UNSUPPORTED 0 #define WMI_TLV_PDEV_PARAM_UNSUPPORTED 0 #define WMI_TLV_VDEV_PARAM_UNSUPPORTED 0 +#define WMI_TLV_MGMT_TX_FRAME_MAX_LEN 64 enum wmi_tlv_grp_id { WMI_TLV_GRP_START = 0x3, @@ -132,6 +133,7 @@ enum wmi_tlv_cmd_id { WMI_TLV_PRB_REQ_FILTER_RX_CMDID, WMI_TLV_MGMT_TX_CMDID, WMI_TLV_PRB_TMPL_CMDID, + WMI_TLV_MGMT_TX_SEND_CMD, WMI_TLV_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_BA_NEG), WMI_TLV_ADDBA_SEND_CMDID, WMI_TLV_ADDBA_STATUS_CMDID, @@ -890,6 +892,63 @@ enum wmi_tlv_tag { WMI_TLV_TAG_STRUCT_SAP_OFL_DEL_STA_EVENT, WMI_TLV_TAG_STRUCT_APFIND_CMD_PARAM, WMI_TLV_TAG_STRUCT_APFIND_EVENT_HDR, + WMI_TLV_TAG_STRUCT_OCB_SET_SCHED_CMD, + WMI_TLV_TAG_STRUCT_OCB_SET_SCHED_EVENT, + WMI_TLV_TAG_STRUCT_OCB_SET_CONFIG_CMD, + WMI_TLV_TAG_STRUCT_OCB_SET_CONFIG_RESP_EVENT, + WMI_TLV_TAG_STRUCT_OCB_SET_UTC_TIME_CMD, + WMI_TLV_TAG_STRUCT_OCB_START_TIMING_ADVERT_CMD, + WMI_TLV_TAG_STRUCT_OCB_STOP_TIMING_ADVERT_CMD, + WMI_TLV_TAG_STRUCT_OCB_GET_TSF_TIMER_CMD, + WMI_TLV_TAG_STRUCT_OCB_GET_TSF_TIMER_RESP_EVENT, + WMI_TLV_TAG_STRUCT_DCC_GET_STATS_CMD, + WMI_TLV_TAG_STRUCT_DCC_CHANNEL_STATS_REQUEST, + WMI_TLV_TAG_STRUCT_DCC_GET_STATS_RESP_EVENT, + WMI_TLV_TAG_STRUCT_DCC_CLEAR_STATS_CMD, + WMI_TLV_TAG_STRUCT_DCC_UPDATE_NDL_CMD, + WMI_TLV_TAG_STRUCT_DCC_UPDATE_NDL_RESP_EVENT, + WMI_TLV_TAG_STRUCT_DCC_STATS_EVENT, + WMI_TLV_TAG_STRUCT_OCB_CHANNEL, + WMI_TLV_TAG_STRUCT_OCB_SCHEDULE_ELEMENT, + WMI_TLV_TAG_STRUCT_DCC_NDL_STATS_PER_CHANNEL, + WMI_TLV_TAG_STRUCT_DCC_NDL_CHAN, + WMI_TLV_TAG_STRUCT_QOS_PARAMETER, + WMI_TLV_TAG_STRUCT_DCC_NDL_ACTIVE_STATE_CONFIG, + WMI_TLV_TAG_STRUCT_ROAM_SCAN_EXTENDED_THRESHOLD_PARAM, + WMI_TLV_TAG_STRUCT_ROAM_FILTER_FIXED_PARAM, + WMI_TLV_TAG_STRUCT_PASSPOINT_CONFIG_CMD, + WMI_TLV_TAG_STRUCT_PASSPOINT_EVENT_HDR, + WMI_TLV_TAG_STRUCT_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMD, + WMI_TLV_TAG_STRUCT_EXTSCAN_HOTLIST_SSID_MATCH_EVENT, + WMI_TLV_TAG_STRUCT_VDEV_TSF_TSTAMP_ACTION_CMD, + WMI_TLV_TAG_STRUCT_VDEV_TSF_REPORT_EVENT, + WMI_TLV_TAG_STRUCT_GET_FW_MEM_DUMP, + WMI_TLV_TAG_STRUCT_UPDATE_FW_MEM_DUMP, + WMI_TLV_TAG_STRUCT_FW_MEM_DUMP_PARAMS, + WMI_TLV_TAG_STRUCT_DEBUG_MESG_FLUSH, + WMI_TLV_TAG_STRUCT_DEBUG_MESG_FLUSH_COMPLETE, + WMI_TLV_TAG_STRUCT_PEER_SET_RATE_REPORT_CONDITION, + WMI_TLV_TAG_STRUCT_ROAM_SUBNET_CHANGE_CONFIG, + WMI_TLV_TAG_STRUCT_VDEV_SET_IE_CMD, + WMI_TLV_TAG_STRUCT_RSSI_BREACH_MONITOR_CONFIG, + WMI_TLV_TAG_STRUCT_RSSI_BREACH_EVENT, + WMI_TLV_TAG_STRUCT_EVENT_INITIAL_WAKEUP, + WMI_TLV_TAG_STRUCT_SOC_SET_PCL_CMD, + WMI_TLV_TAG_STRUCT_SOC_SET_HW_MODE_CMD, + WMI_TLV_TAG_STRUCT_SOC_SET_HW_MODE_RESPONSE_EVENT, + WMI_TLV_TAG_STRUCT_SOC_HW_MODE_TRANSITION_EVENT, + WMI_TLV_TAG_STRUCT_VDEV_TXRX_STREAMS, + WMI_TLV_TAG_STRUCT_SOC_SET_HW_MODE_RESPONSE_VDEV_MAC_ENTRY, + WMI_TLV_TAG_STRUCT_SOC_SET_DUAL_MAC_CONFIG_CMD, + WMI_TLV_TAG_STRUCT_SOC_SET_DUAL_MAC_CONFIG_RESPONSE_EVENT, + WMI_TLV_TAG_STRUCT_IOAC_SOCK_PATTERN_T, + WMI_TLV_TAG_STRUCT_WOW_ENABLE_ICMPV6_NA_FLT_CMD, + WMI_TLV_TAG_STRUCT_DIAG_EVENT_LOG_CONFIG, + WMI_TLV_TAG_STRUCT_DIAG_EVENT_LOG_SUPPORTED_EVENT, + WMI_TLV_TAG_STRUCT_PACKET_FILTER_CONFIG, + WMI_TLV_TAG_STRUCT_PACKET_FILTER_ENABLE, + WMI_TLV_TAG_STRUCT_SAP_SET_BLACKLIST_PARAM_CMD, + WMI_TLV_TAG_STRUCT_MGMT_TX_CMD, WMI_TLV_TAG_MAX }; @@ -965,6 +1024,50 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, WMI_TLV_SERVICE_MDNS_OFFLOAD, WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD, + WMI_TLV_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT, + WMI_TLV_SERVICE_OCB, + WMI_TLV_SERVICE_AP_ARPNS_OFFLOAD, + WMI_TLV_SERVICE_PER_BAND_CHAINMASK_SUPPORT, + WMI_TLV_SERVICE_PACKET_FILTER_OFFLOAD, + WMI_TLV_SERVICE_MGMT_TX_HTT, + WMI_TLV_SERVICE_MGMT_TX_WMI, + WMI_TLV_SERVICE_EXT_MSG, + WMI_TLV_SERVICE_MAWC, + WMI_TLV_SERVICE_PEER_ASSOC_CONF, + WMI_TLV_SERVICE_EGAP, + WMI_TLV_SERVICE_STA_PMF_OFFLOAD, + WMI_TLV_SERVICE_UNIFIED_WOW_CAPABILITY, + WMI_TLV_SERVICE_ENHANCED_PROXY_STA, + WMI_TLV_SERVICE_ATF, + WMI_TLV_SERVICE_COEX_GPIO, + WMI_TLV_SERVICE_AUX_SPECTRAL_INTF, + WMI_TLV_SERVICE_AUX_CHAN_LOAD_INTF, + WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64, + WMI_TLV_SERVICE_ENTERPRISE_MESH, + WMI_TLV_SERVICE_RESTRT_CHNL_SUPPORT, + WMI_TLV_SERVICE_BPF_OFFLOAD, + WMI_TLV_SERVICE_SYNC_DELETE_CMDS, + WMI_TLV_SERVICE_SMART_ANTENNA_SW_SUPPORT, + WMI_TLV_SERVICE_SMART_ANTENNA_HW_SUPPORT, + WMI_TLV_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES, + WMI_TLV_SERVICE_NAN_DATA, + WMI_TLV_SERVICE_NAN_RTT, + WMI_TLV_SERVICE_11AX, + WMI_TLV_SERVICE_DEPRECATED_REPLACE, + WMI_TLV_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, + WMI_TLV_SERVICE_ENHANCED_MCAST_FILTER, + WMI_TLV_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, + WMI_TLV_SERVICE_MESH_11S, + WMI_TLV_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT, + WMI_TLV_SERVICE_VDEV_RX_FILTER, + WMI_TLV_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT, + WMI_TLV_SERVICE_MARK_FIRST_WAKEUP_PACKET, + WMI_TLV_SERVICE_MULTIPLE_MCAST_FILTER_SET, + WMI_TLV_SERVICE_HOST_MANAGED_RX_REORDER, + WMI_TLV_SERVICE_FLASH_RDWR_SUPPORT, + WMI_TLV_SERVICE_WLAN_STATS_REPORT, + WMI_TLV_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT, + WMI_TLV_SERVICE_DFS_PHYERR_OFFLOAD, }; #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \ @@ -1121,6 +1224,8 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len) WMI_SERVICE_MDNS_OFFLOAD, len); SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD, WMI_SERVICE_SAP_AUTH_OFFLOAD, len); + SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI, + WMI_SERVICE_MGMT_TX_WMI, len); } #undef SVCMAP @@ -1643,4 +1748,12 @@ struct wmi_tlv_tx_pause_ev { void ath10k_wmi_tlv_attach(struct ath10k *ar); +struct wmi_tlv_mgmt_tx_cmd { + __le32 vdev_id; + __le32 desc_id; + __le32 chanfreq; + __le64 paddr; + __le32 frame_len; + __le32 buf_len; +} __packed; #endif diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index cad2e42dcef6..b6cbc0281fe1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -29,6 +29,7 @@ #include "p2p.h" #include "hw.h" #include "hif.h" +#include "txrx.h" #define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9 #define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ) @@ -4456,6 +4457,74 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) __le32_to_cpu(ev->rate_max)); } +static void +ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb) +{ + struct wmi_tdls_peer_event *ev; + struct ath10k_peer *peer; + struct ath10k_vif *arvif; + int vdev_id; + int peer_status; + int peer_reason; + u8 reason; + + if (skb->len < sizeof(*ev)) { + ath10k_err(ar, "received tdls peer event with invalid size (%d bytes)\n", + skb->len); + return; + } + + ev = (struct wmi_tdls_peer_event *)skb->data; + vdev_id = __le32_to_cpu(ev->vdev_id); + peer_status = __le32_to_cpu(ev->peer_status); + peer_reason = __le32_to_cpu(ev->peer_reason); + + spin_lock_bh(&ar->data_lock); + peer = ath10k_peer_find(ar, vdev_id, ev->peer_macaddr.addr); + spin_unlock_bh(&ar->data_lock); + + if (!peer) { + ath10k_warn(ar, "failed to find peer entry for %pM\n", + ev->peer_macaddr.addr); + return; + } + + switch (peer_status) { + case WMI_TDLS_SHOULD_TEARDOWN: + switch (peer_reason) { + case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: + case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: + case WMI_TDLS_TEARDOWN_REASON_RSSI: + reason = WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE; + break; + default: + reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; + break; + } + + arvif = ath10k_get_arvif(ar, vdev_id); + if (!arvif) { + ath10k_warn(ar, "received tdls peer event for invalid vdev id %u\n", + vdev_id); + return; + } + + ieee80211_tdls_oper_request(arvif->vif, ev->peer_macaddr.addr, + NL80211_TDLS_TEARDOWN, reason, + GFP_ATOMIC); + + ath10k_dbg(ar, ATH10K_DBG_WMI, + "received tdls teardown event for peer %pM reason %u\n", + ev->peer_macaddr.addr, peer_reason); + break; + default: + ath10k_dbg(ar, ATH10K_DBG_WMI, + "received unknown tdls peer event %u\n", + peer_status); + break; + } +} + void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb) { ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); @@ -5477,6 +5546,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_10_4_PDEV_TPC_CONFIG_EVENTID: ath10k_wmi_event_pdev_tpc_config(ar, skb); break; + case WMI_10_4_TDLS_PEER_EVENTID: + ath10k_wmi_handle_tdls_peer_event(ar, skb); + break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index c02b21cff38d..f6d60dc16d1c 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -195,6 +195,7 @@ enum wmi_service { WMI_SERVICE_SMART_LOGGING_SUPPORT, WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, + WMI_SERVICE_MGMT_TX_WMI, /* keep last */ WMI_SERVICE_MAX, @@ -797,6 +798,7 @@ struct wmi_cmd_map { u32 bcn_filter_rx_cmdid; u32 prb_req_filter_rx_cmdid; u32 mgmt_tx_cmdid; + u32 mgmt_tx_send_cmdid; u32 prb_tmpl_cmdid; u32 addba_clear_resp_cmdid; u32 addba_send_cmdid; @@ -5236,7 +5238,8 @@ enum wmi_10_4_vdev_param { #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3) #define WMI_TXBF_STS_CAP_OFFSET_LSB 4 -#define WMI_TXBF_STS_CAP_OFFSET_MASK 0xf0 +#define WMI_TXBF_STS_CAP_OFFSET_MASK 0x70 +#define WMI_TXBF_CONF_IMPLICIT_BF BIT(7) #define WMI_BF_SOUND_DIM_OFFSET_LSB 8 #define WMI_BF_SOUND_DIM_OFFSET_MASK 0xf00 diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index b53eb2b85f02..2ba8cf3f38af 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2766,7 +2766,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_mgmt *mgmt; bool hidden = false; u8 *ies; - int ies_len; struct wmi_connect_cmd p; int res; int i, ret; @@ -2804,7 +2803,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, ies = mgmt->u.beacon.variable; if (ies > info->beacon.head + info->beacon.head_len) return -EINVAL; - ies_len = info->beacon.head + info->beacon.head_len - ies; if (info->ssid == NULL) return -EINVAL; diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 1379906bf849..8da9506f8c2b 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1001,7 +1001,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr, while (amsdu_len > mac_hdr_len) { hdr = (struct ethhdr *) framep; - payload_8023_len = ntohs(hdr->h_proto); + payload_8023_len = be16_to_cpu(hdr->h_proto); if (payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) { diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 783a38f1a626..1f3523019509 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -61,13 +61,12 @@ config ATH9K_DEBUGFS depends on ATH9K && DEBUG_FS select MAC80211_DEBUGFS select ATH9K_COMMON_DEBUG - select RELAY ---help--- Say Y, if you need access to ath9k's statistics for interrupts, rate control, etc. - Also required for changing debug message flags at run time. - As well as access to the FFT/spectral data and TX99. + Also required for changing debug message flags at run time and for + TX99. config ATH9K_STATION_STATISTICS bool "Detailed station statistics" @@ -177,7 +176,6 @@ config ATH9K_HTC_DEBUGFS bool "Atheros ath9k_htc debugging" depends on ATH9K_HTC && DEBUG_FS select ATH9K_COMMON_DEBUG - select RELAY ---help--- Say Y, if you need access to ath9k_htc's statistics. As well as access to the FFT/spectral data. @@ -192,3 +190,11 @@ config ATH9K_HWRNG Say Y, feeds the entropy directly from the WiFi driver to the input pool. + +config ATH9K_COMMON_SPECTRAL + bool "Atheros ath9k/ath9k_htc spectral scan support" + depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS + select RELAY + default n + ---help--- + Say Y to enable access to the FFT/spectral data via debugfs. diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index d804ce7391a0..f71b2ad8275c 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -62,8 +62,8 @@ ath9k_common-y:= common.o \ common-init.o \ common-beacon.o \ -ath9k_common-$(CONFIG_ATH9K_COMMON_DEBUG) += common-debug.o \ - common-spectral.o +ath9k_common-$(CONFIG_ATH9K_COMMON_DEBUG) += common-debug.o +ath9k_common-$(CONFIG_ATH9K_COMMON_SPECTRAL) += common-spectral.o ath9k_htc-y += htc_hst.o \ hif_usb.o \ diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.h b/drivers/net/wireless/ath/ath9k/common-spectral.h index 5d1a51d83aa6..303ab470ce34 100644 --- a/drivers/net/wireless/ath/ath9k/common-spectral.h +++ b/drivers/net/wireless/ath/ath9k/common-spectral.h @@ -151,7 +151,7 @@ static inline u8 spectral_bitmap_weight(u8 *bins) return bins[0] & 0x3f; } -#ifdef CONFIG_ATH9K_COMMON_DEBUG +#ifdef CONFIG_ATH9K_COMMON_SPECTRAL void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); @@ -183,6 +183,6 @@ static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, { return 0; } -#endif /* CONFIG_ATH9K_COMMON_DEBUG */ +#endif /* CONFIG_ATH9K_COMMON_SPECTRAL */ #endif /* SPECTRAL_H */ diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c index 40a397fd0e0e..6fee9a464cce 100644 --- a/drivers/net/wireless/ath/ath9k/dfs.c +++ b/drivers/net/wireless/ath/ath9k/dfs.c @@ -123,11 +123,9 @@ static bool ath9k_check_chirping(struct ath_softc *sc, u8 *data, fft = (struct ath9k_dfs_fft_40 *) (data + 2); ath_dbg(common, DFS, "fixing datalen by 2\n"); } - if (IS_CHAN_HT40MINUS(ah->curchan)) { - int temp = is_ctl; - is_ctl = is_ext; - is_ext = temp; - } + if (IS_CHAN_HT40MINUS(ah->curchan)) + swap(is_ctl, is_ext); + for (i = 0; i < FFT_NUM_SAMPLES; i++) max_bin[i] = ath9k_get_max_index_ht40(fft + i, is_ctl, is_ext); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f808e5833d7e..a82ad739ab80 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1683,6 +1683,10 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: + if (tid >= ATH9K_HTC_MAX_TID) { + ret = -EINVAL; + break; + } ista = (struct ath9k_htc_sta *) sta->drv_priv; spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = AGGR_OPERATIONAL; diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index b765c647319d..182963522941 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -348,6 +348,13 @@ enum wcn36xx_hal_host_msg_type { WCN36XX_HAL_DHCP_START_IND = 189, WCN36XX_HAL_DHCP_STOP_IND = 190, + /* Scan Offload(hw) APIs */ + WCN36XX_HAL_START_SCAN_OFFLOAD_REQ = 204, + WCN36XX_HAL_START_SCAN_OFFLOAD_RSP = 205, + WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ = 206, + WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP = 207, + WCN36XX_HAL_SCAN_OFFLOAD_IND = 210, + WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233, WCN36XX_HAL_PRINT_REG_INFO_IND = 259, @@ -1115,6 +1122,101 @@ struct wcn36xx_hal_finish_scan_rsp_msg { } __packed; +enum wcn36xx_hal_scan_type { + WCN36XX_HAL_SCAN_TYPE_PASSIVE = 0x00, + WCN36XX_HAL_SCAN_TYPE_ACTIVE = WCN36XX_HAL_MAX_ENUM_SIZE +}; + +struct wcn36xx_hal_mac_ssid { + u8 length; + u8 ssid[32]; +} __packed; + +struct wcn36xx_hal_start_scan_offload_req_msg { + struct wcn36xx_hal_msg_header header; + + /* BSSIDs hot list */ + u8 num_bssid; + u8 bssids[4][ETH_ALEN]; + + /* Directed probe-requests will be sent for listed SSIDs (max 10)*/ + u8 num_ssid; + struct wcn36xx_hal_mac_ssid ssids[10]; + + /* Report AP with hidden ssid */ + u8 scan_hidden; + + /* Self MAC address */ + u8 mac[ETH_ALEN]; + + /* BSS type */ + enum wcn36xx_hal_bss_type bss_type; + + /* Scan type */ + enum wcn36xx_hal_scan_type scan_type; + + /* Minimum scanning time on each channel (ms) */ + u32 min_ch_time; + + /* Maximum scanning time on each channel */ + u32 max_ch_time; + + /* Is a p2p search */ + u8 p2p_search; + + /* Channels to scan */ + u8 num_channel; + u8 channels[80]; + + /* IE field */ + u16 ie_len; + u8 ie[0]; +} __packed; + +struct wcn36xx_hal_start_scan_offload_rsp_msg { + struct wcn36xx_hal_msg_header header; + + /* success or failure */ + u32 status; +} __packed; + +enum wcn36xx_hal_scan_offload_ind_type { + /* Scan has been started */ + WCN36XX_HAL_SCAN_IND_STARTED = 0x01, + /* Scan has been completed */ + WCN36XX_HAL_SCAN_IND_COMPLETED = 0x02, + /* Moved to foreign channel */ + WCN36XX_HAL_SCAN_IND_FOREIGN_CHANNEL = 0x08, + /* scan request has been dequeued */ + WCN36XX_HAL_SCAN_IND_DEQUEUED = 0x10, + /* preempted by other high priority scan */ + WCN36XX_HAL_SCAN_IND_PREEMPTED = 0x20, + /* scan start failed */ + WCN36XX_HAL_SCAN_IND_FAILED = 0x40, + /*scan restarted */ + WCN36XX_HAL_SCAN_IND_RESTARTED = 0x80, + WCN36XX_HAL_SCAN_IND_MAX = WCN36XX_HAL_MAX_ENUM_SIZE +}; + +struct wcn36xx_hal_scan_offload_ind { + struct wcn36xx_hal_msg_header header; + + u32 type; + u32 channel_mhz; + u32 scan_id; +} __packed; + +struct wcn36xx_hal_stop_scan_offload_req_msg { + struct wcn36xx_hal_msg_header header; +} __packed; + +struct wcn36xx_hal_stop_scan_offload_rsp_msg { + struct wcn36xx_hal_msg_header header; + + /* success or failure */ + u32 status; +} __packed; + enum wcn36xx_hal_rate_index { HW_RATE_INDEX_1MBPS = 0x82, HW_RATE_INDEX_2MBPS = 0x84, @@ -1507,11 +1609,6 @@ struct wcn36xx_hal_edca_param_record { u16 txop_limit; } __packed; -struct wcn36xx_hal_mac_ssid { - u8 length; - u8 ssid[32]; -} __packed; - /* Concurrency role. These are generic IDs that identify the various roles * in the software system. */ enum wcn36xx_hal_con_mode { diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index f7d228b5ba93..5bed323f1100 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -629,7 +629,6 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_scan_request *hw_req) { struct wcn36xx *wcn = hw->priv; - mutex_lock(&wcn->scan_lock); if (wcn->scan_req) { mutex_unlock(&wcn->scan_lock); @@ -638,11 +637,16 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw, wcn->scan_aborted = false; wcn->scan_req = &hw_req->req; + mutex_unlock(&wcn->scan_lock); - schedule_work(&wcn->scan_work); + if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { + /* legacy manual/sw scan */ + schedule_work(&wcn->scan_work); + return 0; + } - return 0; + return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req); } static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw, @@ -650,6 +654,12 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw, { struct wcn36xx *wcn = hw->priv; + if (!wcn36xx_smd_stop_hw_scan(wcn)) { + struct cfg80211_scan_info scan_info = { .aborted = true }; + + ieee80211_scan_completed(wcn->hw, &scan_info); + } + mutex_lock(&wcn->scan_lock); wcn->scan_aborted = true; mutex_unlock(&wcn->scan_lock); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 9c6590d5348a..2914618a0335 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -73,6 +73,8 @@ static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = { WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1), WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1), WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0), + WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 120000), + WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 30000), WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10), WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0), }; @@ -613,6 +615,85 @@ out: return ret; } +int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, + struct cfg80211_scan_request *req) +{ + struct wcn36xx_hal_start_scan_offload_req_msg msg_body; + int ret, i; + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_OFFLOAD_REQ); + + msg_body.scan_type = WCN36XX_HAL_SCAN_TYPE_ACTIVE; + msg_body.min_ch_time = 30; + msg_body.min_ch_time = 100; + msg_body.scan_hidden = 1; + memcpy(msg_body.mac, vif->addr, ETH_ALEN); + msg_body.p2p_search = vif->p2p; + + msg_body.num_ssid = min_t(u8, req->n_ssids, ARRAY_SIZE(msg_body.ssids)); + for (i = 0; i < msg_body.num_ssid; i++) { + msg_body.ssids[i].length = min_t(u8, req->ssids[i].ssid_len, + sizeof(msg_body.ssids[i].ssid)); + memcpy(msg_body.ssids[i].ssid, req->ssids[i].ssid, + msg_body.ssids[i].length); + } + + msg_body.num_channel = min_t(u8, req->n_channels, + sizeof(msg_body.channels)); + for (i = 0; i < msg_body.num_channel; i++) + msg_body.channels[i] = req->channels[i]->hw_value; + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + wcn36xx_dbg(WCN36XX_DBG_HAL, + "hal start hw-scan (channels: %u; ssids: %u; p2p: %s)\n", + msg_body.num_channel, msg_body.num_ssid, + msg_body.p2p_search ? "yes" : "no"); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("Sending hal_start_scan_offload failed\n"); + goto out; + } + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_start_scan_offload response failed err=%d\n", + ret); + goto out; + } +out: + mutex_unlock(&wcn->hal_mutex); + return ret; +} + +int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn) +{ + struct wcn36xx_hal_stop_scan_offload_req_msg msg_body; + int ret; + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ); + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + wcn36xx_dbg(WCN36XX_DBG_HAL, "hal stop hw-scan\n"); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("Sending hal_stop_scan_offload failed\n"); + goto out; + } + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_stop_scan_offload response failed err=%d\n", + ret); + goto out; + } +out: + mutex_unlock(&wcn->hal_mutex); + return ret; +} + static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len) { struct wcn36xx_hal_switch_channel_rsp_msg *rsp; @@ -2039,6 +2120,40 @@ static int wcn36xx_smd_tx_compl_ind(struct wcn36xx *wcn, void *buf, size_t len) return 0; } +static int wcn36xx_smd_hw_scan_ind(struct wcn36xx *wcn, void *buf, size_t len) +{ + struct wcn36xx_hal_scan_offload_ind *rsp = buf; + struct cfg80211_scan_info scan_info = {}; + + if (len != sizeof(*rsp)) { + wcn36xx_warn("Corrupted delete scan indication\n"); + return -EIO; + } + + wcn36xx_dbg(WCN36XX_DBG_HAL, "scan indication (type %x)", rsp->type); + + switch (rsp->type) { + case WCN36XX_HAL_SCAN_IND_FAILED: + scan_info.aborted = true; + case WCN36XX_HAL_SCAN_IND_COMPLETED: + mutex_lock(&wcn->scan_lock); + wcn->scan_req = NULL; + mutex_unlock(&wcn->scan_lock); + ieee80211_scan_completed(wcn->hw, &scan_info); + break; + case WCN36XX_HAL_SCAN_IND_STARTED: + case WCN36XX_HAL_SCAN_IND_FOREIGN_CHANNEL: + case WCN36XX_HAL_SCAN_IND_DEQUEUED: + case WCN36XX_HAL_SCAN_IND_PREEMPTED: + case WCN36XX_HAL_SCAN_IND_RESTARTED: + break; + default: + wcn36xx_warn("Unknown scan indication type %x\n", rsp->type); + } + + return 0; +} + static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn, void *buf, size_t len) @@ -2250,6 +2365,8 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_CH_SWITCH_RSP: case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP: case WCN36XX_HAL_8023_MULTICAST_LIST_RSP: + case WCN36XX_HAL_START_SCAN_OFFLOAD_RSP: + case WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP: memcpy(wcn->hal_buf, buf, len); wcn->hal_rsp_len = len; complete(&wcn->hal_rsp_compl); @@ -2262,6 +2379,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_MISSED_BEACON_IND: case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: case WCN36XX_HAL_PRINT_REG_INFO_IND: + case WCN36XX_HAL_SCAN_OFFLOAD_IND: msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_ATOMIC); if (!msg_ind) { wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n", @@ -2298,6 +2416,8 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, struct wcn36xx_hal_ind_msg, list); + list_del(wcn->hal_ind_queue.next); + spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; @@ -2326,12 +2446,14 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) hal_ind_msg->msg, hal_ind_msg->msg_len); break; + case WCN36XX_HAL_SCAN_OFFLOAD_IND: + wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg, + hal_ind_msg->msg_len); + break; default: wcn36xx_err("SMD_EVENT (%d) not supported\n", msg_header->msg_type); } - list_del(wcn->hal_ind_queue.next); - spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); kfree(hal_ind_msg); } int wcn36xx_smd_open(struct wcn36xx *wcn) diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 013fc9546f56..8076edf40ac8 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -65,6 +65,9 @@ int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel); int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode); int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count); +int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, + struct cfg80211_scan_request *req); +int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn); int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index); diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 85d5c04618eb..771a534d6ca9 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -901,7 +901,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, u64 *cookie) { const u8 *buf = params->buf; - size_t len = params->len; + size_t len = params->len, total; struct wil6210_priv *wil = wiphy_to_wil(wiphy); int rc; bool tx_status = false; @@ -926,7 +926,11 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, if (len < sizeof(struct ieee80211_hdr_3addr)) return -EINVAL; - cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL); + total = sizeof(*cmd) + len; + if (total < len) + return -EINVAL; + + cmd = kmalloc(total, GFP_KERNEL); if (!cmd) { rc = -ENOMEM; goto out; @@ -936,7 +940,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, cmd->len = cpu_to_le16(len); memcpy(cmd->payload, buf, len); - rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len, + rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, total, WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); if (rc == 0) tx_status = !evt.evt.status; @@ -1727,9 +1731,12 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy, wil_dbg_pm(wil, "suspending\n"); - wil_p2p_stop_discovery(wil); - + mutex_lock(&wil->mutex); + mutex_lock(&wil->p2p_wdev_mutex); + wil_p2p_stop_radio_operations(wil); wil_abort_scan(wil, true); + mutex_unlock(&wil->p2p_wdev_mutex); + mutex_unlock(&wil->mutex); out: return rc; diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index e58dc6dc1f9c..4475937faf25 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -242,12 +242,19 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, static int wil_mbox_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; + int ret; + + ret = wil_pm_runtime_get(wil); + if (ret < 0) + return ret; wil_print_ring(s, "tx", wil->csr + HOST_MBOX + offsetof(struct wil6210_mbox_ctl, tx)); wil_print_ring(s, "rx", wil->csr + HOST_MBOX + offsetof(struct wil6210_mbox_ctl, rx)); + wil_pm_runtime_put(wil); + return 0; } @@ -265,15 +272,37 @@ static const struct file_operations fops_mbox = { static int wil_debugfs_iomem_x32_set(void *data, u64 val) { - writel(val, (void __iomem *)data); + struct wil_debugfs_iomem_data *d = (struct + wil_debugfs_iomem_data *)data; + struct wil6210_priv *wil = d->wil; + int ret; + + ret = wil_pm_runtime_get(wil); + if (ret < 0) + return ret; + + writel(val, (void __iomem *)d->offset); wmb(); /* make sure write propagated to HW */ + wil_pm_runtime_put(wil); + return 0; } static int wil_debugfs_iomem_x32_get(void *data, u64 *val) { - *val = readl((void __iomem *)data); + struct wil_debugfs_iomem_data *d = (struct + wil_debugfs_iomem_data *)data; + struct wil6210_priv *wil = d->wil; + int ret; + + ret = wil_pm_runtime_get(wil); + if (ret < 0) + return ret; + + *val = readl((void __iomem *)d->offset); + + wil_pm_runtime_put(wil); return 0; } @@ -284,10 +313,21 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, static struct dentry *wil_debugfs_create_iomem_x32(const char *name, umode_t mode, struct dentry *parent, - void *value) + void *value, + struct wil6210_priv *wil) { - return debugfs_create_file(name, mode, parent, value, - &fops_iomem_x32); + struct dentry *file; + struct wil_debugfs_iomem_data *data = &wil->dbg_data.data_arr[ + wil->dbg_data.iomem_data_count]; + + data->wil = wil; + data->offset = value; + + file = debugfs_create_file(name, mode, parent, data, &fops_iomem_x32); + if (!IS_ERR_OR_NULL(file)) + wil->dbg_data.iomem_data_count++; + + return file; } static int wil_debugfs_ulong_set(void *data, u64 val) @@ -346,7 +386,8 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil, case doff_io32: f = wil_debugfs_create_iomem_x32(tbl[i].name, tbl[i].mode, dbg, - base + tbl[i].off); + base + tbl[i].off, + wil); break; case doff_u8: f = debugfs_create_u8(tbl[i].name, tbl[i].mode, dbg, @@ -475,13 +516,22 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, static int wil_memread_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; - void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr)); + void __iomem *a; + int ret; + + ret = wil_pm_runtime_get(wil); + if (ret < 0) + return ret; + + a = wmi_buffer(wil, cpu_to_le32(mem_addr)); if (a) seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, readl(a)); else seq_printf(s, "[0x%08x] = INVALID\n", mem_addr); + wil_pm_runtime_put(wil); + return 0; } @@ -502,10 +552,12 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, { enum { max_count = 4096 }; struct wil_blob_wrapper *wil_blob = file->private_data; + struct wil6210_priv *wil = wil_blob->wil; loff_t pos = *ppos; size_t available = wil_blob->blob.size; void *buf; size_t ret; + int rc; if (test_bit(wil_status_suspending, wil_blob->wil->status) || test_bit(wil_status_suspended, wil_blob->wil->status)) @@ -526,10 +578,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; + rc = wil_pm_runtime_get(wil); + if (rc < 0) { + kfree(buf); + return rc; + } + wil_memcpy_fromio_32(buf, (const void __iomem *) wil_blob->blob.data + pos, count); ret = copy_to_user(user_buf, buf, count); + + wil_pm_runtime_put(wil); + kfree(buf); if (ret == count) return -EFAULT; @@ -1571,8 +1632,6 @@ static ssize_t wil_write_suspend_stats(struct file *file, struct wil6210_priv *wil = file->private_data; memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats)); - wil->suspend_stats.min_suspend_time = ULONG_MAX; - wil->suspend_stats.collection_start = ktime_get(); return len; } @@ -1582,33 +1641,41 @@ static ssize_t wil_read_suspend_stats(struct file *file, size_t count, loff_t *ppos) { struct wil6210_priv *wil = file->private_data; - static char text[400]; - int n; - unsigned long long stats_collection_time = - ktime_to_us(ktime_sub(ktime_get(), - wil->suspend_stats.collection_start)); + char *text; + int n, ret, text_size = 500; - n = snprintf(text, sizeof(text), - "Suspend statistics:\n" + text = kmalloc(text_size, GFP_KERNEL); + if (!text) + return -ENOMEM; + + n = snprintf(text, text_size, + "Radio on suspend statistics:\n" + "successful suspends:%ld failed suspends:%ld\n" + "successful resumes:%ld failed resumes:%ld\n" + "rejected by device:%ld\n" + "Radio off suspend statistics:\n" "successful suspends:%ld failed suspends:%ld\n" "successful resumes:%ld failed resumes:%ld\n" - "rejected by host:%ld rejected by device:%ld\n" - "total suspend time:%lld min suspend time:%lld\n" - "max suspend time:%lld stats collection time: %lld\n", - wil->suspend_stats.successful_suspends, - wil->suspend_stats.failed_suspends, - wil->suspend_stats.successful_resumes, - wil->suspend_stats.failed_resumes, - wil->suspend_stats.rejected_by_host, + "General statistics:\n" + "rejected by host:%ld\n", + wil->suspend_stats.r_on.successful_suspends, + wil->suspend_stats.r_on.failed_suspends, + wil->suspend_stats.r_on.successful_resumes, + wil->suspend_stats.r_on.failed_resumes, wil->suspend_stats.rejected_by_device, - wil->suspend_stats.total_suspend_time, - wil->suspend_stats.min_suspend_time, - wil->suspend_stats.max_suspend_time, - stats_collection_time); + wil->suspend_stats.r_off.successful_suspends, + wil->suspend_stats.r_off.failed_suspends, + wil->suspend_stats.r_off.successful_resumes, + wil->suspend_stats.r_off.failed_resumes, + wil->suspend_stats.rejected_by_host); + + n = min_t(int, n, text_size); - n = min_t(int, n, sizeof(text)); + ret = simple_read_from_buffer(user_buf, count, ppos, text, n); - return simple_read_from_buffer(user_buf, count, ppos, text, n); + kfree(text); + + return ret; } static const struct file_operations fops_suspend_stats = { @@ -1736,14 +1803,31 @@ static const struct dbg_off dbg_statics[] = { {}, }; +static const int dbg_off_count = 4 * (ARRAY_SIZE(isr_off) - 1) + + ARRAY_SIZE(dbg_wil_regs) - 1 + + ARRAY_SIZE(pseudo_isr_off) - 1 + + ARRAY_SIZE(lgc_itr_cnt_off) - 1 + + ARRAY_SIZE(tx_itr_cnt_off) - 1 + + ARRAY_SIZE(rx_itr_cnt_off) - 1; + int wil6210_debugfs_init(struct wil6210_priv *wil) { struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, wil_to_wiphy(wil)->debugfsdir); - if (IS_ERR_OR_NULL(dbg)) return -ENODEV; + wil->dbg_data.data_arr = kcalloc(dbg_off_count, + sizeof(struct wil_debugfs_iomem_data), + GFP_KERNEL); + if (!wil->dbg_data.data_arr) { + debugfs_remove_recursive(dbg); + wil->debug = NULL; + return -ENOMEM; + } + + wil->dbg_data.iomem_data_count = 0; + wil_pmc_init(wil); wil6210_debugfs_init_files(wil, dbg); @@ -1758,8 +1842,6 @@ int wil6210_debugfs_init(struct wil6210_priv *wil) wil6210_debugfs_create_ITR_CNT(wil, dbg); - wil->suspend_stats.collection_start = ktime_get(); - return 0; } @@ -1768,6 +1850,8 @@ void wil6210_debugfs_remove(struct wil6210_priv *wil) debugfs_remove_recursive(wil->debug); wil->debug = NULL; + kfree(wil->dbg_data.data_arr); + /* free pmc memory without sending command to fw, as it will * be reset on the way down anyway */ diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c index adcfef4dabf7..66200f616a37 100644 --- a/drivers/net/wireless/ath/wil6210/ethtool.c +++ b/drivers/net/wireless/ath/wil6210/ethtool.c @@ -47,9 +47,14 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, struct wil6210_priv *wil = ndev_to_wil(ndev); u32 tx_itr_en, tx_itr_val = 0; u32 rx_itr_en, rx_itr_val = 0; + int ret; wil_dbg_misc(wil, "ethtoolops_get_coalesce\n"); + ret = wil_pm_runtime_get(wil); + if (ret < 0) + return ret; + tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL); if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) tx_itr_val = wil_r(wil, RGF_DMA_ITR_TX_CNT_TRSH); @@ -58,6 +63,8 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) rx_itr_val = wil_r(wil, RGF_DMA_ITR_RX_CNT_TRSH); + wil_pm_runtime_put(wil); + cp->tx_coalesce_usecs = tx_itr_val; cp->rx_coalesce_usecs = rx_itr_val; return 0; @@ -67,6 +74,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *cp) { struct wil6210_priv *wil = ndev_to_wil(ndev); + int ret; wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); @@ -86,8 +94,15 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, wil->tx_max_burst_duration = cp->tx_coalesce_usecs; wil->rx_max_burst_duration = cp->rx_coalesce_usecs; + + ret = wil_pm_runtime_get(wil); + if (ret < 0) + return ret; + wil_configure_interrupt_moderation(wil); + wil_pm_runtime_put(wil); + return 0; out_bad: diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c index e01acac88825..77d1902947e3 100644 --- a/drivers/net/wireless/ath/wil6210/fw_inc.c +++ b/drivers/net/wireless/ath/wil6210/fw_inc.c @@ -26,14 +26,17 @@ prefix_type, rowsize, \ groupsize, buf, len, ascii) -#define FW_ADDR_CHECK(ioaddr, val, msg) do { \ - ioaddr = wmi_buffer(wil, val); \ - if (!ioaddr) { \ - wil_err_fw(wil, "bad " msg ": 0x%08x\n", \ - le32_to_cpu(val)); \ - return -EINVAL; \ - } \ - } while (0) +static bool wil_fw_addr_check(struct wil6210_priv *wil, + void __iomem **ioaddr, __le32 val, + u32 size, const char *msg) +{ + *ioaddr = wmi_buffer_block(wil, val, size); + if (!(*ioaddr)) { + wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val)); + return false; + } + return true; +} /** * wil_fw_verify - verify firmware file validity @@ -124,24 +127,19 @@ static int fw_ignore_section(struct wil6210_priv *wil, const void *data, return 0; } -static int fw_handle_comment(struct wil6210_priv *wil, const void *data, - size_t size) -{ - wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); - - return 0; -} - static int -fw_handle_capabilities(struct wil6210_priv *wil, const void *data, - size_t size) +fw_handle_comment(struct wil6210_priv *wil, const void *data, + size_t size) { const struct wil_fw_record_capabilities *rec = data; size_t capa_size; if (size < sizeof(*rec) || - le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) + le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) { + wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, + data, size, true); return 0; + } capa_size = size - offsetof(struct wil_fw_record_capabilities, capabilities); @@ -165,7 +163,8 @@ static int fw_handle_data(struct wil6210_priv *wil, const void *data, return -EINVAL; } - FW_ADDR_CHECK(dst, d->addr, "address"); + if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) + return -EINVAL; wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr), s); wil_memcpy_toio_32(dst, d->data, s); @@ -197,7 +196,8 @@ static int fw_handle_fill(struct wil6210_priv *wil, const void *data, return -EINVAL; } - FW_ADDR_CHECK(dst, d->addr, "address"); + if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) + return -EINVAL; v = le32_to_cpu(d->value); wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", @@ -253,7 +253,8 @@ static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data, u32 v = le32_to_cpu(block[i].value); u32 x, y; - FW_ADDR_CHECK(dst, block[i].addr, "address"); + if (!wil_fw_addr_check(wil, &dst, block[i].addr, 0, "address")) + return -EINVAL; x = readl(dst); y = (x & m) | (v & ~m); @@ -319,10 +320,15 @@ static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd); - FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); - FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr"); - FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); - FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); + if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, + "gateway_addr_addr") || + !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0, + "gateway_value_addr") || + !wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, + "gateway_cmd_addr") || + !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, + "gateway_ctrl_address")) + return -EINVAL; wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" " cmd 0x%08x ctl 0x%08x\n", @@ -378,12 +384,19 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd); - FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); + if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, + "gateway_addr_addr")) + return -EINVAL; for (k = 0; k < ARRAY_SIZE(block->value); k++) - FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k], - "gateway_value_addr"); - FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); - FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); + if (!wil_fw_addr_check(wil, &gwa_val[k], + d->gateway_value_addr[k], + 0, "gateway_value_addr")) + return -EINVAL; + if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, + "gateway_cmd_addr") || + !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, + "gateway_ctrl_address")) + return -EINVAL; wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", le32_to_cpu(d->gateway_addr_addr), @@ -422,7 +435,7 @@ static const struct { int (*parse_handler)(struct wil6210_priv *wil, const void *data, size_t size); } wil_fw_handlers[] = { - {wil_fw_type_comment, fw_handle_comment, fw_handle_capabilities}, + {wil_fw_type_comment, fw_handle_comment, fw_handle_comment}, {wil_fw_type_data, fw_handle_data, fw_ignore_section}, {wil_fw_type_fill, fw_handle_fill, fw_ignore_section}, /* wil_fw_type_action */ @@ -517,7 +530,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name, rc = request_firmware(&fw, name, wil_to_dev(wil)); if (rc) { - wil_err_fw(wil, "Failed to load firmware %s\n", name); + wil_err_fw(wil, "Failed to load firmware %s rc %d\n", name, rc); return rc; } wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size); diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 59def4f3fcf3..5cf341702dc1 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c @@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil) wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); } +static bool wil_validate_mbox_regs(struct wil6210_priv *wil) +{ + size_t min_size = sizeof(struct wil6210_mbox_hdr) + + sizeof(struct wmi_cmd_hdr); + + if (wil->mbox_ctl.rx.entry_size < min_size) { + wil_err(wil, "rx mbox entry too small (%d)\n", + wil->mbox_ctl.rx.entry_size); + return false; + } + if (wil->mbox_ctl.tx.entry_size < min_size) { + wil_err(wil, "tx mbox entry too small (%d)\n", + wil->mbox_ctl.tx.entry_size); + return false; + } + + return true; +} + static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; @@ -393,7 +412,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_READY) { wil_dbg_irq(wil, "IRQ: FW ready\n"); wil_cache_mbox_regs(wil); - set_bit(wil_status_mbox_ready, wil->status); + if (wil_validate_mbox_regs(wil)) + set_bit(wil_status_mbox_ready, wil->status); /** * Actual FW ready indicated by the * WMI_FW_READY_EVENTID diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 885924abf61c..1b53cd3f272b 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -579,7 +579,6 @@ int wil_priv_init(struct wil6210_priv *wil) wil->wakeup_trigger = WMI_WAKEUP_TRIGGER_UCAST | WMI_WAKEUP_TRIGGER_BCAST; memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats)); - wil->suspend_stats.min_suspend_time = ULONG_MAX; wil->vring_idle_trsh = 16; return 0; @@ -760,6 +759,8 @@ static void wil_collect_fw_info(struct wil6210_priv *wil) u8 retry_short; int rc; + wil_refresh_fw_capabilities(wil); + rc = wmi_get_mgmt_retry(wil, &retry_short); if (!rc) { wiphy->retry_short = retry_short; @@ -767,6 +768,25 @@ static void wil_collect_fw_info(struct wil6210_priv *wil) } } +void wil_refresh_fw_capabilities(struct wil6210_priv *wil) +{ + struct wiphy *wiphy = wil_to_wiphy(wil); + + wil->keep_radio_on_during_sleep = + wil->platform_ops.keep_radio_on_during_sleep && + wil->platform_ops.keep_radio_on_during_sleep( + wil->platform_handle) && + test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities); + + wil_info(wil, "keep_radio_on_during_sleep (%d)\n", + wil->keep_radio_on_during_sleep); + + if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities)) + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + else + wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; +} + void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) { le32_to_cpus(&r->base); @@ -1071,11 +1091,11 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) return rc; } + wil_collect_fw_info(wil); + if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT) wil_ps_update(wil, wil->ps_profile); - wil_collect_fw_info(wil); - if (wil->platform_ops.notify) { rc = wil->platform_ops.notify(wil->platform_handle, WIL_PLATFORM_EVT_FW_RDY); diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 4a6ab2d0fdf1..b641ac17a053 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -21,6 +21,7 @@ static int wil_open(struct net_device *ndev) { struct wil6210_priv *wil = ndev_to_wil(ndev); + int rc; wil_dbg_misc(wil, "open\n"); @@ -30,16 +31,29 @@ static int wil_open(struct net_device *ndev) return -EINVAL; } - return wil_up(wil); + rc = wil_pm_runtime_get(wil); + if (rc < 0) + return rc; + + rc = wil_up(wil); + if (rc) + wil_pm_runtime_put(wil); + + return rc; } static int wil_stop(struct net_device *ndev) { struct wil6210_priv *wil = ndev_to_wil(ndev); + int rc; wil_dbg_misc(wil, "stop\n"); - return wil_down(wil); + rc = wil_down(wil); + if (!rc) + wil_pm_runtime_put(wil); + + return rc; } static const struct net_device_ops wil_netdev_ops = { diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 6a3ab4bf916d..42a5480c764d 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -21,6 +21,7 @@ #include <linux/suspend.h> #include "wil6210.h" #include <linux/rtnetlink.h> +#include <linux/pm_runtime.h> static bool use_msi = true; module_param(use_msi, bool, 0444); @@ -31,10 +32,8 @@ module_param(ftm_mode, bool, 0444); MODULE_PARM_DESC(ftm_mode, " Set factory test mode, default - false"); #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP static int wil6210_pm_notify(struct notifier_block *notify_block, unsigned long mode, void *unused); -#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM */ static @@ -84,9 +83,7 @@ void wil_set_capabilities(struct wil6210_priv *wil) /* extract FW capabilities from file without loading the FW */ wil_request_firmware(wil, wil->wil_fw_name, false); - - if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities)) - wil_to_wiphy(wil)->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wil_refresh_fw_capabilities(wil); } void wil_disable_irq(struct wil6210_priv *wil) @@ -296,15 +293,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) wil_set_capabilities(wil); wil6210_clear_irq(wil); - wil->keep_radio_on_during_sleep = - wil->platform_ops.keep_radio_on_during_sleep && - wil->platform_ops.keep_radio_on_during_sleep( - wil->platform_handle) && - test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities); - - wil_info(wil, "keep_radio_on_during_sleep (%d)\n", - wil->keep_radio_on_during_sleep); - /* FW should raise IRQ when ready */ rc = wil_if_pcie_enable(wil); if (rc) { @@ -320,7 +308,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) } #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP wil->pm_notify.notifier_call = wil6210_pm_notify; rc = register_pm_notifier(&wil->pm_notify); if (rc) @@ -328,11 +315,11 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) * be prevented in a later phase if needed */ wil_err(wil, "register_pm_notifier failed: %d\n", rc); -#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM */ wil6210_debugfs_init(wil); + wil_pm_runtime_allow(wil); return 0; @@ -360,11 +347,11 @@ static void wil_pcie_remove(struct pci_dev *pdev) wil_dbg_misc(wil, "pcie_remove\n"); #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP unregister_pm_notifier(&wil->pm_notify); -#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM */ + wil_pm_runtime_forbid(wil); + wil6210_debugfs_remove(wil); rtnl_lock(); wil_p2p_wdev_free(wil); @@ -386,13 +373,15 @@ static const struct pci_device_id wil6210_pcie_ids[] = { MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP static int wil6210_suspend(struct device *dev, bool is_runtime) { int rc = 0; struct pci_dev *pdev = to_pci_dev(dev); struct wil6210_priv *wil = pci_get_drvdata(pdev); + struct net_device *ndev = wil_to_ndev(wil); + bool keep_radio_on = ndev->flags & IFF_UP && + wil->keep_radio_on_during_sleep; wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); @@ -400,16 +389,18 @@ static int wil6210_suspend(struct device *dev, bool is_runtime) if (rc) goto out; - rc = wil_suspend(wil, is_runtime); + rc = wil_suspend(wil, is_runtime, keep_radio_on); if (!rc) { - wil->suspend_stats.successful_suspends++; - - /* If platform device supports keep_radio_on_during_sleep - * it will control PCIe master + /* In case radio stays on, platform device will control + * PCIe master */ - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) { /* disable bus mastering */ pci_clear_master(pdev); + wil->suspend_stats.r_off.successful_suspends++; + } else { + wil->suspend_stats.r_on.successful_suspends++; + } } out: return rc; @@ -420,23 +411,32 @@ static int wil6210_resume(struct device *dev, bool is_runtime) int rc = 0; struct pci_dev *pdev = to_pci_dev(dev); struct wil6210_priv *wil = pci_get_drvdata(pdev); + struct net_device *ndev = wil_to_ndev(wil); + bool keep_radio_on = ndev->flags & IFF_UP && + wil->keep_radio_on_during_sleep; wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); - /* If platform device supports keep_radio_on_during_sleep it will - * control PCIe master + /* In case radio stays on, platform device will control + * PCIe master */ - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) /* allow master */ pci_set_master(pdev); - rc = wil_resume(wil, is_runtime); + rc = wil_resume(wil, is_runtime, keep_radio_on); if (rc) { wil_err(wil, "device failed to resume (%d)\n", rc); - wil->suspend_stats.failed_resumes++; - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) { pci_clear_master(pdev); + wil->suspend_stats.r_off.failed_resumes++; + } else { + wil->suspend_stats.r_on.failed_resumes++; + } } else { - wil->suspend_stats.successful_resumes++; + if (keep_radio_on) + wil->suspend_stats.r_on.successful_resumes++; + else + wil->suspend_stats.r_off.successful_resumes++; } return rc; @@ -490,12 +490,43 @@ static int wil6210_pm_resume(struct device *dev) { return wil6210_resume(dev, false); } -#endif /* CONFIG_PM_SLEEP */ +static int wil6210_pm_runtime_idle(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct wil6210_priv *wil = pci_get_drvdata(pdev); + + wil_dbg_pm(wil, "Runtime idle\n"); + + return wil_can_suspend(wil, true); +} + +static int wil6210_pm_runtime_resume(struct device *dev) +{ + return wil6210_resume(dev, true); +} + +static int wil6210_pm_runtime_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct wil6210_priv *wil = pci_get_drvdata(pdev); + + if (test_bit(wil_status_suspended, wil->status)) { + wil_dbg_pm(wil, "trying to suspend while suspended\n"); + return 1; + } + + return wil6210_suspend(dev, true); +} #endif /* CONFIG_PM */ static const struct dev_pm_ops wil6210_pm_ops = { +#ifdef CONFIG_PM SET_SYSTEM_SLEEP_PM_OPS(wil6210_pm_suspend, wil6210_pm_resume) + SET_RUNTIME_PM_OPS(wil6210_pm_runtime_suspend, + wil6210_pm_runtime_resume, + wil6210_pm_runtime_idle) +#endif /* CONFIG_PM */ }; static struct pci_driver wil6210_driver = { diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 8f5d1b447aaa..056b180fad7f 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -16,15 +16,30 @@ #include "wil6210.h" #include <linux/jiffies.h> +#include <linux/pm_runtime.h> + +#define WIL6210_AUTOSUSPEND_DELAY_MS (1000) int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) { int rc = 0; struct wireless_dev *wdev = wil->wdev; struct net_device *ndev = wil_to_ndev(wil); + bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY, + wil->fw_capabilities); wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system"); + if (wmi_only || debug_fw) { + wil_dbg_pm(wil, "Deny any suspend - %s mode\n", + wmi_only ? "wmi_only" : "debug_fw"); + rc = -EBUSY; + goto out; + } + if (is_runtime && !wil->platform_ops.suspend) { + rc = -EBUSY; + goto out; + } if (!(ndev->flags & IFF_UP)) { /* can always sleep when down */ wil_dbg_pm(wil, "Interface is down\n"); @@ -44,6 +59,10 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) /* interface is running */ switch (wdev->iftype) { case NL80211_IFTYPE_MONITOR: + wil_dbg_pm(wil, "Sniffer\n"); + rc = -EBUSY; + goto out; + /* for STA-like interface, don't runtime suspend */ case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: if (test_bit(wil_status_fwconnecting, wil->status)) { @@ -51,6 +70,12 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) rc = -EBUSY; goto out; } + /* Runtime pm not supported in case the interface is up */ + if (is_runtime) { + wil_dbg_pm(wil, "STA-like interface\n"); + rc = -EBUSY; + goto out; + } break; /* AP-like interface - can't suspend */ default: @@ -158,7 +183,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) break; wil_err(wil, "TO waiting for idle RX, suspend failed\n"); - wil->suspend_stats.failed_suspends++; + wil->suspend_stats.r_on.failed_suspends++; goto resume_after_fail; } wil_dbg_ratelimited(wil, "rx vring is not empty -> NAPI\n"); @@ -174,7 +199,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) */ if (!wil_is_wmi_idle(wil)) { wil_err(wil, "suspend failed due to pending WMI events\n"); - wil->suspend_stats.failed_suspends++; + wil->suspend_stats.r_on.failed_suspends++; goto resume_after_fail; } @@ -188,7 +213,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) if (rc) { wil_err(wil, "platform device failed to suspend (%d)\n", rc); - wil->suspend_stats.failed_suspends++; + wil->suspend_stats.r_on.failed_suspends++; wil_c(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); wil_unmask_irq(wil); goto resume_after_fail; @@ -235,6 +260,7 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) rc = wil_down(wil); if (rc) { wil_err(wil, "wil_down : %d\n", rc); + wil->suspend_stats.r_off.failed_suspends++; goto out; } } @@ -247,6 +273,7 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) rc = wil->platform_ops.suspend(wil->platform_handle, false); if (rc) { wil_enable_irq(wil); + wil->suspend_stats.r_off.failed_suspends++; goto out; } } @@ -279,12 +306,9 @@ static int wil_resume_radio_off(struct wil6210_priv *wil) return rc; } -int wil_suspend(struct wil6210_priv *wil, bool is_runtime) +int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on) { int rc = 0; - struct net_device *ndev = wil_to_ndev(wil); - bool keep_radio_on = ndev->flags & IFF_UP && - wil->keep_radio_on_during_sleep; wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); @@ -301,19 +325,12 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime) wil_dbg_pm(wil, "suspend: %s => %d\n", is_runtime ? "runtime" : "system", rc); - if (!rc) - wil->suspend_stats.suspend_start_time = ktime_get(); - return rc; } -int wil_resume(struct wil6210_priv *wil, bool is_runtime) +int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on) { int rc = 0; - struct net_device *ndev = wil_to_ndev(wil); - bool keep_radio_on = ndev->flags & IFF_UP && - wil->keep_radio_on_during_sleep; - unsigned long long suspend_time_usec = 0; wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); @@ -331,20 +348,49 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime) else rc = wil_resume_radio_off(wil); - if (rc) - goto out; - - suspend_time_usec = - ktime_to_us(ktime_sub(ktime_get(), - wil->suspend_stats.suspend_start_time)); - wil->suspend_stats.total_suspend_time += suspend_time_usec; - if (suspend_time_usec < wil->suspend_stats.min_suspend_time) - wil->suspend_stats.min_suspend_time = suspend_time_usec; - if (suspend_time_usec > wil->suspend_stats.max_suspend_time) - wil->suspend_stats.max_suspend_time = suspend_time_usec; - out: - wil_dbg_pm(wil, "resume: %s => %d, suspend time %lld usec\n", - is_runtime ? "runtime" : "system", rc, suspend_time_usec); + wil_dbg_pm(wil, "resume: %s => %d\n", is_runtime ? "runtime" : "system", + rc); return rc; } + +void wil_pm_runtime_allow(struct wil6210_priv *wil) +{ + struct device *dev = wil_to_dev(wil); + + pm_runtime_put_noidle(dev); + pm_runtime_set_autosuspend_delay(dev, WIL6210_AUTOSUSPEND_DELAY_MS); + pm_runtime_use_autosuspend(dev); + pm_runtime_allow(dev); +} + +void wil_pm_runtime_forbid(struct wil6210_priv *wil) +{ + struct device *dev = wil_to_dev(wil); + + pm_runtime_forbid(dev); + pm_runtime_get_noresume(dev); +} + +int wil_pm_runtime_get(struct wil6210_priv *wil) +{ + int rc; + struct device *dev = wil_to_dev(wil); + + rc = pm_runtime_get_sync(dev); + if (rc < 0) { + wil_err(wil, "pm_runtime_get_sync() failed, rc = %d\n", rc); + pm_runtime_put_noidle(dev); + return rc; + } + + return 0; +} + +void wil_pm_runtime_put(struct wil6210_priv *wil) +{ + struct device *dev = wil_to_dev(wil); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); +} diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 1e340d04bd70..cf27d9711dde 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -82,18 +82,18 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1) */ #define WIL_MAX_MPDU_OVERHEAD (62) -struct wil_suspend_stats { +struct wil_suspend_count_stats { unsigned long successful_suspends; - unsigned long failed_suspends; unsigned long successful_resumes; + unsigned long failed_suspends; unsigned long failed_resumes; - unsigned long rejected_by_device; +}; + +struct wil_suspend_stats { + struct wil_suspend_count_stats r_off; + struct wil_suspend_count_stats r_on; + unsigned long rejected_by_device; /* only radio on */ unsigned long rejected_by_host; - unsigned long long total_suspend_time; - unsigned long long min_suspend_time; - unsigned long long max_suspend_time; - ktime_t collection_start; - ktime_t suspend_start_time; }; /* Calculate MAC buffer size for the firmware. It includes all overhead, @@ -616,6 +616,16 @@ struct blink_on_off_time { u32 off_ms; }; +struct wil_debugfs_iomem_data { + void *offset; + struct wil6210_priv *wil; +}; + +struct wil_debugfs_data { + struct wil_debugfs_iomem_data *data_arr; + int iomem_data_count; +}; + extern struct blink_on_off_time led_blink_time[WIL_LED_TIME_LAST]; extern u8 led_id; extern u8 led_polarity; @@ -708,6 +718,7 @@ struct wil6210_priv { u8 abft_len; u8 wakeup_trigger; struct wil_suspend_stats suspend_stats; + struct wil_debugfs_data dbg_data; void *platform_handle; struct wil_platform_ops platform_ops; @@ -732,9 +743,7 @@ struct wil6210_priv { int fw_calib_result; #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP struct notifier_block pm_notify; -#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM */ bool suspend_resp_rcvd; @@ -861,10 +870,12 @@ int wil_up(struct wil6210_priv *wil); int __wil_up(struct wil6210_priv *wil); int wil_down(struct wil6210_priv *wil); int __wil_down(struct wil6210_priv *wil); +void wil_refresh_fw_capabilities(struct wil6210_priv *wil); void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); void wil_set_ethtoolops(struct net_device *ndev); +void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr, u32 size); void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, @@ -999,9 +1010,14 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name, bool load); bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name); +void wil_pm_runtime_allow(struct wil6210_priv *wil); +void wil_pm_runtime_forbid(struct wil6210_priv *wil); +int wil_pm_runtime_get(struct wil6210_priv *wil); +void wil_pm_runtime_put(struct wil6210_priv *wil); + int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime); -int wil_suspend(struct wil6210_priv *wil, bool is_runtime); -int wil_resume(struct wil6210_priv *wil, bool is_runtime); +int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on); +int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on); bool wil_is_wmi_idle(struct wil6210_priv *wil); int wmi_resume(struct wil6210_priv *wil); int wmi_suspend(struct wil6210_priv *wil); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index ffdd2fa401b1..8ace618d0fd9 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -140,13 +140,15 @@ static u32 wmi_addr_remap(u32 x) /** * Check address validity for WMI buffer; remap if needed * @ptr - internal (linker) fw/ucode address + * @size - if non zero, validate the block does not + * exceed the device memory (bar) * * Valid buffer should be DWORD aligned * * return address for accessing buffer from the host; * if buffer is not valid, return NULL. */ -void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) +void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size) { u32 off; u32 ptr = le32_to_cpu(ptr_); @@ -161,10 +163,17 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) off = HOSTADDR(ptr); if (off > wil->bar_size - 4) return NULL; + if (size && ((off + size > wil->bar_size) || (off + size < off))) + return NULL; return wil->csr + off; } +void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) +{ + return wmi_buffer_block(wil, ptr_, 0); +} + /** * Check address validity */ @@ -198,6 +207,232 @@ int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, return 0; } +static const char *cmdid2name(u16 cmdid) +{ + switch (cmdid) { + case WMI_NOTIFY_REQ_CMDID: + return "WMI_NOTIFY_REQ_CMD"; + case WMI_START_SCAN_CMDID: + return "WMI_START_SCAN_CMD"; + case WMI_CONNECT_CMDID: + return "WMI_CONNECT_CMD"; + case WMI_DISCONNECT_CMDID: + return "WMI_DISCONNECT_CMD"; + case WMI_SW_TX_REQ_CMDID: + return "WMI_SW_TX_REQ_CMD"; + case WMI_GET_RF_SECTOR_PARAMS_CMDID: + return "WMI_GET_RF_SECTOR_PARAMS_CMD"; + case WMI_SET_RF_SECTOR_PARAMS_CMDID: + return "WMI_SET_RF_SECTOR_PARAMS_CMD"; + case WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID: + return "WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD"; + case WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID: + return "WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD"; + case WMI_BRP_SET_ANT_LIMIT_CMDID: + return "WMI_BRP_SET_ANT_LIMIT_CMD"; + case WMI_TOF_SESSION_START_CMDID: + return "WMI_TOF_SESSION_START_CMD"; + case WMI_AOA_MEAS_CMDID: + return "WMI_AOA_MEAS_CMD"; + case WMI_PMC_CMDID: + return "WMI_PMC_CMD"; + case WMI_TOF_GET_TX_RX_OFFSET_CMDID: + return "WMI_TOF_GET_TX_RX_OFFSET_CMD"; + case WMI_TOF_SET_TX_RX_OFFSET_CMDID: + return "WMI_TOF_SET_TX_RX_OFFSET_CMD"; + case WMI_VRING_CFG_CMDID: + return "WMI_VRING_CFG_CMD"; + case WMI_BCAST_VRING_CFG_CMDID: + return "WMI_BCAST_VRING_CFG_CMD"; + case WMI_TRAFFIC_SUSPEND_CMDID: + return "WMI_TRAFFIC_SUSPEND_CMD"; + case WMI_TRAFFIC_RESUME_CMDID: + return "WMI_TRAFFIC_RESUME_CMD"; + case WMI_ECHO_CMDID: + return "WMI_ECHO_CMD"; + case WMI_SET_MAC_ADDRESS_CMDID: + return "WMI_SET_MAC_ADDRESS_CMD"; + case WMI_LED_CFG_CMDID: + return "WMI_LED_CFG_CMD"; + case WMI_PCP_START_CMDID: + return "WMI_PCP_START_CMD"; + case WMI_PCP_STOP_CMDID: + return "WMI_PCP_STOP_CMD"; + case WMI_SET_SSID_CMDID: + return "WMI_SET_SSID_CMD"; + case WMI_GET_SSID_CMDID: + return "WMI_GET_SSID_CMD"; + case WMI_SET_PCP_CHANNEL_CMDID: + return "WMI_SET_PCP_CHANNEL_CMD"; + case WMI_GET_PCP_CHANNEL_CMDID: + return "WMI_GET_PCP_CHANNEL_CMD"; + case WMI_P2P_CFG_CMDID: + return "WMI_P2P_CFG_CMD"; + case WMI_START_LISTEN_CMDID: + return "WMI_START_LISTEN_CMD"; + case WMI_START_SEARCH_CMDID: + return "WMI_START_SEARCH_CMD"; + case WMI_DISCOVERY_STOP_CMDID: + return "WMI_DISCOVERY_STOP_CMD"; + case WMI_DELETE_CIPHER_KEY_CMDID: + return "WMI_DELETE_CIPHER_KEY_CMD"; + case WMI_ADD_CIPHER_KEY_CMDID: + return "WMI_ADD_CIPHER_KEY_CMD"; + case WMI_SET_APPIE_CMDID: + return "WMI_SET_APPIE_CMD"; + case WMI_CFG_RX_CHAIN_CMDID: + return "WMI_CFG_RX_CHAIN_CMD"; + case WMI_TEMP_SENSE_CMDID: + return "WMI_TEMP_SENSE_CMD"; + case WMI_DEL_STA_CMDID: + return "WMI_DEL_STA_CMD"; + case WMI_DISCONNECT_STA_CMDID: + return "WMI_DISCONNECT_STA_CMD"; + case WMI_VRING_BA_EN_CMDID: + return "WMI_VRING_BA_EN_CMD"; + case WMI_VRING_BA_DIS_CMDID: + return "WMI_VRING_BA_DIS_CMD"; + case WMI_RCP_DELBA_CMDID: + return "WMI_RCP_DELBA_CMD"; + case WMI_RCP_ADDBA_RESP_CMDID: + return "WMI_RCP_ADDBA_RESP_CMD"; + case WMI_PS_DEV_PROFILE_CFG_CMDID: + return "WMI_PS_DEV_PROFILE_CFG_CMD"; + case WMI_SET_MGMT_RETRY_LIMIT_CMDID: + return "WMI_SET_MGMT_RETRY_LIMIT_CMD"; + case WMI_GET_MGMT_RETRY_LIMIT_CMDID: + return "WMI_GET_MGMT_RETRY_LIMIT_CMD"; + case WMI_ABORT_SCAN_CMDID: + return "WMI_ABORT_SCAN_CMD"; + case WMI_NEW_STA_CMDID: + return "WMI_NEW_STA_CMD"; + case WMI_SET_THERMAL_THROTTLING_CFG_CMDID: + return "WMI_SET_THERMAL_THROTTLING_CFG_CMD"; + case WMI_GET_THERMAL_THROTTLING_CFG_CMDID: + return "WMI_GET_THERMAL_THROTTLING_CFG_CMD"; + case WMI_LINK_MAINTAIN_CFG_WRITE_CMDID: + return "WMI_LINK_MAINTAIN_CFG_WRITE_CMD"; + case WMI_LO_POWER_CALIB_FROM_OTP_CMDID: + return "WMI_LO_POWER_CALIB_FROM_OTP_CMD"; + default: + return "Untracked CMD"; + } +} + +static const char *eventid2name(u16 eventid) +{ + switch (eventid) { + case WMI_NOTIFY_REQ_DONE_EVENTID: + return "WMI_NOTIFY_REQ_DONE_EVENT"; + case WMI_DISCONNECT_EVENTID: + return "WMI_DISCONNECT_EVENT"; + case WMI_SW_TX_COMPLETE_EVENTID: + return "WMI_SW_TX_COMPLETE_EVENT"; + case WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID: + return "WMI_GET_RF_SECTOR_PARAMS_DONE_EVENT"; + case WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID: + return "WMI_SET_RF_SECTOR_PARAMS_DONE_EVENT"; + case WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID: + return "WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT"; + case WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID: + return "WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT"; + case WMI_BRP_SET_ANT_LIMIT_EVENTID: + return "WMI_BRP_SET_ANT_LIMIT_EVENT"; + case WMI_FW_READY_EVENTID: + return "WMI_FW_READY_EVENT"; + case WMI_TRAFFIC_RESUME_EVENTID: + return "WMI_TRAFFIC_RESUME_EVENT"; + case WMI_TOF_GET_TX_RX_OFFSET_EVENTID: + return "WMI_TOF_GET_TX_RX_OFFSET_EVENT"; + case WMI_TOF_SET_TX_RX_OFFSET_EVENTID: + return "WMI_TOF_SET_TX_RX_OFFSET_EVENT"; + case WMI_VRING_CFG_DONE_EVENTID: + return "WMI_VRING_CFG_DONE_EVENT"; + case WMI_READY_EVENTID: + return "WMI_READY_EVENT"; + case WMI_RX_MGMT_PACKET_EVENTID: + return "WMI_RX_MGMT_PACKET_EVENT"; + case WMI_TX_MGMT_PACKET_EVENTID: + return "WMI_TX_MGMT_PACKET_EVENT"; + case WMI_SCAN_COMPLETE_EVENTID: + return "WMI_SCAN_COMPLETE_EVENT"; + case WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID: + return "WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENT"; + case WMI_CONNECT_EVENTID: + return "WMI_CONNECT_EVENT"; + case WMI_EAPOL_RX_EVENTID: + return "WMI_EAPOL_RX_EVENT"; + case WMI_BA_STATUS_EVENTID: + return "WMI_BA_STATUS_EVENT"; + case WMI_RCP_ADDBA_REQ_EVENTID: + return "WMI_RCP_ADDBA_REQ_EVENT"; + case WMI_DELBA_EVENTID: + return "WMI_DELBA_EVENT"; + case WMI_VRING_EN_EVENTID: + return "WMI_VRING_EN_EVENT"; + case WMI_DATA_PORT_OPEN_EVENTID: + return "WMI_DATA_PORT_OPEN_EVENT"; + case WMI_AOA_MEAS_EVENTID: + return "WMI_AOA_MEAS_EVENT"; + case WMI_TOF_SESSION_END_EVENTID: + return "WMI_TOF_SESSION_END_EVENT"; + case WMI_TOF_GET_CAPABILITIES_EVENTID: + return "WMI_TOF_GET_CAPABILITIES_EVENT"; + case WMI_TOF_SET_LCR_EVENTID: + return "WMI_TOF_SET_LCR_EVENT"; + case WMI_TOF_SET_LCI_EVENTID: + return "WMI_TOF_SET_LCI_EVENT"; + case WMI_TOF_FTM_PER_DEST_RES_EVENTID: + return "WMI_TOF_FTM_PER_DEST_RES_EVENT"; + case WMI_TOF_CHANNEL_INFO_EVENTID: + return "WMI_TOF_CHANNEL_INFO_EVENT"; + case WMI_TRAFFIC_SUSPEND_EVENTID: + return "WMI_TRAFFIC_SUSPEND_EVENT"; + case WMI_ECHO_RSP_EVENTID: + return "WMI_ECHO_RSP_EVENT"; + case WMI_LED_CFG_DONE_EVENTID: + return "WMI_LED_CFG_DONE_EVENT"; + case WMI_PCP_STARTED_EVENTID: + return "WMI_PCP_STARTED_EVENT"; + case WMI_PCP_STOPPED_EVENTID: + return "WMI_PCP_STOPPED_EVENT"; + case WMI_GET_SSID_EVENTID: + return "WMI_GET_SSID_EVENT"; + case WMI_GET_PCP_CHANNEL_EVENTID: + return "WMI_GET_PCP_CHANNEL_EVENT"; + case WMI_P2P_CFG_DONE_EVENTID: + return "WMI_P2P_CFG_DONE_EVENT"; + case WMI_LISTEN_STARTED_EVENTID: + return "WMI_LISTEN_STARTED_EVENT"; + case WMI_SEARCH_STARTED_EVENTID: + return "WMI_SEARCH_STARTED_EVENT"; + case WMI_DISCOVERY_STOPPED_EVENTID: + return "WMI_DISCOVERY_STOPPED_EVENT"; + case WMI_CFG_RX_CHAIN_DONE_EVENTID: + return "WMI_CFG_RX_CHAIN_DONE_EVENT"; + case WMI_TEMP_SENSE_DONE_EVENTID: + return "WMI_TEMP_SENSE_DONE_EVENT"; + case WMI_RCP_ADDBA_RESP_SENT_EVENTID: + return "WMI_RCP_ADDBA_RESP_SENT_EVENT"; + case WMI_PS_DEV_PROFILE_CFG_EVENTID: + return "WMI_PS_DEV_PROFILE_CFG_EVENT"; + case WMI_SET_MGMT_RETRY_LIMIT_EVENTID: + return "WMI_SET_MGMT_RETRY_LIMIT_EVENT"; + case WMI_GET_MGMT_RETRY_LIMIT_EVENTID: + return "WMI_GET_MGMT_RETRY_LIMIT_EVENT"; + case WMI_SET_THERMAL_THROTTLING_CFG_EVENTID: + return "WMI_SET_THERMAL_THROTTLING_CFG_EVENT"; + case WMI_GET_THERMAL_THROTTLING_CFG_EVENTID: + return "WMI_GET_THERMAL_THROTTLING_CFG_EVENT"; + case WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID: + return "WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENT"; + case WMI_LO_POWER_CALIB_FROM_OTP_EVENTID: + return "WMI_LO_POWER_CALIB_FROM_OTP_EVENT"; + default: + return "Untracked EVENT"; + } +} + static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) { struct { @@ -222,7 +457,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) uint retry; int rc = 0; - if (sizeof(cmd) + len > r->entry_size) { + if (len > r->entry_size - sizeof(cmd)) { wil_err(wil, "WMI size too large: %d bytes, max is %d\n", (int)(sizeof(cmd) + len), r->entry_size); return -ERANGE; @@ -294,7 +529,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) } cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); /* set command */ - wil_dbg_wmi(wil, "WMI command 0x%04x [%d]\n", cmdid, len); + wil_dbg_wmi(wil, "sending %s (0x%04x) [%d]\n", + cmdid2name(cmdid), cmdid, len); wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, sizeof(cmd), true); wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, @@ -963,8 +1199,8 @@ void wmi_recv_cmd(struct wil6210_priv *wil) } spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); - wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n", - id, wmi->mid, tstamp); + wil_dbg_wmi(wil, "recv %s (0x%04x) MID %d @%d msec\n", + eventid2name(id), id, wmi->mid, tstamp); trace_wil6210_wmi_event(wmi, &wmi[1], len - sizeof(*wmi)); } @@ -1380,8 +1616,14 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) }; int rc; u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; - struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); + struct wmi_set_appie_cmd *cmd; + + if (len < ie_len) { + rc = -EINVAL; + goto out; + } + cmd = kzalloc(len, GFP_KERNEL); if (!cmd) { rc = -ENOMEM; goto out; @@ -1801,6 +2043,16 @@ void wmi_event_flush(struct wil6210_priv *wil) spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); } +static const char *suspend_status2name(u8 status) +{ + switch (status) { + case WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE: + return "LINK_NOT_IDLE"; + default: + return "Untracked status"; + } +} + int wmi_suspend(struct wil6210_priv *wil) { int rc; @@ -1816,7 +2068,7 @@ int wmi_suspend(struct wil6210_priv *wil) wil->suspend_resp_rcvd = false; wil->suspend_resp_comp = false; - reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED; + reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE; rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, &cmd, sizeof(cmd), WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply), @@ -1848,8 +2100,9 @@ int wmi_suspend(struct wil6210_priv *wil) } wil_dbg_wmi(wil, "suspend_response_completed rcvd\n"); - if (reply.evt.status == WMI_TRAFFIC_SUSPEND_REJECTED) { - wil_dbg_pm(wil, "device rejected the suspend\n"); + if (reply.evt.status != WMI_TRAFFIC_SUSPEND_APPROVED) { + wil_dbg_pm(wil, "device rejected the suspend, %s\n", + suspend_status2name(reply.evt.status)); wil->suspend_stats.rejected_by_device++; } rc = reply.evt.status; @@ -1861,21 +2114,50 @@ out: return rc; } +static void resume_triggers2string(u32 triggers, char *string, int str_size) +{ + string[0] = '\0'; + + if (!triggers) { + strlcat(string, " UNKNOWN", str_size); + return; + } + + if (triggers & WMI_RESUME_TRIGGER_HOST) + strlcat(string, " HOST", str_size); + + if (triggers & WMI_RESUME_TRIGGER_UCAST_RX) + strlcat(string, " UCAST_RX", str_size); + + if (triggers & WMI_RESUME_TRIGGER_BCAST_RX) + strlcat(string, " BCAST_RX", str_size); + + if (triggers & WMI_RESUME_TRIGGER_WMI_EVT) + strlcat(string, " WMI_EVT", str_size); +} + int wmi_resume(struct wil6210_priv *wil) { int rc; + char string[100]; struct { struct wmi_cmd_hdr wmi; struct wmi_traffic_resume_event evt; } __packed reply; reply.evt.status = WMI_TRAFFIC_RESUME_FAILED; + reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN; rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, NULL, 0, WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply), WIL_WAIT_FOR_SUSPEND_RESUME_COMP); if (rc) return rc; + resume_triggers2string(le32_to_cpu(reply.evt.resume_triggers), string, + sizeof(string)); + wil_dbg_pm(wil, "device resume %s, resume triggers:%s (0x%x)\n", + reply.evt.status ? "failed" : "passed", string, + le32_to_cpu(reply.evt.resume_triggers)); return reply.evt.status; } @@ -1906,8 +2188,8 @@ static void wmi_event_handle(struct wil6210_priv *wil, void *evt_data = (void *)(&wmi[1]); u16 id = le16_to_cpu(wmi->command_id); - wil_dbg_wmi(wil, "Handle WMI 0x%04x (reply_id 0x%04x)\n", - id, wil->reply_id); + wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x)\n", + eventid2name(id), id, wil->reply_id); /* check if someone waits for this event */ if (wil->reply_id && wil->reply_id == id) { WARN_ON(wil->reply_buf); diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 5263ee717a4f..d9e220a8c0f4 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -2267,8 +2267,8 @@ struct wmi_link_maintain_cfg_read_done_event { } __packed; enum wmi_traffic_suspend_status { - WMI_TRAFFIC_SUSPEND_APPROVED = 0x0, - WMI_TRAFFIC_SUSPEND_REJECTED = 0x1, + WMI_TRAFFIC_SUSPEND_APPROVED = 0x0, + WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE = 0x1, }; /* WMI_TRAFFIC_SUSPEND_EVENTID */ @@ -2282,10 +2282,21 @@ enum wmi_traffic_resume_status { WMI_TRAFFIC_RESUME_FAILED = 0x1, }; +enum wmi_resume_trigger { + WMI_RESUME_TRIGGER_UNKNOWN = 0x0, + WMI_RESUME_TRIGGER_HOST = 0x1, + WMI_RESUME_TRIGGER_UCAST_RX = 0x2, + WMI_RESUME_TRIGGER_BCAST_RX = 0x4, + WMI_RESUME_TRIGGER_WMI_EVT = 0x8, +}; + /* WMI_TRAFFIC_RESUME_EVENTID */ struct wmi_traffic_resume_event { - /* enum wmi_traffic_resume_status_e */ + /* enum wmi_traffic_resume_status */ u8 status; + u8 reserved[3]; + /* enum wmi_resume_trigger bitmap */ + __le32 resume_triggers; } __packed; /* Power Save command completion status codes */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index cd587325e286..f8b47c1f4bcd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -137,27 +137,27 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) { /* assign GPIO to SDIO core */ addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol); - gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret); + gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret); gpiocontrol |= 0x2; - brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret); + brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret); - brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf, - &ret); - brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret); - brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret); + brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT, + 0xf, &ret); + brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret); + brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret); } /* must configure SDIO_CCCR_IENx to enable irq */ - data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret); + data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret); data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; - brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); /* redirect, configure and enable io for interrupt signal */ - data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; + data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE; if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) - data |= SDIO_SEPINT_ACT_HI; - brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); - + data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI; + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, + data, &ret); sdio_release_host(sdiodev->func[1]); } else { brcmf_dbg(SDIO, "Entering\n"); @@ -183,8 +183,8 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) pdata = &sdiodev->settings->bus.sdio; sdio_claim_host(sdiodev->func[1]); - brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); - brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL); sdio_release_host(sdiodev->func[1]); sdiodev->oob_irq_requested = false; @@ -230,244 +230,93 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, sdiodev->state = state; } -static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, - uint regaddr, u8 byte) -{ - int err_ret; - - /* - * Can only directly write to some F0 registers. - * Handle CCCR_IENx and CCCR_ABORT command - * as a special case. - */ - if ((regaddr == SDIO_CCCR_ABORT) || - (regaddr == SDIO_CCCR_IENx)) - sdio_writeb(func, byte, regaddr, &err_ret); - else - sdio_f0_writeb(func, byte, regaddr, &err_ret); - - return err_ret; -} - -static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, - u32 addr, u8 regsz, void *data, bool write) -{ - struct sdio_func *func; - int ret = -EINVAL; - - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - write, fn, addr, regsz); - - /* only allow byte access on F0 */ - if (WARN_ON(regsz > 1 && !fn)) - return -EINVAL; - func = sdiodev->func[fn]; - - switch (regsz) { - case sizeof(u8): - if (write) { - if (fn) - sdio_writeb(func, *(u8 *)data, addr, &ret); - else - ret = brcmf_sdiod_f0_writeb(func, addr, - *(u8 *)data); - } else { - if (fn) - *(u8 *)data = sdio_readb(func, addr, &ret); - else - *(u8 *)data = sdio_f0_readb(func, addr, &ret); - } - break; - case sizeof(u16): - if (write) - sdio_writew(func, *(u16 *)data, addr, &ret); - else - *(u16 *)data = sdio_readw(func, addr, &ret); - break; - case sizeof(u32): - if (write) - sdio_writel(func, *(u32 *)data, addr, &ret); - else - *(u32 *)data = sdio_readl(func, addr, &ret); - break; - default: - brcmf_err("invalid size: %d\n", regsz); - break; - } - - if (ret) - brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", - write ? "write" : "read", fn, addr, ret); - - return ret; -} - -static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - u8 regsz, void *data, bool write) -{ - u8 func; - s32 retry = 0; - int ret; - - if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) - return -ENOMEDIUM; - - /* - * figure out how to read the register based on address range - * 0x00 ~ 0x7FF: function 0 CCCR and FBR - * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers - * The rest: function 1 silicon backplane core registers - */ - if ((addr & ~REG_F0_REG_MASK) == 0) - func = SDIO_FUNC_0; - else - func = SDIO_FUNC_1; - - do { - if (!write) - memset(data, 0, regsz); - /* for retry wait for 1 ms till bus get settled down */ - if (retry) - usleep_range(1000, 2000); - ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, - data, write); - } while (ret != 0 && ret != -ENOMEDIUM && - retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); - - if (ret == -ENOMEDIUM) - brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); - else if (ret != 0) { - /* - * SleepCSR register access can fail when - * waking up the device so reduce this noise - * in the logs. - */ - if (addr != SBSDIO_FUNC1_SLEEPCSR) - brcmf_err("failed to %s data F%d@0x%05x, err: %d\n", - write ? "write" : "read", func, addr, ret); - else - brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", - write ? "write" : "read", func, addr, ret); - } - return ret; -} - -static int -brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) +static int brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev *sdiodev, + u32 addr) { + u32 v, bar0 = addr & SBSDIO_SBWINDOW_MASK; int err = 0, i; - u8 addr[3]; - - if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) - return -ENOMEDIUM; - - addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; - addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; - addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; - - for (i = 0; i < 3; i++) { - err = brcmf_sdiod_regrw_helper(sdiodev, - SBSDIO_FUNC1_SBADDRLOW + i, - sizeof(u8), &addr[i], true); - if (err) { - brcmf_err("failed at addr: 0x%0x\n", - SBSDIO_FUNC1_SBADDRLOW + i); - break; - } - } - return err; -} + if (bar0 == sdiodev->sbwad) + return 0; -static int -brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) -{ - uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; + v = bar0 >> 8; - if (bar0 != sdiodev->sbwad) { - err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); - if (err) - return err; + for (i = 0 ; i < 3 && !err ; i++, v >>= 8) + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, + v & 0xff, &err); + if (!err) sdiodev->sbwad = bar0; - } - *addr &= SBSDIO_SB_OFT_ADDR_MASK; - - if (width == 4) - *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - return 0; + return err; } -u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) { - u8 data; + u32 data = 0; int retval; - brcmf_dbg(SDIO, "addr:0x%08x\n", addr); - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, - false); - brcmf_dbg(SDIO, "data:0x%02x\n", data); + retval = brcmf_sdiod_set_backplane_window(sdiodev, addr); + if (retval) + goto out; + + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + data = sdio_readl(sdiodev->func[1], addr, &retval); +out: if (ret) *ret = retval; return data; } -u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, + u32 data, int *ret) { - u32 data = 0; int retval; - brcmf_dbg(SDIO, "addr:0x%08x\n", addr); - retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); + retval = brcmf_sdiod_set_backplane_window(sdiodev, addr); if (retval) - goto done; - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, - false); - brcmf_dbg(SDIO, "data:0x%08x\n", data); - -done: - if (ret) - *ret = retval; + goto out; - return data; -} + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; -void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, - u8 data, int *ret) -{ - int retval; + sdio_writel(sdiodev->func[1], data, addr, &retval); - brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, - true); +out: if (ret) *ret = retval; } -void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, - u32 data, int *ret) +static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn, + u32 addr, struct sk_buff *pkt) { - int retval; + unsigned int req_sz; + int err; - brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); - retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); - if (retval) - goto done; - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, - true); + /* Single skb use the standard mmc interface */ + req_sz = pkt->len + 3; + req_sz &= (uint)~3; -done: - if (ret) - *ret = retval; + if (fn == 1) + err = sdio_memcpy_fromio(sdiodev->func[fn], + ((u8 *)(pkt->data)), addr, req_sz); + else + /* function 2 read is FIFO operation */ + err = sdio_readsb(sdiodev->func[fn], + ((u8 *)(pkt->data)), addr, req_sz); + + if (err == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); + + return err; } -static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, - bool write, u32 addr, struct sk_buff *pkt) +static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn, + u32 addr, struct sk_buff *pkt) { unsigned int req_sz; int err; @@ -476,18 +325,12 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, req_sz = pkt->len + 3; req_sz &= (uint)~3; - if (write) - err = sdio_memcpy_toio(sdiodev->func[fn], addr, - ((u8 *)(pkt->data)), req_sz); - else if (fn == 1) - err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)), - addr, req_sz); - else - /* function 2 read is FIFO operation */ - err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, - req_sz); + err = sdio_memcpy_toio(sdiodev->func[fn], addr, + ((u8 *)(pkt->data)), req_sz); + if (err == -ENOMEDIUM) brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); + return err; } @@ -691,11 +534,14 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt) brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); - err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + err = brcmf_sdiod_set_backplane_window(sdiodev, addr); if (err) goto done; - err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt); + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); done: return err; @@ -712,19 +558,22 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); - err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + err = brcmf_sdiod_set_backplane_window(sdiodev, addr); if (err) goto done; + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + if (pktq->qlen == 1) - err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, - pktq->next); + err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, + pktq->next); else if (!sdiodev->sg_support) { glom_skb = brcmu_pkt_buf_get_skb(totlen); if (!glom_skb) return -ENOMEM; - err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, - glom_skb); + err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, + glom_skb); if (err) goto done; @@ -748,6 +597,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) int err; mypkt = brcmu_pkt_buf_get_skb(nbytes); + if (!mypkt) { brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", nbytes); @@ -756,15 +606,19 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) memcpy(mypkt->data, buf, nbytes); - err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + err = brcmf_sdiod_set_backplane_window(sdiodev, addr); + if (err) + return err; + + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; if (!err) - err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr, - mypkt); + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); brcmu_pkt_buf_free_skb(mypkt); - return err; + return err; } int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, @@ -776,20 +630,24 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); - err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + err = brcmf_sdiod_set_backplane_window(sdiodev, addr); if (err) return err; - if (pktq->qlen == 1 || !sdiodev->sg_support) + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (pktq->qlen == 1 || !sdiodev->sg_support) { skb_queue_walk(pktq, skb) { - err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, - addr, skb); + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, + addr, skb); if (err) break; } - else + } else { err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr, pktq); + } return err; } @@ -798,7 +656,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, u8 *data, uint size) { - int bcmerror = 0; + int err = 0; struct sk_buff *pkt; u32 sdaddr; uint dsize; @@ -823,8 +681,8 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, /* Do the transfer(s) */ while (size) { /* Set the backplane window to include the start address */ - bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address); - if (bcmerror) + err = brcmf_sdiod_set_backplane_window(sdiodev, address); + if (err) break; brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", @@ -835,11 +693,17 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG; skb_put(pkt, dsize); - if (write) + + if (write) { memcpy(pkt->data, data, dsize); - bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, - sdaddr, pkt); - if (bcmerror) { + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1, + sdaddr, pkt); + } else { + err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1, + sdaddr, pkt); + } + + if (err) { brcmf_err("membytes transfer failed\n"); break; } @@ -859,24 +723,17 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, dev_kfree_skb(pkt); - /* Return the window to backplane enumeration space for core access */ - if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad)) - brcmf_err("FAILED to set window back to 0x%x\n", - sdiodev->sbwad); - sdio_release_host(sdiodev->func[1]); - return bcmerror; + return err; } -int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) { - char t_func = (char)fn; brcmf_dbg(SDIO, "Enter\n"); - /* issue abort cmd52 command through F0 */ - brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, - sizeof(t_func), &t_func, true); + /* Issue abort cmd52 command through F0 */ + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL); brcmf_dbg(SDIO, "Exit\n"); return 0; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index 53ae30259989..47de35a33853 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -130,13 +130,19 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, } } +#define MAX_CAPS_BUFFER_SIZE 512 static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) { - char caps[256]; + char caps[MAX_CAPS_BUFFER_SIZE]; enum brcmf_feat_id id; - int i; + int i, err; + + err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); + if (err) { + brcmf_err("could not get firmware cap (%d)\n", err); + return; + } - brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); brcmf_dbg(INFO, "[ %s]\n", caps); for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index cdf9e4161592..5cc2d698ea75 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -159,8 +159,8 @@ struct rte_console { /* manfid tuple length, include tuple, link bytes */ #define SBSDIO_CIS_MANFID_TUPLE_LEN 6 -#define CORE_BUS_REG(base, field) \ - (base + offsetof(struct sdpcmd_regs, field)) +#define SD_REG(field) \ + (offsetof(struct sdpcmd_regs, field)) /* SDIO function 1 register CHIPCLKCSR */ /* Force ALP request to backplane */ @@ -436,6 +436,7 @@ struct brcmf_sdio_count { struct brcmf_sdio { struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ struct brcmf_chip *ci; /* Chip info struct */ + struct brcmf_core *sdio_core; /* sdio core info struct */ u32 hostintmask; /* Copy of Host Interrupt Mask */ atomic_t intstatus; /* Intstatus bits (events) pending */ @@ -665,22 +666,20 @@ static bool data_ok(struct brcmf_sdio *bus) */ static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) { - struct brcmf_core *core; + struct brcmf_core *core = bus->sdio_core; int ret; - core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); - *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret); + *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); return ret; } static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) { - struct brcmf_core *core; + struct brcmf_core *core = bus->sdio_core; int ret; - core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); - brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret); + brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); return ret; } @@ -697,8 +696,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); /* 1st KSO write goes to AOS wake up core if device is asleep */ - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - wr_val, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); if (on) { /* device WAKEUP through KSO: @@ -724,7 +722,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) * just one write attempt may fail, * read it back until it matches written value */ - rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + rd_val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); if (!err) { if ((rd_val & bmask) == cmp_val) @@ -734,9 +732,11 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) /* bail out upon subsequent access errors */ if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) break; + udelay(KSO_WAIT_US); - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - wr_val, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, + &err); + } while (try_cnt++ < MAX_KSO_ATTEMPTS); if (try_cnt > 2) @@ -772,15 +772,15 @@ static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok) clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + clkreq, &err); if (err) { brcmf_err("HT Avail request error: %d\n", err); return -EBADE; } /* Check current status */ - clkctl = brcmf_sdiod_regrb(bus->sdiodev, + clkctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { brcmf_err("HT Avail read error: %d\n", err); @@ -790,35 +790,34 @@ static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok) /* Go to pending and await interrupt if appropriate */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { /* Allow only clock-available interrupt */ - devctl = brcmf_sdiod_regrb(bus->sdiodev, + devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err); if (err) { - brcmf_err("Devctl error setting CA: %d\n", - err); + brcmf_err("Devctl error setting CA: %d\n", err); return -EBADE; } devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); brcmf_dbg(SDIO, "CLKCTL: set PENDING\n"); bus->clkstate = CLK_PENDING; return 0; } else if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdiod_regrb(bus->sdiodev, + devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); } /* Otherwise, wait here (polling) for HT Avail */ timeout = jiffies + msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - clkctl = brcmf_sdiod_regrb(bus->sdiodev, + clkctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (time_after(jiffies, timeout)) @@ -852,16 +851,16 @@ static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok) if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdiod_regrb(bus->sdiodev, + devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); } bus->clkstate = CLK_SDONLY; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + clkreq, &err); brcmf_dbg(SDIO, "CLKCTL: turned OFF\n"); if (err) { brcmf_err("Failed access turning clock off: %d\n", @@ -951,14 +950,14 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) /* Going to sleep */ if (sleep) { - clkcsr = brcmf_sdiod_regrb(bus->sdiodev, + clkcsr = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); if ((clkcsr & SBSDIO_CSR_MASK) == 0) { brcmf_dbg(SDIO, "no clock, set ALP\n"); - brcmf_sdiod_regwb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_ALP_AVAIL_REQ, &err); + brcmf_sdiod_writeb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_ALP_AVAIL_REQ, &err); } err = brcmf_sdio_kso_control(bus, false); } else { @@ -1087,12 +1086,10 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) brcmf_dbg(SDIO, "Enter\n"); /* Read mailbox data and ack that we did so */ - ret = r_sdreg32(bus, &hmb_data, - offsetof(struct sdpcmd_regs, tohostmailboxdata)); + ret = r_sdreg32(bus, &hmb_data, SD_REG(tohostmailboxdata)); if (ret == 0) - w_sdreg32(bus, SMB_INT_ACK, - offsetof(struct sdpcmd_regs, tosbmailbox)); + w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox)); bus->sdcnt.f1regdata += 2; /* dongle indicates the firmware has halted/crashed */ @@ -1178,16 +1175,16 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) if (abort) brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_RF_TERM, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, + &err); bus->sdcnt.f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = brcmf_sdiod_regrb(bus->sdiodev, - SBSDIO_FUNC1_RFRAMEBCHI, &err); - lo = brcmf_sdiod_regrb(bus->sdiodev, - SBSDIO_FUNC1_RFRAMEBCLO, &err); + hi = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCHI, + &err); + lo = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO, + &err); bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) @@ -1207,8 +1204,7 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) if (rtx) { bus->sdcnt.rxrtx++; - err = w_sdreg32(bus, SMB_NAK, - offsetof(struct sdpcmd_regs, tosbmailbox)); + err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox)); bus->sdcnt.f1regdata++; if (err == 0) @@ -1229,12 +1225,12 @@ static void brcmf_sdio_txfail(struct brcmf_sdio *bus) bus->sdcnt.tx_sderrs++; brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2); - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { - hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); + hi = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); + lo = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -2333,9 +2329,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) if (!bus->intr) { /* Check device status, signal pending interrupt */ sdio_claim_host(bus->sdiodev->func[1]); - ret = r_sdreg32(bus, &intstatus, - offsetof(struct sdpcmd_regs, - intstatus)); + ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus)); sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2txdata++; if (ret != 0) @@ -2441,16 +2435,16 @@ static void brcmf_sdio_bus_stop(struct device *dev) brcmf_sdio_bus_sleep(bus, false, false); /* Disable and clear interrupts at the chip level also */ - w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); + w_sdreg32(bus, 0, SD_REG(hostintmask)); local_hostintmask = bus->hostintmask; bus->hostintmask = 0; /* Force backplane clocks to assure F2 interrupt propagates */ - saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); if (err) brcmf_err("Failed to force clock for F2: err %d\n", err); @@ -2460,8 +2454,7 @@ static void brcmf_sdio_bus_stop(struct device *dev) sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); /* Clear any pending interrupts now that F2 is disabled */ - w_sdreg32(bus, local_hostintmask, - offsetof(struct sdpcmd_regs, intstatus)); + w_sdreg32(bus, local_hostintmask, SD_REG(intstatus)); sdio_release_host(sdiodev->func[1]); } @@ -2501,15 +2494,14 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) { - struct brcmf_core *buscore; + struct brcmf_core *buscore = bus->sdio_core; u32 addr; unsigned long val; int ret; - buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); - addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); + addr = buscore->base + SD_REG(intstatus); - val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); + val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); bus->sdcnt.f1regdata++; if (ret != 0) return ret; @@ -2519,7 +2511,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) /* Clear interrupts */ if (val) { - brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); + brcmf_sdiod_writel(bus->sdiodev, addr, val, &ret); bus->sdcnt.f1regdata++; atomic_or(val, &bus->intstatus); } @@ -2545,23 +2537,23 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) #ifdef DEBUG /* Check for inconsistent device control */ - devctl = brcmf_sdiod_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, + &err); #endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = brcmf_sdiod_regrb(bus->sdiodev, + clkctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl); if (SBSDIO_HTAV(clkctl)) { - devctl = brcmf_sdiod_regrb(bus->sdiodev, + devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_writeb(bus->sdiodev, + SBSDIO_DEVICE_CTL, devctl, &err); bus->clkstate = CLK_AVAIL; } } @@ -2584,11 +2576,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) */ if (intstatus & I_HMB_FC_CHANGE) { intstatus &= ~I_HMB_FC_CHANGE; - err = w_sdreg32(bus, I_HMB_FC_CHANGE, - offsetof(struct sdpcmd_regs, intstatus)); + err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus)); - err = r_sdreg32(bus, &newstatus, - offsetof(struct sdpcmd_regs, intstatus)); + err = r_sdreg32(bus, &newstatus, SD_REG(intstatus)); bus->sdcnt.f1regdata += 2; atomic_set(&bus->fcstate, !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE))); @@ -3347,31 +3337,31 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); - val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); + val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); if (err) { brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); return; } val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); if (err) { brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); return; } /* Add CMD14 Support */ - brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, - (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | - SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), - &err); + brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, + (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | + SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), + &err); if (err) { brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); return; } - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HT, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_FORCE_HT, &err); if (err) { brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); return; @@ -3385,16 +3375,17 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) /* enable KSO bit */ static int brcmf_sdio_kso_init(struct brcmf_sdio *bus) { + struct brcmf_core *core = bus->sdio_core; u8 val; int err = 0; brcmf_dbg(TRACE, "Enter\n"); /* KSO bit added in SDIO core rev 12 */ - if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) + if (core->rev < 12) return 0; - val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); + val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); if (err) { brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); return err; @@ -3403,8 +3394,8 @@ static int brcmf_sdio_kso_init(struct brcmf_sdio *bus) if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - val, &err); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + val, &err); if (err) { brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); return err; @@ -3420,6 +3411,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; + struct brcmf_core *core = bus->sdio_core; uint pad_size; u32 value; int err; @@ -3428,7 +3420,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev) * a device perspective, ie. bus:txglom affects the * bus transfers from device to host. */ - if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) { + if (core->rev < 12) { /* for sdio core rev < 12, disable txgloming */ value = 0; err = brcmf_iovar_data_set(dev, "bus:txglom", &value, @@ -3565,9 +3557,9 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) u8 devpend; sdio_claim_host(bus->sdiodev->func[1]); - devpend = brcmf_sdiod_regrb(bus->sdiodev, - SDIO_CCCR_INTx, - NULL); + devpend = brcmf_sdiod_func0_rb(bus->sdiodev, + SDIO_CCCR_INTx, + NULL); sdio_release_host(bus->sdiodev->func[1]); intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); @@ -3705,12 +3697,12 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, } } addr = CORE_CC_REG(pmu->base, chipcontrol_addr); - brcmf_sdiod_regwl(sdiodev, addr, 1, NULL); - cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL); + brcmf_sdiod_writel(sdiodev, addr, 1, NULL); + cc_data_temp = brcmf_sdiod_readl(sdiodev, addr, NULL); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL); + brcmf_sdiod_writel(sdiodev, addr, cc_data_temp, NULL); brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", str_tab[i].strength, drivestrength, cc_data_temp); @@ -3725,7 +3717,7 @@ static int brcmf_sdio_buscoreprep(void *ctx) /* Try forcing SDIO core to do ALPAvail request only */ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); if (err) { brcmf_err("error writing for HT off\n"); return err; @@ -3733,8 +3725,7 @@ static int brcmf_sdio_buscoreprep(void *ctx) /* If register supported, wait for ALPAvail and then force ALP */ /* This may take up to 15 milliseconds */ - clkval = brcmf_sdiod_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, NULL); + clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL); if ((clkval & ~SBSDIO_AVBITS) != clkset) { brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n", @@ -3742,10 +3733,11 @@ static int brcmf_sdio_buscoreprep(void *ctx) return -EACCES; } - SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), - !SBSDIO_ALPAV(clkval)), - PMU_MAX_TRANSITION_DLY); + SPINWAIT(((clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + NULL)), + !SBSDIO_ALPAV(clkval)), + PMU_MAX_TRANSITION_DLY); + if (!SBSDIO_ALPAV(clkval)) { brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n", clkval); @@ -3753,11 +3745,11 @@ static int brcmf_sdio_buscoreprep(void *ctx) } clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); udelay(65); /* Also, disable the extra SDIO pull-ups */ - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); return 0; } @@ -3766,13 +3758,12 @@ static void brcmf_sdio_buscore_activate(void *ctx, struct brcmf_chip *chip, u32 rstvec) { struct brcmf_sdio_dev *sdiodev = ctx; - struct brcmf_core *core; + struct brcmf_core *core = sdiodev->bus->sdio_core; u32 reg_addr; /* clear all interrupts */ - core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); - reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus); - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + reg_addr = core->base + SD_REG(intstatus); + brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); if (rstvec) /* Write reset vector to address 0 */ @@ -3785,7 +3776,7 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr) struct brcmf_sdio_dev *sdiodev = ctx; u32 val, rev; - val = brcmf_sdiod_regrl(sdiodev, addr, NULL); + val = brcmf_sdiod_readl(sdiodev, addr, NULL); if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { @@ -3802,7 +3793,7 @@ static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val) { struct brcmf_sdio_dev *sdiodev = ctx; - brcmf_sdiod_regwl(sdiodev, addr, val, NULL); + brcmf_sdiod_writel(sdiodev, addr, val, NULL); } static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { @@ -3826,18 +3817,18 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) sdio_claim_host(sdiodev->func[1]); pr_debug("F1 signature read @0x18000000=0x%4x\n", - brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL)); + brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL)); /* * Force PLL off until brcmf_chip_attach() * programs PLL control regs */ - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - BRCMF_INIT_CLKCTL1, &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1, + &err); if (!err) - clkctl = brcmf_sdiod_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + clkctl = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + &err); if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", @@ -3851,6 +3842,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) bus->ci = NULL; goto fail; } + + /* Pick up the SDIO core info struct from chip.c */ + bus->sdio_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); + if (!bus->sdio_core) + goto fail; + sdiodev->settings = brcmf_get_module_param(sdiodev->dev, BRCMF_BUSTYPE_SDIO, bus->ci->chip, @@ -3897,25 +3894,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); /* Set card control so an SDIO card reset does a WLAN backplane reset */ - reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); + reg_val = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); if (err) goto fail; reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; - brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); if (err) goto fail; /* set PMUControl so a backplane reset does PMU state reload */ reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); - reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err); + reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err); if (err) goto fail; reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); - brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err); + brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err); if (err) goto fail; @@ -4055,10 +4052,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, goto release; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); + saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) { brcmf_err("Failed to force clock for F2: err %d\n", err); @@ -4067,7 +4064,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, /* Enable function 2 (frame transfers) */ w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, - offsetof(struct sdpcmd_regs, tosbmailboxdata)); + SD_REG(tosbmailboxdata)); err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); @@ -4077,10 +4074,9 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, if (!err) { /* Set up the interrupt mask and enable interrupts */ bus->hostintmask = HOSTINTMASK; - w_sdreg32(bus, bus->hostintmask, - offsetof(struct sdpcmd_regs, hostintmask)); + w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask)); - brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); } else { /* Disable F2 again */ sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); @@ -4091,8 +4087,8 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, brcmf_sdio_sr_init(bus); } else { /* Restore previous clock setting */ - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - saveclk, &err); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + saveclk, &err); } if (err == 0) { @@ -4224,7 +4220,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) bus->rxflow = false; /* Done with backplane-dependent accesses, can drop clock... */ - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); sdio_release_host(bus->sdiodev->func[1]); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index f3da32fc6360..01def16cd236 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h @@ -50,17 +50,19 @@ #define SBSDIO_NUM_FUNCTION 3 /* function 0 vendor specific CCCR registers */ + #define SDIO_CCCR_BRCM_CARDCAP 0xf0 -#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 -#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 -#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 -#define SDIO_CCCR_BRCM_CARDCTRL 0xf1 -#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02 -#define SDIO_CCCR_BRCM_SEPINT 0xf2 +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT BIT(1) +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2) +#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3) -#define SDIO_SEPINT_MASK 0x01 -#define SDIO_SEPINT_OE 0x02 -#define SDIO_SEPINT_ACT_HI 0x04 +#define SDIO_CCCR_BRCM_CARDCTRL 0xf1 +#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET BIT(1) + +#define SDIO_CCCR_BRCM_SEPINT 0xf2 +#define SDIO_CCCR_BRCM_SEPINT_MASK BIT(0) +#define SDIO_CCCR_BRCM_SEPINT_OE BIT(1) +#define SDIO_CCCR_BRCM_SEPINT_ACT_HI BIT(2) /* function 1 miscellaneous registers */ @@ -131,11 +133,6 @@ /* with b15, maps to 32-bit SB access */ #define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 -/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ - -#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ -#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ -#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ /* Address bits from SBADDR regs */ #define SBSDIO_SBWINDOW_MASK 0xffff8000 @@ -296,13 +293,24 @@ struct sdpcmd_regs { int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev); void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev); -/* sdio device register access interface */ -u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, - int *ret); -void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, - int *ret); +/* SDIO device register access interface */ +/* Accessors for SDIO Function 0 */ +#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ + sdio_readb((sdiodev)->func[0], (addr), (r)) + +#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ + sdio_writeb((sdiodev)->func[0], (v), (addr), (ret)) + +/* Accessors for SDIO Function 1 */ +#define brcmf_sdiod_readb(sdiodev, addr, r) \ + sdio_readb((sdiodev)->func[1], (addr), (r)) + +#define brcmf_sdiod_writeb(sdiodev, addr, v, ret) \ + sdio_writeb((sdiodev)->func[1], (v), (addr), (ret)) + +u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, + int *ret); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number @@ -342,7 +350,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, u8 *data, uint size); /* Issue an abort to the specified function */ -int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn); void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev); void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, enum brcmf_sdiod_state state); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index 763e8ba6b178..7e01981bc5c8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -16049,8 +16049,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU, rfseq_updategainu_events, rfseq_updategainu_dlys, - sizeof(rfseq_updategainu_events) / - sizeof(rfseq_updategainu_events[0])); + ARRAY_SIZE(rfseq_updategainu_events)); mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8)); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c index dbf50ef6cd75..533bd4b0277e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c @@ -14,6 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <linux/kernel.h> #include <types.h> #include "phytbl_n.h" @@ -4437,109 +4438,39 @@ static const u16 loft_lut_core1_rev0[] = { }; const struct phytbl_info mimophytbl_info_rev0_volatile[] = { - {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0, - 16} - , - {&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]), - 20, 0, 32} - , - {&gainctrl_lut_core0_rev0, - sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev0, - sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]), - 27, 192, 32} - , - - {&est_pwr_lut_core0_rev0, - sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev0, - sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev0, - sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev0, - sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27, - 64, 8} - , - {&iq_lut_core0_rev0, - sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32} - , - {&iq_lut_core1_rev0, - sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32} - , - {&loft_lut_core0_rev0, - sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev0, - sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448, - 16} - , + {&bdi_tbl_rev0, ARRAY_SIZE(bdi_tbl_rev0), 21, 0, 16}, + {&pltlut_tbl_rev0, ARRAY_SIZE(pltlut_tbl_rev0), 20, 0, 32}, + {&gainctrl_lut_core0_rev0, ARRAY_SIZE(gainctrl_lut_core0_rev0), 26, 192, 32}, + {&gainctrl_lut_core1_rev0, ARRAY_SIZE(gainctrl_lut_core1_rev0), 27, 192, 32}, + {&est_pwr_lut_core0_rev0, ARRAY_SIZE(est_pwr_lut_core0_rev0), 26, 0, 8}, + {&est_pwr_lut_core1_rev0, ARRAY_SIZE(est_pwr_lut_core1_rev0), 27, 0, 8}, + {&adj_pwr_lut_core0_rev0, ARRAY_SIZE(adj_pwr_lut_core0_rev0), 26, 64, 8}, + {&adj_pwr_lut_core1_rev0, ARRAY_SIZE(adj_pwr_lut_core1_rev0), 27, 64, 8}, + {&iq_lut_core0_rev0, ARRAY_SIZE(iq_lut_core0_rev0), 26, 320, 32}, + {&iq_lut_core1_rev0, ARRAY_SIZE(iq_lut_core1_rev0), 27, 320, 32}, + {&loft_lut_core0_rev0, ARRAY_SIZE(loft_lut_core0_rev0), 26, 448, 16}, + {&loft_lut_core1_rev0, ARRAY_SIZE(loft_lut_core1_rev0), 27, 448, 16}, }; const struct phytbl_info mimophytbl_info_rev0[] = { - {&frame_struct_rev0, - sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32} - , - {&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]), - 24, 0, 8} - , - {&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12, - 0, 32} - , - {&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]), - 14, 0, 32} - , - {&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]), - 13, 0, 32} - , - {&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]), - 11, 0, 16} - , - {&tdi_tbl20_ant0_rev0, - sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128, - 32} - , - {&tdi_tbl20_ant1_rev0, - sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256, - 32} - , - {&tdi_tbl40_ant0_rev0, - sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640, - 32} - , - {&tdi_tbl40_ant1_rev0, - sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768, - 32} - , - {&chanest_tbl_rev0, - sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32} - , - {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, - 8} - , - {&noise_var_tbl0_rev0, - sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0, - 32} - , - {&noise_var_tbl1_rev0, - sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128, - 32} - , + {&frame_struct_rev0, ARRAY_SIZE(frame_struct_rev0), 10, 0, 32}, + {&frame_lut_rev0, ARRAY_SIZE(frame_lut_rev0), 24, 0, 8}, + {&tmap_tbl_rev0, ARRAY_SIZE(tmap_tbl_rev0), 12, 0, 32}, + {&tdtrn_tbl_rev0, ARRAY_SIZE(tdtrn_tbl_rev0), 14, 0, 32}, + {&intlv_tbl_rev0, ARRAY_SIZE(intlv_tbl_rev0), 13, 0, 32}, + {&pilot_tbl_rev0, ARRAY_SIZE(pilot_tbl_rev0), 11, 0, 16}, + {&tdi_tbl20_ant0_rev0, ARRAY_SIZE(tdi_tbl20_ant0_rev0), 19, 128, 32}, + {&tdi_tbl20_ant1_rev0, ARRAY_SIZE(tdi_tbl20_ant1_rev0), 19, 256, 32}, + {&tdi_tbl40_ant0_rev0, ARRAY_SIZE(tdi_tbl40_ant0_rev0), 19, 640, 32}, + {&tdi_tbl40_ant1_rev0, ARRAY_SIZE(tdi_tbl40_ant1_rev0), 19, 768, 32}, + {&chanest_tbl_rev0, ARRAY_SIZE(chanest_tbl_rev0), 22, 0, 32}, + {&mcs_tbl_rev0, ARRAY_SIZE(mcs_tbl_rev0), 18, 0, 8}, + {&noise_var_tbl0_rev0, ARRAY_SIZE(noise_var_tbl0_rev0), 16, 0, 32}, + {&noise_var_tbl1_rev0, ARRAY_SIZE(noise_var_tbl1_rev0), 16, 128, 32}, }; -const u32 mimophytbl_info_sz_rev0 = - sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]); -const u32 mimophytbl_info_sz_rev0_volatile = - sizeof(mimophytbl_info_rev0_volatile) / - sizeof(mimophytbl_info_rev0_volatile[0]); +const u32 mimophytbl_info_sz_rev0 = ARRAY_SIZE(mimophytbl_info_rev0); +const u32 mimophytbl_info_sz_rev0_volatile = ARRAY_SIZE(mimophytbl_info_rev0_volatile); static const u16 ant_swctrl_tbl_rev3[] = { 0x0082, @@ -9363,132 +9294,53 @@ static const u32 papd_cal_scalars_tbl_core1_rev3[] = { }; const struct phytbl_info mimophytbl_info_rev3_volatile[] = { - {&ant_swctrl_tbl_rev3, - sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16} - , + {&ant_swctrl_tbl_rev3, ARRAY_SIZE(ant_swctrl_tbl_rev3), 9, 0, 16}, }; const struct phytbl_info mimophytbl_info_rev3_volatile1[] = { - {&ant_swctrl_tbl_rev3_1, - sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0, - 16} - , + {&ant_swctrl_tbl_rev3_1, ARRAY_SIZE(ant_swctrl_tbl_rev3_1), 9, 0, 16}, }; const struct phytbl_info mimophytbl_info_rev3_volatile2[] = { - {&ant_swctrl_tbl_rev3_2, - sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0, - 16} - , + {&ant_swctrl_tbl_rev3_2, ARRAY_SIZE(ant_swctrl_tbl_rev3_2), 9, 0, 16}, }; const struct phytbl_info mimophytbl_info_rev3_volatile3[] = { - {&ant_swctrl_tbl_rev3_3, - sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0, - 16} - , + {&ant_swctrl_tbl_rev3_3, ARRAY_SIZE(ant_swctrl_tbl_rev3_3), 9, 0, 16}, }; const struct phytbl_info mimophytbl_info_rev3[] = { - {&frame_struct_rev3, - sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} - , - {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]), - 11, 0, 16} - , - {&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12, - 0, 32} - , - {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]), - 13, 0, 32} - , - {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]), - 14, 0, 32} - , - {&noise_var_tbl_rev3, - sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32} - , - {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0, - 16} - , - {&tdi_tbl20_ant0_rev3, - sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128, - 32} - , - {&tdi_tbl20_ant1_rev3, - sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256, - 32} - , - {&tdi_tbl40_ant0_rev3, - sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640, - 32} - , - {&tdi_tbl40_ant1_rev3, - sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768, - 32} - , - {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]), - 20, 0, 32} - , - {&chanest_tbl_rev3, - sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32} - , - {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]), - 24, 0, 8} - , - {&est_pwr_lut_core0_rev3, - sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev3, - sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev3, - sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev3, - sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, - 64, 8} - , - {&gainctrl_lut_core0_rev3, - sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev3, - sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), - 27, 192, 32} - , - {&iq_lut_core0_rev3, - sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} - , - {&iq_lut_core1_rev3, - sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} - , - {&loft_lut_core0_rev3, - sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev3, - sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, - 16} + {&frame_struct_rev3, ARRAY_SIZE(frame_struct_rev3), 10, 0, 32}, + {&pilot_tbl_rev3, ARRAY_SIZE(pilot_tbl_rev3), 11, 0, 16}, + {&tmap_tbl_rev3, ARRAY_SIZE(tmap_tbl_rev3), 12, 0, 32}, + {&intlv_tbl_rev3, ARRAY_SIZE(intlv_tbl_rev3), 13, 0, 32}, + {&tdtrn_tbl_rev3, ARRAY_SIZE(tdtrn_tbl_rev3), 14, 0, 32}, + {&noise_var_tbl_rev3, ARRAY_SIZE(noise_var_tbl_rev3), 16, 0, 32}, + {&mcs_tbl_rev3, ARRAY_SIZE(mcs_tbl_rev3), 18, 0, 16}, + {&tdi_tbl20_ant0_rev3, ARRAY_SIZE(tdi_tbl20_ant0_rev3), 19, 128, 32}, + {&tdi_tbl20_ant1_rev3, ARRAY_SIZE(tdi_tbl20_ant1_rev3), 19, 256, 32}, + {&tdi_tbl40_ant0_rev3, ARRAY_SIZE(tdi_tbl40_ant0_rev3), 19, 640, 32}, + {&tdi_tbl40_ant1_rev3, ARRAY_SIZE(tdi_tbl40_ant1_rev3), 19, 768, 32}, + {&pltlut_tbl_rev3, ARRAY_SIZE(pltlut_tbl_rev3), 20, 0, 32}, + {&chanest_tbl_rev3, ARRAY_SIZE(chanest_tbl_rev3), 22, 0, 32}, + {&frame_lut_rev3, ARRAY_SIZE(frame_lut_rev3), 24, 0, 8}, + {&est_pwr_lut_core0_rev3, ARRAY_SIZE(est_pwr_lut_core0_rev3), 26, 0, 8}, + {&est_pwr_lut_core1_rev3, ARRAY_SIZE(est_pwr_lut_core1_rev3), 27, 0, 8}, + {&adj_pwr_lut_core0_rev3, ARRAY_SIZE(adj_pwr_lut_core0_rev3), 26, 64, 8}, + {&adj_pwr_lut_core1_rev3, ARRAY_SIZE(adj_pwr_lut_core1_rev3), 27, 64, 8}, + {&gainctrl_lut_core0_rev3, ARRAY_SIZE(gainctrl_lut_core0_rev3), 26, 192, 32}, + {&gainctrl_lut_core1_rev3, ARRAY_SIZE(gainctrl_lut_core1_rev3), 27, 192, 32}, + {&iq_lut_core0_rev3, ARRAY_SIZE(iq_lut_core0_rev3), 26, 320, 32}, + {&iq_lut_core1_rev3, ARRAY_SIZE(iq_lut_core1_rev3), 27, 320, 32}, + {&loft_lut_core0_rev3, ARRAY_SIZE(loft_lut_core0_rev3), 26, 448, 16}, + {&loft_lut_core1_rev3, ARRAY_SIZE(loft_lut_core1_rev3), 27, 448, 16} }; -const u32 mimophytbl_info_sz_rev3 = - sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]); -const u32 mimophytbl_info_sz_rev3_volatile = - sizeof(mimophytbl_info_rev3_volatile) / - sizeof(mimophytbl_info_rev3_volatile[0]); -const u32 mimophytbl_info_sz_rev3_volatile1 = - sizeof(mimophytbl_info_rev3_volatile1) / - sizeof(mimophytbl_info_rev3_volatile1[0]); -const u32 mimophytbl_info_sz_rev3_volatile2 = - sizeof(mimophytbl_info_rev3_volatile2) / - sizeof(mimophytbl_info_rev3_volatile2[0]); -const u32 mimophytbl_info_sz_rev3_volatile3 = - sizeof(mimophytbl_info_rev3_volatile3) / - sizeof(mimophytbl_info_rev3_volatile3[0]); +const u32 mimophytbl_info_sz_rev3 = ARRAY_SIZE(mimophytbl_info_rev3); +const u32 mimophytbl_info_sz_rev3_volatile = ARRAY_SIZE(mimophytbl_info_rev3_volatile); +const u32 mimophytbl_info_sz_rev3_volatile1 = ARRAY_SIZE(mimophytbl_info_rev3_volatile1); +const u32 mimophytbl_info_sz_rev3_volatile2 = ARRAY_SIZE(mimophytbl_info_rev3_volatile2); +const u32 mimophytbl_info_sz_rev3_volatile3 = ARRAY_SIZE(mimophytbl_info_rev3_volatile3); static const u32 tmap_tbl_rev7[] = { 0x8a88aa80, @@ -10469,162 +10321,58 @@ static const u32 papd_cal_scalars_tbl_core1_rev7[] = { }; const struct phytbl_info mimophytbl_info_rev7[] = { - {&frame_struct_rev3, - sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} - , - {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]), - 11, 0, 16} - , - {&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12, - 0, 32} - , - {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]), - 13, 0, 32} - , - {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]), - 14, 0, 32} - , - {&noise_var_tbl_rev7, - sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} - , - {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0, - 16} - , - {&tdi_tbl20_ant0_rev3, - sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128, - 32} - , - {&tdi_tbl20_ant1_rev3, - sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256, - 32} - , - {&tdi_tbl40_ant0_rev3, - sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640, - 32} - , - {&tdi_tbl40_ant1_rev3, - sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768, - 32} - , - {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]), - 20, 0, 32} - , - {&chanest_tbl_rev3, - sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32} - , - {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]), - 24, 0, 8} - , - {&est_pwr_lut_core0_rev3, - sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev3, - sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev3, - sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev3, - sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, - 64, 8} - , - {&gainctrl_lut_core0_rev3, - sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev3, - sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), - 27, 192, 32} - , - {&iq_lut_core0_rev3, - sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} - , - {&iq_lut_core1_rev3, - sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} - , - {&loft_lut_core0_rev3, - sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev3, - sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, - 16} - , + {&frame_struct_rev3, ARRAY_SIZE(frame_struct_rev3), 10, 0, 32}, + {&pilot_tbl_rev3, ARRAY_SIZE(pilot_tbl_rev3), 11, 0, 16}, + {&tmap_tbl_rev7, ARRAY_SIZE(tmap_tbl_rev7), 12, 0, 32}, + {&intlv_tbl_rev3, ARRAY_SIZE(intlv_tbl_rev3), 13, 0, 32}, + {&tdtrn_tbl_rev3, ARRAY_SIZE(tdtrn_tbl_rev3), 14, 0, 32}, + {&noise_var_tbl_rev7, ARRAY_SIZE(noise_var_tbl_rev7), 16, 0, 32}, + {&mcs_tbl_rev3, ARRAY_SIZE(mcs_tbl_rev3), 18, 0, 16}, + {&tdi_tbl20_ant0_rev3, ARRAY_SIZE(tdi_tbl20_ant0_rev3), 19, 128, 32}, + {&tdi_tbl20_ant1_rev3, ARRAY_SIZE(tdi_tbl20_ant1_rev3), 19, 256, 32}, + {&tdi_tbl40_ant0_rev3, ARRAY_SIZE(tdi_tbl40_ant0_rev3), 19, 640, 32}, + {&tdi_tbl40_ant1_rev3, ARRAY_SIZE(tdi_tbl40_ant1_rev3), 19, 768, 32}, + {&pltlut_tbl_rev3, ARRAY_SIZE(pltlut_tbl_rev3), 20, 0, 32}, + {&chanest_tbl_rev3, ARRAY_SIZE(chanest_tbl_rev3), 22, 0, 32}, + {&frame_lut_rev3, ARRAY_SIZE(frame_lut_rev3), 24, 0, 8}, + {&est_pwr_lut_core0_rev3, ARRAY_SIZE(est_pwr_lut_core0_rev3), 26, 0, 8}, + {&est_pwr_lut_core1_rev3, ARRAY_SIZE(est_pwr_lut_core1_rev3), 27, 0, 8}, + {&adj_pwr_lut_core0_rev3, ARRAY_SIZE(adj_pwr_lut_core0_rev3), 26, 64, 8}, + {&adj_pwr_lut_core1_rev3, ARRAY_SIZE(adj_pwr_lut_core1_rev3), 27, 64, 8}, + {&gainctrl_lut_core0_rev3, ARRAY_SIZE(gainctrl_lut_core0_rev3), 26, 192, 32}, + {&gainctrl_lut_core1_rev3, ARRAY_SIZE(gainctrl_lut_core1_rev3), 27, 192, 32}, + {&iq_lut_core0_rev3, ARRAY_SIZE(iq_lut_core0_rev3), 26, 320, 32}, + {&iq_lut_core1_rev3, ARRAY_SIZE(iq_lut_core1_rev3), 27, 320, 32}, + {&loft_lut_core0_rev3, ARRAY_SIZE(loft_lut_core0_rev3), 26, 448, 16}, + {&loft_lut_core1_rev3, ARRAY_SIZE(loft_lut_core1_rev3), 27, 448, 16}, {&papd_comp_rfpwr_tbl_core0_rev3, - sizeof(papd_comp_rfpwr_tbl_core0_rev3) / - sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16} - , + ARRAY_SIZE(papd_comp_rfpwr_tbl_core0_rev3), 26, 576, 16}, {&papd_comp_rfpwr_tbl_core1_rev3, - sizeof(papd_comp_rfpwr_tbl_core1_rev3) / - sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16} - , + ARRAY_SIZE(papd_comp_rfpwr_tbl_core1_rev3), 27, 576, 16}, {&papd_comp_epsilon_tbl_core0_rev7, - sizeof(papd_comp_epsilon_tbl_core0_rev7) / - sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32} - , + ARRAY_SIZE(papd_comp_epsilon_tbl_core0_rev7), 31, 0, 32}, {&papd_cal_scalars_tbl_core0_rev7, - sizeof(papd_cal_scalars_tbl_core0_rev7) / - sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32} - , + ARRAY_SIZE(papd_cal_scalars_tbl_core0_rev7), 32, 0, 32}, {&papd_comp_epsilon_tbl_core1_rev7, - sizeof(papd_comp_epsilon_tbl_core1_rev7) / - sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32} - , + ARRAY_SIZE(papd_comp_epsilon_tbl_core1_rev7), 33, 0, 32}, {&papd_cal_scalars_tbl_core1_rev7, - sizeof(papd_cal_scalars_tbl_core1_rev7) / - sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32} - , + ARRAY_SIZE(papd_cal_scalars_tbl_core1_rev7), 34, 0, 32}, }; -const u32 mimophytbl_info_sz_rev7 = - sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]); +const u32 mimophytbl_info_sz_rev7 = ARRAY_SIZE(mimophytbl_info_rev7); const struct phytbl_info mimophytbl_info_rev16[] = { - {&noise_var_tbl_rev7, - sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} - , - {&est_pwr_lut_core0_rev3, - sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev3, - sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev3, - sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev3, - sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, - 64, 8} - , - {&gainctrl_lut_core0_rev3, - sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev3, - sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), - 27, 192, 32} - , - {&iq_lut_core0_rev3, - sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} - , - {&iq_lut_core1_rev3, - sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} - , - {&loft_lut_core0_rev3, - sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev3, - sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, - 16} - , + {&noise_var_tbl_rev7, ARRAY_SIZE(noise_var_tbl_rev7), 16, 0, 32}, + {&est_pwr_lut_core0_rev3, ARRAY_SIZE(est_pwr_lut_core0_rev3), 26, 0, 8}, + {&est_pwr_lut_core1_rev3, ARRAY_SIZE(est_pwr_lut_core1_rev3), 27, 0, 8}, + {&adj_pwr_lut_core0_rev3, ARRAY_SIZE(adj_pwr_lut_core0_rev3), 26, 64, 8}, + {&adj_pwr_lut_core1_rev3, ARRAY_SIZE(adj_pwr_lut_core1_rev3), 27, 64, 8}, + {&gainctrl_lut_core0_rev3, ARRAY_SIZE(gainctrl_lut_core0_rev3), 26, 192, 32}, + {&gainctrl_lut_core1_rev3, ARRAY_SIZE(gainctrl_lut_core1_rev3), 27, 192, 32}, + {&iq_lut_core0_rev3, ARRAY_SIZE(iq_lut_core0_rev3), 26, 320, 32}, + {&iq_lut_core1_rev3, ARRAY_SIZE(iq_lut_core1_rev3), 27, 320, 32}, + {&loft_lut_core0_rev3, ARRAY_SIZE(loft_lut_core0_rev3), 26, 448, 16}, + {&loft_lut_core1_rev3, ARRAY_SIZE(loft_lut_core1_rev3), 27, 448, 16}, }; -const u32 mimophytbl_info_sz_rev16 = - sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]); +const u32 mimophytbl_info_sz_rev16 = ARRAY_SIZE(mimophytbl_info_rev16); diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile index ff136f299a0a..e2c151ae8649 100644 --- a/drivers/net/wireless/intel/iwlwifi/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/Makefile @@ -9,7 +9,7 @@ iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o iwlwifi-objs += pcie/ctxt-info.o pcie/trans-gen2.o pcie/tx-gen2.o iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o cfg/5000.o cfg/6000.o -iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/a000.o +iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/22000.o iwlwifi-objs += iwl-trans.o iwlwifi-objs += fw/notif-wait.o iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c new file mode 100644 index 000000000000..48f6f80eb24b --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -0,0 +1,216 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015-2017 Intel Deutschland GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2015-2017 Intel Deutschland GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include <linux/module.h> +#include <linux/stringify.h> +#include "iwl-config.h" +#include "iwl-agn-hw.h" + +/* Highest firmware API version supported */ +#define IWL_22000_UCODE_API_MAX 36 + +/* Lowest firmware API version supported */ +#define IWL_22000_UCODE_API_MIN 24 + +/* NVM versions */ +#define IWL_22000_NVM_VERSION 0x0a1d +#define IWL_22000_TX_POWER_VERSION 0xffff /* meaningless */ + +/* Memory offsets and lengths */ +#define IWL_22000_DCCM_OFFSET 0x800000 /* LMAC1 */ +#define IWL_22000_DCCM_LEN 0x10000 /* LMAC1 */ +#define IWL_22000_DCCM2_OFFSET 0x880000 +#define IWL_22000_DCCM2_LEN 0x8000 +#define IWL_22000_SMEM_OFFSET 0x400000 +#define IWL_22000_SMEM_LEN 0xD0000 + +#define IWL_22000_JF_FW_PRE "iwlwifi-Qu-a0-jf-b0-" +#define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-" +#define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-" +#define IWL_22000_HR_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" +#define IWL_22000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-" +#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" + +#define IWL_22000_HR_MODULE_FIRMWARE(api) \ + IWL_22000_HR_FW_PRE __stringify(api) ".ucode" +#define IWL_22000_JF_MODULE_FIRMWARE(api) \ + IWL_22000_JF_FW_PRE __stringify(api) ".ucode" +#define IWL_22000_HR_F0_QNJ_MODULE_FIRMWARE(api) \ + IWL_22000_HR_F0_FW_PRE __stringify(api) ".ucode" +#define IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(api) \ + IWL_22000_JF_B0_FW_PRE __stringify(api) ".ucode" +#define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \ + IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" + +#define NVM_HW_SECTION_NUM_FAMILY_22000 10 + +static const struct iwl_base_params iwl_22000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000, + .num_of_queues = 512, + .shadow_ram_support = true, + .led_compensation = 57, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = true, + .pcie_l1_allowed = true, +}; + +static const struct iwl_ht_params iwl_22000_ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), +}; + +#define IWL_DEVICE_22000 \ + .ucode_api_max = IWL_22000_UCODE_API_MAX, \ + .ucode_api_min = IWL_22000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_22000, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .base_params = &iwl_22000_base_params, \ + .led_mode = IWL_LED_RF_STATE, \ + .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_22000, \ + .non_shared_ant = ANT_A, \ + .dccm_offset = IWL_22000_DCCM_OFFSET, \ + .dccm_len = IWL_22000_DCCM_LEN, \ + .dccm2_offset = IWL_22000_DCCM2_OFFSET, \ + .dccm2_len = IWL_22000_DCCM2_LEN, \ + .smem_offset = IWL_22000_SMEM_OFFSET, \ + .smem_len = IWL_22000_SMEM_LEN, \ + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ + .apmg_not_supported = true, \ + .mq_rx_supported = true, \ + .vht_mu_mimo_supported = true, \ + .mac_addr_from_csr = true, \ + .use_tfh = true, \ + .rf_id = true, \ + .gen2 = true, \ + .nvm_type = IWL_NVM_EXT, \ + .dbgc_supported = true, \ + .tx_cmd_queue_size = 32, \ + .min_umac_error_event_table = 0x400000 + +const struct iwl_cfg iwl22000_2ac_cfg_hr = { + .name = "Intel(R) Dual Band Wireless AC 22000", + .fw_name_pre = IWL_22000_HR_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + +const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb = { + .name = "Intel(R) Dual Band Wireless AC 22000", + .fw_name_pre = IWL_22000_HR_CDB_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, + .cdb = true, +}; + +const struct iwl_cfg iwl22000_2ac_cfg_jf = { + .name = "Intel(R) Dual Band Wireless AC 22000", + .fw_name_pre = IWL_22000_JF_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + +const struct iwl_cfg iwl22000_2ax_cfg_hr = { + .name = "Intel(R) Dual Band Wireless AX 22000", + .fw_name_pre = IWL_22000_HR_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + +const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_f0 = { + .name = "Intel(R) Dual Band Wireless AX 22000", + .fw_name_pre = IWL_22000_HR_F0_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + +const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0 = { + .name = "Intel(R) Dual Band Wireless AX 22000", + .fw_name_pre = IWL_22000_JF_B0_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + +const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { + .name = "Intel(R) Dual Band Wireless AX 22000", + .fw_name_pre = IWL_22000_HR_A0_FW_PRE, + IWL_DEVICE_22000, + .ht_params = &iwl_22000_ht_params, + .nvm_ver = IWL_22000_NVM_VERSION, + .nvm_calib_ver = IWL_22000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + +MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_22000_HR_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index 9bb7c19d48eb..3f4d9bac9f73 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -70,8 +70,8 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL8000_UCODE_API_MAX 34 -#define IWL8265_UCODE_API_MAX 34 +#define IWL8000_UCODE_API_MAX 36 +#define IWL8265_UCODE_API_MAX 36 /* Lowest firmware API version supported */ #define IWL8000_UCODE_API_MIN 22 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index e7e75b458005..90a1d14cf7d2 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -55,7 +55,7 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL9000_UCODE_API_MAX 34 +#define IWL9000_UCODE_API_MAX 36 /* Lowest firmware API version supported */ #define IWL9000_UCODE_API_MIN 30 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c deleted file mode 100644 index 705f83b02e13..000000000000 --- a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c +++ /dev/null @@ -1,216 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2015-2017 Intel Deutschland GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * BSD LICENSE - * - * Copyright(c) 2015-2017 Intel Deutschland GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include <linux/module.h> -#include <linux/stringify.h> -#include "iwl-config.h" -#include "iwl-agn-hw.h" - -/* Highest firmware API version supported */ -#define IWL_A000_UCODE_API_MAX 34 - -/* Lowest firmware API version supported */ -#define IWL_A000_UCODE_API_MIN 24 - -/* NVM versions */ -#define IWL_A000_NVM_VERSION 0x0a1d -#define IWL_A000_TX_POWER_VERSION 0xffff /* meaningless */ - -/* Memory offsets and lengths */ -#define IWL_A000_DCCM_OFFSET 0x800000 /* LMAC1 */ -#define IWL_A000_DCCM_LEN 0x10000 /* LMAC1 */ -#define IWL_A000_DCCM2_OFFSET 0x880000 -#define IWL_A000_DCCM2_LEN 0x8000 -#define IWL_A000_SMEM_OFFSET 0x400000 -#define IWL_A000_SMEM_LEN 0xD0000 - -#define IWL_A000_JF_FW_PRE "iwlwifi-Qu-a0-jf-b0-" -#define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-" -#define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-" -#define IWL_A000_HR_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" -#define IWL_A000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-" -#define IWL_A000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" - -#define IWL_A000_HR_MODULE_FIRMWARE(api) \ - IWL_A000_HR_FW_PRE __stringify(api) ".ucode" -#define IWL_A000_JF_MODULE_FIRMWARE(api) \ - IWL_A000_JF_FW_PRE __stringify(api) ".ucode" -#define IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(api) \ - IWL_A000_HR_F0_FW_PRE __stringify(api) ".ucode" -#define IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(api) \ - IWL_A000_JF_B0_FW_PRE __stringify(api) ".ucode" -#define IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(api) \ - IWL_A000_HR_A0_FW_PRE __stringify(api) ".ucode" - -#define NVM_HW_SECTION_NUM_FAMILY_A000 10 - -static const struct iwl_base_params iwl_a000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_A000, - .num_of_queues = 512, - .shadow_ram_support = true, - .led_compensation = 57, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = true, - .pcie_l1_allowed = true, -}; - -static const struct iwl_ht_params iwl_a000_ht_params = { - .stbc = true, - .ldpc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), -}; - -#define IWL_DEVICE_A000 \ - .ucode_api_max = IWL_A000_UCODE_API_MAX, \ - .ucode_api_min = IWL_A000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_A000, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .base_params = &iwl_a000_base_params, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_A000, \ - .non_shared_ant = ANT_A, \ - .dccm_offset = IWL_A000_DCCM_OFFSET, \ - .dccm_len = IWL_A000_DCCM_LEN, \ - .dccm2_offset = IWL_A000_DCCM2_OFFSET, \ - .dccm2_len = IWL_A000_DCCM2_LEN, \ - .smem_offset = IWL_A000_SMEM_OFFSET, \ - .smem_len = IWL_A000_SMEM_LEN, \ - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ - .apmg_not_supported = true, \ - .mq_rx_supported = true, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = true, \ - .use_tfh = true, \ - .rf_id = true, \ - .gen2 = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .tx_cmd_queue_size = 32, \ - .min_umac_error_event_table = 0x400000 - -const struct iwl_cfg iwla000_2ac_cfg_hr = { - .name = "Intel(R) Dual Band Wireless AC a000", - .fw_name_pre = IWL_A000_HR_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, -}; - -const struct iwl_cfg iwla000_2ac_cfg_hr_cdb = { - .name = "Intel(R) Dual Band Wireless AC a000", - .fw_name_pre = IWL_A000_HR_CDB_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, - .cdb = true, -}; - -const struct iwl_cfg iwla000_2ac_cfg_jf = { - .name = "Intel(R) Dual Band Wireless AC a000", - .fw_name_pre = IWL_A000_JF_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, -}; - -const struct iwl_cfg iwla000_2ax_cfg_hr = { - .name = "Intel(R) Dual Band Wireless AX a000", - .fw_name_pre = IWL_A000_HR_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, -}; - -const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0 = { - .name = "Intel(R) Dual Band Wireless AX a000", - .fw_name_pre = IWL_A000_HR_F0_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, -}; - -const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0 = { - .name = "Intel(R) Dual Band Wireless AX a000", - .fw_name_pre = IWL_A000_JF_B0_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, -}; - -const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0 = { - .name = "Intel(R) Dual Band Wireless AX a000", - .fw_name_pre = IWL_A000_HR_A0_FW_PRE, - IWL_DEVICE_A000, - .ht_params = &iwl_a000_ht_params, - .nvm_ver = IWL_A000_NVM_VERSION, - .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, -}; - -MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h index 3684a3e180e5..007bfe7656a4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h @@ -95,8 +95,8 @@ enum { #define IWL_ALIVE_FLG_RFKILL BIT(0) struct iwl_lmac_alive { - __le32 ucode_minor; __le32 ucode_major; + __le32 ucode_minor; u8 ver_subtype; u8 ver_type; u8 mac; @@ -113,8 +113,8 @@ struct iwl_lmac_alive { } __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */ struct iwl_umac_alive { - __le32 umac_minor; /* UMAC version: minor */ __le32 umac_major; /* UMAC version: major */ + __le32 umac_minor; /* UMAC version: minor */ __le32 error_info_addr; /* SRAM address for UMAC error log */ __le32 dbg_print_buff_addr; } __packed; /* UMAC_ALIVE_DATA_API_S_VER_2 */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h index d09555afe2c5..87c1ddea75ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h @@ -188,11 +188,6 @@ enum iwl_bt_mxbox_dw3 { BT_MBOX(3, UPDATE_REQUEST, 21, 1), }; -enum iwl_bt_mxbox_dw4 { - BT_MBOX(4, ATS_BT_INTERVAL, 0, 7), - BT_MBOX(4, ATS_BT_ACTIVE_MAX_TH, 7, 7), -}; - #define BT_MBOX_MSG(_notif, _num, _field) \ ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ >> BT_MBOX##_num##_##_field##_POS) @@ -232,31 +227,6 @@ enum iwl_bt_ci_compliance { * @reserved: reserved */ struct iwl_bt_coex_profile_notif { - __le32 mbox_msg[8]; - __le32 msg_idx; - __le32 bt_ci_compliance; - - __le32 primary_ch_lut; - __le32 secondary_ch_lut; - __le32 bt_activity_grading; - u8 ttc_status; - u8 rrc_status; - __le16 reserved; -} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_5 */ - -/** - * struct iwl_bt_coex_profile_notif - notification about BT coex - * @mbox_msg: message from BT to WiFi - * @msg_idx: the index of the message - * @bt_ci_compliance: enum %iwl_bt_ci_compliance - * @primary_ch_lut: LUT used for primary channel &enum iwl_bt_coex_lut_type - * @secondary_ch_lut: LUT used for secondary channel &enum iwl_bt_coex_lut_type - * @bt_activity_grading: the activity of BT &enum iwl_bt_activity_grading - * @ttc_status: is TTC enabled - one bit per PHY - * @rrc_status: is RRC enabled - one bit per PHY - * @reserved: reserved - */ -struct iwl_bt_coex_profile_notif_v4 { __le32 mbox_msg[4]; __le32 msg_idx; __le32 bt_ci_compliance; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index 7ebbf097488b..f285bacc8726 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -215,7 +215,7 @@ enum iwl_legacy_cmds { /** * @SCD_QUEUE_CFG: &struct iwl_scd_txq_cfg_cmd for older hardware, * &struct iwl_tx_queue_cfg_cmd with &struct iwl_tx_queue_cfg_rsp - * for newer (A000) hardware. + * for newer (22000) hardware. */ SCD_QUEUE_CFG = 0x1d, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h index aa76dcc148bd..a57c7223df0f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h @@ -83,6 +83,21 @@ enum iwl_data_path_subcmd_ids { TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2, /** + * @TLC_MNG_CONFIG_CMD: &struct iwl_tlc_config_cmd + */ + TLC_MNG_CONFIG_CMD = 0xF, + + /** + * @TLC_MNG_NOTIF_REQ_CMD: &struct iwl_tlc_notif_req_config_cmd + */ + TLC_MNG_NOTIF_REQ_CMD = 0x10, + + /** + * @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif + */ + TLC_MNG_UPDATE_NOTIF = 0xF7, + + /** * @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification */ STA_PM_NOTIF = 0xFD, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index a13fd8a1be62..e9a6e5627f94 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -62,6 +62,267 @@ #include "mac.h" +/** + * enum iwl_tlc_mng_cfg_flags_enum - options for TLC config flags + * @IWL_TLC_MNG_CFG_FLAGS_CCK_MSK: CCK support + * @IWL_TLC_MNG_CFG_FLAGS_DD_MSK: enable DD + * @IWL_TLC_MNG_CFG_FLAGS_STBC_MSK: enable STBC + * @IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK: enable LDPC + * @IWL_TLC_MNG_CFG_FLAGS_BF_MSK: enable BFER + * @IWL_TLC_MNG_CFG_FLAGS_DCM_MSK: enable DCM + */ +enum iwl_tlc_mng_cfg_flags_enum { + IWL_TLC_MNG_CFG_FLAGS_CCK_MSK = BIT(0), + IWL_TLC_MNG_CFG_FLAGS_DD_MSK = BIT(1), + IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(2), + IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK = BIT(3), + IWL_TLC_MNG_CFG_FLAGS_BF_MSK = BIT(4), + IWL_TLC_MNG_CFG_FLAGS_DCM_MSK = BIT(5), +}; + +/** + * enum iwl_tlc_mng_cfg_cw_enum - channel width options + * @IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ: 20MHZ channel + * @IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ: 40MHZ channel + * @IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ: 80MHZ channel + * @IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ: 160MHZ channel + * @IWL_TLC_MNG_MAX_CH_WIDTH_LAST: maximum value + */ +enum iwl_tlc_mng_cfg_cw_enum { + IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ, + IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ, + IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ, + IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ, + IWL_TLC_MNG_MAX_CH_WIDTH_LAST = IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ, +}; + +/** + * enum iwl_tlc_mng_cfg_chains_enum - possible chains + * @IWL_TLC_MNG_CHAIN_A_MSK: chain A + * @IWL_TLC_MNG_CHAIN_B_MSK: chain B + * @IWL_TLC_MNG_CHAIN_C_MSK: chain C + */ +enum iwl_tlc_mng_cfg_chains_enum { + IWL_TLC_MNG_CHAIN_A_MSK = BIT(0), + IWL_TLC_MNG_CHAIN_B_MSK = BIT(1), + IWL_TLC_MNG_CHAIN_C_MSK = BIT(2), +}; + +/** + * enum iwl_tlc_mng_cfg_gi_enum - guard interval options + * @IWL_TLC_MNG_SGI_20MHZ_MSK: enable short GI for 20MHZ + * @IWL_TLC_MNG_SGI_40MHZ_MSK: enable short GI for 40MHZ + * @IWL_TLC_MNG_SGI_80MHZ_MSK: enable short GI for 80MHZ + * @IWL_TLC_MNG_SGI_160MHZ_MSK: enable short GI for 160MHZ + */ +enum iwl_tlc_mng_cfg_gi_enum { + IWL_TLC_MNG_SGI_20MHZ_MSK = BIT(0), + IWL_TLC_MNG_SGI_40MHZ_MSK = BIT(1), + IWL_TLC_MNG_SGI_80MHZ_MSK = BIT(2), + IWL_TLC_MNG_SGI_160MHZ_MSK = BIT(3), +}; + +/** + * enum iwl_tlc_mng_cfg_mode_enum - supported modes + * @IWL_TLC_MNG_MODE_CCK: enable CCK + * @IWL_TLC_MNG_MODE_OFDM_NON_HT: enable OFDM (non HT) + * @IWL_TLC_MNG_MODE_NON_HT: enable non HT + * @IWL_TLC_MNG_MODE_HT: enable HT + * @IWL_TLC_MNG_MODE_VHT: enable VHT + * @IWL_TLC_MNG_MODE_HE: enable HE + * @IWL_TLC_MNG_MODE_INVALID: invalid value + * @IWL_TLC_MNG_MODE_NUM: a count of possible modes + */ +enum iwl_tlc_mng_cfg_mode_enum { + IWL_TLC_MNG_MODE_CCK = 0, + IWL_TLC_MNG_MODE_OFDM_NON_HT = IWL_TLC_MNG_MODE_CCK, + IWL_TLC_MNG_MODE_NON_HT = IWL_TLC_MNG_MODE_CCK, + IWL_TLC_MNG_MODE_HT, + IWL_TLC_MNG_MODE_VHT, + IWL_TLC_MNG_MODE_HE, + IWL_TLC_MNG_MODE_INVALID, + IWL_TLC_MNG_MODE_NUM = IWL_TLC_MNG_MODE_INVALID, +}; + +/** + * enum iwl_tlc_mng_vht_he_types_enum - VHT HE types + * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU: VHT HT single user + * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT: VHT HT single user extended + * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU: VHT HT multiple users + * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED: trigger based + * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM: a count of possible types + */ +enum iwl_tlc_mng_vht_he_types_enum { + IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU = 0, + IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT, + IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU, + IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED, + IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM = + IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED, + +}; + +/** + * enum iwl_tlc_mng_ht_rates_enum - HT/VHT rates + * @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0 + * @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1 + * @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2 + * @IWL_TLC_MNG_HT_RATE_MCS3: index of MCS3 + * @IWL_TLC_MNG_HT_RATE_MCS4: index of MCS4 + * @IWL_TLC_MNG_HT_RATE_MCS5: index of MCS5 + * @IWL_TLC_MNG_HT_RATE_MCS6: index of MCS6 + * @IWL_TLC_MNG_HT_RATE_MCS7: index of MCS7 + * @IWL_TLC_MNG_HT_RATE_MCS8: index of MCS8 + * @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9 + * @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT + */ +enum iwl_tlc_mng_ht_rates_enum { + IWL_TLC_MNG_HT_RATE_MCS0 = 0, + IWL_TLC_MNG_HT_RATE_MCS1, + IWL_TLC_MNG_HT_RATE_MCS2, + IWL_TLC_MNG_HT_RATE_MCS3, + IWL_TLC_MNG_HT_RATE_MCS4, + IWL_TLC_MNG_HT_RATE_MCS5, + IWL_TLC_MNG_HT_RATE_MCS6, + IWL_TLC_MNG_HT_RATE_MCS7, + IWL_TLC_MNG_HT_RATE_MCS8, + IWL_TLC_MNG_HT_RATE_MCS9, + IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS9, +}; + +/* Maximum supported tx antennas number */ +#define MAX_RS_ANT_NUM 3 + +/** + * struct tlc_config_cmd - TLC configuration + * @sta_id: station id + * @reserved1: reserved + * @max_supp_ch_width: channel width + * @flags: bitmask of %IWL_TLC_MNG_CONFIG_FLAGS_ENABLE_\* + * @chains: bitmask of %IWL_TLC_MNG_CHAIN_\* + * @max_supp_ss: valid values are 0-3, 0 - spatial streams are not supported + * @valid_vht_he_types: bitmap of %IWL_TLC_MNG_VALID_VHT_HE_TYPES_\* + * @non_ht_supp_rates: bitmap of supported legacy rates + * @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9 + * @mode: modulation type %IWL_TLC_MNG_MODE_\* + * @reserved2: reserved + * @he_supp_rates: bitmap of supported HE rates + * @sgi_ch_width_supp: bitmap of SGI support per channel width + * @he_gi_support: 11ax HE guard interval + * @max_ampdu_cnt: max AMPDU size (frames count) + */ +struct iwl_tlc_config_cmd { + u8 sta_id; + u8 reserved1[3]; + u8 max_supp_ch_width; + u8 chains; + u8 max_supp_ss; + u8 valid_vht_he_types; + __le16 flags; + __le16 non_ht_supp_rates; + __le16 ht_supp_rates[MAX_RS_ANT_NUM]; + u8 mode; + u8 reserved2; + __le16 he_supp_rates; + u8 sgi_ch_width_supp; + u8 he_gi_support; + __le32 max_ampdu_cnt; +} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */ + +#define IWL_TLC_NOTIF_INIT_RATE_POS 0 +#define IWL_TLC_NOTIF_INIT_RATE_MSK BIT(IWL_TLC_NOTIF_INIT_RATE_POS) +#define IWL_TLC_NOTIF_REQ_INTERVAL (500) + +/** + * struct iwl_tlc_notif_req_config_cmd - request notif on specific changes + * @sta_id: relevant station + * @reserved1: reserved + * @flags: bitmap of requested notifications %IWL_TLC_NOTIF_INIT_\* + * @interval: minimum time between notifications from TLC to the driver (msec) + * @reserved2: reserved + */ +struct iwl_tlc_notif_req_config_cmd { + u8 sta_id; + u8 reserved1; + __le16 flags; + __le16 interval; + __le16 reserved2; +} __packed; /* TLC_MNG_NOTIF_REQ_CMD_API_S_VER_1 */ + +/** + * struct iwl_tlc_update_notif - TLC notification from FW + * @sta_id: station id + * @reserved: reserved + * @flags: bitmap of notifications reported + * @values: field per flag in struct iwl_tlc_notif_req_config_cmd + */ +struct iwl_tlc_update_notif { + u8 sta_id; + u8 reserved; + __le16 flags; + __le32 values[16]; +} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_1 */ + +/** + * enum iwl_tlc_debug_flags - debug options + * @IWL_TLC_DEBUG_FIXED_RATE: set fixed rate for rate scaling + * @IWL_TLC_DEBUG_STATS_TH: threshold for sending statistics to the driver, in + * frames + * @IWL_TLC_DEBUG_STATS_TIME_TH: threshold for sending statistics to the + * driver, in msec + * @IWL_TLC_DEBUG_AGG_TIME_LIM: time limit for a BA session + * @IWL_TLC_DEBUG_AGG_DIS_START_TH: frame with try-count greater than this + * threshold should not start an aggregation session + * @IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM: set max number of frames in an aggregation + * @IWL_TLC_DEBUG_RENEW_ADDBA_DELAY: delay between retries of ADD BA + * @IWL_TLC_DEBUG_START_AC_RATE_IDX: frames per second to start a BA session + * @IWL_TLC_DEBUG_NO_FAR_RANGE_TWEAK: disable BW scaling + */ +enum iwl_tlc_debug_flags { + IWL_TLC_DEBUG_FIXED_RATE, + IWL_TLC_DEBUG_STATS_TH, + IWL_TLC_DEBUG_STATS_TIME_TH, + IWL_TLC_DEBUG_AGG_TIME_LIM, + IWL_TLC_DEBUG_AGG_DIS_START_TH, + IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM, + IWL_TLC_DEBUG_RENEW_ADDBA_DELAY, + IWL_TLC_DEBUG_START_AC_RATE_IDX, + IWL_TLC_DEBUG_NO_FAR_RANGE_TWEAK, +}; /* TLC_MNG_DEBUG_FLAGS_API_E_VER_1 */ + +/** + * struct iwl_dhc_tlc_dbg - fixed debug config + * @sta_id: bit 0 - enable/disable, bits 1 - 7 hold station id + * @reserved1: reserved + * @flags: bitmap of %IWL_TLC_DEBUG_\* + * @fixed_rate: rate value + * @stats_threshold: if number of tx-ed frames is greater, send statistics + * @time_threshold: statistics threshold in usec + * @agg_time_lim: max agg time + * @agg_dis_start_threshold: frames with try-cont greater than this count will + * not be aggregated + * @agg_frame_count_lim: agg size + * @addba_retry_delay: delay between retries of ADD BA + * @start_ac_rate_idx: frames per second to start a BA session + * @no_far_range_tweak: disable BW scaling + * @reserved2: reserved + */ +struct iwl_dhc_tlc_cmd { + u8 sta_id; + u8 reserved1[3]; + __le32 flags; + __le32 fixed_rate; + __le16 stats_threshold; + __le16 time_threshold; + __le16 agg_time_lim; + __le16 agg_dis_start_threshold; + __le16 agg_frame_count_lim; + __le16 addba_retry_delay; + u8 start_ac_rate_idx[IEEE80211_NUM_ACS]; + u8 no_far_range_tweak; + u8 reserved2[3]; +} __packed; + /* * These serve as indexes into * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; @@ -253,7 +514,6 @@ enum { #define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \ RATE_MCS_ANT_C_MSK) #define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK -#define RATE_MCS_ANT_NUM 3 /* Bit 17: (0) SS, (1) SS*2 */ #define RATE_MCS_STBC_POS 17 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index f5d5ba7e37ec..a2a40b515a3c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -121,7 +121,7 @@ enum iwl_tx_flags { }; /* TX_FLAGS_BITS_API_S_VER_1 */ /** - * enum iwl_tx_cmd_flags - bitmasks for tx_flags in TX command for a000 + * enum iwl_tx_cmd_flags - bitmasks for tx_flags in TX command for 22000 * @IWL_TX_FLAGS_CMD_RATE: use rate from the TX command * @IWL_TX_FLAGS_ENCRYPT_DIS: frame should not be encrypted, even if it belongs * to a secured STA @@ -301,7 +301,7 @@ struct iwl_dram_sec_info { } __packed; /* DRAM_SEC_INFO_API_S_VER_1 */ /** - * struct iwl_tx_cmd_gen2 - TX command struct to FW for a000 devices + * struct iwl_tx_cmd_gen2 - TX command struct to FW for 22000 devices * ( TX_CMD = 0x1c ) * @len: in bytes of the payload, see below for details * @offload_assist: TX offload configuration diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 8106fd4be996..67aefc8fc9ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -964,7 +964,20 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, if (trigger) delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay)); - if (WARN(fwrt->trans->state == IWL_TRANS_NO_FW, + /* + * If the loading of the FW completed successfully, the next step is to + * get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non + * zero, the FW was already loaded successully. If the state is "NO_FW" + * in such a case - WARN and exit, since FW may be dead. Otherwise, we + * can try to collect the data, since FW might just not be fully + * loaded (no "ALIVE" yet), and the debug data is accessible. + * + * Corner case: got the FW alive but crashed before getting the SMEM + * config. In such a case, due to HW access problems, we might + * collect garbage. + */ + if (WARN((fwrt->trans->state == IWL_TRANS_NO_FW) && + fwrt->smem_cfg.num_lmacs, "Can't collect dbg data when FW isn't alive\n")) return -EIO; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 37a5c5b4eda6..4687d016f676 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -246,8 +246,6 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; * @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement. * @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2 * @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used - * @IWL_UCODE_TLV_API_ATS_COEX_EXTERNAL: the coex notification is enlared to - * include information about ACL time sharing. * @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field * indicating low latency direction. * @@ -267,7 +265,6 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_ADAPTIVE_DWELL = (__force iwl_ucode_tlv_api_t)32, IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34, IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35, - IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL = (__force iwl_ucode_tlv_api_t)37, IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38, NUM_IWL_UCODE_TLV_API @@ -313,6 +310,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC * @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan * @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification + * @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm * @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement * @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts * @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT @@ -367,6 +365,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39, IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST = (__force iwl_ucode_tlv_capa_t)41, + IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43, IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65, IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/smem.c b/drivers/net/wireless/intel/iwlwifi/fw/smem.c index 76675736ba4f..fb4b6442b4d7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/smem.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/smem.c @@ -63,8 +63,8 @@ #include "runtime.h" #include "fw/api/commands.h" -static void iwl_parse_shared_mem_a000(struct iwl_fw_runtime *fwrt, - struct iwl_rx_packet *pkt) +static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt, + struct iwl_rx_packet *pkt) { struct iwl_shared_mem_cfg *mem_cfg = (void *)pkt->data; int i, lmac; @@ -143,8 +143,8 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt) return; pkt = cmd.resp_pkt; - if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) - iwl_parse_shared_mem_a000(fwrt, pkt); + if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_22000) + iwl_parse_shared_mem_22000(fwrt, pkt); else iwl_parse_shared_mem(fwrt, pkt); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index e21e46cf6f9a..258d439bb0a9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -89,7 +89,7 @@ enum iwl_device_family { IWL_DEVICE_FAMILY_7000, IWL_DEVICE_FAMILY_8000, IWL_DEVICE_FAMILY_9000, - IWL_DEVICE_FAMILY_A000, + IWL_DEVICE_FAMILY_22000, }; /* @@ -266,7 +266,7 @@ struct iwl_tt_params { #define OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(u16)) /* 16 KB */ #define OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(u16)) /* 32 KB */ #define OTP_LOW_IMAGE_SIZE_FAMILY_9000 OTP_LOW_IMAGE_SIZE_FAMILY_8000 -#define OTP_LOW_IMAGE_SIZE_FAMILY_A000 OTP_LOW_IMAGE_SIZE_FAMILY_9000 +#define OTP_LOW_IMAGE_SIZE_FAMILY_22000 OTP_LOW_IMAGE_SIZE_FAMILY_9000 struct iwl_eeprom_params { const u8 regulatory_bands[7]; @@ -330,7 +330,7 @@ struct iwl_pwr_tx_backoff { * @vht_mu_mimo_supported: VHT MU-MIMO support * @rf_id: need to read rf_id to determine the firmware image * @integrated: discrete or integrated - * @gen2: a000 and on transport operation + * @gen2: 22000 and on transport operation * @cdb: CDB support * @nvm_type: see &enum iwl_nvm_type * @tx_cmd_queue_size: size of the cmd queue. If zero, use the same value as @@ -477,13 +477,13 @@ extern const struct iwl_cfg iwl9460_2ac_cfg_soc; extern const struct iwl_cfg iwl9461_2ac_cfg_soc; extern const struct iwl_cfg iwl9462_2ac_cfg_soc; extern const struct iwl_cfg iwl9560_2ac_cfg_soc; -extern const struct iwl_cfg iwla000_2ac_cfg_hr; -extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb; -extern const struct iwl_cfg iwla000_2ac_cfg_jf; -extern const struct iwl_cfg iwla000_2ax_cfg_hr; -extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0; -extern const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0; -extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0; +extern const struct iwl_cfg iwl22000_2ac_cfg_hr; +extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; +extern const struct iwl_cfg iwl22000_2ac_cfg_jf; +extern const struct iwl_cfg iwl22000_2ax_cfg_hr; +extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_f0; +extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0; +extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; #endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 4b224d7d967c..de8f6ae2f51b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -919,9 +919,14 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, minor = le32_to_cpup(ptr++); local_comp = le32_to_cpup(ptr); - snprintf(drv->fw.fw_version, - sizeof(drv->fw.fw_version), "%u.%u.%u", - major, minor, local_comp); + if (major >= 35) + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), + "%u.%08x.%u", major, minor, local_comp); + else + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), + "%u.%u.%u", major, minor, local_comp); break; } case IWL_UCODE_TLV_FW_DBG_DEST: { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index 66e5db41e559..11789ffb6512 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -121,7 +121,7 @@ #define FH_MEM_CBBC_16_19_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) #define FH_MEM_CBBC_20_31_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xB20) #define FH_MEM_CBBC_20_31_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xB80) -/* a000 TFD table address, 64 bit */ +/* 22000 TFD table address, 64 bit */ #define TFH_TFDQ_CBB_TABLE (0x1C00) /* Find TFD CB base pointer for given queue */ @@ -140,7 +140,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans, return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20); } -/* a000 configuration registers */ +/* 22000 configuration registers */ /* * TFH Configuration register. @@ -697,8 +697,8 @@ struct iwl_tfh_tb { * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM. * Both driver and device share these circular buffers, each of which must be * contiguous 256 TFDs. - * For pre a000 HW it is 256 x 128 bytes-per-TFD = 32 KBytes - * For a000 HW and on it is 256 x 256 bytes-per-TFD = 65 KBytes + * For pre 22000 HW it is 256 x 128 bytes-per-TFD = 32 KBytes + * For 22000 HW and on it is 256 x 256 bytes-per-TFD = 65 KBytes * * Driver must indicate the physical address of the base of each * circular buffer via the FH_MEM_CBBC_QUEUE registers. @@ -750,10 +750,10 @@ struct iwl_tfh_tfd { /** * struct iwlagn_schedq_bc_tbl scheduler byte count table * base physical address provided by SCD_DRAM_BASE_ADDR - * For devices up to a000: + * For devices up to 22000: * @tfd_offset 0-12 - tx command byte count * 12-16 - station index - * For a000 and on: + * For 22000 and on: * @tfd_offset 0-12 - tx command byte count * 12-13 - number of 64 byte chunks * 14-16 - reserved diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 921cab9e2d73..84ae1e274d38 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -551,7 +551,7 @@ struct iwl_trans_ops { unsigned int queue_wdg_timeout); void (*txq_disable)(struct iwl_trans *trans, int queue, bool configure_scd); - /* a000 functions */ + /* 22000 functions */ int (*txq_alloc)(struct iwl_trans *trans, struct iwl_tx_queue_cfg_cmd *cmd, int cmd_id, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/Makefile b/drivers/net/wireless/intel/iwlwifi/mvm/Makefile index a47635c32c11..9ffd21918b5a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/mvm/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o iwlmvm-y += utils.o rx.o rxmq.o tx.o binding.o quota.o sta.o sf.o -iwlmvm-y += scan.o time-event.o rs.o +iwlmvm-y += scan.o time-event.o rs.o rs-fw.o iwlmvm-y += power.o coex.o iwlmvm-y += tt.o offloading.o tdls.o iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index 79c80f181f7d..890dbfff3a06 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -7,7 +7,6 @@ * * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH - * Copyright(c) 2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -34,7 +33,6 @@ * * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH - * Copyright(c) 2017 Intel Deutschland GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -514,36 +512,17 @@ void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; - if (!iwl_mvm_has_new_ats_coex_api(mvm)) { - struct iwl_bt_coex_profile_notif_v4 *v4 = (void *)pkt->data; - - mvm->last_bt_notif.mbox_msg[0] = v4->mbox_msg[0]; - mvm->last_bt_notif.mbox_msg[1] = v4->mbox_msg[1]; - mvm->last_bt_notif.mbox_msg[2] = v4->mbox_msg[2]; - mvm->last_bt_notif.mbox_msg[3] = v4->mbox_msg[3]; - mvm->last_bt_notif.msg_idx = v4->msg_idx; - mvm->last_bt_notif.bt_ci_compliance = v4->bt_ci_compliance; - mvm->last_bt_notif.primary_ch_lut = v4->primary_ch_lut; - mvm->last_bt_notif.secondary_ch_lut = v4->secondary_ch_lut; - mvm->last_bt_notif.bt_activity_grading = - v4->bt_activity_grading; - mvm->last_bt_notif.ttc_status = v4->ttc_status; - mvm->last_bt_notif.rrc_status = v4->rrc_status; - } else { - /* save this notification for future use: rssi fluctuations */ - memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); - } - IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); - IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", - mvm->last_bt_notif.bt_ci_compliance); + IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n", - le32_to_cpu(mvm->last_bt_notif.primary_ch_lut)); + le32_to_cpu(notif->primary_ch_lut)); IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n", - le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut)); + le32_to_cpu(notif->secondary_ch_lut)); IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n", - le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)); + le32_to_cpu(notif->bt_activity_grading)); + /* remember this notification for future use: rssi fluctuations */ + memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); iwl_mvm_bt_coex_notif_handle(mvm); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index b1f73dcabd31..0e6cf39285f4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -429,231 +429,6 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm, return err; } -enum iwl_mvm_tcp_packet_type { - MVM_TCP_TX_SYN, - MVM_TCP_RX_SYNACK, - MVM_TCP_TX_DATA, - MVM_TCP_RX_ACK, - MVM_TCP_RX_WAKE, - MVM_TCP_TX_FIN, -}; - -static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr) -{ - __sum16 check = tcp_v4_check(len, saddr, daddr, 0); - return cpu_to_le16(be16_to_cpu((__force __be16)check)); -} - -static void iwl_mvm_build_tcp_packet(struct ieee80211_vif *vif, - struct cfg80211_wowlan_tcp *tcp, - void *_pkt, u8 *mask, - __le16 *pseudo_hdr_csum, - enum iwl_mvm_tcp_packet_type ptype) -{ - struct { - struct ethhdr eth; - struct iphdr ip; - struct tcphdr tcp; - u8 data[]; - } __packed *pkt = _pkt; - u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); - int i; - - pkt->eth.h_proto = cpu_to_be16(ETH_P_IP), - pkt->ip.version = 4; - pkt->ip.ihl = 5; - pkt->ip.protocol = IPPROTO_TCP; - - switch (ptype) { - case MVM_TCP_TX_SYN: - case MVM_TCP_TX_DATA: - case MVM_TCP_TX_FIN: - memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN); - memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN); - pkt->ip.ttl = 128; - pkt->ip.saddr = tcp->src; - pkt->ip.daddr = tcp->dst; - pkt->tcp.source = cpu_to_be16(tcp->src_port); - pkt->tcp.dest = cpu_to_be16(tcp->dst_port); - /* overwritten for TX SYN later */ - pkt->tcp.doff = sizeof(struct tcphdr) / 4; - pkt->tcp.window = cpu_to_be16(65000); - break; - case MVM_TCP_RX_SYNACK: - case MVM_TCP_RX_ACK: - case MVM_TCP_RX_WAKE: - memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN); - memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN); - pkt->ip.saddr = tcp->dst; - pkt->ip.daddr = tcp->src; - pkt->tcp.source = cpu_to_be16(tcp->dst_port); - pkt->tcp.dest = cpu_to_be16(tcp->src_port); - break; - default: - WARN_ON(1); - return; - } - - switch (ptype) { - case MVM_TCP_TX_SYN: - /* firmware assumes 8 option bytes - 8 NOPs for now */ - memset(pkt->data, 0x01, 8); - ip_tot_len += 8; - pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4; - pkt->tcp.syn = 1; - break; - case MVM_TCP_TX_DATA: - ip_tot_len += tcp->payload_len; - memcpy(pkt->data, tcp->payload, tcp->payload_len); - pkt->tcp.psh = 1; - pkt->tcp.ack = 1; - break; - case MVM_TCP_TX_FIN: - pkt->tcp.fin = 1; - pkt->tcp.ack = 1; - break; - case MVM_TCP_RX_SYNACK: - pkt->tcp.syn = 1; - pkt->tcp.ack = 1; - break; - case MVM_TCP_RX_ACK: - pkt->tcp.ack = 1; - break; - case MVM_TCP_RX_WAKE: - ip_tot_len += tcp->wake_len; - pkt->tcp.psh = 1; - pkt->tcp.ack = 1; - memcpy(pkt->data, tcp->wake_data, tcp->wake_len); - break; - } - - switch (ptype) { - case MVM_TCP_TX_SYN: - case MVM_TCP_TX_DATA: - case MVM_TCP_TX_FIN: - pkt->ip.tot_len = cpu_to_be16(ip_tot_len); - pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl); - break; - case MVM_TCP_RX_WAKE: - for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) { - u8 tmp = tcp->wake_mask[i]; - mask[i + 6] |= tmp << 6; - if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8)) - mask[i + 7] = tmp >> 2; - } - /* fall through for ethernet/IP/TCP headers mask */ - case MVM_TCP_RX_SYNACK: - case MVM_TCP_RX_ACK: - mask[0] = 0xff; /* match ethernet */ - /* - * match ethernet, ip.version, ip.ihl - * the ip.ihl half byte is really masked out by firmware - */ - mask[1] = 0x7f; - mask[2] = 0x80; /* match ip.protocol */ - mask[3] = 0xfc; /* match ip.saddr, ip.daddr */ - mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */ - mask[5] = 0x80; /* match tcp flags */ - /* leave rest (0 or set for MVM_TCP_RX_WAKE) */ - break; - }; - - *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr), - pkt->ip.saddr, pkt->ip.daddr); -} - -static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_wowlan_tcp *tcp) -{ - struct iwl_wowlan_remote_wake_config *cfg; - struct iwl_host_cmd cmd = { - .id = REMOTE_WAKE_CONFIG_CMD, - .len = { sizeof(*cfg), }, - .dataflags = { IWL_HCMD_DFL_NOCOPY, }, - }; - int ret; - - if (!tcp) - return 0; - - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); - if (!cfg) - return -ENOMEM; - cmd.data[0] = cfg; - - cfg->max_syn_retries = 10; - cfg->max_data_retries = 10; - cfg->tcp_syn_ack_timeout = 1; /* seconds */ - cfg->tcp_ack_timeout = 1; /* seconds */ - - /* SYN (TX) */ - iwl_mvm_build_tcp_packet( - vif, tcp, cfg->syn_tx.data, NULL, - &cfg->syn_tx.info.tcp_pseudo_header_checksum, - MVM_TCP_TX_SYN); - cfg->syn_tx.info.tcp_payload_length = 0; - - /* SYN/ACK (RX) */ - iwl_mvm_build_tcp_packet( - vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask, - &cfg->synack_rx.info.tcp_pseudo_header_checksum, - MVM_TCP_RX_SYNACK); - cfg->synack_rx.info.tcp_payload_length = 0; - - /* KEEPALIVE/ACK (TX) */ - iwl_mvm_build_tcp_packet( - vif, tcp, cfg->keepalive_tx.data, NULL, - &cfg->keepalive_tx.info.tcp_pseudo_header_checksum, - MVM_TCP_TX_DATA); - cfg->keepalive_tx.info.tcp_payload_length = - cpu_to_le16(tcp->payload_len); - cfg->sequence_number_offset = tcp->payload_seq.offset; - /* length must be 0..4, the field is little endian */ - cfg->sequence_number_length = tcp->payload_seq.len; - cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start); - cfg->keepalive_interval = cpu_to_le16(tcp->data_interval); - if (tcp->payload_tok.len) { - cfg->token_offset = tcp->payload_tok.offset; - cfg->token_length = tcp->payload_tok.len; - cfg->num_tokens = - cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len); - memcpy(cfg->tokens, tcp->payload_tok.token_stream, - tcp->tokens_size); - } else { - /* set tokens to max value to almost never run out */ - cfg->num_tokens = cpu_to_le16(65535); - } - - /* ACK (RX) */ - iwl_mvm_build_tcp_packet( - vif, tcp, cfg->keepalive_ack_rx.data, - cfg->keepalive_ack_rx.rx_mask, - &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum, - MVM_TCP_RX_ACK); - cfg->keepalive_ack_rx.info.tcp_payload_length = 0; - - /* WAKEUP (RX) */ - iwl_mvm_build_tcp_packet( - vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask, - &cfg->wake_rx.info.tcp_pseudo_header_checksum, - MVM_TCP_RX_WAKE); - cfg->wake_rx.info.tcp_payload_length = - cpu_to_le16(tcp->wake_len); - - /* FIN */ - iwl_mvm_build_tcp_packet( - vif, tcp, cfg->fin_tx.data, NULL, - &cfg->fin_tx.info.tcp_pseudo_header_checksum, - MVM_TCP_TX_FIN); - cfg->fin_tx.info.tcp_payload_length = 0; - - ret = iwl_mvm_send_cmd(mvm, &cmd); - kfree(cfg); - - return ret; -} - static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *ap_sta) { @@ -1082,12 +857,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, if (ret) return ret; - ret = iwl_mvm_send_proto_offload(mvm, vif, false, true, 0); - if (ret) - return ret; - - ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp); - return ret; + return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0); } static int diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 2ff594f11259..270781e13e89 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -425,6 +425,50 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } +static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ieee80211_sta *sta = file->private_data; + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; + struct iwl_mvm *mvm = lq_sta->pers.drv; + static const size_t bufsz = 2048; + char *buff; + int desc = 0; + ssize_t ret; + + buff = kmalloc(bufsz, GFP_KERNEL); + if (!buff) + return -ENOMEM; + + mutex_lock(&mvm->mutex); + + desc += scnprintf(buff + desc, bufsz - desc, "sta_id %d\n", + lq_sta->pers.sta_id); + desc += scnprintf(buff + desc, bufsz - desc, + "fixed rate 0x%X\n", + lq_sta->pers.dbg_fixed_rate); + desc += scnprintf(buff + desc, bufsz - desc, + "A-MPDU size limit %d\n", + lq_sta->pers.dbg_agg_frame_count_lim); + desc += scnprintf(buff + desc, bufsz - desc, + "valid_tx_ant %s%s%s\n", + (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "", + (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "", + (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : ""); + desc += scnprintf(buff + desc, bufsz - desc, + "last tx rate=0x%X ", + lq_sta->last_rate_n_flags); + + desc += rs_pretty_print_rate(buff + desc, bufsz - desc, + lq_sta->last_rate_n_flags); + mutex_unlock(&mvm->mutex); + + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + kfree(buff); + return ret; +} + static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -470,8 +514,7 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf, } static -int iwl_mvm_coex_dump_mbox(struct iwl_mvm *mvm, - struct iwl_bt_coex_profile_notif *notif, char *buf, +int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf, int pos, int bufsz) { pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); @@ -525,12 +568,7 @@ int iwl_mvm_coex_dump_mbox(struct iwl_mvm *mvm, BT_MBOX_PRINT(3, INBAND_P, false); BT_MBOX_PRINT(3, MSG_TYPE_2, false); BT_MBOX_PRINT(3, SSN_2, false); - BT_MBOX_PRINT(3, UPDATE_REQUEST, !iwl_mvm_has_new_ats_coex_api(mvm)); - - if (iwl_mvm_has_new_ats_coex_api(mvm)) { - BT_MBOX_PRINT(4, ATS_BT_INTERVAL, false); - BT_MBOX_PRINT(4, ATS_BT_ACTIVE_MAX_TH, true); - } + BT_MBOX_PRINT(3, UPDATE_REQUEST, true); return pos; } @@ -549,7 +587,7 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, mutex_lock(&mvm->mutex); - pos += iwl_mvm_coex_dump_mbox(mvm, notif, buf, pos, bufsz); + pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n", notif->bt_ci_compliance); @@ -721,6 +759,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, mutex_lock(&mvm->mutex); + if (iwl_mvm_firmware_running(mvm)) + iwl_mvm_request_statistics(mvm, false); + pos += scnprintf(buf + pos, bufsz - pos, fmt_header, "Statistics_Rx - OFDM"); if (!iwl_mvm_has_new_rx_stats_api(mvm)) { @@ -936,7 +977,8 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm, continue; pos += scnprintf(pos, endpos - pos, "Rate[%d]: ", (int)(ARRAY_SIZE(stats->last_rates) - i)); - pos += rs_pretty_print_rate(pos, stats->last_rates[idx]); + pos += rs_pretty_print_rate(pos, endpos - pos, + stats->last_rates[idx]); } spin_unlock_bh(&mvm->drv_stats_lock); @@ -1603,6 +1645,19 @@ static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf, #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \ MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) +#define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \ + _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta) +#define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \ + _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta) + +#define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do { \ + if (!debugfs_create_file(alias, mode, parent, sta, \ + &iwl_dbgfs_##name##_ops)) \ + goto err; \ + } while (0) +#define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \ + MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode) + static ssize_t iwl_dbgfs_prph_reg_read(struct file *file, char __user *user_buf, @@ -1687,6 +1742,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64); MVM_DEBUGFS_READ_FILE_OPS(nic_temp); MVM_DEBUGFS_READ_FILE_OPS(stations); +MVM_DEBUGFS_READ_FILE_OPS(rs_data); MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64); @@ -1851,6 +1907,21 @@ static const struct file_operations iwl_dbgfs_mem_ops = { .llseek = default_llseek, }; +void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct dentry *dir) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) + MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, S_IRUSR); + + return; +err: + IWL_ERR(mvm, "Can't create the mvm station debugfs entry\n"); +} + int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) { struct dentry *bcast_dir __maybe_unused; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index c0de7bb86cf7..0920be637b57 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -297,7 +297,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, if (ret) { struct iwl_trans *trans = mvm->trans; - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22000) IWL_ERR(mvm, "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", iwl_read_prph(trans, UMAG_SB_CPU_1_STATUS), @@ -923,11 +923,11 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) ret = iwl_run_init_mvm_ucode(mvm, false); - if (iwlmvm_mod_params.init_dbg) - return 0; - if (ret) { IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); + + if (iwlmvm_mod_params.init_dbg) + return 0; return ret; } @@ -998,9 +998,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; /* Init RSS configuration */ - /* TODO - remove a000 disablement when we have RXQ config API */ + /* TODO - remove 22000 disablement when we have RXQ config API */ if (iwl_mvm_has_new_rx_api(mvm) && - mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_A000) { + mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_22000) { ret = iwl_send_rss_cfg_cmd(mvm); if (ret) { IWL_ERR(mvm, "Failed to configure RSS queues: %d\n", @@ -1111,7 +1111,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); return 0; error: - if (!iwlmvm_mod_params.init_dbg) + if (!iwlmvm_mod_params.init_dbg || !ret) iwl_mvm_stop_device(mvm); return ret; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3e92a117c0b8..4f5686526d4b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -114,29 +114,6 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { }, }; -#ifdef CONFIG_PM_SLEEP -static const struct nl80211_wowlan_tcp_data_token_feature -iwl_mvm_wowlan_tcp_token_feature = { - .min_len = 0, - .max_len = 255, - .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS, -}; - -static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = { - .tok = &iwl_mvm_wowlan_tcp_token_feature, - .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN - - sizeof(struct ethhdr) - - sizeof(struct iphdr) - - sizeof(struct tcphdr), - .data_interval_max = 65535, /* __le16 in API */ - .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN - - sizeof(struct ethhdr) - - sizeof(struct iphdr) - - sizeof(struct tcphdr), - .seq = true, -}; -#endif - #ifdef CONFIG_IWLWIFI_BCAST_FILTERING /* * Use the reserved field to indicate magic values. @@ -443,6 +420,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR); + + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) { + ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + } + if (iwl_mvm_has_new_rx_api(mvm)) ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); @@ -477,7 +460,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) /* this is the case for CCK frames, it's better (only 8) for OFDM */ hw->radiotap_timestamp.accuracy = 22; - hw->rate_control_algorithm = "iwl-mvm-rs"; + if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) + hw->rate_control_algorithm = RS_NAME; + hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; @@ -702,7 +687,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; mvm->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES; - mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; hw->wiphy->wowlan = &mvm->wowlan; } #endif @@ -3216,6 +3200,10 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, duration, type); + /* + * Flush the done work, just in case it's still pending, so that + * the work it does can complete and we can accept new frames. + */ flush_work(&mvm->roc_done_wk); mutex_lock(&mvm->mutex); @@ -4301,7 +4289,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, mvm->trans->num_rx_queues); /* TODO - remove this when we have RXQ config API */ - if (mvm->trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) { + if (mvm->trans->cfg->device_family == IWL_DEVICE_FAMILY_22000) { qmask = BIT(0); if (notif->sync) atomic_set(&mvm->queue_sync_counter, 1); @@ -4414,4 +4402,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { #endif .get_survey = iwl_mvm_mac_get_survey, .sta_statistics = iwl_mvm_mac_sta_statistics, +#ifdef CONFIG_IWLWIFI_DEBUGFS + .sta_add_debugfs = iwl_mvm_sta_add_debugfs, +#endif }; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 55ab5349dd40..5ecba2b9bc99 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1248,7 +1248,7 @@ static inline bool iwl_mvm_has_new_tx_api(struct iwl_mvm *mvm) static inline bool iwl_mvm_has_unified_ucode(struct iwl_mvm *mvm) { /* TODO - better define this */ - return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_A000; + return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm) @@ -1272,12 +1272,6 @@ static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) IWL_UCODE_TLV_API_NEW_RX_STATS); } -static inline bool iwl_mvm_has_new_ats_coex_api(struct iwl_mvm *mvm) -{ - return fw_has_api(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL); -} - static inline bool iwl_mvm_has_quota_low_latency(struct iwl_mvm *mvm) { return fw_has_api(&mvm->fw->ucode_capa, @@ -1600,9 +1594,9 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) /* rate scaling */ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg); -int rs_pretty_print_rate(char *buf, const u32 rate); +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); void rs_update_last_rssi(struct iwl_mvm *mvm, - struct iwl_lq_sta *lq_sta, + struct iwl_mvm_sta *mvmsta, struct ieee80211_rx_status *rx_status); /* power management */ @@ -1882,5 +1876,11 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm, int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b); int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm); +#ifdef CONFIG_IWLWIFI_DEBUGFS +void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct dentry *dir); +#endif #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 45470b6b351a..aab4aeaee58c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -127,11 +127,8 @@ static int __init iwl_mvm_init(void) } ret = iwl_opmode_register("iwlmvm", &iwl_mvm_ops); - - if (ret) { + if (ret) pr_err("Unable to register MVM op_mode: %d\n", ret); - iwl_mvm_rate_control_unregister(); - } return ret; } @@ -750,7 +747,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mutex_lock(&mvm->mutex); iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); err = iwl_run_init_mvm_ucode(mvm, true); - if (!iwlmvm_mod_params.init_dbg) + if (!iwlmvm_mod_params.init_dbg || !err) iwl_mvm_stop_device(mvm); iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); mutex_unlock(&mvm->mutex); @@ -1021,6 +1018,8 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode, iwl_mvm_rx_queue_notif(mvm, rxb, 0); else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE)) iwl_mvm_rx_frame_release(mvm, napi, rxb, 0); + else if (cmd == WIDE_ID(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF)) + iwl_mvm_tlc_update_notif(mvm, pkt); else iwl_mvm_rx_common(mvm, rxb, pkt); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c new file mode 100644 index 000000000000..55d1274c6092 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -0,0 +1,314 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2017 Intel Deutschland GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless <linuxwifi@intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2017 Intel Deutschland GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include "rs.h" +#include "fw-api.h" +#include "sta.h" +#include "iwl-op-mode.h" +#include "mvm.h" + +static u8 rs_fw_bw_from_sta_bw(struct ieee80211_sta *sta) +{ + switch (sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + return IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ; + case IEEE80211_STA_RX_BW_80: + return IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ; + case IEEE80211_STA_RX_BW_40: + return IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ; + case IEEE80211_STA_RX_BW_20: + default: + return IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ; + } +} + +static u8 rs_fw_set_active_chains(u8 chains) +{ + u8 fw_chains = 0; + + if (chains & ANT_A) + fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK; + if (chains & ANT_B) + fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK; + if (chains & ANT_C) + fw_chains |= IWL_TLC_MNG_CHAIN_C_MSK; + + return fw_chains; +} + +static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta) +{ + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + u8 supp = 0; + + if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) + supp |= IWL_TLC_MNG_SGI_20MHZ_MSK; + if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) + supp |= IWL_TLC_MNG_SGI_40MHZ_MSK; + if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80) + supp |= IWL_TLC_MNG_SGI_80MHZ_MSK; + if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160) + supp |= IWL_TLC_MNG_SGI_160MHZ_MSK; + + return supp; +} + +static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm, + struct ieee80211_sta *sta) +{ + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + bool vht_ena = vht_cap && vht_cap->vht_supported; + u16 flags = IWL_TLC_MNG_CFG_FLAGS_CCK_MSK | + IWL_TLC_MNG_CFG_FLAGS_DCM_MSK | + IWL_TLC_MNG_CFG_FLAGS_DD_MSK; + + if (mvm->cfg->ht_params->stbc && + (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && + ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) || + (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)))) + flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; + + if (mvm->cfg->ht_params->ldpc && + ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) || + (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) + flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; + + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BEAMFORMER) && + (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && + (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) + flags |= IWL_TLC_MNG_CFG_FLAGS_BF_MSK; + + return flags; +} + +static +int rs_fw_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap, + int nss) +{ + u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & + (0x3 << (2 * (nss - 1))); + rx_mcs >>= (2 * (nss - 1)); + + switch (rx_mcs) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: + return IWL_TLC_MNG_HT_RATE_MCS7; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + return IWL_TLC_MNG_HT_RATE_MCS8; + case IEEE80211_VHT_MCS_SUPPORT_0_9: + return IWL_TLC_MNG_HT_RATE_MCS9; + default: + WARN_ON_ONCE(1); + break; + } + + return 0; +} + +static void rs_fw_vht_set_enabled_rates(struct ieee80211_sta *sta, + struct ieee80211_sta_vht_cap *vht_cap, + struct iwl_tlc_config_cmd *cmd) +{ + u16 supp; + int i, highest_mcs; + + for (i = 0; i < sta->rx_nss; i++) { + if (i == MAX_RS_ANT_NUM) + break; + + highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); + if (!highest_mcs) + continue; + + supp = BIT(highest_mcs + 1) - 1; + if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); + + cmd->ht_supp_rates[i] = cpu_to_le16(supp); + } +} + +static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, + struct ieee80211_supported_band *sband, + struct iwl_tlc_config_cmd *cmd) +{ + int i; + unsigned long tmp; + unsigned long supp; /* must be unsigned long for for_each_set_bit */ + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + + /* non HT rates */ + supp = 0; + tmp = sta->supp_rates[sband->band]; + for_each_set_bit(i, &tmp, BITS_PER_LONG) + supp |= BIT(sband->bitrates[i].hw_value); + + cmd->non_ht_supp_rates = cpu_to_le16(supp); + cmd->mode = IWL_TLC_MNG_MODE_NON_HT; + + /* HT/VHT rates */ + if (vht_cap && vht_cap->vht_supported) { + cmd->mode = IWL_TLC_MNG_MODE_VHT; + rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd); + } else if (ht_cap && ht_cap->ht_supported) { + cmd->mode = IWL_TLC_MNG_MODE_HT; + cmd->ht_supp_rates[0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]); + cmd->ht_supp_rates[1] = cpu_to_le16(ht_cap->mcs.rx_mask[1]); + } +} + +static void rs_fw_tlc_mng_notif_req_config(struct iwl_mvm *mvm, u8 sta_id) +{ + u32 cmd_id = iwl_cmd_id(TLC_MNG_NOTIF_REQ_CMD, DATA_PATH_GROUP, 0); + struct iwl_tlc_notif_req_config_cmd cfg_cmd = { + .sta_id = sta_id, + .flags = cpu_to_le16(IWL_TLC_NOTIF_INIT_RATE_MSK), + .interval = cpu_to_le16(IWL_TLC_NOTIF_REQ_INTERVAL), + }; + int ret; + + ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd); + if (ret) + IWL_ERR(mvm, "Failed to send TLC notif request (%d)\n", ret); +} + +void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) +{ + struct iwl_tlc_update_notif *notif; + struct iwl_mvm_sta *mvmsta; + struct iwl_lq_sta_rs_fw *lq_sta; + + notif = (void *)pkt->data; + mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, notif->sta_id); + + if (!mvmsta) { + IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", + notif->sta_id); + return; + } + + lq_sta = &mvmsta->lq_sta.rs_fw; + + if (le16_to_cpu(notif->flags) & IWL_TLC_NOTIF_INIT_RATE_MSK) { + lq_sta->last_rate_n_flags = + le32_to_cpu(notif->values[IWL_TLC_NOTIF_INIT_RATE_POS]); + IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n", + lq_sta->last_rate_n_flags); + } +} + +void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + enum nl80211_band band) +{ + struct ieee80211_hw *hw = mvm->hw; + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; + u32 cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0); + struct ieee80211_supported_band *sband; + struct iwl_tlc_config_cmd cfg_cmd = { + .sta_id = mvmsta->sta_id, + .max_supp_ch_width = rs_fw_bw_from_sta_bw(sta), + .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)), + .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), + .max_supp_ss = sta->rx_nss, + .max_ampdu_cnt = cpu_to_le32(mvmsta->max_agg_bufsize), + .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta), + }; + int ret; + + memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); + +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl_mvm_reset_frame_stats(mvm); +#endif + sband = hw->wiphy->bands[band]; + rs_fw_set_supp_rates(sta, sband, &cfg_cmd); + + ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd); + if (ret) + IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret); + + rs_fw_tlc_mng_notif_req_config(mvm, cfg_cmd.sta_id); +} + +int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, + bool enable) +{ + /* TODO: need to introduce a new FW cmd since LQ cmd is not relevant */ + IWL_DEBUG_RATE(mvm, "tx protection - not implemented yet.\n"); + return 0; +} + +void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta) +{ + struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; + + IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); + + lq_sta->pers.drv = mvm; + lq_sta->pers.sta_id = mvmsta->sta_id; + lq_sta->pers.chains = 0; + memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); + lq_sta->pers.last_rssi = S8_MIN; + lq_sta->last_rate_n_flags = 0; + +#ifdef CONFIG_MAC80211_DEBUGFS + lq_sta->pers.dbg_fixed_rate = 0; +#endif +} diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index c69515ed72df..56b3cf1834e5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -42,8 +42,6 @@ #include "mvm.h" #include "debugfs.h" -#define RS_NAME "iwl-mvm-rs" - #define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ /* Calculations of success ratio are done in fixed point where 12800 is 100%. @@ -809,7 +807,7 @@ static int rs_collect_tlc_data(struct iwl_mvm *mvm, return -EINVAL; if (tbl->column != RS_COLUMN_INVALID) { - struct lq_sta_pers *pers = &mvmsta->lq_sta.pers; + struct lq_sta_pers *pers = &mvmsta->lq_sta.rs_drv.pers; pers->tx_stats[tbl->column][scale_index].total += attempts; pers->tx_stats[tbl->column][scale_index].success += successes; @@ -1206,7 +1204,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info); u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); - struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; + struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; /* Treat uninitialized rate scaling data same as non-existing. */ if (!lq_sta) { @@ -1416,13 +1414,13 @@ done: /* * mac80211 sends us Tx status */ -static void rs_mac80211_tx_status(void *mvm_r, - struct ieee80211_supported_band *sband, - struct ieee80211_sta *sta, void *priv_sta, - struct sk_buff *skb) +static void rs_drv_mac80211_tx_status(void *mvm_r, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r; + struct iwl_op_mode *op_mode = mvm_r; struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1877,12 +1875,10 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, struct rs_rate *rate = &search_tbl->rate; const struct rs_tx_column *column = &rs_tx_columns[col_id]; const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; - u32 sz = (sizeof(struct iwl_scale_tbl_info) - - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); unsigned long rate_mask = 0; u32 rate_idx = 0; - memcpy(search_tbl, tbl, sz); + memcpy(search_tbl, tbl, offsetof(struct iwl_scale_tbl_info, win)); rate->sgi = column->sgi; rate->ant = column->ant; @@ -2787,9 +2783,10 @@ out: /* Save info about RSSI of last Rx */ void rs_update_last_rssi(struct iwl_mvm *mvm, - struct iwl_lq_sta *lq_sta, + struct iwl_mvm_sta *mvmsta, struct ieee80211_rx_status *rx_status) { + struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; int i; lq_sta->pers.chains = rx_status->chains; @@ -2858,15 +2855,15 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init); } -static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, - struct ieee80211_tx_rate_control *txrc) +static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, + void *mvm_sta, + struct ieee80211_tx_rate_control *txrc) { - struct sk_buff *skb = txrc->skb; - struct iwl_op_mode *op_mode __maybe_unused = - (struct iwl_op_mode *)mvm_r; + struct iwl_op_mode *op_mode = mvm_r; struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); + struct sk_buff *skb = txrc->skb; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct iwl_lq_sta *lq_sta = mvm_sta; + struct iwl_lq_sta *lq_sta; struct rs_rate *optimal_rate; u32 last_ucode_rate; @@ -2878,18 +2875,14 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, mvm_sta = NULL; } - /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ - - /* Treat uninitialized rate scaling data same as non-existing. */ - if (lq_sta && !lq_sta->pers.drv) { - IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); - mvm_sta = NULL; - } - /* Send management frames and NO_ACK data using lowest rate. */ if (rate_control_send_low(sta, mvm_sta, txrc)) return; + if (!mvm_sta) + return; + + lq_sta = mvm_sta; iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, info->band, &info->control.rates[0]); info->control.rates[0].count = 1; @@ -2906,13 +2899,13 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, } } -static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, - gfp_t gfp) +static void *rs_drv_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, + gfp_t gfp) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate; struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; + struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); @@ -2926,7 +2919,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); lq_sta->pers.last_rssi = S8_MIN; - return &mvmsta->lq_sta; + return lq_sta; } static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap, @@ -3043,7 +3036,7 @@ static void rs_vht_init(struct iwl_mvm *mvm, } #ifdef CONFIG_IWLWIFI_DEBUGFS -static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm) +void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm) { spin_lock_bh(&mvm->drv_stats_lock); memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats)); @@ -3111,15 +3104,15 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) /* * Called after adding a new station to initialize rate scaling */ -void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum nl80211_band band, bool init) +static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + enum nl80211_band band, bool init) { int i, j; struct ieee80211_hw *hw = mvm->hw; struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); - struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; + struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; struct ieee80211_supported_band *sband; unsigned long supp; /* must be unsigned long for for_each_set_bit */ @@ -3194,16 +3187,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, rs_initialize_lq(mvm, sta, lq_sta, band, init); } -static void rs_rate_update(void *mvm_r, - struct ieee80211_supported_band *sband, - struct cfg80211_chan_def *chandef, - struct ieee80211_sta *sta, void *priv_sta, - u32 changed) +static void rs_drv_rate_update(void *mvm_r, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, + void *priv_sta, u32 changed) { + struct iwl_op_mode *op_mode = mvm_r; + struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); u8 tid; - struct iwl_op_mode *op_mode = - (struct iwl_op_mode *)mvm_r; - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); if (!iwl_mvm_sta_from_mac80211(sta)->vif) return; @@ -3385,7 +3377,7 @@ static void rs_bfer_active_iter(void *_data, { struct rs_bfer_active_iter_data *data = _data; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); - struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.lq; + struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.rs_drv.lq; u32 ss_params = le32_to_cpu(lq_cmd->ss_params); if (sta == data->exclude_sta) @@ -3497,7 +3489,8 @@ static void rs_set_lq_ss_params(struct iwl_mvm *mvm, /* Disallow BFER on another STA if active and we're a higher priority */ if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { - struct iwl_lq_cmd *bfersta_lq_cmd = &bfer_mvmsta->lq_sta.lq; + struct iwl_lq_cmd *bfersta_lq_cmd = + &bfer_mvmsta->lq_sta.rs_drv.lq; u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; @@ -3569,14 +3562,14 @@ static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { return hw->priv; } + /* rate scale requires free function to be implemented */ static void rs_free(void *mvm_rate) { return; } -static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta, - void *mvm_sta) +static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta) { struct iwl_op_mode *op_mode __maybe_unused = mvm_r; struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); @@ -3586,7 +3579,7 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta, } #ifdef CONFIG_MAC80211_DEBUGFS -int rs_pretty_print_rate(char *buf, const u32 rate) +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) { char *type, *bw; @@ -3597,10 +3590,10 @@ int rs_pretty_print_rate(char *buf, const u32 rate) !(rate & RATE_MCS_VHT_MSK)) { int index = iwl_hwrate_to_plcp_idx(rate); - return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n", - rs_pretty_ant(ant), - index == IWL_RATE_INVALID ? "BAD" : - iwl_rate_mcs[index].mbps); + return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps\n", + rs_pretty_ant(ant), + index == IWL_RATE_INVALID ? "BAD" : + iwl_rate_mcs[index].mbps); } if (rate & RATE_MCS_VHT_MSK) { @@ -3634,12 +3627,13 @@ int rs_pretty_print_rate(char *buf, const u32 rate) bw = "BAD BW"; } - return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s\n", - type, rs_pretty_ant(ant), bw, mcs, nss, - (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", - (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", - (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", - (rate & RATE_MCS_BF_MSK) ? "BF " : ""); + return scnprintf(buf, bufsz, + "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s\n", + type, rs_pretty_ant(ant), bw, mcs, nss, + (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", + (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", + (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", + (rate & RATE_MCS_BF_MSK) ? "BF " : ""); } /** @@ -3696,65 +3690,70 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, int desc = 0; int i = 0; ssize_t ret; + static const size_t bufsz = 2048; struct iwl_lq_sta *lq_sta = file->private_data; struct iwl_mvm_sta *mvmsta = - container_of(lq_sta, struct iwl_mvm_sta, lq_sta); + container_of(lq_sta, struct iwl_mvm_sta, lq_sta.rs_drv); struct iwl_mvm *mvm; struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); struct rs_rate *rate = &tbl->rate; u32 ss_params; mvm = lq_sta->pers.drv; - buff = kmalloc(2048, GFP_KERNEL); + buff = kmalloc(bufsz, GFP_KERNEL); if (!buff) return -ENOMEM; - desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); - desc += sprintf(buff+desc, "failed=%d success=%d rate=0%lX\n", - lq_sta->total_failed, lq_sta->total_success, - lq_sta->active_legacy_rate); - desc += sprintf(buff+desc, "fixed rate 0x%X\n", - lq_sta->pers.dbg_fixed_rate); - desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", + desc += scnprintf(buff + desc, bufsz - desc, + "sta_id %d\n", lq_sta->lq.sta_id); + desc += scnprintf(buff + desc, bufsz - desc, + "failed=%d success=%d rate=0%lX\n", + lq_sta->total_failed, lq_sta->total_success, + lq_sta->active_legacy_rate); + desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n", + lq_sta->pers.dbg_fixed_rate); + desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s%s\n", (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "", (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "", (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : ""); - desc += sprintf(buff+desc, "lq type %s\n", - (is_legacy(rate)) ? "legacy" : - is_vht(rate) ? "VHT" : "HT"); + desc += scnprintf(buff + desc, bufsz - desc, "lq type %s\n", + (is_legacy(rate)) ? "legacy" : + is_vht(rate) ? "VHT" : "HT"); if (!is_legacy(rate)) { - desc += sprintf(buff + desc, " %s", + desc += scnprintf(buff + desc, bufsz - desc, " %s", (is_siso(rate)) ? "SISO" : "MIMO2"); - desc += sprintf(buff + desc, " %s", + desc += scnprintf(buff + desc, bufsz - desc, " %s", (is_ht20(rate)) ? "20MHz" : (is_ht40(rate)) ? "40MHz" : (is_ht80(rate)) ? "80MHz" : (is_ht160(rate)) ? "160MHz" : "BAD BW"); - desc += sprintf(buff + desc, " %s %s %s %s\n", + desc += scnprintf(buff + desc, bufsz - desc, " %s %s %s %s\n", (rate->sgi) ? "SGI" : "NGI", (rate->ldpc) ? "LDPC" : "BCC", (lq_sta->is_agg) ? "AGG on" : "", (mvmsta->tlc_amsdu) ? "AMSDU on" : ""); } - desc += sprintf(buff+desc, "last tx rate=0x%X\n", + desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n", lq_sta->last_rate_n_flags); - desc += sprintf(buff+desc, + desc += scnprintf(buff + desc, bufsz - desc, "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n", lq_sta->lq.flags, lq_sta->lq.mimo_delim, lq_sta->lq.single_stream_ant_msk, lq_sta->lq.dual_stream_ant_msk); - desc += sprintf(buff+desc, + desc += scnprintf(buff + desc, bufsz - desc, "agg: time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n", le16_to_cpu(lq_sta->lq.agg_time_limit), lq_sta->lq.agg_disable_start_th, lq_sta->lq.agg_frame_cnt_limit); - desc += sprintf(buff+desc, "reduced tpc=%d\n", lq_sta->lq.reduced_tpc); + desc += scnprintf(buff + desc, bufsz - desc, "reduced tpc=%d\n", + lq_sta->lq.reduced_tpc); ss_params = le32_to_cpu(lq_sta->lq.ss_params); - desc += sprintf(buff+desc, "single stream params: %s%s%s%s\n", + desc += scnprintf(buff + desc, bufsz - desc, + "single stream params: %s%s%s%s\n", (ss_params & LQ_SS_PARAMS_VALID) ? "VALID" : "INVALID", (ss_params & LQ_SS_BFER_ALLOWED) ? @@ -3763,7 +3762,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, ", STBC" : "", (ss_params & LQ_SS_FORCE) ? ", FORCE" : ""); - desc += sprintf(buff+desc, + desc += scnprintf(buff + desc, bufsz - desc, "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n", lq_sta->lq.initial_rate_index[0], lq_sta->lq.initial_rate_index[1], @@ -3773,8 +3772,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { u32 r = le32_to_cpu(lq_sta->lq.rs_table[i]); - desc += sprintf(buff+desc, " rate[%d] 0x%X ", i, r); - desc += rs_pretty_print_rate(buff+desc, r); + desc += scnprintf(buff + desc, bufsz - desc, + " rate[%d] 0x%X ", i, r); + desc += rs_pretty_print_rate(buff + desc, bufsz - desc, r); } ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); @@ -3987,12 +3987,13 @@ static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf, MVM_DEBUGFS_READ_WRITE_FILE_OPS(ss_force, 32); -static void rs_add_debugfs(void *mvm, void *priv_sta, struct dentry *dir) +static void rs_drv_add_sta_debugfs(void *mvm, void *priv_sta, + struct dentry *dir) { struct iwl_lq_sta *lq_sta = priv_sta; struct iwl_mvm_sta *mvmsta; - mvmsta = container_of(lq_sta, struct iwl_mvm_sta, lq_sta); + mvmsta = container_of(lq_sta, struct iwl_mvm_sta, lq_sta.rs_drv); if (!mvmsta->vif) return; @@ -4014,7 +4015,7 @@ err: IWL_ERR((struct iwl_mvm *)mvm, "Can't create debugfs entity\n"); } -static void rs_remove_debugfs(void *mvm, void *mvm_sta) +void rs_remove_sta_debugfs(void *mvm, void *mvm_sta) { } #endif @@ -4024,50 +4025,53 @@ static void rs_remove_debugfs(void *mvm, void *mvm_sta) * the station is added. Since mac80211 calls this function before a * station is added we ignore it. */ -static void rs_rate_init_stub(void *mvm_r, - struct ieee80211_supported_band *sband, - struct cfg80211_chan_def *chandef, - struct ieee80211_sta *sta, void *mvm_sta) +static void rs_rate_init_ops(void *mvm_r, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *mvm_sta) { } -static const struct rate_control_ops rs_mvm_ops = { +/* ops for rate scaling implemented in the driver */ +static const struct rate_control_ops rs_mvm_ops_drv = { .name = RS_NAME, - .tx_status = rs_mac80211_tx_status, - .get_rate = rs_get_rate, - .rate_init = rs_rate_init_stub, + .tx_status = rs_drv_mac80211_tx_status, + .get_rate = rs_drv_get_rate, + .rate_init = rs_rate_init_ops, .alloc = rs_alloc, .free = rs_free, - .alloc_sta = rs_alloc_sta, + .alloc_sta = rs_drv_alloc_sta, .free_sta = rs_free_sta, - .rate_update = rs_rate_update, + .rate_update = rs_drv_rate_update, #ifdef CONFIG_MAC80211_DEBUGFS - .add_sta_debugfs = rs_add_debugfs, - .remove_sta_debugfs = rs_remove_debugfs, + .add_sta_debugfs = rs_drv_add_sta_debugfs, + .remove_sta_debugfs = rs_remove_sta_debugfs, #endif }; +void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + enum nl80211_band band, bool init) +{ + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) + rs_fw_rate_init(mvm, sta, band); + else + rs_drv_rate_init(mvm, sta, band, init); +} + int iwl_mvm_rate_control_register(void) { - return ieee80211_rate_control_register(&rs_mvm_ops); + return ieee80211_rate_control_register(&rs_mvm_ops_drv); } void iwl_mvm_rate_control_unregister(void) { - ieee80211_rate_control_unregister(&rs_mvm_ops); + ieee80211_rate_control_unregister(&rs_mvm_ops_drv); } -/** - * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable - * Tx protection, according to this request and previous requests, - * and send the LQ command. - * @mvmsta: The station - * @enable: Enable Tx protection? - */ -int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, - bool enable) +static int rs_drv_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, + bool enable) { - struct iwl_lq_cmd *lq = &mvmsta->lq_sta.lq; + struct iwl_lq_cmd *lq = &mvmsta->lq_sta.rs_drv.lq; lockdep_assert_held(&mvm->mutex); @@ -4083,3 +4087,17 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, return iwl_mvm_send_lq_cmd(mvm, lq, false); } + +/** + * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection + * @mvmsta: The station + * @enable: Enable Tx protection? + */ +int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, + bool enable) +{ + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) + return rs_fw_tx_protection(mvm, mvmsta, enable); + else + return rs_drv_tx_protection(mvm, mvmsta, enable); +} diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index 32b4d66debea..fb18cb8c233d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -36,6 +36,8 @@ #include "fw-api.h" #include "iwl-trans.h" +#define RS_NAME "iwl-mvm-rs" + struct iwl_rs_rate_info { u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ u8 plcp_ht_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ @@ -218,6 +220,38 @@ struct iwl_rate_mcs_info { }; /** + * struct iwl_lq_sta_rs_fw - rate and related statistics for RS in FW + * @last_rate_n_flags: last rate reported by FW + * @sta_id: the id of the station +#ifdef CONFIG_MAC80211_DEBUGFS + * @dbg_fixed_rate: for debug, use fixed rate if not 0 + * @dbg_agg_frame_count_lim: for debug, max number of frames in A-MPDU +#endif + * @chains: bitmask of chains reported in %chain_signal + * @chain_signal: per chain signal strength + * @last_rssi: last rssi reported + * @drv: pointer back to the driver data + */ + +struct iwl_lq_sta_rs_fw { + /* last tx rate_n_flags */ + u32 last_rate_n_flags; + + /* persistent fields - initialized only once - keep last! */ + struct lq_sta_pers_rs_fw { + u32 sta_id; +#ifdef CONFIG_MAC80211_DEBUGFS + u32 dbg_fixed_rate; + u16 dbg_agg_frame_count_lim; +#endif + u8 chains; + s8 chain_signal[IEEE80211_MAX_CHAINS]; + s8 last_rssi; + struct iwl_mvm *drv; + } pers; +}; + +/** * struct iwl_rate_scale_data -- tx success history for one rate */ struct iwl_rate_scale_data { @@ -407,4 +441,18 @@ struct iwl_mvm_sta; int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool enable); +#ifdef CONFIG_IWLWIFI_DEBUGFS +void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm); +#endif + +#ifdef CONFIG_MAC80211_DEBUGFS +void rs_remove_sta_debugfs(void *mvm, void *mvm_sta); +#endif + +void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta); +void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + enum nl80211_band band); +int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, + bool enable); +void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt); #endif /* __rs__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index d1a40688d5e1..63a57f0a16ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -383,7 +383,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, false); } - rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status); + rs_update_last_rssi(mvm, mvmsta, rx_status); if (iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_RSSI) && ieee80211_is_beacon(hdr->frame_control)) { @@ -439,7 +439,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->bw = RATE_INFO_BW_160; break; } - if (rate_n_flags & RATE_MCS_SGI_MSK) + if (!(rate_n_flags & RATE_MCS_CCK_MSK) && + rate_n_flags & RATE_MCS_SGI_MSK) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_HT_MCS_GF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 3b8d44361380..4a70e62c1b87 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -943,7 +943,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, false); } - rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status); + rs_update_last_rssi(mvm, mvmsta, rx_status); if (iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_RSSI) && ieee80211_is_beacon(hdr->frame_control)) { @@ -1020,7 +1020,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->bw = RATE_INFO_BW_160; break; } - if (rate_n_flags & RATE_MCS_SGI_MSK) + + if (!(rate_n_flags & RATE_MCS_CCK_MSK) && + rate_n_flags & RATE_MCS_SGI_MSK) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_HT_MCS_GF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index e4fd476e9ccb..356b16f40e78 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -664,6 +664,22 @@ static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies, return newpos; } +#define WFA_TPC_IE_LEN 9 + +static void iwl_mvm_add_tpc_report_ie(u8 *pos) +{ + pos[0] = WLAN_EID_VENDOR_SPECIFIC; + pos[1] = WFA_TPC_IE_LEN - 2; + pos[2] = (WLAN_OUI_MICROSOFT >> 16) & 0xff; + pos[3] = (WLAN_OUI_MICROSOFT >> 8) & 0xff; + pos[4] = WLAN_OUI_MICROSOFT & 0xff; + pos[5] = WLAN_OUI_TYPE_MICROSOFT_TPC; + pos[6] = 0; + /* pos[7] - tx power will be inserted by the FW */ + pos[7] = 0; + pos[8] = 0; +} + static void iwl_mvm_build_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_scan_ies *ies, @@ -716,7 +732,16 @@ iwl_mvm_build_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, memcpy(pos, ies->common_ies, ies->common_ie_len); params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf); - params->preq.common_data.len = cpu_to_le16(ies->common_ie_len); + + if (iwl_mvm_rrm_scan_needed(mvm) && + !fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)) { + iwl_mvm_add_tpc_report_ie(pos + ies->common_ie_len); + params->preq.common_data.len = cpu_to_le16(ies->common_ie_len + + WFA_TPC_IE_LEN); + } else { + params->preq.common_data.len = cpu_to_le16(ies->common_ie_len); + } } static void iwl_mvm_scan_lmac_dwell(struct iwl_mvm *mvm, @@ -781,7 +806,9 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, if (params->type == IWL_SCAN_TYPE_FRAGMENTED) flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED; - if (iwl_mvm_rrm_scan_needed(mvm)) + if (iwl_mvm_rrm_scan_needed(mvm) && + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)) flags |= IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED; if (params->pass_all) @@ -1183,7 +1210,9 @@ static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm, flags |= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED; } - if (iwl_mvm_rrm_scan_needed(mvm)) + if (iwl_mvm_rrm_scan_needed(mvm) && + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)) flags |= IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED; if (params->pass_all) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 1add5615fc3a..9d33f7a0a80a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1439,6 +1439,13 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, goto err; } + /* + * if rs is registered with mac80211, then "add station" will be handled + * via the corresponding ops, otherwise need to notify rate scaling here + */ + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) + iwl_mvm_rs_add_sta(mvm, mvm_sta); + update_fw: ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags); if (ret) @@ -1762,7 +1769,7 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) } /* - * For a000 firmware and on we cannot add queue to a station unknown + * For 22000 firmware and on we cannot add queue to a station unknown * to firmware so enable queue here - after the station was added */ if (iwl_mvm_has_new_tx_api(mvm)) @@ -1885,7 +1892,7 @@ int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) return ret; /* - * For a000 firmware and on we cannot add queue to a station unknown + * For 22000 firmware and on we cannot add queue to a station unknown * to firmware so enable queue here - after the station was added */ if (iwl_mvm_has_new_tx_api(mvm)) { @@ -2064,7 +2071,7 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) /* * Enable cab queue after the ADD_STA command is sent. - * This is needed for a000 firmware which won't accept SCD_QUEUE_CFG + * This is needed for 22000 firmware which won't accept SCD_QUEUE_CFG * command with unknown station id, and for FW that doesn't support * station API since the cab queue is not included in the * tfd_queue_mask. @@ -2530,7 +2537,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, tid_data->next_reclaimed); /* - * In A000 HW, the next_reclaimed index is only 8 bit, so we'll need + * In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; @@ -2575,6 +2582,14 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, .aggregate = true, }; + /* + * When FW supports TLC_OFFLOAD, it also implements Tx aggregation + * manager, so this function should never be called in this case. + */ + if (WARN_ON_ONCE(fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))) + return -EINVAL; + BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE) != IWL_MAX_TID_COUNT); @@ -2672,12 +2687,12 @@ out: */ mvmsta->max_agg_bufsize = min(mvmsta->max_agg_bufsize, buf_size); - mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize; + mvmsta->lq_sta.rs_drv.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize; IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n", sta->addr, tid); - return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, false); + return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.rs_drv.lq, false); } static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, @@ -3615,7 +3630,7 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data) u16 sn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); /* - * In A000 HW, the next_reclaimed index is only 8 bit, so we'll need + * In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need * to align the wrap around of ssn so we compare relevant values. */ if (mvm->trans->cfg->gen2) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index aedabe101cf0..5ffd6adbc383 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -383,6 +383,8 @@ struct iwl_mvm_rxq_dup_data { * and from Tx response flow, it needs a spinlock. * @tid_data: per tid data + mgmt. Look at %iwl_mvm_tid_data. * @tid_to_baid: a simple map of TID to baid + * @lq_sta: holds rate scaling data, either for the case when RS is done in + * the driver - %rs_drv or in the FW - %rs_fw. * @reserved_queue: the queue reserved for this STA for DQA purposes * Every STA has is given one reserved queue to allow it to operate. If no * such queue can be guaranteed, the STA addition will fail. @@ -417,7 +419,10 @@ struct iwl_mvm_sta { spinlock_t lock; struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT + 1]; u8 tid_to_baid[IWL_MAX_TID_COUNT]; - struct iwl_lq_sta lq_sta; + union { + struct iwl_lq_sta_rs_fw rs_fw; + struct iwl_lq_sta rs_drv; + } lq_sta; struct ieee80211_vif *vif; struct iwl_mvm_key_pn __rcu *ptk_pn[4]; struct iwl_mvm_rxq_dup_data *dup_data; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index e25cda9fbf6c..200ab50ec86b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -101,7 +101,6 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, void iwl_mvm_roc_done_wk(struct work_struct *wk) { struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk); - u32 queues = 0; /* * Clear the ROC_RUNNING /ROC_AUX_RUNNING status bit. @@ -110,14 +109,10 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) * in the case that the time event actually completed in the firmware * (which is handled in iwl_mvm_te_handle_notif). */ - if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) { - queues |= BIT(IWL_MVM_OFFCHANNEL_QUEUE); + if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) iwl_mvm_unref(mvm, IWL_MVM_REF_ROC); - } - if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) { - queues |= BIT(mvm->aux_queue); + if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) iwl_mvm_unref(mvm, IWL_MVM_REF_ROC_AUX); - } synchronize_net(); @@ -777,12 +772,6 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return -EBUSY; } - /* - * Flush the done work, just in case it's still pending, so that - * the work it does can complete and we can accept new frames. - */ - flush_work(&mvm->roc_done_wk); - time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); time_cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 333bcb75b8af..84d16522d664 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1132,7 +1132,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, } /* - * In A000 HW, the next_reclaimed index is only 8 bit, so we'll need + * In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; @@ -1624,7 +1624,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, int freed; if (WARN_ONCE(sta_id >= IWL_MVM_STATION_COUNT || - tid >= IWL_MAX_TID_COUNT, + tid > IWL_MAX_TID_COUNT, "sta_id %d tid %d", sta_id, tid)) return; @@ -1679,7 +1679,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, if (ieee80211_is_data_qos(hdr->frame_control)) freed++; else - WARN_ON_ONCE(1); + WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); @@ -1719,8 +1719,12 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, ba_info->band = chanctx_conf->def.chan->band; iwl_mvm_hwrate_to_tx_status(rate, ba_info); - IWL_DEBUG_TX_REPLY(mvm, "No reclaim. Update rs directly\n"); - iwl_mvm_rs_tx_status(mvm, sta, tid, ba_info, false); + if (!fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) { + IWL_DEBUG_TX_REPLY(mvm, + "No reclaim. Update rs directly\n"); + iwl_mvm_rs_tx_status(mvm, sta, tid, ba_info, false); + } } out: @@ -1771,8 +1775,12 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) struct iwl_mvm_compressed_ba_tfd *ba_tfd = &ba_res->tfd[i]; + tid = ba_tfd->tid; + if (tid == IWL_MGMT_TID) + tid = IWL_MAX_TID_COUNT; + mvmsta->tid_data[i].lq_color = lq_color; - iwl_mvm_tx_reclaim(mvm, sta_id, ba_tfd->tid, + iwl_mvm_tx_reclaim(mvm, sta_id, tid, (int)(le16_to_cpu(ba_tfd->q_num)), le16_to_cpu(ba_tfd->tfd_index), &ba_info, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 03ffd84786ca..0b7e29be8e50 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -278,8 +278,8 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx) u8 ind = last_idx; int i; - for (i = 0; i < RATE_MCS_ANT_NUM; i++) { - ind = (ind + 1) % RATE_MCS_ANT_NUM; + for (i = 0; i < MAX_RS_ANT_NUM; i++) { + ind = (ind + 1) % MAX_RS_ANT_NUM; if (valid & BIT(ind)) return ind; } @@ -595,6 +595,12 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base) void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) { + if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) { + IWL_ERR(mvm, + "DEVICE_ENABLED bit is not set. Aborting dump.\n"); + return; + } + iwl_mvm_dump_lmac_error_log(mvm, mvm->error_event_table[0]); if (mvm->error_event_table[1]) @@ -906,7 +912,9 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init) .data = { lq, }, }; - if (WARN_ON(lq->sta_id == IWL_MVM_INVALID_STA)) + if (WARN_ON(lq->sta_id == IWL_MVM_INVALID_STA || + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))) return -EINVAL; return iwl_mvm_send_cmd(mvm, &cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index ccd7c33c4c28..56fc28750a41 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -652,20 +652,20 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0xA370, 0x4034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA370, 0x40A4, iwl9462_2ac_cfg_soc)}, -/* a000 Series */ - {IWL_PCI_DEVICE(0x2720, 0x0A10, iwla000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x34F0, 0x0310, iwla000_2ac_cfg_jf)}, - {IWL_PCI_DEVICE(0x2720, 0x0000, iwla000_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0070, iwla000_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0078, iwla000_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x2720, 0x0030, iwla000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x2720, 0x1080, iwla000_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0090, iwla000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x2720, 0x0310, iwla000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x40C0, 0x0000, iwla000_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwla000_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwla000_2ax_cfg_hr)}, +/* 22000 Series */ + {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl22000_2ac_cfg_jf)}, + {IWL_PCI_DEVICE(0x2720, 0x0000, iwl22000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl22000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0078, iwl22000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x2720, 0x0030, iwl22000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x2720, 0x1080, iwl22000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x2720, 0x0310, iwl22000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x40C0, 0x0000, iwl22000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwl22000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl22000_2ax_cfg_hr)}, #endif /* CONFIG_IWLMVM */ @@ -707,7 +707,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->cfg = cfg_7265d; } - if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb && + if (iwl_trans->cfg->rf_id && cfg == &iwl22000_2ac_cfg_hr_cdb && iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) { u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id); u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF); @@ -715,14 +715,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (rf_id_chp == jf_chp_id) { if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ) - cfg = &iwla000_2ax_cfg_qnj_jf_b0; + cfg = &iwl22000_2ax_cfg_qnj_jf_b0; else - cfg = &iwla000_2ac_cfg_jf; + cfg = &iwl22000_2ac_cfg_jf; } else if (rf_id_chp == hr_chp_id) { if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ) - cfg = &iwla000_2ax_cfg_qnj_hr_a0; + cfg = &iwl22000_2ax_cfg_qnj_hr_a0; else - cfg = &iwla000_2ac_cfg_hr; + cfg = &iwl22000_2ac_cfg_hr; } iwl_trans->cfg = cfg; } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 4541c86881d6..fbc45361f0bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3250,9 +3250,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS); if (hw_status & UMAG_GEN_HW_IS_FPGA) - trans->cfg = &iwla000_2ax_cfg_qnj_hr_f0; + trans->cfg = &iwl22000_2ax_cfg_qnj_hr_f0; else - trans->cfg = &iwla000_2ac_cfg_hr; + trans->cfg = &iwl22000_2ac_cfg_hr; } #endif diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 10b075a46b26..e8189c07b41f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -684,6 +684,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, hdr = skb_put(skb, sizeof(*hdr) - ETH_ALEN); hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | + IEEE80211_FCTL_TODS | (ps ? IEEE80211_FCTL_PM : 0)); hdr->duration_id = cpu_to_le16(0); memcpy(hdr->addr1, vp->bssid, ETH_ALEN); @@ -3215,7 +3216,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) continue; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!skb) { res = -ENOMEM; goto out_err; diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 6e0d9a9c5cfb..ce4432c535f0 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -1116,6 +1116,12 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); enum nl80211_iftype curr_iftype = dev->ieee80211_ptr->iftype; + if (priv->scan_request) { + mwifiex_dbg(priv->adapter, ERROR, + "change virtual interface: scan in process\n"); + return -EBUSY; + } + switch (curr_iftype) { case NL80211_IFTYPE_ADHOC: switch (type) { @@ -1180,7 +1186,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, case NL80211_IFTYPE_AP: switch (type) { case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype, type, params); break; diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index e813b2ca740c..8e4e9b6919e0 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -199,7 +199,7 @@ struct mwl8k_priv { struct ieee80211_channel channels_24[14]; struct ieee80211_rate rates_24[13]; struct ieee80211_supported_band band_50; - struct ieee80211_channel channels_50[4]; + struct ieee80211_channel channels_50[9]; struct ieee80211_rate rates_50[8]; u32 ap_macids_supported; u32 sta_macids_supported; @@ -383,6 +383,11 @@ static const struct ieee80211_channel mwl8k_channels_50[] = { { .band = NL80211_BAND_5GHZ, .center_freq = 5200, .hw_value = 40, }, { .band = NL80211_BAND_5GHZ, .center_freq = 5220, .hw_value = 44, }, { .band = NL80211_BAND_5GHZ, .center_freq = 5240, .hw_value = 48, }, + { .band = NL80211_BAND_5GHZ, .center_freq = 5745, .hw_value = 149, }, + { .band = NL80211_BAND_5GHZ, .center_freq = 5765, .hw_value = 153, }, + { .band = NL80211_BAND_5GHZ, .center_freq = 5785, .hw_value = 157, }, + { .band = NL80211_BAND_5GHZ, .center_freq = 5805, .hw_value = 161, }, + { .band = NL80211_BAND_5GHZ, .center_freq = 5825, .hw_value = 165, }, }; static const struct ieee80211_rate mwl8k_rates_50[] = { diff --git a/drivers/net/wireless/mediatek/Kconfig b/drivers/net/wireless/mediatek/Kconfig index 28843fed750a..92ce4062f307 100644 --- a/drivers/net/wireless/mediatek/Kconfig +++ b/drivers/net/wireless/mediatek/Kconfig @@ -11,4 +11,5 @@ config WLAN_VENDOR_MEDIATEK if WLAN_VENDOR_MEDIATEK source "drivers/net/wireless/mediatek/mt7601u/Kconfig" +source "drivers/net/wireless/mediatek/mt76/Kconfig" endif # WLAN_VENDOR_MEDIATEK diff --git a/drivers/net/wireless/mediatek/Makefile b/drivers/net/wireless/mediatek/Makefile index 9d5f182fd7fd..00f945f59b38 100644 --- a/drivers/net/wireless/mediatek/Makefile +++ b/drivers/net/wireless/mediatek/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_MT7601U) += mt7601u/ +obj-$(CONFIG_MT76_CORE) += mt76/ diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig new file mode 100644 index 000000000000..fc05d79c80d0 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/Kconfig @@ -0,0 +1,10 @@ +config MT76_CORE + tristate + +config MT76x2E + tristate "MediaTek MT76x2E (PCIe) support" + select MT76_CORE + depends on MAC80211 + depends on PCI + ---help--- + This adds support for MT7612/MT7602/MT7662-based wireless PCIe devices. diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile new file mode 100644 index 000000000000..2bb919863616 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -0,0 +1,15 @@ +obj-$(CONFIG_MT76_CORE) += mt76.o +obj-$(CONFIG_MT76x2E) += mt76x2e.o + +mt76-y := \ + mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o + +CFLAGS_trace.o := -I$(src) + +mt76x2e-y := \ + mt76x2_pci.o mt76x2_dma.o \ + mt76x2_main.o mt76x2_init.o mt76x2_debugfs.o mt76x2_tx.o \ + mt76x2_core.o mt76x2_mac.o mt76x2_eeprom.o mt76x2_mcu.o mt76x2_phy.o \ + mt76x2_dfs.o mt76x2_trace.o + +CFLAGS_mt76x2_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c new file mode 100644 index 000000000000..7c3612aaa8c4 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "mt76.h" + +static int +mt76_reg_set(void *data, u64 val) +{ + struct mt76_dev *dev = data; + + dev->bus->wr(dev, dev->debugfs_reg, val); + return 0; +} + +static int +mt76_reg_get(void *data, u64 *val) +{ + struct mt76_dev *dev = data; + + *val = dev->bus->rr(dev, dev->debugfs_reg); + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_regval, mt76_reg_get, mt76_reg_set, "0x%08llx\n"); + +static int +mt76_queues_read(struct seq_file *s, void *data) +{ + struct mt76_dev *dev = dev_get_drvdata(s->private); + int i; + + for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) { + struct mt76_queue *q = &dev->q_tx[i]; + + if (!q->ndesc) + continue; + + seq_printf(s, + "%d: queued=%d head=%d tail=%d swq_queued=%d\n", + i, q->queued, q->head, q->tail, q->swq_queued); + } + + return 0; +} + +struct dentry *mt76_register_debugfs(struct mt76_dev *dev) +{ + struct dentry *dir; + + dir = debugfs_create_dir("mt76", dev->hw->wiphy->debugfsdir); + if (!dir) + return NULL; + + debugfs_create_u8("led_pin", S_IRUSR | S_IWUSR, dir, &dev->led_pin); + debugfs_create_u32("regidx", S_IRUSR | S_IWUSR, dir, &dev->debugfs_reg); + debugfs_create_file("regval", S_IRUSR | S_IWUSR, dir, dev, + &fops_regval); + debugfs_create_blob("eeprom", S_IRUSR, dir, &dev->eeprom); + if (dev->otp.data) + debugfs_create_blob("otp", S_IRUSR, dir, &dev->otp); + debugfs_create_devm_seqfile(dev->dev, "queues", dir, mt76_queues_read); + + return dir; +} +EXPORT_SYMBOL_GPL(mt76_register_debugfs); diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c new file mode 100644 index 000000000000..ecd409a4a89b --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/dma-mapping.h> +#include "mt76.h" +#include "dma.h" + +#define DMA_DUMMY_TXWI ((void *) ~0) + +static int +mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q) +{ + int size; + int i; + + spin_lock_init(&q->lock); + INIT_LIST_HEAD(&q->swq); + + size = q->ndesc * sizeof(struct mt76_desc); + q->desc = dmam_alloc_coherent(dev->dev, size, &q->desc_dma, GFP_KERNEL); + if (!q->desc) + return -ENOMEM; + + size = q->ndesc * sizeof(*q->entry); + q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL); + if (!q->entry) + return -ENOMEM; + + /* clear descriptors */ + for (i = 0; i < q->ndesc; i++) + q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE); + + iowrite32(q->desc_dma, &q->regs->desc_base); + iowrite32(0, &q->regs->cpu_idx); + iowrite32(0, &q->regs->dma_idx); + iowrite32(q->ndesc, &q->regs->ring_size); + + return 0; +} + +static int +mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, + struct mt76_queue_buf *buf, int nbufs, u32 info, + struct sk_buff *skb, void *txwi) +{ + struct mt76_desc *desc; + u32 ctrl; + int i, idx = -1; + + if (txwi) + q->entry[q->head].txwi = DMA_DUMMY_TXWI; + + for (i = 0; i < nbufs; i += 2, buf += 2) { + u32 buf0 = buf[0].addr, buf1 = 0; + + ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); + if (i < nbufs - 1) { + buf1 = buf[1].addr; + ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len); + } + + if (i == nbufs - 1) + ctrl |= MT_DMA_CTL_LAST_SEC0; + else if (i == nbufs - 2) + ctrl |= MT_DMA_CTL_LAST_SEC1; + + idx = q->head; + q->head = (q->head + 1) % q->ndesc; + + desc = &q->desc[idx]; + + WRITE_ONCE(desc->buf0, cpu_to_le32(buf0)); + WRITE_ONCE(desc->buf1, cpu_to_le32(buf1)); + WRITE_ONCE(desc->info, cpu_to_le32(info)); + WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); + + q->queued++; + } + + q->entry[idx].txwi = txwi; + q->entry[idx].skb = skb; + + return idx; +} + +static void +mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx, + struct mt76_queue_entry *prev_e) +{ + struct mt76_queue_entry *e = &q->entry[idx]; + __le32 __ctrl = READ_ONCE(q->desc[idx].ctrl); + u32 ctrl = le32_to_cpu(__ctrl); + + if (!e->txwi || !e->skb) { + __le32 addr = READ_ONCE(q->desc[idx].buf0); + u32 len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctrl); + + dma_unmap_single(dev->dev, le32_to_cpu(addr), len, + DMA_TO_DEVICE); + } + + if (!(ctrl & MT_DMA_CTL_LAST_SEC0)) { + __le32 addr = READ_ONCE(q->desc[idx].buf1); + u32 len = FIELD_GET(MT_DMA_CTL_SD_LEN1, ctrl); + + dma_unmap_single(dev->dev, le32_to_cpu(addr), len, + DMA_TO_DEVICE); + } + + if (e->txwi == DMA_DUMMY_TXWI) + e->txwi = NULL; + + *prev_e = *e; + memset(e, 0, sizeof(*e)); +} + +static void +mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q) +{ + q->head = ioread32(&q->regs->dma_idx); + q->tail = q->head; + iowrite32(q->head, &q->regs->cpu_idx); +} + +static void +mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush) +{ + struct mt76_queue *q = &dev->q_tx[qid]; + struct mt76_queue_entry entry; + bool wake = false; + int last; + + if (!q->ndesc) + return; + + spin_lock_bh(&q->lock); + if (flush) + last = -1; + else + last = ioread32(&q->regs->dma_idx); + + while (q->queued && q->tail != last) { + mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry); + if (entry.schedule) + q->swq_queued--; + + if (entry.skb) + dev->drv->tx_complete_skb(dev, q, &entry, flush); + + if (entry.txwi) { + mt76_put_txwi(dev, entry.txwi); + wake = true; + } + + q->tail = (q->tail + 1) % q->ndesc; + q->queued--; + + if (!flush && q->tail == last) + last = ioread32(&q->regs->dma_idx); + } + + if (!flush) + mt76_txq_schedule(dev, q); + else + mt76_dma_sync_idx(dev, q); + + wake = wake && qid < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8; + spin_unlock_bh(&q->lock); + + if (wake) + ieee80211_wake_queue(dev->hw, qid); +} + +static void * +mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx, + int *len, u32 *info, bool *more) +{ + struct mt76_queue_entry *e = &q->entry[idx]; + struct mt76_desc *desc = &q->desc[idx]; + dma_addr_t buf_addr; + void *buf = e->buf; + int buf_len = SKB_WITH_OVERHEAD(q->buf_size); + + buf_addr = le32_to_cpu(READ_ONCE(desc->buf0)); + if (len) { + u32 ctl = le32_to_cpu(READ_ONCE(desc->ctrl)); + *len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctl); + *more = !(ctl & MT_DMA_CTL_LAST_SEC0); + } + + if (info) + *info = le32_to_cpu(desc->info); + + dma_unmap_single(dev->dev, buf_addr, buf_len, DMA_FROM_DEVICE); + e->buf = NULL; + + return buf; +} + +static void * +mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush, + int *len, u32 *info, bool *more) +{ + int idx = q->tail; + + *more = false; + if (!q->queued) + return NULL; + + if (!flush && !(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE))) + return NULL; + + q->tail = (q->tail + 1) % q->ndesc; + q->queued--; + + return mt76_dma_get_buf(dev, q, idx, len, info, more); +} + +static void +mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q) +{ + iowrite32(q->head, &q->regs->cpu_idx); +} + +static int +mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q, bool napi) +{ + dma_addr_t addr; + void *buf; + int frames = 0; + int len = SKB_WITH_OVERHEAD(q->buf_size); + int offset = q->buf_offset; + int idx; + void *(*alloc)(unsigned int fragsz); + + if (napi) + alloc = napi_alloc_frag; + else + alloc = netdev_alloc_frag; + + spin_lock_bh(&q->lock); + + while (q->queued < q->ndesc - 1) { + struct mt76_queue_buf qbuf; + + buf = alloc(q->buf_size); + if (!buf) + break; + + addr = dma_map_single(dev->dev, buf, len, DMA_FROM_DEVICE); + if (dma_mapping_error(dev->dev, addr)) { + skb_free_frag(buf); + break; + } + + qbuf.addr = addr + offset; + qbuf.len = len - offset; + idx = mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, NULL); + frames++; + } + + if (frames) + mt76_dma_kick_queue(dev, q); + + spin_unlock_bh(&q->lock); + + return frames; +} + +static void +mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) +{ + void *buf; + bool more; + + spin_lock_bh(&q->lock); + do { + buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more); + if (!buf) + break; + + skb_free_frag(buf); + } while (1); + spin_unlock_bh(&q->lock); +} + +static void +mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid) +{ + struct mt76_queue *q = &dev->q_rx[qid]; + int i; + + for (i = 0; i < q->ndesc; i++) + q->desc[i].ctrl &= ~cpu_to_le32(MT_DMA_CTL_DMA_DONE); + + mt76_dma_rx_cleanup(dev, q); + mt76_dma_sync_idx(dev, q); + mt76_dma_rx_fill(dev, q, false); +} + +static void +mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, + int len, bool more) +{ + struct page *page = virt_to_head_page(data); + int offset = data - page_address(page); + struct sk_buff *skb = q->rx_head; + + offset += q->buf_offset; + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len, + q->buf_size); + + if (more) + return; + + q->rx_head = NULL; + dev->drv->rx_skb(dev, q - dev->q_rx, skb); +} + +static int +mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget) +{ + struct sk_buff *skb; + unsigned char *data; + int len; + int done = 0; + bool more; + + while (done < budget) { + u32 info; + + data = mt76_dma_dequeue(dev, q, false, &len, &info, &more); + if (!data) + break; + + if (q->rx_head) { + mt76_add_fragment(dev, q, data, len, more); + continue; + } + + skb = build_skb(data, q->buf_size); + if (!skb) { + skb_free_frag(data); + continue; + } + + skb_reserve(skb, q->buf_offset); + if (skb->tail + len > skb->end) { + dev_kfree_skb(skb); + continue; + } + + if (q == &dev->q_rx[MT_RXQ_MCU]) { + u32 *rxfce = (u32 *) skb->cb; + *rxfce = info; + } + + __skb_put(skb, len); + done++; + + if (more) { + q->rx_head = skb; + continue; + } + + dev->drv->rx_skb(dev, q - dev->q_rx, skb); + } + + mt76_dma_rx_fill(dev, q, true); + return done; +} + +static int +mt76_dma_rx_poll(struct napi_struct *napi, int budget) +{ + struct mt76_dev *dev; + int qid, done; + + dev = container_of(napi->dev, struct mt76_dev, napi_dev); + qid = napi - dev->napi; + + done = mt76_dma_rx_process(dev, &dev->q_rx[qid], budget); + if (done < budget) { + napi_complete(napi); + dev->drv->rx_poll_complete(dev, qid); + } + mt76_rx_complete(dev, qid); + + return done; +} + +static int +mt76_dma_init(struct mt76_dev *dev) +{ + int i; + + init_dummy_netdev(&dev->napi_dev); + + for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) { + netif_napi_add(&dev->napi_dev, &dev->napi[i], mt76_dma_rx_poll, + 64); + mt76_dma_rx_fill(dev, &dev->q_rx[i], false); + skb_queue_head_init(&dev->rx_skb[i]); + napi_enable(&dev->napi[i]); + } + + return 0; +} + +static const struct mt76_queue_ops mt76_dma_ops = { + .init = mt76_dma_init, + .alloc = mt76_dma_alloc_queue, + .add_buf = mt76_dma_add_buf, + .tx_cleanup = mt76_dma_tx_cleanup, + .rx_reset = mt76_dma_rx_reset, + .kick = mt76_dma_kick_queue, +}; + +int mt76_dma_attach(struct mt76_dev *dev) +{ + dev->queue_ops = &mt76_dma_ops; + return 0; +} +EXPORT_SYMBOL_GPL(mt76_dma_attach); + +void mt76_dma_cleanup(struct mt76_dev *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) + mt76_dma_tx_cleanup(dev, i, true); + + for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) { + netif_napi_del(&dev->napi[i]); + mt76_dma_rx_cleanup(dev, &dev->q_rx[i]); + } +} +EXPORT_SYMBOL_GPL(mt76_dma_cleanup); diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h new file mode 100644 index 000000000000..1dad39697929 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/dma.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __MT76_DMA_H +#define __MT76_DMA_H + +#define MT_RING_SIZE 0x10 + +#define MT_DMA_CTL_SD_LEN1 GENMASK(13, 0) +#define MT_DMA_CTL_LAST_SEC1 BIT(14) +#define MT_DMA_CTL_BURST BIT(15) +#define MT_DMA_CTL_SD_LEN0 GENMASK(29, 16) +#define MT_DMA_CTL_LAST_SEC0 BIT(30) +#define MT_DMA_CTL_DMA_DONE BIT(31) + +struct mt76_desc { + __le32 buf0; + __le32 ctrl; + __le32 buf1; + __le32 info; +} __packed __aligned(4); + +int mt76_dma_attach(struct mt76_dev *dev); +void mt76_dma_cleanup(struct mt76_dev *dev); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c new file mode 100644 index 000000000000..530e5593765c --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <linux/of.h> +#include <linux/of_net.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/etherdevice.h> +#include "mt76.h" + +static int +mt76_get_of_eeprom(struct mt76_dev *dev, int len) +{ +#if defined(CONFIG_OF) && defined(CONFIG_MTD) + struct device_node *np = dev->dev->of_node; + struct mtd_info *mtd; + const __be32 *list; + const char *part; + phandle phandle; + int offset = 0; + int size; + size_t retlen; + int ret; + + if (!np) + return -ENOENT; + + list = of_get_property(np, "mediatek,mtd-eeprom", &size); + if (!list) + return -ENOENT; + + phandle = be32_to_cpup(list++); + if (!phandle) + return -ENOENT; + + np = of_find_node_by_phandle(phandle); + if (!np) + return -EINVAL; + + part = of_get_property(np, "label", NULL); + if (!part) + part = np->name; + + mtd = get_mtd_device_nm(part); + if (IS_ERR(mtd)) + return PTR_ERR(mtd); + + if (size <= sizeof(*list)) + return -EINVAL; + + offset = be32_to_cpup(list); + ret = mtd_read(mtd, offset, len, &retlen, dev->eeprom.data); + put_mtd_device(mtd); + if (ret) + return ret; + + if (retlen < len) + return -EINVAL; + + return 0; +#else + return -ENOENT; +#endif +} + +void +mt76_eeprom_override(struct mt76_dev *dev) +{ +#ifdef CONFIG_OF + struct device_node *np = dev->dev->of_node; + const u8 *mac; + + if (!np) + return; + + mac = of_get_mac_address(np); + if (mac) + memcpy(dev->macaddr, mac, ETH_ALEN); +#endif + + if (!is_valid_ether_addr(dev->macaddr)) { + eth_random_addr(dev->macaddr); + dev_info(dev->dev, + "Invalid MAC address, using random address %pM\n", + dev->macaddr); + } +} +EXPORT_SYMBOL_GPL(mt76_eeprom_override); + +int +mt76_eeprom_init(struct mt76_dev *dev, int len) +{ + dev->eeprom.size = len; + dev->eeprom.data = devm_kzalloc(dev->dev, len, GFP_KERNEL); + if (!dev->eeprom.data) + return -ENOMEM; + + return !mt76_get_of_eeprom(dev, len); +} +EXPORT_SYMBOL_GPL(mt76_eeprom_init); diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c new file mode 100644 index 000000000000..3acf0e175d71 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <linux/of.h> +#include "mt76.h" + +#define CHAN2G(_idx, _freq) { \ + .band = NL80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_idx), \ + .max_power = 30, \ +} + +#define CHAN5G(_idx, _freq) { \ + .band = NL80211_BAND_5GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_idx), \ + .max_power = 30, \ +} + +static const struct ieee80211_channel mt76_channels_2ghz[] = { + CHAN2G(1, 2412), + CHAN2G(2, 2417), + CHAN2G(3, 2422), + CHAN2G(4, 2427), + CHAN2G(5, 2432), + CHAN2G(6, 2437), + CHAN2G(7, 2442), + CHAN2G(8, 2447), + CHAN2G(9, 2452), + CHAN2G(10, 2457), + CHAN2G(11, 2462), + CHAN2G(12, 2467), + CHAN2G(13, 2472), + CHAN2G(14, 2484), +}; + +static const struct ieee80211_channel mt76_channels_5ghz[] = { + CHAN5G(36, 5180), + CHAN5G(40, 5200), + CHAN5G(44, 5220), + CHAN5G(48, 5240), + + CHAN5G(52, 5260), + CHAN5G(56, 5280), + CHAN5G(60, 5300), + CHAN5G(64, 5320), + + CHAN5G(100, 5500), + CHAN5G(104, 5520), + CHAN5G(108, 5540), + CHAN5G(112, 5560), + CHAN5G(116, 5580), + CHAN5G(120, 5600), + CHAN5G(124, 5620), + CHAN5G(128, 5640), + CHAN5G(132, 5660), + CHAN5G(136, 5680), + CHAN5G(140, 5700), + + CHAN5G(149, 5745), + CHAN5G(153, 5765), + CHAN5G(157, 5785), + CHAN5G(161, 5805), + CHAN5G(165, 5825), +}; + +static const struct ieee80211_tpt_blink mt76_tpt_blink[] = { + { .throughput = 0 * 1024, .blink_time = 334 }, + { .throughput = 1 * 1024, .blink_time = 260 }, + { .throughput = 5 * 1024, .blink_time = 220 }, + { .throughput = 10 * 1024, .blink_time = 190 }, + { .throughput = 20 * 1024, .blink_time = 170 }, + { .throughput = 50 * 1024, .blink_time = 150 }, + { .throughput = 70 * 1024, .blink_time = 130 }, + { .throughput = 100 * 1024, .blink_time = 110 }, + { .throughput = 200 * 1024, .blink_time = 80 }, + { .throughput = 300 * 1024, .blink_time = 50 }, +}; + +static int mt76_led_init(struct mt76_dev *dev) +{ + struct device_node *np = dev->dev->of_node; + struct ieee80211_hw *hw = dev->hw; + int led_pin; + + if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set) + return 0; + + snprintf(dev->led_name, sizeof(dev->led_name), + "mt76-%s", wiphy_name(hw->wiphy)); + + dev->led_cdev.name = dev->led_name; + dev->led_cdev.default_trigger = + ieee80211_create_tpt_led_trigger(hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, + mt76_tpt_blink, + ARRAY_SIZE(mt76_tpt_blink)); + + np = of_get_child_by_name(np, "led"); + if (np) { + if (!of_property_read_u32(np, "led-sources", &led_pin)) + dev->led_pin = led_pin; + dev->led_al = of_property_read_bool(np, "led-active-low"); + } + + return devm_led_classdev_register(dev->dev, &dev->led_cdev); +} + +static int +mt76_init_sband(struct mt76_dev *dev, struct mt76_sband *msband, + const struct ieee80211_channel *chan, int n_chan, + struct ieee80211_rate *rates, int n_rates, bool vht) +{ + struct ieee80211_supported_band *sband = &msband->sband; + struct ieee80211_sta_ht_cap *ht_cap; + struct ieee80211_sta_vht_cap *vht_cap; + void *chanlist; + u16 mcs_map; + int size; + + size = n_chan * sizeof(*chan); + chanlist = devm_kmemdup(dev->dev, chan, size, GFP_KERNEL); + if (!chanlist) + return -ENOMEM; + + msband->chan = devm_kzalloc(dev->dev, n_chan * sizeof(*msband->chan), + GFP_KERNEL); + if (!msband->chan) + return -ENOMEM; + + sband->channels = chanlist; + sband->n_channels = n_chan; + sband->bitrates = rates; + sband->n_bitrates = n_rates; + dev->chandef.chan = &sband->channels[0]; + + ht_cap = &sband->ht_cap; + ht_cap->ht_supported = true; + ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_TX_STBC | + (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); + + ht_cap->mcs.rx_mask[0] = 0xff; + ht_cap->mcs.rx_mask[1] = 0xff; + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; + + if (!vht) + return 0; + + vht_cap = &sband->vht_cap; + vht_cap->vht_supported = true; + + mcs_map = (IEEE80211_VHT_MCS_SUPPORT_0_9 << (0 * 2)) | + (IEEE80211_VHT_MCS_SUPPORT_0_9 << (1 * 2)) | + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (2 * 2)) | + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (3 * 2)) | + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (4 * 2)) | + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (5 * 2)) | + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (6 * 2)) | + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (7 * 2)); + + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC | + IEEE80211_VHT_CAP_TXSTBC | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_SHORT_GI_80; + + return 0; +} + +static int +mt76_init_sband_2g(struct mt76_dev *dev, struct ieee80211_rate *rates, + int n_rates) +{ + dev->hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->sband_2g.sband; + + return mt76_init_sband(dev, &dev->sband_2g, + mt76_channels_2ghz, + ARRAY_SIZE(mt76_channels_2ghz), + rates, n_rates, false); +} + +static int +mt76_init_sband_5g(struct mt76_dev *dev, struct ieee80211_rate *rates, + int n_rates, bool vht) +{ + dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = &dev->sband_5g.sband; + + return mt76_init_sband(dev, &dev->sband_5g, + mt76_channels_5ghz, + ARRAY_SIZE(mt76_channels_5ghz), + rates, n_rates, vht); +} + +static void +mt76_check_sband(struct mt76_dev *dev, int band) +{ + struct ieee80211_supported_band *sband = dev->hw->wiphy->bands[band]; + bool found = false; + int i; + + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & IEEE80211_CHAN_DISABLED) + continue; + + found = true; + break; + } + + if (found) + return; + + sband->n_channels = 0; + dev->hw->wiphy->bands[band] = NULL; +} + +int mt76_register_device(struct mt76_dev *dev, bool vht, + struct ieee80211_rate *rates, int n_rates) +{ + struct ieee80211_hw *hw = dev->hw; + struct wiphy *wiphy = hw->wiphy; + int ret; + + dev_set_drvdata(dev->dev, dev); + + spin_lock_init(&dev->lock); + spin_lock_init(&dev->cc_lock); + INIT_LIST_HEAD(&dev->txwi_cache); + + SET_IEEE80211_DEV(hw, dev->dev); + SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); + + wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | +#ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | +#endif + BIT(NL80211_IFTYPE_ADHOC); + + wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; + + hw->txq_data_size = sizeof(struct mt76_txq); + hw->max_tx_fragments = 16; + + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, PS_NULLFUNC_STACK); + ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, SUPPORTS_RC_TABLE); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(hw, TX_AMSDU); + ieee80211_hw_set(hw, TX_FRAG_LIST); + ieee80211_hw_set(hw, MFP_CAPABLE); + + wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + + if (dev->cap.has_2ghz) { + ret = mt76_init_sband_2g(dev, rates, n_rates); + if (ret) + return ret; + } + + if (dev->cap.has_5ghz) { + ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht); + if (ret) + return ret; + } + + wiphy_read_of_freq_limits(dev->hw->wiphy); + mt76_check_sband(dev, NL80211_BAND_2GHZ); + mt76_check_sband(dev, NL80211_BAND_5GHZ); + + ret = mt76_led_init(dev); + if (ret) + return ret; + + return ieee80211_register_hw(hw); +} +EXPORT_SYMBOL_GPL(mt76_register_device); + +void mt76_unregister_device(struct mt76_dev *dev) +{ + struct ieee80211_hw *hw = dev->hw; + + ieee80211_unregister_hw(hw); + mt76_tx_free(dev); +} +EXPORT_SYMBOL_GPL(mt76_unregister_device); + +void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) +{ + if (!test_bit(MT76_STATE_RUNNING, &dev->state)) { + dev_kfree_skb(skb); + return; + } + + __skb_queue_tail(&dev->rx_skb[q], skb); +} +EXPORT_SYMBOL_GPL(mt76_rx); + +void mt76_set_channel(struct mt76_dev *dev) +{ + struct ieee80211_hw *hw = dev->hw; + struct cfg80211_chan_def *chandef = &hw->conf.chandef; + struct mt76_channel_state *state; + bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL; + + if (dev->drv->update_survey) + dev->drv->update_survey(dev); + + dev->chandef = *chandef; + + if (!offchannel) + dev->main_chan = chandef->chan; + + if (chandef->chan != dev->main_chan) { + state = mt76_channel_state(dev, chandef->chan); + memset(state, 0, sizeof(*state)); + } +} +EXPORT_SYMBOL_GPL(mt76_set_channel); + +int mt76_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct mt76_dev *dev = hw->priv; + struct mt76_sband *sband; + struct ieee80211_channel *chan; + struct mt76_channel_state *state; + int ret = 0; + + if (idx == 0 && dev->drv->update_survey) + dev->drv->update_survey(dev); + + sband = &dev->sband_2g; + if (idx >= sband->sband.n_channels) { + idx -= sband->sband.n_channels; + sband = &dev->sband_5g; + } + + if (idx >= sband->sband.n_channels) + return -ENOENT; + + chan = &sband->sband.channels[idx]; + state = mt76_channel_state(dev, chan); + + memset(survey, 0, sizeof(*survey)); + survey->channel = chan; + survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY; + if (chan == dev->main_chan) + survey->filled |= SURVEY_INFO_IN_USE; + + spin_lock_bh(&dev->cc_lock); + survey->time = div_u64(state->cc_active, 1000); + survey->time_busy = div_u64(state->cc_busy, 1000); + spin_unlock_bh(&dev->cc_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(mt76_get_survey); + +void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) + ieee80211_rx_napi(dev->hw, NULL, skb, &dev->napi[q]); +} diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c new file mode 100644 index 000000000000..09a14dead6e3 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mmio.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76.h" +#include "trace.h" + +static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset) +{ + u32 val; + + val = ioread32(dev->regs + offset); + trace_reg_rr(dev, offset, val); + + return val; +} + +static void mt76_mmio_wr(struct mt76_dev *dev, u32 offset, u32 val) +{ + trace_reg_wr(dev, offset, val); + iowrite32(val, dev->regs + offset); +} + +static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val) +{ + val |= mt76_mmio_rr(dev, offset) & ~mask; + mt76_mmio_wr(dev, offset, val); + return val; +} + +static void mt76_mmio_copy(struct mt76_dev *dev, u32 offset, const void *data, + int len) +{ + __iowrite32_copy(dev->regs + offset, data, len >> 2); +} + +void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs) +{ + static const struct mt76_bus_ops mt76_mmio_ops = { + .rr = mt76_mmio_rr, + .rmw = mt76_mmio_rmw, + .wr = mt76_mmio_wr, + .copy = mt76_mmio_copy, + }; + + dev->bus = &mt76_mmio_ops; + dev->regs = regs; +} +EXPORT_SYMBOL_GPL(mt76_mmio_init); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h new file mode 100644 index 000000000000..aa0880bbea7f --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76_H +#define __MT76_H + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/spinlock.h> +#include <linux/skbuff.h> +#include <linux/leds.h> +#include <net/mac80211.h> +#include "util.h" + +#define MT_TX_RING_SIZE 256 +#define MT_MCU_RING_SIZE 32 +#define MT_RX_BUF_SIZE 2048 + +struct mt76_dev; + +struct mt76_bus_ops { + u32 (*rr)(struct mt76_dev *dev, u32 offset); + void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); + u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); + void (*copy)(struct mt76_dev *dev, u32 offset, const void *data, + int len); +}; + +enum mt76_txq_id { + MT_TXQ_VO = IEEE80211_AC_VO, + MT_TXQ_VI = IEEE80211_AC_VI, + MT_TXQ_BE = IEEE80211_AC_BE, + MT_TXQ_BK = IEEE80211_AC_BK, + MT_TXQ_PSD, + MT_TXQ_MCU, + MT_TXQ_BEACON, + MT_TXQ_CAB, + __MT_TXQ_MAX +}; + +enum mt76_rxq_id { + MT_RXQ_MAIN, + MT_RXQ_MCU, + __MT_RXQ_MAX +}; + +struct mt76_queue_buf { + dma_addr_t addr; + int len; +}; + +struct mt76_queue_entry { + union { + void *buf; + struct sk_buff *skb; + }; + struct mt76_txwi_cache *txwi; + bool schedule; +}; + +struct mt76_queue_regs { + u32 desc_base; + u32 ring_size; + u32 cpu_idx; + u32 dma_idx; +} __packed __aligned(4); + +struct mt76_queue { + struct mt76_queue_regs __iomem *regs; + + spinlock_t lock; + struct mt76_queue_entry *entry; + struct mt76_desc *desc; + + struct list_head swq; + int swq_queued; + + u16 head; + u16 tail; + int ndesc; + int queued; + int buf_size; + + u8 buf_offset; + u8 hw_idx; + + dma_addr_t desc_dma; + struct sk_buff *rx_head; +}; + +struct mt76_queue_ops { + int (*init)(struct mt76_dev *dev); + + int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q); + + int (*add_buf)(struct mt76_dev *dev, struct mt76_queue *q, + struct mt76_queue_buf *buf, int nbufs, u32 info, + struct sk_buff *skb, void *txwi); + + void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush, + int *len, u32 *info, bool *more); + + void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid); + + void (*tx_cleanup)(struct mt76_dev *dev, enum mt76_txq_id qid, + bool flush); + + void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); +}; + +struct mt76_wcid { + u8 idx; + u8 hw_key_idx; + + __le16 tx_rate; + bool tx_rate_set; + u8 tx_rate_nss; + s8 max_txpwr_adj; +}; + +struct mt76_txq { + struct list_head list; + struct mt76_queue *hwq; + struct mt76_wcid *wcid; + + struct sk_buff_head retry_q; + + u16 agg_ssn; + bool send_bar; + bool aggr; +}; + +struct mt76_txwi_cache { + u32 txwi[8]; + dma_addr_t dma_addr; + struct list_head list; +}; + +enum { + MT76_STATE_INITIALIZED, + MT76_STATE_RUNNING, + MT76_SCANNING, + MT76_RESET, +}; + +struct mt76_hw_cap { + bool has_2ghz; + bool has_5ghz; +}; + +struct mt76_driver_ops { + u16 txwi_size; + + void (*update_survey)(struct mt76_dev *dev); + + int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, + struct sk_buff *skb, struct mt76_queue *q, + struct mt76_wcid *wcid, + struct ieee80211_sta *sta, u32 *tx_info); + + void (*tx_complete_skb)(struct mt76_dev *dev, struct mt76_queue *q, + struct mt76_queue_entry *e, bool flush); + + void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, + struct sk_buff *skb); + + void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); +}; + +struct mt76_channel_state { + u64 cc_active; + u64 cc_busy; +}; + +struct mt76_sband { + struct ieee80211_supported_band sband; + struct mt76_channel_state *chan; +}; + +struct mt76_dev { + struct ieee80211_hw *hw; + struct cfg80211_chan_def chandef; + struct ieee80211_channel *main_chan; + + spinlock_t lock; + spinlock_t cc_lock; + const struct mt76_bus_ops *bus; + const struct mt76_driver_ops *drv; + void __iomem *regs; + struct device *dev; + + struct net_device napi_dev; + struct napi_struct napi[__MT_RXQ_MAX]; + struct sk_buff_head rx_skb[__MT_RXQ_MAX]; + + struct list_head txwi_cache; + struct mt76_queue q_tx[__MT_TXQ_MAX]; + struct mt76_queue q_rx[__MT_RXQ_MAX]; + const struct mt76_queue_ops *queue_ops; + + u8 macaddr[ETH_ALEN]; + u32 rev; + unsigned long state; + + struct mt76_sband sband_2g; + struct mt76_sband sband_5g; + struct debugfs_blob_wrapper eeprom; + struct debugfs_blob_wrapper otp; + struct mt76_hw_cap cap; + + u32 debugfs_reg; + + struct led_classdev led_cdev; + char led_name[32]; + bool led_al; + u8 led_pin; +}; + +enum mt76_phy_type { + MT_PHY_TYPE_CCK, + MT_PHY_TYPE_OFDM, + MT_PHY_TYPE_HT, + MT_PHY_TYPE_HT_GF, + MT_PHY_TYPE_VHT, +}; + +struct mt76_rate_power { + union { + struct { + s8 cck[4]; + s8 ofdm[8]; + s8 ht[16]; + s8 vht[10]; + }; + s8 all[38]; + }; +}; + +#define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) +#define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) +#define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) +#define mt76_wr_copy(dev, ...) (dev)->mt76.bus->copy(&((dev)->mt76), __VA_ARGS__) + +#define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) +#define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) + +#define mt76_get_field(_dev, _reg, _field) \ + FIELD_GET(_field, mt76_rr(dev, _reg)) + +#define mt76_rmw_field(_dev, _reg, _field, _val) \ + mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) + +#define mt76_hw(dev) (dev)->mt76.hw + +bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, + int timeout); + +#define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) + +bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, + int timeout); + +#define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) + +void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); + +static inline u16 mt76_chip(struct mt76_dev *dev) +{ + return dev->rev >> 16; +} + +static inline u16 mt76_rev(struct mt76_dev *dev) +{ + return dev->rev & 0xffff; +} + +#define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) +#define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) + +#define mt76_init_queues(dev) (dev)->mt76.queue_ops->init(&((dev)->mt76)) +#define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_add_buf(dev, ...) (dev)->mt76.queue_ops->add_buf(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) + +static inline struct mt76_channel_state * +mt76_channel_state(struct mt76_dev *dev, struct ieee80211_channel *c) +{ + struct mt76_sband *msband; + int idx; + + if (c->band == NL80211_BAND_2GHZ) + msband = &dev->sband_2g; + else + msband = &dev->sband_5g; + + idx = c - &msband->sband.channels[0]; + return &msband->chan[idx]; +} + +int mt76_register_device(struct mt76_dev *dev, bool vht, + struct ieee80211_rate *rates, int n_rates); +void mt76_unregister_device(struct mt76_dev *dev); + +struct dentry *mt76_register_debugfs(struct mt76_dev *dev); + +int mt76_eeprom_init(struct mt76_dev *dev, int len); +void mt76_eeprom_override(struct mt76_dev *dev); + +static inline struct ieee80211_txq * +mtxq_to_txq(struct mt76_txq *mtxq) +{ + void *ptr = mtxq; + + return container_of(ptr, struct ieee80211_txq, drv_priv); +} + +int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_sta *sta); + +void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); +void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta, + struct mt76_wcid *wcid, struct sk_buff *skb); +void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq); +void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq); +void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); +void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta, + bool send_bar); +void mt76_txq_schedule(struct mt76_dev *dev, struct mt76_queue *hwq); +void mt76_txq_schedule_all(struct mt76_dev *dev); +void mt76_release_buffered_frames(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u16 tids, int nframes, + enum ieee80211_frame_release_type reason, + bool more_data); +void mt76_set_channel(struct mt76_dev *dev); +int mt76_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey); + +/* internal */ +void mt76_tx_free(struct mt76_dev *dev); +void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); +void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h new file mode 100644 index 000000000000..a12dfce8c0d1 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_H +#define __MT76x2_H + +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/spinlock.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/mutex.h> +#include <linux/bitops.h> +#include <linux/kfifo.h> + +#define MT7662_FIRMWARE "mt7662.bin" +#define MT7662_ROM_PATCH "mt7662_rom_patch.bin" +#define MT7662_EEPROM_SIZE 512 + +#define MT76x2_RX_RING_SIZE 256 +#define MT_RX_HEADROOM 32 + +#define MT_MAX_CHAINS 2 + +#define MT_CALIBRATE_INTERVAL HZ + +#include "mt76.h" +#include "mt76x2_regs.h" +#include "mt76x2_mac.h" +#include "mt76x2_dfs.h" + +struct mt76x2_mcu { + struct mutex mutex; + + wait_queue_head_t wait; + struct sk_buff_head res_q; + + u32 msg_seq; +}; + +struct mt76x2_rx_freq_cal { + s8 high_gain[MT_MAX_CHAINS]; + s8 rssi_offset[MT_MAX_CHAINS]; + s8 lna_gain; + u32 mcu_gain; +}; + +struct mt76x2_calibration { + struct mt76x2_rx_freq_cal rx; + + u8 agc_gain_init[MT_MAX_CHAINS]; + u8 agc_gain_cur[MT_MAX_CHAINS]; + + int avg_rssi[MT_MAX_CHAINS]; + int avg_rssi_all; + + s8 agc_gain_adjust; + s8 low_gain; + + u8 temp; + + bool init_cal_done; + bool tssi_cal_done; + bool tssi_comp_pending; + bool dpd_cal_done; + bool channel_cal_done; +}; + +struct mt76x2_dev { + struct mt76_dev mt76; /* must be first */ + + struct mac_address macaddr_list[8]; + + struct mutex mutex; + + const u16 *beacon_offsets; + unsigned long wcid_mask[128 / BITS_PER_LONG]; + + int txpower_conf; + int txpower_cur; + + u8 txdone_seq; + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x2_tx_status); + + struct mt76x2_mcu mcu; + struct sk_buff *rx_head; + + struct tasklet_struct tx_tasklet; + struct tasklet_struct pre_tbtt_tasklet; + struct delayed_work cal_work; + struct delayed_work mac_work; + + u32 aggr_stats[32]; + + struct mt76_wcid global_wcid; + struct mt76_wcid __rcu *wcid[128]; + + spinlock_t irq_lock; + u32 irqmask; + + struct sk_buff *beacons[8]; + u8 beacon_mask; + u8 beacon_data_mask; + + u32 rev; + u32 rxfilter; + + u16 chainmask; + + struct mt76x2_calibration cal; + + s8 target_power; + s8 target_power_delta[2]; + struct mt76_rate_power rate_power; + bool enable_tpc; + + u8 coverage_class; + u8 slottime; + + struct mt76x2_dfs_pattern_detector dfs_pd; +}; + +struct mt76x2_vif { + u8 idx; + + struct mt76_wcid group_wcid; +}; + +struct mt76x2_sta { + struct mt76_wcid wcid; /* must be first */ + + struct mt76x2_tx_status status; + int n_frames; +}; + +static inline bool is_mt7612(struct mt76x2_dev *dev) +{ + return (dev->rev >> 16) == 0x7612; +} + +void mt76x2_set_irq_mask(struct mt76x2_dev *dev, u32 clear, u32 set); + +static inline void mt76x2_irq_enable(struct mt76x2_dev *dev, u32 mask) +{ + mt76x2_set_irq_mask(dev, 0, mask); +} + +static inline void mt76x2_irq_disable(struct mt76x2_dev *dev, u32 mask) +{ + mt76x2_set_irq_mask(dev, mask, 0); +} + +extern const struct ieee80211_ops mt76x2_ops; + +struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev); +int mt76x2_register_device(struct mt76x2_dev *dev); +void mt76x2_init_debugfs(struct mt76x2_dev *dev); + +irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance); +void mt76x2_phy_power_on(struct mt76x2_dev *dev); +int mt76x2_init_hardware(struct mt76x2_dev *dev); +void mt76x2_stop_hardware(struct mt76x2_dev *dev); +int mt76x2_eeprom_init(struct mt76x2_dev *dev); +int mt76x2_apply_calibration_data(struct mt76x2_dev *dev, int channel); +void mt76x2_set_tx_ackto(struct mt76x2_dev *dev); + +int mt76x2_phy_start(struct mt76x2_dev *dev); +int mt76x2_phy_set_channel(struct mt76x2_dev *dev, + struct cfg80211_chan_def *chandef); +int mt76x2_phy_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain); +void mt76x2_phy_calibrate(struct work_struct *work); +void mt76x2_phy_set_txpower(struct mt76x2_dev *dev); + +int mt76x2_mcu_init(struct mt76x2_dev *dev); +int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, + u8 bw_index, bool scan); +int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on); +int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, + u8 channel); +int mt76x2_mcu_cleanup(struct mt76x2_dev *dev); + +int mt76x2_dma_init(struct mt76x2_dev *dev); +void mt76x2_dma_cleanup(struct mt76x2_dev *dev); + +void mt76x2_cleanup(struct mt76x2_dev *dev); + +int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, + struct sk_buff *skb, int cmd, int seq); +void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, + struct sk_buff *skb); +void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb); +int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, + struct sk_buff *skb, struct mt76_queue *q, + struct mt76_wcid *wcid, struct ieee80211_sta *sta, + u32 *tx_info); +void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, + struct mt76_queue_entry *e, bool flush); + +void mt76x2_pre_tbtt_tasklet(unsigned long arg); + +void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); +void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, + struct sk_buff *skb); + +void mt76x2_update_channel(struct mt76_dev *mdev); + +s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev, + const struct ieee80211_tx_rate *rate); +s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj); +void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2_core.c new file mode 100644 index 000000000000..2629779e8d3e --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_core.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/delay.h> +#include "mt76x2.h" +#include "mt76x2_trace.h" + +void mt76x2_set_irq_mask(struct mt76x2_dev *dev, u32 clear, u32 set) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->irq_lock, flags); + dev->irqmask &= ~clear; + dev->irqmask |= set; + mt76_wr(dev, MT_INT_MASK_CSR, dev->irqmask); + spin_unlock_irqrestore(&dev->irq_lock, flags); +} + +void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) +{ + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + + mt76x2_irq_enable(dev, MT_INT_RX_DONE(q)); +} + +irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance) +{ + struct mt76x2_dev *dev = dev_instance; + u32 intr; + + intr = mt76_rr(dev, MT_INT_SOURCE_CSR); + mt76_wr(dev, MT_INT_SOURCE_CSR, intr); + + if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state)) + return IRQ_NONE; + + trace_dev_irq(dev, intr, dev->irqmask); + + intr &= dev->irqmask; + + if (intr & MT_INT_TX_DONE_ALL) { + mt76x2_irq_disable(dev, MT_INT_TX_DONE_ALL); + tasklet_schedule(&dev->tx_tasklet); + } + + if (intr & MT_INT_RX_DONE(0)) { + mt76x2_irq_disable(dev, MT_INT_RX_DONE(0)); + napi_schedule(&dev->mt76.napi[0]); + } + + if (intr & MT_INT_RX_DONE(1)) { + mt76x2_irq_disable(dev, MT_INT_RX_DONE(1)); + napi_schedule(&dev->mt76.napi[1]); + } + + if (intr & MT_INT_PRE_TBTT) + tasklet_schedule(&dev->pre_tbtt_tasklet); + + /* send buffered multicast frames now */ + if (intr & MT_INT_TBTT) + mt76_queue_kick(dev, &dev->mt76.q_tx[MT_TXQ_PSD]); + + if (intr & MT_INT_TX_STAT) { + mt76x2_mac_poll_tx_status(dev, true); + tasklet_schedule(&dev->tx_tasklet); + } + + if (intr & MT_INT_GPTIMER) { + mt76x2_irq_disable(dev, MT_INT_GPTIMER); + tasklet_schedule(&dev->dfs_pd.dfs_tasklet); + } + + return IRQ_HANDLED; +} + diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c new file mode 100644 index 000000000000..612feb593d7d --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/debugfs.h> +#include "mt76x2.h" + +static int +mt76x2_ampdu_stat_read(struct seq_file *file, void *data) +{ + struct mt76x2_dev *dev = file->private; + int i, j; + + for (i = 0; i < 4; i++) { + seq_puts(file, "Length: "); + for (j = 0; j < 8; j++) + seq_printf(file, "%8d | ", i * 8 + j + 1); + seq_puts(file, "\n"); + seq_puts(file, "Count: "); + for (j = 0; j < 8; j++) + seq_printf(file, "%8d | ", dev->aggr_stats[i * 8 + j]); + seq_puts(file, "\n"); + seq_puts(file, "--------"); + for (j = 0; j < 8; j++) + seq_puts(file, "-----------"); + seq_puts(file, "\n"); + } + + return 0; +} + +static int +mt76x2_ampdu_stat_open(struct inode *inode, struct file *f) +{ + return single_open(f, mt76x2_ampdu_stat_read, inode->i_private); +} + +static void +seq_puts_array(struct seq_file *file, const char *str, s8 *val, int len) +{ + int i; + + seq_printf(file, "%10s:", str); + for (i = 0; i < len; i++) + seq_printf(file, " %2d", val[i]); + seq_puts(file, "\n"); +} + +static int read_txpower(struct seq_file *file, void *data) +{ + struct mt76x2_dev *dev = dev_get_drvdata(file->private); + + seq_printf(file, "Target power: %d\n", dev->target_power); + + seq_puts_array(file, "Delta", dev->target_power_delta, + ARRAY_SIZE(dev->target_power_delta)); + seq_puts_array(file, "CCK", dev->rate_power.cck, + ARRAY_SIZE(dev->rate_power.cck)); + seq_puts_array(file, "OFDM", dev->rate_power.ofdm, + ARRAY_SIZE(dev->rate_power.ofdm)); + seq_puts_array(file, "HT", dev->rate_power.ht, + ARRAY_SIZE(dev->rate_power.ht)); + seq_puts_array(file, "VHT", dev->rate_power.vht, + ARRAY_SIZE(dev->rate_power.vht)); + return 0; +} + +static const struct file_operations fops_ampdu_stat = { + .open = mt76x2_ampdu_stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int +mt76x2_dfs_stat_read(struct seq_file *file, void *data) +{ + int i; + struct mt76x2_dev *dev = file->private; + struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd; + + for (i = 0; i < MT_DFS_NUM_ENGINES; i++) { + seq_printf(file, "engine: %d\n", i); + seq_printf(file, " hw pattern detected:\t%d\n", + dfs_pd->stats[i].hw_pattern); + seq_printf(file, " hw pulse discarded:\t%d\n", + dfs_pd->stats[i].hw_pulse_discarded); + } + + return 0; +} + +static int +mt76x2_dfs_stat_open(struct inode *inode, struct file *f) +{ + return single_open(f, mt76x2_dfs_stat_read, inode->i_private); +} + +static const struct file_operations fops_dfs_stat = { + .open = mt76x2_dfs_stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void mt76x2_init_debugfs(struct mt76x2_dev *dev) +{ + struct dentry *dir; + + dir = mt76_register_debugfs(&dev->mt76); + if (!dir) + return; + + debugfs_create_u8("temperature", S_IRUSR, dir, &dev->cal.temp); + debugfs_create_bool("tpc", S_IRUSR | S_IWUSR, dir, &dev->enable_tpc); + + debugfs_create_file("ampdu_stat", S_IRUSR, dir, dev, &fops_ampdu_stat); + debugfs_create_file("dfs_stats", S_IRUSR, dir, dev, &fops_dfs_stat); + debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir, + read_txpower); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.c new file mode 100644 index 000000000000..5b452a596016 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.c @@ -0,0 +1,493 @@ +/* + * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76x2.h" + +#define RADAR_SPEC(m, len, el, eh, wl, wh, \ + w_tolerance, tl, th, t_tolerance, \ + bl, bh, event_exp, power_jmp) \ +{ \ + .mode = m, \ + .avg_len = len, \ + .e_low = el, \ + .e_high = eh, \ + .w_low = wl, \ + .w_high = wh, \ + .w_margin = w_tolerance, \ + .t_low = tl, \ + .t_high = th, \ + .t_margin = t_tolerance, \ + .b_low = bl, \ + .b_high = bh, \ + .event_expiration = event_exp, \ + .pwr_jmp = power_jmp \ +} + +static const struct mt76x2_radar_specs etsi_radar_specs[] = { + /* 20MHz */ + RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0, + 0x7fffffff, 0x155cc0, 0x19cc), + RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0, + 0x7fffffff, 0x155cc0, 0x19cc), + RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0, + 0x7fffffff, 0x155cc0, 0x19dd), + RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0, + 0x7fffffff, 0x2191c0, 0x15cc), + /* 40MHz */ + RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0, + 0x7fffffff, 0x155cc0, 0x19cc), + RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0, + 0x7fffffff, 0x155cc0, 0x19cc), + RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0, + 0x7fffffff, 0x155cc0, 0x19dd), + RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0, + 0x7fffffff, 0x2191c0, 0x15cc), + /* 80MHz */ + RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0, + 0x7fffffff, 0x155cc0, 0x19cc), + RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0, + 0x7fffffff, 0x155cc0, 0x19cc), + RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0, + 0x7fffffff, 0x155cc0, 0x19dd), + RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0, + 0x7fffffff, 0x2191c0, 0x15cc) +}; + +static const struct mt76x2_radar_specs fcc_radar_specs[] = { + /* 20MHz */ + RADAR_SPEC(0, 8, 2, 12, 106, 150, 5, 2900, 80100, 5, 0, + 0x7fffffff, 0xfe808, 0x13dc), + RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0, + 0x7fffffff, 0xfe808, 0x19dd), + RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0, + 0x7fffffff, 0xfe808, 0x12cc), + RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0, + 0x3938700, 0x57bcf00, 0x1289), + /* 40MHz */ + RADAR_SPEC(0, 8, 2, 12, 106, 150, 5, 2900, 80100, 5, 0, + 0x7fffffff, 0xfe808, 0x13dc), + RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0, + 0x7fffffff, 0xfe808, 0x19dd), + RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0, + 0x7fffffff, 0xfe808, 0x12cc), + RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0, + 0x3938700, 0x57bcf00, 0x1289), + /* 80MHz */ + RADAR_SPEC(0, 8, 2, 14, 106, 150, 15, 2900, 80100, 15, 0, + 0x7fffffff, 0xfe808, 0x16cc), + RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0, + 0x7fffffff, 0xfe808, 0x19dd), + RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0, + 0x7fffffff, 0xfe808, 0x12cc), + RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0, + 0x3938700, 0x57bcf00, 0x1289) +}; + +static const struct mt76x2_radar_specs jp_w56_radar_specs[] = { + /* 20MHz */ + RADAR_SPEC(0, 8, 2, 7, 106, 150, 5, 2900, 80100, 5, 0, + 0x7fffffff, 0x14c080, 0x13dc), + RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0, + 0x7fffffff, 0x14c080, 0x19dd), + RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0, + 0x7fffffff, 0x14c080, 0x12cc), + RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0, + 0x3938700, 0X57bcf00, 0x1289), + /* 40MHz */ + RADAR_SPEC(0, 8, 2, 7, 106, 150, 5, 2900, 80100, 5, 0, + 0x7fffffff, 0x14c080, 0x13dc), + RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0, + 0x7fffffff, 0x14c080, 0x19dd), + RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0, + 0x7fffffff, 0x14c080, 0x12cc), + RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0, + 0x3938700, 0X57bcf00, 0x1289), + /* 80MHz */ + RADAR_SPEC(0, 8, 2, 9, 106, 150, 15, 2900, 80100, 15, 0, + 0x7fffffff, 0x14c080, 0x16cc), + RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0, + 0x7fffffff, 0x14c080, 0x19dd), + RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0, + 0x7fffffff, 0x14c080, 0x12cc), + RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0, + 0x3938700, 0X57bcf00, 0x1289) +}; + +static const struct mt76x2_radar_specs jp_w53_radar_specs[] = { + /* 20MHz */ + RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0, + 0x7fffffff, 0x14c080, 0x16cc), + { 0 }, + RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0, + 0x7fffffff, 0x14c080, 0x16cc), + { 0 }, + /* 40MHz */ + RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0, + 0x7fffffff, 0x14c080, 0x16cc), + { 0 }, + RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0, + 0x7fffffff, 0x14c080, 0x16cc), + { 0 }, + /* 80MHz */ + RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0, + 0x7fffffff, 0x14c080, 0x16cc), + { 0 }, + RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0, + 0x7fffffff, 0x14c080, 0x16cc), + { 0 } +}; + +static void mt76x2_dfs_set_capture_mode_ctrl(struct mt76x2_dev *dev, + u8 enable) +{ + u32 data; + + data = (1 << 1) | enable; + mt76_wr(dev, MT_BBP(DFS, 36), data); +} + +static bool mt76x2_dfs_check_chirp(struct mt76x2_dev *dev) +{ + bool ret = false; + u32 current_ts, delta_ts; + struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd; + + current_ts = mt76_rr(dev, MT_PBF_LIFE_TIMER); + delta_ts = current_ts - dfs_pd->chirp_pulse_ts; + dfs_pd->chirp_pulse_ts = current_ts; + + /* 12 sec */ + if (delta_ts <= (12 * (1 << 20))) { + if (++dfs_pd->chirp_pulse_cnt > 8) + ret = true; + } else { + dfs_pd->chirp_pulse_cnt = 1; + } + + return ret; +} + +static void mt76x2_dfs_get_hw_pulse(struct mt76x2_dev *dev, + struct mt76x2_dfs_hw_pulse *pulse) +{ + u32 data; + + /* select channel */ + data = (MT_DFS_CH_EN << 16) | pulse->engine; + mt76_wr(dev, MT_BBP(DFS, 0), data); + + /* reported period */ + pulse->period = mt76_rr(dev, MT_BBP(DFS, 19)); + + /* reported width */ + pulse->w1 = mt76_rr(dev, MT_BBP(DFS, 20)); + pulse->w2 = mt76_rr(dev, MT_BBP(DFS, 23)); + + /* reported burst number */ + pulse->burst = mt76_rr(dev, MT_BBP(DFS, 22)); +} + +static bool mt76x2_dfs_check_hw_pulse(struct mt76x2_dev *dev, + struct mt76x2_dfs_hw_pulse *pulse) +{ + bool ret = false; + + if (!pulse->period || !pulse->w1) + return false; + + switch (dev->dfs_pd.region) { + case NL80211_DFS_FCC: + if (pulse->engine > 3) + break; + + if (pulse->engine == 3) { + ret = mt76x2_dfs_check_chirp(dev); + break; + } + + /* check short pulse*/ + if (pulse->w1 < 120) + ret = (pulse->period >= 2900 && + (pulse->period <= 4700 || + pulse->period >= 6400) && + (pulse->period <= 6800 || + pulse->period >= 10200) && + pulse->period <= 61600); + else if (pulse->w1 < 130) /* 120 - 130 */ + ret = (pulse->period >= 2900 && + pulse->period <= 61600); + else + ret = (pulse->period >= 3500 && + pulse->period <= 10100); + break; + case NL80211_DFS_ETSI: + if (pulse->engine >= 3) + break; + + ret = (pulse->period >= 4900 && + (pulse->period <= 10200 || + pulse->period >= 12400) && + pulse->period <= 100100); + break; + case NL80211_DFS_JP: + if (dev->mt76.chandef.chan->center_freq >= 5250 && + dev->mt76.chandef.chan->center_freq <= 5350) { + /* JPW53 */ + if (pulse->w1 <= 130) + ret = (pulse->period >= 28360 && + (pulse->period <= 28700 || + pulse->period >= 76900) && + pulse->period <= 76940); + break; + } + + if (pulse->engine > 3) + break; + + if (pulse->engine == 3) { + ret = mt76x2_dfs_check_chirp(dev); + break; + } + + /* check short pulse*/ + if (pulse->w1 < 120) + ret = (pulse->period >= 2900 && + (pulse->period <= 4700 || + pulse->period >= 6400) && + (pulse->period <= 6800 || + pulse->period >= 27560) && + (pulse->period <= 27960 || + pulse->period >= 28360) && + (pulse->period <= 28700 || + pulse->period >= 79900) && + pulse->period <= 80100); + else if (pulse->w1 < 130) /* 120 - 130 */ + ret = (pulse->period >= 2900 && + (pulse->period <= 10100 || + pulse->period >= 27560) && + (pulse->period <= 27960 || + pulse->period >= 28360) && + (pulse->period <= 28700 || + pulse->period >= 79900) && + pulse->period <= 80100); + else + ret = (pulse->period >= 3900 && + pulse->period <= 10100); + break; + case NL80211_DFS_UNSET: + default: + return false; + } + + return ret; +} + +static void mt76x2_dfs_tasklet(unsigned long arg) +{ + struct mt76x2_dev *dev = (struct mt76x2_dev *)arg; + struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd; + u32 engine_mask; + int i; + + if (test_bit(MT76_SCANNING, &dev->mt76.state)) + goto out; + + engine_mask = mt76_rr(dev, MT_BBP(DFS, 1)); + if (!(engine_mask & 0xf)) + goto out; + + for (i = 0; i < MT_DFS_NUM_ENGINES; i++) { + struct mt76x2_dfs_hw_pulse pulse; + + if (!(engine_mask & (1 << i))) + continue; + + pulse.engine = i; + mt76x2_dfs_get_hw_pulse(dev, &pulse); + + if (!mt76x2_dfs_check_hw_pulse(dev, &pulse)) { + dfs_pd->stats[i].hw_pulse_discarded++; + continue; + } + + /* hw detector rx radar pattern */ + dfs_pd->stats[i].hw_pattern++; + ieee80211_radar_detected(dev->mt76.hw); + + /* reset hw detector */ + mt76_wr(dev, MT_BBP(DFS, 1), 0xf); + + return; + } + + /* reset hw detector */ + mt76_wr(dev, MT_BBP(DFS, 1), 0xf); + +out: + mt76x2_irq_enable(dev, MT_INT_GPTIMER); +} + +static void mt76x2_dfs_set_bbp_params(struct mt76x2_dev *dev) +{ + u32 data; + u8 i, shift; + const struct mt76x2_radar_specs *radar_specs; + + switch (dev->mt76.chandef.width) { + case NL80211_CHAN_WIDTH_40: + shift = MT_DFS_NUM_ENGINES; + break; + case NL80211_CHAN_WIDTH_80: + shift = 2 * MT_DFS_NUM_ENGINES; + break; + default: + shift = 0; + break; + } + + switch (dev->dfs_pd.region) { + case NL80211_DFS_FCC: + radar_specs = &fcc_radar_specs[shift]; + break; + case NL80211_DFS_ETSI: + radar_specs = &etsi_radar_specs[shift]; + break; + case NL80211_DFS_JP: + if (dev->mt76.chandef.chan->center_freq >= 5250 && + dev->mt76.chandef.chan->center_freq <= 5350) + radar_specs = &jp_w53_radar_specs[shift]; + else + radar_specs = &jp_w56_radar_specs[shift]; + break; + case NL80211_DFS_UNSET: + default: + return; + } + + data = (MT_DFS_VGA_MASK << 16) | + (MT_DFS_PWR_GAIN_OFFSET << 12) | + (MT_DFS_PWR_DOWN_TIME << 8) | + (MT_DFS_SYM_ROUND << 4) | + (MT_DFS_DELTA_DELAY & 0xf); + mt76_wr(dev, MT_BBP(DFS, 2), data); + + data = (MT_DFS_RX_PE_MASK << 16) | MT_DFS_PKT_END_MASK; + mt76_wr(dev, MT_BBP(DFS, 3), data); + + for (i = 0; i < MT_DFS_NUM_ENGINES; i++) { + /* configure engine */ + mt76_wr(dev, MT_BBP(DFS, 0), i); + + /* detection mode + avg_len */ + data = ((radar_specs[i].avg_len & 0x1ff) << 16) | + (radar_specs[i].mode & 0xf); + mt76_wr(dev, MT_BBP(DFS, 4), data); + + /* dfs energy */ + data = ((radar_specs[i].e_high & 0x0fff) << 16) | + (radar_specs[i].e_low & 0x0fff); + mt76_wr(dev, MT_BBP(DFS, 5), data); + + /* dfs period */ + mt76_wr(dev, MT_BBP(DFS, 7), radar_specs[i].t_low); + mt76_wr(dev, MT_BBP(DFS, 9), radar_specs[i].t_high); + + /* dfs burst */ + mt76_wr(dev, MT_BBP(DFS, 11), radar_specs[i].b_low); + mt76_wr(dev, MT_BBP(DFS, 13), radar_specs[i].b_high); + + /* dfs width */ + data = ((radar_specs[i].w_high & 0x0fff) << 16) | + (radar_specs[i].w_low & 0x0fff); + mt76_wr(dev, MT_BBP(DFS, 14), data); + + /* dfs margins */ + data = (radar_specs[i].w_margin << 16) | + radar_specs[i].t_margin; + mt76_wr(dev, MT_BBP(DFS, 15), data); + + /* dfs event expiration */ + mt76_wr(dev, MT_BBP(DFS, 17), radar_specs[i].event_expiration); + + /* dfs pwr adj */ + mt76_wr(dev, MT_BBP(DFS, 30), radar_specs[i].pwr_jmp); + } + + /* reset status */ + mt76_wr(dev, MT_BBP(DFS, 1), 0xf); + mt76_wr(dev, MT_BBP(DFS, 36), 0x3); + + /* enable detection*/ + mt76_wr(dev, MT_BBP(DFS, 0), MT_DFS_CH_EN << 16); + mt76_wr(dev, 0x212c, 0x0c350001); +} + +void mt76x2_dfs_adjust_agc(struct mt76x2_dev *dev) +{ + u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31; + + agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8)); + agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4)); + + val_r8 = (agc_r8 & 0x00007e00) >> 9; + val_r4 = agc_r4 & ~0x1f000000; + val_r4 += (((val_r8 + 1) >> 1) << 24); + mt76_wr(dev, MT_BBP(AGC, 4), val_r4); + + dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4); + dfs_r31 += val_r8; + dfs_r31 -= (agc_r8 & 0x00000038) >> 3; + dfs_r31 = (dfs_r31 << 16) | 0x00000307; + mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31); + + mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071); +} + +void mt76x2_dfs_init_params(struct mt76x2_dev *dev) +{ + struct cfg80211_chan_def *chandef = &dev->mt76.chandef; + + tasklet_kill(&dev->dfs_pd.dfs_tasklet); + if (chandef->chan->flags & IEEE80211_CHAN_RADAR) { + mt76x2_dfs_set_bbp_params(dev); + /* enable debug mode */ + mt76x2_dfs_set_capture_mode_ctrl(dev, true); + + mt76x2_irq_enable(dev, MT_INT_GPTIMER); + mt76_rmw_field(dev, MT_INT_TIMER_EN, + MT_INT_TIMER_EN_GP_TIMER_EN, 1); + } else { + /* disable hw detector */ + mt76_wr(dev, MT_BBP(DFS, 0), 0); + /* clear detector status */ + mt76_wr(dev, MT_BBP(DFS, 1), 0xf); + mt76_wr(dev, 0x212c, 0); + + mt76x2_irq_disable(dev, MT_INT_GPTIMER); + mt76_rmw_field(dev, MT_INT_TIMER_EN, + MT_INT_TIMER_EN_GP_TIMER_EN, 0); + } +} + +void mt76x2_dfs_init_detector(struct mt76x2_dev *dev) +{ + struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd; + + dfs_pd->region = NL80211_DFS_UNSET; + tasklet_init(&dfs_pd->dfs_tasklet, mt76x2_dfs_tasklet, + (unsigned long)dev); +} + diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.h b/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.h new file mode 100644 index 000000000000..9ac69b6a116d --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_DFS_H +#define __MT76x2_DFS_H + +#include <linux/types.h> +#include <linux/nl80211.h> + +#define MT_DFS_GP_INTERVAL (10 << 4) /* 64 us unit */ +#define MT_DFS_NUM_ENGINES 4 + +/* bbp params */ +#define MT_DFS_SYM_ROUND 0 +#define MT_DFS_DELTA_DELAY 2 +#define MT_DFS_VGA_MASK 0 +#define MT_DFS_PWR_GAIN_OFFSET 3 +#define MT_DFS_PWR_DOWN_TIME 0xf +#define MT_DFS_RX_PE_MASK 0xff +#define MT_DFS_PKT_END_MASK 0 +#define MT_DFS_CH_EN 0xf + +struct mt76x2_radar_specs { + u8 mode; + u16 avg_len; + u16 e_low; + u16 e_high; + u16 w_low; + u16 w_high; + u16 w_margin; + u32 t_low; + u32 t_high; + u16 t_margin; + u32 b_low; + u32 b_high; + u32 event_expiration; + u16 pwr_jmp; +}; + +struct mt76x2_dfs_hw_pulse { + u8 engine; + u32 period; + u32 w1; + u32 w2; + u32 burst; +}; + +struct mt76x2_dfs_engine_stats { + u32 hw_pattern; + u32 hw_pulse_discarded; +}; + +struct mt76x2_dfs_pattern_detector { + enum nl80211_dfs_regions region; + + u8 chirp_pulse_cnt; + u32 chirp_pulse_ts; + + struct mt76x2_dfs_engine_stats stats[MT_DFS_NUM_ENGINES]; + struct tasklet_struct dfs_tasklet; +}; + +void mt76x2_dfs_init_params(struct mt76x2_dev *dev); +void mt76x2_dfs_init_detector(struct mt76x2_dev *dev); +void mt76x2_dfs_adjust_agc(struct mt76x2_dev *dev); + +#endif /* __MT76x2_DFS_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c new file mode 100644 index 000000000000..0a3f729a7156 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76x2.h" +#include "mt76x2_dma.h" + +int +mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, + struct sk_buff *skb, int cmd, int seq) +{ + struct mt76_queue *q = &dev->mt76.q_tx[qid]; + struct mt76_queue_buf buf; + dma_addr_t addr; + u32 tx_info; + + tx_info = MT_MCU_MSG_TYPE_CMD | + FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | + FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | + FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | + FIELD_PREP(MT_MCU_MSG_LEN, skb->len); + + addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(dev->mt76.dev, addr)) + return -ENOMEM; + + buf.addr = addr; + buf.len = skb->len; + spin_lock_bh(&q->lock); + mt76_queue_add_buf(dev, q, &buf, 1, tx_info, skb, NULL); + mt76_queue_kick(dev, q); + spin_unlock_bh(&q->lock); + + return 0; +} + +static int +mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, + int idx, int n_desc) +{ + int ret; + + q->regs = dev->mt76.regs + MT_TX_RING_BASE + idx * MT_RING_SIZE; + q->ndesc = n_desc; + + ret = mt76_queue_alloc(dev, q); + if (ret) + return ret; + + mt76x2_irq_enable(dev, MT_INT_TX_DONE(idx)); + + return 0; +} + +void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, + struct sk_buff *skb) +{ + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + void *rxwi = skb->data; + + if (q == MT_RXQ_MCU) { + skb_queue_tail(&dev->mcu.res_q, skb); + wake_up(&dev->mcu.wait); + return; + } + + skb_pull(skb, sizeof(struct mt76x2_rxwi)); + if (mt76x2_mac_process_rx(dev, skb, rxwi)) { + dev_kfree_skb(skb); + return; + } + + mt76_rx(&dev->mt76, q, skb); +} + +static int +mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, + int idx, int n_desc, int bufsize) +{ + int ret; + + q->regs = dev->mt76.regs + MT_RX_RING_BASE + idx * MT_RING_SIZE; + q->ndesc = n_desc; + q->buf_size = bufsize; + + ret = mt76_queue_alloc(dev, q); + if (ret) + return ret; + + mt76x2_irq_enable(dev, MT_INT_RX_DONE(idx)); + + return 0; +} + +static void +mt76x2_tx_tasklet(unsigned long data) +{ + struct mt76x2_dev *dev = (struct mt76x2_dev *) data; + int i; + + mt76x2_mac_process_tx_status_fifo(dev); + + for (i = MT_TXQ_MCU; i >= 0; i--) + mt76_queue_tx_cleanup(dev, i, false); + + mt76x2_mac_poll_tx_status(dev, false); + mt76x2_irq_enable(dev, MT_INT_TX_DONE_ALL); +} + +int mt76x2_dma_init(struct mt76x2_dev *dev) +{ + static const u8 wmm_queue_map[] = { + [IEEE80211_AC_BE] = 0, + [IEEE80211_AC_BK] = 1, + [IEEE80211_AC_VI] = 2, + [IEEE80211_AC_VO] = 3, + }; + int ret; + int i; + struct mt76_txwi_cache __maybe_unused *t; + struct mt76_queue *q; + + BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x2_txwi)); + BUILD_BUG_ON(sizeof(struct mt76x2_rxwi) > MT_RX_HEADROOM); + + mt76_dma_attach(&dev->mt76); + + init_waitqueue_head(&dev->mcu.wait); + skb_queue_head_init(&dev->mcu.res_q); + + tasklet_init(&dev->tx_tasklet, mt76x2_tx_tasklet, (unsigned long) dev); + + mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); + + for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) { + ret = mt76x2_init_tx_queue(dev, &dev->mt76.q_tx[i], + wmm_queue_map[i], MT_TX_RING_SIZE); + if (ret) + return ret; + } + + ret = mt76x2_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_PSD], + MT_TX_HW_QUEUE_MGMT, MT_TX_RING_SIZE); + if (ret) + return ret; + + ret = mt76x2_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_MCU], + MT_TX_HW_QUEUE_MCU, MT_MCU_RING_SIZE); + if (ret) + return ret; + + ret = mt76x2_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1, + MT_MCU_RING_SIZE, MT_RX_BUF_SIZE); + if (ret) + return ret; + + q = &dev->mt76.q_rx[MT_RXQ_MAIN]; + q->buf_offset = MT_RX_HEADROOM - sizeof(struct mt76x2_rxwi); + ret = mt76x2_init_rx_queue(dev, q, 0, MT76x2_RX_RING_SIZE, MT_RX_BUF_SIZE); + if (ret) + return ret; + + return mt76_init_queues(dev); +} + +void mt76x2_dma_cleanup(struct mt76x2_dev *dev) +{ + tasklet_kill(&dev->tx_tasklet); + mt76_dma_cleanup(&dev->mt76); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.h b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.h new file mode 100644 index 000000000000..47f79d83fcb4 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_DMA_H +#define __MT76x2_DMA_H + +#include "dma.h" + +#define MT_TXD_INFO_LEN GENMASK(13, 0) +#define MT_TXD_INFO_NEXT_VLD BIT(16) +#define MT_TXD_INFO_TX_BURST BIT(17) +#define MT_TXD_INFO_80211 BIT(19) +#define MT_TXD_INFO_TSO BIT(20) +#define MT_TXD_INFO_CSO BIT(21) +#define MT_TXD_INFO_WIV BIT(24) +#define MT_TXD_INFO_QSEL GENMASK(26, 25) +#define MT_TXD_INFO_TCO BIT(29) +#define MT_TXD_INFO_UCO BIT(30) +#define MT_TXD_INFO_ICO BIT(31) + +#define MT_RX_FCE_INFO_LEN GENMASK(13, 0) +#define MT_RX_FCE_INFO_SELF_GEN BIT(15) +#define MT_RX_FCE_INFO_CMD_SEQ GENMASK(19, 16) +#define MT_RX_FCE_INFO_EVT_TYPE GENMASK(23, 20) +#define MT_RX_FCE_INFO_PCIE_INTR BIT(24) +#define MT_RX_FCE_INFO_QSEL GENMASK(26, 25) +#define MT_RX_FCE_INFO_D_PORT GENMASK(29, 27) +#define MT_RX_FCE_INFO_TYPE GENMASK(31, 30) + +/* MCU request message header */ +#define MT_MCU_MSG_LEN GENMASK(15, 0) +#define MT_MCU_MSG_CMD_SEQ GENMASK(19, 16) +#define MT_MCU_MSG_CMD_TYPE GENMASK(26, 20) +#define MT_MCU_MSG_PORT GENMASK(29, 27) +#define MT_MCU_MSG_TYPE GENMASK(31, 30) +#define MT_MCU_MSG_TYPE_CMD BIT(30) + +enum mt76x2_qsel { + MT_QSEL_MGMT, + MT_QSEL_HCCA, + MT_QSEL_EDCA, + MT_QSEL_EDCA_2, +}; + +enum dma_msg_port { + WLAN_PORT, + CPU_RX_PORT, + CPU_TX_PORT, + HOST_PORT, + VIRTUAL_CPU_RX_PORT, + VIRTUAL_CPU_TX_PORT, + DISCARD, +}; + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c new file mode 100644 index 000000000000..440b7e7d73a9 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c @@ -0,0 +1,647 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <asm/unaligned.h> +#include "mt76x2.h" +#include "mt76x2_eeprom.h" + +#define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1 + +static int +mt76x2_eeprom_copy(struct mt76x2_dev *dev, enum mt76x2_eeprom_field field, + void *dest, int len) +{ + if (field + len > dev->mt76.eeprom.size) + return -1; + + memcpy(dest, dev->mt76.eeprom.data + field, len); + return 0; +} + +static int +mt76x2_eeprom_get_macaddr(struct mt76x2_dev *dev) +{ + void *src = dev->mt76.eeprom.data + MT_EE_MAC_ADDR; + + memcpy(dev->mt76.macaddr, src, ETH_ALEN); + return 0; +} + +static void +mt76x2_eeprom_parse_hw_cap(struct mt76x2_dev *dev) +{ + u16 val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0); + + switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) { + case BOARD_TYPE_5GHZ: + dev->mt76.cap.has_5ghz = true; + break; + case BOARD_TYPE_2GHZ: + dev->mt76.cap.has_2ghz = true; + break; + default: + dev->mt76.cap.has_2ghz = true; + dev->mt76.cap.has_5ghz = true; + break; + } +} + +static int +mt76x2_efuse_read(struct mt76x2_dev *dev, u16 addr, u8 *data) +{ + u32 val; + int i; + + val = mt76_rr(dev, MT_EFUSE_CTRL); + val &= ~(MT_EFUSE_CTRL_AIN | + MT_EFUSE_CTRL_MODE); + val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf); + val |= MT_EFUSE_CTRL_KICK; + mt76_wr(dev, MT_EFUSE_CTRL, val); + + if (!mt76_poll(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000)) + return -ETIMEDOUT; + + udelay(2); + + val = mt76_rr(dev, MT_EFUSE_CTRL); + if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) { + memset(data, 0xff, 16); + return 0; + } + + for (i = 0; i < 4; i++) { + val = mt76_rr(dev, MT_EFUSE_DATA(i)); + put_unaligned_le32(val, data + 4 * i); + } + + return 0; +} + +static int +mt76x2_get_efuse_data(struct mt76x2_dev *dev, void *buf, int len) +{ + int ret, i; + + for (i = 0; i + 16 <= len; i += 16) { + ret = mt76x2_efuse_read(dev, i, buf + i); + if (ret) + return ret; + } + + return 0; +} + +static bool +mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse) +{ + u16 *efuse_w = (u16 *) efuse; + + if (efuse_w[MT_EE_NIC_CONF_0] != 0) + return false; + + if (efuse_w[MT_EE_XTAL_TRIM_1] == 0xffff) + return false; + + if (efuse_w[MT_EE_TX_POWER_DELTA_BW40] != 0) + return false; + + if (efuse_w[MT_EE_TX_POWER_0_START_2G] == 0xffff) + return false; + + if (efuse_w[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA] != 0) + return false; + + if (efuse_w[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE] == 0xffff) + return false; + + return true; +} + +static void +mt76x2_apply_cal_free_data(struct mt76x2_dev *dev, u8 *efuse) +{ +#define GROUP_5G(_id) \ + MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \ + MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \ + MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \ + MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1 + + static const u8 cal_free_bytes[] = { + MT_EE_XTAL_TRIM_1, + MT_EE_TX_POWER_EXT_PA_5G + 1, + MT_EE_TX_POWER_0_START_2G, + MT_EE_TX_POWER_0_START_2G + 1, + MT_EE_TX_POWER_1_START_2G, + MT_EE_TX_POWER_1_START_2G + 1, + GROUP_5G(0), + GROUP_5G(1), + GROUP_5G(2), + GROUP_5G(3), + GROUP_5G(4), + GROUP_5G(5), + MT_EE_RF_2G_TSSI_OFF_TXPOWER, + MT_EE_RF_2G_RX_HIGH_GAIN + 1, + MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN, + MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN + 1, + MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN, + MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN + 1, + MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN, + MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN + 1, + }; + u8 *eeprom = dev->mt76.eeprom.data; + u8 prev_grp0[4] = { + eeprom[MT_EE_TX_POWER_0_START_5G], + eeprom[MT_EE_TX_POWER_0_START_5G + 1], + eeprom[MT_EE_TX_POWER_1_START_5G], + eeprom[MT_EE_TX_POWER_1_START_5G + 1] + }; + u16 val; + int i; + + if (!mt76x2_has_cal_free_data(dev, efuse)) + return; + + for (i = 0; i < ARRAY_SIZE(cal_free_bytes); i++) { + int offset = cal_free_bytes[i]; + + eeprom[offset] = efuse[offset]; + } + + if (!(efuse[MT_EE_TX_POWER_0_START_5G] | + efuse[MT_EE_TX_POWER_0_START_5G + 1])) + memcpy(eeprom + MT_EE_TX_POWER_0_START_5G, prev_grp0, 2); + if (!(efuse[MT_EE_TX_POWER_1_START_5G] | + efuse[MT_EE_TX_POWER_1_START_5G + 1])) + memcpy(eeprom + MT_EE_TX_POWER_1_START_5G, prev_grp0 + 2, 2); + + val = get_unaligned_le16(efuse + MT_EE_BT_RCAL_RESULT); + if (val != 0xffff) + eeprom[MT_EE_BT_RCAL_RESULT] = val & 0xff; + + val = get_unaligned_le16(efuse + MT_EE_BT_VCDL_CALIBRATION); + if (val != 0xffff) + eeprom[MT_EE_BT_VCDL_CALIBRATION + 1] = val >> 8; + + val = get_unaligned_le16(efuse + MT_EE_BT_PMUCFG); + if (val != 0xffff) + eeprom[MT_EE_BT_PMUCFG] = val & 0xff; +} + +static int mt76x2_check_eeprom(struct mt76x2_dev *dev) +{ + u16 val = get_unaligned_le16(dev->mt76.eeprom.data); + + if (!val) + val = get_unaligned_le16(dev->mt76.eeprom.data + MT_EE_PCI_ID); + + switch (val) { + case 0x7662: + case 0x7612: + return 0; + default: + dev_err(dev->mt76.dev, "EEPROM data check failed: %04x\n", val); + return -EINVAL; + } +} + +static int +mt76x2_eeprom_load(struct mt76x2_dev *dev) +{ + void *efuse; + int len = MT7662_EEPROM_SIZE; + bool found; + int ret; + + ret = mt76_eeprom_init(&dev->mt76, len); + if (ret < 0) + return ret; + + found = ret; + if (found) + found = !mt76x2_check_eeprom(dev); + + dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL); + dev->mt76.otp.size = len; + if (!dev->mt76.otp.data) + return -ENOMEM; + + efuse = dev->mt76.otp.data; + + if (mt76x2_get_efuse_data(dev, efuse, len)) + goto out; + + if (found) { + mt76x2_apply_cal_free_data(dev, efuse); + } else { + /* FIXME: check if efuse data is complete */ + found = true; + memcpy(dev->mt76.eeprom.data, efuse, len); + } + +out: + if (!found) + return -ENOENT; + + return 0; +} + +static inline int +mt76x2_sign_extend(u32 val, unsigned int size) +{ + bool sign = val & BIT(size - 1); + + val &= BIT(size - 1) - 1; + + return sign ? val : -val; +} + +static inline int +mt76x2_sign_extend_optional(u32 val, unsigned int size) +{ + bool enable = val & BIT(size); + + return enable ? mt76x2_sign_extend(val, size) : 0; +} + +static bool +field_valid(u8 val) +{ + return val != 0 && val != 0xff; +} + +static void +mt76x2_set_rx_gain_group(struct mt76x2_dev *dev, u8 val) +{ + s8 *dest = dev->cal.rx.high_gain; + + if (!field_valid(val)) { + dest[0] = 0; + dest[1] = 0; + return; + } + + dest[0] = mt76x2_sign_extend(val, 4); + dest[1] = mt76x2_sign_extend(val >> 4, 4); +} + +static void +mt76x2_set_rssi_offset(struct mt76x2_dev *dev, int chain, u8 val) +{ + s8 *dest = dev->cal.rx.rssi_offset; + + if (!field_valid(val)) { + dest[chain] = 0; + return; + } + + dest[chain] = mt76x2_sign_extend_optional(val, 7); +} + +static enum mt76x2_cal_channel_group +mt76x2_get_cal_channel_group(int channel) +{ + if (channel >= 184 && channel <= 196) + return MT_CH_5G_JAPAN; + if (channel <= 48) + return MT_CH_5G_UNII_1; + if (channel <= 64) + return MT_CH_5G_UNII_2; + if (channel <= 114) + return MT_CH_5G_UNII_2E_1; + if (channel <= 144) + return MT_CH_5G_UNII_2E_2; + return MT_CH_5G_UNII_3; +} + +static u8 +mt76x2_get_5g_rx_gain(struct mt76x2_dev *dev, u8 channel) +{ + enum mt76x2_cal_channel_group group; + + group = mt76x2_get_cal_channel_group(channel); + switch (group) { + case MT_CH_5G_JAPAN: + return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN); + case MT_CH_5G_UNII_1: + return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8; + case MT_CH_5G_UNII_2: + return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN); + case MT_CH_5G_UNII_2E_1: + return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8; + case MT_CH_5G_UNII_2E_2: + return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN); + default: + return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8; + } +} + +void mt76x2_read_rx_gain(struct mt76x2_dev *dev) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + int channel = chan->hw_value; + s8 lna_5g[3], lna_2g; + u8 lna; + u16 val; + + if (chan->band == NL80211_BAND_2GHZ) + val = mt76x2_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN) >> 8; + else + val = mt76x2_get_5g_rx_gain(dev, channel); + + mt76x2_set_rx_gain_group(dev, val); + + if (chan->band == NL80211_BAND_2GHZ) { + val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_0); + mt76x2_set_rssi_offset(dev, 0, val); + mt76x2_set_rssi_offset(dev, 1, val >> 8); + } else { + val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_0); + mt76x2_set_rssi_offset(dev, 0, val); + mt76x2_set_rssi_offset(dev, 1, val >> 8); + } + + val = mt76x2_eeprom_get(dev, MT_EE_LNA_GAIN); + lna_2g = val & 0xff; + lna_5g[0] = val >> 8; + + val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_1); + lna_5g[1] = val >> 8; + + val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_1); + lna_5g[2] = val >> 8; + + if (!field_valid(lna_5g[1])) + lna_5g[1] = lna_5g[0]; + + if (!field_valid(lna_5g[2])) + lna_5g[2] = lna_5g[0]; + + dev->cal.rx.mcu_gain = (lna_2g & 0xff); + dev->cal.rx.mcu_gain |= (lna_5g[0] & 0xff) << 8; + dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; + dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; + + val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1); + if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G) + lna_2g = 0; + if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G) + memset(lna_5g, 0, sizeof(lna_5g)); + + if (chan->band == NL80211_BAND_2GHZ) + lna = lna_2g; + else if (channel <= 64) + lna = lna_5g[0]; + else if (channel <= 128) + lna = lna_5g[1]; + else + lna = lna_5g[2]; + + if (lna == 0xff) + lna = 0; + + dev->cal.rx.lna_gain = mt76x2_sign_extend(lna, 8); +} + +static s8 +mt76x2_rate_power_val(u8 val) +{ + if (!field_valid(val)) + return 0; + + return mt76x2_sign_extend_optional(val, 7); +} + +void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t) +{ + bool is_5ghz; + u16 val; + + is_5ghz = dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ; + + memset(t, 0, sizeof(*t)); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_CCK); + t->cck[0] = t->cck[1] = mt76x2_rate_power_val(val); + t->cck[2] = t->cck[3] = mt76x2_rate_power_val(val >> 8); + + if (is_5ghz) + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_6M); + else + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_6M); + t->ofdm[0] = t->ofdm[1] = mt76x2_rate_power_val(val); + t->ofdm[2] = t->ofdm[3] = mt76x2_rate_power_val(val >> 8); + + if (is_5ghz) + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_24M); + else + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_24M); + t->ofdm[4] = t->ofdm[5] = mt76x2_rate_power_val(val); + t->ofdm[6] = t->ofdm[7] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS0); + t->ht[0] = t->ht[1] = mt76x2_rate_power_val(val); + t->ht[2] = t->ht[3] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS4); + t->ht[4] = t->ht[5] = mt76x2_rate_power_val(val); + t->ht[6] = t->ht[7] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS8); + t->ht[8] = t->ht[9] = mt76x2_rate_power_val(val); + t->ht[10] = t->ht[11] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS12); + t->ht[12] = t->ht[13] = mt76x2_rate_power_val(val); + t->ht[14] = t->ht[15] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS0); + t->vht[0] = t->vht[1] = mt76x2_rate_power_val(val); + t->vht[2] = t->vht[3] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS4); + t->vht[4] = t->vht[5] = mt76x2_rate_power_val(val); + t->vht[6] = t->vht[7] = mt76x2_rate_power_val(val >> 8); + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8); + if (!is_5ghz) + val >>= 8; + t->vht[8] = t->vht[9] = mt76x2_rate_power_val(val >> 8); +} + +static void +mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t, + int chain, int offset) +{ + int channel = dev->mt76.chandef.chan->hw_value; + int delta_idx; + u8 data[6]; + u16 val; + + if (channel < 6) + delta_idx = 3; + else if (channel < 11) + delta_idx = 4; + else + delta_idx = 5; + + mt76x2_eeprom_copy(dev, offset, data, sizeof(data)); + + t->chain[chain].tssi_slope = data[0]; + t->chain[chain].tssi_offset = data[1]; + t->chain[chain].target_power = data[2]; + t->chain[chain].delta = mt76x2_sign_extend_optional(data[delta_idx], 7); + + val = mt76x2_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER); + t->target_power = val >> 8; +} + +static void +mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t, + int chain, int offset) +{ + int channel = dev->mt76.chandef.chan->hw_value; + enum mt76x2_cal_channel_group group; + int delta_idx; + u16 val; + u8 data[5]; + + group = mt76x2_get_cal_channel_group(channel); + offset += group * MT_TX_POWER_GROUP_SIZE_5G; + + if (channel >= 192) + delta_idx = 4; + else if (channel >= 484) + delta_idx = 3; + else if (channel < 44) + delta_idx = 3; + else if (channel < 52) + delta_idx = 4; + else if (channel < 58) + delta_idx = 3; + else if (channel < 98) + delta_idx = 4; + else if (channel < 106) + delta_idx = 3; + else if (channel < 116) + delta_idx = 4; + else if (channel < 130) + delta_idx = 3; + else if (channel < 149) + delta_idx = 4; + else if (channel < 157) + delta_idx = 3; + else + delta_idx = 4; + + mt76x2_eeprom_copy(dev, offset, data, sizeof(data)); + + t->chain[chain].tssi_slope = data[0]; + t->chain[chain].tssi_offset = data[1]; + t->chain[chain].target_power = data[2]; + t->chain[chain].delta = mt76x2_sign_extend_optional(data[delta_idx], 7); + + val = mt76x2_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN); + t->target_power = val & 0xff; +} + +void mt76x2_get_power_info(struct mt76x2_dev *dev, + struct mt76x2_tx_power_info *t) +{ + u16 bw40, bw80; + + memset(t, 0, sizeof(*t)); + + bw40 = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW40); + bw80 = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80); + + if (dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ) { + bw40 >>= 8; + mt76x2_get_power_info_5g(dev, t, 0, MT_EE_TX_POWER_0_START_5G); + mt76x2_get_power_info_5g(dev, t, 1, MT_EE_TX_POWER_1_START_5G); + } else { + mt76x2_get_power_info_2g(dev, t, 0, MT_EE_TX_POWER_0_START_2G); + mt76x2_get_power_info_2g(dev, t, 1, MT_EE_TX_POWER_1_START_2G); + } + + if (mt76x2_tssi_enabled(dev) || !field_valid(t->target_power)) + t->target_power = t->chain[0].target_power; + + t->delta_bw40 = mt76x2_rate_power_val(bw40); + t->delta_bw80 = mt76x2_rate_power_val(bw80); +} + +int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t) +{ + enum nl80211_band band = dev->mt76.chandef.chan->band; + u16 val, slope; + u8 bounds; + + memset(t, 0, sizeof(*t)); + + val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1); + if (!(val & MT_EE_NIC_CONF_1_TEMP_TX_ALC)) + return -EINVAL; + + if (!mt76x2_ext_pa_enabled(dev, band)) + return -EINVAL; + + val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G) >> 8; + if (!(val & BIT(7))) + return -EINVAL; + + t->temp_25_ref = val & 0x7f; + if (band == NL80211_BAND_5GHZ) { + slope = mt76x2_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_5G); + bounds = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G); + } else { + slope = mt76x2_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_2G); + bounds = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80) >> 8; + } + + t->high_slope = slope & 0xff; + t->low_slope = slope >> 8; + t->lower_bound = 0 - (bounds & 0xf); + t->upper_bound = (bounds >> 4) & 0xf; + + return 0; +} + +bool mt76x2_ext_pa_enabled(struct mt76x2_dev *dev, enum nl80211_band band) +{ + u16 conf0 = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0); + + if (band == NL80211_BAND_5GHZ) + return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_5G); + else + return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_2G); +} + +int mt76x2_eeprom_init(struct mt76x2_dev *dev) +{ + int ret; + + ret = mt76x2_eeprom_load(dev); + if (ret) + return ret; + + mt76x2_eeprom_parse_hw_cap(dev); + mt76x2_eeprom_get_macaddr(dev); + mt76_eeprom_override(&dev->mt76); + dev->mt76.macaddr[0] &= ~BIT(1); + + return 0; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h new file mode 100644 index 000000000000..063d6c8451c9 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_EEPROM_H +#define __MT76x2_EEPROM_H + +#include "mt76x2.h" + +enum mt76x2_eeprom_field { + MT_EE_CHIP_ID = 0x000, + MT_EE_VERSION = 0x002, + MT_EE_MAC_ADDR = 0x004, + MT_EE_PCI_ID = 0x00A, + MT_EE_NIC_CONF_0 = 0x034, + MT_EE_NIC_CONF_1 = 0x036, + MT_EE_NIC_CONF_2 = 0x042, + + MT_EE_XTAL_TRIM_1 = 0x03a, + MT_EE_XTAL_TRIM_2 = 0x09e, + + MT_EE_LNA_GAIN = 0x044, + MT_EE_RSSI_OFFSET_2G_0 = 0x046, + MT_EE_RSSI_OFFSET_2G_1 = 0x048, + MT_EE_RSSI_OFFSET_5G_0 = 0x04a, + MT_EE_RSSI_OFFSET_5G_1 = 0x04c, + + MT_EE_TX_POWER_DELTA_BW40 = 0x050, + MT_EE_TX_POWER_DELTA_BW80 = 0x052, + + MT_EE_TX_POWER_EXT_PA_5G = 0x054, + + MT_EE_TX_POWER_0_START_2G = 0x056, + MT_EE_TX_POWER_1_START_2G = 0x05c, + + /* used as byte arrays */ +#define MT_TX_POWER_GROUP_SIZE_5G 5 +#define MT_TX_POWER_GROUPS_5G 6 + MT_EE_TX_POWER_0_START_5G = 0x062, + + MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA = 0x074, + MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE = 0x076, + + MT_EE_TX_POWER_1_START_5G = 0x080, + + MT_EE_TX_POWER_CCK = 0x0a0, + MT_EE_TX_POWER_OFDM_2G_6M = 0x0a2, + MT_EE_TX_POWER_OFDM_2G_24M = 0x0a4, + MT_EE_TX_POWER_OFDM_5G_6M = 0x0b2, + MT_EE_TX_POWER_OFDM_5G_24M = 0x0b4, + MT_EE_TX_POWER_HT_MCS0 = 0x0a6, + MT_EE_TX_POWER_HT_MCS4 = 0x0a8, + MT_EE_TX_POWER_HT_MCS8 = 0x0aa, + MT_EE_TX_POWER_HT_MCS12 = 0x0ac, + MT_EE_TX_POWER_VHT_MCS0 = 0x0ba, + MT_EE_TX_POWER_VHT_MCS4 = 0x0bc, + MT_EE_TX_POWER_VHT_MCS8 = 0x0be, + + MT_EE_RF_TEMP_COMP_SLOPE_5G = 0x0f2, + MT_EE_RF_TEMP_COMP_SLOPE_2G = 0x0f4, + + MT_EE_RF_2G_TSSI_OFF_TXPOWER = 0x0f6, + MT_EE_RF_2G_RX_HIGH_GAIN = 0x0f8, + MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN = 0x0fa, + MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN = 0x0fc, + MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN = 0x0fe, + + MT_EE_BT_RCAL_RESULT = 0x138, + MT_EE_BT_VCDL_CALIBRATION = 0x13c, + MT_EE_BT_PMUCFG = 0x13e, + + __MT_EE_MAX +}; + +#define MT_EE_NIC_CONF_0_PA_INT_2G BIT(8) +#define MT_EE_NIC_CONF_0_PA_INT_5G BIT(9) +#define MT_EE_NIC_CONF_0_BOARD_TYPE GENMASK(13, 12) + +#define MT_EE_NIC_CONF_1_TEMP_TX_ALC BIT(1) +#define MT_EE_NIC_CONF_1_LNA_EXT_2G BIT(2) +#define MT_EE_NIC_CONF_1_LNA_EXT_5G BIT(3) +#define MT_EE_NIC_CONF_1_TX_ALC_EN BIT(13) + +#define MT_EE_NIC_CONF_2_RX_STREAM GENMASK(3, 0) +#define MT_EE_NIC_CONF_2_TX_STREAM GENMASK(7, 4) +#define MT_EE_NIC_CONF_2_HW_ANTDIV BIT(8) +#define MT_EE_NIC_CONF_2_XTAL_OPTION GENMASK(10, 9) +#define MT_EE_NIC_CONF_2_TEMP_DISABLE BIT(11) +#define MT_EE_NIC_CONF_2_COEX_METHOD GENMASK(15, 13) + +enum mt76x2_board_type { + BOARD_TYPE_2GHZ = 1, + BOARD_TYPE_5GHZ = 2, +}; + +enum mt76x2_cal_channel_group { + MT_CH_5G_JAPAN, + MT_CH_5G_UNII_1, + MT_CH_5G_UNII_2, + MT_CH_5G_UNII_2E_1, + MT_CH_5G_UNII_2E_2, + MT_CH_5G_UNII_3, + __MT_CH_MAX +}; + +struct mt76x2_tx_power_info { + u8 target_power; + + s8 delta_bw40; + s8 delta_bw80; + + struct { + s8 tssi_slope; + s8 tssi_offset; + s8 target_power; + s8 delta; + } chain[MT_MAX_CHAINS]; +}; + +struct mt76x2_temp_comp { + u8 temp_25_ref; + int lower_bound; /* J */ + int upper_bound; /* J */ + unsigned int high_slope; /* J / dB */ + unsigned int low_slope; /* J / dB */ +}; + +static inline int +mt76x2_eeprom_get(struct mt76x2_dev *dev, enum mt76x2_eeprom_field field) +{ + if ((field & 1) || field >= __MT_EE_MAX) + return -1; + + return get_unaligned_le16(dev->mt76.eeprom.data + field); +} + +void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t); +void mt76x2_get_power_info(struct mt76x2_dev *dev, + struct mt76x2_tx_power_info *t); +int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t); +bool mt76x2_ext_pa_enabled(struct mt76x2_dev *dev, enum nl80211_band band); +void mt76x2_read_rx_gain(struct mt76x2_dev *dev); + +static inline bool +mt76x2_temp_tx_alc_enabled(struct mt76x2_dev *dev) +{ + return mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) & + MT_EE_NIC_CONF_1_TEMP_TX_ALC; +} + +static inline bool +mt76x2_tssi_enabled(struct mt76x2_dev *dev) +{ + return !mt76x2_temp_tx_alc_enabled(dev) && + (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) & + MT_EE_NIC_CONF_1_TX_ALC_EN); +} + +static inline bool +mt76x2_has_ext_lna(struct mt76x2_dev *dev) +{ + u32 val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1); + + if (dev->mt76.chandef.chan->band == NL80211_BAND_2GHZ) + return val & MT_EE_NIC_CONF_1_LNA_EXT_2G; + else + return val & MT_EE_NIC_CONF_1_LNA_EXT_5G; +} + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c new file mode 100644 index 000000000000..d3f03a8aee90 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -0,0 +1,839 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/delay.h> +#include "mt76x2.h" +#include "mt76x2_eeprom.h" +#include "mt76x2_mcu.h" + +struct mt76x2_reg_pair { + u32 reg; + u32 value; +}; + +static bool +mt76x2_wait_for_mac(struct mt76x2_dev *dev) +{ + int i; + + for (i = 0; i < 500; i++) { + switch (mt76_rr(dev, MT_MAC_CSR0)) { + case 0: + case ~0: + break; + default: + return true; + } + usleep_range(5000, 10000); + } + + return false; +} + +static bool +wait_for_wpdma(struct mt76x2_dev *dev) +{ + return mt76_poll(dev, MT_WPDMA_GLO_CFG, + MT_WPDMA_GLO_CFG_TX_DMA_BUSY | + MT_WPDMA_GLO_CFG_RX_DMA_BUSY, + 0, 1000); +} + +static void +mt76x2_mac_pbf_init(struct mt76x2_dev *dev) +{ + u32 val; + + val = MT_PBF_SYS_CTRL_MCU_RESET | + MT_PBF_SYS_CTRL_DMA_RESET | + MT_PBF_SYS_CTRL_MAC_RESET | + MT_PBF_SYS_CTRL_PBF_RESET | + MT_PBF_SYS_CTRL_ASY_RESET; + + mt76_set(dev, MT_PBF_SYS_CTRL, val); + mt76_clear(dev, MT_PBF_SYS_CTRL, val); + + mt76_wr(dev, MT_PBF_TX_MAX_PCNT, 0xefef3f1f); + mt76_wr(dev, MT_PBF_RX_MAX_PCNT, 0xfebf); +} + +static void +mt76x2_write_reg_pairs(struct mt76x2_dev *dev, + const struct mt76x2_reg_pair *data, int len) +{ + while (len > 0) { + mt76_wr(dev, data->reg, data->value); + len--; + data++; + } +} + +static void +mt76_write_mac_initvals(struct mt76x2_dev *dev) +{ +#define DEFAULT_PROT_CFG \ + (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) | \ + FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ + FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) | \ + MT_PROT_CFG_RTS_THRESH) + +#define DEFAULT_PROT_CFG_20 \ + (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) | \ + FIELD_PREP(MT_PROT_CFG_CTRL, 1) | \ + FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ + FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x17)) + +#define DEFAULT_PROT_CFG_40 \ + (FIELD_PREP(MT_PROT_CFG_RATE, 0x2084) | \ + FIELD_PREP(MT_PROT_CFG_CTRL, 1) | \ + FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ + FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f)) + + static const struct mt76x2_reg_pair vals[] = { + /* Copied from MediaTek reference source */ + { MT_PBF_SYS_CTRL, 0x00080c00 }, + { MT_PBF_CFG, 0x1efebcff }, + { MT_FCE_PSE_CTRL, 0x00000001 }, + { MT_MAC_SYS_CTRL, 0x0000000c }, + { MT_MAX_LEN_CFG, 0x003e3f00 }, + { MT_AMPDU_MAX_LEN_20M1S, 0xaaa99887 }, + { MT_AMPDU_MAX_LEN_20M2S, 0x000000aa }, + { MT_XIFS_TIME_CFG, 0x33a40d0a }, + { MT_BKOFF_SLOT_CFG, 0x00000209 }, + { MT_TBTT_SYNC_CFG, 0x00422010 }, + { MT_PWR_PIN_CFG, 0x00000000 }, + { 0x1238, 0x001700c8 }, + { MT_TX_SW_CFG0, 0x00101001 }, + { MT_TX_SW_CFG1, 0x00010000 }, + { MT_TX_SW_CFG2, 0x00000000 }, + { MT_TXOP_CTRL_CFG, 0x0400583f }, + { MT_TX_RTS_CFG, 0x00100020 }, + { MT_TX_TIMEOUT_CFG, 0x000a2290 }, + { MT_TX_RETRY_CFG, 0x47f01f0f }, + { MT_EXP_ACK_TIME, 0x002c00dc }, + { MT_TX_PROT_CFG6, 0xe3f42004 }, + { MT_TX_PROT_CFG7, 0xe3f42084 }, + { MT_TX_PROT_CFG8, 0xe3f42104 }, + { MT_PIFS_TX_CFG, 0x00060fff }, + { MT_RX_FILTR_CFG, 0x00015f97 }, + { MT_LEGACY_BASIC_RATE, 0x0000017f }, + { MT_HT_BASIC_RATE, 0x00004003 }, + { MT_PN_PAD_MODE, 0x00000002 }, + { MT_TXOP_HLDR_ET, 0x00000002 }, + { 0xa44, 0x00000000 }, + { MT_HEADER_TRANS_CTRL_REG, 0x00000000 }, + { MT_TSO_CTRL, 0x00000000 }, + { MT_AUX_CLK_CFG, 0x00000000 }, + { MT_DACCLK_EN_DLY_CFG, 0x00000000 }, + { MT_TX_ALC_CFG_4, 0x00000000 }, + { MT_TX_ALC_VGA3, 0x00000000 }, + { MT_TX_PWR_CFG_0, 0x3a3a3a3a }, + { MT_TX_PWR_CFG_1, 0x3a3a3a3a }, + { MT_TX_PWR_CFG_2, 0x3a3a3a3a }, + { MT_TX_PWR_CFG_3, 0x3a3a3a3a }, + { MT_TX_PWR_CFG_4, 0x3a3a3a3a }, + { MT_TX_PWR_CFG_7, 0x3a3a3a3a }, + { MT_TX_PWR_CFG_8, 0x0000003a }, + { MT_TX_PWR_CFG_9, 0x0000003a }, + { MT_EFUSE_CTRL, 0x0000d000 }, + { MT_PAUSE_ENABLE_CONTROL1, 0x0000000a }, + { MT_FCE_WLAN_FLOW_CONTROL1, 0x60401c18 }, + { MT_WPDMA_DELAY_INT_CFG, 0x94ff0000 }, + { MT_TX_SW_CFG3, 0x00000004 }, + { MT_HT_FBK_TO_LEGACY, 0x00001818 }, + { MT_VHT_HT_FBK_CFG1, 0xedcba980 }, + { MT_PROT_AUTO_TX_CFG, 0x00830083 }, + { MT_HT_CTRL_CFG, 0x000001ff }, + }; + struct mt76x2_reg_pair prot_vals[] = { + { MT_CCK_PROT_CFG, DEFAULT_PROT_CFG }, + { MT_OFDM_PROT_CFG, DEFAULT_PROT_CFG }, + { MT_MM20_PROT_CFG, DEFAULT_PROT_CFG_20 }, + { MT_MM40_PROT_CFG, DEFAULT_PROT_CFG_40 }, + { MT_GF20_PROT_CFG, DEFAULT_PROT_CFG_20 }, + { MT_GF40_PROT_CFG, DEFAULT_PROT_CFG_40 }, + }; + + mt76x2_write_reg_pairs(dev, vals, ARRAY_SIZE(vals)); + mt76x2_write_reg_pairs(dev, prot_vals, ARRAY_SIZE(prot_vals)); +} + +static void +mt76x2_fixup_xtal(struct mt76x2_dev *dev) +{ + u16 eep_val; + s8 offset = 0; + + eep_val = mt76x2_eeprom_get(dev, MT_EE_XTAL_TRIM_2); + + offset = eep_val & 0x7f; + if ((eep_val & 0xff) == 0xff) + offset = 0; + else if (eep_val & 0x80) + offset = 0 - offset; + + eep_val >>= 8; + if (eep_val == 0x00 || eep_val == 0xff) { + eep_val = mt76x2_eeprom_get(dev, MT_EE_XTAL_TRIM_1); + eep_val &= 0xff; + + if (eep_val == 0x00 || eep_val == 0xff) + eep_val = 0x14; + } + + eep_val &= 0x7f; + mt76_rmw_field(dev, MT_XO_CTRL5, MT_XO_CTRL5_C2_VAL, eep_val + offset); + mt76_set(dev, MT_XO_CTRL6, MT_XO_CTRL6_C2_CTRL); + + eep_val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_2); + switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) { + case 0: + mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80); + break; + case 1: + mt76_wr(dev, MT_XO_CTRL7, 0x5c1feed0); + break; + default: + break; + } +} + +static void +mt76x2_init_beacon_offsets(struct mt76x2_dev *dev) +{ + u16 base = MT_BEACON_BASE; + u32 regs[4] = {}; + int i; + + for (i = 0; i < 16; i++) { + u16 addr = dev->beacon_offsets[i]; + + regs[i / 4] |= ((addr - base) / 64) << (8 * (i % 4)); + } + + for (i = 0; i < 4; i++) + mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]); +} + +int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard) +{ + static const u8 null_addr[ETH_ALEN] = {}; + const u8 *macaddr = dev->mt76.macaddr; + u32 val; + int i, k; + + if (!mt76x2_wait_for_mac(dev)) + return -ETIMEDOUT; + + val = mt76_rr(dev, MT_WPDMA_GLO_CFG); + + val &= ~(MT_WPDMA_GLO_CFG_TX_DMA_EN | + MT_WPDMA_GLO_CFG_TX_DMA_BUSY | + MT_WPDMA_GLO_CFG_RX_DMA_EN | + MT_WPDMA_GLO_CFG_RX_DMA_BUSY | + MT_WPDMA_GLO_CFG_DMA_BURST_SIZE); + val |= FIELD_PREP(MT_WPDMA_GLO_CFG_DMA_BURST_SIZE, 3); + + mt76_wr(dev, MT_WPDMA_GLO_CFG, val); + + mt76x2_mac_pbf_init(dev); + mt76_write_mac_initvals(dev); + mt76x2_fixup_xtal(dev); + + mt76_clear(dev, MT_MAC_SYS_CTRL, + MT_MAC_SYS_CTRL_RESET_CSR | + MT_MAC_SYS_CTRL_RESET_BBP); + + if (is_mt7612(dev)) + mt76_clear(dev, MT_COEXCFG0, MT_COEXCFG0_COEX_EN); + + mt76_set(dev, MT_EXT_CCA_CFG, 0x0000f000); + mt76_clear(dev, MT_TX_ALC_CFG_4, BIT(31)); + + mt76_wr(dev, MT_RF_BYPASS_0, 0x06000000); + mt76_wr(dev, MT_RF_SETTING_0, 0x08800000); + usleep_range(5000, 10000); + mt76_wr(dev, MT_RF_BYPASS_0, 0x00000000); + + mt76_wr(dev, MT_MCU_CLOCK_CTL, 0x1401); + mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN); + + mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(macaddr)); + mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(macaddr + 4)); + + mt76_wr(dev, MT_MAC_BSSID_DW0, get_unaligned_le32(macaddr)); + mt76_wr(dev, MT_MAC_BSSID_DW1, get_unaligned_le16(macaddr + 4) | + FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */ + MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT); + + /* Fire a pre-TBTT interrupt 8 ms before TBTT */ + mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT, + 8 << 4); + mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER, + MT_DFS_GP_INTERVAL); + mt76_wr(dev, MT_INT_TIMER_EN, 0); + + mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff); + if (!hard) + return 0; + + for (i = 0; i < 256 / 32; i++) + mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0); + + for (i = 0; i < 256; i++) + mt76x2_mac_wcid_setup(dev, i, 0, NULL); + + for (i = 0; i < 16; i++) + for (k = 0; k < 4; k++) + mt76x2_mac_shared_key_setup(dev, i, k, NULL); + + for (i = 0; i < 8; i++) { + mt76x2_mac_set_bssid(dev, i, null_addr); + mt76x2_mac_set_beacon(dev, i, NULL); + } + + for (i = 0; i < 16; i++) + mt76_rr(dev, MT_TX_STAT_FIFO); + + mt76_set(dev, MT_MAC_APC_BSSID_H(0), MT_MAC_APC_BSSID0_H_EN); + + mt76_wr(dev, MT_CH_TIME_CFG, + MT_CH_TIME_CFG_TIMER_EN | + MT_CH_TIME_CFG_TX_AS_BUSY | + MT_CH_TIME_CFG_RX_AS_BUSY | + MT_CH_TIME_CFG_NAV_AS_BUSY | + MT_CH_TIME_CFG_EIFS_AS_BUSY | + FIELD_PREP(MT_CH_TIME_CFG_CH_TIMER_CLR, 1)); + + mt76x2_init_beacon_offsets(dev); + + mt76x2_set_tx_ackto(dev); + + return 0; +} + +int mt76x2_mac_start(struct mt76x2_dev *dev) +{ + int i; + + for (i = 0; i < 16; i++) + mt76_rr(dev, MT_TX_AGG_CNT(i)); + + for (i = 0; i < 16; i++) + mt76_rr(dev, MT_TX_STAT_FIFO); + + memset(dev->aggr_stats, 0, sizeof(dev->aggr_stats)); + + mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX); + wait_for_wpdma(dev); + usleep_range(50, 100); + + mt76_set(dev, MT_WPDMA_GLO_CFG, + MT_WPDMA_GLO_CFG_TX_DMA_EN | + MT_WPDMA_GLO_CFG_RX_DMA_EN); + + mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); + + mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + + mt76_wr(dev, MT_MAC_SYS_CTRL, + MT_MAC_SYS_CTRL_ENABLE_TX | + MT_MAC_SYS_CTRL_ENABLE_RX); + + mt76x2_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL | + MT_INT_TX_STAT); + + return 0; +} + +void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force) +{ + bool stopped = false; + u32 rts_cfg; + int i; + + mt76_wr(dev, MT_MAC_SYS_CTRL, 0); + + rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG); + mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT); + + /* Wait for MAC to become idle */ + for (i = 0; i < 300; i++) { + if (mt76_rr(dev, MT_MAC_STATUS) & + (MT_MAC_STATUS_RX | MT_MAC_STATUS_TX)) + continue; + + if (mt76_rr(dev, MT_BBP(IBI, 12))) + continue; + + stopped = true; + break; + } + + if (force && !stopped) { + mt76_set(dev, MT_BBP(CORE, 4), BIT(1)); + mt76_clear(dev, MT_BBP(CORE, 4), BIT(1)); + + mt76_set(dev, MT_BBP(CORE, 4), BIT(0)); + mt76_clear(dev, MT_BBP(CORE, 4), BIT(0)); + } + + mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg); +} + +void mt76x2_mac_resume(struct mt76x2_dev *dev) +{ + mt76_wr(dev, MT_MAC_SYS_CTRL, + MT_MAC_SYS_CTRL_ENABLE_TX | + MT_MAC_SYS_CTRL_ENABLE_RX); +} + +static void +mt76x2_power_on_rf_patch(struct mt76x2_dev *dev) +{ + mt76_set(dev, 0x10130, BIT(0) | BIT(16)); + udelay(1); + + mt76_clear(dev, 0x1001c, 0xff); + mt76_set(dev, 0x1001c, 0x30); + + mt76_wr(dev, 0x10014, 0x484f); + udelay(1); + + mt76_set(dev, 0x10130, BIT(17)); + udelay(125); + + mt76_clear(dev, 0x10130, BIT(16)); + udelay(50); + + mt76_set(dev, 0x1014c, BIT(19) | BIT(20)); +} + +static void +mt76x2_power_on_rf(struct mt76x2_dev *dev, int unit) +{ + int shift = unit ? 8 : 0; + + /* Enable RF BG */ + mt76_set(dev, 0x10130, BIT(0) << shift); + udelay(10); + + /* Enable RFDIG LDO/AFE/ABB/ADDA */ + mt76_set(dev, 0x10130, (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift); + udelay(10); + + /* Switch RFDIG power to internal LDO */ + mt76_clear(dev, 0x10130, BIT(2) << shift); + udelay(10); + + mt76x2_power_on_rf_patch(dev); + + mt76_set(dev, 0x530, 0xf); +} + +static void +mt76x2_power_on(struct mt76x2_dev *dev) +{ + u32 val; + + /* Turn on WL MTCMOS */ + mt76_set(dev, MT_WLAN_MTC_CTRL, MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP); + + val = MT_WLAN_MTC_CTRL_STATE_UP | + MT_WLAN_MTC_CTRL_PWR_ACK | + MT_WLAN_MTC_CTRL_PWR_ACK_S; + + mt76_poll(dev, MT_WLAN_MTC_CTRL, val, val, 1000); + + mt76_clear(dev, MT_WLAN_MTC_CTRL, 0x7f << 16); + udelay(10); + + mt76_clear(dev, MT_WLAN_MTC_CTRL, 0xf << 24); + udelay(10); + + mt76_set(dev, MT_WLAN_MTC_CTRL, 0xf << 24); + mt76_clear(dev, MT_WLAN_MTC_CTRL, 0xfff); + + /* Turn on AD/DA power down */ + mt76_clear(dev, 0x11204, BIT(3)); + + /* WLAN function enable */ + mt76_set(dev, 0x10080, BIT(0)); + + /* Release BBP software reset */ + mt76_clear(dev, 0x10064, BIT(18)); + + mt76x2_power_on_rf(dev, 0); + mt76x2_power_on_rf(dev, 1); +} + +void mt76x2_set_tx_ackto(struct mt76x2_dev *dev) +{ + u8 ackto, sifs, slottime = dev->slottime; + + slottime += 3 * dev->coverage_class; + + sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG, + MT_XIFS_TIME_CFG_OFDM_SIFS); + + ackto = slottime + sifs; + mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG, + MT_TX_TIMEOUT_CFG_ACKTO, ackto); +} + +static void +mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable) +{ + u32 val = mt76_rr(dev, MT_WLAN_FUN_CTRL); + + if (enable) + val |= (MT_WLAN_FUN_CTRL_WLAN_EN | + MT_WLAN_FUN_CTRL_WLAN_CLK_EN); + else + val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN | + MT_WLAN_FUN_CTRL_WLAN_CLK_EN); + + mt76_wr(dev, MT_WLAN_FUN_CTRL, val); + udelay(20); +} + +static void +mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable) +{ + u32 val; + + val = mt76_rr(dev, MT_WLAN_FUN_CTRL); + + val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL; + + if (val & MT_WLAN_FUN_CTRL_WLAN_EN) { + val |= MT_WLAN_FUN_CTRL_WLAN_RESET_RF; + mt76_wr(dev, MT_WLAN_FUN_CTRL, val); + udelay(20); + + val &= ~MT_WLAN_FUN_CTRL_WLAN_RESET_RF; + } + + mt76_wr(dev, MT_WLAN_FUN_CTRL, val); + udelay(20); + + mt76x2_set_wlan_state(dev, enable); +} + +int mt76x2_init_hardware(struct mt76x2_dev *dev) +{ + static const u16 beacon_offsets[16] = { + /* 1024 byte per beacon */ + 0xc000, + 0xc400, + 0xc800, + 0xcc00, + 0xd000, + 0xd400, + 0xd800, + 0xdc00, + + /* BSS idx 8-15 not used for beacons */ + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + }; + u32 val; + int ret; + + dev->beacon_offsets = beacon_offsets; + tasklet_init(&dev->pre_tbtt_tasklet, mt76x2_pre_tbtt_tasklet, + (unsigned long) dev); + + dev->chainmask = 0x202; + dev->global_wcid.idx = 255; + dev->global_wcid.hw_key_idx = -1; + dev->slottime = 9; + + val = mt76_rr(dev, MT_WPDMA_GLO_CFG); + val &= MT_WPDMA_GLO_CFG_DMA_BURST_SIZE | + MT_WPDMA_GLO_CFG_BIG_ENDIAN | + MT_WPDMA_GLO_CFG_HDR_SEG_LEN; + val |= MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE; + mt76_wr(dev, MT_WPDMA_GLO_CFG, val); + + mt76x2_reset_wlan(dev, true); + mt76x2_power_on(dev); + + ret = mt76x2_eeprom_init(dev); + if (ret) + return ret; + + ret = mt76x2_mac_reset(dev, true); + if (ret) + return ret; + + ret = mt76x2_dma_init(dev); + if (ret) + return ret; + + set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); + ret = mt76x2_mac_start(dev); + if (ret) + return ret; + + ret = mt76x2_mcu_init(dev); + if (ret) + return ret; + + mt76x2_mac_stop(dev, false); + dev->rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); + + return 0; +} + +void mt76x2_stop_hardware(struct mt76x2_dev *dev) +{ + cancel_delayed_work_sync(&dev->cal_work); + cancel_delayed_work_sync(&dev->mac_work); + mt76x2_mcu_set_radio_state(dev, false); + mt76x2_mac_stop(dev, false); +} + +void mt76x2_cleanup(struct mt76x2_dev *dev) +{ + mt76x2_stop_hardware(dev); + mt76x2_dma_cleanup(dev); + mt76x2_mcu_cleanup(dev); +} + +struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) +{ + static const struct mt76_driver_ops drv_ops = { + .txwi_size = sizeof(struct mt76x2_txwi), + .update_survey = mt76x2_update_channel, + .tx_prepare_skb = mt76x2_tx_prepare_skb, + .tx_complete_skb = mt76x2_tx_complete_skb, + .rx_skb = mt76x2_queue_rx_skb, + .rx_poll_complete = mt76x2_rx_poll_complete, + }; + struct ieee80211_hw *hw; + struct mt76x2_dev *dev; + + hw = ieee80211_alloc_hw(sizeof(*dev), &mt76x2_ops); + if (!hw) + return NULL; + + dev = hw->priv; + dev->mt76.dev = pdev; + dev->mt76.hw = hw; + dev->mt76.drv = &drv_ops; + mutex_init(&dev->mutex); + spin_lock_init(&dev->irq_lock); + + return dev; +} + +static void mt76x2_regd_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct mt76x2_dev *dev = hw->priv; + + dev->dfs_pd.region = request->dfs_region; +} + +#define CCK_RATE(_idx, _rate) { \ + .bitrate = _rate, \ + .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ + .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ + .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ +} + +#define OFDM_RATE(_idx, _rate) { \ + .bitrate = _rate, \ + .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ + .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ +} + +static struct ieee80211_rate mt76x2_rates[] = { + CCK_RATE(0, 10), + CCK_RATE(1, 20), + CCK_RATE(2, 55), + CCK_RATE(3, 110), + OFDM_RATE(0, 60), + OFDM_RATE(1, 90), + OFDM_RATE(2, 120), + OFDM_RATE(3, 180), + OFDM_RATE(4, 240), + OFDM_RATE(5, 360), + OFDM_RATE(6, 480), + OFDM_RATE(7, 540), +}; + +static const struct ieee80211_iface_limit if_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_ADHOC) + }, { + .max = 8, + .types = BIT(NL80211_IFTYPE_STATION) | +#ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | +#endif + BIT(NL80211_IFTYPE_AP) + }, +}; + +static const struct ieee80211_iface_combination if_comb[] = { + { + .limits = if_limits, + .n_limits = ARRAY_SIZE(if_limits), + .max_interfaces = 8, + .num_different_channels = 1, + .beacon_int_infra_match = true, + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), + } +}; + +static void mt76x2_led_set_config(struct mt76_dev *mt76, u8 delay_on, + u8 delay_off) +{ + struct mt76x2_dev *dev = container_of(mt76, struct mt76x2_dev, + mt76); + u32 val; + + val = MT_LED_STATUS_DURATION(0xff) | + MT_LED_STATUS_OFF(delay_off) | + MT_LED_STATUS_ON(delay_on); + + mt76_wr(dev, MT_LED_S0(mt76->led_pin), val); + mt76_wr(dev, MT_LED_S1(mt76->led_pin), val); + + val = MT_LED_CTRL_REPLAY(mt76->led_pin) | + MT_LED_CTRL_KICK(mt76->led_pin); + if (mt76->led_al) + val |= MT_LED_CTRL_POLARITY(mt76->led_pin); + mt76_wr(dev, MT_LED_CTRL, val); +} + +static int mt76x2_led_set_blink(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev, + led_cdev); + u8 delta_on, delta_off; + + delta_off = max_t(u8, *delay_off / 10, 1); + delta_on = max_t(u8, *delay_on / 10, 1); + + mt76x2_led_set_config(mt76, delta_on, delta_off); + return 0; +} + +static void mt76x2_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev, + led_cdev); + + if (!brightness) + mt76x2_led_set_config(mt76, 0, 0xff); + else + mt76x2_led_set_config(mt76, 0xff, 0); +} + +int mt76x2_register_device(struct mt76x2_dev *dev) +{ + struct ieee80211_hw *hw = mt76_hw(dev); + struct wiphy *wiphy = hw->wiphy; + void *status_fifo; + int fifo_size; + int i, ret; + + fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x2_tx_status)); + status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL); + if (!status_fifo) + return -ENOMEM; + + kfifo_init(&dev->txstatus_fifo, status_fifo, fifo_size); + + ret = mt76x2_init_hardware(dev); + if (ret) + return ret; + + hw->queues = 4; + hw->max_rates = 1; + hw->max_report_rates = 7; + hw->max_rate_tries = 1; + hw->extra_tx_headroom = 2; + + hw->sta_data_size = sizeof(struct mt76x2_sta); + hw->vif_data_size = sizeof(struct mt76x2_vif); + + for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) { + u8 *addr = dev->macaddr_list[i].addr; + + memcpy(addr, dev->mt76.macaddr, ETH_ALEN); + + if (!i) + continue; + + addr[0] |= BIT(1); + addr[0] ^= ((i - 1) << 2); + } + wiphy->addresses = dev->macaddr_list; + wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list); + + wiphy->iface_combinations = if_comb; + wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); + + wiphy->reg_notifier = mt76x2_regd_notifier; + + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); + + ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); + INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate); + INIT_DELAYED_WORK(&dev->mac_work, mt76x2_mac_work); + + dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; + dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; + + mt76x2_dfs_init_detector(dev); + + /* init led callbacks */ + dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; + dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; + + ret = mt76_register_device(&dev->mt76, true, mt76x2_rates, + ARRAY_SIZE(mt76x2_rates)); + if (ret) + goto fail; + + mt76x2_init_debugfs(dev); + + return 0; + +fail: + mt76x2_stop_hardware(dev); + return ret; +} + + diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c new file mode 100644 index 000000000000..39fc1d7b65ce --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -0,0 +1,755 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/delay.h> +#include "mt76x2.h" +#include "mt76x2_mcu.h" +#include "mt76x2_eeprom.h" +#include "mt76x2_trace.h" + +void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr) +{ + idx &= 7; + mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr)); + mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR, + get_unaligned_le16(addr + 4)); +} + +static void +mt76x2_mac_process_rate(struct ieee80211_rx_status *status, u16 rate) +{ + u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); + + switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { + case MT_PHY_TYPE_OFDM: + if (idx >= 8) + idx = 0; + + if (status->band == NL80211_BAND_2GHZ) + idx += 4; + + status->rate_idx = idx; + return; + case MT_PHY_TYPE_CCK: + if (idx >= 8) { + idx -= 8; + status->enc_flags |= RX_ENC_FLAG_SHORTPRE; + } + + if (idx >= 4) + idx = 0; + + status->rate_idx = idx; + return; + case MT_PHY_TYPE_HT_GF: + status->enc_flags |= RX_ENC_FLAG_HT_GF; + /* fall through */ + case MT_PHY_TYPE_HT: + status->encoding = RX_ENC_HT; + status->rate_idx = idx; + break; + case MT_PHY_TYPE_VHT: + status->encoding = RX_ENC_VHT; + status->rate_idx = FIELD_GET(MT_RATE_INDEX_VHT_IDX, idx); + status->nss = FIELD_GET(MT_RATE_INDEX_VHT_NSS, idx) + 1; + break; + default: + WARN_ON(1); + return; + } + + if (rate & MT_RXWI_RATE_LDPC) + status->enc_flags |= RX_ENC_FLAG_LDPC; + + if (rate & MT_RXWI_RATE_SGI) + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + + if (rate & MT_RXWI_RATE_STBC) + status->enc_flags |= 1 << RX_ENC_FLAG_STBC_SHIFT; + + switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { + case MT_PHY_BW_20: + break; + case MT_PHY_BW_40: + status->bw = RATE_INFO_BW_40; + break; + case MT_PHY_BW_80: + status->bw = RATE_INFO_BW_80; + break; + default: + break; + } +} + +static __le16 +mt76x2_mac_tx_rate_val(struct mt76x2_dev *dev, + const struct ieee80211_tx_rate *rate, u8 *nss_val) +{ + u16 rateval; + u8 phy, rate_idx; + u8 nss = 1; + u8 bw = 0; + + if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + rate_idx = rate->idx; + nss = 1 + (rate->idx >> 4); + phy = MT_PHY_TYPE_VHT; + if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + bw = 2; + else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + bw = 1; + } else if (rate->flags & IEEE80211_TX_RC_MCS) { + rate_idx = rate->idx; + nss = 1 + (rate->idx >> 3); + phy = MT_PHY_TYPE_HT; + if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD) + phy = MT_PHY_TYPE_HT_GF; + if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + bw = 1; + } else { + const struct ieee80211_rate *r; + int band = dev->mt76.chandef.chan->band; + u16 val; + + r = &mt76_hw(dev)->wiphy->bands[band]->bitrates[rate->idx]; + if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + val = r->hw_value_short; + else + val = r->hw_value; + + phy = val >> 8; + rate_idx = val & 0xff; + bw = 0; + } + + rateval = FIELD_PREP(MT_RXWI_RATE_INDEX, rate_idx); + rateval |= FIELD_PREP(MT_RXWI_RATE_PHY, phy); + rateval |= FIELD_PREP(MT_RXWI_RATE_BW, bw); + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + rateval |= MT_RXWI_RATE_SGI; + + *nss_val = nss; + return cpu_to_le16(rateval); +} + +void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop) +{ + u32 val = mt76_rr(dev, MT_WCID_DROP(idx)); + u32 bit = MT_WCID_DROP_MASK(idx); + + /* prevent unnecessary writes */ + if ((val & bit) != (bit * drop)) + mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); +} + +void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, + const struct ieee80211_tx_rate *rate) +{ + spin_lock_bh(&dev->mt76.lock); + wcid->tx_rate = mt76x2_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); + wcid->tx_rate_set = true; + spin_unlock_bh(&dev->mt76.lock); +} + +void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_sta *sta) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *rate = &info->control.rates[0]; + u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); + u16 txwi_flags = 0; + u8 nss; + s8 txpwr_adj, max_txpwr_adj; + + memset(txwi, 0, sizeof(*txwi)); + + if (wcid) + txwi->wcid = wcid->idx; + else + txwi->wcid = 0xff; + + txwi->pktid = 1; + + spin_lock_bh(&dev->mt76.lock); + if (rate->idx < 0 || !rate->count) { + txwi->rate = wcid->tx_rate; + max_txpwr_adj = wcid->max_txpwr_adj; + nss = wcid->tx_rate_nss; + } else { + txwi->rate = mt76x2_mac_tx_rate_val(dev, rate, &nss); + max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(dev, rate); + } + spin_unlock_bh(&dev->mt76.lock); + + txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, dev->txpower_conf, + max_txpwr_adj); + txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj); + + if (mt76xx_rev(dev) >= MT76XX_REV_E4) + txwi->txstream = 0x13; + else if (mt76xx_rev(dev) >= MT76XX_REV_E3 && + !(txwi->rate & cpu_to_le16(rate_ht_mask))) + txwi->txstream = 0x93; + + if (info->flags & IEEE80211_TX_CTL_LDPC) + txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); + if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) + txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); + if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) + txwi_flags |= MT_TXWI_FLAGS_MMPS; + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) + txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; + if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) + txwi->pktid |= MT_TXWI_PKTID_PROBE; + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { + u8 ba_size = IEEE80211_MIN_AMPDU_BUF; + + ba_size <<= sta->ht_cap.ampdu_factor; + ba_size = min_t(int, 63, ba_size - 1); + if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) + ba_size = 0; + txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); + + txwi_flags |= MT_TXWI_FLAGS_AMPDU | + FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, + sta->ht_cap.ampdu_density); + } + + txwi->flags |= cpu_to_le16(txwi_flags); + txwi->len_ctl = cpu_to_le16(skb->len); +} + +static void mt76x2_remove_hdr_pad(struct sk_buff *skb) +{ + int len = ieee80211_get_hdrlen_from_skb(skb); + + memmove(skb->data + 2, skb->data, len); + skb_pull(skb, 2); +} + +int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, + void *rxi) +{ + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct mt76x2_rxwi *rxwi = rxi; + u32 ctl = le32_to_cpu(rxwi->ctl); + u16 rate = le16_to_cpu(rxwi->rate); + int len; + + if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) + mt76x2_remove_hdr_pad(skb); + + if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_DECRYPT)) { + status->flag |= RX_FLAG_DECRYPTED; + status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; + } + + len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl); + if (WARN_ON_ONCE(len > skb->len)) + return -EINVAL; + + pskb_trim(skb, len); + status->chains = BIT(0) | BIT(1); + status->chain_signal[0] = mt76x2_phy_get_rssi(dev, rxwi->rssi[0], 0); + status->chain_signal[1] = mt76x2_phy_get_rssi(dev, rxwi->rssi[1], 1); + status->signal = max(status->chain_signal[0], status->chain_signal[1]); + status->freq = dev->mt76.chandef.chan->center_freq; + status->band = dev->mt76.chandef.chan->band; + + mt76x2_mac_process_rate(status, rate); + + return 0; +} + +static void +mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, + enum nl80211_band band) +{ + u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); + + txrate->idx = 0; + txrate->flags = 0; + txrate->count = 1; + + switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { + case MT_PHY_TYPE_OFDM: + if (band == NL80211_BAND_2GHZ) + idx += 4; + + txrate->idx = idx; + return; + case MT_PHY_TYPE_CCK: + if (idx >= 8) + idx -= 8; + + txrate->idx = idx; + return; + case MT_PHY_TYPE_HT_GF: + txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD; + /* fall through */ + case MT_PHY_TYPE_HT: + txrate->flags |= IEEE80211_TX_RC_MCS; + txrate->idx = idx; + break; + case MT_PHY_TYPE_VHT: + txrate->flags |= IEEE80211_TX_RC_VHT_MCS; + txrate->idx = idx; + break; + default: + WARN_ON(1); + return; + } + + switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { + case MT_PHY_BW_20: + break; + case MT_PHY_BW_40: + txrate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + break; + case MT_PHY_BW_80: + txrate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + break; + default: + WARN_ON(1); + break; + } + + if (rate & MT_RXWI_RATE_SGI) + txrate->flags |= IEEE80211_TX_RC_SHORT_GI; +} + +static void +mt76x2_mac_fill_tx_status(struct mt76x2_dev *dev, + struct ieee80211_tx_info *info, + struct mt76x2_tx_status *st, int n_frames) +{ + struct ieee80211_tx_rate *rate = info->status.rates; + int cur_idx, last_rate; + int i; + + if (!n_frames) + return; + + last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); + mt76x2_mac_process_tx_rate(&rate[last_rate], st->rate, + dev->mt76.chandef.chan->band); + if (last_rate < IEEE80211_TX_MAX_RATES - 1) + rate[last_rate + 1].idx = -1; + + cur_idx = rate[last_rate].idx + st->retry; + for (i = 0; i <= last_rate; i++) { + rate[i].flags = rate[last_rate].flags; + rate[i].idx = max_t(int, 0, cur_idx - i); + rate[i].count = 1; + } + + if (last_rate > 0) + rate[last_rate - 1].count = st->retry + 1 - last_rate; + + info->status.ampdu_len = n_frames; + info->status.ampdu_ack_len = st->success ? n_frames : 0; + + if (st->pktid & MT_TXWI_PKTID_PROBE) + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; + + if (st->aggr) + info->flags |= IEEE80211_TX_CTL_AMPDU | + IEEE80211_TX_STAT_AMPDU; + + if (!st->ack_req) + info->flags |= IEEE80211_TX_CTL_NO_ACK; + else if (st->success) + info->flags |= IEEE80211_TX_STAT_ACK; +} + +static void +mt76x2_send_tx_status(struct mt76x2_dev *dev, struct mt76x2_tx_status *stat, + u8 *update) +{ + struct ieee80211_tx_info info = {}; + struct ieee80211_sta *sta = NULL; + struct mt76_wcid *wcid = NULL; + struct mt76x2_sta *msta = NULL; + + rcu_read_lock(); + if (stat->wcid < ARRAY_SIZE(dev->wcid)) + wcid = rcu_dereference(dev->wcid[stat->wcid]); + + if (wcid) { + void *priv; + + priv = msta = container_of(wcid, struct mt76x2_sta, wcid); + sta = container_of(priv, struct ieee80211_sta, + drv_priv); + } + + if (msta && stat->aggr) { + u32 stat_val, stat_cache; + + stat_val = stat->rate; + stat_val |= ((u32) stat->retry) << 16; + stat_cache = msta->status.rate; + stat_cache |= ((u32) msta->status.retry) << 16; + + if (*update == 0 && stat_val == stat_cache && + stat->wcid == msta->status.wcid && msta->n_frames < 32) { + msta->n_frames++; + goto out; + } + + mt76x2_mac_fill_tx_status(dev, &info, &msta->status, + msta->n_frames); + + msta->status = *stat; + msta->n_frames = 1; + *update = 0; + } else { + mt76x2_mac_fill_tx_status(dev, &info, stat, 1); + *update = 1; + } + + ieee80211_tx_status_noskb(mt76_hw(dev), sta, &info); + +out: + rcu_read_unlock(); +} + +void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq) +{ + struct mt76x2_tx_status stat = {}; + unsigned long flags; + u8 update = 1; + + if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state)) + return; + + trace_mac_txstat_poll(dev); + + while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) { + u32 stat1, stat2; + + spin_lock_irqsave(&dev->irq_lock, flags); + stat2 = mt76_rr(dev, MT_TX_STAT_FIFO_EXT); + stat1 = mt76_rr(dev, MT_TX_STAT_FIFO); + if (!(stat1 & MT_TX_STAT_FIFO_VALID)) { + spin_unlock_irqrestore(&dev->irq_lock, flags); + break; + } + + spin_unlock_irqrestore(&dev->irq_lock, flags); + + stat.valid = 1; + stat.success = !!(stat1 & MT_TX_STAT_FIFO_SUCCESS); + stat.aggr = !!(stat1 & MT_TX_STAT_FIFO_AGGR); + stat.ack_req = !!(stat1 & MT_TX_STAT_FIFO_ACKREQ); + stat.wcid = FIELD_GET(MT_TX_STAT_FIFO_WCID, stat1); + stat.rate = FIELD_GET(MT_TX_STAT_FIFO_RATE, stat1); + stat.retry = FIELD_GET(MT_TX_STAT_FIFO_EXT_RETRY, stat2); + stat.pktid = FIELD_GET(MT_TX_STAT_FIFO_EXT_PKTID, stat2); + trace_mac_txstat_fetch(dev, &stat); + + if (!irq) { + mt76x2_send_tx_status(dev, &stat, &update); + continue; + } + + kfifo_put(&dev->txstatus_fifo, stat); + } +} + +static void +mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, + void *txwi_ptr) +{ + struct mt76x2_tx_info *txi = mt76x2_skb_tx_info(skb); + struct mt76x2_txwi *txwi = txwi_ptr; + + mt76x2_mac_poll_tx_status(dev, false); + + txi->tries = 0; + txi->jiffies = jiffies; + txi->wcid = txwi->wcid; + txi->pktid = txwi->pktid; + trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid); + mt76x2_tx_complete(dev, skb); +} + +void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev) +{ + struct mt76x2_tx_status stat; + u8 update = 1; + + while (kfifo_get(&dev->txstatus_fifo, &stat)) + mt76x2_send_tx_status(dev, &stat, &update); +} + +void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, + struct mt76_queue_entry *e, bool flush) +{ + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + + if (e->txwi) + mt76x2_mac_queue_txdone(dev, e->skb, &e->txwi->txwi); + else + dev_kfree_skb_any(e->skb); +} + +static enum mt76x2_cipher_type +mt76x2_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) +{ + memset(key_data, 0, 32); + if (!key) + return MT_CIPHER_NONE; + + if (key->keylen > 32) + return MT_CIPHER_NONE; + + memcpy(key_data, key->key, key->keylen); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + return MT_CIPHER_WEP40; + case WLAN_CIPHER_SUITE_WEP104: + return MT_CIPHER_WEP104; + case WLAN_CIPHER_SUITE_TKIP: + return MT_CIPHER_TKIP; + case WLAN_CIPHER_SUITE_CCMP: + return MT_CIPHER_AES_CCMP; + default: + return MT_CIPHER_NONE; + } +} + +void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac) +{ + struct mt76_wcid_addr addr = {}; + u32 attr; + + attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | + FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); + + mt76_wr(dev, MT_WCID_ATTR(idx), attr); + + mt76_wr(dev, MT_WCID_TX_RATE(idx), 0); + mt76_wr(dev, MT_WCID_TX_RATE(idx) + 4, 0); + + if (idx >= 128) + return; + + if (mac) + memcpy(addr.macaddr, mac, ETH_ALEN); + + mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr)); +} + +int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, + struct ieee80211_key_conf *key) +{ + enum mt76x2_cipher_type cipher; + u8 key_data[32]; + u8 iv_data[8]; + + cipher = mt76x2_mac_get_key_info(key, key_data); + if (cipher == MT_CIPHER_NONE && key) + return -EOPNOTSUPP; + + mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PKEY_MODE, cipher); + mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); + + memset(iv_data, 0, sizeof(iv_data)); + if (key) { + mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PAIRWISE, + !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); + iv_data[3] = key->keyidx << 6; + if (cipher >= MT_CIPHER_TKIP) + iv_data[3] |= 0x20; + } + + mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); + + return 0; +} + +int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, + struct ieee80211_key_conf *key) +{ + enum mt76x2_cipher_type cipher; + u8 key_data[32]; + u32 val; + + cipher = mt76x2_mac_get_key_info(key, key_data); + if (cipher == MT_CIPHER_NONE && key) + return -EOPNOTSUPP; + + val = mt76_rr(dev, MT_SKEY_MODE(vif_idx)); + val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); + val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); + mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); + + mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), key_data, + sizeof(key_data)); + + return 0; +} + +static int +mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb) +{ + int beacon_len = dev->beacon_offsets[1] - dev->beacon_offsets[0]; + struct mt76x2_txwi txwi; + + if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x2_txwi))) + return -ENOSPC; + + mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL); + txwi.flags |= cpu_to_le16(MT_TXWI_FLAGS_TS); + + mt76_wr_copy(dev, offset, &txwi, sizeof(txwi)); + offset += sizeof(txwi); + + mt76_wr_copy(dev, offset, skb->data, skb->len); + return 0; +} + +static int +__mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 bcn_idx, struct sk_buff *skb) +{ + int beacon_len = dev->beacon_offsets[1] - dev->beacon_offsets[0]; + int beacon_addr = dev->beacon_offsets[bcn_idx]; + int ret = 0; + int i; + + /* Prevent corrupt transmissions during update */ + mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx)); + + if (skb) { + ret = mt76_write_beacon(dev, beacon_addr, skb); + if (!ret) + dev->beacon_data_mask |= BIT(bcn_idx) & + dev->beacon_mask; + } else { + dev->beacon_data_mask &= ~BIT(bcn_idx); + for (i = 0; i < beacon_len; i += 4) + mt76_wr(dev, beacon_addr + i, 0); + } + + mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask); + + return ret; +} + +int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, + struct sk_buff *skb) +{ + bool force_update = false; + int bcn_idx = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) { + if (vif_idx == i) { + force_update = !!dev->beacons[i] ^ !!skb; + + if (dev->beacons[i]) + dev_kfree_skb(dev->beacons[i]); + + dev->beacons[i] = skb; + __mt76x2_mac_set_beacon(dev, bcn_idx, skb); + } else if (force_update && dev->beacons[i]) { + __mt76x2_mac_set_beacon(dev, bcn_idx, dev->beacons[i]); + } + + bcn_idx += !!dev->beacons[i]; + } + + for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) { + if (!(dev->beacon_data_mask & BIT(i))) + break; + + __mt76x2_mac_set_beacon(dev, i, NULL); + } + + mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N, + bcn_idx - 1); + return 0; +} + +void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val) +{ + u8 old_mask = dev->beacon_mask; + bool en; + u32 reg; + + if (val) { + dev->beacon_mask |= BIT(vif_idx); + } else { + dev->beacon_mask &= ~BIT(vif_idx); + mt76x2_mac_set_beacon(dev, vif_idx, NULL); + } + + if (!!old_mask == !!dev->beacon_mask) + return; + + en = dev->beacon_mask; + + mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en); + reg = MT_BEACON_TIME_CFG_BEACON_TX | + MT_BEACON_TIME_CFG_TBTT_EN | + MT_BEACON_TIME_CFG_TIMER_EN; + mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en); + + if (en) + mt76x2_irq_enable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT); + else + mt76x2_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT); +} + +void mt76x2_update_channel(struct mt76_dev *mdev) +{ + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + struct mt76_channel_state *state; + u32 active, busy; + + state = mt76_channel_state(&dev->mt76, dev->mt76.chandef.chan); + + busy = mt76_rr(dev, MT_CH_BUSY); + active = busy + mt76_rr(dev, MT_CH_IDLE); + + spin_lock_bh(&dev->mt76.cc_lock); + state->cc_busy += busy; + state->cc_active += active; + spin_unlock_bh(&dev->mt76.cc_lock); +} + +void mt76x2_mac_work(struct work_struct *work) +{ + struct mt76x2_dev *dev = container_of(work, struct mt76x2_dev, + mac_work.work); + int i, idx; + + mt76x2_update_channel(&dev->mt76); + for (i = 0, idx = 0; i < 16; i++) { + u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i)); + + dev->aggr_stats[idx++] += val & 0xffff; + dev->aggr_stats[idx++] += val >> 16; + } + + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work, + MT_CALIBRATE_INTERVAL); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h new file mode 100644 index 000000000000..8a8a25e32d5f --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_MAC_H +#define __MT76x2_MAC_H + +#include "mt76.h" + +struct mt76x2_dev; +struct mt76x2_sta; +struct mt76x2_vif; +struct mt76x2_txwi; + +struct mt76x2_tx_status { + u8 valid:1; + u8 success:1; + u8 aggr:1; + u8 ack_req:1; + u8 wcid; + u8 pktid; + u8 retry; + u16 rate; +} __packed __aligned(2); + +struct mt76x2_tx_info { + unsigned long jiffies; + u8 tries; + + u8 wcid; + u8 pktid; + u8 retry; +}; + +struct mt76x2_rxwi { + __le32 rxinfo; + + __le32 ctl; + + __le16 tid_sn; + __le16 rate; + + u8 rssi[4]; + + __le32 bbp_rxinfo[4]; +}; + +#define MT_RXINFO_BA BIT(0) +#define MT_RXINFO_DATA BIT(1) +#define MT_RXINFO_NULL BIT(2) +#define MT_RXINFO_FRAG BIT(3) +#define MT_RXINFO_UNICAST BIT(4) +#define MT_RXINFO_MULTICAST BIT(5) +#define MT_RXINFO_BROADCAST BIT(6) +#define MT_RXINFO_MYBSS BIT(7) +#define MT_RXINFO_CRCERR BIT(8) +#define MT_RXINFO_ICVERR BIT(9) +#define MT_RXINFO_MICERR BIT(10) +#define MT_RXINFO_AMSDU BIT(11) +#define MT_RXINFO_HTC BIT(12) +#define MT_RXINFO_RSSI BIT(13) +#define MT_RXINFO_L2PAD BIT(14) +#define MT_RXINFO_AMPDU BIT(15) +#define MT_RXINFO_DECRYPT BIT(16) +#define MT_RXINFO_BSSIDX3 BIT(17) +#define MT_RXINFO_WAPI_KEY BIT(18) +#define MT_RXINFO_PN_LEN GENMASK(21, 19) +#define MT_RXINFO_SW_FTYPE0 BIT(22) +#define MT_RXINFO_SW_FTYPE1 BIT(23) +#define MT_RXINFO_PROBE_RESP BIT(24) +#define MT_RXINFO_BEACON BIT(25) +#define MT_RXINFO_DISASSOC BIT(26) +#define MT_RXINFO_DEAUTH BIT(27) +#define MT_RXINFO_ACTION BIT(28) +#define MT_RXINFO_TCP_SUM_ERR BIT(30) +#define MT_RXINFO_IP_SUM_ERR BIT(31) + +#define MT_RXWI_CTL_WCID GENMASK(7, 0) +#define MT_RXWI_CTL_KEY_IDX GENMASK(9, 8) +#define MT_RXWI_CTL_BSS_IDX GENMASK(12, 10) +#define MT_RXWI_CTL_UDF GENMASK(15, 13) +#define MT_RXWI_CTL_MPDU_LEN GENMASK(29, 16) +#define MT_RXWI_CTL_EOF BIT(31) + +#define MT_RXWI_TID GENMASK(3, 0) +#define MT_RXWI_SN GENMASK(15, 4) + +#define MT_RXWI_RATE_INDEX GENMASK(5, 0) +#define MT_RXWI_RATE_LDPC BIT(6) +#define MT_RXWI_RATE_BW GENMASK(8, 7) +#define MT_RXWI_RATE_SGI BIT(9) +#define MT_RXWI_RATE_STBC BIT(10) +#define MT_RXWI_RATE_LDPC_EXSYM BIT(11) +#define MT_RXWI_RATE_PHY GENMASK(15, 13) + +#define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0) +#define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4) + +#define MT_TX_PWR_ADJ GENMASK(3, 0) + +enum mt76x2_phy_bandwidth { + MT_PHY_BW_20, + MT_PHY_BW_40, + MT_PHY_BW_80, +}; + +#define MT_TXWI_FLAGS_FRAG BIT(0) +#define MT_TXWI_FLAGS_MMPS BIT(1) +#define MT_TXWI_FLAGS_CFACK BIT(2) +#define MT_TXWI_FLAGS_TS BIT(3) +#define MT_TXWI_FLAGS_AMPDU BIT(4) +#define MT_TXWI_FLAGS_MPDU_DENSITY GENMASK(7, 5) +#define MT_TXWI_FLAGS_TXOP GENMASK(9, 8) +#define MT_TXWI_FLAGS_NDPS BIT(10) +#define MT_TXWI_FLAGS_RTSBWSIG BIT(11) +#define MT_TXWI_FLAGS_NDP_BW GENMASK(13, 12) +#define MT_TXWI_FLAGS_SOUND BIT(14) +#define MT_TXWI_FLAGS_TX_RATE_LUT BIT(15) + +#define MT_TXWI_ACK_CTL_REQ BIT(0) +#define MT_TXWI_ACK_CTL_NSEQ BIT(1) +#define MT_TXWI_ACK_CTL_BA_WINDOW GENMASK(7, 2) + +#define MT_TXWI_PKTID_PROBE BIT(7) + +struct mt76x2_txwi { + __le16 flags; + __le16 rate; + u8 ack_ctl; + u8 wcid; + __le16 len_ctl; + __le32 iv; + __le32 eiv; + u8 aid; + u8 txstream; + u8 ctl2; + u8 pktid; +} __packed __aligned(4); + +static inline struct mt76x2_tx_info * +mt76x2_skb_tx_info(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + return (void *) info->status.status_driver_data; +} + +int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard); +int mt76x2_mac_start(struct mt76x2_dev *dev); +void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force); +void mt76x2_mac_resume(struct mt76x2_dev *dev); +void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr); + +int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, + void *rxi); +void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_sta *sta); +void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac); +int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, + struct ieee80211_key_conf *key); +void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, + const struct ieee80211_tx_rate *rate); +void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop); + +int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, + struct ieee80211_key_conf *key); + +int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, + struct sk_buff *skb); +void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val); + +void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq); +void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev); + +void mt76x2_mac_work(struct work_struct *work); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c new file mode 100644 index 000000000000..2cef48edb275 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76x2.h" + +static int +mt76x2_start(struct ieee80211_hw *hw) +{ + struct mt76x2_dev *dev = hw->priv; + int ret; + + mutex_lock(&dev->mutex); + + ret = mt76x2_mac_start(dev); + if (ret) + goto out; + + ret = mt76x2_phy_start(dev); + if (ret) + goto out; + + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work, + MT_CALIBRATE_INTERVAL); + + set_bit(MT76_STATE_RUNNING, &dev->mt76.state); + +out: + mutex_unlock(&dev->mutex); + return ret; +} + +static void +mt76x2_stop(struct ieee80211_hw *hw) +{ + struct mt76x2_dev *dev = hw->priv; + + mutex_lock(&dev->mutex); + clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); + mt76x2_stop_hardware(dev); + mutex_unlock(&dev->mutex); +} + +static void +mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq) +{ + struct mt76_txq *mtxq; + + if (!txq) + return; + + mtxq = (struct mt76_txq *) txq->drv_priv; + if (txq->sta) { + struct mt76x2_sta *sta; + + sta = (struct mt76x2_sta *) txq->sta->drv_priv; + mtxq->wcid = &sta->wcid; + } else { + struct mt76x2_vif *mvif; + + mvif = (struct mt76x2_vif *) txq->vif->drv_priv; + mtxq->wcid = &mvif->group_wcid; + } + + mt76_txq_init(&dev->mt76, txq); +} + +static int +mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + unsigned int idx = 0; + int ret = 0; + + if (vif->addr[0] & BIT(1)) + idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); + + /* + * Client mode typically only has one configurable BSSID register, + * which is used for bssidx=0. This is linked to the MAC address. + * Since mac80211 allows changing interface types, and we cannot + * force the use of the primary MAC address for a station mode + * interface, we need some other way of configuring a per-interface + * remote BSSID. + * The hardware provides an AP-Client feature, where bssidx 0-7 are + * used for AP mode and bssidx 8-15 for client mode. + * We shift the station interface bss index by 8 to force the + * hardware to recognize the BSSID. + * The resulting bssidx mismatch for unicast frames is ignored by hw. + */ + if (vif->type == NL80211_IFTYPE_STATION) + idx += 8; + + mvif->idx = idx; + mvif->group_wcid.idx = 254 - idx; + mvif->group_wcid.hw_key_idx = -1; + mt76x2_txq_init(dev, vif->txq); + + return ret; +} + +static void +mt76x2_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct mt76x2_dev *dev = hw->priv; + + mt76_txq_remove(&dev->mt76, vif->txq); +} + +static int +mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef) +{ + int ret; + + mt76_set_channel(&dev->mt76); + + tasklet_disable(&dev->pre_tbtt_tasklet); + cancel_delayed_work_sync(&dev->cal_work); + + mt76x2_mac_stop(dev, true); + ret = mt76x2_phy_set_channel(dev, chandef); + + /* channel cycle counters read-and-clear */ + mt76_rr(dev, MT_CH_IDLE); + mt76_rr(dev, MT_CH_BUSY); + + mt76x2_dfs_init_params(dev); + + mt76x2_mac_resume(dev); + tasklet_enable(&dev->pre_tbtt_tasklet); + + return ret; +} + +static int +mt76x2_config(struct ieee80211_hw *hw, u32 changed) +{ + struct mt76x2_dev *dev = hw->priv; + int ret = 0; + + mutex_lock(&dev->mutex); + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + dev->txpower_conf = hw->conf.power_level * 2; + + if (test_bit(MT76_STATE_RUNNING, &dev->mt76.state)) { + mt76x2_phy_set_txpower(dev); + mt76x2_tx_set_txpwr_auto(dev, dev->txpower_conf); + } + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + ieee80211_stop_queues(hw); + ret = mt76x2_set_channel(dev, &hw->conf.chandef); + ieee80211_wake_queues(hw); + } + + mutex_unlock(&dev->mutex); + + return ret; +} + +static void +mt76x2_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, + unsigned int *total_flags, u64 multicast) +{ + struct mt76x2_dev *dev = hw->priv; + u32 flags = 0; + +#define MT76_FILTER(_flag, _hw) do { \ + flags |= *total_flags & FIF_##_flag; \ + dev->rxfilter &= ~(_hw); \ + dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \ + } while (0) + + mutex_lock(&dev->mutex); + + dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; + + MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); + MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); + MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | + MT_RX_FILTR_CFG_CTS | + MT_RX_FILTR_CFG_CFEND | + MT_RX_FILTR_CFG_CFACK | + MT_RX_FILTR_CFG_BA | + MT_RX_FILTR_CFG_CTRL_RSV); + MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); + + *total_flags = flags; + mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + + mutex_unlock(&dev->mutex); +} + +static void +mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, u32 changed) +{ + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + + mutex_lock(&dev->mutex); + + if (changed & BSS_CHANGED_BSSID) + mt76x2_mac_set_bssid(dev, mvif->idx, info->bssid); + + if (changed & BSS_CHANGED_BEACON_INT) + mt76_rmw_field(dev, MT_BEACON_TIME_CFG, + MT_BEACON_TIME_CFG_INTVAL, + info->beacon_int << 4); + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + tasklet_disable(&dev->pre_tbtt_tasklet); + mt76x2_mac_set_beacon_enable(dev, mvif->idx, + info->enable_beacon); + tasklet_enable(&dev->pre_tbtt_tasklet); + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + int slottime = info->use_short_slot ? 9 : 20; + + dev->slottime = slottime; + mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG, + MT_BKOFF_SLOT_CFG_SLOTTIME, slottime); + } + + mutex_unlock(&dev->mutex); +} + +static int +mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + int ret = 0; + int idx = 0; + int i; + + mutex_lock(&dev->mutex); + + idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); + if (idx < 0) { + ret = -ENOSPC; + goto out; + } + + msta->wcid.idx = idx; + msta->wcid.hw_key_idx = -1; + mt76x2_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); + mt76x2_mac_wcid_set_drop(dev, idx, false); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + mt76x2_txq_init(dev, sta->txq[i]); + + rcu_assign_pointer(dev->wcid[idx], &msta->wcid); + +out: + mutex_unlock(&dev->mutex); + + return ret; +} + +static int +mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + int idx = msta->wcid.idx; + int i; + + mutex_lock(&dev->mutex); + rcu_assign_pointer(dev->wcid[idx], NULL); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + mt76_txq_remove(&dev->mt76, sta->txq[i]); + mt76x2_mac_wcid_set_drop(dev, idx, true); + mt76_wcid_free(dev->wcid_mask, idx); + mt76x2_mac_wcid_setup(dev, idx, 0, NULL); + mutex_unlock(&dev->mutex); + + return 0; +} + +static void +mt76x2_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, struct ieee80211_sta *sta) +{ + struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x2_dev *dev = hw->priv; + int idx = msta->wcid.idx; + + switch (cmd) { + case STA_NOTIFY_SLEEP: + mt76x2_mac_wcid_set_drop(dev, idx, true); + mt76_stop_tx_queues(&dev->mt76, sta, true); + break; + case STA_NOTIFY_AWAKE: + mt76x2_mac_wcid_set_drop(dev, idx, false); + break; + } +} + +static int +mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x2_sta *msta; + struct mt76_wcid *wcid; + int idx = key->keyidx; + int ret; + + /* + * The hardware does not support per-STA RX GTK, fall back + * to software mode for these. + */ + if ((vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + msta = sta ? (struct mt76x2_sta *) sta->drv_priv : NULL; + wcid = msta ? &msta->wcid : &mvif->group_wcid; + + if (cmd == SET_KEY) { + key->hw_key_idx = wcid->idx; + wcid->hw_key_idx = idx; + } else { + if (idx == wcid->hw_key_idx) + wcid->hw_key_idx = -1; + + key = NULL; + } + + if (!msta) { + if (key || wcid->hw_key_idx == idx) { + ret = mt76x2_mac_wcid_set_key(dev, wcid->idx, key); + if (ret) + return ret; + } + + return mt76x2_mac_shared_key_setup(dev, mvif->idx, idx, key); + } + + return mt76x2_mac_wcid_set_key(dev, msta->wcid.idx, key); +} + +static int +mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct mt76x2_dev *dev = hw->priv; + u8 cw_min = 5, cw_max = 10; + u32 val; + + if (params->cw_min) + cw_min = fls(params->cw_min); + if (params->cw_max) + cw_max = fls(params->cw_max); + + val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) | + FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | + FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | + FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); + mt76_wr(dev, MT_EDCA_CFG_AC(queue), val); + + val = mt76_rr(dev, MT_WMM_TXOP(queue)); + val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(queue)); + val |= params->txop << MT_WMM_TXOP_SHIFT(queue); + mt76_wr(dev, MT_WMM_TXOP(queue), val); + + val = mt76_rr(dev, MT_WMM_AIFSN); + val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(queue)); + val |= params->aifs << MT_WMM_AIFSN_SHIFT(queue); + mt76_wr(dev, MT_WMM_AIFSN, val); + + val = mt76_rr(dev, MT_WMM_CWMIN); + val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(queue)); + val |= cw_min << MT_WMM_CWMIN_SHIFT(queue); + mt76_wr(dev, MT_WMM_CWMIN, val); + + val = mt76_rr(dev, MT_WMM_CWMAX); + val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(queue)); + val |= cw_max << MT_WMM_CWMAX_SHIFT(queue); + mt76_wr(dev, MT_WMM_CWMAX, val); + + return 0; +} + +static void +mt76x2_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const u8 *mac) +{ + struct mt76x2_dev *dev = hw->priv; + + tasklet_disable(&dev->pre_tbtt_tasklet); + set_bit(MT76_SCANNING, &dev->mt76.state); +} + +static void +mt76x2_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct mt76x2_dev *dev = hw->priv; + + clear_bit(MT76_SCANNING, &dev->mt76.state); + tasklet_enable(&dev->pre_tbtt_tasklet); + mt76_txq_schedule_all(&dev->mt76); +} + +static void +mt76x2_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop) +{ +} + +static int +mt76x2_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm) +{ + struct mt76x2_dev *dev = hw->priv; + + *dbm = dev->txpower_cur / 2; + return 0; +} + +static int +mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + enum ieee80211_ampdu_mlme_action action = params->action; + struct ieee80211_sta *sta = params->sta; + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct ieee80211_txq *txq = sta->txq[params->tid]; + struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv; + u16 tid = params->tid; + u16 *ssn = ¶ms->ssn; + + if (!txq) + return -EINVAL; + + switch (action) { + case IEEE80211_AMPDU_RX_START: + mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); + break; + case IEEE80211_AMPDU_RX_STOP: + mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, + BIT(16 + tid)); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + mtxq->aggr = true; + mtxq->send_bar = false; + ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); + break; + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + mtxq->aggr = false; + ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); + break; + case IEEE80211_AMPDU_TX_START: + mtxq->agg_ssn = *ssn << 4; + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_STOP_CONT: + mtxq->aggr = false; + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + } + + return 0; +} + +static void +mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76x2_dev *dev = hw->priv; + struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); + struct ieee80211_tx_rate rate = {}; + + if (!rates) + return; + + rate.idx = rates->rate[0].idx; + rate.flags = rates->rate[0].flags; + mt76x2_mac_wcid_set_rate(dev, &msta->wcid, &rate); + msta->wcid.max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(dev, &rate); +} + +static void mt76x2_set_coverage_class(struct ieee80211_hw *hw, + s16 coverage_class) +{ + struct mt76x2_dev *dev = hw->priv; + + mutex_lock(&dev->mutex); + dev->coverage_class = coverage_class; + mt76x2_set_tx_ackto(dev); + mutex_unlock(&dev->mutex); +} + +const struct ieee80211_ops mt76x2_ops = { + .tx = mt76x2_tx, + .start = mt76x2_start, + .stop = mt76x2_stop, + .add_interface = mt76x2_add_interface, + .remove_interface = mt76x2_remove_interface, + .config = mt76x2_config, + .configure_filter = mt76x2_configure_filter, + .bss_info_changed = mt76x2_bss_info_changed, + .sta_add = mt76x2_sta_add, + .sta_remove = mt76x2_sta_remove, + .sta_notify = mt76x2_sta_notify, + .set_key = mt76x2_set_key, + .conf_tx = mt76x2_conf_tx, + .sw_scan_start = mt76x2_sw_scan, + .sw_scan_complete = mt76x2_sw_scan_complete, + .flush = mt76x2_flush, + .ampdu_action = mt76x2_ampdu_action, + .get_txpower = mt76x2_get_txpower, + .wake_tx_queue = mt76_wake_tx_queue, + .sta_rate_tbl_update = mt76x2_sta_rate_tbl_update, + .release_buffered_frames = mt76_release_buffered_frames, + .set_coverage_class = mt76x2_set_coverage_class, + .get_survey = mt76_get_survey, +}; + diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c new file mode 100644 index 000000000000..d45737ee1412 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/kernel.h> +#include <linux/firmware.h> +#include <linux/delay.h> + +#include "mt76x2.h" +#include "mt76x2_mcu.h" +#include "mt76x2_dma.h" +#include "mt76x2_eeprom.h" + +struct mt76x2_fw_header { + __le32 ilm_len; + __le32 dlm_len; + __le16 build_ver; + __le16 fw_ver; + u8 pad[4]; + char build_time[16]; +}; + +struct mt76x2_patch_header { + char build_time[16]; + char platform[4]; + char hw_version[4]; + char patch_version[4]; + u8 pad[2]; +}; + +static struct sk_buff *mt76x2_mcu_msg_alloc(const void *data, int len) +{ + struct sk_buff *skb; + + skb = alloc_skb(len, GFP_KERNEL); + memcpy(skb_put(skb, len), data, len); + + return skb; +} + +static struct sk_buff * +mt76x2_mcu_get_response(struct mt76x2_dev *dev, unsigned long expires) +{ + unsigned long timeout; + + if (!time_is_after_jiffies(expires)) + return NULL; + + timeout = expires - jiffies; + wait_event_timeout(dev->mcu.wait, !skb_queue_empty(&dev->mcu.res_q), + timeout); + return skb_dequeue(&dev->mcu.res_q); +} + +static int +mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, + enum mcu_cmd cmd) +{ + unsigned long expires = jiffies + HZ; + int ret; + u8 seq; + + if (!skb) + return -EINVAL; + + mutex_lock(&dev->mcu.mutex); + + seq = ++dev->mcu.msg_seq & 0xf; + if (!seq) + seq = ++dev->mcu.msg_seq & 0xf; + + ret = mt76x2_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); + if (ret) + goto out; + + while (1) { + u32 *rxfce; + bool check_seq = false; + + skb = mt76x2_mcu_get_response(dev, expires); + if (!skb) { + dev_err(dev->mt76.dev, + "MCU message %d (seq %d) timed out\n", cmd, + seq); + ret = -ETIMEDOUT; + break; + } + + rxfce = (u32 *) skb->cb; + + if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce)) + check_seq = true; + + dev_kfree_skb(skb); + if (check_seq) + break; + } + +out: + mutex_unlock(&dev->mcu.mutex); + + return ret; +} + +static int +mt76pci_load_rom_patch(struct mt76x2_dev *dev) +{ + const struct firmware *fw = NULL; + struct mt76x2_patch_header *hdr; + bool rom_protect = !is_mt7612(dev); + int len, ret = 0; + __le32 *cur; + u32 patch_mask, patch_reg; + + if (rom_protect && !mt76_poll(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) { + dev_err(dev->mt76.dev, + "Could not get hardware semaphore for ROM PATCH\n"); + return -ETIMEDOUT; + } + + if (mt76xx_rev(dev) >= MT76XX_REV_E3) { + patch_mask = BIT(0); + patch_reg = MT_MCU_CLOCK_CTL; + } else { + patch_mask = BIT(1); + patch_reg = MT_MCU_COM_REG0; + } + + if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) { + dev_info(dev->mt76.dev, "ROM patch already applied\n"); + goto out; + } + + ret = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev); + if (ret) + goto out; + + if (!fw || !fw->data || fw->size <= sizeof(*hdr)) { + ret = -EIO; + dev_err(dev->mt76.dev, "Failed to load firmware\n"); + goto out; + } + + hdr = (struct mt76x2_patch_header *) fw->data; + dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time); + + mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET); + + cur = (__le32 *) (fw->data + sizeof(*hdr)); + len = fw->size - sizeof(*hdr); + mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len); + + mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); + + /* Trigger ROM */ + mt76_wr(dev, MT_MCU_INT_LEVEL, 4); + + if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 2000)) { + dev_err(dev->mt76.dev, "Failed to load ROM patch\n"); + ret = -ETIMEDOUT; + } + +out: + /* release semaphore */ + if (rom_protect) + mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1); + release_firmware(fw); + return ret; +} + +static int +mt76pci_load_firmware(struct mt76x2_dev *dev) +{ + const struct firmware *fw; + const struct mt76x2_fw_header *hdr; + int i, len, ret; + __le32 *cur; + u32 offset, val; + + ret = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev); + if (ret) + return ret; + + if (!fw || !fw->data || fw->size < sizeof(*hdr)) + goto error; + + hdr = (const struct mt76x2_fw_header *) fw->data; + + len = sizeof(*hdr); + len += le32_to_cpu(hdr->ilm_len); + len += le32_to_cpu(hdr->dlm_len); + + if (fw->size != len) + goto error; + + val = le16_to_cpu(hdr->fw_ver); + dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n", + (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf); + + val = le16_to_cpu(hdr->build_ver); + dev_info(dev->mt76.dev, "Build: %x\n", val); + dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); + + cur = (__le32 *) (fw->data + sizeof(*hdr)); + len = le32_to_cpu(hdr->ilm_len); + + mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET); + mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len); + + cur += len / sizeof(*cur); + len = le32_to_cpu(hdr->dlm_len); + + if (mt76xx_rev(dev) >= MT76XX_REV_E3) + offset = MT_MCU_DLM_ADDR_E3; + else + offset = MT_MCU_DLM_ADDR; + + mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET); + mt76_wr_copy(dev, offset, cur, len); + + mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); + + val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_2); + if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1) + mt76_set(dev, MT_MCU_COM_REG0, BIT(30)); + + /* trigger firmware */ + mt76_wr(dev, MT_MCU_INT_LEVEL, 2); + for (i = 200; i > 0; i--) { + val = mt76_rr(dev, MT_MCU_COM_REG0); + + if (val & 1) + break; + + msleep(10); + } + + if (!i) { + dev_err(dev->mt76.dev, "Firmware failed to start\n"); + release_firmware(fw); + return -ETIMEDOUT; + } + + dev_info(dev->mt76.dev, "Firmware running!\n"); + + release_firmware(fw); + + return ret; + +error: + dev_err(dev->mt76.dev, "Invalid firmware\n"); + release_firmware(fw); + return -ENOENT; +} + +static int +mt76x2_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, + u32 val) +{ + struct sk_buff *skb; + struct { + __le32 id; + __le32 value; + } __packed __aligned(4) msg = { + .id = cpu_to_le32(func), + .value = cpu_to_le32(val), + }; + + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + return mt76x2_mcu_msg_send(dev, skb, CMD_FUN_SET_OP); +} + +int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, + u8 channel) +{ + struct sk_buff *skb; + struct { + u8 cr_mode; + u8 temp; + u8 ch; + u8 _pad0; + + __le32 cfg; + } __packed __aligned(4) msg = { + .cr_mode = type, + .temp = temp_level, + .ch = channel, + }; + u32 val; + + val = BIT(31); + val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; + val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00; + msg.cfg = cpu_to_le32(val); + + /* first set the channel without the extension channel info */ + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + return mt76x2_mcu_msg_send(dev, skb, CMD_LOAD_CR); +} + +int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, + u8 bw_index, bool scan) +{ + struct sk_buff *skb; + struct { + u8 idx; + u8 scan; + u8 bw; + u8 _pad0; + + __le16 chainmask; + u8 ext_chan; + u8 _pad1; + + } __packed __aligned(4) msg = { + .idx = channel, + .scan = scan, + .bw = bw, + .chainmask = cpu_to_le16(dev->chainmask), + }; + + /* first set the channel without the extension channel info */ + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + mt76x2_mcu_msg_send(dev, skb, CMD_SWITCH_CHANNEL_OP); + + usleep_range(5000, 10000); + + msg.ext_chan = 0xe0 + bw_index; + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + return mt76x2_mcu_msg_send(dev, skb, CMD_SWITCH_CHANNEL_OP); +} + +int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on) +{ + struct sk_buff *skb; + struct { + __le32 mode; + __le32 level; + } __packed __aligned(4) msg = { + .mode = cpu_to_le32(on ? RADIO_ON : RADIO_OFF), + .level = cpu_to_le32(0), + }; + + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + return mt76x2_mcu_msg_send(dev, skb, CMD_POWER_SAVING_OP); +} + +int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, + u32 param) +{ + struct sk_buff *skb; + struct { + __le32 id; + __le32 value; + } __packed __aligned(4) msg = { + .id = cpu_to_le32(type), + .value = cpu_to_le32(param), + }; + int ret; + + mt76_clear(dev, MT_MCU_COM_REG0, BIT(31)); + + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + ret = mt76x2_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP); + if (ret) + return ret; + + if (WARN_ON(!mt76_poll_msec(dev, MT_MCU_COM_REG0, + BIT(31), BIT(31), 100))) + return -ETIMEDOUT; + + return 0; +} + +int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, + struct mt76x2_tssi_comp *tssi_data) +{ + struct sk_buff *skb; + struct { + __le32 id; + struct mt76x2_tssi_comp data; + } __packed __aligned(4) msg = { + .id = cpu_to_le32(MCU_CAL_TSSI_COMP), + .data = *tssi_data, + }; + + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + return mt76x2_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP); +} + +int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, + bool force) +{ + struct sk_buff *skb; + struct { + __le32 channel; + __le32 gain_val; + } __packed __aligned(4) msg = { + .channel = cpu_to_le32(channel), + .gain_val = cpu_to_le32(gain), + }; + + if (force) + msg.channel |= cpu_to_le32(BIT(31)); + + skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); + return mt76x2_mcu_msg_send(dev, skb, CMD_INIT_GAIN_OP); +} + +int mt76x2_mcu_init(struct mt76x2_dev *dev) +{ + int ret; + + mutex_init(&dev->mcu.mutex); + + ret = mt76pci_load_rom_patch(dev); + if (ret) + return ret; + + ret = mt76pci_load_firmware(dev); + if (ret) + return ret; + + mt76x2_mcu_function_select(dev, Q_SELECT, 1); + return 0; +} + +int mt76x2_mcu_cleanup(struct mt76x2_dev *dev) +{ + struct sk_buff *skb; + + mt76_wr(dev, MT_MCU_INT_LEVEL, 1); + usleep_range(20000, 30000); + + while ((skb = skb_dequeue(&dev->mcu.res_q)) != NULL) + dev_kfree_skb(skb); + + return 0; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h new file mode 100644 index 000000000000..d7a7e83262ce --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_MCU_H +#define __MT76x2_MCU_H + +/* Register definitions */ +#define MT_MCU_CPU_CTL 0x0704 +#define MT_MCU_CLOCK_CTL 0x0708 +#define MT_MCU_RESET_CTL 0x070C +#define MT_MCU_INT_LEVEL 0x0718 +#define MT_MCU_COM_REG0 0x0730 +#define MT_MCU_COM_REG1 0x0734 +#define MT_MCU_COM_REG2 0x0738 +#define MT_MCU_COM_REG3 0x073C +#define MT_MCU_PCIE_REMAP_BASE1 0x0740 +#define MT_MCU_PCIE_REMAP_BASE2 0x0744 +#define MT_MCU_PCIE_REMAP_BASE3 0x0748 +#define MT_MCU_PCIE_REMAP_BASE4 0x074C + +#define MT_LED_CTRL 0x0770 +#define MT_LED_CTRL_REPLAY(_n) BIT(0 + (8 * (_n))) +#define MT_LED_CTRL_POLARITY(_n) BIT(1 + (8 * (_n))) +#define MT_LED_CTRL_TX_BLINK_MODE(_n) BIT(2 + (8 * (_n))) +#define MT_LED_CTRL_KICK(_n) BIT(7 + (8 * (_n))) + +#define MT_LED_TX_BLINK_0 0x0774 +#define MT_LED_TX_BLINK_1 0x0778 + +#define MT_LED_S0_BASE 0x077C +#define MT_LED_S0(_n) (MT_LED_S0_BASE + 8 * (_n)) +#define MT_LED_S1_BASE 0x0780 +#define MT_LED_S1(_n) (MT_LED_S1_BASE + 8 * (_n)) +#define MT_LED_STATUS_OFF_MASK GENMASK(31, 24) +#define MT_LED_STATUS_OFF(_v) (((_v) << __ffs(MT_LED_STATUS_OFF_MASK)) & \ + MT_LED_STATUS_OFF_MASK) +#define MT_LED_STATUS_ON_MASK GENMASK(23, 16) +#define MT_LED_STATUS_ON(_v) (((_v) << __ffs(MT_LED_STATUS_ON_MASK)) & \ + MT_LED_STATUS_ON_MASK) +#define MT_LED_STATUS_DURATION_MASK GENMASK(15, 8) +#define MT_LED_STATUS_DURATION(_v) (((_v) << __ffs(MT_LED_STATUS_DURATION_MASK)) & \ + MT_LED_STATUS_DURATION_MASK) + +#define MT_MCU_SEMAPHORE_00 0x07B0 +#define MT_MCU_SEMAPHORE_01 0x07B4 +#define MT_MCU_SEMAPHORE_02 0x07B8 +#define MT_MCU_SEMAPHORE_03 0x07BC + +#define MT_MCU_ROM_PATCH_OFFSET 0x80000 +#define MT_MCU_ROM_PATCH_ADDR 0x90000 + +#define MT_MCU_ILM_OFFSET 0x80000 +#define MT_MCU_ILM_ADDR 0x80000 + +#define MT_MCU_DLM_OFFSET 0x100000 +#define MT_MCU_DLM_ADDR 0x90000 +#define MT_MCU_DLM_ADDR_E3 0x90800 + +enum mcu_cmd { + CMD_FUN_SET_OP = 1, + CMD_LOAD_CR = 2, + CMD_INIT_GAIN_OP = 3, + CMD_DYNC_VGA_OP = 6, + CMD_TDLS_CH_SW = 7, + CMD_BURST_WRITE = 8, + CMD_READ_MODIFY_WRITE = 9, + CMD_RANDOM_READ = 10, + CMD_BURST_READ = 11, + CMD_RANDOM_WRITE = 12, + CMD_LED_MODE_OP = 16, + CMD_POWER_SAVING_OP = 20, + CMD_WOW_CONFIG = 21, + CMD_WOW_QUERY = 22, + CMD_WOW_FEATURE = 24, + CMD_CARRIER_DETECT_OP = 28, + CMD_RADOR_DETECT_OP = 29, + CMD_SWITCH_CHANNEL_OP = 30, + CMD_CALIBRATION_OP = 31, + CMD_BEACON_OP = 32, + CMD_ANTENNA_OP = 33, +}; + +enum mcu_function { + Q_SELECT = 1, + BW_SETTING = 2, + USB2_SW_DISCONNECT = 2, + USB3_SW_DISCONNECT = 3, + LOG_FW_DEBUG_MSG = 4, + GET_FW_VERSION = 5, +}; + +enum mcu_power_mode { + RADIO_OFF = 0x30, + RADIO_ON = 0x31, + RADIO_OFF_AUTO_WAKEUP = 0x32, + RADIO_OFF_ADVANCE = 0x33, + RADIO_ON_ADVANCE = 0x34, +}; + +enum mcu_calibration { + MCU_CAL_R = 1, + MCU_CAL_TEMP_SENSOR, + MCU_CAL_RXDCOC, + MCU_CAL_RC, + MCU_CAL_SX_LOGEN, + MCU_CAL_LC, + MCU_CAL_TX_LOFT, + MCU_CAL_TXIQ, + MCU_CAL_TSSI, + MCU_CAL_TSSI_COMP, + MCU_CAL_DPD, + MCU_CAL_RXIQC_FI, + MCU_CAL_RXIQC_FD, + MCU_CAL_PWRON, + MCU_CAL_TX_SHAPING, +}; + +enum mt76x2_mcu_cr_mode { + MT_RF_CR, + MT_BBP_CR, + MT_RF_BBP_CR, + MT_HL_TEMP_CR_UPDATE, +}; + +struct mt76x2_tssi_comp { + u8 pa_mode; + u8 cal_mode; + u16 pad; + + u8 slope0; + u8 slope1; + u8 offset0; + u8 offset1; +} __packed __aligned(4); + +int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, + u32 param); +int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, struct mt76x2_tssi_comp *tssi_data); +int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, + bool force); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2_pci.c new file mode 100644 index 000000000000..e66f047ea448 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_pci.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> + +#include "mt76x2.h" +#include "mt76x2_trace.h" + +static const struct pci_device_id mt76pci_device_table[] = { + { PCI_DEVICE(0x14c3, 0x7662) }, + { PCI_DEVICE(0x14c3, 0x7612) }, + { PCI_DEVICE(0x14c3, 0x7602) }, + { }, +}; + +static int +mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct mt76x2_dev *dev; + int ret; + + ret = pcim_enable_device(pdev); + if (ret) + return ret; + + ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); + if (ret) + return ret; + + pci_set_master(pdev); + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + dev = mt76x2_alloc_device(&pdev->dev); + if (!dev) + return -ENOMEM; + + mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); + + dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION); + dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev); + + ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt76x2_irq_handler, + IRQF_SHARED, KBUILD_MODNAME, dev); + if (ret) + goto error; + + ret = mt76x2_register_device(dev); + if (ret) + goto error; + + /* Fix up ASPM configuration */ + + /* RG_SSUSB_G1_CDR_BIR_LTR = 0x9 */ + mt76_rmw_field(dev, 0x15a10, 0x1f << 16, 0x9); + + /* RG_SSUSB_G1_CDR_BIC_LTR = 0xf */ + mt76_rmw_field(dev, 0x15a0c, 0xf << 28, 0xf); + + /* RG_SSUSB_CDR_BR_PE1D = 0x3 */ + mt76_rmw_field(dev, 0x15c58, 0x3 << 6, 0x3); + + return 0; + +error: + ieee80211_free_hw(mt76_hw(dev)); + return ret; +} + +static void +mt76pci_remove(struct pci_dev *pdev) +{ + struct mt76_dev *mdev = pci_get_drvdata(pdev); + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + + mt76_unregister_device(mdev); + mt76x2_cleanup(dev); + ieee80211_free_hw(mdev->hw); +} + +MODULE_DEVICE_TABLE(pci, mt76pci_device_table); +MODULE_FIRMWARE(MT7662_FIRMWARE); +MODULE_FIRMWARE(MT7662_ROM_PATCH); +MODULE_LICENSE("Dual BSD/GPL"); + +static struct pci_driver mt76pci_driver = { + .name = KBUILD_MODNAME, + .id_table = mt76pci_device_table, + .probe = mt76pci_probe, + .remove = mt76pci_remove, +}; + +module_pci_driver(mt76pci_driver); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c new file mode 100644 index 000000000000..126497172284 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c @@ -0,0 +1,758 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/delay.h> +#include "mt76x2.h" +#include "mt76x2_mcu.h" +#include "mt76x2_eeprom.h" + +static void +mt76x2_adjust_high_lna_gain(struct mt76x2_dev *dev, int reg, s8 offset) +{ + s8 gain; + + gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, mt76_rr(dev, MT_BBP(AGC, reg))); + gain -= offset / 2; + mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_LNA_HIGH_GAIN, gain); +} + +static void +mt76x2_adjust_agc_gain(struct mt76x2_dev *dev, int reg, s8 offset) +{ + s8 gain; + + gain = FIELD_GET(MT_BBP_AGC_GAIN, mt76_rr(dev, MT_BBP(AGC, reg))); + gain += offset; + mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_GAIN, gain); +} + +static void +mt76x2_apply_gain_adj(struct mt76x2_dev *dev) +{ + s8 *gain_adj = dev->cal.rx.high_gain; + + mt76x2_adjust_high_lna_gain(dev, 4, gain_adj[0]); + mt76x2_adjust_high_lna_gain(dev, 5, gain_adj[1]); + + mt76x2_adjust_agc_gain(dev, 8, gain_adj[0]); + mt76x2_adjust_agc_gain(dev, 9, gain_adj[1]); +} + +static u32 +mt76x2_tx_power_mask(u8 v1, u8 v2, u8 v3, u8 v4) +{ + u32 val = 0; + + val |= (v1 & (BIT(6) - 1)) << 0; + val |= (v2 & (BIT(6) - 1)) << 8; + val |= (v3 & (BIT(6) - 1)) << 16; + val |= (v4 & (BIT(6) - 1)) << 24; + return val; +} + +int mt76x2_phy_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain) +{ + struct mt76x2_rx_freq_cal *cal = &dev->cal.rx; + + rssi += cal->rssi_offset[chain]; + rssi -= cal->lna_gain; + + return rssi; +} + +static u8 +mt76x2_txpower_check(int value) +{ + if (value < 0) + return 0; + if (value > 0x2f) + return 0x2f; + return value; +} + +static void +mt76x2_add_rate_power_offset(struct mt76_rate_power *r, int offset) +{ + int i; + + for (i = 0; i < sizeof(r->all); i++) + r->all[i] += offset; +} + +static void +mt76x2_limit_rate_power(struct mt76_rate_power *r, int limit) +{ + int i; + + for (i = 0; i < sizeof(r->all); i++) + if (r->all[i] > limit) + r->all[i] = limit; +} + +static int +mt76x2_get_max_power(struct mt76_rate_power *r) +{ + int i; + s8 ret = 0; + + for (i = 0; i < sizeof(r->all); i++) + ret = max(ret, r->all[i]); + + return ret; +} + +void mt76x2_phy_set_txpower(struct mt76x2_dev *dev) +{ + enum nl80211_chan_width width = dev->mt76.chandef.width; + struct mt76x2_tx_power_info txp; + int txp_0, txp_1, delta = 0; + struct mt76_rate_power t = {}; + + mt76x2_get_power_info(dev, &txp); + + if (width == NL80211_CHAN_WIDTH_40) + delta = txp.delta_bw40; + else if (width == NL80211_CHAN_WIDTH_80) + delta = txp.delta_bw80; + + if (txp.target_power > dev->txpower_conf) + delta -= txp.target_power - dev->txpower_conf; + + mt76x2_get_rate_power(dev, &t); + mt76x2_add_rate_power_offset(&t, txp.chain[0].target_power + + txp.chain[0].delta); + mt76x2_limit_rate_power(&t, dev->txpower_conf); + dev->txpower_cur = mt76x2_get_max_power(&t); + mt76x2_add_rate_power_offset(&t, -(txp.chain[0].target_power + + txp.chain[0].delta + delta)); + dev->target_power = txp.chain[0].target_power; + dev->target_power_delta[0] = txp.chain[0].delta + delta; + dev->target_power_delta[1] = txp.chain[1].delta + delta; + dev->rate_power = t; + + txp_0 = mt76x2_txpower_check(txp.chain[0].target_power + + txp.chain[0].delta + delta); + + txp_1 = mt76x2_txpower_check(txp.chain[1].target_power + + txp.chain[1].delta + delta); + + mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_0, txp_0); + mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_1, txp_1); + + mt76_wr(dev, MT_TX_PWR_CFG_0, + mt76x2_tx_power_mask(t.cck[0], t.cck[2], t.ofdm[0], t.ofdm[2])); + mt76_wr(dev, MT_TX_PWR_CFG_1, + mt76x2_tx_power_mask(t.ofdm[4], t.ofdm[6], t.ht[0], t.ht[2])); + mt76_wr(dev, MT_TX_PWR_CFG_2, + mt76x2_tx_power_mask(t.ht[4], t.ht[6], t.ht[8], t.ht[10])); + mt76_wr(dev, MT_TX_PWR_CFG_3, + mt76x2_tx_power_mask(t.ht[12], t.ht[14], t.ht[0], t.ht[2])); + mt76_wr(dev, MT_TX_PWR_CFG_4, + mt76x2_tx_power_mask(t.ht[4], t.ht[6], 0, 0)); + mt76_wr(dev, MT_TX_PWR_CFG_7, + mt76x2_tx_power_mask(t.ofdm[6], t.vht[8], t.ht[6], t.vht[8])); + mt76_wr(dev, MT_TX_PWR_CFG_8, + mt76x2_tx_power_mask(t.ht[14], t.vht[8], t.vht[8], 0)); + mt76_wr(dev, MT_TX_PWR_CFG_9, + mt76x2_tx_power_mask(t.ht[6], t.vht[8], t.vht[8], 0)); +} + +static bool +mt76x2_channel_silent(struct mt76x2_dev *dev) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + + return ((chan->flags & IEEE80211_CHAN_RADAR) && + chan->dfs_state != NL80211_DFS_AVAILABLE); +} + +static bool +mt76x2_phy_tssi_init_cal(struct mt76x2_dev *dev) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + u32 flag = 0; + + if (!mt76x2_tssi_enabled(dev)) + return false; + + if (mt76x2_channel_silent(dev)) + return false; + + if (chan->band == NL80211_BAND_2GHZ) + flag |= BIT(0); + + if (mt76x2_ext_pa_enabled(dev, chan->band)) + flag |= BIT(8); + + mt76x2_mcu_calibrate(dev, MCU_CAL_TSSI, flag); + dev->cal.tssi_cal_done = true; + return true; +} + +static void +mt76x2_phy_channel_calibrate(struct mt76x2_dev *dev, bool mac_stopped) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + bool is_5ghz = chan->band == NL80211_BAND_5GHZ; + + if (dev->cal.channel_cal_done) + return; + + if (mt76x2_channel_silent(dev)) + return; + + if (!dev->cal.tssi_cal_done) + mt76x2_phy_tssi_init_cal(dev); + + if (!mac_stopped) + mt76x2_mac_stop(dev, false); + + if (is_5ghz) + mt76x2_mcu_calibrate(dev, MCU_CAL_LC, 0); + + mt76x2_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz); + mt76x2_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); + mt76x2_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz); + mt76x2_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0); + mt76x2_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0); + + if (!mac_stopped) + mt76x2_mac_resume(dev); + + mt76x2_apply_gain_adj(dev); + + dev->cal.channel_cal_done = true; +} + +static void +mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev, enum nl80211_band band) +{ + u32 pa_mode[2]; + u32 pa_mode_adj; + + if (band == NL80211_BAND_2GHZ) { + pa_mode[0] = 0x010055ff; + pa_mode[1] = 0x00550055; + + mt76_wr(dev, MT_TX_ALC_CFG_2, 0x35160a00); + mt76_wr(dev, MT_TX_ALC_CFG_3, 0x35160a06); + + if (mt76x2_ext_pa_enabled(dev, band)) { + mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0x0000ec00); + mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0x0000ec00); + } else { + mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0xf4000200); + mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0xfa000200); + } + } else { + pa_mode[0] = 0x0000ffff; + pa_mode[1] = 0x00ff00ff; + + if (mt76x2_ext_pa_enabled(dev, band)) { + mt76_wr(dev, MT_TX_ALC_CFG_2, 0x2f0f0400); + mt76_wr(dev, MT_TX_ALC_CFG_3, 0x2f0f0476); + } else { + mt76_wr(dev, MT_TX_ALC_CFG_2, 0x1b0f0400); + mt76_wr(dev, MT_TX_ALC_CFG_3, 0x1b0f0476); + } + mt76_wr(dev, MT_TX_ALC_CFG_4, 0); + + if (mt76x2_ext_pa_enabled(dev, band)) + pa_mode_adj = 0x04000000; + else + pa_mode_adj = 0; + + mt76_wr(dev, MT_RF_PA_MODE_ADJ0, pa_mode_adj); + mt76_wr(dev, MT_RF_PA_MODE_ADJ1, pa_mode_adj); + } + + mt76_wr(dev, MT_BB_PA_MODE_CFG0, pa_mode[0]); + mt76_wr(dev, MT_BB_PA_MODE_CFG1, pa_mode[1]); + mt76_wr(dev, MT_RF_PA_MODE_CFG0, pa_mode[0]); + mt76_wr(dev, MT_RF_PA_MODE_CFG1, pa_mode[1]); + + if (mt76x2_ext_pa_enabled(dev, band)) { + u32 val; + + if (band == NL80211_BAND_2GHZ) + val = 0x3c3c023c; + else + val = 0x363c023c; + + mt76_wr(dev, MT_TX0_RF_GAIN_CORR, val); + mt76_wr(dev, MT_TX1_RF_GAIN_CORR, val); + mt76_wr(dev, MT_TX_ALC_CFG_4, 0x00001818); + } else { + if (band == NL80211_BAND_2GHZ) { + u32 val = 0x0f3c3c3c; + + mt76_wr(dev, MT_TX0_RF_GAIN_CORR, val); + mt76_wr(dev, MT_TX1_RF_GAIN_CORR, val); + mt76_wr(dev, MT_TX_ALC_CFG_4, 0x00000606); + } else { + mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x383c023c); + mt76_wr(dev, MT_TX1_RF_GAIN_CORR, 0x24282e28); + mt76_wr(dev, MT_TX_ALC_CFG_4, 0); + } + } +} + +static void +mt76x2_configure_tx_delay(struct mt76x2_dev *dev, enum nl80211_band band, u8 bw) +{ + u32 cfg0, cfg1; + + if (mt76x2_ext_pa_enabled(dev, band)) { + cfg0 = bw ? 0x000b0c01 : 0x00101101; + cfg1 = 0x00011414; + } else { + cfg0 = bw ? 0x000b0b01 : 0x00101001; + cfg1 = 0x00021414; + } + mt76_wr(dev, MT_TX_SW_CFG0, cfg0); + mt76_wr(dev, MT_TX_SW_CFG1, cfg1); + + mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_CCK_SIFS, + 13 + (bw ? 1 : 0)); +} + +static void +mt76x2_phy_set_bw(struct mt76x2_dev *dev, int width, u8 ctrl) +{ + int core_val, agc_val; + + switch (width) { + case NL80211_CHAN_WIDTH_80: + core_val = 3; + agc_val = 7; + break; + case NL80211_CHAN_WIDTH_40: + core_val = 2; + agc_val = 3; + break; + default: + core_val = 0; + agc_val = 1; + break; + } + + mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val); + mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val); + mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl); + mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl); +} + +static void +mt76x2_phy_set_band(struct mt76x2_dev *dev, int band, bool primary_upper) +{ + switch (band) { + case NL80211_BAND_2GHZ: + mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); + mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); + break; + case NL80211_BAND_5GHZ: + mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); + mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); + break; + } + + mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M, + primary_upper); +} + +static void +mt76x2_set_rx_chains(struct mt76x2_dev *dev) +{ + u32 val; + + val = mt76_rr(dev, MT_BBP(AGC, 0)); + val &= ~(BIT(3) | BIT(4)); + + if (dev->chainmask & BIT(1)) + val |= BIT(3); + + mt76_wr(dev, MT_BBP(AGC, 0), val); +} + +static void +mt76x2_set_tx_dac(struct mt76x2_dev *dev) +{ + if (dev->chainmask & BIT(1)) + mt76_set(dev, MT_BBP(TXBE, 5), 3); + else + mt76_clear(dev, MT_BBP(TXBE, 5), 3); +} + +static void +mt76x2_get_agc_gain(struct mt76x2_dev *dev, u8 *dest) +{ + dest[0] = mt76_get_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN); + dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN); +} + +static int +mt76x2_get_rssi_gain_thresh(struct mt76x2_dev *dev) +{ + switch (dev->mt76.chandef.width) { + case NL80211_CHAN_WIDTH_80: + return -62; + case NL80211_CHAN_WIDTH_40: + return -65; + default: + return -68; + } +} + +static int +mt76x2_get_low_rssi_gain_thresh(struct mt76x2_dev *dev) +{ + switch (dev->mt76.chandef.width) { + case NL80211_CHAN_WIDTH_80: + return -76; + case NL80211_CHAN_WIDTH_40: + return -79; + default: + return -82; + } +} + +static void +mt76x2_phy_set_gain_val(struct mt76x2_dev *dev) +{ + u32 val; + u8 gain_val[2]; + + gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust; + gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust; + + if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40) + val = 0x1e42 << 16; + else + val = 0x1836 << 16; + + val |= 0xf8; + + mt76_wr(dev, MT_BBP(AGC, 8), + val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0])); + mt76_wr(dev, MT_BBP(AGC, 9), + val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1])); + + if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR) + mt76x2_dfs_adjust_agc(dev); +} + +static void +mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev) +{ + u32 false_cca; + u8 limit = dev->cal.low_gain > 1 ? 4 : 16; + + false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1)); + if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) + dev->cal.agc_gain_adjust += 2; + else if (false_cca < 10 && dev->cal.agc_gain_adjust > 0) + dev->cal.agc_gain_adjust -= 2; + else + return; + + mt76x2_phy_set_gain_val(dev); +} + +static void +mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev) +{ + u32 val = mt76_rr(dev, MT_BBP(AGC, 20)); + int rssi0 = (s8) FIELD_GET(MT_BBP_AGC20_RSSI0, val); + int rssi1 = (s8) FIELD_GET(MT_BBP_AGC20_RSSI1, val); + u8 *gain = dev->cal.agc_gain_init; + u8 gain_delta; + int low_gain; + + dev->cal.avg_rssi[0] = (dev->cal.avg_rssi[0] * 15) / 16 + (rssi0 << 8); + dev->cal.avg_rssi[1] = (dev->cal.avg_rssi[1] * 15) / 16 + (rssi1 << 8); + dev->cal.avg_rssi_all = (dev->cal.avg_rssi[0] + + dev->cal.avg_rssi[1]) / 512; + + low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) + + (dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev)); + + if (dev->cal.low_gain == low_gain) { + mt76x2_phy_adjust_vga_gain(dev); + return; + } + + dev->cal.low_gain = low_gain; + + if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) + mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211); + else + mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423); + + if (low_gain) { + mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991); + mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808); + mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808); + if (mt76x2_has_ext_lna(dev)) + gain_delta = 10; + else + gain_delta = 14; + } else { + mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990); + if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) + mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014); + else + mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116); + mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C); + gain_delta = 0; + } + + dev->cal.agc_gain_cur[0] = gain[0] - gain_delta; + dev->cal.agc_gain_cur[1] = gain[1] - gain_delta; + dev->cal.agc_gain_adjust = 0; + mt76x2_phy_set_gain_val(dev); +} + +int mt76x2_phy_set_channel(struct mt76x2_dev *dev, + struct cfg80211_chan_def *chandef) +{ + struct ieee80211_channel *chan = chandef->chan; + bool scan = test_bit(MT76_SCANNING, &dev->mt76.state); + enum nl80211_band band = chan->band; + u8 channel; + + u32 ext_cca_chan[4] = { + [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)), + [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)), + [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)), + [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | + FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)), + }; + int ch_group_index; + u8 bw, bw_index; + int freq, freq1; + int ret; + u8 sifs = 13; + + dev->cal.channel_cal_done = false; + freq = chandef->chan->center_freq; + freq1 = chandef->center_freq1; + channel = chan->hw_value; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_40: + bw = 1; + if (freq1 > freq) { + bw_index = 1; + ch_group_index = 0; + } else { + bw_index = 3; + ch_group_index = 1; + } + channel += 2 - ch_group_index * 4; + break; + case NL80211_CHAN_WIDTH_80: + ch_group_index = (freq - freq1 + 30) / 20; + if (WARN_ON(ch_group_index < 0 || ch_group_index > 3)) + ch_group_index = 0; + bw = 2; + bw_index = ch_group_index; + channel += 6 - ch_group_index * 4; + break; + default: + bw = 0; + bw_index = 0; + ch_group_index = 0; + break; + } + + mt76x2_read_rx_gain(dev); + mt76x2_phy_set_txpower_regs(dev, band); + mt76x2_configure_tx_delay(dev, band, bw); + mt76x2_phy_set_txpower(dev); + + mt76x2_set_rx_chains(dev); + mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1); + mt76x2_phy_set_bw(dev, chandef->width, ch_group_index); + mt76x2_set_tx_dac(dev); + + mt76_rmw(dev, MT_EXT_CCA_CFG, + (MT_EXT_CCA_CFG_CCA0 | + MT_EXT_CCA_CFG_CCA1 | + MT_EXT_CCA_CFG_CCA2 | + MT_EXT_CCA_CFG_CCA3 | + MT_EXT_CCA_CFG_CCA_MASK), + ext_cca_chan[ch_group_index]); + + if (chandef->width >= NL80211_CHAN_WIDTH_40) + sifs++; + + mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_OFDM_SIFS, sifs); + + ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); + if (ret) + return ret; + + mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); + + /* Enable LDPC Rx */ + if (mt76xx_rev(dev) >= MT76XX_REV_E3) + mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); + + if (!dev->cal.init_cal_done) { + u8 val = mt76x2_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); + + if (val != 0xff) + mt76x2_mcu_calibrate(dev, MCU_CAL_R, 0); + } + + mt76x2_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel); + + /* Rx LPF calibration */ + if (!dev->cal.init_cal_done) + mt76x2_mcu_calibrate(dev, MCU_CAL_RC, 0); + + dev->cal.init_cal_done = true; + + mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2); + mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010); + mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404); + mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070); + mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F); + + if (scan) + return 0; + + dev->cal.low_gain = -1; + mt76x2_phy_channel_calibrate(dev, true); + mt76x2_get_agc_gain(dev, dev->cal.agc_gain_init); + memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init, + sizeof(dev->cal.agc_gain_cur)); + + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, + MT_CALIBRATE_INTERVAL); + + return 0; +} + +static void +mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + struct mt76x2_tx_power_info txp; + struct mt76x2_tssi_comp t = {}; + + if (!dev->cal.tssi_cal_done) + return; + + if (!dev->cal.tssi_comp_pending) { + /* TSSI trigger */ + t.cal_mode = BIT(0); + mt76x2_mcu_tssi_comp(dev, &t); + dev->cal.tssi_comp_pending = true; + } else { + if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4)) + return; + + dev->cal.tssi_comp_pending = false; + mt76x2_get_power_info(dev, &txp); + + if (mt76x2_ext_pa_enabled(dev, chan->band)) + t.pa_mode = 1; + + t.cal_mode = BIT(1); + t.slope0 = txp.chain[0].tssi_slope; + t.offset0 = txp.chain[0].tssi_offset; + t.slope1 = txp.chain[1].tssi_slope; + t.offset1 = txp.chain[1].tssi_offset; + mt76x2_mcu_tssi_comp(dev, &t); + + if (t.pa_mode || dev->cal.dpd_cal_done) + return; + + usleep_range(10000, 20000); + mt76x2_mcu_calibrate(dev, MCU_CAL_DPD, chan->hw_value); + dev->cal.dpd_cal_done = true; + } +} + +static void +mt76x2_phy_temp_compensate(struct mt76x2_dev *dev) +{ + struct mt76x2_temp_comp t; + int temp, db_diff; + + if (mt76x2_get_temp_comp(dev, &t)) + return; + + temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL); + temp -= t.temp_25_ref; + temp = (temp * 1789) / 1000 + 25; + dev->cal.temp = temp; + + if (temp > 25) + db_diff = (temp - 25) / t.high_slope; + else + db_diff = (25 - temp) / t.low_slope; + + db_diff = min(db_diff, t.upper_bound); + db_diff = max(db_diff, t.lower_bound); + + mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, + db_diff * 2); + mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, + db_diff * 2); +} + +void mt76x2_phy_calibrate(struct work_struct *work) +{ + struct mt76x2_dev *dev; + + dev = container_of(work, struct mt76x2_dev, cal_work.work); + mt76x2_phy_channel_calibrate(dev, false); + mt76x2_phy_tssi_compensate(dev); + mt76x2_phy_temp_compensate(dev); + mt76x2_phy_update_channel_gain(dev); + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, + MT_CALIBRATE_INTERVAL); +} + +int mt76x2_phy_start(struct mt76x2_dev *dev) +{ + int ret; + + ret = mt76x2_mcu_set_radio_state(dev, true); + if (ret) + return ret; + + mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); + + return ret; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_regs.h b/drivers/net/wireless/mediatek/mt76/mt76x2_regs.h new file mode 100644 index 000000000000..ce3ab85c8b0f --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_regs.h @@ -0,0 +1,587 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x2_REGS_H +#define __MT76x2_REGS_H + +#define MT_ASIC_VERSION 0x0000 + +#define MT76XX_REV_E3 0x22 +#define MT76XX_REV_E4 0x33 + +#define MT_CMB_CTRL 0x0020 +#define MT_CMB_CTRL_XTAL_RDY BIT(22) +#define MT_CMB_CTRL_PLL_LD BIT(23) + +#define MT_EFUSE_CTRL 0x0024 +#define MT_EFUSE_CTRL_AOUT GENMASK(5, 0) +#define MT_EFUSE_CTRL_MODE GENMASK(7, 6) +#define MT_EFUSE_CTRL_LDO_OFF_TIME GENMASK(13, 8) +#define MT_EFUSE_CTRL_LDO_ON_TIME GENMASK(15, 14) +#define MT_EFUSE_CTRL_AIN GENMASK(25, 16) +#define MT_EFUSE_CTRL_KICK BIT(30) +#define MT_EFUSE_CTRL_SEL BIT(31) + +#define MT_EFUSE_DATA_BASE 0x0028 +#define MT_EFUSE_DATA(_n) (MT_EFUSE_DATA_BASE + ((_n) << 2)) + +#define MT_COEXCFG0 0x0040 +#define MT_COEXCFG0_COEX_EN BIT(0) + +#define MT_WLAN_FUN_CTRL 0x0080 +#define MT_WLAN_FUN_CTRL_WLAN_EN BIT(0) +#define MT_WLAN_FUN_CTRL_WLAN_CLK_EN BIT(1) +#define MT_WLAN_FUN_CTRL_WLAN_RESET_RF BIT(2) + +#define MT_WLAN_FUN_CTRL_WLAN_RESET BIT(3) /* MT76x0 */ +#define MT_WLAN_FUN_CTRL_CSR_F20M_CKEN BIT(3) /* MT76x2 */ + +#define MT_WLAN_FUN_CTRL_PCIE_CLK_REQ BIT(4) +#define MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL BIT(5) +#define MT_WLAN_FUN_CTRL_INV_ANT_SEL BIT(6) +#define MT_WLAN_FUN_CTRL_WAKE_HOST BIT(7) + +#define MT_WLAN_FUN_CTRL_THERM_RST BIT(8) /* MT76x2 */ +#define MT_WLAN_FUN_CTRL_THERM_CKEN BIT(9) /* MT76x2 */ + +#define MT_WLAN_FUN_CTRL_GPIO_IN GENMASK(15, 8) /* MT76x0 */ +#define MT_WLAN_FUN_CTRL_GPIO_OUT GENMASK(23, 16) /* MT76x0 */ +#define MT_WLAN_FUN_CTRL_GPIO_OUT_EN GENMASK(31, 24) /* MT76x0 */ + +#define MT_XO_CTRL0 0x0100 +#define MT_XO_CTRL1 0x0104 +#define MT_XO_CTRL2 0x0108 +#define MT_XO_CTRL3 0x010c +#define MT_XO_CTRL4 0x0110 + +#define MT_XO_CTRL5 0x0114 +#define MT_XO_CTRL5_C2_VAL GENMASK(14, 8) + +#define MT_XO_CTRL6 0x0118 +#define MT_XO_CTRL6_C2_CTRL GENMASK(14, 8) + +#define MT_XO_CTRL7 0x011c + +#define MT_WLAN_MTC_CTRL 0x10148 +#define MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP BIT(0) +#define MT_WLAN_MTC_CTRL_PWR_ACK BIT(12) +#define MT_WLAN_MTC_CTRL_PWR_ACK_S BIT(13) +#define MT_WLAN_MTC_CTRL_BBP_MEM_PD GENMASK(19, 16) +#define MT_WLAN_MTC_CTRL_PBF_MEM_PD BIT(20) +#define MT_WLAN_MTC_CTRL_FCE_MEM_PD BIT(21) +#define MT_WLAN_MTC_CTRL_TSO_MEM_PD BIT(22) +#define MT_WLAN_MTC_CTRL_BBP_MEM_RB BIT(24) +#define MT_WLAN_MTC_CTRL_PBF_MEM_RB BIT(25) +#define MT_WLAN_MTC_CTRL_FCE_MEM_RB BIT(26) +#define MT_WLAN_MTC_CTRL_TSO_MEM_RB BIT(27) +#define MT_WLAN_MTC_CTRL_STATE_UP BIT(28) + +#define MT_INT_SOURCE_CSR 0x0200 +#define MT_INT_MASK_CSR 0x0204 + +#define MT_INT_RX_DONE(_n) BIT(_n) +#define MT_INT_RX_DONE_ALL GENMASK(1, 0) +#define MT_INT_TX_DONE_ALL GENMASK(13, 4) +#define MT_INT_TX_DONE(_n) BIT(_n + 4) +#define MT_INT_RX_COHERENT BIT(16) +#define MT_INT_TX_COHERENT BIT(17) +#define MT_INT_ANY_COHERENT BIT(18) +#define MT_INT_MCU_CMD BIT(19) +#define MT_INT_TBTT BIT(20) +#define MT_INT_PRE_TBTT BIT(21) +#define MT_INT_TX_STAT BIT(22) +#define MT_INT_AUTO_WAKEUP BIT(23) +#define MT_INT_GPTIMER BIT(24) +#define MT_INT_RXDELAYINT BIT(26) +#define MT_INT_TXDELAYINT BIT(27) + +#define MT_WPDMA_GLO_CFG 0x0208 +#define MT_WPDMA_GLO_CFG_TX_DMA_EN BIT(0) +#define MT_WPDMA_GLO_CFG_TX_DMA_BUSY BIT(1) +#define MT_WPDMA_GLO_CFG_RX_DMA_EN BIT(2) +#define MT_WPDMA_GLO_CFG_RX_DMA_BUSY BIT(3) +#define MT_WPDMA_GLO_CFG_DMA_BURST_SIZE GENMASK(5, 4) +#define MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE BIT(6) +#define MT_WPDMA_GLO_CFG_BIG_ENDIAN BIT(7) +#define MT_WPDMA_GLO_CFG_HDR_SEG_LEN GENMASK(15, 8) +#define MT_WPDMA_GLO_CFG_CLK_GATE_DIS BIT(30) +#define MT_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) + +#define MT_WPDMA_RST_IDX 0x020c + +#define MT_WPDMA_DELAY_INT_CFG 0x0210 + +#define MT_WMM_AIFSN 0x0214 +#define MT_WMM_AIFSN_MASK GENMASK(3, 0) +#define MT_WMM_AIFSN_SHIFT(_n) ((_n) * 4) + +#define MT_WMM_CWMIN 0x0218 +#define MT_WMM_CWMIN_MASK GENMASK(3, 0) +#define MT_WMM_CWMIN_SHIFT(_n) ((_n) * 4) + +#define MT_WMM_CWMAX 0x021c +#define MT_WMM_CWMAX_MASK GENMASK(3, 0) +#define MT_WMM_CWMAX_SHIFT(_n) ((_n) * 4) + +#define MT_WMM_TXOP_BASE 0x0220 +#define MT_WMM_TXOP(_n) (MT_WMM_TXOP_BASE + (((_n) / 2) << 2)) +#define MT_WMM_TXOP_SHIFT(_n) ((_n & 1) * 16) +#define MT_WMM_TXOP_MASK GENMASK(15, 0) + +#define MT_TSO_CTRL 0x0250 +#define MT_HEADER_TRANS_CTRL_REG 0x0260 + +#define MT_TX_RING_BASE 0x0300 +#define MT_RX_RING_BASE 0x03c0 + +#define MT_TX_HW_QUEUE_MCU 8 +#define MT_TX_HW_QUEUE_MGMT 9 + +#define MT_PBF_SYS_CTRL 0x0400 +#define MT_PBF_SYS_CTRL_MCU_RESET BIT(0) +#define MT_PBF_SYS_CTRL_DMA_RESET BIT(1) +#define MT_PBF_SYS_CTRL_MAC_RESET BIT(2) +#define MT_PBF_SYS_CTRL_PBF_RESET BIT(3) +#define MT_PBF_SYS_CTRL_ASY_RESET BIT(4) + +#define MT_PBF_CFG 0x0404 +#define MT_PBF_CFG_TX0Q_EN BIT(0) +#define MT_PBF_CFG_TX1Q_EN BIT(1) +#define MT_PBF_CFG_TX2Q_EN BIT(2) +#define MT_PBF_CFG_TX3Q_EN BIT(3) +#define MT_PBF_CFG_RX0Q_EN BIT(4) +#define MT_PBF_CFG_RX_DROP_EN BIT(8) + +#define MT_PBF_TX_MAX_PCNT 0x0408 +#define MT_PBF_RX_MAX_PCNT 0x040c + +#define MT_BCN_OFFSET_BASE 0x041c +#define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2)) + +#define MT_RF_BYPASS_0 0x0504 +#define MT_RF_BYPASS_1 0x0508 +#define MT_RF_SETTING_0 0x050c + +#define MT_RF_DATA_WRITE 0x0524 + +#define MT_RF_CTRL 0x0528 +#define MT_RF_CTRL_ADDR GENMASK(11, 0) +#define MT_RF_CTRL_WRITE BIT(12) +#define MT_RF_CTRL_BUSY BIT(13) +#define MT_RF_CTRL_IDX BIT(16) + +#define MT_RF_DATA_READ 0x052c + +#define MT_FCE_PSE_CTRL 0x0800 +#define MT_FCE_PARAMETERS 0x0804 +#define MT_FCE_CSO 0x0808 + +#define MT_FCE_L2_STUFF 0x080c +#define MT_FCE_L2_STUFF_HT_L2_EN BIT(0) +#define MT_FCE_L2_STUFF_QOS_L2_EN BIT(1) +#define MT_FCE_L2_STUFF_RX_STUFF_EN BIT(2) +#define MT_FCE_L2_STUFF_TX_STUFF_EN BIT(3) +#define MT_FCE_L2_STUFF_WR_MPDU_LEN_EN BIT(4) +#define MT_FCE_L2_STUFF_MVINV_BSWAP BIT(5) +#define MT_FCE_L2_STUFF_TS_CMD_QSEL_EN GENMASK(15, 8) +#define MT_FCE_L2_STUFF_TS_LEN_EN GENMASK(23, 16) +#define MT_FCE_L2_STUFF_OTHER_PORT GENMASK(25, 24) + +#define MT_FCE_WLAN_FLOW_CONTROL1 0x0824 + +#define MT_PAUSE_ENABLE_CONTROL1 0x0a38 + +#define MT_MAC_CSR0 0x1000 + +#define MT_MAC_SYS_CTRL 0x1004 +#define MT_MAC_SYS_CTRL_RESET_CSR BIT(0) +#define MT_MAC_SYS_CTRL_RESET_BBP BIT(1) +#define MT_MAC_SYS_CTRL_ENABLE_TX BIT(2) +#define MT_MAC_SYS_CTRL_ENABLE_RX BIT(3) + +#define MT_MAC_ADDR_DW0 0x1008 +#define MT_MAC_ADDR_DW1 0x100c + +#define MT_MAC_BSSID_DW0 0x1010 +#define MT_MAC_BSSID_DW1 0x1014 +#define MT_MAC_BSSID_DW1_ADDR GENMASK(15, 0) +#define MT_MAC_BSSID_DW1_MBSS_MODE GENMASK(17, 16) +#define MT_MAC_BSSID_DW1_MBEACON_N GENMASK(20, 18) +#define MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT BIT(21) +#define MT_MAC_BSSID_DW1_MBSS_MODE_B2 BIT(22) +#define MT_MAC_BSSID_DW1_MBEACON_N_B3 BIT(23) +#define MT_MAC_BSSID_DW1_MBSS_IDX_BYTE GENMASK(26, 24) + +#define MT_MAX_LEN_CFG 0x1018 + +#define MT_AMPDU_MAX_LEN_20M1S 0x1030 +#define MT_AMPDU_MAX_LEN_20M2S 0x1034 +#define MT_AMPDU_MAX_LEN_40M1S 0x1038 +#define MT_AMPDU_MAX_LEN_40M2S 0x103c +#define MT_AMPDU_MAX_LEN 0x1040 + +#define MT_WCID_DROP_BASE 0x106c +#define MT_WCID_DROP(_n) (MT_WCID_DROP_BASE + ((_n) >> 5) * 4) +#define MT_WCID_DROP_MASK(_n) BIT((_n) % 32) + +#define MT_BCN_BYPASS_MASK 0x108c + +#define MT_MAC_APC_BSSID_BASE 0x1090 +#define MT_MAC_APC_BSSID_L(_n) (MT_MAC_APC_BSSID_BASE + ((_n) * 8)) +#define MT_MAC_APC_BSSID_H(_n) (MT_MAC_APC_BSSID_BASE + ((_n) * 8 + 4)) +#define MT_MAC_APC_BSSID_H_ADDR GENMASK(15, 0) +#define MT_MAC_APC_BSSID0_H_EN BIT(16) + +#define MT_XIFS_TIME_CFG 0x1100 +#define MT_XIFS_TIME_CFG_CCK_SIFS GENMASK(7, 0) +#define MT_XIFS_TIME_CFG_OFDM_SIFS GENMASK(15, 8) +#define MT_XIFS_TIME_CFG_OFDM_XIFS GENMASK(19, 16) +#define MT_XIFS_TIME_CFG_EIFS GENMASK(28, 20) +#define MT_XIFS_TIME_CFG_BB_RXEND_EN BIT(29) + +#define MT_BKOFF_SLOT_CFG 0x1104 +#define MT_BKOFF_SLOT_CFG_SLOTTIME GENMASK(7, 0) +#define MT_BKOFF_SLOT_CFG_CC_DELAY GENMASK(11, 8) + +#define MT_CH_TIME_CFG 0x110c +#define MT_CH_TIME_CFG_TIMER_EN BIT(0) +#define MT_CH_TIME_CFG_TX_AS_BUSY BIT(1) +#define MT_CH_TIME_CFG_RX_AS_BUSY BIT(2) +#define MT_CH_TIME_CFG_NAV_AS_BUSY BIT(3) +#define MT_CH_TIME_CFG_EIFS_AS_BUSY BIT(4) +#define MT_CH_TIME_CFG_MDRDY_CNT_EN BIT(5) +#define MT_CH_TIME_CFG_CH_TIMER_CLR GENMASK(9, 8) +#define MT_CH_TIME_CFG_MDRDY_CLR GENMASK(11, 10) + +#define MT_PBF_LIFE_TIMER 0x1110 + +#define MT_BEACON_TIME_CFG 0x1114 +#define MT_BEACON_TIME_CFG_INTVAL GENMASK(15, 0) +#define MT_BEACON_TIME_CFG_TIMER_EN BIT(16) +#define MT_BEACON_TIME_CFG_SYNC_MODE GENMASK(18, 17) +#define MT_BEACON_TIME_CFG_TBTT_EN BIT(19) +#define MT_BEACON_TIME_CFG_BEACON_TX BIT(20) +#define MT_BEACON_TIME_CFG_TSF_COMP GENMASK(31, 24) + +#define MT_TBTT_SYNC_CFG 0x1118 +#define MT_TBTT_TIMER_CFG 0x1124 + +#define MT_INT_TIMER_CFG 0x1128 +#define MT_INT_TIMER_CFG_PRE_TBTT GENMASK(15, 0) +#define MT_INT_TIMER_CFG_GP_TIMER GENMASK(31, 16) + +#define MT_INT_TIMER_EN 0x112c +#define MT_INT_TIMER_EN_PRE_TBTT_EN BIT(0) +#define MT_INT_TIMER_EN_GP_TIMER_EN BIT(1) + +#define MT_CH_IDLE 0x1130 +#define MT_CH_BUSY 0x1134 +#define MT_EXT_CH_BUSY 0x1138 +#define MT_ED_CCA_TIMER 0x1140 + +#define MT_MAC_STATUS 0x1200 +#define MT_MAC_STATUS_TX BIT(0) +#define MT_MAC_STATUS_RX BIT(1) + +#define MT_PWR_PIN_CFG 0x1204 +#define MT_AUX_CLK_CFG 0x120c + +#define MT_BB_PA_MODE_CFG0 0x1214 +#define MT_BB_PA_MODE_CFG1 0x1218 +#define MT_RF_PA_MODE_CFG0 0x121c +#define MT_RF_PA_MODE_CFG1 0x1220 + +#define MT_RF_PA_MODE_ADJ0 0x1228 +#define MT_RF_PA_MODE_ADJ1 0x122c + +#define MT_DACCLK_EN_DLY_CFG 0x1264 + +#define MT_EDCA_CFG_BASE 0x1300 +#define MT_EDCA_CFG_AC(_n) (MT_EDCA_CFG_BASE + ((_n) << 2)) +#define MT_EDCA_CFG_TXOP GENMASK(7, 0) +#define MT_EDCA_CFG_AIFSN GENMASK(11, 8) +#define MT_EDCA_CFG_CWMIN GENMASK(15, 12) +#define MT_EDCA_CFG_CWMAX GENMASK(19, 16) + +#define MT_TX_PWR_CFG_0 0x1314 +#define MT_TX_PWR_CFG_1 0x1318 +#define MT_TX_PWR_CFG_2 0x131c +#define MT_TX_PWR_CFG_3 0x1320 +#define MT_TX_PWR_CFG_4 0x1324 + +#define MT_TX_BAND_CFG 0x132c +#define MT_TX_BAND_CFG_UPPER_40M BIT(0) +#define MT_TX_BAND_CFG_5G BIT(1) +#define MT_TX_BAND_CFG_2G BIT(2) + +#define MT_HT_FBK_TO_LEGACY 0x1384 +#define MT_TX_MPDU_ADJ_INT 0x1388 + +#define MT_TX_PWR_CFG_7 0x13d4 +#define MT_TX_PWR_CFG_8 0x13d8 +#define MT_TX_PWR_CFG_9 0x13dc + +#define MT_TX_SW_CFG0 0x1330 +#define MT_TX_SW_CFG1 0x1334 +#define MT_TX_SW_CFG2 0x1338 + +#define MT_TXOP_CTRL_CFG 0x1340 + +#define MT_TX_RTS_CFG 0x1344 +#define MT_TX_RTS_CFG_RETRY_LIMIT GENMASK(7, 0) +#define MT_TX_RTS_CFG_THRESH GENMASK(23, 8) +#define MT_TX_RTS_FALLBACK BIT(24) + +#define MT_TX_TIMEOUT_CFG 0x1348 +#define MT_TX_TIMEOUT_CFG_ACKTO GENMASK(15, 8) + +#define MT_TX_RETRY_CFG 0x134c +#define MT_VHT_HT_FBK_CFG1 0x1358 + +#define MT_PROT_CFG_RATE GENMASK(15, 0) +#define MT_PROT_CFG_CTRL GENMASK(17, 16) +#define MT_PROT_CFG_NAV GENMASK(19, 18) +#define MT_PROT_CFG_TXOP_ALLOW GENMASK(25, 20) +#define MT_PROT_CFG_RTS_THRESH BIT(26) + +#define MT_CCK_PROT_CFG 0x1364 +#define MT_OFDM_PROT_CFG 0x1368 +#define MT_MM20_PROT_CFG 0x136c +#define MT_MM40_PROT_CFG 0x1370 +#define MT_GF20_PROT_CFG 0x1374 +#define MT_GF40_PROT_CFG 0x1378 + +#define MT_EXP_ACK_TIME 0x1380 + +#define MT_TX_PWR_CFG_0_EXT 0x1390 +#define MT_TX_PWR_CFG_1_EXT 0x1394 + +#define MT_TX_FBK_LIMIT 0x1398 +#define MT_TX_FBK_LIMIT_MPDU_FBK GENMASK(7, 0) +#define MT_TX_FBK_LIMIT_AMPDU_FBK GENMASK(15, 8) +#define MT_TX_FBK_LIMIT_MPDU_UP_CLEAR BIT(16) +#define MT_TX_FBK_LIMIT_AMPDU_UP_CLEAR BIT(17) +#define MT_TX_FBK_LIMIT_RATE_LUT BIT(18) + +#define MT_TX0_RF_GAIN_CORR 0x13a0 +#define MT_TX1_RF_GAIN_CORR 0x13a4 + +#define MT_TX_ALC_CFG_0 0x13b0 +#define MT_TX_ALC_CFG_0_CH_INIT_0 GENMASK(5, 0) +#define MT_TX_ALC_CFG_0_CH_INIT_1 GENMASK(13, 8) +#define MT_TX_ALC_CFG_0_LIMIT_0 GENMASK(21, 16) +#define MT_TX_ALC_CFG_0_LIMIT_1 GENMASK(29, 24) + +#define MT_TX_ALC_CFG_1 0x13b4 +#define MT_TX_ALC_CFG_1_TEMP_COMP GENMASK(5, 0) + +#define MT_TX_ALC_CFG_2 0x13a8 +#define MT_TX_ALC_CFG_2_TEMP_COMP GENMASK(5, 0) + +#define MT_TX_ALC_CFG_3 0x13ac +#define MT_TX_ALC_CFG_4 0x13c0 +#define MT_TX_ALC_CFG_4_LOWGAIN_CH_EN BIT(31) + +#define MT_TX_ALC_VGA3 0x13c8 + +#define MT_TX_PROT_CFG6 0x13e0 +#define MT_TX_PROT_CFG7 0x13e4 +#define MT_TX_PROT_CFG8 0x13e8 + +#define MT_PIFS_TX_CFG 0x13ec + +#define MT_RX_FILTR_CFG 0x1400 + +#define MT_RX_FILTR_CFG_CRC_ERR BIT(0) +#define MT_RX_FILTR_CFG_PHY_ERR BIT(1) +#define MT_RX_FILTR_CFG_PROMISC BIT(2) +#define MT_RX_FILTR_CFG_OTHER_BSS BIT(3) +#define MT_RX_FILTR_CFG_VER_ERR BIT(4) +#define MT_RX_FILTR_CFG_MCAST BIT(5) +#define MT_RX_FILTR_CFG_BCAST BIT(6) +#define MT_RX_FILTR_CFG_DUP BIT(7) +#define MT_RX_FILTR_CFG_CFACK BIT(8) +#define MT_RX_FILTR_CFG_CFEND BIT(9) +#define MT_RX_FILTR_CFG_ACK BIT(10) +#define MT_RX_FILTR_CFG_CTS BIT(11) +#define MT_RX_FILTR_CFG_RTS BIT(12) +#define MT_RX_FILTR_CFG_PSPOLL BIT(13) +#define MT_RX_FILTR_CFG_BA BIT(14) +#define MT_RX_FILTR_CFG_BAR BIT(15) +#define MT_RX_FILTR_CFG_CTRL_RSV BIT(16) + +#define MT_LEGACY_BASIC_RATE 0x1408 +#define MT_HT_BASIC_RATE 0x140c + +#define MT_HT_CTRL_CFG 0x1410 + +#define MT_EXT_CCA_CFG 0x141c +#define MT_EXT_CCA_CFG_CCA0 GENMASK(1, 0) +#define MT_EXT_CCA_CFG_CCA1 GENMASK(3, 2) +#define MT_EXT_CCA_CFG_CCA2 GENMASK(5, 4) +#define MT_EXT_CCA_CFG_CCA3 GENMASK(7, 6) +#define MT_EXT_CCA_CFG_CCA_MASK GENMASK(11, 8) +#define MT_EXT_CCA_CFG_ED_CCA_MASK GENMASK(15, 12) + +#define MT_TX_SW_CFG3 0x1478 + +#define MT_PN_PAD_MODE 0x150c + +#define MT_TXOP_HLDR_ET 0x1608 + +#define MT_PROT_AUTO_TX_CFG 0x1648 +#define MT_PROT_AUTO_TX_CFG_PROT_PADJ GENMASK(11, 8) +#define MT_PROT_AUTO_TX_CFG_AUTO_PADJ GENMASK(27, 24) + +#define MT_RX_STAT_0 0x1700 +#define MT_RX_STAT_0_CRC_ERRORS GENMASK(15, 0) +#define MT_RX_STAT_0_PHY_ERRORS GENMASK(31, 16) + +#define MT_RX_STAT_1 0x1704 +#define MT_RX_STAT_1_CCA_ERRORS GENMASK(15, 0) +#define MT_RX_STAT_1_PLCP_ERRORS GENMASK(31, 16) + +#define MT_RX_STAT_2 0x1708 +#define MT_RX_STAT_2_DUP_ERRORS GENMASK(15, 0) +#define MT_RX_STAT_2_OVERFLOW_ERRORS GENMASK(31, 16) + +#define MT_TX_STAT_FIFO 0x1718 +#define MT_TX_STAT_FIFO_VALID BIT(0) +#define MT_TX_STAT_FIFO_SUCCESS BIT(5) +#define MT_TX_STAT_FIFO_AGGR BIT(6) +#define MT_TX_STAT_FIFO_ACKREQ BIT(7) +#define MT_TX_STAT_FIFO_WCID GENMASK(15, 8) +#define MT_TX_STAT_FIFO_RATE GENMASK(31, 16) + +#define MT_TX_AGG_CNT_BASE0 0x1720 +#define MT_TX_AGG_CNT_BASE1 0x174c + +#define MT_TX_AGG_CNT(_id) ((_id) < 8 ? \ + MT_TX_AGG_CNT_BASE0 + ((_id) << 2) : \ + MT_TX_AGG_CNT_BASE1 + ((_id - 8) << 2)) + +#define MT_TX_STAT_FIFO_EXT 0x1798 +#define MT_TX_STAT_FIFO_EXT_RETRY GENMASK(7, 0) +#define MT_TX_STAT_FIFO_EXT_PKTID GENMASK(15, 8) + +#define MT_WCID_TX_RATE_BASE 0x1c00 +#define MT_WCID_TX_RATE(_i) (MT_WCID_TX_RATE_BASE + ((_i) << 3)) + +#define MT_BBP_CORE_BASE 0x2000 +#define MT_BBP_IBI_BASE 0x2100 +#define MT_BBP_AGC_BASE 0x2300 +#define MT_BBP_TXC_BASE 0x2400 +#define MT_BBP_RXC_BASE 0x2500 +#define MT_BBP_TXO_BASE 0x2600 +#define MT_BBP_TXBE_BASE 0x2700 +#define MT_BBP_RXFE_BASE 0x2800 +#define MT_BBP_RXO_BASE 0x2900 +#define MT_BBP_DFS_BASE 0x2a00 +#define MT_BBP_TR_BASE 0x2b00 +#define MT_BBP_CAL_BASE 0x2c00 +#define MT_BBP_DSC_BASE 0x2e00 +#define MT_BBP_PFMU_BASE 0x2f00 + +#define MT_BBP(_type, _n) (MT_BBP_##_type##_BASE + ((_n) << 2)) + +#define MT_BBP_CORE_R1_BW GENMASK(4, 3) + +#define MT_BBP_AGC_R0_CTRL_CHAN GENMASK(9, 8) +#define MT_BBP_AGC_R0_BW GENMASK(14, 12) + +/* AGC, R4/R5 */ +#define MT_BBP_AGC_LNA_HIGH_GAIN GENMASK(21, 16) +#define MT_BBP_AGC_LNA_MID_GAIN GENMASK(13, 8) +#define MT_BBP_AGC_LNA_LOW_GAIN GENMASK(5, 0) + +/* AGC, R6/R7 */ +#define MT_BBP_AGC_LNA_ULOW_GAIN GENMASK(5, 0) + +/* AGC, R8/R9 */ +#define MT_BBP_AGC_LNA_GAIN_MODE GENMASK(7, 6) +#define MT_BBP_AGC_GAIN GENMASK(14, 8) + +#define MT_BBP_AGC20_RSSI0 GENMASK(7, 0) +#define MT_BBP_AGC20_RSSI1 GENMASK(15, 8) + +#define MT_BBP_TXBE_R0_CTRL_CHAN GENMASK(1, 0) + +#define MT_WCID_ADDR_BASE 0x1800 +#define MT_WCID_ADDR(_n) (MT_WCID_ADDR_BASE + (_n) * 8) + +#define MT_SRAM_BASE 0x4000 + +#define MT_WCID_KEY_BASE 0x8000 +#define MT_WCID_KEY(_n) (MT_WCID_KEY_BASE + (_n) * 32) + +#define MT_WCID_IV_BASE 0xa000 +#define MT_WCID_IV(_n) (MT_WCID_IV_BASE + (_n) * 8) + +#define MT_WCID_ATTR_BASE 0xa800 +#define MT_WCID_ATTR(_n) (MT_WCID_ATTR_BASE + (_n) * 4) + +#define MT_WCID_ATTR_PAIRWISE BIT(0) +#define MT_WCID_ATTR_PKEY_MODE GENMASK(3, 1) +#define MT_WCID_ATTR_BSS_IDX GENMASK(6, 4) +#define MT_WCID_ATTR_RXWI_UDF GENMASK(9, 7) +#define MT_WCID_ATTR_PKEY_MODE_EXT BIT(10) +#define MT_WCID_ATTR_BSS_IDX_EXT BIT(11) +#define MT_WCID_ATTR_WAPI_MCBC BIT(15) +#define MT_WCID_ATTR_WAPI_KEYID GENMASK(31, 24) + +#define MT_SKEY_BASE_0 0xac00 +#define MT_SKEY_BASE_1 0xb400 +#define MT_SKEY_0(_bss, _idx) (MT_SKEY_BASE_0 + (4 * (_bss) + _idx) * 32) +#define MT_SKEY_1(_bss, _idx) (MT_SKEY_BASE_1 + (4 * ((_bss) & 7) + _idx) * 32) +#define MT_SKEY(_bss, _idx) ((_bss & 8) ? MT_SKEY_1(_bss, _idx) : MT_SKEY_0(_bss, _idx)) + +#define MT_SKEY_MODE_BASE_0 0xb000 +#define MT_SKEY_MODE_BASE_1 0xb3f0 +#define MT_SKEY_MODE_0(_bss) (MT_SKEY_MODE_BASE_0 + ((_bss / 2) << 2)) +#define MT_SKEY_MODE_1(_bss) (MT_SKEY_MODE_BASE_1 + ((((_bss) & 7) / 2) << 2)) +#define MT_SKEY_MODE(_bss) ((_bss & 8) ? MT_SKEY_MODE_1(_bss) : MT_SKEY_MODE_0(_bss)) +#define MT_SKEY_MODE_MASK GENMASK(3, 0) +#define MT_SKEY_MODE_SHIFT(_bss, _idx) (4 * ((_idx) + 4 * (_bss & 1))) + +#define MT_BEACON_BASE 0xc000 + +#define MT_TEMP_SENSOR 0x1d000 +#define MT_TEMP_SENSOR_VAL GENMASK(6, 0) + +struct mt76_wcid_addr { + u8 macaddr[6]; + __le16 ba_mask; +} __packed __aligned(4); + +struct mt76_wcid_key { + u8 key[16]; + u8 tx_mic[8]; + u8 rx_mic[8]; +} __packed __aligned(4); + +enum mt76x2_cipher_type { + MT_CIPHER_NONE, + MT_CIPHER_WEP40, + MT_CIPHER_WEP104, + MT_CIPHER_TKIP, + MT_CIPHER_AES_CCMP, + MT_CIPHER_CKIP40, + MT_CIPHER_CKIP104, + MT_CIPHER_CKIP128, + MT_CIPHER_WAPI, +}; + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_trace.c b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.c new file mode 100644 index 000000000000..a09f117848d6 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/module.h> + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "mt76x2_trace.h" + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h new file mode 100644 index 000000000000..4cd424148d4b --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__MT76x2_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __MT76x2_TRACE_H + +#include <linux/tracepoint.h> +#include "mt76x2.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mt76x2 + +#define MAXNAME 32 +#define DEV_ENTRY __array(char, wiphy_name, 32) +#define DEV_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(mt76_hw(dev)->wiphy), MAXNAME) +#define DEV_PR_FMT "%s" +#define DEV_PR_ARG __entry->wiphy_name + +#define TXID_ENTRY __field(u8, wcid) __field(u8, pktid) +#define TXID_ASSIGN __entry->wcid = wcid; __entry->pktid = pktid +#define TXID_PR_FMT " [%d:%d]" +#define TXID_PR_ARG __entry->wcid, __entry->pktid + +DECLARE_EVENT_CLASS(dev_evt, + TP_PROTO(struct mt76x2_dev *dev), + TP_ARGS(dev), + TP_STRUCT__entry( + DEV_ENTRY + ), + TP_fast_assign( + DEV_ASSIGN; + ), + TP_printk(DEV_PR_FMT, DEV_PR_ARG) +); + +DECLARE_EVENT_CLASS(dev_txid_evt, + TP_PROTO(struct mt76x2_dev *dev, u8 wcid, u8 pktid), + TP_ARGS(dev, wcid, pktid), + TP_STRUCT__entry( + DEV_ENTRY + TXID_ENTRY + ), + TP_fast_assign( + DEV_ASSIGN; + TXID_ASSIGN; + ), + TP_printk( + DEV_PR_FMT TXID_PR_FMT, + DEV_PR_ARG, TXID_PR_ARG + ) +); + +DEFINE_EVENT(dev_evt, mac_txstat_poll, + TP_PROTO(struct mt76x2_dev *dev), + TP_ARGS(dev) +); + +DEFINE_EVENT(dev_txid_evt, mac_txdone_add, + TP_PROTO(struct mt76x2_dev *dev, u8 wcid, u8 pktid), + TP_ARGS(dev, wcid, pktid) +); + +TRACE_EVENT(mac_txstat_fetch, + TP_PROTO(struct mt76x2_dev *dev, + struct mt76x2_tx_status *stat), + + TP_ARGS(dev, stat), + + TP_STRUCT__entry( + DEV_ENTRY + TXID_ENTRY + __field(bool, success) + __field(bool, aggr) + __field(bool, ack_req) + __field(u16, rate) + __field(u8, retry) + ), + + TP_fast_assign( + DEV_ASSIGN; + __entry->success = stat->success; + __entry->aggr = stat->aggr; + __entry->ack_req = stat->ack_req; + __entry->wcid = stat->wcid; + __entry->pktid = stat->pktid; + __entry->rate = stat->rate; + __entry->retry = stat->retry; + ), + + TP_printk( + DEV_PR_FMT TXID_PR_FMT + " success:%d aggr:%d ack_req:%d" + " rate:%04x retry:%d", + DEV_PR_ARG, TXID_PR_ARG, + __entry->success, __entry->aggr, __entry->ack_req, + __entry->rate, __entry->retry + ) +); + + +TRACE_EVENT(dev_irq, + TP_PROTO(struct mt76x2_dev *dev, u32 val, u32 mask), + + TP_ARGS(dev, val, mask), + + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, val) + __field(u32, mask) + ), + + TP_fast_assign( + DEV_ASSIGN; + __entry->val = val; + __entry->mask = mask; + ), + + TP_printk( + DEV_PR_FMT " %08x & %08x", + DEV_PR_ARG, __entry->val, __entry->mask + ) +); + +#endif + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE mt76x2_trace + +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c new file mode 100644 index 000000000000..1a32e1fb8743 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76x2.h" +#include "mt76x2_dma.h" + +struct beacon_bc_data { + struct mt76x2_dev *dev; + struct sk_buff_head q; + struct sk_buff *tail[8]; +}; + +void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct mt76x2_dev *dev = hw->priv; + struct ieee80211_vif *vif = info->control.vif; + struct mt76_wcid *wcid = &dev->global_wcid; + + if (control->sta) { + struct mt76x2_sta *msta; + + msta = (struct mt76x2_sta *) control->sta->drv_priv; + wcid = &msta->wcid; + } else if (vif) { + struct mt76x2_vif *mvif; + + mvif = (struct mt76x2_vif *) vif->drv_priv; + wcid = &mvif->group_wcid; + } + + mt76_tx(&dev->mt76, control->sta, wcid, skb); +} + +void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + ieee80211_free_txskb(mt76_hw(dev), skb); + } else { + ieee80211_tx_info_clear_status(info); + info->status.rates[0].idx = -1; + info->flags |= IEEE80211_TX_STAT_ACK; + ieee80211_tx_status(mt76_hw(dev), skb); + } +} + +s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev, + const struct ieee80211_tx_rate *rate) +{ + s8 max_txpwr; + + if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + u8 mcs = ieee80211_rate_get_vht_mcs(rate); + + if (mcs == 8 || mcs == 9) { + max_txpwr = dev->rate_power.vht[8]; + } else { + u8 nss, idx; + + nss = ieee80211_rate_get_vht_nss(rate); + idx = ((nss - 1) << 3) + mcs; + max_txpwr = dev->rate_power.ht[idx & 0xf]; + } + } else if (rate->flags & IEEE80211_TX_RC_MCS) { + max_txpwr = dev->rate_power.ht[rate->idx & 0xf]; + } else { + enum nl80211_band band = dev->mt76.chandef.chan->band; + + if (band == NL80211_BAND_2GHZ) { + const struct ieee80211_rate *r; + struct wiphy *wiphy = mt76_hw(dev)->wiphy; + struct mt76_rate_power *rp = &dev->rate_power; + + r = &wiphy->bands[band]->bitrates[rate->idx]; + if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE) + max_txpwr = rp->cck[r->hw_value & 0x3]; + else + max_txpwr = rp->ofdm[r->hw_value & 0x7]; + } else { + max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7]; + } + } + + return max_txpwr; +} + +s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj) +{ + txpwr = min_t(s8, txpwr, dev->txpower_conf); + txpwr -= (dev->target_power + dev->target_power_delta[0]); + txpwr = min_t(s8, txpwr, max_txpwr_adj); + + if (!dev->enable_tpc) + return 0; + else if (txpwr >= 0) + return min_t(s8, txpwr, 7); + else + return (txpwr < -16) ? 8 : (txpwr + 32) / 2; +} + +void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr) +{ + s8 txpwr_adj; + + txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, txpwr, + dev->rate_power.ofdm[4]); + mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG, + MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj); + mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG, + MT_PROT_AUTO_TX_CFG_AUTO_PADJ, txpwr_adj); +} + +static int mt76x2_insert_hdr_pad(struct sk_buff *skb) +{ + int len = ieee80211_get_hdrlen_from_skb(skb); + + if (len % 4 == 0) + return 0; + + skb_push(skb, 2); + memmove(skb->data, skb->data + 2, len); + + skb->data[len] = 0; + skb->data[len + 1] = 0; + return 2; +} + +int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, + struct sk_buff *skb, struct mt76_queue *q, + struct mt76_wcid *wcid, struct ieee80211_sta *sta, + u32 *tx_info) +{ + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int qsel = MT_QSEL_EDCA; + int ret; + + if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128) + mt76x2_mac_wcid_set_drop(dev, wcid->idx, false); + + mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta); + + ret = mt76x2_insert_hdr_pad(skb); + if (ret < 0) + return ret; + + if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) + qsel = MT_QSEL_MGMT; + + *tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) | + MT_TXD_INFO_80211; + + if (!wcid || wcid->hw_key_idx == 0xff) + *tx_info |= MT_TXD_INFO_WIV; + + return 0; +} + +static void +mt76x2_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) +{ + struct mt76x2_dev *dev = (struct mt76x2_dev *) priv; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct sk_buff *skb = NULL; + + if (!(dev->beacon_mask & BIT(mvif->idx))) + return; + + skb = ieee80211_beacon_get(mt76_hw(dev), vif); + if (!skb) + return; + + mt76x2_mac_set_beacon(dev, mvif->idx, skb); +} + +static void +mt76x2_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif) +{ + struct beacon_bc_data *data = priv; + struct mt76x2_dev *dev = data->dev; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct ieee80211_tx_info *info; + struct sk_buff *skb; + + if (!(dev->beacon_mask & BIT(mvif->idx))) + return; + + skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif); + if (!skb) + return; + + info = IEEE80211_SKB_CB(skb); + info->control.vif = vif; + info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; + mt76_skb_set_moredata(skb, true); + __skb_queue_tail(&data->q, skb); + data->tail[mvif->idx] = skb; +} + +void mt76x2_pre_tbtt_tasklet(unsigned long arg) +{ + struct mt76x2_dev *dev = (struct mt76x2_dev *) arg; + struct mt76_queue *q = &dev->mt76.q_tx[MT_TXQ_PSD]; + struct beacon_bc_data data = {}; + struct sk_buff *skb; + int i, nframes; + + data.dev = dev; + __skb_queue_head_init(&data.q); + + ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev), + IEEE80211_IFACE_ITER_RESUME_ALL, + mt76x2_update_beacon_iter, dev); + + do { + nframes = skb_queue_len(&data.q); + ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev), + IEEE80211_IFACE_ITER_RESUME_ALL, + mt76x2_add_buffered_bc, &data); + } while (nframes != skb_queue_len(&data.q)); + + if (!nframes) + return; + + for (i = 0; i < ARRAY_SIZE(data.tail); i++) { + if (!data.tail[i]) + continue; + + mt76_skb_set_moredata(data.tail[i], false); + } + + spin_lock_bh(&q->lock); + while ((skb = __skb_dequeue(&data.q)) != NULL) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = info->control.vif; + struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + + mt76_tx_queue_skb(&dev->mt76, q, skb, &mvif->group_wcid, NULL); + } + spin_unlock_bh(&q->lock); +} + diff --git a/drivers/net/wireless/mediatek/mt76/trace.c b/drivers/net/wireless/mediatek/mt76/trace.c new file mode 100644 index 000000000000..ea4ab8729ae4 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/trace.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/module.h> + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "trace.h" + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/trace.h b/drivers/net/wireless/mediatek/mt76/trace.h new file mode 100644 index 000000000000..ea30895933c5 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/trace.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__MT76_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __MT76_TRACE_H + +#include <linux/tracepoint.h> +#include "mt76.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mt76 + +#define MAXNAME 32 +#define DEV_ENTRY __array(char, wiphy_name, 32) +#define DEV_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(dev->hw->wiphy), MAXNAME) +#define DEV_PR_FMT "%s" +#define DEV_PR_ARG __entry->wiphy_name + +#define REG_ENTRY __field(u32, reg) __field(u32, val) +#define REG_ASSIGN __entry->reg = reg; __entry->val = val +#define REG_PR_FMT " %04x=%08x" +#define REG_PR_ARG __entry->reg, __entry->val + +DECLARE_EVENT_CLASS(dev_reg_evt, + TP_PROTO(struct mt76_dev *dev, u32 reg, u32 val), + TP_ARGS(dev, reg, val), + TP_STRUCT__entry( + DEV_ENTRY + REG_ENTRY + ), + TP_fast_assign( + DEV_ASSIGN; + REG_ASSIGN; + ), + TP_printk( + DEV_PR_FMT REG_PR_FMT, + DEV_PR_ARG, REG_PR_ARG + ) +); + +DEFINE_EVENT(dev_reg_evt, reg_rr, + TP_PROTO(struct mt76_dev *dev, u32 reg, u32 val), + TP_ARGS(dev, reg, val) +); + +DEFINE_EVENT(dev_reg_evt, reg_wr, + TP_PROTO(struct mt76_dev *dev, u32 reg, u32 val), + TP_ARGS(dev, reg, val) +); + +#endif + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c new file mode 100644 index 000000000000..4eef69bd8a9e --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76.h" + +static struct mt76_txwi_cache * +mt76_alloc_txwi(struct mt76_dev *dev) +{ + struct mt76_txwi_cache *t; + dma_addr_t addr; + int size; + + size = (sizeof(*t) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1); + t = devm_kzalloc(dev->dev, size, GFP_ATOMIC); + if (!t) + return NULL; + + addr = dma_map_single(dev->dev, &t->txwi, sizeof(t->txwi), + DMA_TO_DEVICE); + t->dma_addr = addr; + + return t; +} + +static struct mt76_txwi_cache * +__mt76_get_txwi(struct mt76_dev *dev) +{ + struct mt76_txwi_cache *t = NULL; + + spin_lock_bh(&dev->lock); + if (!list_empty(&dev->txwi_cache)) { + t = list_first_entry(&dev->txwi_cache, struct mt76_txwi_cache, + list); + list_del(&t->list); + } + spin_unlock_bh(&dev->lock); + + return t; +} + +static struct mt76_txwi_cache * +mt76_get_txwi(struct mt76_dev *dev) +{ + struct mt76_txwi_cache *t = __mt76_get_txwi(dev); + + if (t) + return t; + + return mt76_alloc_txwi(dev); +} + +void +mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t) +{ + if (!t) + return; + + spin_lock_bh(&dev->lock); + list_add(&t->list, &dev->txwi_cache); + spin_unlock_bh(&dev->lock); +} + +void mt76_tx_free(struct mt76_dev *dev) +{ + struct mt76_txwi_cache *t; + + while ((t = __mt76_get_txwi(dev)) != NULL) + dma_unmap_single(dev->dev, t->dma_addr, sizeof(t->txwi), + DMA_TO_DEVICE); +} + +static int +mt76_txq_get_qid(struct ieee80211_txq *txq) +{ + if (!txq->sta) + return MT_TXQ_BE; + + return txq->ac; +} + +int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_sta *sta) +{ + struct mt76_queue_entry e; + struct mt76_txwi_cache *t; + struct mt76_queue_buf buf[32]; + struct sk_buff *iter; + dma_addr_t addr; + int len; + u32 tx_info = 0; + int n, ret; + + t = mt76_get_txwi(dev); + if (!t) { + ieee80211_free_txskb(dev->hw, skb); + return -ENOMEM; + } + + dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi), + DMA_TO_DEVICE); + ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, q, wcid, sta, + &tx_info); + dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi), + DMA_TO_DEVICE); + if (ret < 0) + goto free; + + len = skb->len - skb->data_len; + addr = dma_map_single(dev->dev, skb->data, len, DMA_TO_DEVICE); + if (dma_mapping_error(dev->dev, addr)) { + ret = -ENOMEM; + goto free; + } + + n = 0; + buf[n].addr = t->dma_addr; + buf[n++].len = dev->drv->txwi_size; + buf[n].addr = addr; + buf[n++].len = len; + + skb_walk_frags(skb, iter) { + if (n == ARRAY_SIZE(buf)) + goto unmap; + + addr = dma_map_single(dev->dev, iter->data, iter->len, + DMA_TO_DEVICE); + if (dma_mapping_error(dev->dev, addr)) + goto unmap; + + buf[n].addr = addr; + buf[n++].len = iter->len; + } + + if (q->queued + (n + 1) / 2 >= q->ndesc - 1) + goto unmap; + + return dev->queue_ops->add_buf(dev, q, buf, n, tx_info, skb, t); + +unmap: + ret = -ENOMEM; + for (n--; n > 0; n--) + dma_unmap_single(dev->dev, buf[n].addr, buf[n].len, + DMA_TO_DEVICE); + +free: + e.skb = skb; + e.txwi = t; + dev->drv->tx_complete_skb(dev, q, &e, true); + mt76_put_txwi(dev, t); + return ret; +} +EXPORT_SYMBOL_GPL(mt76_tx_queue_skb); + +void +mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta, + struct mt76_wcid *wcid, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct mt76_queue *q; + int qid = skb_get_queue_mapping(skb); + + if (WARN_ON(qid >= MT_TXQ_PSD)) { + qid = MT_TXQ_BE; + skb_set_queue_mapping(skb, qid); + } + + if (!wcid->tx_rate_set) + ieee80211_get_tx_rates(info->control.vif, sta, skb, + info->control.rates, 1); + + q = &dev->q_tx[qid]; + + spin_lock_bh(&q->lock); + mt76_tx_queue_skb(dev, q, skb, wcid, sta); + dev->queue_ops->kick(dev, q); + + if (q->queued > q->ndesc - 8) + ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb)); + spin_unlock_bh(&q->lock); +} +EXPORT_SYMBOL_GPL(mt76_tx); + +static struct sk_buff * +mt76_txq_dequeue(struct mt76_dev *dev, struct mt76_txq *mtxq, bool ps) +{ + struct ieee80211_txq *txq = mtxq_to_txq(mtxq); + struct sk_buff *skb; + + skb = skb_dequeue(&mtxq->retry_q); + if (skb) { + u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; + + if (ps && skb_queue_empty(&mtxq->retry_q)) + ieee80211_sta_set_buffered(txq->sta, tid, false); + + return skb; + } + + skb = ieee80211_tx_dequeue(dev->hw, txq); + if (!skb) + return NULL; + + return skb; +} + +static void +mt76_check_agg_ssn(struct mt76_txq *mtxq, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + + if (!ieee80211_is_data_qos(hdr->frame_control)) + return; + + mtxq->agg_ssn = le16_to_cpu(hdr->seq_ctrl) + 0x10; +} + +static void +mt76_queue_ps_skb(struct mt76_dev *dev, struct ieee80211_sta *sta, + struct sk_buff *skb, bool last) +{ + struct mt76_wcid *wcid = (struct mt76_wcid *) sta->drv_priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct mt76_queue *hwq = &dev->q_tx[MT_TXQ_PSD]; + + info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE; + if (last) + info->flags |= IEEE80211_TX_STATUS_EOSP; + + mt76_skb_set_moredata(skb, !last); + mt76_tx_queue_skb(dev, hwq, skb, wcid, sta); +} + +void +mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + u16 tids, int nframes, + enum ieee80211_frame_release_type reason, + bool more_data) +{ + struct mt76_dev *dev = hw->priv; + struct sk_buff *last_skb = NULL; + struct mt76_queue *hwq = &dev->q_tx[MT_TXQ_PSD]; + int i; + + spin_lock_bh(&hwq->lock); + for (i = 0; tids && nframes; i++, tids >>= 1) { + struct ieee80211_txq *txq = sta->txq[i]; + struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv; + struct sk_buff *skb; + + if (!(tids & 1)) + continue; + + do { + skb = mt76_txq_dequeue(dev, mtxq, true); + if (!skb) + break; + + if (mtxq->aggr) + mt76_check_agg_ssn(mtxq, skb); + + nframes--; + if (last_skb) + mt76_queue_ps_skb(dev, sta, last_skb, false); + + last_skb = skb; + } while (nframes); + } + + if (last_skb) { + mt76_queue_ps_skb(dev, sta, last_skb, true); + dev->queue_ops->kick(dev, hwq); + } + spin_unlock_bh(&hwq->lock); +} +EXPORT_SYMBOL_GPL(mt76_release_buffered_frames); + +static int +mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq, + struct mt76_txq *mtxq, bool *empty) +{ + struct ieee80211_txq *txq = mtxq_to_txq(mtxq); + struct ieee80211_tx_info *info; + struct mt76_wcid *wcid = mtxq->wcid; + struct sk_buff *skb; + int n_frames = 1, limit; + struct ieee80211_tx_rate tx_rate; + bool ampdu; + bool probe; + int idx; + + skb = mt76_txq_dequeue(dev, mtxq, false); + if (!skb) { + *empty = true; + return 0; + } + + info = IEEE80211_SKB_CB(skb); + if (!wcid->tx_rate_set) + ieee80211_get_tx_rates(txq->vif, txq->sta, skb, + info->control.rates, 1); + tx_rate = info->control.rates[0]; + + probe = (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); + ampdu = IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU; + limit = ampdu ? 16 : 3; + + if (ampdu) + mt76_check_agg_ssn(mtxq, skb); + + idx = mt76_tx_queue_skb(dev, hwq, skb, wcid, txq->sta); + + if (idx < 0) + return idx; + + do { + bool cur_ampdu; + + if (probe) + break; + + if (test_bit(MT76_SCANNING, &dev->state) || + test_bit(MT76_RESET, &dev->state)) + return -EBUSY; + + skb = mt76_txq_dequeue(dev, mtxq, false); + if (!skb) { + *empty = true; + break; + } + + info = IEEE80211_SKB_CB(skb); + cur_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU; + + if (ampdu != cur_ampdu || + (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) { + skb_queue_tail(&mtxq->retry_q, skb); + break; + } + + info->control.rates[0] = tx_rate; + + if (cur_ampdu) + mt76_check_agg_ssn(mtxq, skb); + + idx = mt76_tx_queue_skb(dev, hwq, skb, wcid, txq->sta); + if (idx < 0) + return idx; + + n_frames++; + } while (n_frames < limit); + + if (!probe) { + hwq->swq_queued++; + hwq->entry[idx].schedule = true; + } + + dev->queue_ops->kick(dev, hwq); + + return n_frames; +} + +static int +mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq) +{ + struct mt76_txq *mtxq, *mtxq_last; + int len = 0; + +restart: + mtxq_last = list_last_entry(&hwq->swq, struct mt76_txq, list); + while (!list_empty(&hwq->swq)) { + bool empty = false; + int cur; + + mtxq = list_first_entry(&hwq->swq, struct mt76_txq, list); + if (mtxq->send_bar && mtxq->aggr) { + struct ieee80211_txq *txq = mtxq_to_txq(mtxq); + struct ieee80211_sta *sta = txq->sta; + struct ieee80211_vif *vif = txq->vif; + u16 agg_ssn = mtxq->agg_ssn; + u8 tid = txq->tid; + + mtxq->send_bar = false; + spin_unlock_bh(&hwq->lock); + ieee80211_send_bar(vif, sta->addr, tid, agg_ssn); + spin_lock_bh(&hwq->lock); + goto restart; + } + + list_del_init(&mtxq->list); + + cur = mt76_txq_send_burst(dev, hwq, mtxq, &empty); + if (!empty) + list_add_tail(&mtxq->list, &hwq->swq); + + if (cur < 0) + return cur; + + len += cur; + + if (mtxq == mtxq_last) + break; + } + + return len; +} + +void mt76_txq_schedule(struct mt76_dev *dev, struct mt76_queue *hwq) +{ + int len; + + do { + if (hwq->swq_queued >= 4 || list_empty(&hwq->swq)) + break; + + len = mt76_txq_schedule_list(dev, hwq); + } while (len > 0); +} +EXPORT_SYMBOL_GPL(mt76_txq_schedule); + +void mt76_txq_schedule_all(struct mt76_dev *dev) +{ + int i; + + for (i = 0; i <= MT_TXQ_BK; i++) { + struct mt76_queue *q = &dev->q_tx[i]; + + spin_lock_bh(&q->lock); + mt76_txq_schedule(dev, q); + spin_unlock_bh(&q->lock); + } +} +EXPORT_SYMBOL_GPL(mt76_txq_schedule_all); + +void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta, + bool send_bar) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { + struct ieee80211_txq *txq = sta->txq[i]; + struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv; + + spin_lock_bh(&mtxq->hwq->lock); + mtxq->send_bar = mtxq->aggr && send_bar; + if (!list_empty(&mtxq->list)) + list_del_init(&mtxq->list); + spin_unlock_bh(&mtxq->hwq->lock); + } +} +EXPORT_SYMBOL_GPL(mt76_stop_tx_queues); + +void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) +{ + struct mt76_dev *dev = hw->priv; + struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv; + struct mt76_queue *hwq = mtxq->hwq; + + spin_lock_bh(&hwq->lock); + if (list_empty(&mtxq->list)) + list_add_tail(&mtxq->list, &hwq->swq); + mt76_txq_schedule(dev, hwq); + spin_unlock_bh(&hwq->lock); +} +EXPORT_SYMBOL_GPL(mt76_wake_tx_queue); + +void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq) +{ + struct mt76_txq *mtxq; + struct mt76_queue *hwq; + struct sk_buff *skb; + + if (!txq) + return; + + mtxq = (struct mt76_txq *) txq->drv_priv; + hwq = mtxq->hwq; + + spin_lock_bh(&hwq->lock); + if (!list_empty(&mtxq->list)) + list_del(&mtxq->list); + spin_unlock_bh(&hwq->lock); + + while ((skb = skb_dequeue(&mtxq->retry_q)) != NULL) + ieee80211_free_txskb(dev->hw, skb); +} +EXPORT_SYMBOL_GPL(mt76_txq_remove); + +void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) +{ + struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv; + + INIT_LIST_HEAD(&mtxq->list); + skb_queue_head_init(&mtxq->retry_q); + + mtxq->hwq = &dev->q_tx[mt76_txq_get_qid(txq)]; +} +EXPORT_SYMBOL_GPL(mt76_txq_init); diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c new file mode 100644 index 000000000000..0c35b8db58cd --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/util.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/module.h> +#include "mt76.h" + +bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, + int timeout) +{ + u32 cur; + + timeout /= 10; + do { + cur = dev->bus->rr(dev, offset) & mask; + if (cur == val) + return true; + + udelay(10); + } while (timeout-- > 0); + + return false; +} +EXPORT_SYMBOL_GPL(__mt76_poll); + +bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, + int timeout) +{ + u32 cur; + + timeout /= 10; + do { + cur = dev->bus->rr(dev, offset) & mask; + if (cur == val) + return true; + + usleep_range(10000, 20000); + } while (timeout-- > 0); + + return false; +} +EXPORT_SYMBOL_GPL(__mt76_poll_msec); + +int mt76_wcid_alloc(unsigned long *mask, int size) +{ + int i, idx = 0, cur; + + for (i = 0; i < size / BITS_PER_LONG; i++) { + idx = ffs(~mask[i]); + if (!idx) + continue; + + idx--; + cur = i * BITS_PER_LONG + idx; + if (cur >= size) + break; + + mask[i] |= BIT(idx); + return cur; + } + + return -1; +} +EXPORT_SYMBOL_GPL(mt76_wcid_alloc); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/util.h b/drivers/net/wireless/mediatek/mt76/util.h new file mode 100644 index 000000000000..018d475504a2 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/util.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> + * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MT76_UTIL_H +#define __MT76_UTIL_H + +#include <linux/skbuff.h> +#include <linux/bitops.h> +#include <linux/bitfield.h> + +#define MT76_INCR(_var, _size) \ + _var = (((_var) + 1) % _size) + +int mt76_wcid_alloc(unsigned long *mask, int size); + +static inline void +mt76_wcid_free(unsigned long *mask, int idx) +{ + mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); +} + +static inline void +mt76_skb_set_moredata(struct sk_buff *skb, bool enable) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + + if (enable) + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); + else + hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c index e6668ffb77e6..ff0971f1e2c8 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c @@ -688,10 +688,7 @@ static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel) cck_power = priv->channels[channel - 1].hw_value & 0xF; ofdm_power = priv->channels[channel - 1].hw_value >> 4; - if (cck_power > 15) - cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22; - else - cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; + cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; cck_power += priv->txpwr_base & 0xF; cck_power = min(cck_power, (u8)35); diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index cad2272ae21b..704741d6f495 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -1726,7 +1726,7 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv) { struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; - u8 reject_agg, ctrl_agg_size = 0, agg_size; + u8 reject_agg = 0, ctrl_agg_size = 0, agg_size = 0; if (rtlpriv->cfg->ops->get_btc_status()) btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg, diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index c2575b0b9440..4013394fac33 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -59,6 +59,7 @@ static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, struct sk_buff *skb) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); __le16 fc = rtl_get_fc(skb); u8 queue_index = skb_get_queue_mapping(skb); + struct ieee80211_hdr *hdr; if (unlikely(ieee80211_is_beacon(fc))) return BEACON_QUEUE; @@ -67,6 +68,13 @@ static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, struct sk_buff *skb) if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) if (ieee80211_is_nullfunc(fc)) return HIGH_QUEUE; + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { + hdr = rtl_get_hdr(skb); + + if (is_multicast_ether_addr(hdr->addr1) || + is_broadcast_ether_addr(hdr->addr1)) + return HIGH_QUEUE; + } return ac_to_hwq[queue_index]; } @@ -557,13 +565,6 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) else entry = (u8 *)(&ring->desc[ring->idx]); - if (rtlpriv->cfg->ops->get_available_desc && - rtlpriv->cfg->ops->get_available_desc(hw, prio) <= 1) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_DMESG, - "no available desc!\n"); - return; - } - if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx)) return; ring->idx = (ring->idx + 1) % ring->entries; @@ -747,7 +748,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) u8 tmp_one; bool unicast = false; u8 hw_queue = 0; - unsigned int rx_remained_cnt; + unsigned int rx_remained_cnt = 0; struct rtl_stats stats = { .signal = 0, .rate = 0, @@ -768,7 +769,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) struct sk_buff *new_skb; if (rtlpriv->use_new_trx_flow) { - rx_remained_cnt = + if (rx_remained_cnt == 0) + rx_remained_cnt = rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw, hw_queue); if (rx_remained_cnt == 0) @@ -924,10 +926,8 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); unsigned long flags; - u32 inta = 0; - u32 intb = 0; - u32 intc = 0; - u32 intd = 0; + struct rtl_int intvec = {0}; + irqreturn_t ret = IRQ_HANDLED; if (rtlpci->irq_enabled == 0) @@ -937,47 +937,47 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->cfg->ops->disable_interrupt(hw); /*read ISR: 4/8bytes */ - rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb, &intc, &intd); + rtlpriv->cfg->ops->interrupt_recognized(hw, &intvec); /*Shared IRQ or HW disappeared */ - if (!inta || inta == 0xffff) + if (!intvec.inta || intvec.inta == 0xffff) goto done; /*<1> beacon related */ - if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon ok interrupt!\n"); - if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) + if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon err interrupt!\n"); - if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); - if (inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<2> Tx related */ - if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) + if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); - if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } - if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } - if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -985,7 +985,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) _rtl_pci_tx_isr(hw, BK_QUEUE); } - if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -993,7 +993,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) _rtl_pci_tx_isr(hw, BE_QUEUE); } - if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -1001,7 +1001,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) _rtl_pci_tx_isr(hw, VI_QUEUE); } - if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -1010,7 +1010,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) } if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { - if (intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) { + if (intvec.intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) { rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -1020,7 +1020,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) } if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { - if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -1030,25 +1030,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) } /*<3> Rx related */ - if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } - if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { + if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } - if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { + if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } /*<4> fw related*/ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) { - if (inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "firmware interrupt!\n"); queue_delayed_work(rtlpriv->works.rtl_wq, @@ -1064,7 +1064,8 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) */ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE || rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) { - if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) { + if (unlikely(intvec.inta & + rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "hsisr interrupt!\n"); _rtl_pci_hs_interrupt(hw); @@ -1250,7 +1251,6 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, rtlpci->tx_ring[prio].cur_tx_rp = 0; rtlpci->tx_ring[prio].cur_tx_wp = 0; - rtlpci->tx_ring[prio].avl_desc = entries; } /* alloc dma for this ring */ @@ -1555,7 +1555,14 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) dev_kfree_skb_irq(skb); ring->idx = (ring->idx + 1) % ring->entries; } + + if (rtlpriv->use_new_trx_flow) { + rtlpci->tx_ring[i].cur_tx_rp = 0; + rtlpci->tx_ring[i].cur_tx_wp = 0; + } + ring->idx = 0; + ring->entries = rtlpci->txringcount[i]; } } spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h index e7d070e8da2d..3fb56c845a61 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.h +++ b/drivers/net/wireless/realtek/rtlwifi/pci.h @@ -173,7 +173,6 @@ struct rtl8192_tx_ring { /*add for new trx flow*/ struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/ dma_addr_t buffer_desc_dma; /*tx bufferd desc dma memory*/ - u16 avl_desc; /* available_desc_to_write */ u16 cur_tx_wp; /* current_tx_write_point */ u16 cur_tx_rp; /* current_tx_read_point */ }; @@ -320,10 +319,10 @@ static inline void pci_write32_async(struct rtl_priv *rtlpriv, writel(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } -static inline u16 calc_fifo_space(u16 rp, u16 wp) +static inline u16 calc_fifo_space(u16 rp, u16 wp, u16 size) { if (rp <= wp) - return RTL_PCI_MAX_RX_COUNT - 1 + rp - wp; + return size - 1 + rp - wp; return rp - wp - 1; } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c index e30a18e64ff5..988d5ac57d02 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -1472,17 +1472,16 @@ void rtl88ee_card_disable(struct ieee80211_hw *hw) } void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); - *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; - rtl_write_dword(rtlpriv, REG_HISRE, *p_intb); + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h index cdf49de1e6ed..214cd2a32018 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h @@ -29,8 +29,7 @@ void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw); void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl88ee_hw_init(struct ieee80211_hw *hw); void rtl88ee_card_disable(struct ieee80211_hw *hw); void rtl88ee_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c index 0f4c86a28716..4a81e0ef4b8e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c @@ -1375,19 +1375,13 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw) } void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); - - /* - * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; - * rtl_write_dword(rtlpriv, ISR + 4, *p_intb); - */ + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); } void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h index b5c8e2fc1ba2..6711ea1a75d9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h @@ -42,8 +42,7 @@ static inline u8 rtl92c_get_chnl_group(u8 chnl) void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl92ce_hw_init(struct ieee80211_hw *hw); void rtl92ce_card_disable(struct ieee80211_hw *hw); void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c index 0da6c0136857..80123fd97221 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c @@ -1356,19 +1356,13 @@ void rtl92de_card_disable(struct ieee80211_hw *hw) } void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); - - /* - * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; - * rtl_write_dword(rtlpriv, ISR + 4, *p_intb); - */ + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); } void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h index 9236aa91273d..e6c702e69ecf 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h @@ -29,8 +29,7 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92de_read_eeprom_info(struct ieee80211_hw *hw); void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl92de_hw_init(struct ieee80211_hw *hw); void rtl92de_card_disable(struct ieee80211_hw *hw); void rtl92de_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c index fe5da637e77a..fd7928fdbd1a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c @@ -1694,17 +1694,16 @@ void rtl92ee_card_disable(struct ieee80211_hw *hw) } void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); - *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; - rtl_write_dword(rtlpriv, REG_HISRE, *p_intb); + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); } void rtl92ee_set_beacon_related_registers(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h index cd6d3322f033..3a63bec9b0cc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h @@ -29,8 +29,7 @@ void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92ee_read_eeprom_info(struct ieee80211_hw *hw); void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl92ee_hw_init(struct ieee80211_hw *hw); void rtl92ee_card_disable(struct ieee80211_hw *hw); void rtl92ee_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c index 12255682e890..4f7444331b07 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c @@ -498,7 +498,8 @@ u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index) if (!start_rx) return 0; - remind_cnt = calc_fifo_space(read_point, write_point); + remind_cnt = calc_fifo_space(read_point, write_point, + RTL_PCI_MAX_RX_COUNT); if (remind_cnt == 0) return 0; @@ -548,7 +549,6 @@ static u16 get_desc_addr_fr_q_idx(u16 queue_index) u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) { - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_priv *rtlpriv = rtl_priv(hw); u16 point_diff = 0; u16 current_tx_read_point = 0, current_tx_write_point = 0; @@ -560,9 +560,9 @@ u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) current_tx_write_point = (u16)((tmp_4byte) & 0x0fff); point_diff = calc_fifo_space(current_tx_read_point, - current_tx_write_point); + current_tx_write_point, + TX_DESC_NUM_92E); - rtlpci->tx_ring[q_idx].avl_desc = point_diff; return point_diff; } @@ -907,10 +907,6 @@ void rtl92ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, u8 desc_name, u8 *val) { struct rtl_priv *rtlpriv = rtl_priv(hw); - u16 cur_tx_rp = 0; - u16 cur_tx_wp = 0; - static bool over_run; - u32 tmp = 0; u8 q_idx = *val; bool dma64 = rtlpriv->cfg->mod_params->dma64; @@ -931,38 +927,12 @@ void rtl92ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, return; } + /* make sure tx desc is available by caller */ ring->cur_tx_wp = ((ring->cur_tx_wp + 1) % max_tx_desc); - if (over_run) { - ring->cur_tx_wp = 0; - over_run = false; - } - if (ring->avl_desc > 1) { - ring->avl_desc--; - - rtl_write_word(rtlpriv, - get_desc_addr_fr_q_idx(q_idx), - ring->cur_tx_wp); - } - - if (ring->avl_desc < (max_tx_desc - 15)) { - u16 point_diff = 0; - - tmp = - rtl_read_dword(rtlpriv, - get_desc_addr_fr_q_idx(q_idx)); - cur_tx_rp = (u16)((tmp >> 16) & 0x0fff); - cur_tx_wp = (u16)(tmp & 0x0fff); - - ring->cur_tx_wp = cur_tx_wp; - ring->cur_tx_rp = cur_tx_rp; - point_diff = ((cur_tx_rp > cur_tx_wp) ? - (cur_tx_rp - cur_tx_wp) : - (TX_DESC_NUM_92E - 1 - - cur_tx_wp + cur_tx_rp)); - - ring->avl_desc = point_diff; - } + rtl_write_word(rtlpriv, + get_desc_addr_fr_q_idx(q_idx), + ring->cur_tx_wp); } break; } @@ -1044,13 +1014,12 @@ bool rtl92ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_priv *rtlpriv = rtl_priv(hw); - u16 read_point, write_point, available_desc_num; + u16 read_point, write_point; bool ret = false; static u8 stop_report_cnt; struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; { - u16 point_diff = 0; u16 cur_tx_rp, cur_tx_wp; u32 tmpu32 = 0; @@ -1060,18 +1029,12 @@ bool rtl92ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index) cur_tx_rp = (u16)((tmpu32 >> 16) & 0x0fff); cur_tx_wp = (u16)(tmpu32 & 0x0fff); - ring->cur_tx_wp = cur_tx_wp; + /* don't need to update ring->cur_tx_wp */ ring->cur_tx_rp = cur_tx_rp; - point_diff = ((cur_tx_rp > cur_tx_wp) ? - (cur_tx_rp - cur_tx_wp) : - (TX_DESC_NUM_92E - cur_tx_wp + cur_tx_rp)); - - ring->avl_desc = point_diff; } read_point = ring->cur_tx_rp; write_point = ring->cur_tx_wp; - available_desc_num = ring->avl_desc; if (write_point > read_point) { if (index < write_point && index >= read_point) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c index 76bf089cced4..30dea7b9bc17 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c @@ -1558,17 +1558,17 @@ void rtl92se_card_disable(struct ieee80211_hw *hw) udelay(100); } -void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, - u32 *p_intb, u32 *p_intc, u32 *p_intd) +void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); - *p_intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1]; - rtl_write_dword(rtlpriv, ISR + 4, *p_intb); + intvec->intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, ISR + 4, intvec->intb); } void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h index 607056010974..fa836ceefc8f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h @@ -42,8 +42,7 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92se_read_eeprom_info(struct ieee80211_hw *hw); void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl92se_hw_init(struct ieee80211_hw *hw); void rtl92se_card_disable(struct ieee80211_hw *hw); void rtl92se_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c index c3f98d58124c..545115db507e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c @@ -1340,14 +1340,13 @@ void rtl8723e_card_disable(struct ieee80211_hw *hw) } void rtl8723e_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, 0x3a0, *p_inta); + intvec->inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, 0x3a0, intvec->inta); } void rtl8723e_set_beacon_related_registers(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h index 19e467a37c72..c76e453f4f43 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h @@ -34,8 +34,7 @@ void rtl8723e_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl8723e_read_eeprom_info(struct ieee80211_hw *hw); void rtl8723e_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl8723e_hw_init(struct ieee80211_hw *hw); void rtl8723e_card_disable(struct ieee80211_hw *hw); void rtl8723e_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index 7cd1ffa7d4a7..f9ccd13c79f9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -43,6 +43,7 @@ #include "../pwrseqcmd.h" #include "pwrseq.h" #include "../btcoexist/rtl_btc.h" +#include <linux/kernel.h> #define LLT_CONFIG 5 @@ -1682,18 +1683,17 @@ void rtl8723be_card_disable(struct ieee80211_hw *hw) } void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); - *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & - rtlpci->irq_mask[1]; - rtl_write_dword(rtlpriv, REG_HISRE, *p_intb); + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & + rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); } void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw) @@ -2127,28 +2127,28 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw, if (rtlhal->oem_id == RT_CID_DEFAULT) { /* Does this one have a Toshiba SMID from group 1? */ - for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) { + for (i = 0; i < ARRAY_SIZE(toshiba_smid1); i++) { if (rtlefuse->eeprom_smid == toshiba_smid1[i]) { is_toshiba_smid1 = true; break; } } /* Does this one have a Toshiba SMID from group 2? */ - for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) { + for (i = 0; i < ARRAY_SIZE(toshiba_smid2); i++) { if (rtlefuse->eeprom_smid == toshiba_smid2[i]) { is_toshiba_smid2 = true; break; } } /* Does this one have a Samsung SMID? */ - for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) { + for (i = 0; i < ARRAY_SIZE(samsung_smid); i++) { if (rtlefuse->eeprom_smid == samsung_smid[i]) { is_samsung_smid = true; break; } } /* Does this one have a Lenovo SMID? */ - for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) { + for (i = 0; i < ARRAY_SIZE(lenovo_smid); i++) { if (rtlefuse->eeprom_smid == lenovo_smid[i]) { is_lenovo_smid = true; break; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h index 2215a792f6bf..ae856a19e81a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h @@ -30,8 +30,7 @@ void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw); void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl8723be_hw_init(struct ieee80211_hw *hw); void rtl8723be_card_disable(struct ieee80211_hw *hw); void rtl8723be_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c index 9606641519e7..1263b12db5dc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c @@ -35,6 +35,7 @@ #include "../rtl8723com/dm_common.h" #include "table.h" #include "trx.h" +#include <linux/kernel.h> static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw); static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); @@ -1143,14 +1144,13 @@ void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) DESC92C_RATEMCS2, DESC92C_RATEMCS3, DESC92C_RATEMCS4, DESC92C_RATEMCS5, DESC92C_RATEMCS6, DESC92C_RATEMCS7}; - u8 i, size; + u8 i; u8 power_index; if (!rtlefuse->txpwr_fromeprom) return; - size = sizeof(cck_rates) / sizeof(u8); - for (i = 0; i < size; i++) { + for (i = 0; i < ARRAY_SIZE(cck_rates); i++) { power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, cck_rates[i], rtl_priv(hw)->phy.current_chan_bw, @@ -1158,8 +1158,7 @@ void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, cck_rates[i]); } - size = sizeof(ofdm_rates) / sizeof(u8); - for (i = 0; i < size; i++) { + for (i = 0; i < ARRAY_SIZE(ofdm_rates); i++) { power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, ofdm_rates[i], rtl_priv(hw)->phy.current_chan_bw, @@ -1167,8 +1166,7 @@ void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, ofdm_rates[i]); } - size = sizeof(ht_rates_1t) / sizeof(u8); - for (i = 0; i < size; i++) { + for (i = 0; i < ARRAY_SIZE(ht_rates_1t); i++) { power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, ht_rates_1t[i], rtl_priv(hw)->phy.current_chan_bw, diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c index 381c16b9b3a9..160fee8333ae 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c @@ -25,6 +25,7 @@ * *****************************************************************************/ +#include <linux/kernel.h> #include "table.h" u32 RTL8723BEPHY_REG_1TARRAY[] = { @@ -224,8 +225,7 @@ u32 RTL8723BEPHY_REG_1TARRAY[] = { }; -u32 RTL8723BEPHY_REG_1TARRAYLEN = - sizeof(RTL8723BEPHY_REG_1TARRAY) / sizeof(u32); +u32 RTL8723BEPHY_REG_1TARRAYLEN = ARRAY_SIZE(RTL8723BEPHY_REG_1TARRAY); u32 RTL8723BEPHY_REG_ARRAY_PG[] = { 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003800, @@ -236,8 +236,7 @@ u32 RTL8723BEPHY_REG_ARRAY_PG[] = { 0, 0, 0, 0x00000e14, 0xffffffff, 0x26303436 }; -u32 RTL8723BEPHY_REG_ARRAY_PGLEN = - sizeof(RTL8723BEPHY_REG_ARRAY_PG) / sizeof(u32); +u32 RTL8723BEPHY_REG_ARRAY_PGLEN = ARRAY_SIZE(RTL8723BEPHY_REG_ARRAY_PG); u32 RTL8723BE_RADIOA_1TARRAY[] = { 0x000, 0x00010000, @@ -373,8 +372,7 @@ u32 RTL8723BE_RADIOA_1TARRAY[] = { }; -u32 RTL8723BE_RADIOA_1TARRAYLEN = - sizeof(RTL8723BE_RADIOA_1TARRAY) / sizeof(u32); +u32 RTL8723BE_RADIOA_1TARRAYLEN = ARRAY_SIZE(RTL8723BE_RADIOA_1TARRAY); u32 RTL8723BEMAC_1T_ARRAY[] = { 0x02F, 0x00000030, @@ -483,7 +481,7 @@ u32 RTL8723BEMAC_1T_ARRAY[] = { }; -u32 RTL8723BEMAC_1T_ARRAYLEN = sizeof(RTL8723BEMAC_1T_ARRAY) / sizeof(u32); +u32 RTL8723BEMAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8723BEMAC_1T_ARRAY); u32 RTL8723BEAGCTAB_1TARRAY[] = { 0xC78, 0xFD000001, @@ -620,4 +618,4 @@ u32 RTL8723BEAGCTAB_1TARRAY[] = { }; -u32 RTL8723BEAGCTAB_1TARRAYLEN = sizeof(RTL8723BEAGCTAB_1TARRAY) / sizeof(u32); +u32 RTL8723BEAGCTAB_1TARRAYLEN = ARRAY_SIZE(RTL8723BEAGCTAB_1TARRAY); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 43e18c4c1e68..f20e77b4bb65 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -2483,17 +2483,16 @@ void rtl8821ae_card_disable(struct ieee80211_hw *hw) } void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd) + struct rtl_int *intvec) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, ISR, *p_inta); + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); - *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; - rtl_write_dword(rtlpriv, REG_HISRE, *p_intb); + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); } void rtl8821ae_set_beacon_related_registers(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h index 284d259fe557..e2ab783a2ad9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h @@ -30,8 +30,7 @@ void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw); void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *int_vec); int rtl8821ae_hw_init(struct ieee80211_hw *hw); void rtl8821ae_card_disable(struct ieee80211_hw *hw); void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c index 408c4611e5de..f87f9d03b9fa 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c @@ -24,7 +24,7 @@ * Larry Finger <Larry.Finger@lwfinger.net> * *****************************************************************************/ - +#include <linux/kernel.h> #include "table.h" u32 RTL8812AE_PHY_REG_ARRAY[] = { 0x800, 0x8020D010, @@ -258,8 +258,7 @@ u32 RTL8812AE_PHY_REG_ARRAY[] = { 0xEB8, 0x00508242, }; -u32 RTL8812AE_PHY_REG_1TARRAYLEN = - sizeof(RTL8812AE_PHY_REG_ARRAY) / sizeof(u32); +u32 RTL8812AE_PHY_REG_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_PHY_REG_ARRAY); u32 RTL8821AE_PHY_REG_ARRAY[] = { 0x800, 0x0020D090, @@ -436,8 +435,7 @@ u32 RTL8821AE_PHY_REG_ARRAY[] = { 0xCB8, 0x00508240, }; -u32 RTL8821AE_PHY_REG_1TARRAYLEN = - sizeof(RTL8821AE_PHY_REG_ARRAY) / sizeof(u32); +u32 RTL8821AE_PHY_REG_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_PHY_REG_ARRAY); u32 RTL8812AE_PHY_REG_ARRAY_PG[] = { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, @@ -488,8 +486,7 @@ u32 RTL8812AE_PHY_REG_ARRAY_PG[] = { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628 }; -u32 RTL8812AE_PHY_REG_ARRAY_PGLEN = - sizeof(RTL8812AE_PHY_REG_ARRAY_PG) / sizeof(u32); +u32 RTL8812AE_PHY_REG_ARRAY_PGLEN = ARRAY_SIZE(RTL8812AE_PHY_REG_ARRAY_PG); u32 RTL8821AE_PHY_REG_ARRAY_PG[] = { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, @@ -509,8 +506,7 @@ u32 RTL8821AE_PHY_REG_ARRAY_PG[] = { 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022 }; -u32 RTL8821AE_PHY_REG_ARRAY_PGLEN = - sizeof(RTL8821AE_PHY_REG_ARRAY_PG) / sizeof(u32); +u32 RTL8821AE_PHY_REG_ARRAY_PGLEN = ARRAY_SIZE(RTL8821AE_PHY_REG_ARRAY_PG); u32 RTL8812AE_RADIOA_ARRAY[] = { 0x000, 0x00010000, @@ -927,7 +923,7 @@ u32 RTL8812AE_RADIOA_ARRAY[] = { 0x018, 0x0001712A, }; -u32 RTL8812AE_RADIOA_1TARRAYLEN = sizeof(RTL8812AE_RADIOA_ARRAY) / sizeof(u32); +u32 RTL8812AE_RADIOA_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_RADIOA_ARRAY); u32 RTL8812AE_RADIOB_ARRAY[] = { 0x056, 0x00051CF2, @@ -1335,7 +1331,7 @@ u32 RTL8812AE_RADIOB_ARRAY[] = { 0x008, 0x00008400, }; -u32 RTL8812AE_RADIOB_1TARRAYLEN = sizeof(RTL8812AE_RADIOB_ARRAY) / sizeof(u32); +u32 RTL8812AE_RADIOB_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_RADIOB_ARRAY); u32 RTL8821AE_RADIOA_ARRAY[] = { 0x018, 0x0001712A, @@ -1929,7 +1925,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { }; -u32 RTL8821AE_RADIOA_1TARRAYLEN = sizeof(RTL8821AE_RADIOA_ARRAY) / sizeof(u32); +u32 RTL8821AE_RADIOA_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_RADIOA_ARRAY); u32 RTL8812AE_MAC_REG_ARRAY[] = { 0x010, 0x0000000C, @@ -2041,7 +2037,7 @@ u32 RTL8812AE_MAC_REG_ARRAY[] = { 0x718, 0x00000040, }; -u32 RTL8812AE_MAC_1T_ARRAYLEN = sizeof(RTL8812AE_MAC_REG_ARRAY) / sizeof(u32); +u32 RTL8812AE_MAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8812AE_MAC_REG_ARRAY); u32 RTL8821AE_MAC_REG_ARRAY[] = { 0x428, 0x0000000A, @@ -2143,7 +2139,7 @@ u32 RTL8821AE_MAC_REG_ARRAY[] = { 0x718, 0x00000040, }; -u32 RTL8821AE_MAC_1T_ARRAYLEN = sizeof(RTL8821AE_MAC_REG_ARRAY) / sizeof(u32); +u32 RTL8821AE_MAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8821AE_MAC_REG_ARRAY); u32 RTL8812AE_AGC_TAB_ARRAY[] = { 0x80000001, 0x00000000, 0x40000000, 0x00000000, @@ -2479,8 +2475,7 @@ u32 RTL8812AE_AGC_TAB_ARRAY[] = { 0xE50, 0x00000020, }; -u32 RTL8812AE_AGC_TAB_1TARRAYLEN = - sizeof(RTL8812AE_AGC_TAB_ARRAY) / sizeof(u32); +u32 RTL8812AE_AGC_TAB_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_AGC_TAB_ARRAY); u32 RTL8821AE_AGC_TAB_ARRAY[] = { 0x81C, 0xBF000001, @@ -2676,8 +2671,7 @@ u32 RTL8821AE_AGC_TAB_ARRAY[] = { 0xC50, 0x00000020, }; -u32 RTL8821AE_AGC_TAB_1TARRAYLEN = - sizeof(RTL8821AE_AGC_TAB_ARRAY) / sizeof(u32); +u32 RTL8821AE_AGC_TAB_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_AGC_TAB_ARRAY); /****************************************************************************** * TXPWR_LMT.TXT @@ -3250,7 +3244,7 @@ u8 *RTL8812AE_TXPWR_LMT[] = { "MKK", "5G", "80M", "VHT", "2T", "155", "63" }; -u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = sizeof(RTL8812AE_TXPWR_LMT) / sizeof(u8 *); +u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8812AE_TXPWR_LMT); u8 *RTL8821AE_TXPWR_LMT[] = { "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", @@ -3819,4 +3813,4 @@ u8 *RTL8821AE_TXPWR_LMT[] = { "MKK", "5G", "80M", "VHT", "2T", "155", "63" }; -u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN = sizeof(RTL8821AE_TXPWR_LMT) / sizeof(u8 *); +u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8821AE_TXPWR_LMT); diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index 92d4859ec906..e2b14793b705 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -2093,14 +2093,21 @@ struct rtl_wow_pattern { u32 mask[4]; }; +/* struct to store contents of interrupt vectors */ +struct rtl_int { + u32 inta; + u32 intb; + u32 intc; + u32 intd; +}; + struct rtl_hal_ops { int (*init_sw_vars) (struct ieee80211_hw *hw); void (*deinit_sw_vars) (struct ieee80211_hw *hw); void (*read_chip_version)(struct ieee80211_hw *hw); void (*read_eeprom_info) (struct ieee80211_hw *hw); void (*interrupt_recognized) (struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb, - u32 *p_intc, u32 *p_intd); + struct rtl_int *intvec); int (*hw_init) (struct ieee80211_hw *hw); void (*hw_disable) (struct ieee80211_hw *hw); void (*hw_suspend) (struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/ti/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c index 1d799bffaa9f..e7d77acdf18c 100644 --- a/drivers/net/wireless/ti/wl1251/init.c +++ b/drivers/net/wireless/ti/wl1251/init.c @@ -310,10 +310,8 @@ static int wl1251_hw_init_data_path_config(struct wl1251 *wl) /* asking for the data path parameters */ wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp), GFP_KERNEL); - if (!wl->data_path) { - wl1251_error("Couldnt allocate data path parameters"); + if (!wl->data_path) return -ENOMEM; - } ret = wl1251_acx_data_path_params(wl, wl->data_path); if (ret < 0) { diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index a4859993db3c..3ca9167d6146 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -146,7 +146,7 @@ int wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif) ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG, feature, sizeof(*feature)); if (ret < 0) { - wl1271_error("Couldnt set HW encryption"); + wl1271_error("Couldn't set HW encryption"); goto out; } diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index f46d7fdf9a00..7011c5d9599f 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -1129,10 +1129,8 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl); int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif, s8 *avg_rssi); -#ifdef CONFIG_PM int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action); int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, struct wl12xx_rx_filter *filter); -#endif /* CONFIG_PM */ #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index d47921a84509..09714034dbf1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -42,6 +42,7 @@ #include "sysfs.h" #define WL1271_BOOT_RETRIES 3 +#define WL1271_SUSPEND_SLEEP 100 static char *fwlog_param; static int fwlog_mem_blocks = -1; @@ -388,7 +389,6 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) { struct wl12xx_vif *wlvif; - struct timespec ts; u32 old_tx_blk_count = wl->tx_blocks_available; int avail, freed_blocks; int i; @@ -485,8 +485,7 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) } /* update the host-chipset time offset */ - getnstimeofday(&ts); - wl->time_offset = (timespec_to_ns(&ts) >> 10) - + wl->time_offset = (ktime_get_boot_ns() >> 10) - (s64)(status->fw_localtime); wl->fw_fast_lnk_map = status->link_fast_bitmap; @@ -979,6 +978,24 @@ static int wlcore_fw_wakeup(struct wl1271 *wl) return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); } +static int wlcore_fw_sleep(struct wl1271 *wl) +{ + int ret; + + mutex_lock(&wl->mutex); + ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } + set_bit(WL1271_FLAG_IN_ELP, &wl->flags); +out: + mutex_unlock(&wl->mutex); + mdelay(WL1271_SUSPEND_SLEEP); + + return 0; +} + static int wl1271_setup(struct wl1271 *wl) { wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL); @@ -1326,7 +1343,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) } -#ifdef CONFIG_PM static int wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p) { @@ -1698,8 +1714,8 @@ static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif) } } -static int wl1271_op_suspend(struct ieee80211_hw *hw, - struct cfg80211_wowlan *wow) +static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wow) { struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif; @@ -1749,7 +1765,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, goto out_sleep; out_sleep: - wl1271_ps_elp_sleep(wl); mutex_unlock(&wl->mutex); if (ret < 0) { @@ -1782,10 +1797,19 @@ out_sleep: */ cancel_delayed_work(&wl->tx_watchdog_work); + /* + * Use an immediate call for allowing the firmware to go into power + * save during suspend. + * Using a workque for this last write was only hapenning on resume + * leaving the firmware with power save disabled during suspend, + * while consuming full power during wowlan suspend. + */ + wlcore_fw_sleep(wl); + return 0; } -static int wl1271_op_resume(struct ieee80211_hw *hw) +static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) { struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif; @@ -1869,7 +1893,6 @@ out: return 0; } -#endif static int wl1271_op_start(struct ieee80211_hw *hw) { diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index a3f5e9ca492a..00e9b4624dcf 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -264,7 +264,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct sk_buff *skb, u32 extra, struct ieee80211_tx_info *control, u8 hlid) { - struct timespec ts; struct wl1271_tx_hw_descr *desc; int ac, rate_idx; s64 hosttime; @@ -287,8 +286,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, } /* configure packet life time */ - getnstimeofday(&ts); - hosttime = (timespec_to_ns(&ts) >> 10); + hosttime = (ktime_get_boot_ns() >> 10); desc->start_time = cpu_to_le32(hosttime - wl->time_offset); is_dummy = wl12xx_is_dummy_packet(wl, skb); diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f837d666cbd4..1e46e60b8f10 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1287,7 +1287,7 @@ static void nvme_config_discard(struct nvme_ctrl *ctrl, BUILD_BUG_ON(PAGE_SIZE / sizeof(struct nvme_dsm_range) < NVME_DSM_MAX_RANGES); - queue->limits.discard_alignment = size; + queue->limits.discard_alignment = 0; queue->limits.discard_granularity = size; blk_queue_max_discard_sectors(queue, UINT_MAX); @@ -1705,7 +1705,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); } - if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) + if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && + is_power_of_2(ctrl->max_hw_sectors)) blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); blk_queue_virt_boundary(q, ctrl->page_size - 1); if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) @@ -2869,7 +2870,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); nvme_set_queue_limits(ctrl, ns->queue); - nvme_setup_streams_ns(ctrl, ns); id = nvme_identify_ns(ctrl, nsid); if (!id) @@ -2880,6 +2880,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) if (nvme_init_ns_head(ns, nsid, id, &new)) goto out_free_id; + nvme_setup_streams_ns(ctrl, ns); #ifdef CONFIG_NVME_MULTIPATH /* @@ -2965,8 +2966,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) return; if (ns->disk && ns->disk->flags & GENHD_FL_UP) { - if (blk_get_integrity(ns->disk)) - blk_integrity_unregister(ns->disk); nvme_mpath_remove_disk_links(ns); sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, &nvme_ns_id_attr_group); @@ -2974,6 +2973,8 @@ static void nvme_ns_remove(struct nvme_ns *ns) nvme_nvm_unregister_sysfs(ns); del_gendisk(ns->disk); blk_cleanup_queue(ns->queue); + if (blk_get_integrity(ns->disk)) + blk_integrity_unregister(ns->disk); } mutex_lock(&ns->ctrl->subsys->lock); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 0a8af4daef89..794e66e4aa20 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3221,7 +3221,6 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, /* initiate nvme ctrl ref counting teardown */ nvme_uninit_ctrl(&ctrl->ctrl); - nvme_put_ctrl(&ctrl->ctrl); /* Remove core ctrl ref. */ nvme_put_ctrl(&ctrl->ctrl); diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index f4c73292b304..1b9ef35cf0d9 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -77,9 +77,10 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, if (of_property_read_bool(child, "broken-turn-around")) mdio->phy_ignore_ta_mask |= 1 << addr; - of_property_read_u32(child, "reset-delay-us", &phy->mdio.reset_delay); - of_property_read_u32(child, "reset-post-delay-us", - &phy->mdio.reset_post_delay); + of_property_read_u32(child, "reset-assert-us", + &phy->mdio.reset_assert_delay); + of_property_read_u32(child, "reset-deassert-us", + &phy->mdio.reset_deassert_delay); /* Associate the OF node with the device structure so it * can be looked up later */ diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index a25fed52f7e9..41b740aed3a3 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1692,3 +1692,36 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) iounmap(base_addr); } + +/* + * The design of the Diva management card in rp34x0 machines (rp3410, rp3440) + * seems rushed, so that many built-in components simply don't work. + * The following quirks disable the serial AUX port and the built-in ATI RV100 + * Radeon 7000 graphics card which both don't have any external connectors and + * thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as + * such makes those machines the only PARISC machines on which we can't use + * ttyS0 as boot console. + */ +static void quirk_diva_ati_card(struct pci_dev *dev) +{ + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || + dev->subsystem_device != 0x1292) + return; + + dev_info(&dev->dev, "Hiding Diva built-in ATI card"); + dev->device = 0; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, + quirk_diva_ati_card); + +static void quirk_diva_aux_disable(struct pci_dev *dev) +{ + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || + dev->subsystem_device != 0x1291) + return; + + dev_info(&dev->dev, "Hiding Diva built-in AUX serial device"); + dev->device = 0; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, + quirk_diva_aux_disable); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 945099d49f8f..14fd865a5120 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1012,7 +1012,12 @@ static int pci_pm_thaw_noirq(struct device *dev) if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume_early(dev); - pci_update_current_state(pci_dev, PCI_D0); + /* + * pci_restore_state() requires the device to be in D0 (because of MSI + * restoration among other things), so force it into D0 in case the + * driver's "freeze" callbacks put it into a low-power state directly. + */ + pci_set_power_state(pci_dev, PCI_D0); pci_restore_state(pci_dev); if (drv && drv->pm && drv->pm->thaw_noirq) diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index a782a207ad31..c7e484f70654 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -91,9 +91,6 @@ config QETH_L3 To compile as a module choose M. The module name is qeth_l3. If unsure, choose Y. -config QETH_IPV6 - def_bool y if (QETH_L3 = IPV6) || (QETH_L3 && IPV6 = 'y') - config CCWGROUP tristate default (LCS || CTCM || QETH) diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 92ae84a927fc..0ee8f33efb54 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -756,18 +756,14 @@ lcs_get_lancmd(struct lcs_card *card, int count) static void lcs_get_reply(struct lcs_reply *reply) { - WARN_ON(atomic_read(&reply->refcnt) <= 0); - atomic_inc(&reply->refcnt); + refcount_inc(&reply->refcnt); } static void lcs_put_reply(struct lcs_reply *reply) { - WARN_ON(atomic_read(&reply->refcnt) <= 0); - if (atomic_dec_and_test(&reply->refcnt)) { + if (refcount_dec_and_test(&reply->refcnt)) kfree(reply); - } - } static struct lcs_reply * @@ -780,7 +776,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd) reply = kzalloc(sizeof(struct lcs_reply), GFP_ATOMIC); if (!reply) return NULL; - atomic_set(&reply->refcnt,1); + refcount_set(&reply->refcnt, 1); reply->sequence_no = cmd->sequence_no; reply->received = 0; reply->rc = 0; diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h index fbc8b90b1f85..bd52caa3b11b 100644 --- a/drivers/s390/net/lcs.h +++ b/drivers/s390/net/lcs.h @@ -5,6 +5,7 @@ #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/workqueue.h> +#include <linux/refcount.h> #include <asm/ccwdev.h> #define LCS_DBF_TEXT(level, name, text) \ @@ -271,7 +272,7 @@ struct lcs_buffer { struct lcs_reply { struct list_head list; __u16 sequence_no; - atomic_t refcnt; + refcount_t refcnt; /* Callback for completion notification. */ void (*callback)(struct lcs_card *, struct lcs_cmd *); wait_queue_head_t wait_q; diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index badf42acbf95..db42107bf2f5 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -21,6 +21,7 @@ #include <linux/ethtool.h> #include <linux/hashtable.h> #include <linux/ip.h> +#include <linux/refcount.h> #include <net/ipv6.h> #include <net/if_inet6.h> @@ -296,8 +297,23 @@ struct qeth_hdr_layer3 { __u8 ext_flags; __u16 vlan_id; __u16 frame_offset; - __u8 dest_addr[16]; -} __attribute__ ((packed)); + union { + /* TX: */ + u8 ipv6_addr[16]; + struct ipv4 { + u8 res[12]; + u32 addr; + } ipv4; + /* RX: */ + struct rx { + u8 res1[2]; + u8 src_mac[6]; + u8 res2[4]; + u16 vlan_id; + u8 res3[2]; + } rx; + } next_hop; +}; struct qeth_hdr_layer2 { __u8 id; @@ -504,12 +520,6 @@ struct qeth_qdio_info { int default_out_queue; }; -#define QETH_ETH_MAC_V4 0x0100 /* like v4 */ -#define QETH_ETH_MAC_V6 0x3333 /* like v6 */ -/* tr mc mac is longer, but that will be enough to detect mc frames */ -#define QETH_TR_MAC_NC 0xc000 /* non-canonical */ -#define QETH_TR_MAC_C 0x0300 /* canonical */ - /** * buffer stuff for read channel */ @@ -632,7 +642,7 @@ struct qeth_reply { int rc; void *param; struct qeth_card *card; - atomic_t refcnt; + refcount_t refcnt; }; struct qeth_card_blkt { @@ -846,14 +856,16 @@ static inline int qeth_get_micros(void) static inline int qeth_get_ip_version(struct sk_buff *skb) { - __be16 *p = &((struct ethhdr *)skb->data)->h_proto; + struct vlan_ethhdr *veth = vlan_eth_hdr(skb); + __be16 prot = veth->h_vlan_proto; + + if (prot == htons(ETH_P_8021Q)) + prot = veth->h_vlan_encapsulated_proto; - if (be16_to_cpu(*p) == ETH_P_8021Q) - p += 2; - switch (be16_to_cpu(*p)) { - case ETH_P_IPV6: + switch (prot) { + case htons(ETH_P_IPV6): return 6; - case ETH_P_IP: + case htons(ETH_P_IP): return 4; default: return 0; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 6c815207f4f5..bdc28330800e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -564,7 +564,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC); if (reply) { - atomic_set(&reply->refcnt, 1); + refcount_set(&reply->refcnt, 1); atomic_set(&reply->received, 0); reply->card = card; } @@ -573,14 +573,12 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) static void qeth_get_reply(struct qeth_reply *reply) { - WARN_ON(atomic_read(&reply->refcnt) <= 0); - atomic_inc(&reply->refcnt); + refcount_inc(&reply->refcnt); } static void qeth_put_reply(struct qeth_reply *reply) { - WARN_ON(atomic_read(&reply->refcnt) <= 0); - if (atomic_dec_and_test(&reply->refcnt)) + if (refcount_dec_and_test(&reply->refcnt)) kfree(reply); } @@ -4218,9 +4216,8 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; if (!card->options.layer2 || !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { - memcpy(card->dev->dev_addr, - &cmd->data.setadapterparms.data.change_addr.addr, - OSA_ADDR_LEN); + ether_addr_copy(card->dev->dev_addr, + cmd->data.setadapterparms.data.change_addr.addr); card->info.mac_bits |= QETH_LAYER2_MAC_READ; } qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); @@ -4242,9 +4239,9 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; - cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; - memcpy(&cmd->data.setadapterparms.data.change_addr.addr, - card->dev->dev_addr, OSA_ADDR_LEN); + cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN; + ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr, + card->dev->dev_addr); rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb, NULL); return rc; @@ -5386,6 +5383,13 @@ out: } EXPORT_SYMBOL_GPL(qeth_poll); +static int qeth_setassparms_inspect_rc(struct qeth_ipa_cmd *cmd) +{ + if (!cmd->hdr.return_code) + cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code; + return cmd->hdr.return_code; +} + int qeth_setassparms_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -6242,7 +6246,7 @@ static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card, (struct qeth_checksum_cmd *)reply->param; QETH_CARD_TEXT(card, 4, "chkdoccb"); - if (cmd->hdr.return_code) + if (qeth_setassparms_inspect_rc(cmd)) return 0; memset(chksum_cb, 0, sizeof(*chksum_cb)); diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index ff6877f7b6f8..619f897b4bb0 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -10,6 +10,7 @@ #define __QETH_CORE_MPC_H__ #include <asm/qeth.h> +#include <uapi/linux/if_ether.h> #define IPA_PDU_HEADER_SIZE 0x40 #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer + 0x0e) @@ -25,7 +26,6 @@ extern unsigned char IPA_PDU_HEADER[]; #define QETH_SEQ_NO_LENGTH 4 #define QETH_MPC_TOKEN_LENGTH 4 #define QETH_MCL_LENGTH 4 -#define OSA_ADDR_LEN 6 #define QETH_TIMEOUT (10 * HZ) #define QETH_IPA_TIMEOUT (45 * HZ) @@ -416,12 +416,11 @@ struct qeth_query_cmds_supp { } __attribute__ ((packed)); struct qeth_change_addr { - __u32 cmd; - __u32 addr_size; - __u32 no_macs; - __u8 addr[OSA_ADDR_LEN]; -} __attribute__ ((packed)); - + u32 cmd; + u32 addr_size; + u32 no_macs; + u8 addr[ETH_ALEN]; +}; struct qeth_snmp_cmd { __u8 token[16]; diff --git a/drivers/s390/net/qeth_l2.h b/drivers/s390/net/qeth_l2.h index 09b1c4ef3dc9..f2130051ca11 100644 --- a/drivers/s390/net/qeth_l2.h +++ b/drivers/s390/net/qeth_l2.h @@ -22,8 +22,7 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout); bool qeth_l2_vnicc_is_in_use(struct qeth_card *card); struct qeth_mac { - u8 mac_addr[OSA_ADDR_LEN]; - u8 is_uc:1; + u8 mac_addr[ETH_ALEN]; u8 disp_flag:2; struct hlist_node hnode; }; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 5863ea170ff2..7f236440483f 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -109,8 +109,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, if (!iob) return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; - memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); + cmd->data.setdelmac.mac_length = ETH_ALEN; + ether_addr_copy(cmd->data.setdelmac.mac, mac); return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob, NULL, NULL)); } @@ -123,7 +123,7 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC); if (rc == 0) { card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; - memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN); + ether_addr_copy(card->dev->dev_addr, mac); dev_info(&card->gdev->dev, "MAC address %pM successfully registered on device %s\n", card->dev->dev_addr, card->dev->name); @@ -156,54 +156,37 @@ static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) return rc; } -static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) +static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac) { + enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ? + IPA_CMD_SETGMAC : IPA_CMD_SETVMAC; int rc; - QETH_CARD_TEXT(card, 2, "L2Sgmac"); - rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC); + QETH_CARD_TEXT(card, 2, "L2Wmac"); + rc = qeth_l2_send_setdelmac(card, mac, cmd); if (rc == -EEXIST) - QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n", - mac, QETH_CARD_IFNAME(card)); + QETH_DBF_MESSAGE(2, "MAC %pM already registered on %s\n", + mac, QETH_CARD_IFNAME(card)); else if (rc) - QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n", - mac, QETH_CARD_IFNAME(card), rc); + QETH_DBF_MESSAGE(2, "Failed to register MAC %pM on %s: %d\n", + mac, QETH_CARD_IFNAME(card), rc); return rc; } -static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) +static int qeth_l2_remove_mac(struct qeth_card *card, u8 *mac) { + enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ? + IPA_CMD_DELGMAC : IPA_CMD_DELVMAC; int rc; - QETH_CARD_TEXT(card, 2, "L2Dgmac"); - rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC); + QETH_CARD_TEXT(card, 2, "L2Rmac"); + rc = qeth_l2_send_setdelmac(card, mac, cmd); if (rc) - QETH_DBF_MESSAGE(2, - "Could not delete group MAC %pM on %s: %d\n", - mac, QETH_CARD_IFNAME(card), rc); + QETH_DBF_MESSAGE(2, "Failed to delete MAC %pM on %s: %d\n", + mac, QETH_CARD_IFNAME(card), rc); return rc; } -static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac) -{ - if (mac->is_uc) { - return qeth_l2_send_setdelmac(card, mac->mac_addr, - IPA_CMD_SETVMAC); - } else { - return qeth_l2_send_setgroupmac(card, mac->mac_addr); - } -} - -static int qeth_l2_remove_mac(struct qeth_card *card, struct qeth_mac *mac) -{ - if (mac->is_uc) { - return qeth_l2_send_setdelmac(card, mac->mac_addr, - IPA_CMD_DELVMAC); - } else { - return qeth_l2_send_delgroupmac(card, mac->mac_addr); - } -} - static void qeth_l2_del_all_macs(struct qeth_card *card) { struct qeth_mac *mac; @@ -549,7 +532,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) QETH_CARD_TEXT(card, 3, "setmcTYP"); return -EOPNOTSUPP; } - QETH_CARD_HEX(card, 3, addr->sa_data, OSA_ADDR_LEN); + QETH_CARD_HEX(card, 3, addr->sa_data, ETH_ALEN); if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { QETH_CARD_TEXT(card, 3, "setmcREC"); return -ERESTARTSYS; @@ -597,27 +580,23 @@ static void qeth_promisc_to_bridge(struct qeth_card *card) * only if there is not in the hash table storage already * */ -static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha, - u8 is_uc) +static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha) { u32 mac_hash = get_unaligned((u32 *)(&ha->addr[2])); struct qeth_mac *mac; hash_for_each_possible(card->mac_htable, mac, hnode, mac_hash) { - if (is_uc == mac->is_uc && - !memcmp(ha->addr, mac->mac_addr, OSA_ADDR_LEN)) { + if (ether_addr_equal_64bits(ha->addr, mac->mac_addr)) { mac->disp_flag = QETH_DISP_ADDR_DO_NOTHING; return; } } mac = kzalloc(sizeof(struct qeth_mac), GFP_ATOMIC); - if (!mac) return; - memcpy(mac->mac_addr, ha->addr, OSA_ADDR_LEN); - mac->is_uc = is_uc; + ether_addr_copy(mac->mac_addr, ha->addr); mac->disp_flag = QETH_DISP_ADDR_ADD; hash_add(card->mac_htable, &mac->hnode, mac_hash); @@ -643,26 +622,29 @@ static void qeth_l2_set_rx_mode(struct net_device *dev) spin_lock_bh(&card->mclock); netdev_for_each_mc_addr(ha, dev) - qeth_l2_add_mac(card, ha, 0); - + qeth_l2_add_mac(card, ha); netdev_for_each_uc_addr(ha, dev) - qeth_l2_add_mac(card, ha, 1); + qeth_l2_add_mac(card, ha); hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) { - if (mac->disp_flag == QETH_DISP_ADDR_DELETE) { - qeth_l2_remove_mac(card, mac); + switch (mac->disp_flag) { + case QETH_DISP_ADDR_DELETE: + qeth_l2_remove_mac(card, mac->mac_addr); hash_del(&mac->hnode); kfree(mac); - - } else if (mac->disp_flag == QETH_DISP_ADDR_ADD) { - rc = qeth_l2_write_mac(card, mac); + break; + case QETH_DISP_ADDR_ADD: + rc = qeth_l2_write_mac(card, mac->mac_addr); if (rc) { hash_del(&mac->hnode); kfree(mac); - } else - mac->disp_flag = QETH_DISP_ADDR_DELETE; - } else + break; + } + /* fall through */ + default: + /* for next call to set_rx_mode(): */ mac->disp_flag = QETH_DISP_ADDR_DELETE; + } } spin_unlock_bh(&card->mclock); diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index e5833837b799..49f92ebbc5ad 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h @@ -29,7 +29,7 @@ struct qeth_ipaddr { */ int ref_counter; enum qeth_prot_versions proto; - unsigned char mac[OSA_ADDR_LEN]; + unsigned char mac[ETH_ALEN]; union { struct { unsigned int addr; @@ -69,7 +69,6 @@ struct qeth_ipato_entry { extern const struct attribute_group *qeth_l3_attr_groups[]; void qeth_l3_ipaddr_to_string(enum qeth_prot_versions, const __u8 *, char *); -int qeth_l3_string_to_ipaddr(const char *, enum qeth_prot_versions, __u8 *); int qeth_l3_create_device_attributes(struct device *); void qeth_l3_remove_device_attributes(struct device *); int qeth_l3_setrouting_v4(struct qeth_card *); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index ef0961e18686..92bcb02671bc 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -18,15 +18,20 @@ #include <linux/kernel.h> #include <linux/etherdevice.h> #include <linux/ip.h> +#include <linux/in.h> #include <linux/ipv6.h> #include <linux/inetdevice.h> #include <linux/igmp.h> #include <linux/slab.h> +#include <linux/if_ether.h> #include <linux/if_vlan.h> +#include <linux/skbuff.h> #include <net/ip.h> #include <net/arp.h> #include <net/route.h> +#include <net/ipv6.h> +#include <net/ip6_route.h> #include <net/ip6_fib.h> #include <net/ip6_checksum.h> #include <net/iucv/af_iucv.h> @@ -37,99 +42,22 @@ static int qeth_l3_set_offline(struct ccwgroup_device *); static int qeth_l3_stop(struct net_device *); -static void qeth_l3_set_multicast_list(struct net_device *); +static void qeth_l3_set_rx_mode(struct net_device *dev); static int qeth_l3_register_addr_entry(struct qeth_card *, struct qeth_ipaddr *); static int qeth_l3_deregister_addr_entry(struct qeth_card *, struct qeth_ipaddr *); -static int qeth_l3_isxdigit(char *buf) -{ - while (*buf) { - if (!isxdigit(*buf++)) - return 0; - } - return 1; -} - static void qeth_l3_ipaddr4_to_string(const __u8 *addr, char *buf) { sprintf(buf, "%pI4", addr); } -static int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) -{ - int count = 0, rc = 0; - unsigned int in[4]; - char c; - - rc = sscanf(buf, "%u.%u.%u.%u%c", - &in[0], &in[1], &in[2], &in[3], &c); - if (rc != 4 && (rc != 5 || c != '\n')) - return -EINVAL; - for (count = 0; count < 4; count++) { - if (in[count] > 255) - return -EINVAL; - addr[count] = in[count]; - } - return 0; -} - static void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) { sprintf(buf, "%pI6", addr); } -static int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) -{ - const char *end, *end_tmp, *start; - __u16 *in; - char num[5]; - int num2, cnt, out, found, save_cnt; - unsigned short in_tmp[8] = {0, }; - - cnt = out = found = save_cnt = num2 = 0; - end = start = buf; - in = (__u16 *) addr; - memset(in, 0, 16); - while (*end) { - end = strchr(start, ':'); - if (end == NULL) { - end = buf + strlen(buf); - end_tmp = strchr(start, '\n'); - if (end_tmp != NULL) - end = end_tmp; - out = 1; - } - if ((end - start)) { - memset(num, 0, 5); - if ((end - start) > 4) - return -EINVAL; - memcpy(num, start, end - start); - if (!qeth_l3_isxdigit(num)) - return -EINVAL; - sscanf(start, "%x", &num2); - if (found) - in_tmp[save_cnt++] = num2; - else - in[cnt++] = num2; - if (out) - break; - } else { - if (found) - return -EINVAL; - found = 1; - } - start = ++end; - } - if (cnt + save_cnt > 8) - return -EINVAL; - cnt = 7; - while (save_cnt) - in[cnt--] = in_tmp[--save_cnt]; - return 0; -} - void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr, char *buf) { @@ -139,17 +67,6 @@ void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr, qeth_l3_ipaddr6_to_string(addr, buf); } -int qeth_l3_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto, - __u8 *addr) -{ - if (proto == QETH_PROT_IPV4) - return qeth_l3_string_to_ipaddr4(buf, addr); - else if (proto == QETH_PROT_IPV6) - return qeth_l3_string_to_ipaddr6(buf, addr); - else - return -EINVAL; -} - static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len) { int i, j; @@ -207,8 +124,8 @@ inline int qeth_l3_ipaddrs_is_equal(struct qeth_ipaddr *addr1, struct qeth_ipaddr *addr2) { return addr1->proto == addr2->proto && - !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) && - !memcmp(&addr1->mac, &addr2->mac, sizeof(addr1->mac)); + !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) && + ether_addr_equal_64bits(addr1->mac, addr2->mac); } static struct qeth_ipaddr * @@ -446,7 +363,7 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card, if (!iob) return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); + ether_addr_copy(cmd->data.setdelipm.mac, addr->mac); if (addr->proto == QETH_PROT_IPV6) memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr, sizeof(struct in6_addr)); @@ -582,7 +499,6 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) int rc = 0; QETH_CARD_TEXT(card, 3, "setrtg6"); -#ifdef CONFIG_QETH_IPV6 if (!qeth_is_supported(card, IPA_IPV6)) return 0; @@ -599,7 +515,6 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) " on %s. Type set to 'no router'.\n", rc, QETH_CARD_IFNAME(card)); } -#endif return rc; } @@ -896,27 +811,6 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card, return rc; } -static u8 qeth_l3_get_qeth_hdr_flags4(int cast_type) -{ - if (cast_type == RTN_MULTICAST) - return QETH_CAST_MULTICAST; - if (cast_type == RTN_BROADCAST) - return QETH_CAST_BROADCAST; - return QETH_CAST_UNICAST; -} - -static u8 qeth_l3_get_qeth_hdr_flags6(int cast_type) -{ - u8 ct = QETH_HDR_PASSTHRU | QETH_HDR_IPV6; - if (cast_type == RTN_MULTICAST) - return ct | QETH_CAST_MULTICAST; - if (cast_type == RTN_ANYCAST) - return ct | QETH_CAST_ANYCAST; - if (cast_type == RTN_BROADCAST) - return ct | QETH_CAST_BROADCAST; - return ct | QETH_CAST_UNICAST; -} - static int qeth_l3_setadapter_parms(struct qeth_card *card) { int rc = 0; @@ -933,7 +827,6 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card) return rc; } -#ifdef CONFIG_QETH_IPV6 static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, enum qeth_ipa_funcs ipa_func, __u16 cmd_code) { @@ -949,7 +842,6 @@ static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, qeth_setassparms_cb, NULL); return rc; } -#endif static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card) { @@ -1045,7 +937,6 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card) return rc; } -#ifdef CONFIG_QETH_IPV6 static int qeth_l3_softsetup_ipv6(struct qeth_card *card) { int rc; @@ -1091,12 +982,9 @@ out: dev_info(&card->gdev->dev, "IPV6 enabled\n"); return 0; } -#endif static int qeth_l3_start_ipa_ipv6(struct qeth_card *card) { - int rc = 0; - QETH_CARD_TEXT(card, 3, "strtipv6"); if (!qeth_is_supported(card, IPA_IPV6)) { @@ -1104,10 +992,7 @@ static int qeth_l3_start_ipa_ipv6(struct qeth_card *card) "IPv6 not supported on %s\n", QETH_CARD_IFNAME(card)); return 0; } -#ifdef CONFIG_QETH_IPV6 - rc = qeth_l3_softsetup_ipv6(card); -#endif - return rc ; + return qeth_l3_softsetup_ipv6(card); } static int qeth_l3_start_ipa_broadcast(struct qeth_card *card) @@ -1179,8 +1064,8 @@ static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; if (cmd->hdr.return_code == 0) - memcpy(card->dev->dev_addr, - cmd->data.create_destroy_addr.unique_id, ETH_ALEN); + ether_addr_copy(card->dev->dev_addr, + cmd->data.create_destroy_addr.unique_id); else eth_random_addr(card->dev->dev_addr); @@ -1328,81 +1213,22 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL); } -static void qeth_l3_get_mac_for_ipm(__be32 ipm, char *mac) -{ - ip_eth_mc_map(ipm, mac); -} - -static void qeth_l3_mark_all_mc_to_be_deleted(struct qeth_card *card) -{ - struct qeth_ipaddr *addr; - int i; - - hash_for_each(card->ip_mc_htable, i, addr, hnode) - addr->disp_flag = QETH_DISP_ADDR_DELETE; - -} - -static void qeth_l3_add_all_new_mc(struct qeth_card *card) -{ - struct qeth_ipaddr *addr; - struct hlist_node *tmp; - int i; - int rc; - - hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) { - if (addr->disp_flag == QETH_DISP_ADDR_ADD) { - rc = qeth_l3_register_addr_entry(card, addr); - if (!rc || (rc == IPA_RC_LAN_OFFLINE)) - addr->ref_counter = 1; - else { - hash_del(&addr->hnode); - kfree(addr); - } - } - } - -} - -static void qeth_l3_delete_nonused_mc(struct qeth_card *card) -{ - struct qeth_ipaddr *addr; - struct hlist_node *tmp; - int i; - int rc; - - hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) { - if (addr->disp_flag == QETH_DISP_ADDR_DELETE) { - rc = qeth_l3_deregister_addr_entry(card, addr); - if (!rc || (rc == IPA_RC_MC_ADDR_NOT_FOUND)) { - hash_del(&addr->hnode); - kfree(addr); - } - } - } - -} - - static void qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev) { struct ip_mc_list *im4; struct qeth_ipaddr *tmp, *ipm; - char buf[MAX_ADDR_LEN]; QETH_CARD_TEXT(card, 4, "addmc"); tmp = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); - if (!tmp) - return; + if (!tmp) + return; for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; im4 = rcu_dereference(im4->next_rcu)) { - qeth_l3_get_mac_for_ipm(im4->multiaddr, buf); - + ip_eth_mc_map(im4->multiaddr, tmp->mac); tmp->u.a4.addr = be32_to_cpu(im4->multiaddr); - memcpy(tmp->mac, buf, sizeof(tmp->mac)); tmp->is_multicast = 1; ipm = qeth_l3_ip_from_hash(card, tmp); @@ -1412,7 +1238,7 @@ qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev) ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); if (!ipm) continue; - memcpy(ipm->mac, buf, sizeof(tmp->mac)); + ether_addr_copy(ipm->mac, tmp->mac); ipm->u.a4.addr = be32_to_cpu(im4->multiaddr); ipm->is_multicast = 1; ipm->disp_flag = QETH_DISP_ADDR_ADD; @@ -1466,25 +1292,21 @@ unlock: rcu_read_unlock(); } -#ifdef CONFIG_QETH_IPV6 -static void -qeth_l3_add_mc6_to_hash(struct qeth_card *card, struct inet6_dev *in6_dev) +static void qeth_l3_add_mc6_to_hash(struct qeth_card *card, + struct inet6_dev *in6_dev) { struct qeth_ipaddr *ipm; struct ifmcaddr6 *im6; struct qeth_ipaddr *tmp; - char buf[MAX_ADDR_LEN]; QETH_CARD_TEXT(card, 4, "addmc6"); tmp = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); - if (!tmp) - return; + if (!tmp) + return; for (im6 = in6_dev->mc_list; im6 != NULL; im6 = im6->next) { - ndisc_mc_map(&im6->mca_addr, buf, in6_dev->dev, 0); - - memcpy(tmp->mac, buf, sizeof(tmp->mac)); + ipv6_eth_mc_map(&im6->mca_addr, tmp->mac); memcpy(&tmp->u.a6.addr, &im6->mca_addr.s6_addr, sizeof(struct in6_addr)); tmp->is_multicast = 1; @@ -1499,7 +1321,7 @@ qeth_l3_add_mc6_to_hash(struct qeth_card *card, struct inet6_dev *in6_dev) if (!ipm) continue; - memcpy(ipm->mac, buf, OSA_ADDR_LEN); + ether_addr_copy(ipm->mac, tmp->mac); memcpy(&ipm->u.a6.addr, &im6->mca_addr.s6_addr, sizeof(struct in6_addr)); ipm->is_multicast = 1; @@ -1560,7 +1382,6 @@ static void qeth_l3_add_multicast_ipv6(struct qeth_card *card) rcu_read_unlock(); in6_dev_put(in6_dev); } -#endif /* CONFIG_QETH_IPV6 */ static void qeth_l3_free_vlan_addresses4(struct qeth_card *card, unsigned short vid) @@ -1600,9 +1421,8 @@ out: } static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, - unsigned short vid) + unsigned short vid) { -#ifdef CONFIG_QETH_IPV6 struct inet6_dev *in6_dev; struct inet6_ifaddr *ifa; struct qeth_ipaddr *addr; @@ -1637,7 +1457,6 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, kfree(addr); out: in6_dev_put(in6_dev); -#endif /* CONFIG_QETH_IPV6 */ } static void qeth_l3_free_vlan_addresses(struct qeth_card *card, @@ -1672,44 +1491,31 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev, /* unregister IP addresses of vlan device */ qeth_l3_free_vlan_addresses(card, vid); clear_bit(vid, card->active_vlans); - qeth_l3_set_multicast_list(card->dev); + qeth_l3_set_rx_mode(dev); return 0; } static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *hdr) { - __u16 prot; - struct iphdr *ip_hdr; - unsigned char tg_addr[MAX_ADDR_LEN]; - if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) { - prot = (hdr->hdr.l3.flags & QETH_HDR_IPV6) ? ETH_P_IPV6 : - ETH_P_IP; + u16 prot = (hdr->hdr.l3.flags & QETH_HDR_IPV6) ? ETH_P_IPV6 : + ETH_P_IP; + unsigned char tg_addr[ETH_ALEN]; + + skb_reset_network_header(skb); switch (hdr->hdr.l3.flags & QETH_HDR_CAST_MASK) { case QETH_CAST_MULTICAST: - switch (prot) { -#ifdef CONFIG_QETH_IPV6 - case ETH_P_IPV6: - ndisc_mc_map((struct in6_addr *) - skb->data + 24, - tg_addr, card->dev, 0); - break; -#endif - case ETH_P_IP: - ip_hdr = (struct iphdr *)skb->data; - ip_eth_mc_map(ip_hdr->daddr, tg_addr); - break; - default: - memcpy(tg_addr, card->dev->broadcast, - card->dev->addr_len); - } + if (prot == ETH_P_IP) + ip_eth_mc_map(ip_hdr(skb)->daddr, tg_addr); + else + ipv6_eth_mc_map(&ipv6_hdr(skb)->daddr, tg_addr); + card->stats.multicast++; skb->pkt_type = PACKET_MULTICAST; break; case QETH_CAST_BROADCAST: - memcpy(tg_addr, card->dev->broadcast, - card->dev->addr_len); + ether_addr_copy(tg_addr, card->dev->broadcast); card->stats.multicast++; skb->pkt_type = PACKET_BROADCAST; break; @@ -1721,12 +1527,11 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, skb->pkt_type = PACKET_OTHERHOST; else skb->pkt_type = PACKET_HOST; - memcpy(tg_addr, card->dev->dev_addr, - card->dev->addr_len); + ether_addr_copy(tg_addr, card->dev->dev_addr); } if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR) card->dev->header_ops->create(skb, card->dev, prot, - tg_addr, &hdr->hdr.l3.dest_addr[2], + tg_addr, &hdr->hdr.l3.next_hop.rx.src_mac, card->dev->addr_len); else card->dev->header_ops->create(skb, card->dev, prot, @@ -1741,7 +1546,7 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, QETH_HDR_EXT_INCLUDE_VLAN_TAG))) { u16 tag = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME) ? hdr->hdr.l3.vlan_id : - *((u16 *)&hdr->hdr.l3.dest_addr[12]); + hdr->hdr.l3.next_hop.rx.vlan_id; __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tag); } @@ -1949,26 +1754,46 @@ qeth_l3_handle_promisc_mode(struct qeth_card *card) } } -static void qeth_l3_set_multicast_list(struct net_device *dev) +static void qeth_l3_set_rx_mode(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; + struct qeth_ipaddr *addr; + struct hlist_node *tmp; + int i, rc; QETH_CARD_TEXT(card, 3, "setmulti"); if (qeth_threads_running(card, QETH_RECOVER_THREAD) && (card->state != CARD_STATE_UP)) return; if (!card->options.sniffer) { - spin_lock_bh(&card->mclock); - qeth_l3_mark_all_mc_to_be_deleted(card); - qeth_l3_add_multicast_ipv4(card); -#ifdef CONFIG_QETH_IPV6 qeth_l3_add_multicast_ipv6(card); -#endif - qeth_l3_delete_nonused_mc(card); - qeth_l3_add_all_new_mc(card); + + hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) { + switch (addr->disp_flag) { + case QETH_DISP_ADDR_DELETE: + rc = qeth_l3_deregister_addr_entry(card, addr); + if (!rc || rc == IPA_RC_MC_ADDR_NOT_FOUND) { + hash_del(&addr->hnode); + kfree(addr); + } + break; + case QETH_DISP_ADDR_ADD: + rc = qeth_l3_register_addr_entry(card, addr); + if (rc && rc != IPA_RC_LAN_OFFLINE) { + hash_del(&addr->hnode); + kfree(addr); + break; + } + addr->ref_counter = 1; + /* fall through */ + default: + /* for next call to set_rx_mode(): */ + addr->disp_flag = QETH_DISP_ADDR_DELETE; + } + } spin_unlock_bh(&card->mclock); @@ -2237,12 +2062,10 @@ static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) rc = -EFAULT; goto free_and_out; } -#ifdef CONFIG_QETH_IPV6 if (qinfo.mask_bits & QETH_QARP_WITH_IPV6) { /* fails in case of GuestLAN QDIO mode */ qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV6, &qinfo); } -#endif if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) { QETH_CARD_TEXT(card, 4, "qactf"); rc = -EFAULT; @@ -2422,9 +2245,8 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return rc; } -static int qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb) +static int qeth_l3_get_cast_type(struct sk_buff *skb) { - int cast_type = RTN_UNSPEC; struct neighbour *n = NULL; struct dst_entry *dst; @@ -2433,48 +2255,34 @@ static int qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb) if (dst) n = dst_neigh_lookup_skb(dst, skb); if (n) { - cast_type = n->type; + int cast_type = n->type; + rcu_read_unlock(); neigh_release(n); if ((cast_type == RTN_BROADCAST) || (cast_type == RTN_MULTICAST) || (cast_type == RTN_ANYCAST)) return cast_type; - else - return RTN_UNSPEC; + return RTN_UNSPEC; } rcu_read_unlock(); - /* try something else */ + /* no neighbour (eg AF_PACKET), fall back to target's IP address ... */ if (be16_to_cpu(skb->protocol) == ETH_P_IPV6) - return (skb_network_header(skb)[24] == 0xff) ? - RTN_MULTICAST : 0; + return ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ? + RTN_MULTICAST : RTN_UNSPEC; else if (be16_to_cpu(skb->protocol) == ETH_P_IP) - return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ? - RTN_MULTICAST : 0; - /* ... */ - if (!memcmp(skb->data, skb->dev->broadcast, 6)) + return ipv4_is_multicast(ip_hdr(skb)->daddr) ? + RTN_MULTICAST : RTN_UNSPEC; + + /* ... and MAC address */ + if (ether_addr_equal_64bits(eth_hdr(skb)->h_dest, skb->dev->broadcast)) return RTN_BROADCAST; - else { - u16 hdr_mac; - - hdr_mac = *((u16 *)skb->data); - /* tr multicast? */ - switch (card->info.link_type) { - case QETH_LINK_TYPE_HSTR: - case QETH_LINK_TYPE_LANE_TR: - if ((hdr_mac == QETH_TR_MAC_NC) || - (hdr_mac == QETH_TR_MAC_C)) - return RTN_MULTICAST; - break; - /* eth or so multicast? */ - default: - if ((hdr_mac == QETH_ETH_MAC_V4) || - (hdr_mac == QETH_ETH_MAC_V6)) - return RTN_MULTICAST; - } - } - return cast_type; + if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) + return RTN_MULTICAST; + + /* default to unicast */ + return RTN_UNSPEC; } static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card, @@ -2494,17 +2302,27 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card, daddr[0] = 0xfe; daddr[1] = 0x80; memcpy(&daddr[8], iucv_hdr->destUserID, 8); - memcpy(hdr->hdr.l3.dest_addr, daddr, 16); + memcpy(hdr->hdr.l3.next_hop.ipv6_addr, daddr, 16); } -static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, - struct sk_buff *skb, int ipv, int cast_type) +static u8 qeth_l3_cast_type_to_flag(int cast_type) { - struct dst_entry *dst; + if (cast_type == RTN_MULTICAST) + return QETH_CAST_MULTICAST; + if (cast_type == RTN_ANYCAST) + return QETH_CAST_ANYCAST; + if (cast_type == RTN_BROADCAST) + return QETH_CAST_BROADCAST; + return QETH_CAST_UNICAST; +} +static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, + struct sk_buff *skb, int ipv, int cast_type, + unsigned int data_len) +{ memset(hdr, 0, sizeof(struct qeth_hdr)); hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3; - hdr->hdr.l3.ext_flags = 0; + hdr->hdr.l3.length = data_len; /* * before we're going to overwrite this location with next hop ip. @@ -2518,44 +2336,40 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.vlan_id = skb_vlan_tag_get(skb); } - hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr); + /* OSA only: */ + if (!ipv) { + hdr->hdr.l3.flags = QETH_HDR_PASSTHRU; + if (ether_addr_equal_64bits(eth_hdr(skb)->h_dest, + skb->dev->broadcast)) + hdr->hdr.l3.flags |= QETH_CAST_BROADCAST; + else + hdr->hdr.l3.flags |= (cast_type == RTN_MULTICAST) ? + QETH_CAST_MULTICAST : QETH_CAST_UNICAST; + return; + } + hdr->hdr.l3.flags = qeth_l3_cast_type_to_flag(cast_type); rcu_read_lock(); - dst = skb_dst(skb); if (ipv == 4) { - struct rtable *rt = (struct rtable *) dst; - __be32 *pkey = &ip_hdr(skb)->daddr; + struct rtable *rt = skb_rtable(skb); - if (rt && rt->rt_gateway) - pkey = &rt->rt_gateway; - - /* IPv4 */ - hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); - memset(hdr->hdr.l3.dest_addr, 0, 12); - *((__be32 *) (&hdr->hdr.l3.dest_addr[12])) = *pkey; - } else if (ipv == 6) { - struct rt6_info *rt = (struct rt6_info *) dst; - struct in6_addr *pkey = &ipv6_hdr(skb)->daddr; + *((__be32 *) &hdr->hdr.l3.next_hop.ipv4.addr) = (rt) ? + rt_nexthop(rt, ip_hdr(skb)->daddr) : + ip_hdr(skb)->daddr; + } else { + /* IPv6 */ + const struct rt6_info *rt = skb_rt6_info(skb); + const struct in6_addr *next_hop; if (rt && !ipv6_addr_any(&rt->rt6i_gateway)) - pkey = &rt->rt6i_gateway; + next_hop = &rt->rt6i_gateway; + else + next_hop = &ipv6_hdr(skb)->daddr; + memcpy(hdr->hdr.l3.next_hop.ipv6_addr, next_hop, 16); - /* IPv6 */ - hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); - if (card->info.type == QETH_CARD_TYPE_IQD) - hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - memcpy(hdr->hdr.l3.dest_addr, pkey, 16); - } else { - if (!memcmp(skb->data + sizeof(struct qeth_hdr), - skb->dev->broadcast, 6)) { - /* broadcast? */ - hdr->hdr.l3.flags = QETH_CAST_BROADCAST | - QETH_HDR_PASSTHRU; - } else { - hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ? - QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU : - QETH_CAST_UNICAST | QETH_HDR_PASSTHRU; - } + hdr->hdr.l3.flags |= QETH_HDR_IPV6; + if (card->info.type != QETH_CARD_TYPE_IQD) + hdr->hdr.l3.flags |= QETH_HDR_PASSTHRU; } rcu_read_unlock(); } @@ -2587,7 +2401,6 @@ static void qeth_tso_fill_header(struct qeth_card *card, /*fix header to TSO values ...*/ hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; - hdr->hdr.hdr.l3.length = skb->len - sizeof(struct qeth_hdr_tso); /*set values which are fix for the first approach ...*/ hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); hdr->ext.imb_hdr_no = 1; @@ -2655,7 +2468,7 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, struct qeth_card *card = dev->ml_priv; struct sk_buff *new_skb = NULL; int ipv = qeth_get_ip_version(skb); - int cast_type = qeth_l3_get_cast_type(card, skb); + int cast_type = qeth_l3_get_cast_type(skb); struct qeth_qdio_out_q *queue = card->qdio.out_qs[card->qdio.do_prio_queueing || (cast_type && card->info.is_multicast_different) ? @@ -2748,21 +2561,23 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, if (use_tso) { hdr = skb_push(new_skb, sizeof(struct qeth_hdr_tso)); memset(hdr, 0, sizeof(struct qeth_hdr_tso)); - qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type); + qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type, + new_skb->len - sizeof(struct qeth_hdr_tso)); qeth_tso_fill_header(card, hdr, new_skb); hdr_elements++; } else { if (data_offset < 0) { hdr = skb_push(new_skb, sizeof(struct qeth_hdr)); - qeth_l3_fill_header(card, hdr, new_skb, ipv, - cast_type); + qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type, + new_skb->len - + sizeof(struct qeth_hdr)); } else { if (be16_to_cpu(new_skb->protocol) == ETH_P_AF_IUCV) qeth_l3_fill_af_iucv_hdr(card, hdr, new_skb); else { qeth_l3_fill_header(card, hdr, new_skb, ipv, - cast_type); - hdr->hdr.l3.length = new_skb->len - data_offset; + cast_type, + new_skb->len - data_offset); } } @@ -2930,7 +2745,7 @@ static const struct net_device_ops qeth_l3_netdev_ops = { .ndo_get_stats = qeth_get_stats, .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = qeth_l3_set_multicast_list, + .ndo_set_rx_mode = qeth_l3_set_rx_mode, .ndo_do_ioctl = qeth_do_ioctl, .ndo_change_mtu = qeth_change_mtu, .ndo_fix_features = qeth_fix_features, @@ -2947,7 +2762,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_features_check = qeth_features_check, .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = qeth_l3_set_multicast_list, + .ndo_set_rx_mode = qeth_l3_set_rx_mode, .ndo_do_ioctl = qeth_do_ioctl, .ndo_change_mtu = qeth_change_mtu, .ndo_fix_features = qeth_fix_features, @@ -3145,7 +2960,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) __qeth_l3_open(card->dev); else dev_open(card->dev); - qeth_l3_set_multicast_list(card->dev); + qeth_l3_set_rx_mode(card->dev); qeth_recover_features(card->dev); rtnl_unlock(); } @@ -3371,10 +3186,6 @@ static struct notifier_block qeth_l3_ip_notifier = { NULL, }; -#ifdef CONFIG_QETH_IPV6 -/** - * IPv6 event handler - */ static int qeth_l3_ip6_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -3419,7 +3230,6 @@ static struct notifier_block qeth_l3_ip6_notifier = { qeth_l3_ip6_event, NULL, }; -#endif static int qeth_l3_register_notifiers(void) { @@ -3429,35 +3239,25 @@ static int qeth_l3_register_notifiers(void) rc = register_inetaddr_notifier(&qeth_l3_ip_notifier); if (rc) return rc; -#ifdef CONFIG_QETH_IPV6 rc = register_inet6addr_notifier(&qeth_l3_ip6_notifier); if (rc) { unregister_inetaddr_notifier(&qeth_l3_ip_notifier); return rc; } -#else - pr_warn("There is no IPv6 support for the layer 3 discipline\n"); -#endif return 0; } static void qeth_l3_unregister_notifiers(void) { - QETH_DBF_TEXT(SETUP, 5, "unregnot"); WARN_ON(unregister_inetaddr_notifier(&qeth_l3_ip_notifier)); -#ifdef CONFIG_QETH_IPV6 WARN_ON(unregister_inet6addr_notifier(&qeth_l3_ip6_notifier)); -#endif /* QETH_IPV6 */ } static int __init qeth_l3_init(void) { - int rc = 0; - pr_info("register layer 3 discipline\n"); - rc = qeth_l3_register_notifiers(); - return rc; + return qeth_l3_register_notifiers(); } static void __exit qeth_l3_exit(void) diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 6ea2b528a64e..00a10b66c01f 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -10,11 +10,23 @@ #include <linux/slab.h> #include <asm/ebcdic.h> #include <linux/hashtable.h> +#include <linux/inet.h> #include "qeth_l3.h" #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store) +static int qeth_l3_string_to_ipaddr(const char *buf, + enum qeth_prot_versions proto, u8 *addr) +{ + const char *end; + + if ((proto == QETH_PROT_IPV4 && !in4_pton(buf, -1, addr, -1, &end)) || + (proto == QETH_PROT_IPV6 && !in6_pton(buf, -1, addr, -1, &end))) + return -EINVAL; + return 0; +} + static ssize_t qeth_l3_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route, char *buf) { diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 6e3d81969a77..d52265416da2 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1725,6 +1725,7 @@ struct aac_dev #define FIB_CONTEXT_FLAG_NATIVE_HBA (0x00000010) #define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF (0x00000020) #define FIB_CONTEXT_FLAG_SCSI_CMD (0x00000040) +#define FIB_CONTEXT_FLAG_EH_RESET (0x00000080) /* * Define the command values diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index bdf127aaab41..d55332de08f9 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1037,7 +1037,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd) info = &aac->hba_map[bus][cid]; if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || info->devtype != AAC_DEVTYPE_NATIVE_RAW) { - fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; + fib->flags |= FIB_CONTEXT_FLAG_EH_RESET; cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; } } diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index a4f28b7e4c65..e18877177f1b 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -1576,7 +1576,9 @@ static struct request *_make_request(struct request_queue *q, bool has_write, return req; for_each_bio(bio) { - ret = blk_rq_append_bio(req, bio); + struct bio *bounce_bio = bio; + + ret = blk_rq_append_bio(req, &bounce_bio); if (ret) return ERR_PTR(ret); } diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 449ef5adbb2b..dfb8da83fa50 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -374,10 +374,8 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, model, compatible); if (strflags) - devinfo->flags = simple_strtoul(strflags, NULL, 0); - else - devinfo->flags = flags; - + flags = (__force blist_flags_t)simple_strtoul(strflags, NULL, 0); + devinfo->flags = flags; devinfo->compatible = compatible; if (compatible) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index be5e919db0e8..0880d975eed3 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -770,7 +770,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized **/ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, - int *bflags, int async) + blist_flags_t *bflags, int async) { int ret; @@ -1049,14 +1049,15 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq, * - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized **/ static int scsi_probe_and_add_lun(struct scsi_target *starget, - u64 lun, int *bflagsp, + u64 lun, blist_flags_t *bflagsp, struct scsi_device **sdevp, enum scsi_scan_mode rescan, void *hostdata) { struct scsi_device *sdev; unsigned char *result; - int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256; + blist_flags_t bflags; + int res = SCSI_SCAN_NO_RESPONSE, result_len = 256; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); /* @@ -1201,7 +1202,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * Modifies sdevscan->lun. **/ static void scsi_sequential_lun_scan(struct scsi_target *starget, - int bflags, int scsi_level, + blist_flags_t bflags, int scsi_level, enum scsi_scan_mode rescan) { uint max_dev_lun; @@ -1292,7 +1293,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, * 0: scan completed (or no memory, so further scanning is futile) * 1: could not scan with REPORT LUN **/ -static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, +static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags, enum scsi_scan_mode rescan) { unsigned char scsi_cmd[MAX_COMMAND_SIZE]; @@ -1538,7 +1539,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, unsigned int id, u64 lun, enum scsi_scan_mode rescan) { struct Scsi_Host *shost = dev_to_shost(parent); - int bflags = 0; + blist_flags_t bflags = 0; int res; struct scsi_target *starget; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 50e7d7e4a861..a9996c16f4ae 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -967,7 +967,8 @@ sdev_show_wwid(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL); -#define BLIST_FLAG_NAME(name) [ilog2(BLIST_##name)] = #name +#define BLIST_FLAG_NAME(name) \ + [ilog2((__force unsigned int)BLIST_##name)] = #name static const char *const sdev_bflags_name[] = { #include "scsi_devinfo_tbl.c" }; @@ -984,7 +985,7 @@ sdev_show_blacklist(struct device *dev, struct device_attribute *attr, for (i = 0; i < sizeof(sdev->sdev_bflags) * BITS_PER_BYTE; i++) { const char *name = NULL; - if (!(sdev->sdev_bflags & BIT(i))) + if (!(sdev->sdev_bflags & (__force blist_flags_t)BIT(i))) continue; if (i < ARRAY_SIZE(sdev_bflags_name) && sdev_bflags_name[i]) name = sdev_bflags_name[i]; diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index d0219e36080c..10ebb213ddb3 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -50,14 +50,14 @@ /* Our blacklist flags */ enum { - SPI_BLIST_NOIUS = 0x1, + SPI_BLIST_NOIUS = (__force blist_flags_t)0x1, }; /* blacklist table, modelled on scsi_devinfo.c */ static struct { char *vendor; char *model; - unsigned flags; + blist_flags_t flags; } spi_static_device_list[] __initdata = { {"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS }, {"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS }, @@ -221,9 +221,11 @@ static int spi_device_configure(struct transport_container *tc, { struct scsi_device *sdev = to_scsi_device(dev); struct scsi_target *starget = sdev->sdev_target; - unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], - &sdev->inquiry[16], - SCSI_DEVINFO_SPI); + blist_flags_t bflags; + + bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], + &sdev->inquiry[16], + SCSI_DEVINFO_SPI); /* Populate the target capability fields with the values * gleaned from the device inquiry */ diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 77fe55ce790c..d65345312527 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -79,6 +79,7 @@ #define A3700_SPI_BYTE_LEN BIT(5) #define A3700_SPI_CLK_PRESCALE BIT(0) #define A3700_SPI_CLK_PRESCALE_MASK (0x1f) +#define A3700_SPI_CLK_EVEN_OFFS (0x10) #define A3700_SPI_WFIFO_THRS_BIT 28 #define A3700_SPI_RFIFO_THRS_BIT 24 @@ -220,6 +221,13 @@ static void a3700_spi_clock_set(struct a3700_spi *a3700_spi, prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); + /* For prescaler values over 15, we can only set it by steps of 2. + * Starting from A3700_SPI_CLK_EVEN_OFFS, we set values from 0 up to + * 30. We only use this range from 16 to 30. + */ + if (prescale > 15) + prescale = A3700_SPI_CLK_EVEN_OFFS + DIV_ROUND_UP(prescale, 2); + val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); val = val & ~A3700_SPI_CLK_PRESCALE_MASK; diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index f95da364c283..669470971023 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1661,12 +1661,12 @@ static int atmel_spi_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); /* reset the hardware and block queue progress */ - spin_lock_irq(&as->lock); if (as->use_dma) { atmel_spi_stop_dma(master); atmel_spi_release_dma(master); } + spin_lock_irq(&as->lock); spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_readl(as, SR); diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 2ce875764ca6..0835a8d88fb8 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -377,8 +377,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size) /* Sets SPCMD */ rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); - /* Enables SPI function in master mode */ - rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR); + /* Sets RSPI mode */ + rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); return 0; } diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index c5cd635c28f3..41410031f8e9 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -525,7 +525,7 @@ err_free_master: static int sun4i_spi_remove(struct platform_device *pdev) { - pm_runtime_disable(&pdev->dev); + pm_runtime_force_suspend(&pdev->dev); return 0; } diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index bc7100b93dfc..e0b9fe1d0e37 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -271,6 +271,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) while (remaining_words) { int n_words, tx_words, rx_words; u32 sr; + int stalled; n_words = min(remaining_words, xspi->buffer_size); @@ -299,7 +300,17 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) /* Read out all the data from the Rx FIFO */ rx_words = n_words; + stalled = 10; while (rx_words) { + if (rx_words == n_words && !(stalled--) && + !(sr & XSPI_SR_TX_EMPTY_MASK) && + (sr & XSPI_SR_RX_EMPTY_MASK)) { + dev_err(&spi->dev, + "Detected stall. Check C_SPI_MODE and C_SPI_MEMORY\n"); + xspi_init_hw(xspi); + return -EIO; + } + if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) { xilinx_spi_rx(xspi); rx_words--; diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index d8e4219c2324..f48a2ee587a4 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -3,10 +3,7 @@ config SSB_POSSIBLE depends on HAS_IOMEM && HAS_DMA default y -menu "Sonics Silicon Backplane" - depends on SSB_POSSIBLE - -config SSB +menuconfig SSB tristate "Sonics Silicon Backplane support" depends on SSB_POSSIBLE help @@ -21,6 +18,8 @@ config SSB If unsure, say N. +if SSB + # Common SPROM support routines config SSB_SPROM bool @@ -185,4 +184,4 @@ config SSB_DRIVER_GPIO If unsure, say N -endmenu +endif # SSB diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 7c69b4a9694d..0d99b242e82e 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -920,7 +920,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, " %d i: %d bio: %p, allocating another" " bio\n", bio->bi_vcnt, i, bio); - rc = blk_rq_append_bio(req, bio); + rc = blk_rq_append_bio(req, &bio); if (rc) { pr_err("pSCSI: failed to append bio\n"); goto fail; @@ -938,7 +938,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, } if (bio) { - rc = blk_rq_append_bio(req, bio); + rc = blk_rq_append_bio(req, &bio); if (rc) { pr_err("pSCSI: failed to append bio\n"); goto fail; |