[PATCH net] MAINTAINERS: update cxgb4 maintainer
Ganesg will be taking over as maintainer from now Signed-off-by: Hariprasad Shenai --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c36976d3bd1a..af3456d33a18 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3564,7 +3564,7 @@ F:drivers/infiniband/hw/cxgb3/ F: include/uapi/rdma/cxgb3-abi.h CXGB4 ETHERNET DRIVER (CXGB4) -M: Hariprasad S +M: Ganesh Goudar L: netdev@vger.kernel.org W: http://www.chelsio.com S: Supported -- 2.3.4
[PATCH net-next] cxgb4: Shutdown adapter if firmware times out or errors out
Perform an emergency shutdown of the adapter and stop it from continuing any further communication on the ports or DMA to the host. This is typically used when the adapter and/or firmware have crashed and we want to prevent any further accidental communication with the rest of the world. This will also force the port Link Status to go down -- if register writes work -- which should help our peers figure out that we're down. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 20 +++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 39 +++-- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h| 8 + 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index ad0096e74813..ccb455f14d08 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1501,6 +1501,7 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, const u8 *fw_data, unsigned int fw_size, struct fw_hdr *card_fw, enum dev_state state, int *reset); int t4_prep_adapter(struct adapter *adapter); +int t4_shutdown_adapter(struct adapter *adapter); enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS }; int t4_bar2_sge_qregs(struct adapter *adapter, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 3349e1f376c3..45ec2374f668 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2782,8 +2782,24 @@ static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = { void t4_fatal_err(struct adapter *adap) { - t4_set_reg_field(adap, SGE_CONTROL_A, GLOBALENABLE_F, 0); - t4_intr_disable(adap); + int port; + + /* Disable the SGE since ULDs are going to free resources that +* could be exposed to the adapter. RDMA MWs for example... +*/ + t4_shutdown_adapter(adap); + for_each_port(adap, port) { + struct net_device *dev = adap->port[port]; + + /* If we get here in very early initialization the network +* devices may not have been set up yet. +*/ + if (!dev) + continue; + + netif_tx_stop_all_queues(dev); + netif_carrier_off(dev); + } dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n"); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index f113015074b1..093444a220af 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -330,11 +330,12 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, * mailbox access list but this is a start. We very rearely * contend on access to the mailbox ... */ - if (i > FW_CMD_MAX_TIMEOUT) { + pcie_fw = t4_read_reg(adap, PCIE_FW_A); + if (i > FW_CMD_MAX_TIMEOUT || (pcie_fw & PCIE_FW_ERR_F)) { spin_lock(&adap->mbox_lock); list_del(&entry.list); spin_unlock(&adap->mbox_lock); - ret = -EBUSY; + ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -EBUSY; t4_record_mbox(adap, cmd, size, access, ret); return ret; } @@ -432,6 +433,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, spin_lock(&adap->mbox_lock); list_del(&entry.list); spin_unlock(&adap->mbox_lock); + t4_fatal_err(adap); return ret; } @@ -7540,6 +7542,39 @@ int t4_prep_adapter(struct adapter *adapter) } /** + * t4_shutdown_adapter - shut down adapter, host & wire + * @adapter: the adapter + * + * Perform an emergency shutdown of the adapter and stop it from + * continuing any further communication on the ports or DMA to the + * host. This is typically used when the adapter and/or firmware + * have crashed and we want to prevent any further accidental + * communication with the rest of the world. This will also force + * the port Link Status to go down -- if register writes work -- + * which should help our peers figure out that we're down. + */ +int t4_shutdown_adapter(struct adapter *adapter) +{ + int port; + + t4_intr_disable(adapter); + t4_write_reg(adapter, DBG_GPIO_EN_A, 0); + for_each_port(adapter, port) { + u32 a_port_cfg = POR
[PATCHv2 net-next] cxgb4: Synchronize access to mailbox
The issue comes when there are multiple threads attempting to use the mailbox facility at the same time. When DCB operations and interface up/down is run in a loop for every 0.1 sec, we observed mailbox collisions. And out of the two commands one would fail with the present code, since we don't queue the second command. To overcome the above issue, added a queue to access the mailbox. Whenever a mailbox command is issued add it to the queue. If its at the head issue the mailbox command, else wait for the existing command to complete. Usually command takes less than a milli-second to complete. Also timeout from the loop, if the command under execution takes long time to run. In reality, the number of mailbox access collisions is going to be very rare since no one runs such abusive script. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 ++ drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 59 - 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 0bce1bf9ca0f..78a852c72f5d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -782,6 +782,10 @@ struct vf_info { bool pf_set_mac; }; +struct mbox_list { + struct list_head list; +}; + struct adapter { void __iomem *regs; void __iomem *bar2; @@ -844,6 +848,10 @@ struct adapter { struct work_struct db_drop_task; bool tid_release_task_busy; + /* lock for mailbox cmd list */ + spinlock_t mbox_lock; + struct mbox_list mlist; + /* support for mailbox command/reply logging */ #define T4_OS_LOG_MBOX_CMDS 256 struct mbox_cmd_log *mbox_log; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 6f951877430b..9d2fe5140b88 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4707,6 +4707,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&adapter->stats_lock); spin_lock_init(&adapter->tid_release_lock); spin_lock_init(&adapter->win0_lock); + spin_lock_init(&adapter->mbox_lock); + + INIT_LIST_HEAD(&adapter->mlist.list); INIT_WORK(&adapter->tid_release_task, process_tid_release_list); INIT_WORK(&adapter->db_full_task, process_db_full); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index e8139514d32c..7ac6ea531b0f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -284,6 +284,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, 1, 1, 3, 5, 10, 10, 20, 50, 100, 200 }; + struct mbox_list entry; u16 access = 0; u16 execute = 0; u32 v; @@ -311,11 +312,61 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, timeout = -timeout; } + /* Queue ourselves onto the mailbox access list. When our entry is at +* the front of the list, we have rights to access the mailbox. So we +* wait [for a while] till we're at the front [or bail out with an +* EBUSY] ... +*/ + spin_lock(&adap->mbox_lock); + list_add_tail(&entry.list, &adap->mlist.list); + spin_unlock(&adap->mbox_lock); + + delay_idx = 0; + ms = delay[0]; + + for (i = 0; ; i += ms) { + /* If we've waited too long, return a busy indication. This +* really ought to be based on our initial position in the +* mailbox access list but this is a start. We very rearely +* contend on access to the mailbox ... +*/ + if (i > FW_CMD_MAX_TIMEOUT) { + spin_lock(&adap->mbox_lock); + list_del(&entry.list); + spin_unlock(&adap->mbox_lock); + ret = -EBUSY; + t4_record_mbox(adap, cmd, size, access, ret); + return ret; + } + + /* If we're at the head, break out and start the mailbox +* protocol. +*/ + if (list_first_entry(&adap->mlist.list, struct mbox_list, +list) == &entry) + break; + + /* Delay for a bit before checking again ... */ + if (sleep_ok) { + ms = delay[delay_idx]; /* last
[PATCH net-next] cxgb4: Synchronize access to mailbox
The issue comes when there are multiple threads attempting to use the mailbox facility at the same time. When DCB operations and interface up/down is run in a loop for every 0.1 sec, we observed mailbox collisions. And out of the two commands one would fail with the present code, since we don't queue the second command. To overcome the above issue, added a queue to access the mailbox. Whenever a mailbox command is issued add it to the queue. If its at the head issue the mailbox command, else wait for the existing command to complete. Usually command takes less than a milli-second to complete. Also timeout from the loop, if the command under execution takes long time to run. In reality, the number of mailbox access collisions is going to be very rare since no one runs such abusive script. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 ++ drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 59 - 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 0bce1bf9ca0f..78a852c72f5d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -782,6 +782,10 @@ struct vf_info { bool pf_set_mac; }; +struct mbox_list { + struct list_head list; +}; + struct adapter { void __iomem *regs; void __iomem *bar2; @@ -844,6 +848,10 @@ struct adapter { struct work_struct db_drop_task; bool tid_release_task_busy; + /* lock for mailbox cmd list */ + spinlock_t mbox_lock; + struct mbox_list mlist; + /* support for mailbox command/reply logging */ #define T4_OS_LOG_MBOX_CMDS 256 struct mbox_cmd_log *mbox_log; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 6f951877430b..34ceb3518dd4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4707,6 +4707,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&adapter->stats_lock); spin_lock_init(&adapter->tid_release_lock); spin_lock_init(&adapter->win0_lock); + spin_lock_init(&adapter->mbox_lock); + + INIT_LIST_HEAD(&adapter->mbox_list.list); INIT_WORK(&adapter->tid_release_task, process_tid_release_list); INIT_WORK(&adapter->db_full_task, process_db_full); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index e8139514d32c..7ac6ea531b0f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -284,6 +284,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, 1, 1, 3, 5, 10, 10, 20, 50, 100, 200 }; + struct mbox_list entry; u16 access = 0; u16 execute = 0; u32 v; @@ -311,11 +312,61 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, timeout = -timeout; } + /* Queue ourselves onto the mailbox access list. When our entry is at +* the front of the list, we have rights to access the mailbox. So we +* wait [for a while] till we're at the front [or bail out with an +* EBUSY] ... +*/ + spin_lock(&adap->mbox_lock); + list_add_tail(&entry.list, &adap->mlist.list); + spin_unlock(&adap->mbox_lock); + + delay_idx = 0; + ms = delay[0]; + + for (i = 0; ; i += ms) { + /* If we've waited too long, return a busy indication. This +* really ought to be based on our initial position in the +* mailbox access list but this is a start. We very rearely +* contend on access to the mailbox ... +*/ + if (i > FW_CMD_MAX_TIMEOUT) { + spin_lock(&adap->mbox_lock); + list_del(&entry.list); + spin_unlock(&adap->mbox_lock); + ret = -EBUSY; + t4_record_mbox(adap, cmd, size, access, ret); + return ret; + } + + /* If we're at the head, break out and start the mailbox +* protocol. +*/ + if (list_first_entry(&adap->mlist.list, struct mbox_list, +list) == &entry) + break; + + /* Delay for a bit before checking again ... */ + if (sleep_ok) { + ms = delay[delay_idx]; /* last
[PATCH net] cxgb4: Add PCI device ID for new adapter
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h | 1 + 1 file changed, 1 insertion(+) 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 df1573c4a659..ecf3ccc257bc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -168,6 +168,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */ CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */ CH_PCI_ID_TABLE_FENTRY(0x509c), /* Custom T520-CR*/ + CH_PCI_ID_TABLE_FENTRY(0x509d), /* Custom T540-CR*/ /* T6 adapters: */ -- 2.3.4
[PATCH net] cxgb4: correct device ID of T6 adapter
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 50812a1d67bd..df1573c4a659 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -178,9 +178,9 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x6005), CH_PCI_ID_TABLE_FENTRY(0x6006), CH_PCI_ID_TABLE_FENTRY(0x6007), + CH_PCI_ID_TABLE_FENTRY(0x6008), CH_PCI_ID_TABLE_FENTRY(0x6009), CH_PCI_ID_TABLE_FENTRY(0x600d), - CH_PCI_ID_TABLE_FENTRY(0x6010), CH_PCI_ID_TABLE_FENTRY(0x6011), CH_PCI_ID_TABLE_FENTRY(0x6014), CH_PCI_ID_TABLE_FENTRY(0x6015), -- 2.3.4
[PATCHv2 net] cxgb4/cxgb4vf: Allocate more queues for 25G and 100G adapter
We were missing check for 25G and 100G while checking port speed, which lead to less number of queues getting allocated for 25G & 100G adapters and leading to low throughput. Adding the missing check for both NIC and vNIC driver. Also fixes port advertisement for 25G and 100G in ethtool output. Signed-off-by: Hariprasad Shenai --- V2: Missed 25G in the first one drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 4 ++-- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 15 +-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 7 ++- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 6 ++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 15 +++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 9 +++-- 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 2e2aa9fec9bb..edd23386b47d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -419,8 +419,8 @@ struct link_config { unsigned short supported;/* link capabilities */ unsigned short advertising; /* advertised capabilities */ unsigned short lp_advertising; /* peer advertised capabilities */ - unsigned short requested_speed; /* speed user has requested */ - unsigned short speed;/* actual link speed */ + unsigned int requested_speed; /* speed user has requested */ + unsigned int speed;/* actual link speed */ unsigned char requested_fc; /* flow control user has requested */ unsigned char fc; /* actual link flow control */ unsigned char autoneg; /* autonegotiating? */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c762a8c8c954..3ceafb55d6da 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4305,10 +4305,17 @@ static const struct pci_error_handlers cxgb4_eeh = { .resume = eeh_resume, }; +/* Return true if the Link Configuration supports "High Speeds" (those greater + * than 1Gb/s). + */ static inline bool is_x_10g_port(const struct link_config *lc) { - return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 || - (lc->supported & FW_PORT_CAP_SPEED_40G) != 0; + unsigned int speeds, high_speeds; + + speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported)); + high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G); + + return high_speeds != 0; } static inline void init_rspq(struct adapter *adap, struct sge_rspq *q, @@ -4756,8 +4763,12 @@ static void print_port_info(const struct net_device *dev) bufp += sprintf(bufp, "1000/"); if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) bufp += sprintf(bufp, "10G/"); + if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) + bufp += sprintf(bufp, "25G/"); if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) bufp += sprintf(bufp, "40G/"); + if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) + bufp += sprintf(bufp, "100G/"); if (bufp != buf) --bufp; sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type)); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index dc92c80a75f4..660204bff726 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3627,7 +3627,8 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) } #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ -FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ +FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \ +FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \ FW_PORT_CAP_ANEG) /** @@ -7196,8 +7197,12 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) speed = 1000; else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) speed = 1; + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G)) + speed = 25000; else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) speed = 4; + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G)) + speed = 10; lc = &pi->link_cfg; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index a89b30720e38..30507d44422c 1
Re: [PATCH net] cxgb4/cxgb4vf: Allocate more queues for 100G adapter
On Mon, Sep 19, 2016 at 01:32:46PM +0530, Hariprasad Shenai wrote: > We were missing check for 100G while checking port speed, which lead to > less number of queues getting allocated for 100G and leading to low > throughput. Adding the missing check for both NIC and vNIC driver. > > Signed-off-by: Hariprasad Shenai > --- Hi David, I missed 25G, will send a V2 for the same with changes for 25Gbps adapter too. Thanks, Hari
[PATCH net] cxgb4/cxgb4vf: Allocate more queues for 100G adapter
We were missing check for 100G while checking port speed, which lead to less number of queues getting allocated for 100G and leading to low throughput. Adding the missing check for both NIC and vNIC driver. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 3 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c762a8c8c954..a8e4580f0440 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4308,7 +4308,8 @@ static const struct pci_error_handlers cxgb4_eeh = { static inline bool is_x_10g_port(const struct link_config *lc) { return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 || - (lc->supported & FW_PORT_CAP_SPEED_40G) != 0; + (lc->supported & FW_PORT_CAP_SPEED_40G) != 0 || + (lc->supported & FW_PORT_CAP_SPEED_100G) != 0; } static inline void init_rspq(struct adapter *adap, struct sge_rspq *q, diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index dc92c80a75f4..37885223347d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3628,7 +3628,7 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ -FW_PORT_CAP_ANEG) +FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG) /** * t4_link_l1cfg - apply link configuration to MAC/PHY diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 8ee541431e8b..903c0584c6c4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -274,7 +274,8 @@ static inline bool is_10g_port(const struct link_config *lc) static inline bool is_x_10g_port(const struct link_config *lc) { return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 || - (lc->supported & FW_PORT_CAP_SPEED_40G) != 0; + (lc->supported & FW_PORT_CAP_SPEED_40G) != 0 || + (lc->supported & FW_PORT_CAP_SPEED_100G) != 0; } static inline unsigned int core_ticks_per_usec(const struct adapter *adapter) -- 2.3.4
[PATCH net-next] chcr/cxgb4i/cxgbit/RDMA/cxgb4: Allocate resources dynamically for all cxgb4 ULD's
Allocate resources dynamically to cxgb4's Upper layer driver's(ULD) like cxgbit, iw_cxgb4 and cxgb4i. Allocate resources when they register with cxgb4 driver and free them while unregistering. All the queues and the interrupts for them will be allocated during ULD probe only and freed during remove. Signed-off-by: Hariprasad Shenai --- drivers/crypto/chelsio/chcr_core.c | 10 +- drivers/infiniband/hw/cxgb4/device.c |4 + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 47 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 127 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 613 +--- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 223 ++-- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 31 +- drivers/net/ethernet/chelsio/cxgb4/sge.c | 18 +- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c |3 + drivers/target/iscsi/cxgbit/cxgbit_main.c |3 + 10 files changed, 385 insertions(+), 694 deletions(-) diff --git a/drivers/crypto/chelsio/chcr_core.c b/drivers/crypto/chelsio/chcr_core.c index 2f6156b..fb5f9bb 100644 --- a/drivers/crypto/chelsio/chcr_core.c +++ b/drivers/crypto/chelsio/chcr_core.c @@ -39,12 +39,10 @@ static chcr_handler_func work_handlers[NUM_CPL_CMDS] = { [CPL_FW6_PLD] = cpl_fw6_pld_handler, }; -static struct cxgb4_pci_uld_info chcr_uld_info = { +static struct cxgb4_uld_info chcr_uld_info = { .name = DRV_MODULE_NAME, - .nrxq = 4, + .nrxq = MAX_ULD_QSETS, .rxq_size = 1024, - .nciq = 0, - .ciq_size = 0, .add = chcr_uld_add, .state_change = chcr_uld_state_change, .rx_handler = chcr_uld_rx_handler, @@ -205,7 +203,7 @@ static int chcr_uld_state_change(void *handle, enum cxgb4_state state) static int __init chcr_crypto_init(void) { - if (cxgb4_register_pci_uld(CXGB4_PCI_ULD1, &chcr_uld_info)) { + if (cxgb4_register_uld(CXGB4_ULD_CRYPTO, &chcr_uld_info)) { pr_err("ULD register fail: No chcr crypto support in cxgb4"); return -1; } @@ -228,7 +226,7 @@ static void __exit chcr_crypto_exit(void) kfree(u_ctx); } mutex_unlock(&dev_mutex); - cxgb4_unregister_pci_uld(CXGB4_PCI_ULD1); + cxgb4_unregister_uld(CXGB4_ULD_CRYPTO); } module_init(chcr_crypto_init); diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 071d733..f170b63 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -1475,6 +1475,10 @@ static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...) static struct cxgb4_uld_info c4iw_uld_info = { .name = DRV_NAME, + .nrxq = MAX_ULD_QSETS, + .rxq_size = 511, + .ciq = true, + .lro = false, .add = c4iw_uld_add, .rx_handler = c4iw_uld_rx_handler, .state_change = c4iw_uld_state_change, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 4595569..1f9867d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -437,11 +437,6 @@ enum { MAX_ETH_QSETS = 32, /* # of Ethernet Tx/Rx queue sets */ MAX_OFLD_QSETS = 16, /* # of offload Tx, iscsi Rx queue sets */ MAX_CTRL_QUEUES = NCHAN, /* # of control Tx queues */ - MAX_RDMA_QUEUES = NCHAN, /* # of streaming RDMA Rx queues */ - MAX_RDMA_CIQS = 32,/* # of RDMA concentrator IQs */ - - /* # of streaming iSCSIT Rx queues */ - MAX_ISCSIT_QUEUES = MAX_OFLD_QSETS, }; enum { @@ -458,8 +453,7 @@ enum { enum { INGQ_EXTRAS = 2,/* firmware event queue and */ /* forwarded interrupts */ - MAX_INGQ = MAX_ETH_QSETS + MAX_OFLD_QSETS + MAX_RDMA_QUEUES + - MAX_RDMA_CIQS + MAX_ISCSIT_QUEUES + INGQ_EXTRAS, + MAX_INGQ = MAX_ETH_QSETS + INGQ_EXTRAS, }; struct adapter; @@ -704,10 +698,6 @@ struct sge { struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES]; struct sge_eth_rxq ethrxq[MAX_ETH_QSETS]; - struct sge_ofld_rxq iscsirxq[MAX_OFLD_QSETS]; - struct sge_ofld_rxq iscsitrxq[MAX_ISCSIT_QUEUES]; - struct sge_ofld_rxq rdmarxq[MAX_RDMA_QUEUES]; - struct sge_ofld_rxq rdmaciq[MAX_RDMA_CIQS]; struct sge_rspq fw_evtq cacheline_aligned_in_smp; struct sge_uld_rxq_info **uld_rxq_info; @@ -717,15 +707,8 @@ struct sge { u16 max_ethqsets; /* # of available Ethernet queue sets */ u16 ethqsets; /* # of active Ethernet queue sets */ u16 ethtxq_rover; /* Tx queue to clean up next */ - u16 iscsiqsets; /* # of active iSCSI queue sets */ - u16 niscsitq; /* # of available iSCST
[PATCHv2 net-next] cxgb4vf: don't offload Rx checksums for IPv6 fragments
The checksum provided by the device doesn't include the L3 headers, as IPv6 expects Signed-off-by: Hariprasad Shenai --- V2: Fixed compilation issue reported by kbuild bot drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index c8fd4f8fe1fa..f3ed9ce99e5e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -1648,14 +1648,15 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, if (csum_ok && !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP_F | RXF_TCP_F))) { - if (!pkt->ip_frag) + if (!pkt->ip_frag) { skb->ip_summed = CHECKSUM_UNNECESSARY; - else { + rxq->stats.rx_cso++; + } else if (pkt->l2info & htonl(RXF_IP_F)) { __sum16 c = (__force __sum16)pkt->csum; skb->csum = csum_unfold(c); skb->ip_summed = CHECKSUM_COMPLETE; + rxq->stats.rx_cso++; } - rxq->stats.rx_cso++; } else skb_checksum_none_assert(skb); -- 2.3.4
[PATCH net-next] cxgb4vf: don't offload Rx checksums for IPv6 fragments
The checksum provided by the device doesn't include the L3 headers, as IPv6 expects Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index c8fd4f8fe1fa..4d4b94a8969a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -1648,14 +1648,15 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, if (csum_ok && !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP_F | RXF_TCP_F))) { - if (!pkt->ip_frag) + if (!pkt->ip_frag) { skb->ip_summed = CHECKSUM_UNNECESSARY; - else { + rxq->stats.rx_cso++; + } else if (pkt->l2info & htonl(F_RXF_IP)) { __sum16 c = (__force __sum16)pkt->csum; skb->csum = csum_unfold(c); skb->ip_summed = CHECKSUM_COMPLETE; + rxq->stats.rx_cso++; } - rxq->stats.rx_cso++; } else skb_checksum_none_assert(skb); -- 2.3.4
[PATCH net-next] cxgb4: Add support for ndo_get_vf_config
Adds support for ndo_get_vf_config, also fill the default mac address that will be provided to the VF by firmware, in case user doesn't provide one. So user can get the default MAC address address also through ndo_get_vf_config. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |8 +++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 64 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c |2 +- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 3f7b33a..4595569 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -788,6 +788,11 @@ struct uld_msix_info { char desc[IFNAMSIZ + 10]; }; +struct vf_info { + unsigned char vf_mac_addr[ETH_ALEN]; + bool pf_set_mac; +}; + struct adapter { void __iomem *regs; void __iomem *bar2; @@ -821,6 +826,9 @@ struct adapter { struct net_device *port[MAX_NPORTS]; u8 chan_map[NCHAN]; /* channel -> port map */ + struct vf_info *vfinfo; + u8 num_vfs; + u32 filter_mode; unsigned int l2t_start; unsigned int l2t_end; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 44019bd..44cc976 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3094,10 +3094,44 @@ static int dummy_open(struct net_device *dev) return 0; } +/* Fill MAC address that will be assigned by the FW */ +static void fill_vf_station_mac_addr(struct adapter *adap) +{ + unsigned int i; + u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN]; + int err; + u8 *na; + u16 a, b; + + err = t4_get_raw_vpd_params(adap, &adap->params.vpd); + if (!err) { + na = adap->params.vpd.na; + for (i = 0; i < ETH_ALEN; i++) + hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 + + hex2val(na[2 * i + 1])); + a = (hw_addr[0] << 8) | hw_addr[1]; + b = (hw_addr[1] << 8) | hw_addr[2]; + a ^= b; + a |= 0x0200;/* locally assigned Ethernet MAC address */ + a &= ~0x0100; /* not a multicast Ethernet MAC address */ + macaddr[0] = a >> 8; + macaddr[1] = a & 0xff; + + for (i = 2; i < 5; i++) + macaddr[i] = hw_addr[i + 1]; + + for (i = 0; i < adap->num_vfs; i++) { + macaddr[5] = adap->pf * 16 + i; + ether_addr_copy(adap->vfinfo[i].vf_mac_addr, macaddr); + } + } +} + static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) { struct port_info *pi = netdev_priv(dev); struct adapter *adap = pi->adapter; + int ret; /* verify MAC addr is valid */ if (!is_valid_ether_addr(mac)) { @@ -3109,7 +3143,23 @@ static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) dev_info(pi->adapter->pdev_dev, "Setting MAC %pM on VF %d\n", mac, vf); - return t4_set_vf_mac_acl(adap, vf + 1, 1, mac); + ret = t4_set_vf_mac_acl(adap, vf + 1, 1, mac); + if (!ret) + ether_addr_copy(adap->vfinfo[vf].vf_mac_addr, mac); + return ret; +} + +static int cxgb_get_vf_config(struct net_device *dev, + int vf, struct ifla_vf_info *ivi) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + + if (vf >= adap->num_vfs) + return -EINVAL; + ivi->vf = vf; + ether_addr_copy(ivi->mac, adap->vfinfo[vf].vf_mac_addr); + return 0; } #endif @@ -3259,6 +3309,7 @@ static const struct net_device_ops cxgb4_netdev_ops = { static const struct net_device_ops cxgb4_mgmt_netdev_ops = { .ndo_open = dummy_open, .ndo_set_vf_mac = cxgb_set_vf_mac, + .ndo_get_vf_config= cxgb_get_vf_config, }; #endif @@ -5116,6 +5167,10 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) unregister_netdev(adap->port[0]); adap->port[0] = NULL; } + /* free VF resources */ + kfree(adap->vfinfo); + adap->vfinfo = NULL; + adap->num_vfs = 0; return num_vfs; } @@ -5124,10 +5179,16 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) if (err) return err; + adap->num_vfs = num_vfs; err = config_mgmt
Re: [PATCH net-next 1/2] cxgb4/cxgb4vf: Add support for ndo_set_vf_vlan
On Wednesday, August 08/24/16, 2016 at 08:31:58 +, Yuval Mintz wrote: > > > > @@ -1202,6 +1202,10 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct > > > > net_device *dev) > > > > BUG_ON(qidx >= pi->nqsets); > > > > txq = &adapter->sge.ethtxq[pi->first_qset + qidx]; > > > > > > > > + if (pi->vlan_id && !skb_vlan_tag_present(skb)) > > > > + __vlan_hwaccel_put_tag(skb, cpu_to_be16(ETH_P_8021Q), > > > > + pi->vlan_id); > > > > + > > > > > > So it's a purely SW implementation of the feature on the VF side? > > > Does the HW enforces the configuration in any way on the VF? > > Basically the PF driver passes the VLAN ID it got through ndo_set_vf_vlan > > to the > > VF driver. And then the VF driver reads it and requests hardware to tag it. > > Problem with SW implementations is mainly that they have no effect over > Malicious VFs > I.e., if the purpose here is to add the VF to some vlan-tagged subnet > Whereas the user is oblivious to it, a malicious user can easily modify > the driver to ignore this restriction and get access to the entire network. > > I think one of the problems with this ndo is that it's poorly documented > and thus open for various interpretations - so it's debatable what's important > and what's not. [If it is properly documented anywhere, please educate me] I agree with you. Even I coudn't find a proper documentation for the same. I never thought about security issuses, (i.e., user modifying the VF driver to gain access over the network) while implementing this. > > > Also, looks like an already tagged packet would be processed with the > > > original vlan-id [instead of the one of PF has provided]. > > > Is that intentional? > > No, this isn't intentional. I thought VST and VGT cannot co-exist. > > What should be the behavior? > > Are you preventing VGT configuration once VST is configured? > If not, what to prevent VM user from configuring vlan interfaces > on top of the VF, even if VST is configured? Again this misses documentation, what if VLAN interface is already configured in VM before VST is configured. Before there were callbacks to add/remove vlan interface, now that is removed how to achieve it? OR am I missing something?
Re: [PATCH net-next 1/2] cxgb4/cxgb4vf: Add support for ndo_set_vf_vlan
On Wednesday, August 08/24/16, 2016 at 07:08:14 +, Yuval Mintz wrote: > > @@ -1202,6 +1202,10 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct > > net_device *dev) > > BUG_ON(qidx >= pi->nqsets); > > txq = &adapter->sge.ethtxq[pi->first_qset + qidx]; > > > > + if (pi->vlan_id && !skb_vlan_tag_present(skb)) > > + __vlan_hwaccel_put_tag(skb, cpu_to_be16(ETH_P_8021Q), > > + pi->vlan_id); > > + > > So it's a purely SW implementation of the feature on the VF side? > Does the HW enforces the configuration in any way on the VF? Basically the PF driver passes the VLAN ID it got through ndo_set_vf_vlan to the VF driver. And then the VF driver reads it and requests hardware to tag it. > > Also, looks like an already tagged packet would be processed with > the original vlan-id [instead of the one of PF has provided]. > Is that intentional? No, this isn't intentional. I thought VST and VGT cannot co-exist. What should be the behavior? Thanks, Hariprasad Shenai
Re: [PATCH net-next 2/2] cxgb4: Add support for ndo_get_vf_config
On Wednesday, August 08/24/16, 2016 at 07:15:49 +, Yuval Mintz wrote: > > +static void fill_vf_station_mac_addr(struct adapter *adap) > > +{ > > + unsigned int i; > > + u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN]; > > + int err; > > + u8 *na; > > + u16 a, b; > > + > > + err = t4_get_raw_vpd_params(adap, &adap->params.vpd); > > + if (!err) { > > + na = adap->params.vpd.na; > > + for (i = 0; i < ETH_ALEN; i++) > > + hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 + > > + hex2val(na[2 * i + 1])); > > + a = (hw_addr[0] << 8) | hw_addr[1]; > > + b = (hw_addr[1] << 8) | hw_addr[2]; > > + a ^= b; > > + a |= 0x0200;/* locally assigned Ethernet MAC address */ > > + a &= ~0x0100; /* not a multicast Ethernet MAC address */ > > + macaddr[0] = a >> 8; > > + macaddr[1] = a & 0xff; > > + > > + for (i = 2; i < 5; i++) > > + macaddr[i] = hw_addr[i + 1]; > > + > > + for (i = 0; i < adap->num_vfs; i++) { > > + macaddr[5] = adap->pf * 16 + i; > > + ether_addr_copy(adap->vfinfo[i].vf_mac_addr, > > macaddr); > > + } > > + } > > +} > > That's some... magical magic? :-) > But I couldn't see anywhere in the patch where this MAC is propagated > to the VF, only to the new NDO(). Care to explain how does the VF learn it? > The same logic is used by the firmware to generate the MAC address for the VF. If MAC address isn't provided through IFLA_VF_MAC. This function is only used to populate the stationary MAC's for the VF, when user hasn't provided one. -Hari
[PATCH net-next 2/2] cxgb4: Add support for ndo_get_vf_config
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 10 +++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 77 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c |2 +- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index b20d345..2781658 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -788,6 +788,13 @@ struct uld_msix_info { char desc[IFNAMSIZ + 10]; }; +struct vf_info { + unsigned char vf_mac_addr[ETH_ALEN]; + bool pf_set_mac; + u16 pf_vlan; /* When set, guest VLAN config not allowed. */ + u16 pf_qos; +}; + struct adapter { void __iomem *regs; void __iomem *bar2; @@ -821,6 +828,9 @@ struct adapter { struct net_device *port[MAX_NPORTS]; u8 chan_map[NCHAN]; /* channel -> port map */ + struct vf_info *vfinfo; + u8 num_vfs; + u32 filter_mode; unsigned int l2t_start; unsigned int l2t_end; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 330e18a..9baab2c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3094,10 +3094,43 @@ static int dummy_open(struct net_device *dev) return 0; } +static void fill_vf_station_mac_addr(struct adapter *adap) +{ + unsigned int i; + u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN]; + int err; + u8 *na; + u16 a, b; + + err = t4_get_raw_vpd_params(adap, &adap->params.vpd); + if (!err) { + na = adap->params.vpd.na; + for (i = 0; i < ETH_ALEN; i++) + hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 + + hex2val(na[2 * i + 1])); + a = (hw_addr[0] << 8) | hw_addr[1]; + b = (hw_addr[1] << 8) | hw_addr[2]; + a ^= b; + a |= 0x0200;/* locally assigned Ethernet MAC address */ + a &= ~0x0100; /* not a multicast Ethernet MAC address */ + macaddr[0] = a >> 8; + macaddr[1] = a & 0xff; + + for (i = 2; i < 5; i++) + macaddr[i] = hw_addr[i + 1]; + + for (i = 0; i < adap->num_vfs; i++) { + macaddr[5] = adap->pf * 16 + i; + ether_addr_copy(adap->vfinfo[i].vf_mac_addr, macaddr); + } + } +} + static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) { struct port_info *pi = netdev_priv(dev); struct adapter *adap = pi->adapter; + int ret; /* verify MAC addr is valid */ if (!is_valid_ether_addr(mac)) { @@ -3109,14 +3142,22 @@ static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) dev_info(pi->adapter->pdev_dev, "Setting MAC %pM on VF %d\n", mac, vf); - return t4_set_vf_mac_acl(adap, vf + 1, 1, mac); + ret = t4_set_vf_mac_acl(adap, vf + 1, 1, mac); + if (!ret) + ether_addr_copy(adap->vfinfo[vf].vf_mac_addr, mac); + return ret; } static int cxgb_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) { struct port_info *pi = netdev_priv(dev); struct adapter *adap = pi->adapter; + int ret; + if (vf >= adap->num_vfs) { + dev_err(pi->adapter->pdev_dev, "Invalid VF %d\n", vf); + return -EINVAL; + } if (vlan > 4095 || qos > 7) { dev_err(pi->adapter->pdev_dev, "Illegal vlan value %u qos %u\n", vlan, qos); @@ -3129,7 +3170,27 @@ static int cxgb_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) "The VF [%d] interface needs to brought down and up, " "if VF is already up and running, for VST to work\n", vf); vlan |= qos << VLAN_PRIO_SHIFT; - return t4_set_vf_vlan_acl(adap, vf + 1, vlan); + ret = t4_set_vf_vlan_acl(adap, vf + 1, vlan); + if (!ret) { + adap->vfinfo[vf].pf_vlan = vlan & VLAN_VID_MASK; + adap->vfinfo[vf].pf_qos = qos; + } + return ret; +} + +static int cxgb_get_vf_config(struct net_device *dev, + int vf, struct ifla_vf_info *ivi) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + + if (vf >= adap->num_vfs) + return -EINVAL; + ivi->vf = vf; + ether_addr_copy(ivi->mac, adap->vfinfo[vf].vf_mac_addr); + ivi->vlan = adap->vfinfo[vf]
[PATCH net-next 0/2] cxgb4: Adds support for VF mgmt ndo's
Hi, This patch series adds support for ndo_set_vf_vlan and ndo_get_vf_config for cxgb4 driver. This patch series has been created against net-next tree. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (2): cxgb4/cxgb4vf: Add support for ndo_set_vf_vlan cxgb4: Add support for ndo_get_vf_config drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 11 +++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 96 +++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 27 ++- drivers/net/ethernet/chelsio/cxgb4vf/adapter.h |1 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|2 + drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 15 +++- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |1 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 28 ++ 8 files changed, 176 insertions(+), 5 deletions(-) -- 1.7.3
[PATCH net-next 1/2] cxgb4/cxgb4vf: Add support for ndo_set_vf_vlan
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |1 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 21 +++ drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 25 + drivers/net/ethernet/chelsio/cxgb4vf/adapter.h |1 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|2 + drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 15 -- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |1 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 28 8 files changed, 91 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 3f7b33a..b20d345 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1627,6 +1627,7 @@ void t4_idma_monitor(struct adapter *adapter, int hz, int ticks); int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, unsigned int naddr, u8 *addr); +int t4_set_vf_vlan_acl(struct adapter *adapter, unsigned int vf, u16 vlan); void uld_mem_free(struct adapter *adap); int uld_mem_alloc(struct adapter *adap); void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 44019bd..330e18a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3111,6 +3111,26 @@ static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) "Setting MAC %pM on VF %d\n", mac, vf); return t4_set_vf_mac_acl(adap, vf + 1, 1, mac); } + +static int cxgb_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + + if (vlan > 4095 || qos > 7) { + dev_err(pi->adapter->pdev_dev, + "Illegal vlan value %u qos %u\n", vlan, qos); + return -EINVAL; + } + + dev_info(pi->adapter->pdev_dev, +"Setting Vlan %u to VF [%d]\n", vlan, vf); + dev_info(pi->adapter->pdev_dev, +"The VF [%d] interface needs to brought down and up, " +"if VF is already up and running, for VST to work\n", vf); + vlan |= qos << VLAN_PRIO_SHIFT; + return t4_set_vf_vlan_acl(adap, vf + 1, vlan); +} #endif static int cxgb_set_mac_addr(struct net_device *dev, void *p) @@ -3259,6 +3279,7 @@ static const struct net_device_ops cxgb4_netdev_ops = { static const struct net_device_ops cxgb4_mgmt_netdev_ops = { .ndo_open = dummy_open, .ndo_set_vf_mac = cxgb_set_vf_mac, + .ndo_set_vf_vlan = cxgb_set_vf_vlan, }; #endif diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index de451ee..210979c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8334,3 +8334,28 @@ int t4_sched_params(struct adapter *adapter, int type, int level, int mode, return t4_wr_mbox_meat(adapter, adapter->mbox, &cmd, sizeof(cmd), NULL, 1); } + +/** + * t4_set_vf_vlan_acl - Set MAC address for the specified VF + * @adapter: The adapter + * @vf: one of the VFs instantiated by the specified PF + * @vlan: the vlan id + * @qos: QOS + */ +int t4_set_vf_vlan_acl(struct adapter *adapter, unsigned int vf, u16 vlan) +{ + struct fw_acl_vlan_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.op_to_vfn = htonl(FW_CMD_OP_V(FW_ACL_VLAN_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_ACL_MAC_CMD_PFN_V(adapter->pf) | + FW_ACL_MAC_CMD_VFN_V(vf)); + cmd.en_to_len16 = htonl((unsigned int)FW_LEN16(cmd)); + cmd.nvlan = 1; + cmd.vlanid[0] = vlan; + + return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); +} diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index 109bc63..ed1037e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h @@ -92,6 +92,7 @@ struct sge_rspq; */ struct port_info { struct adapter *adapter;/* our adapter */ + u32 vlan_id;/* vlan id for VST */ u16 viid; /* virtual interface ID */ s16 xact_addr_filt; /* index of our MAC address filter */ u16 rss_size; /* size of VI's RSS table slice */ diff --git a
Re: [PATCH] cxgb4: fix invalid checks in alloc_uld_rxqs
On Tuesday, August 08/23/16, 2016 at 10:01:59 +0200, Andrzej Hajda wrote: > On 08/23/2016 09:46 AM, Hariprasad Shenai wrote: > > On Tuesday, August 08/23/16, 2016 at 08:16:19 +0200, Andrzej Hajda wrote: > >> Local variable msi_idx defined as unsigned int is always >= 0, thus both > >> 'if' checks are always true. On the other side presence of USING_MSIX flag > >> suggests the checks should not be trivially true. > >> The simplest solution is to replace incorrect checks with direct testing > >> of adap->flags and remove spare variables. > >> > >> The problem has been detected using semantic patch > >> scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci > >> > > The correct fix is to have local variable 'msi_idx' as int instead of > > unsigned > > int. Thanks for reporting the issue. Do you want me to send a V2? > > > > Thanks, > > Hari > > > > > If adap->flags is constant during the call I see no point in creating > separate > > variable with complicated initialization used only for the same thing as > > 'adap->flags & USING_MSIX', and even if adap->flags changes during the call > > much simpler would be to use local var: > > int using_msix = adap->flags & USING_MSIX; > > and later use tests: > > if (using_msix) > > ... > > Am I correct? Yes, you are correct.
Re: [PATCH] cxgb4: fix invalid checks in alloc_uld_rxqs
On Tuesday, August 08/23/16, 2016 at 08:16:19 +0200, Andrzej Hajda wrote: > Local variable msi_idx defined as unsigned int is always >= 0, thus both > 'if' checks are always true. On the other side presence of USING_MSIX flag > suggests the checks should not be trivially true. > The simplest solution is to replace incorrect checks with direct testing > of adap->flags and remove spare variables. > > The problem has been detected using semantic patch > scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci > The correct fix is to have local variable 'msi_idx' as int instead of unsigned int. Thanks for reporting the issue. Do you want me to send a V2? Thanks, Hari
[PATCH net-next] cxgb4: Fix issue while re-registering VF mgmt netdev
When we disable SRIOV, we used to unregister the netdev but wasn't freed. But next time when the same netdev is registered, since the state was in 'NETREG_UNREGISTERED', we used to hit BUG_ON in register_netdevice, where it expects the state to be 'NETREG_UNINITIALIZED'. Alloc netdev and register them while configuring SRIOV, and free them when SRIOV is disabled. Also added a new function to setup ethernet properties instead of using ether_setup. Set carrier off by default, since we don't have to do any transmit on the interface. Fixes: 7829451c695e ("cxgb4: Add control net_device for configuring PCIe VF") Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |1 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 97 +++--- 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index f988c60..3f7b33a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -798,6 +798,7 @@ struct adapter { unsigned int mbox; unsigned int pf; unsigned int flags; + unsigned int adap_idx; enum chip_type chip; int msg_enable; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index be5c942..44019bd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3085,6 +3085,15 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) } #ifdef CONFIG_PCI_IOV +static int dummy_open(struct net_device *dev) +{ + /* Turn carrier off since we don't have to transmit anything on this +* interface. +*/ + netif_carrier_off(dev); + return 0; +} + static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) { struct port_info *pi = netdev_priv(dev); @@ -3246,11 +3255,12 @@ static const struct net_device_ops cxgb4_netdev_ops = { .ndo_set_tx_maxrate = cxgb_set_tx_maxrate, }; -static const struct net_device_ops cxgb4_mgmt_netdev_ops = { #ifdef CONFIG_PCI_IOV +static const struct net_device_ops cxgb4_mgmt_netdev_ops = { + .ndo_open = dummy_open, .ndo_set_vf_mac = cxgb_set_vf_mac, -#endif }; +#endif static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -5023,6 +5033,51 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) } #ifdef CONFIG_PCI_IOV +static void dummy_setup(struct net_device *dev) +{ + dev->type = ARPHRD_NONE; + dev->mtu = 0; + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->tx_queue_len = 0; + dev->flags |= IFF_NOARP; + dev->priv_flags |= IFF_NO_QUEUE; + + /* Initialize the device structure. */ + dev->netdev_ops = &cxgb4_mgmt_netdev_ops; + dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; + dev->destructor = free_netdev; +} + +static int config_mgmt_dev(struct pci_dev *pdev) +{ + struct adapter *adap = pci_get_drvdata(pdev); + struct net_device *netdev; + struct port_info *pi; + char name[IFNAMSIZ]; + int err; + + snprintf(name, IFNAMSIZ, "mgmtpf%d%d", adap->adap_idx, adap->pf); + netdev = alloc_netdev(0, name, NET_NAME_UNKNOWN, dummy_setup); + if (!netdev) + return -ENOMEM; + + pi = netdev_priv(netdev); + pi->adapter = adap; + SET_NETDEV_DEV(netdev, &pdev->dev); + + adap->port[0] = netdev; + + err = register_netdev(adap->port[0]); + if (err) { + pr_info("Unable to register VF mgmt netdev %s\n", name); + free_netdev(adap->port[0]); + adap->port[0] = NULL; + return err; + } + return 0; +} + static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) { struct adapter *adap = pci_get_drvdata(pdev); @@ -5057,8 +5112,10 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) */ if (!num_vfs) { pci_disable_sriov(pdev); - if (adap->port[0]->reg_state == NETREG_REGISTERED) + if (adap->port[0]) { unregister_netdev(adap->port[0]); + adap->port[0] = NULL; + } return num_vfs; } @@ -5067,11 +5124,9 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) if (err) return err; - if (adap->port[0]->reg_state == NETREG_UNINITIALIZED) { - err = register_netdev(adap->port[0]); - if (err < 0) - pr_info(&quo
[PATCH net-next] cxgb4/cxgb4vf: Add support for IFLA_VF_VLAN
Adds support for ndo_set_vf_vlan for cxgb4 driver Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 6b0528913687..f354f90d7faa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1572,6 +1572,7 @@ void t4_idma_monitor(struct adapter *adapter, int hz, int ticks); int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, unsigned int naddr, u8 *addr); +int t4_set_vf_vlan_acl(struct adapter *adapter, unsigned int vf, u16 vlan); void uld_mem_free(struct adapter *adap); int uld_mem_alloc(struct adapter *adap); void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl); -- 2.3.4
[PATCH net] cxgb4: Fixes resource allocation for ULD's in kdump kernel
At present the code to check in kdump kernel was not disabling allocation of resources when CONFIG_CHELSIO_T4_DCB is defined, move the code outside #defines so that it gets disabled irrespective of #define, when in kdump kernel. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49dc963..c762a8c8c954 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4335,6 +4335,11 @@ static void cfg_queues(struct adapter *adap) #endif int ciq_size; + /* Reduce memory usage in kdump environment, disable all offload. +*/ + if (is_kdump_kernel()) + adap->params.offload = 0; + for_each_port(adap, i) n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg); #ifdef CONFIG_CHELSIO_T4_DCB @@ -4365,11 +4370,6 @@ static void cfg_queues(struct adapter *adap) if (q10g > netif_get_num_default_rss_queues()) q10g = netif_get_num_default_rss_queues(); - /* Reduce memory usage in kdump environment, disable all offload. -*/ - if (is_kdump_kernel()) - adap->params.offload = 0; - for_each_port(adap, i) { struct port_info *pi = adap2pinfo(adap, i); -- 2.3.4
[PATCHv3 net-next 2/4] cxgb4: Register changes and fw defines for crypto
Signed-off-by: Atul Gupta Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 437 + drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 124 +++ 2 files changed, 561 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index 4705e2d..7a2be51 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h @@ -61,6 +61,7 @@ enum { CPL_ABORT_REQ_RSS = 0x2B, CPL_ABORT_RPL_RSS = 0x2D, + CPL_RX_PHYS_ADDR = 0x30, CPL_CLOSE_CON_RPL = 0x32, CPL_ISCSI_HDR = 0x33, CPL_RDMA_CQE = 0x35, @@ -83,6 +84,10 @@ enum { CPL_PASS_OPEN_REQ6= 0x81, CPL_ACT_OPEN_REQ6 = 0x83, + CPL_TX_TLS_PDU =0x88, + CPL_TX_SEC_PDU= 0x8A, + CPL_TX_TLS_ACK= 0x8B, + CPL_RDMA_TERMINATE= 0xA2, CPL_RDMA_WRITE= 0xA4, CPL_SGE_EGR_UPDATE= 0xA5, @@ -94,6 +99,8 @@ enum { CPL_FW4_PLD = 0xC1, CPL_FW4_ACK = 0xC3, + CPL_RX_PHYS_DSGL = 0xD0, + CPL_FW6_MSG = 0xE0, CPL_FW6_PLD = 0xE1, CPL_TX_PKT_LSO= 0xED, @@ -1360,6 +1367,15 @@ struct ulptx_idata { __be32 len; }; +struct ulp_txpkt { + __be32 cmd_dest; + __be32 len; +}; + +#define ULPTX_CMD_S24 +#define ULPTX_CMD_M0xFF +#define ULPTX_CMD_V(x) ((x) << ULPTX_CMD_S) + #define ULPTX_NSGE_S0 #define ULPTX_NSGE_V(x) ((x) << ULPTX_NSGE_S) @@ -1367,6 +1383,22 @@ struct ulptx_idata { #define ULPTX_MORE_V(x)((x) << ULPTX_MORE_S) #define ULPTX_MORE_F ULPTX_MORE_V(1U) +#define ULP_TXPKT_DEST_S16 +#define ULP_TXPKT_DEST_M0x3 +#define ULP_TXPKT_DEST_V(x) ((x) << ULP_TXPKT_DEST_S) + +#define ULP_TXPKT_FID_S 4 +#define ULP_TXPKT_FID_M 0x7ff +#define ULP_TXPKT_FID_V(x) ((x) << ULP_TXPKT_FID_S) + +#define ULP_TXPKT_RO_S 3 +#define ULP_TXPKT_RO_V(x) ((x) << ULP_TXPKT_RO_S) +#define ULP_TXPKT_RO_F ULP_TXPKT_RO_V(1U) + +#define ULP_TX_SC_MORE_S 23 +#define ULP_TX_SC_MORE_V(x) ((x) << ULP_TX_SC_MORE_S) +#define ULP_TX_SC_MORE_F ULP_TX_SC_MORE_V(1U) + struct ulp_mem_io { WR_HDR; __be32 cmd; @@ -1404,4 +1436,409 @@ struct ulp_mem_io { #define ULP_MEMIO_DATA_LEN_S0 #define ULP_MEMIO_DATA_LEN_V(x) ((x) << ULP_MEMIO_DATA_LEN_S) +#define ULPTX_NSGE_S0 +#define ULPTX_NSGE_M0x +#define ULPTX_NSGE_V(x) ((x) << ULPTX_NSGE_S) +#define ULPTX_NSGE_G(x) (((x) >> ULPTX_NSGE_S) & ULPTX_NSGE_M) + +struct ulptx_sc_memrd { + __be32 cmd_to_len; + __be32 addr; +}; + +#define ULP_TXPKT_DATAMODIFY_S 23 +#define ULP_TXPKT_DATAMODIFY_M 0x1 +#define ULP_TXPKT_DATAMODIFY_V(x)((x) << ULP_TXPKT_DATAMODIFY_S) +#define ULP_TXPKT_DATAMODIFY_G(x)\ + (((x) >> ULP_TXPKT_DATAMODIFY_S) & ULP_TXPKT_DATAMODIFY__M) +#define ULP_TXPKT_DATAMODIFY_F ULP_TXPKT_DATAMODIFY_V(1U) + +#define ULP_TXPKT_CHANNELID_S22 +#define ULP_TXPKT_CHANNELID_M0x1 +#define ULP_TXPKT_CHANNELID_V(x) ((x) << ULP_TXPKT_CHANNELID_S) +#define ULP_TXPKT_CHANNELID_G(x) \ + (((x) >> ULP_TXPKT_CHANNELID_S) & ULP_TXPKT_CHANNELID_M) +#define ULP_TXPKT_CHANNELID_FULP_TXPKT_CHANNELID_V(1U) + +#define SCMD_SEQ_NO_CTRL_S 29 +#define SCMD_SEQ_NO_CTRL_M 0x3 +#define SCMD_SEQ_NO_CTRL_V(x) ((x) << SCMD_SEQ_NO_CTRL_S) +#define SCMD_SEQ_NO_CTRL_G(x) \ + (((x) >> SCMD_SEQ_NO_CTRL_S) & SCMD_SEQ_NO_CTRL_M) + +/* StsFieldPrsnt- Status field at the end of the TLS PDU */ +#define SCMD_STATUS_PRESENT_S 28 +#define SCMD_STATUS_PRESENT_M 0x1 +#define SCMD_STATUS_PRESENT_V(x)((x) << SCMD_STATUS_PRESENT_S) +#define SCMD_STATUS_PRESENT_G(x)\ + (((x) >> SCMD_STATUS_PRESENT_S) & SCMD_STATUS_PRESENT_M) +#define SCMD_STATUS_PRESENT_F SCMD_STATUS_PRESENT_V(1U) + +/* ProtoVersion - Protocol Version 0: 1.2, 1:1.1, 2:DTLS, 3:Generic, + * 3-15: Reserved. + */ +#define SCMD_PROTO_VERSION_S24 +#define SCMD_PROTO_VERSION_M0xf +#define SCMD_PROTO_VERSION_V(x) ((x) << SCMD_PROTO_VERSION_S) +#define SCMD_PROTO_VERSION_G(x) \ + (((x) >> SCMD_PROTO_VERSION_S) & SCMD_PROTO_VERSION_M) + +/* EncDecCtrl - Encryption/Decryption Control. 0: Encrypt, 1: Decrypt */ +#define SCMD_ENC_DEC_CTRL_S 23 +#define SCMD_ENC_DEC_CTRL_M 0x1 +#define SCMD_ENC_DEC_CTRL_V(x) ((x) << SCMD_ENC_DEC_CTRL_S) +#define SCMD_ENC_DEC_CTRL_G(x) \ + (((x) >> SCMD_ENC_DEC_CTRL_S) & SCMD_ENC_DEC_CTRL_M) +#define SCMD_ENC_DEC_CTRL_F SCMD_ENC_DEC_CTRL_V(1U) + +/* CipherAuthSeqCtrl - Cipher Authentication Sequence Control. */ +#define SCMD_CIPH_AUTH_SEQ_CTRL_S 22 +#define SCMD_CIPH_AUTH_SE
[PATCHv3 net-next 3/4] chcr: Support for Chelsio's Crypto Hardware
The Chelsio's Crypto Hardware can perform the following operations: SHA1, SHA224, SHA256, SHA384 and SHA512, HMAC(SHA1), HMAC(SHA224), HMAC(SHA256), HMAC(SHA384), HAMC(SHA512), AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-XTS, AES-256-XTS This patch implements the driver for above mentioned features. This driver is an Upper Layer Driver which is attached to Chelsio's LLD (cxgb4) and uses the queue allocated by the LLD for sending the crypto requests to the Hardware and receiving the responses from it. The crypto operations can be performed by Chelsio's hardware from the userspace applications and/or from within the kernel space using the kernel's crypto API. The above mentioned crypto features have been tested using kernel's tests mentioned in testmgr.h. They also have been tested from user space using libkcapi and Openssl. Signed-off-by: Atul Gupta Signed-off-by: Hariprasad Shenai --- drivers/crypto/chelsio/chcr_algo.c | 1525 ++ drivers/crypto/chelsio/chcr_algo.h | 471 +++ drivers/crypto/chelsio/chcr_core.c | 240 ++ drivers/crypto/chelsio/chcr_core.h | 80 ++ drivers/crypto/chelsio/chcr_crypto.h | 204 + 5 files changed, 2520 insertions(+), 0 deletions(-) create mode 100644 drivers/crypto/chelsio/chcr_algo.c create mode 100644 drivers/crypto/chelsio/chcr_algo.h create mode 100644 drivers/crypto/chelsio/chcr_core.c create mode 100644 drivers/crypto/chelsio/chcr_core.h create mode 100644 drivers/crypto/chelsio/chcr_crypto.h diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c new file mode 100644 index 000..ad8e353 --- /dev/null +++ b/drivers/crypto/chelsio/chcr_algo.c @@ -0,0 +1,1525 @@ +/* + * This file is part of the Chelsio T6 Crypto driver for Linux. + * + * Copyright (c) 2003-2016 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Written and Maintained by: + * Manoj Malviya (manojmalv...@chelsio.com) + * Atul Gupta (atul.gu...@chelsio.com) + * Jitendra Lulla (jlu...@chelsio.com) + * Yeshaswi M R Gowda (yesha...@chelsio.com) + * Harsh Jain (ha...@chelsio.com) + */ + +#define pr_fmt(fmt) "chcr:" fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "t4fw_api.h" +#include "t4_msg.h" +#include "chcr_core.h" +#include "chcr_algo.h" +#include "chcr_crypto.h" + +static inline struct ablk_ctx *ABLK_CTX(struct chcr_context *ctx) +{ + return ctx->crypto_ctx->ablkctx; +} + +static inline struct hmac_ctx *HMAC_CTX(struct chcr_context *ctx) +{ + return ctx->crypto_ctx->hmacctx; +} + +static inline struct uld_ctx *ULD_CTX(struct chcr_context *ctx) +{ + return ctx->dev->u_ctx; +} + +static inline int is_ofld_imm(const struct sk_buff *skb) +{ + return (skb->len <= CRYPTO_MAX_IMM_TX_PKT_LEN); +} + +/* + * sgl_len - calculates the size of an SGL of the given capacity + * @n: the number of SGL entries + * Calculates the number of flits needed for a scatter/gather list that + * can hold the given number of entries. + */ +static inline unsigned int sgl_len(unsigned int n) +{ + n--; + return (3 * n) / 2 + (n & 1) + 2; +} + +/* + * chcr_handle_resp - Unmap the DMA buffers associated with the request + * @req: crypto request + */ +int chcr_handle_resp(struct crypto_async_request *req, unsigned char *input, +
[PATCHv3 net-next 4/4] crypto: Added Chelsio Menu to the Kconfig file
Adds the config entry for the Chelsio Crypto Driver, Makefile changes for the same. Signed-off-by: Atul Gupta Signed-off-by: Hariprasad Shenai --- drivers/crypto/Kconfig |2 ++ drivers/crypto/Makefile |1 + drivers/crypto/chelsio/Kconfig | 19 +++ drivers/crypto/chelsio/Makefile |4 4 files changed, 26 insertions(+), 0 deletions(-) create mode 100644 drivers/crypto/chelsio/Kconfig create mode 100644 drivers/crypto/chelsio/Makefile diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index d77ba2f..b44faf0 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -537,4 +537,6 @@ config CRYPTO_DEV_ROCKCHIP This driver interfaces with the hardware crypto accelerator. Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. +source "drivers/crypto/chelsio/Kconfig" + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 3c6432d..ad7250f 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -31,3 +31,4 @@ obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ +obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chelsio/ diff --git a/drivers/crypto/chelsio/Kconfig b/drivers/crypto/chelsio/Kconfig new file mode 100644 index 000..2c05224 --- /dev/null +++ b/drivers/crypto/chelsio/Kconfig @@ -0,0 +1,19 @@ +config CRYPTO_DEV_CHELSIO + tristate "Chelsio Crypto Co-processor Driver" + depends on CHELSIO_T4 + select CRYPTO_SHA1 + select CRYPTO_SHA256 + select CRYPTO_SHA512 + ---help--- + The Chelsio Crypto Co-processor driver for T6 adapters. + + For general information about Chelsio and our products, visit + our website at <http://www.chelsio.com>. + + For customer support, please visit our customer support page at + <http://www.chelsio.com/support.html>. + + Please send feedback to . + + To compile this driver as a module, choose M here: the module + will be called chcr. diff --git a/drivers/crypto/chelsio/Makefile b/drivers/crypto/chelsio/Makefile new file mode 100644 index 000..7e4fda5 --- /dev/null +++ b/drivers/crypto/chelsio/Makefile @@ -0,0 +1,4 @@ + ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 + + obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chcr.o + chcr-objs := chcr_core.o chcr_algo.o \ No newline at end of file -- 1.7.3
[PATCHv3 net-next 0/4] crypto/chcr: Add support for Chelsio Crypto Driver
Hi All, This patch series adds support for Chelsio Crypto driver. The patch series has been created against net-next tree and includes patches for Chelsio Low Level Driver(cxgb4) and adds the new crypto Upper Layer Driver(chcr) under a new directory drivers/crypto/chelsio. Patch 1/4 ("cxgb4: Add support for dynamic allocation of resources for ULD") adds support for dynamic allocation of resources for ULD. The objective of this patch is to provide generic interface for upper layer drivers to allocate and initialize hardware resources. The present cxgb4 (network driver) apart from network functionality, also initializes hardware and thus acts as lower layer driver for other drivers to use hardware resources. Thus it acts as both a Low level driver for Upper layer driver's like iw_cxgb4, cxgb4i and cxgb4it and a Network Driver. Right now the allocation of resources for Upper layer driver's is done statically. Patch 1/4 adds a new infrastructure for dynamic allocation of resources. cxgb4 will read the hardware capability through firmware and allocate/free the queues for Upper layer drivers when the respective driver's are loaded and freed when unloaded. Patch 2/3, 3/4 and 4/4 adds support for Chelsio Crypto Driver. The Crypto driver will act as another ULD on top of cxgb4. In this patch series, the ULD API framework is used only by crypto and other ULD's will make use of it in the next series. This patch series is only for review, if this looks ok we will test it thoroughly and send request for merge. We have included all the maintainers of respective drivers. Kindly review the changes and provide feedback on the same. V3: - Removed crypto queues from cxgb4 and added support for dynamic allocation of resources for Upper layer drivers - Dependency fix in Kconfig. V2: - Some residual code cleanup - Adds pr_fmt with chcr (KBUILD_MODNAME) added - Changes var name to accomodate them <80 columns in the chcr_register_alg - Support for printing the crypto queue stats - Fix compile warnings reported by kbuild bot for certain architectures - Dependency fix in Kconfig. - If the request has the MAY_BACKLOG bit set and hardware queue is full the request is queued up else -EBUSY is returned to throttle the user. The queue when executed and processed returns -EINPROGRESS in completion. Hariprasad Shenai (4): cxgb4: Add support for dynamic allocation of resources for ULD cxgb4: Register changes and fw defines for crypto chcr: Support for Chelsio's Crypto Hardware crypto: Added Chelsio Menu to the Kconfig file drivers/crypto/Kconfig |2 + drivers/crypto/Makefile |1 + drivers/crypto/chelsio/Kconfig | 19 + drivers/crypto/chelsio/Makefile |4 + drivers/crypto/chelsio/chcr_algo.c | 1525 +++ drivers/crypto/chelsio/chcr_algo.h | 471 +++ drivers/crypto/chelsio/chcr_core.c | 240 drivers/crypto/chelsio/chcr_core.h | 80 ++ drivers/crypto/chelsio/chcr_crypto.h| 204 +++ drivers/net/ethernet/chelsio/cxgb4/Makefile |2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 59 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 153 ++- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 555 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 34 +- drivers/net/ethernet/chelsio/cxgb4/sge.c|4 +- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 437 +++ drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 126 ++- 17 files changed, 3866 insertions(+), 50 deletions(-) create mode 100644 drivers/crypto/chelsio/Kconfig create mode 100644 drivers/crypto/chelsio/Makefile create mode 100644 drivers/crypto/chelsio/chcr_algo.c create mode 100644 drivers/crypto/chelsio/chcr_algo.h create mode 100644 drivers/crypto/chelsio/chcr_core.c create mode 100644 drivers/crypto/chelsio/chcr_core.h create mode 100644 drivers/crypto/chelsio/chcr_crypto.h create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c -- 1.7.3
[PATCHv3 net-next 1/4] cxgb4: Add support for dynamic allocation of resources for ULD
Add a new commmon infrastructure to allocate reosurces dynamically to Upper layer driver's(ULD) when they register with cxgb4 driver and free them during unregistering. All the queues and the interrupts for them will be allocated during ULD probe only and freed during remove. Signed-off-by: Atul Gupta Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/Makefile |2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 59 +++- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 153 +-- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 555 +++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 34 ++- drivers/net/ethernet/chelsio/cxgb4/sge.c|4 +- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h |2 +- 7 files changed, 759 insertions(+), 50 deletions(-) create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile index 85c9282..e955eda 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/Makefile +++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_CHELSIO_T4) += cxgb4.o -cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o +cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o cxgb4_uld.o cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o cxgb4-$(CONFIG_CHELSIO_T4_UWIRE) += cxgb4_ppm.o diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 7ce076f..94d7592 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -53,6 +53,8 @@ #include "cxgb4_uld.h" #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__) +extern struct list_head adapter_list; +extern struct mutex uld_mutex; enum { MAX_NPORTS = 4, /* max # of ports */ @@ -338,6 +340,7 @@ struct adapter_params { enum chip_type chip; /* chip code */ struct arch_specific_params arch; /* chip specific params */ unsigned char offload; + unsigned char crypto; /* HW capability for crypto */ unsigned char bypass; @@ -403,7 +406,6 @@ struct fw_info { struct fw_hdr fw_hdr; }; - struct trace_params { u32 data[TRACE_LEN / 4]; u32 mask[TRACE_LEN / 4]; @@ -509,6 +511,10 @@ enum { /* adapter flags */ FW_OFLD_CONN = (1 << 9), }; +enum { + ULP_CRYPTO_LOOKASIDE = 1 << 0, +}; + struct rx_sw_desc; struct sge_fl { /* SGE free-buffer queue state */ @@ -679,6 +685,16 @@ struct sge_ctrl_txq { /* state for an SGE control Tx queue */ u8 full;/* the Tx ring is full */ } cacheline_aligned_in_smp; +struct sge_uld_rxq_info { + char name[IFNAMSIZ];/* name of ULD driver */ + struct sge_ofld_rxq *uldrxq; /* Rxq's for ULD */ + u16 *msix_tbl; /* msix_tbl for uld */ + u16 *rspq_id; /* response queue id's of rxq */ + u16 nrxq; /* # of ingress uld queues */ + u16 nciq; /* # of completion queues */ + u8 uld; /* uld type */ +}; + struct sge { struct sge_eth_txq ethtxq[MAX_ETH_QSETS]; struct sge_ofld_txq ofldtxq[MAX_OFLD_QSETS]; @@ -690,6 +706,7 @@ struct sge { struct sge_ofld_rxq rdmarxq[MAX_RDMA_QUEUES]; struct sge_ofld_rxq rdmaciq[MAX_RDMA_CIQS]; struct sge_rspq fw_evtq cacheline_aligned_in_smp; + struct sge_uld_rxq_info **uld_rxq_info; struct sge_rspq intrq cacheline_aligned_in_smp; spinlock_t intrq_lock; @@ -701,6 +718,7 @@ struct sge { u16 niscsitq; /* # of available iSCST Rx queues */ u16 rdmaqs; /* # of available RDMA Rx queues */ u16 rdmaciqs; /* # of available RDMA concentrator IQs */ + u16 nqs_per_uld;/* # of Rx queues per ULD */ u16 iscsi_rxq[MAX_OFLD_QSETS]; u16 iscsit_rxq[MAX_ISCSIT_QUEUES]; u16 rdma_rxq[MAX_RDMA_QUEUES]; @@ -756,6 +774,17 @@ struct hash_mac_addr { u8 addr[ETH_ALEN]; }; +struct uld_msix_bmap { + unsigned long *msix_bmap; + unsigned int mapsize; + spinlock_t lock; /* lock for acquiring bitmap */ +}; + +struct uld_msix_info { + unsigned short vec; + char desc[IFNAMSIZ + 10]; +}; + struct adapter { void __iomem *regs; void __iomem *bar2; @@ -778,6 +807,9 @@ struct adapter { unsigned short vec; char desc[IFNAMSIZ + 10]; } msix_info[MAX_INGQ + 1]; + struct uld_msix_info *msix_info_ulds; /* msix info for uld's */ + struct uld_msix_bmap msix_bmap_ulds; /* msix bitma
Re: [Patch-V2 2/3] chcr: Support for Chelsio's Crypto Hardware
On Tue, Jul 19, 2016 at 09:15:22PM -0700, David Miller wrote: > From: Yeshaswi M R Gowda > Date: Mon, 18 Jul 2016 22:42:14 -0700 > > > +config CRYPTO_DEV_CHELSIO > > + tristate "Chelsio Crypto Co-processor Driver" > > + depends on PCI && NETDEVICES && ETHERNET > > + select CRYPTO_SHA1 > > + select CRYPTO_SHA256 > > + select CRYPTO_SHA512 > > + select NET_VENDOR_CHELSIO > > + select CHELSIO_T4 > > The user shouldn't have to know about the technical details about > how this chip is physically implemented. > > It's therefore not reasonable to require an ethernet driver to be > enabled to use the crypto engine. > > Also, selecting Kconfig symbol X does not recursively enable the > "select" statement(s) of symbol X nor does it check symbol X's > dependencies. > > This is really one big huge dependency mess, and I think you have > to split out the core of the T4 driver into a driver subtype > agnostic library or similar to make this work properly. > > Don't just shoehorn this stuff into the ethernet driver. Round > peg, square hole. > Hi David, We looked at the interface exposed by the current Ethernet driver and how other drivers/protocols use that for exchanging control/data with hardware. The cxgb4 driver is more than a Ethernet driver, it also initializes the hardware so that other protocols can use them. We have a terminology called lower level driver(LLD) and Upper level driver(ULD). The lower level driver, which is cxgb4 acts both as Ethernet driver and enables the hardware resources for ULD. The ULD's such as iSCSI/iWARP/Crypto depends on lower level driver for the initializied harware resources before processing the protocol specific part. In v3 series of patch we have introduced common API framework for upper level drivers to use the hardware resources. At present, all resouces are allocated statically, no matter whether ULD is loaded or not. With the new framework, all allocations and initialization for respective ULD's are done, when they register with the LLD and freed when unregistered. The ULD API framework makes the interface flexible and scalable for any new driver which shall run on top of cxgb4. The v3 patch uses the new ULD APIs introduced by cxgb4 only for crypto, and shall be extended further for iSCSI and iWARP in upcoming series. The API also saves new driver(ULD) from exclusively requesting the PCI function and manage the resources associated. Thanks, Hari
[PATCHv5 net-next 1/2] cxgb4: Add control net_device for configuring PCIe VF
Issue: For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtual Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Fix: Since the control node is always the netdevice for all VF ACL commands. Created a dummy netdevice for each Physical Function from 0 to 3 through which one could control their VFs. The device won't be associated with any port, since it doesn't need to transmit/receive. Its purely used for VF management purpose only. The device will be registered only when VF for a particular PF is configured using PCI sysfs interface and unregistered while pci_disable_sriov() for the PF is called. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 121 1 file changed, 103 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49dc963..b7e932ec6894 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3139,6 +3139,24 @@ static const struct net_device_ops cxgb4_netdev_ops = { }; +static const struct net_device_ops cxgb4_mgmt_netdev_ops = { +}; + +static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct adapter *adapter = netdev2adap(dev); + + strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); + strlcpy(info->version, cxgb4_driver_version, + sizeof(info->version)); + strlcpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); +} + +static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = { + .get_drvinfo = get_drvinfo, +}; + void t4_fatal_err(struct adapter *adap) { t4_set_reg_field(adap, SGE_CONTROL_A, GLOBALENABLE_F, 0); @@ -4836,19 +4854,12 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) #ifdef CONFIG_PCI_IOV static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) { + struct adapter *adap = pci_get_drvdata(pdev); int err = 0; int current_vfs = pci_num_vf(pdev); u32 pcie_fw; - void __iomem *regs; - regs = pci_ioremap_bar(pdev, 0); - if (!regs) { - dev_err(&pdev->dev, "cannot map device registers\n"); - return -ENOMEM; - } - - pcie_fw = readl(regs + PCIE_FW_A); - iounmap(regs); + pcie_fw = readl(adap->regs + PCIE_FW_A); /* Check if cxgb4 is the MASTER and fw is initialized */ if (!(pcie_fw & PCIE_FW_INIT_F) || !(pcie_fw & PCIE_FW_MASTER_VLD_F) || @@ -4875,6 +4886,8 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) */ if (!num_vfs) { pci_disable_sriov(pdev); + if (adap->port[0]->reg_state == NETREG_REGISTERED) + unregister_netdev(adap->port[0]); return num_vfs; } @@ -4882,6 +4895,12 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) err = pci_enable_sriov(pdev, num_vfs); if (err) return err; + + if (adap->port[0]->reg_state == NETREG_UNINITIALIZED) { + err = register_netdev(adap->port[0]); + if (err < 0) + pr_info("Unable to register VF mgmt netdev\n"); + } } return num_vfs; } @@ -4893,9 +4912,14 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct port_info *pi; bool highdma = false; struct adapter *adapter = NULL; + struct net_device *netdev; +#ifdef CONFIG_PCI_IOV + char name[IFNAMSIZ]; +
[PATCHv5 net-next 0/2] Add support for IFLA_VF_MAC
Hi, We're struggling to implement the PCI SR-IOV management features for administering Virtual Functions which represent networking devices using the current Linux APIs. The problem is that these APIs incorporate all sorts of assumptions which don't match chelsio networking cards. For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtuali Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Patch 1/2 adds support to create management interface for each PF to control thier corresponding VF's. Patch 2/2 adds support for ndo_set_vf_mac. This patch series has been created against net-next tree. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. V5: Fix warning reported by kbuild bot when CONFIG_PCI_IOV isn't defined. V4: Handle memory allocation failure for adapter->mbox_log in init_one(). Based on review comment by Yuval Mintz V3: Based on review comment by Yuval Mintz, removed extra parameter pf added to IFLA_VF API's and created a net_device corresponding to each PF for controling their VF. Based on review comment by Yuval Mintz V2: Fixed check for MAC address in Patch 2/2, based on review comment by Yuval Mintz Hariprasad Shenai (2): cxgb4: Add control net_device for configuring PCIe VF cxgb4/cxgb4vf: Add set VF mac address support drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 143 ++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 - 6 files changed, 253 insertions(+), 24 deletions(-) -- 2.3.4
[PATCHv5 net-next 2/2] cxgb4/cxgb4vf: Add set VF mac address support
Add ndo_set_vf_mac support which allows to set the MAC address for cxgb4vf interfaces from the host Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 ++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 24 - drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 3 ++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 +++--- 6 files changed, 151 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 2e2aa9fec9bb..bcfa51226b46 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1521,4 +1521,7 @@ void t4_idma_monitor_init(struct adapter *adapter, void t4_idma_monitor(struct adapter *adapter, struct sge_idma_monitor_state *idma, int hz, int ticks); +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + unsigned int naddr, u8 *addr); + #endif /* __CXGB4_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index b7e932ec6894..2bb804c93688 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3078,6 +3078,26 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) return ret; } +#ifdef CONFIG_PCI_IOV +static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + + /* verify MAC addr is valid */ + if (!is_valid_ether_addr(mac)) { + dev_err(pi->adapter->pdev_dev, + "Invalid Ethernet address %pM for VF %d\n", + mac, vf); + return -EINVAL; + } + + dev_info(pi->adapter->pdev_dev, +"Setting MAC %pM on VF %d\n", mac, vf); + return t4_set_vf_mac_acl(adap, vf + 1, 1, mac); +} +#endif + static int cxgb_set_mac_addr(struct net_device *dev, void *p) { int ret; @@ -3136,10 +3156,12 @@ static const struct net_device_ops cxgb4_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll= cxgb_busy_poll, #endif - }; static const struct net_device_ops cxgb4_mgmt_netdev_ops = { +#ifdef CONFIG_PCI_IOV + .ndo_set_vf_mac = cxgb_set_vf_mac, +#endif }; static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index dc92c80a75f4..2a476cc4e073 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8264,3 +8264,44 @@ void t4_idma_monitor(struct adapter *adapter, t4_sge_decode_idma_state(adapter, idma->idma_state[i]); } } + +/** + * t4_set_vf_mac - Set MAC address for the specified VF + * @adapter: The adapter + * @vf: one of the VFs instantiated by the specified PF + * @naddr: the number of MAC addresses + * @addr: the MAC address(es) to be set to the specified VF + */ +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + unsigned int naddr, u8 *addr) +{ + struct fw_acl_mac_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_ACL_MAC_CMD_PFN_V(adapter->pf) | + FW_ACL_MAC_CMD_VFN_V(vf)); + + /* Note: Do not enable the ACL */ + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + cmd.nmac = naddr; + + switch (adapter->pf) { + case 3: + memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); + break; + case 2: + memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2)); + break; + case 1: + memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1)); + break; + case 0: + memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0)); + break; + } + + return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); +} diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index e116bb8d1729..f2951bf68992 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2777,6 +2777,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, struct adapter *adapter;
[PATCHv4 net-next 1/2] cxgb4: Add control net_device for configuring PCIe VF
Issue: For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtual Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Fix: Since the control node is always the netdevice for all VF ACL commands. Created a dummy netdevice for each Physical Function from 0 to 3 through which one could control their VFs. The device won't be associated with any port, since it doesn't need to transmit/receive. Its purely used for VF management purpose only. The device will be registered only when VF for a particular PF is configured using PCI sysfs interface and unregistered while pci_disable_sriov() for the PF is called. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 119 +++ 1 files changed, 101 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49..771e7ad 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3139,6 +3139,24 @@ static const struct net_device_ops cxgb4_netdev_ops = { }; +static const struct net_device_ops cxgb4_mgmt_netdev_ops = { +}; + +static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct adapter *adapter = netdev2adap(dev); + + strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); + strlcpy(info->version, cxgb4_driver_version, + sizeof(info->version)); + strlcpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); +} + +static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = { + .get_drvinfo = get_drvinfo, +}; + void t4_fatal_err(struct adapter *adap) { t4_set_reg_field(adap, SGE_CONTROL_A, GLOBALENABLE_F, 0); @@ -4836,19 +4854,12 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) #ifdef CONFIG_PCI_IOV static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) { + struct adapter *adap = pci_get_drvdata(pdev); int err = 0; int current_vfs = pci_num_vf(pdev); u32 pcie_fw; - void __iomem *regs; - regs = pci_ioremap_bar(pdev, 0); - if (!regs) { - dev_err(&pdev->dev, "cannot map device registers\n"); - return -ENOMEM; - } - - pcie_fw = readl(regs + PCIE_FW_A); - iounmap(regs); + pcie_fw = readl(adap->regs + PCIE_FW_A); /* Check if cxgb4 is the MASTER and fw is initialized */ if (!(pcie_fw & PCIE_FW_INIT_F) || !(pcie_fw & PCIE_FW_MASTER_VLD_F) || @@ -4875,6 +4886,8 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) */ if (!num_vfs) { pci_disable_sriov(pdev); + if (adap->port[0]->reg_state == NETREG_REGISTERED) + unregister_netdev(adap->port[0]); return num_vfs; } @@ -4882,6 +4895,12 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) err = pci_enable_sriov(pdev, num_vfs); if (err) return err; + + if (adap->port[0]->reg_state == NETREG_UNINITIALIZED) { + err = register_netdev(adap->port[0]); + if (err < 0) + pr_info("Unable to register VF mgmt netdev\n"); + } } return num_vfs; } @@ -4893,9 +4912,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct port_info *pi; bool highdma = false; struct adapter *adapter = NULL; + struct net_device *netdev; + char name[IFNAMSIZ]; void __iomem *regs
[PATCHv4 net-next 0/2] Add support for IFLA_VF_MAC
Hi, We're struggling to implement the PCI SR-IOV management features for administering Virtual Functions which represent networking devices using the current Linux APIs. The problem is that these APIs incorporate all sorts of assumptions which don't match chelsio networking cards. For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtuali Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Patch 1/2 adds support to create management interface for each PF to control thier corresponding VF's. Patch 2/2 adds support for ndo_set_vf_mac. This patch series has been created against net-next tree. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. V4: Handle memory allocation failure for adapter->mbox_log in init_one(). Based on review comment by Yuval Mintz V3: Based on review comment by Yuval Mintz, removed extra parameter pf added to IFLA_VF API's and created a net_device corresponding to each PF for controling their VF. Based on review comment by Yuval Mintz V2: Fixed check for MAC address in Patch 2/2, based on review comment by Yuval Mintz Hariprasad Shenai (2): cxgb4: Add control net_device for configuring PCIe VF cxgb4/cxgb4vf: Add set VF mac address support drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 141 +--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 - 6 files changed, 251 insertions(+), 24 deletions(-) -- 1.7.3
[PATCHv4 net-next 2/2] cxgb4/cxgb4vf: Add set VF mac address support
Add ndo_set_vf_mac support which allows to set the MAC address for cxgb4vf interfaces from the host Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 24 +++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 ++-- 6 files changed, 151 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index b4fceb9..7ce076f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1520,4 +1520,7 @@ void t4_idma_monitor_init(struct adapter *adapter, void t4_idma_monitor(struct adapter *adapter, struct sge_idma_monitor_state *idma, int hz, int ticks); +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + unsigned int naddr, u8 *addr); + #endif /* __CXGB4_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 771e7ad..4f196d9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3078,6 +3078,26 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) return ret; } +#ifdef CONFIG_PCI_IOV +static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + + /* verify MAC addr is valid */ + if (!is_valid_ether_addr(mac)) { + dev_err(pi->adapter->pdev_dev, + "Invalid Ethernet address %pM for VF %d\n", + mac, vf); + return -EINVAL; + } + + dev_info(pi->adapter->pdev_dev, +"Setting MAC %pM on VF %d\n", mac, vf); + return t4_set_vf_mac_acl(adap, vf + 1, 1, mac); +} +#endif + static int cxgb_set_mac_addr(struct net_device *dev, void *p) { int ret; @@ -3136,10 +3156,12 @@ static const struct net_device_ops cxgb4_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll= cxgb_busy_poll, #endif - }; static const struct net_device_ops cxgb4_mgmt_netdev_ops = { +#ifdef CONFIG_PCI_IOV + .ndo_set_vf_mac = cxgb_set_vf_mac, +#endif }; static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index a63addb..065affe 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8262,3 +8262,44 @@ void t4_idma_monitor(struct adapter *adapter, t4_sge_decode_idma_state(adapter, idma->idma_state[i]); } } + +/** + * t4_set_vf_mac - Set MAC address for the specified VF + * @adapter: The adapter + * @vf: one of the VFs instantiated by the specified PF + * @naddr: the number of MAC addresses + * @addr: the MAC address(es) to be set to the specified VF + */ +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + unsigned int naddr, u8 *addr) +{ + struct fw_acl_mac_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_ACL_MAC_CMD_PFN_V(adapter->pf) | + FW_ACL_MAC_CMD_VFN_V(vf)); + + /* Note: Do not enable the ACL */ + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + cmd.nmac = naddr; + + switch (adapter->pf) { + case 3: + memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); + break; + case 2: + memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2)); + break; + case 1: + memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1)); + break; + case 0: + memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0)); + break; + } + + return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); +} diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 8d9b2cb..9b42ad0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2695,6 +2695,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, struct adapter *adapter; struct port_info *pi;
[PATCHv3 net-next 2/2] cxgb4/cxgb4vf: Add set VF mac address support
Add ndo_set_vf_mac support which allows to set the MAC address for cxgb4vf interfaces from the host Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 ++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 24 - drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 3 ++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 +++--- 6 files changed, 151 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 2e2aa9fec9bb..bcfa51226b46 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1521,4 +1521,7 @@ void t4_idma_monitor_init(struct adapter *adapter, void t4_idma_monitor(struct adapter *adapter, struct sge_idma_monitor_state *idma, int hz, int ticks); +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + unsigned int naddr, u8 *addr); + #endif /* __CXGB4_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 490388239b7f..a13da5ae98ab 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3078,6 +3078,26 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) return ret; } +#ifdef CONFIG_PCI_IOV +static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + + /* verify MAC addr is valid */ + if (!is_valid_ether_addr(mac)) { + dev_err(pi->adapter->pdev_dev, + "Invalid Ethernet address %pM for VF %d\n", + mac, vf); + return -EINVAL; + } + + dev_info(pi->adapter->pdev_dev, +"Setting MAC %pM on VF %d\n", mac, vf); + return t4_set_vf_mac_acl(adap, vf + 1, 1, mac); +} +#endif + static int cxgb_set_mac_addr(struct net_device *dev, void *p) { int ret; @@ -3136,10 +3156,12 @@ static const struct net_device_ops cxgb4_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll= cxgb_busy_poll, #endif - }; static const struct net_device_ops cxgb4_mgmt_netdev_ops = { +#ifdef CONFIG_PCI_IOV + .ndo_set_vf_mac = cxgb_set_vf_mac, +#endif }; static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index dc92c80a75f4..2a476cc4e073 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8264,3 +8264,44 @@ void t4_idma_monitor(struct adapter *adapter, t4_sge_decode_idma_state(adapter, idma->idma_state[i]); } } + +/** + * t4_set_vf_mac - Set MAC address for the specified VF + * @adapter: The adapter + * @vf: one of the VFs instantiated by the specified PF + * @naddr: the number of MAC addresses + * @addr: the MAC address(es) to be set to the specified VF + */ +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + unsigned int naddr, u8 *addr) +{ + struct fw_acl_mac_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_ACL_MAC_CMD_PFN_V(adapter->pf) | + FW_ACL_MAC_CMD_VFN_V(vf)); + + /* Note: Do not enable the ACL */ + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + cmd.nmac = naddr; + + switch (adapter->pf) { + case 3: + memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); + break; + case 2: + memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2)); + break; + case 1: + memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1)); + break; + case 0: + memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0)); + break; + } + + return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); +} diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index e116bb8d1729..f2951bf68992 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2777,6 +2777,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, struct adapter *adapter;
[PATCHv3 net-next 1/2] cxgb4: Add control net_device for configuring PCIe VF
Issue: For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtual Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Fix: Since the control node is always the netdevice for all VF ACL commands. Created a dummy netdevice for each Physical Function from 0 to 3 through which one could control their VFs. The device won't be associated with any port, since it doesn't need to transmit/receive. Its purely used for VF management purpose only. The device will be registered only when VF for a particular PF is configured using PCI sysfs interface and unregistered while pci_disable_sriov() for the PF is called. The interface will be named "mgmtpf", for example for PF1 of adapter 0 will be named 'mgmtpf01'. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 115 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49dc963..490388239b7f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3139,6 +3139,24 @@ static const struct net_device_ops cxgb4_netdev_ops = { }; +static const struct net_device_ops cxgb4_mgmt_netdev_ops = { +}; + +static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct adapter *adapter = netdev2adap(dev); + + strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); + strlcpy(info->version, cxgb4_driver_version, + sizeof(info->version)); + strlcpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); +} + +static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = { + .get_drvinfo = get_drvinfo, +}; + void t4_fatal_err(struct adapter *adap) { t4_set_reg_field(adap, SGE_CONTROL_A, GLOBALENABLE_F, 0); @@ -4836,19 +4854,12 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) #ifdef CONFIG_PCI_IOV static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) { + struct adapter *adap = pci_get_drvdata(pdev); int err = 0; int current_vfs = pci_num_vf(pdev); u32 pcie_fw; - void __iomem *regs; - regs = pci_ioremap_bar(pdev, 0); - if (!regs) { - dev_err(&pdev->dev, "cannot map device registers\n"); - return -ENOMEM; - } - - pcie_fw = readl(regs + PCIE_FW_A); - iounmap(regs); + pcie_fw = readl(adap->regs + PCIE_FW_A); /* Check if cxgb4 is the MASTER and fw is initialized */ if (!(pcie_fw & PCIE_FW_INIT_F) || !(pcie_fw & PCIE_FW_MASTER_VLD_F) || @@ -4875,6 +4886,8 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) */ if (!num_vfs) { pci_disable_sriov(pdev); + if (adap->port[0]->reg_state == NETREG_REGISTERED) + unregister_netdev(adap->port[0]); return num_vfs; } @@ -4882,6 +4895,12 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) err = pci_enable_sriov(pdev, num_vfs); if (err) return err; + + if (adap->port[0]->reg_state == NETREG_UNINITIALIZED) { + err = register_netdev(adap->port[0]); + if (err < 0) + pr_info("Unable to register VF mgmt netdev\n"); + } } return num_vfs; } @@ -4893,9 +4912,14 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct port_info *pi; bool highdma = false; struct adapter *
[PATCHv3 net-next 0/2] Add support for IFLA_VF_MAC
Hi, We're struggling to implement the PCI SR-IOV management features for administering Virtual Functions which represent networking devices using the current Linux APIs. The problem is that these APIs incorporate all sorts of assumptions which don't match chelsio networking cards. For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtuali Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Patch 1/2 adds support to create management interface for each PF to control thier corresponding VF's when SRIOV VF's are configure via sysyfs. Patch 2/2 adds support for ndo_set_vf_mac. This patch series has been created against net-next tree. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. V3: Based on review comment by Yuval Mintz, removed extra parameter pf added to IFLA_VF API's and created a net_device corresponding to each PF for controling their VF. Based on review comment by Yuval Mintz V2: Fixed check for MAC address in Patch 2/2, based on review comments by Yuval Mintz Hariprasad Shenai (2): cxgb4: Add control net_device for configuring PCIe VF cxgb4/cxgb4vf: Add set VF mac address support drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 137 ++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 +- 6 files changed, 247 insertions(+), 24 deletions(-) -- 2.3.4
[PATCH net] cxgb4/cxgb4vf: Fixes regression in perf when tx vlan offload is disabled
The commit 637d3e997351 ("cxgb4: Discard the packet if the length is greater than mtu") introduced a regression in the VLAN interface performance when Tx VLAN offload is disabled. Check if skb is tagged, regardless of whether it is hardware accelerated or not. Presently we were checking only for hardware acclereated one, which caused performance to drop to ~0.17Mbps on a 10GbE adapter for VLAN interface, when tx vlan offload is turned off using ethtool. The ethernet head length calculation was going wrong in this case, and driver ended up dropping packets. Fixes: 637d3e997351 ("cxgb4: Discard the packet if the length is greater than mtu") Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index bad253beb8c8..ad3552df0545 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -1192,7 +1192,7 @@ out_free: dev_kfree_skb_any(skb); /* Discard the packet if the length is greater than mtu */ max_pkt_len = ETH_HLEN + dev->mtu; - if (skb_vlan_tag_present(skb)) + if (skb_vlan_tagged(skb)) max_pkt_len += VLAN_HLEN; if (!skb_shinfo(skb)->gso_size && (unlikely(skb->len > max_pkt_len))) goto out_free; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 1bb57d3fbbe8..c8fd4f8fe1fa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -1188,7 +1188,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) /* Discard the packet if the length is greater than mtu */ max_pkt_len = ETH_HLEN + dev->mtu; - if (skb_vlan_tag_present(skb)) + if (skb_vlan_tagged(skb)) max_pkt_len += VLAN_HLEN; if (!skb_shinfo(skb)->gso_size && (unlikely(skb->len > max_pkt_len))) goto out_free; -- 2.3.4
Re: [PATCHv2 net-next 1/3] net: Add provision to specify pf number while assigning VF mac
On Fri, Jul 01, 2016 at 04:41:52 +, Yuval Mintz wrote: > > > > Chelsio T4/T5 cards have SR-IOV Capabilities on Physical Functions > > > > 0..3 and the administrative Driver(cxgb4) attaches to Physical Function > > > > 4. > > > > Each of the Physical Functions 0..3 can support up to 16 Virtual > > > > Functions. With the current Linux APIs, a 2-Port card would only be > > > > able to use the Virtual Functions on Physical Functions 0..1 and not > > > > allow the Virtual Functions on Physical Functions 2..3 to be used since > > > > there are no Ports 2..3 on a 2-Port card. > > > > > > > > Also the current ip commands takes netdev as one of the argument, and > > > > it assumes a 1-to-1 mapping of Network Ports, Physical Functions and the > > > > SR-IOV Virtual Functions of those Physical Functions. But it is not > > > > true in our case and won't work for us. > > > > > > > > Added a new argument to specify the PF number associated with the VF, to > > > > fix this. > > > > > > I don't get it - what's the exact definition of 'Physical Function'? > > > Are we talking PCI functions? Logical partitons? Something else? > > > Its PCIe physical function. Physical functions (PFs) are full-featured > > PCIe functions; virtual functions (VFs) are "lightweight" functions that > > lack configuration resource. > > Seems like a bad precedent to me - the control node is always the netdevice. > While I understand your need, looks like what you really want some kind of > a dummy netdevice for the higher PFs through which you could control their > VFs. Hi Dave and all, Based on above comment, since the control node should always be net_device, we will go with the below implementation. We will have dummy net devices with 00:00:00:00:00:00 mac address. The device won't be associated with any port, since it doesn't need to transmit/receive. On a two port adapter, we need to create 4 dummy net devices, corresponding to PF0 ... PF3. Basically the dummy net device will have callback's only for "ndo_set_vf_*" API's. Thanks, Hariprasad Shenai
Re: [PATCHv2 net-next 1/3] net: Add provision to specify pf number while assigning VF mac
On Thu, Jun 30, 2016 at 19:04:16 +, Yuval Mintz wrote: > > Chelsio T4/T5 cards have SR-IOV Capabilities on Physical Functions > > 0..3 and the administrative Driver(cxgb4) attaches to Physical Function 4. > > Each of the Physical Functions 0..3 can support up to 16 Virtual > > Functions. With the current Linux APIs, a 2-Port card would only be > > able to use the Virtual Functions on Physical Functions 0..1 and not > > allow the Virtual Functions on Physical Functions 2..3 to be used since > > there are no Ports 2..3 on a 2-Port card. > > > > Also the current ip commands takes netdev as one of the argument, and > > it assumes a 1-to-1 mapping of Network Ports, Physical Functions and the > > SR-IOV Virtual Functions of those Physical Functions. But it is not > > true in our case and won't work for us. > > > > Added a new argument to specify the PF number associated with the VF, to > > fix this. > > I don't get it - what's the exact definition of 'Physical Function'? > Are we talking PCI functions? Logical partitons? Something else? Its PCIe physical function. Physical functions (PFs) are full-featured PCIe functions; virtual functions (VFs) are “lightweight” functions that lack configuration resource.
Re: [PATCH net-next 2/3] cxgb4/cxgb4vf: Add set VF mac address support
On Thu, Jun 30, 2016 at 13:13:15 +, Yuval Mintz wrote: > > + /* verify MAC addr is valid */ > > + if (!is_zero_ether_addr(mac) && !is_valid_ether_addr(mac) && > > + is_multicast_ether_addr(mac)) { > > This is really odd as verification goes; Currently this is a very elaborate > way of checking for multicast, but I guess it's probably a mistake. > My bad, will send a V2
[PATCHv2 net-next 1/3] net: Add provision to specify pf number while assigning VF mac
Chelsio T4/T5 cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver(cxgb4) attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Functions 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Also the current ip commands takes netdev as one of the argument, and it assumes a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. But it is not true in our case and won't work for us. Added a new argument to specify the PF number associated with the VF, to fix this. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h|2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c |2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c|2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h|2 +- drivers/net/ethernet/cisco/enic/enic_main.c|2 +- drivers/net/ethernet/emulex/benet/be_main.c|2 +- drivers/net/ethernet/intel/fm10k/fm10k.h |3 ++- drivers/net/ethernet/intel/fm10k/fm10k_iov.c |3 ++- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |2 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h |2 +- drivers/net/ethernet/intel/igb/igb_main.c |6 -- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h |3 ++- drivers/net/ethernet/mellanox/mlx4/en_netdev.c |3 ++- drivers/net/ethernet/mellanox/mlx5/core/en_main.c |2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h |2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c |2 +- drivers/net/ethernet/sfc/sriov.c |3 ++- drivers/net/ethernet/sfc/sriov.h |3 ++- include/linux/netdevice.h |2 +- include/uapi/linux/if_link.h |1 + net/core/rtnetlink.c |4 ++-- 22 files changed, 32 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 0e68fad..bc8560b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -491,7 +491,7 @@ int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto, int bnx2x_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi); -int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); +int bnx2x_set_vf_mac(struct net_device *dev, int pf, int queue, u8 *mac); int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); /* select_queue callback */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 632daff..2342daa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -2664,7 +2664,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, * mac configuration request, the PF will simply fail the request and VF can try * again after consulting its bulletin board. */ -int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac) +int bnx2x_set_vf_mac(struct net_device *dev, int pf, int vfidx, u8 *mac) { struct bnx2x *bp = netdev_priv(dev); int rc, q_logical_state; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 50d2007..7d0a318 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -107,7 +107,7 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id, return 0; } -int bnxt_set_vf_mac(struct net_device *dev, int vf_id, u8 *mac) +int bnxt_set_vf_mac(struct net_device *dev, int pf, int vf_id, u8 *mac) { struct hwrm_func_cfg_input req = {0}; struct bnxt *bp = netdev_priv(dev); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h index 0392670..a44e7b2 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h @@ -11,7 +11,7 @@ #define BNXT_SRIOV_H int bnxt_get_vf_config(struct net_device *, int, struct ifla_vf_info *); -int bnxt_set_vf_mac(struct net_device *, int, u8 *); +int bnxt_set_vf_mac(struct net_device *, int, int, u8 *); int bnxt_set_vf_vlan(struct net_device *, int, u16, u8); int bnxt_set_vf_bw(struct net_device *, int, int, int); int bnxt_set_vf_link_state(struct net_device *, int, int); diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_m
[PATCHv2 net-next iproute2 3/3] ip: Add option to specify PF number associated with the VF
Add options to specify PF number associated with the VF for MAC ACL. The current API assumes that there is one to one mapping between Network Ports, Physical Functions and the SR-IOV Virtual Function. But that's not true in the case of Chelsio, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the PF Driver registers ports on PF4. Signed-off-by: Hariprasad Shenai --- include/linux/if_link.h |1 + ip/ipaddress.c |3 +++ ip/iplink.c | 21 ++--- man/man8/ip-link.8.in | 15 +-- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 15bbeb8..793c765 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -631,6 +631,7 @@ enum { #define IFLA_VF_MAX (__IFLA_VF_MAX - 1) struct ifla_vf_mac { + __u32 pf; __u32 vf; __u8 mac[32]; /* MAX_ADDR_LEN */ }; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index df363b0..d67c89b 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -351,6 +351,9 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) fprintf(fp, "%svf %d MAC %s", _SL_, vf_mac->vf, ll_addr_n2a((unsigned char *)&vf_mac->mac, ETH_ALEN, 0, b1, sizeof(b1))); + fprintf(fp, "%spf %d vf %d MAC %s", _SL_, vf_mac->pf, + vf_mac->pf, ll_addr_n2a((unsigned char *)&vf_mac->mac, + ETH_ALEN, 0, b1, sizeof(b1))); if (vf_vlan->vlan) fprintf(fp, ", vlan %d", vf_vlan->vlan); if (vf_vlan->qos) diff --git a/ip/iplink.c b/ip/iplink.c index d2e586b..9c1b625 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -73,7 +73,7 @@ void iplink_usage(void) fprintf(stderr, " [ netns { PID | NAME } ]\n"); fprintf(stderr, " [ link-netnsid ID ]\n"); fprintf(stderr, " [ alias NAME ]\n"); - fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n"); + fprintf(stderr, " [ pf NUM vf NUM [ mac LLADDR ]\n"); fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n"); fprintf(stderr, " [ rate TXRATE ]\n"); @@ -237,7 +237,7 @@ struct iplink_req { charbuf[1024]; }; -static int iplink_parse_vf(int vf, int *argcp, char ***argvp, +static int iplink_parse_vf(int pf, int vf, int *argcp, char ***argvp, struct iplink_req *req, int dev_index) { char new_rate_api = 0, count = 0, override_legacy_rate = 0; @@ -276,6 +276,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, struct ifla_vf_mac ivm; NEXT_ARG(); + ivm.pf = pf; ivm.vf = vf; len = ll_addr_a2n((char *)ivm.mac, 32, *argv); if (len < 0) @@ -423,7 +424,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, int qlen = -1; int mtu = -1; int netns = -1; - int vf = -1; + int pf = -1, vf = -1; int numtxqueues = -1; int numrxqueues = -1; int dev_index = 0; @@ -540,19 +541,25 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, req->i.ifi_flags |= IFF_NOARP; else return on_off("arp", *argv); - } else if (strcmp(*argv, "vf") == 0) { + } else if (strcmp(*argv, "pf") == 0) { struct rtattr *vflist; NEXT_ARG(); - if (get_integer(&vf, *argv, 0)) - invarg("Invalid \"vf\" value\n", *argv); + if (get_integer(&pf, *argv, 0)) + invarg("Invalid \"pf\" value\n", *argv); + NEXT_ARG(); + if (strcmp(*argv, "vf") == 0) { + NEXT_ARG(); + if (get_integer(&vf, *argv, 0)) + invarg("Invalid \"vf\" value\n", *argv); + } vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST); if (dev_index == 0) missarg("dev"); - len = iplink_parse_vf(vf, &argc, &argv, req, dev_index); + len = iplink_parse_vf(pf, vf, &argc, &argv,
[PATCHv2 net-next 2/3] cxgb4/cxgb4vf: Add set VF mac address support
Add ndo_set_vf_mac support which allows to set the MAC address for cxgb4vf interfaces from the host. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 32 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 42 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 ++-- 6 files changed, 160 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index b4fceb9..f38735f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1520,4 +1520,7 @@ void t4_idma_monitor_init(struct adapter *adapter, void t4_idma_monitor(struct adapter *adapter, struct sge_idma_monitor_state *idma, int hz, int ticks); +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int pf, unsigned int vf, + unsigned int naddr, u8 *addr); + #endif /* __CXGB4_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49..da8a444 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3078,6 +3078,34 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) return ret; } +#ifdef CONFIG_PCI_IOV +#define CXGB_PF_WITH_VF 4 + +static int cxgb_set_vf_mac(struct net_device *dev, int pf, int vf, u8 *mac) +{ + struct port_info *pi = netdev_priv(dev); + + /* validate the request */ + if (pf >= CXGB_PF_WITH_VF) { + dev_err(pi->adapter->pdev_dev, + "Invalid PF Identifier %d\n", pf); + return -EINVAL; + } + + /* verify MAC addr is valid */ + if (!is_valid_ether_addr(mac)) { + dev_err(pi->adapter->pdev_dev, + "Invalid Ethernet address %pM for PF %d VF %d\n", + mac, pf, vf); + return -EINVAL; + } + + dev_info(pi->adapter->pdev_dev, +"Setting MAC %pM on PF %d VF %d\n", mac, pf, vf); + return t4_set_vf_mac_acl(pi->adapter, pf, vf + 1, 1, mac); +} +#endif + static int cxgb_set_mac_addr(struct net_device *dev, void *p) { int ret; @@ -3136,7 +3164,9 @@ static const struct net_device_ops cxgb4_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll= cxgb_busy_poll, #endif - +#ifdef CONFIG_PCI_IOV + .ndo_set_vf_mac = cxgb_set_vf_mac, +#endif }; void t4_fatal_err(struct adapter *adap) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index a63addb..a92e74a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8262,3 +8262,45 @@ void t4_idma_monitor(struct adapter *adapter, t4_sge_decode_idma_state(adapter, idma->idma_state[i]); } } + +/** + * t4_set_vf_mac - Set MAC address for the specified VF + * @adapter: The adapter + * @pf: the PF + * @vf: one of the VFs instantiated by the specified PF + * @naddr: the number of MAC addresses + * @addr: the MAC address(es) to be set to the specified VF + */ +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int pf, unsigned int vf, + unsigned int naddr, u8 *addr) +{ + struct fw_acl_mac_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_ACL_MAC_CMD_PFN_V(pf) | + FW_ACL_MAC_CMD_VFN_V(vf)); + + /* Note: Do not enable the ACL */ + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + cmd.nmac = naddr; + + switch (pf) { + case 3: + memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); + break; + case 2: + memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2)); + break; + case 1: + memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1)); + break; + case 0: + memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0)); + break; + } + + return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); +} diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 8d9b2cb..eadf9b1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/
[PATCHv2 net-next 0/3] Add option to specify PF parameter for IFLA_VF_MAC
Hi, We're struggling to implement the PCI SR-IOV management features for administering Virtual Functions which represent networking devices using the current Linux APIs. The problem is that these APIs incorporate all sorts of assumptions which don't match chelsio networking cards. For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtuali Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. To start with we have just modified the code to add support for ndo_set_vf_mac to work with chelsio adapter. And once this gets merged, will submit patches for reset of the IFLA_VF API's. This patch 1/3 and 2/3 has been created against net-next tree, and patch 3/3 has been created against iproute2 tree. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks V2: Fixed check for MAC address in Patch 2/3, based on review comments by Yuval Mintz Hariprasad Shenai (2): net: Add provision to specify pf number while assigning VF mac cxgb4/cxgb4vf: Add set VF mac address support drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h|2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c |2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c|2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h|2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 32 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 42 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 ++-- drivers/net/ethernet/cisco/enic/enic_main.c|2 +- drivers/net/ethernet/emulex/benet/be_main.c|2 +- drivers/net/ethernet/intel/fm10k/fm10k.h |3 +- drivers/net/ethernet/intel/fm10k/fm10k_iov.c |3 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |2 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h |2 +- drivers/net/ethernet/intel/igb/igb_main.c |6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h |3 +- drivers/net/ethernet/mellanox/mlx4/en_netdev.c |3 +- drivers/net/ethernet/mellanox/mlx5/core/en_main.c |2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h |2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c |2 +- drivers/net/ethernet/sfc/sriov.c |3 +- drivers/net/ethernet/sfc/sriov.h |3 +- include/linux/netdevice.h |2 +- include/uapi/linux/if_link.h |1 + net/core/rtnetlink.c |4 +- 28 files changed, 192 insertions(+), 30 deletions(-) Hariprasad Shenai (1): ip: Add option to specify PF number associated with the VF include/linux/if_link.h |1 + ip/ipaddress.c |3 +++ ip/iplink.c | 21 ++--- man/man8/ip-link.8.in | 15 +-- 4 files changed, 31 insertions(+), 9 deletions(-) -- 1.7.3
[PATCH net-next 0/3] Add option to specify PF parameter for IFLA_VF_MAC
Hi, We're struggling to implement the PCI SR-IOV management features for administering Virtual Functions which represent networking devices using the current Linux APIs. The problem is that these APIs incorporate all sorts of assumptions which don't match chelsio networking cards. For instance, the current APIs assume a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. This is not the case with our cards where any Virtual Function can be hooked up to any Port -- or any number of Ports the current Linux APIs also assume only 1 Network Interface/Port can be accessed per Virtuali Function. Another issue is that these APIs assume that the Administrative Driver is attached to the Physical Function Associated with a Virtual Function. This is not the case with our card where all administration is performed by a Driver which is not attached to any of the Physical Functions which have SR-IOV PCI Capabilities. Another consequence of these assumptions is the inability to utilize all of the cards SR-IOV resources. For instance, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Function 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. To start with we have just modified the code to add support for ndo_set_vf_mac to work with chelsio adapter. And once this gets merged, will submit patches for reset of the IFLA_VF API's. This patch 1/3 and 2/3 has been created against net-next tree, and patch 3/3 has been created against iproute2 tree. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (2): net: Add provision to specify pf number while assigning VF mac cxgb4/cxgb4vf: Add set VF mac address support drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h|2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c |2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c|2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h|2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 33 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 42 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 ++-- drivers/net/ethernet/cisco/enic/enic_main.c|2 +- drivers/net/ethernet/emulex/benet/be_main.c|2 +- drivers/net/ethernet/intel/fm10k/fm10k.h |3 +- drivers/net/ethernet/intel/fm10k/fm10k_iov.c |3 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |2 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h |2 +- drivers/net/ethernet/intel/igb/igb_main.c |6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h |3 +- drivers/net/ethernet/mellanox/mlx4/en_netdev.c |3 +- drivers/net/ethernet/mellanox/mlx5/core/en_main.c |2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h |2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c |2 +- drivers/net/ethernet/sfc/sriov.c |3 +- drivers/net/ethernet/sfc/sriov.h |3 +- include/linux/netdevice.h |2 +- include/uapi/linux/if_link.h |1 + net/core/rtnetlink.c |4 +- 28 files changed, 193 insertions(+), 30 deletions(-) Hariprasad Shenai (1): ip: Add option to specify PF number associated with the VF include/linux/if_link.h |1 + ip/ipaddress.c |3 +++ ip/iplink.c | 21 ++--- man/man8/ip-link.8.in | 15 +-- 4 files changed, 31 insertions(+), 9 deletions(-) -- 1.7.3
[PATCH net-next 1/3] net: Add provision to specify pf number while assigning VF mac
Chelsio T4/T5 cards have SR-IOV Capabilities on Physical Functions 0..3 and the administrative Driver(cxgb4) attaches to Physical Function 4. Each of the Physical Functions 0..3 can support up to 16 Virtual Functions. With the current Linux APIs, a 2-Port card would only be able to use the Virtual Functions on Physical Functions 0..1 and not allow the Virtual Functions on Physical Functions 2..3 to be used since there are no Ports 2..3 on a 2-Port card. Also the current ip commands takes netdev as one of the argument, and it assumes a 1-to-1 mapping of Network Ports, Physical Functions and the SR-IOV Virtual Functions of those Physical Functions. But it is not true in our case and won't work for us. Added a new argument to specify the PF number associated with the VF, to fix this. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h|2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c |2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c|2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h|2 +- drivers/net/ethernet/cisco/enic/enic_main.c|2 +- drivers/net/ethernet/emulex/benet/be_main.c|2 +- drivers/net/ethernet/intel/fm10k/fm10k.h |3 ++- drivers/net/ethernet/intel/fm10k/fm10k_iov.c |3 ++- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |2 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h |2 +- drivers/net/ethernet/intel/igb/igb_main.c |6 -- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h |3 ++- drivers/net/ethernet/mellanox/mlx4/en_netdev.c |3 ++- drivers/net/ethernet/mellanox/mlx5/core/en_main.c |2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h |2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c |2 +- drivers/net/ethernet/sfc/sriov.c |3 ++- drivers/net/ethernet/sfc/sriov.h |3 ++- include/linux/netdevice.h |2 +- include/uapi/linux/if_link.h |1 + net/core/rtnetlink.c |4 ++-- 22 files changed, 32 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 0e68fad..bc8560b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -491,7 +491,7 @@ int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto, int bnx2x_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi); -int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); +int bnx2x_set_vf_mac(struct net_device *dev, int pf, int queue, u8 *mac); int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); /* select_queue callback */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 632daff..2342daa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -2664,7 +2664,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, * mac configuration request, the PF will simply fail the request and VF can try * again after consulting its bulletin board. */ -int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac) +int bnx2x_set_vf_mac(struct net_device *dev, int pf, int vfidx, u8 *mac) { struct bnx2x *bp = netdev_priv(dev); int rc, q_logical_state; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 50d2007..7d0a318 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -107,7 +107,7 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id, return 0; } -int bnxt_set_vf_mac(struct net_device *dev, int vf_id, u8 *mac) +int bnxt_set_vf_mac(struct net_device *dev, int pf, int vf_id, u8 *mac) { struct hwrm_func_cfg_input req = {0}; struct bnxt *bp = netdev_priv(dev); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h index 0392670..a44e7b2 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h @@ -11,7 +11,7 @@ #define BNXT_SRIOV_H int bnxt_get_vf_config(struct net_device *, int, struct ifla_vf_info *); -int bnxt_set_vf_mac(struct net_device *, int, u8 *); +int bnxt_set_vf_mac(struct net_device *, int, int, u8 *); int bnxt_set_vf_vlan(struct net_device *, int, u16, u8); int bnxt_set_vf_bw(struct net_device *, int, int, int); int bnxt_set_vf_link_state(struct net_device *, int, int); diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_m
[PATCH net-next 2/3] cxgb4/cxgb4vf: Add set VF mac address support
Add ndo_set_vf_mac support which allows to set the MAC address for cxgb4vf interfaces from the host. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |3 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 33 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 42 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 24 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |3 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 63 ++-- 6 files changed, 161 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index b4fceb9..f38735f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1520,4 +1520,7 @@ void t4_idma_monitor_init(struct adapter *adapter, void t4_idma_monitor(struct adapter *adapter, struct sge_idma_monitor_state *idma, int hz, int ticks); +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int pf, unsigned int vf, + unsigned int naddr, u8 *addr); + #endif /* __CXGB4_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49..d719c75 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3078,6 +3078,35 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) return ret; } +#ifdef CONFIG_PCI_IOV +#define CXGB_PF_WITH_VF 4 + +static int cxgb_set_vf_mac(struct net_device *dev, int pf, int vf, u8 *mac) +{ + struct port_info *pi = netdev_priv(dev); + + /* validate the request */ + if (pf >= CXGB_PF_WITH_VF) { + dev_err(pi->adapter->pdev_dev, + "Invalid PF Identifier %d\n", pf); + return -EINVAL; + } + + /* verify MAC addr is valid */ + if (!is_zero_ether_addr(mac) && !is_valid_ether_addr(mac) && + is_multicast_ether_addr(mac)) { + dev_err(pi->adapter->pdev_dev, + "Invalid Ethernet address %pM for PF %d VF %d\n", + mac, pf, vf); + return -EINVAL; + } + + dev_info(pi->adapter->pdev_dev, +"Setting MAC %pM on PF %d VF %d\n", mac, pf, vf); + return t4_set_vf_mac_acl(pi->adapter, pf, vf + 1, 1, mac); +} +#endif + static int cxgb_set_mac_addr(struct net_device *dev, void *p) { int ret; @@ -3136,7 +3165,9 @@ static const struct net_device_ops cxgb4_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll= cxgb_busy_poll, #endif - +#ifdef CONFIG_PCI_IOV + .ndo_set_vf_mac = cxgb_set_vf_mac, +#endif }; void t4_fatal_err(struct adapter *adap) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index a63addb..a92e74a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8262,3 +8262,45 @@ void t4_idma_monitor(struct adapter *adapter, t4_sge_decode_idma_state(adapter, idma->idma_state[i]); } } + +/** + * t4_set_vf_mac - Set MAC address for the specified VF + * @adapter: The adapter + * @pf: the PF + * @vf: one of the VFs instantiated by the specified PF + * @naddr: the number of MAC addresses + * @addr: the MAC address(es) to be set to the specified VF + */ +int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int pf, unsigned int vf, + unsigned int naddr, u8 *addr) +{ + struct fw_acl_mac_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_ACL_MAC_CMD_PFN_V(pf) | + FW_ACL_MAC_CMD_VFN_V(vf)); + + /* Note: Do not enable the ACL */ + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + cmd.nmac = naddr; + + switch (pf) { + case 3: + memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); + break; + case 2: + memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2)); + break; + case 1: + memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1)); + break; + case 0: + memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0)); + break; + } + + return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); +} diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 8d9b2cb..ea
[PATCH net-next iproute2 3/3] ip: Add option to specify PF number associated with the VF
Add options to specify PF number associated with the VF for MAC ACL. The current API assumes that there is one to one mapping between Network Ports, Physical Functions and the SR-IOV Virtual Function. But that's not true in the case of Chelsio, our cards have SR-IOV Capabilities on Physical Functions 0..3 and the PF Driver registers ports on PF4. Signed-off-by: Hariprasad Shenai --- include/linux/if_link.h |1 + ip/ipaddress.c |3 +++ ip/iplink.c | 21 ++--- man/man8/ip-link.8.in | 15 +-- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 15bbeb8..793c765 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -631,6 +631,7 @@ enum { #define IFLA_VF_MAX (__IFLA_VF_MAX - 1) struct ifla_vf_mac { + __u32 pf; __u32 vf; __u8 mac[32]; /* MAX_ADDR_LEN */ }; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index df363b0..d67c89b 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -351,6 +351,9 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) fprintf(fp, "%svf %d MAC %s", _SL_, vf_mac->vf, ll_addr_n2a((unsigned char *)&vf_mac->mac, ETH_ALEN, 0, b1, sizeof(b1))); + fprintf(fp, "%spf %d vf %d MAC %s", _SL_, vf_mac->pf, + vf_mac->pf, ll_addr_n2a((unsigned char *)&vf_mac->mac, + ETH_ALEN, 0, b1, sizeof(b1))); if (vf_vlan->vlan) fprintf(fp, ", vlan %d", vf_vlan->vlan); if (vf_vlan->qos) diff --git a/ip/iplink.c b/ip/iplink.c index d2e586b..9c1b625 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -73,7 +73,7 @@ void iplink_usage(void) fprintf(stderr, " [ netns { PID | NAME } ]\n"); fprintf(stderr, " [ link-netnsid ID ]\n"); fprintf(stderr, " [ alias NAME ]\n"); - fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n"); + fprintf(stderr, " [ pf NUM vf NUM [ mac LLADDR ]\n"); fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n"); fprintf(stderr, " [ rate TXRATE ]\n"); @@ -237,7 +237,7 @@ struct iplink_req { charbuf[1024]; }; -static int iplink_parse_vf(int vf, int *argcp, char ***argvp, +static int iplink_parse_vf(int pf, int vf, int *argcp, char ***argvp, struct iplink_req *req, int dev_index) { char new_rate_api = 0, count = 0, override_legacy_rate = 0; @@ -276,6 +276,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, struct ifla_vf_mac ivm; NEXT_ARG(); + ivm.pf = pf; ivm.vf = vf; len = ll_addr_a2n((char *)ivm.mac, 32, *argv); if (len < 0) @@ -423,7 +424,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, int qlen = -1; int mtu = -1; int netns = -1; - int vf = -1; + int pf = -1, vf = -1; int numtxqueues = -1; int numrxqueues = -1; int dev_index = 0; @@ -540,19 +541,25 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, req->i.ifi_flags |= IFF_NOARP; else return on_off("arp", *argv); - } else if (strcmp(*argv, "vf") == 0) { + } else if (strcmp(*argv, "pf") == 0) { struct rtattr *vflist; NEXT_ARG(); - if (get_integer(&vf, *argv, 0)) - invarg("Invalid \"vf\" value\n", *argv); + if (get_integer(&pf, *argv, 0)) + invarg("Invalid \"pf\" value\n", *argv); + NEXT_ARG(); + if (strcmp(*argv, "vf") == 0) { + NEXT_ARG(); + if (get_integer(&vf, *argv, 0)) + invarg("Invalid \"vf\" value\n", *argv); + } vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST); if (dev_index == 0) missarg("dev"); - len = iplink_parse_vf(vf, &argc, &argv, req, dev_index); + len = iplink_parse_vf(pf, vf, &argc, &argv,
[PATCH net-next] cxgb4: Introduce API for sending work requests on ctrl queue via copy
If the ctrl queue is full, just follows current path by allocating an skb. If that fails then caller will just have to handle that case as before. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 10 +-- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 2 + drivers/net/ethernet/chelsio/cxgb4/l2t.c| 11 +-- drivers/net/ethernet/chelsio/cxgb4/sge.c| 108 5 files changed, 118 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index b4fceb92479f..08e0c639cf90 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1166,6 +1166,7 @@ netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev); int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, const struct pkt_gl *gl); int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb); +int t4_mgmt_tx_direct(struct adapter *adap, const void *src, unsigned int len); int t4_ofld_send(struct adapter *adap, struct sk_buff *skb); int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, struct net_device *dev, int intr_idx, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49dc963..cac8ef209f68 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1696,8 +1696,8 @@ static void process_tid_release_list(struct work_struct *work) */ void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid) { - struct sk_buff *skb; struct adapter *adap = container_of(t, struct adapter, tids); + struct cpl_tid_release sreq, *req = &sreq; WARN_ON(tid >= t->ntids); @@ -1709,11 +1709,9 @@ void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid) atomic_dec(&t->tids_in_use); } - skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); - if (likely(skb)) { - mk_tid_release(skb, chan, tid); - t4_ofld_send(adap, skb); - } else + INIT_TP_WR_CPL(req, CPL_TID_RELEASE, tid); + req->rsvd = 0; + if (cxgb4_ctrl_send(adap->port[chan], req, sizeof(*req))) cxgb4_queue_tid_release(t, chan, tid); } EXPORT_SYMBOL(cxgb4_remove_tid); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index f3c58aaa932d..128efc914317 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h @@ -299,6 +299,8 @@ struct cxgb4_uld_info { int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p); int cxgb4_unregister_uld(enum cxgb4_uld type); int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb); +int cxgb4_ctrl_send(struct net_device *dev, const void *src, + unsigned int len); unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo); unsigned int cxgb4_port_chan(const struct net_device *dev); unsigned int cxgb4_port_viid(const struct net_device *dev); diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c index 60a26037a1c6..e5a67cfca5bb 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c @@ -139,14 +139,8 @@ static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync) { struct l2t_data *d = adap->l2t; unsigned int l2t_idx = e->idx + d->l2t_start; - struct sk_buff *skb; - struct cpl_l2t_write_req *req; - - skb = alloc_skb(sizeof(*req), GFP_ATOMIC); - if (!skb) - return -ENOMEM; + struct cpl_l2t_write_req sreq, *req = &sreq; - req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); INIT_TP_WR(req, 0); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, @@ -159,7 +153,8 @@ static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync) memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac)); memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac)); - t4_mgmt_tx(adap, skb); + if (t4_mgmt_tx_direct(adap, req, sizeof(*req))) + return -ENOMEM; if (sync && e->state != L2T_STATE_SWITCHING) e->state = L2T_STATE_SYNC_WRITE; diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index bad253beb8c8..8e0562f52b91 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -1056,6 +1056,30 @@ static void *inline_tx_skb_header(const struct sk_buff *skb
[PATCH net-next] cxgb4vf: Synchronize access to mailbox
The issue comes when there are multiple threads attempting to use the mailbox facility at the same time. The issue is the for the Virtual Function Driver, the only way to get the Virtual Interface statistics is to issue mailbox commands to ask the firmware for the VI Stats. And, because the VI Stats command can only retrieve a smallish number of stats per mailbox command, we have to issue three mailbox commands in quick succession. When ethtool or netstat command to get interface stats and interface up/down is run in a loop for every 0.1 sec, we observed mailbox collisions. And out of the two commands one would fail with the present code, since we don't queue the second command. To overcome the above issue, added a queue to access the mailbox. Whenever a mailbox command is issued add it to the queue. If its at the head issue the mailbox command, else wait for the existing command to complete. Usually command takes less than a milli-second to complete. Also timeout from the loop, if the command under execution takes long time to run. In reality, the number of mailbox access collisions is going to be very rare since no one runs such abusive script. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 8 .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 2 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 55 ++ 3 files changed, 65 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index 734dd776c22f..109bc630408b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h @@ -353,6 +353,10 @@ struct hash_mac_addr { u8 addr[ETH_ALEN]; }; +struct mbox_list { + struct list_head list; +}; + /* * Per-"adapter" (Virtual Function) information. */ @@ -387,6 +391,10 @@ struct adapter { /* various locks */ spinlock_t stats_lock; + /* lock for mailbox cmd list */ + spinlock_t mbox_lock; + struct mbox_list mlist; + /* support for mailbox command/reply logging */ #define T4VF_OS_LOG_MBOX_CMDS 256 struct mbox_cmd_log *mbox_log; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 8d9b2cb74aa2..9f5526478d2f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2774,6 +2774,8 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, * Initialize SMP data synchronization resources. */ spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->mbox_lock); + INIT_LIST_HEAD(&adapter->mlist.list); /* * Map our I/O registers in BAR0. diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 955ff7c61f1b..61bfe86da86d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -139,6 +139,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL; u32 cmd_op = FW_CMD_OP_G(be32_to_cpu(((struct fw_cmd_hdr *)cmd)->hi)); __be64 cmd_rpl[MBOX_LEN / 8]; + struct mbox_list entry; /* In T6, mailbox size is changed to 128 bytes to avoid * invalidating the entire prefetch buffer. @@ -156,6 +157,51 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4) return -EINVAL; + /* Queue ourselves onto the mailbox access list. When our entry is at +* the front of the list, we have rights to access the mailbox. So we +* wait [for a while] till we're at the front [or bail out with an +* EBUSY] ... +*/ + spin_lock(&adapter->mbox_lock); + list_add_tail(&entry.list, &adapter->mlist.list); + spin_unlock(&adapter->mbox_lock); + + delay_idx = 0; + ms = delay[0]; + + for (i = 0; ; i += ms) { + /* If we've waited too long, return a busy indication. This +* really ought to be based on our initial position in the +* mailbox access list but this is a start. We very rearely +* contend on access to the mailbox ... +*/ + if (i > FW_CMD_MAX_TIMEOUT) { + spin_lock(&adapter->mbox_lock); + list_del(&entry.list); + spin_unlock(&adapter->mbox_lock); + ret = -EBUSY; + t4vf_record_mbox(adapter, cmd, size, access, ret); + return ret; + } + +
[PATCH net-next 2/3] cxgb4: Enable SR-IOV configuration via PCI sysfs interface
Implement callback in the driver for the new PCI bus driver interface that allows the user to enable/disable SR-IOV virtual functions in a device via the sysfs interface. Deprecate module parameter used to configure SRIOV Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 66 - 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c045f65d4106..6ce4344ea6fb 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -207,7 +207,7 @@ static int rx_dma_offset = 2; static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV]; module_param_array(num_vf, uint, NULL, 0644); -MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3"); +MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3, deprecated parameter - please use the pci sysfs interface."); #endif /* TX Queue select used to determine what algorithm to use for selecting TX @@ -4836,6 +4836,60 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) return -EINVAL; } +#ifdef CONFIG_PCI_IOV +static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) +{ + int err = 0; + int current_vfs = pci_num_vf(pdev); + u32 pcie_fw; + void __iomem *regs; + + regs = pci_ioremap_bar(pdev, 0); + if (!regs) { + dev_err(&pdev->dev, "cannot map device registers\n"); + return -ENOMEM; + } + + pcie_fw = readl(regs + PCIE_FW_A); + iounmap(regs); + /* Check if cxgb4 is the MASTER and fw is initialized */ + if (!(pcie_fw & PCIE_FW_INIT_F) || + !(pcie_fw & PCIE_FW_MASTER_VLD_F) || + PCIE_FW_MASTER_G(pcie_fw) != 4) { + dev_warn(&pdev->dev, +"cxgb4 driver needs to be MASTER to support SRIOV\n"); + return -EOPNOTSUPP; + } + + /* If any of the VF's is already assigned to Guest OS, then +* SRIOV for the same cannot be modified +*/ + if (current_vfs && pci_vfs_assigned(pdev)) { + dev_err(&pdev->dev, + "Cannot modify SR-IOV while VFs are assigned\n"); + num_vfs = current_vfs; + return num_vfs; + } + + /* Disable SRIOV when zero is passed. +* One needs to disable SRIOV before modifying it, else +* stack throws the below warning: +* " 'n' VFs already enabled. Disable before enabling 'm' VFs." +*/ + if (!num_vfs) { + pci_disable_sriov(pdev); + return num_vfs; + } + + if (num_vfs != current_vfs) { + err = pci_enable_sriov(pdev, num_vfs); + if (err) + return err; + } + return num_vfs; +} +#endif + static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int func, i, err, s_qpp, qpp, num_seg; @@ -5169,11 +5223,16 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) sriov: #ifdef CONFIG_PCI_IOV - if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) + if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) { + dev_warn(&pdev->dev, +"Enabling SR-IOV VFs using the num_vf module " +"parameter is deprecated - please use the pci sysfs " +"interface instead.\n"); if (pci_enable_sriov(pdev, num_vf[func]) == 0) dev_info(&pdev->dev, "instantiated %u virtual functions\n", num_vf[func]); + } #endif return 0; @@ -5266,6 +5325,9 @@ static struct pci_driver cxgb4_driver = { .probe= init_one, .remove = remove_one, .shutdown = remove_one, +#ifdef CONFIG_PCI_IOV + .sriov_configure = cxgb4_iov_configure, +#endif .err_handler = &cxgb4_eeh, }; -- 2.3.4
[PATCH net-next 1/3] cxgb4: Force cxgb4 driver as MASTER in kdump kernel
When is_kdump_kernel() is true, Forcing cxgb4 driver as Master so we can reinitialize the Firmware/Chip. Also reduce memory usage by disabling offload. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 477db477b133..c045f65d4106 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -64,6 +64,7 @@ #include #include #include +#include #include "cxgb4.h" #include "t4_regs.h" @@ -3735,7 +3736,8 @@ static int adap_init0(struct adapter *adap) return ret; /* Contact FW, advertising Master capability */ - ret = t4_fw_hello(adap, adap->mbox, adap->mbox, MASTER_MAY, &state); + ret = t4_fw_hello(adap, adap->mbox, adap->mbox, + is_kdump_kernel() ? MASTER_MUST : MASTER_MAY, &state); if (ret < 0) { dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", ret); @@ -4366,6 +4368,11 @@ static void cfg_queues(struct adapter *adap) if (q10g > netif_get_num_default_rss_queues()) q10g = netif_get_num_default_rss_queues(); + /* Reduce memory usage in kdump environment, disable all offload. +*/ + if (is_kdump_kernel()) + adap->params.offload = 0; + for_each_port(adap, i) { struct port_info *pi = adap2pinfo(adap, i); -- 2.3.4
[PATCH net-next 0/3] Add SRIOV configuration via sysfs and few fixes
Hi, This series adds support to configure SR-IOV via PCI sysfs interface, reduces resource allocation in kdump kernel by disabling offload. Also synchronize unicast and multicast mac address, even in the interface is in Promiscuous mode. This patch series has been created against net-next tree and includes patches on cxgb4 and cxgb4vf driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (3): cxgb4: Force cxgb4 driver as MASTER in kdump kernel cxgb4: Enable SR-IOV configuration via PCI sysfs interface cxgb4/cxgb4vf: Synchronize all MAC addresses drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 82 +++--- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 8 +-- 2 files changed, 76 insertions(+), 14 deletions(-) -- 2.3.4
[PATCH net-next 3/3] cxgb4/cxgb4vf: Synchronize all MAC addresses
Even if interface is in Promiscuous mode/Allmulti mode synchronize MAC addresses. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 7 ++- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 8 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 6ce4344ea6fb..c45de49dc963 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -461,11 +461,8 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - if (!(dev->flags & IFF_PROMISC)) { - __dev_uc_sync(dev, cxgb4_mac_sync, cxgb4_mac_unsync); - if (!(dev->flags & IFF_ALLMULTI)) - __dev_mc_sync(dev, cxgb4_mac_sync, cxgb4_mac_unsync); - } + __dev_uc_sync(dev, cxgb4_mac_sync, cxgb4_mac_unsync); + __dev_mc_sync(dev, cxgb4_mac_sync, cxgb4_mac_unsync); return t4_set_rxmode(adapter, adapter->mbox, pi->viid, mtu, (dev->flags & IFF_PROMISC) ? 1 : 0, diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 04fc6f6d1e25..8d9b2cb74aa2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -937,12 +937,8 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) { struct port_info *pi = netdev_priv(dev); - if (!(dev->flags & IFF_PROMISC)) { - __dev_uc_sync(dev, cxgb4vf_mac_sync, cxgb4vf_mac_unsync); - if (!(dev->flags & IFF_ALLMULTI)) - __dev_mc_sync(dev, cxgb4vf_mac_sync, - cxgb4vf_mac_unsync); - } + __dev_uc_sync(dev, cxgb4vf_mac_sync, cxgb4vf_mac_unsync); + __dev_mc_sync(dev, cxgb4vf_mac_sync, cxgb4vf_mac_unsync); return t4vf_set_rxmode(pi->adapter, pi->viid, -1, (dev->flags & IFF_PROMISC) != 0, (dev->flags & IFF_ALLMULTI) != 0, -- 2.3.4
[PATCH net-next] net: Reduce queue allocation to one in kdump kernel
When in kdump kernel, reduce memory usage by only using a single Queue Set for multiqueue devices. So make netif_get_num_default_rss_queues() return one, when in kdump kernel. Signed-off-by: Hariprasad Shenai --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 904ff431d570..161c4627a798 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -139,6 +139,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -2249,7 +2250,8 @@ EXPORT_SYMBOL(netif_set_real_num_rx_queues); */ int netif_get_num_default_rss_queues(void) { - return min_t(int, DEFAULT_MAX_NUM_RSS_QUEUES, num_online_cpus()); + return is_kdump_kernel() ? + 1 : min_t(int, DEFAULT_MAX_NUM_RSS_QUEUES, num_online_cpus()); } EXPORT_SYMBOL(netif_get_num_default_rss_queues); -- 2.3.4
[PATCH net] cxgb4: Add device id of T540-BT adapter
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h | 1 + 1 file changed, 1 insertion(+) 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 a2cdfc1261dc..50812a1d67bd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -144,6 +144,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x5015), /* T502-bt */ CH_PCI_ID_TABLE_FENTRY(0x5016), /* T580-OCP-SO */ CH_PCI_ID_TABLE_FENTRY(0x5017), /* T520-OCP-SO */ + CH_PCI_ID_TABLE_FENTRY(0x5018), /* T540-BT */ CH_PCI_ID_TABLE_FENTRY(0x5080), /* Custom T540-cr */ CH_PCI_ID_TABLE_FENTRY(0x5081), /* Custom T540-LL-cr */ CH_PCI_ID_TABLE_FENTRY(0x5082), /* Custom T504-cr */ -- 2.3.4
[PATCH net-next] cxgb4: Reduce resource allocation in kdump kernel
When is_kdump_kernel() is true, reduce our memory footprint by only using a single "Queue Set" and Forcing Master so we can reinitialize the Firmware/Chip. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 477db477b133..5317187d0073 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -64,6 +64,7 @@ #include #include #include +#include #include "cxgb4.h" #include "t4_regs.h" @@ -3735,7 +3736,8 @@ static int adap_init0(struct adapter *adap) return ret; /* Contact FW, advertising Master capability */ - ret = t4_fw_hello(adap, adap->mbox, adap->mbox, MASTER_MAY, &state); + ret = t4_fw_hello(adap, adap->mbox, adap->mbox, + is_kdump_kernel() ? MASTER_MUST : MASTER_MAY, &state); if (ret < 0) { dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", ret); @@ -4366,6 +4368,14 @@ static void cfg_queues(struct adapter *adap) if (q10g > netif_get_num_default_rss_queues()) q10g = netif_get_num_default_rss_queues(); + /* Reduce memory usage in kdump environment by using only one queue +* and disable all offload. +*/ + if (is_kdump_kernel()) { + q10g = 1; + adap->params.offload = 0; + } + for_each_port(adap, i) { struct port_info *pi = adap2pinfo(adap, i); -- 2.3.4
[PATCH net-next] cxgb4: Reset dcb state machine and tx queue prio only if dcb is enabled
When cxgb4 is enabled with CONFIG_CHELSIO_T4_DCB set, VI enable command gets called with DCB enabled. But when we have a back to back setup with DCB enabled on one side and non-DCB on the Peer side. Firmware doesn't send any DCB_L2_CFG, and DCB priority is never set for Tx queue. But driver resets the queue priority and state machine whenever there is a link down, this patch fixes it by adding a check to reset only if cxgb4_dcb_enabled() returns true. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 38 + 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index d7f40436f319..477db477b133 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -304,6 +304,22 @@ static void dcb_tx_queue_prio_enable(struct net_device *dev, int enable) } #endif /* CONFIG_CHELSIO_T4_DCB */ +int cxgb4_dcb_enabled(const struct net_device *dev) +{ +#ifdef CONFIG_CHELSIO_T4_DCB + struct port_info *pi = netdev_priv(dev); + + if (!pi->dcb.enabled) + return 0; + + return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) || + (pi->dcb.state == CXGB4_DCB_STATE_HOST)); +#else + return 0; +#endif +} +EXPORT_SYMBOL(cxgb4_dcb_enabled); + void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat) { struct net_device *dev = adapter->port[port_id]; @@ -314,8 +330,10 @@ void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat) netif_carrier_on(dev); else { #ifdef CONFIG_CHELSIO_T4_DCB - cxgb4_dcb_state_init(dev); - dcb_tx_queue_prio_enable(dev, false); + if (cxgb4_dcb_enabled(dev)) { + cxgb4_dcb_state_init(dev); + dcb_tx_queue_prio_enable(dev, false); + } #endif /* CONFIG_CHELSIO_T4_DCB */ netif_carrier_off(dev); } @@ -494,22 +512,6 @@ static int link_start(struct net_device *dev) return ret; } -int cxgb4_dcb_enabled(const struct net_device *dev) -{ -#ifdef CONFIG_CHELSIO_T4_DCB - struct port_info *pi = netdev_priv(dev); - - if (!pi->dcb.enabled) - return 0; - - return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) || - (pi->dcb.state == CXGB4_DCB_STATE_HOST)); -#else - return 0; -#endif -} -EXPORT_SYMBOL(cxgb4_dcb_enabled); - #ifdef CONFIG_CHELSIO_T4_DCB /* Handle a Data Center Bridging update message from the firmware. */ static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd) -- 2.3.4
[PATCH net-next 0/2] cxgb4: mbox enhancements for cxgb4
Hi This patch series checks for firmware errors when we are waiting for mbox response in a loop and breaks out. When negative timeout is passed to mailbox code, don't sleep. Negative timeout is passed only from interrupt context. This patch series has been created against net-next tree and includes patches on cxgb4 driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (2): cxgb4: Don't sleep when mbox cmd is issued from interrupt context cxgb4: Check for firmware errors in the mailbox command loop drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) -- 2.3.4
[PATCH net-next 2/2] cxgb4: Check for firmware errors in the mailbox command loop
Check for firmware errors in the mailbox command loop and report them differently rather than simply timing out when the firmware goes belly up. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 59f5e0b40286..a63addb4e72c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -293,6 +293,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA_A); u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL_A); __be64 cmd_rpl[MBOX_LEN / 8]; + u32 pcie_fw; if ((size & 15) || size > MBOX_LEN) return -EINVAL; @@ -331,7 +332,10 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, delay_idx = 0; ms = delay[0]; - for (i = 0; i < timeout; i += ms) { + for (i = 0; +!((pcie_fw = t4_read_reg(adap, PCIE_FW_A)) & PCIE_FW_ERR_F) && +i < timeout; +i += ms) { if (sleep_ok) { ms = delay[delay_idx]; /* last element may repeat */ if (delay_idx < ARRAY_SIZE(delay) - 1) @@ -366,7 +370,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, } } - ret = -ETIMEDOUT; + ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -ETIMEDOUT; t4_record_mbox(adap, cmd, MBOX_LEN, access, ret); dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", *(const u8 *)cmd, mbox); -- 2.3.4
[PATCH net-next 1/2] cxgb4: Don't sleep when mbox cmd is issued from interrupt context
When link goes down, from the interrupt handler DCB priority for the Tx queues needs to be unset. We issue mbox command to unset the Tx queue priority with negative timeout. In t4_wr_mbox_meat_timeout() do not sleep when negative timeout is passed, since it is called from interrupt context. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 49bcbf16c9ca..59f5e0b40286 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -304,6 +304,12 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, if (adap->pdev->error_state != pci_channel_io_normal) return -EIO; + /* If we have a negative timeout, that implies that we can't sleep. */ + if (timeout < 0) { + sleep_ok = false; + timeout = -timeout; + } + v = MBOWNER_G(t4_read_reg(adap, ctl_reg)); for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++) v = MBOWNER_G(t4_read_reg(adap, ctl_reg)); -- 2.3.4
[PATCH net-next 0/2] cxgb4/cxgb4vf: add support for mbox cmd logging
Hi This patch series adds support for logging mailbox commands and replies for debugging purpose for both PF and VF driver. This patch series has been created against net-next tree and includes patches on cxgb4 and cxgb4vf driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (2): cxgb4: Add support to enable logging of firmware mailbox commands cxgb4vf: Add support to enable logging of firmware mailbox commands for VF drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 32 ++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 99 ++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 12 +++ drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 69 + drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 4 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 112 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 29 ++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 72 - 8 files changed, 384 insertions(+), 45 deletions(-) -- 2.3.4
[PATCH net-next 2/2] cxgb4vf: Add support to enable logging of firmware mailbox commands for VF
Add new /sys/kernel/debug/ support to dump firmware mailbox commands and replies for debugging purpose. Based on original work by Casey Leedom Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 4 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 112 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 29 ++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 72 - 4 files changed, 192 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index 4a707c32d76f..734dd776c22f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h @@ -387,6 +387,10 @@ struct adapter { /* various locks */ spinlock_t stats_lock; + /* support for mailbox command/reply logging */ +#define T4VF_OS_LOG_MBOX_CMDS 256 + struct mbox_cmd_log *mbox_log; + /* list of MAC addresses in MPS Hash */ struct list_head mac_hlist; }; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 730fec73d5a6..04fc6f6d1e25 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -1704,6 +1704,105 @@ static const struct ethtool_ops cxgb4vf_ethtool_ops = { */ /* + * Show Firmware Mailbox Command/Reply Log + * + * Note that we don't do any locking when dumping the Firmware Mailbox Log so + * it's possible that we can catch things during a log update and therefore + * see partially corrupted log entries. But i9t's probably Good Enough(tm). + * If we ever decide that we want to make sure that we're dumping a coherent + * log, we'd need to perform locking in the mailbox logging and in + * mboxlog_open() where we'd need to grab the entire mailbox log in one go + * like we do for the Firmware Device Log. But as stated above, meh ... + */ +static int mboxlog_show(struct seq_file *seq, void *v) +{ + struct adapter *adapter = seq->private; + struct mbox_cmd_log *log = adapter->mbox_log; + struct mbox_cmd *entry; + int entry_idx, i; + + if (v == SEQ_START_TOKEN) { + seq_printf(seq, + "%10s %15s %5s %5s %s\n", + "Seq#", "Tstamp", "Atime", "Etime", + "Command/Reply"); + return 0; + } + + entry_idx = log->cursor + ((uintptr_t)v - 2); + if (entry_idx >= log->size) + entry_idx -= log->size; + entry = mbox_cmd_log_entry(log, entry_idx); + + /* skip over unused entries */ + if (entry->timestamp == 0) + return 0; + + seq_printf(seq, "%10u %15llu %5d %5d", + entry->seqno, entry->timestamp, + entry->access, entry->execute); + for (i = 0; i < MBOX_LEN / 8; i++) { + u64 flit = entry->cmd[i]; + u32 hi = (u32)(flit >> 32); + u32 lo = (u32)flit; + + seq_printf(seq, " %08x %08x", hi, lo); + } + seq_puts(seq, "\n"); + return 0; +} + +static inline void *mboxlog_get_idx(struct seq_file *seq, loff_t pos) +{ + struct adapter *adapter = seq->private; + struct mbox_cmd_log *log = adapter->mbox_log; + + return ((pos <= log->size) ? (void *)(uintptr_t)(pos + 1) : NULL); +} + +static void *mboxlog_start(struct seq_file *seq, loff_t *pos) +{ + return *pos ? mboxlog_get_idx(seq, *pos) : SEQ_START_TOKEN; +} + +static void *mboxlog_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + return mboxlog_get_idx(seq, *pos); +} + +static void mboxlog_stop(struct seq_file *seq, void *v) +{ +} + +static const struct seq_operations mboxlog_seq_ops = { + .start = mboxlog_start, + .next = mboxlog_next, + .stop = mboxlog_stop, + .show = mboxlog_show +}; + +static int mboxlog_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &mboxlog_seq_ops); + + if (!res) { + struct seq_file *seq = file->private_data; + + seq->private = inode->i_private; + } + return res; +} + +static const struct file_operations mboxlog_fops = { + .owner = THIS_MODULE, + .open= mboxlog_open, + .read= seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* * Show SGE Queue Set information. We display QPL Queues Sets per line. */ #define QPL4 @@ -2122,6 +2221,7 @@ struct cxgb4vf_debugfs_entry { }; static struct cxgb4vf_debugfs_entry debugfs_files[] = { + { "mboxlog",S_IRUGO, &a
[PATCH net-next 1/2] cxgb4: Add support to enable logging of firmware mailbox commands
Add new /sys/kernel/debug/ support to dump a firmware mailbox command issued and replies for debugging purpose. Based on original work by Casey Leedom Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 32 +++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 99 ++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 12 +++ drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 69 ++- 4 files changed, 192 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 6af5242e6d21..b4fceb92479f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -359,6 +359,34 @@ struct sge_idma_monitor_state { unsigned int idma_warn[2]; /* time to warning in HZ */ }; +/* Firmware Mailbox Command/Reply log. All values are in Host-Endian format. + * The access and execute times are signed in order to accommodate negative + * error returns. + */ +struct mbox_cmd { + u64 cmd[MBOX_LEN / 8]; /* a Firmware Mailbox Command/Reply */ + u64 timestamp; /* OS-dependent timestamp */ + u32 seqno; /* sequence number */ + s16 access; /* time (ms) to access mailbox */ + s16 execute;/* time (ms) to execute */ +}; + +struct mbox_cmd_log { + unsigned int size; /* number of entries in the log */ + unsigned int cursor;/* next position in the log to write */ + u32 seqno; /* next sequence number */ + /* variable length mailbox command log starts here */ +}; + +/* Given a pointer to a Firmware Mailbox Command Log and a log entry index, + * return a pointer to the specified entry. + */ +static inline struct mbox_cmd *mbox_cmd_log_entry(struct mbox_cmd_log *log, + unsigned int entry_idx) +{ + return &((struct mbox_cmd *)&(log)[1])[entry_idx]; +} + #include "t4fw_api.h" #define FW_VERSION(chip) ( \ @@ -780,6 +808,10 @@ struct adapter { struct work_struct db_drop_task; bool tid_release_task_busy; + /* support for mailbox command/reply logging */ +#define T4_OS_LOG_MBOX_CMDS 256 + struct mbox_cmd_log *mbox_log; + struct dentry *debugfs_root; bool use_bd; /* Use SGE Back Door intfc for reading SGE Contexts */ bool trace_rss; /* 1 implies that different RSS flit per filter is diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 9506c5cd11b9..91fb50850fff 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -1152,6 +1152,104 @@ static const struct file_operations devlog_fops = { .release = seq_release_private }; +/* Show Firmware Mailbox Command/Reply Log + * + * Note that we don't do any locking when dumping the Firmware Mailbox Log so + * it's possible that we can catch things during a log update and therefore + * see partially corrupted log entries. But it's probably Good Enough(tm). + * If we ever decide that we want to make sure that we're dumping a coherent + * log, we'd need to perform locking in the mailbox logging and in + * mboxlog_open() where we'd need to grab the entire mailbox log in one go + * like we do for the Firmware Device Log. + */ +static int mboxlog_show(struct seq_file *seq, void *v) +{ + struct adapter *adapter = seq->private; + struct mbox_cmd_log *log = adapter->mbox_log; + struct mbox_cmd *entry; + int entry_idx, i; + + if (v == SEQ_START_TOKEN) { + seq_printf(seq, + "%10s %15s %5s %5s %s\n", + "Seq#", "Tstamp", "Atime", "Etime", + "Command/Reply"); + return 0; + } + + entry_idx = log->cursor + ((uintptr_t)v - 2); + if (entry_idx >= log->size) + entry_idx -= log->size; + entry = mbox_cmd_log_entry(log, entry_idx); + + /* skip over unused entries */ + if (entry->timestamp == 0) + return 0; + + seq_printf(seq, "%10u %15llu %5d %5d", + entry->seqno, entry->timestamp, + entry->access, entry->execute); + for (i = 0; i < MBOX_LEN / 8; i++) { + u64 flit = entry->cmd[i]; + u32 hi = (u32)(flit >> 32); + u32 lo = (u32)flit; + + seq_printf(seq, " %08x %08x", hi, lo); + } + seq_puts(seq, "\n"); + return 0; +} + +static inline void *mboxlog_get_idx(struct seq_fi
[PATCH net-next 6/8] cxgb4: DCB message handler needs to use correct portid to netdev mapping
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c index 052c660aca80..6ee2ed30626b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c @@ -253,7 +253,7 @@ void cxgb4_dcb_handle_fw_update(struct adapter *adap, { const union fw_port_dcb *fwdcb = &pcmd->u.dcb; int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid)); - struct net_device *dev = adap->port[port]; + struct net_device *dev = adap->port[adap->chan_map[port]]; struct port_info *pi = netdev_priv(dev); struct port_dcb_info *dcb = &pi->dcb; int dcb_type = pcmd->u.dcb.pgid.type; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index abc425bfc744..4f627f3edb98 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -515,7 +515,7 @@ EXPORT_SYMBOL(cxgb4_dcb_enabled); static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd) { int port = FW_PORT_CMD_PORTID_G(ntohl(pcmd->op_to_portid)); - struct net_device *dev = adap->port[port]; + struct net_device *dev = adap->port[adap->chan_map[port]]; int old_dcb_enabled = cxgb4_dcb_enabled(dev); int new_dcb_enabled; @@ -645,7 +645,8 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, action == FW_PORT_ACTION_GET_PORT_INFO) { int port = FW_PORT_CMD_PORTID_G( be32_to_cpu(pcmd->op_to_portid)); - struct net_device *dev = q->adap->port[port]; + struct net_device *dev = + q->adap->port[q->adap->chan_map[port]]; int state_input = ((pcmd->u.info.dcbxdis_pkd & FW_PORT_CMD_DCBXDIS_F) ? CXGB4_DCB_INPUT_FW_DISABLED -- 2.3.4
[PATCH net-next 2/8] cxgb4: Add llseek operation for flash debugfs entry
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 0bb41e9b9b1c..9506c5cd11b9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -1572,6 +1572,7 @@ static const struct file_operations flash_debugfs_fops = { .owner = THIS_MODULE, .open= mem_open, .read= flash_read, + .llseek = default_llseek, }; static inline void tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask) -- 2.3.4
[PATCH net-next 7/8] cxgb4: Don't assume FW_PORT_CMD reply is always port info msg
The firmware can send a set of asynchronous replies through FW_PORT_CMD with DCBX information when that's negotiated with the Link Peer. The old code always assumed that a FW_PORT_CMD reply was always a Get Port Information message. This change conditionalizes the code to only handle the Get Port Information messages and throws a warning if we don't understand what we've been given. Also refactor t4_handle_fw_rpl() so that core functionality performed by t4_handle_get_port_info() for a specified port. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 110 +++-- 2 files changed, 74 insertions(+), 37 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index f69119bc5990..911fe11d32c6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1470,6 +1470,7 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int eqid); int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox); +void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl); int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl); void t4_db_full(struct adapter *adapter); void t4_db_dropped(struct adapter *adapter); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 1e9323e3..cf3efbf4a37a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -7103,52 +7103,88 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, } /** - * t4_handle_fw_rpl - process a FW reply message - * @adap: the adapter + * t4_handle_get_port_info - process a FW reply message + * @pi: the port info * @rpl: start of the FW message * - * Processes a FW message, such as link state change messages. + * Processes a GET_PORT_INFO FW reply message. + */ +void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) +{ + const struct fw_port_cmd *p = (const void *)rpl; + struct adapter *adap = pi->adapter; + + /* link/module state change message */ + int speed = 0, fc = 0; + struct link_config *lc; + u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype); + int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0; + u32 mod = FW_PORT_CMD_MODTYPE_G(stat); + + if (stat & FW_PORT_CMD_RXPAUSE_F) + fc |= PAUSE_RX; + if (stat & FW_PORT_CMD_TXPAUSE_F) + fc |= PAUSE_TX; + if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) + speed = 100; + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) + speed = 1000; + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) + speed = 1; + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) + speed = 4; + + lc = &pi->link_cfg; + + if (mod != pi->mod_type) { + pi->mod_type = mod; + t4_os_portmod_changed(adap, pi->port_id); + } + if (link_ok != lc->link_ok || speed != lc->speed || + fc != lc->fc) { /* something changed */ + lc->link_ok = link_ok; + lc->speed = speed; + lc->fc = fc; + lc->supported = be16_to_cpu(p->u.info.pcap); + t4_os_link_changed(adap, pi->port_id, link_ok); + } +} + +/** + * t4_handle_fw_rpl - process a FW reply message + * @adap: the adapter + * @rpl: start of the FW message + * + * Processes a FW message, such as link state change messages. */ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) { u8 opcode = *(const u8 *)rpl; - if (opcode == FW_PORT_CMD) {/* link/module state change message */ - int speed = 0, fc = 0; - const struct fw_port_cmd *p = (void *)rpl; + /* This might be a port command ... this simplifies the following +* conditionals ... We can get away with pre-dereferencing +* action_to_len16 because it's in the first 16 bytes and all messages +* will be at least that long. +*/ + const struct fw_port_cmd *p = (const void *)rpl; + unsigned int action = + FW_PORT_CMD_ACTION_G(be32_to_cpu(p->action_to_len16)); + + if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) { + int i; int chan = FW_PORT_CMD_PORTID_G(be32_to_cpu(p->op_to_portid)); - int port = adap->chan_map[chan]; -
[PATCH net-next 3/8] cxgb4: Avoids race and deadlock while freeing tx descriptor
There could be race between t4_eth_xmit() and t4_free_sge_resources() while freeing tx descriptors, take txq lock in t4_free_sge_resources(). We need to stop the xmit frame path which runs in bottom half context while unloading the driver using _bh variant of the lock. This is to prevent the deadlock between xmit and driver unload. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 6278e5a74b74..bad253beb8c8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -3006,7 +3006,9 @@ void t4_free_sge_resources(struct adapter *adap) if (etq->q.desc) { t4_eth_eq_free(adap, adap->mbox, adap->pf, 0, etq->q.cntxt_id); + __netif_tx_lock_bh(etq->txq); free_tx_desc(adap, &etq->q, etq->q.in_use, true); + __netif_tx_unlock_bh(etq->txq); kfree(etq->q.sdesc); free_txq(adap, &etq->q); } -- 2.3.4
[PATCH net-next 4/8] cxgb4: Properly decode port module type
Decode and log port module error, unknown modules and unsupported modules. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index b8dc7921b258..abc425bfc744 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -337,6 +337,17 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id) netdev_info(dev, "port module unplugged\n"); else if (pi->mod_type < ARRAY_SIZE(mod_str)) netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]); + else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED) + netdev_info(dev, "%s: unsupported port module inserted\n", + dev->name); + else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN) + netdev_info(dev, "%s: unknown port module inserted\n", + dev->name); + else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR) + netdev_info(dev, "%s: transceiver module error\n", dev->name); + else + netdev_info(dev, "%s: unknown module type %d inserted\n", + dev->name, pi->mod_type); } int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */ -- 2.3.4
[PATCH net-next 1/8] cxgb4: add new routine to get adapter info
Add new routine to print out general adapter information (various version numbers, adapter name, part number, serial number, etc.) and remove redundant information dumped in the Port Information. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 4 ++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 78 ++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 14 + drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 7 +++ 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 326d4009525e..459775884cad 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -324,7 +324,9 @@ struct adapter_params { unsigned int sf_fw_start; /* start of FW image in flash */ unsigned int fw_vers; + unsigned int bs_vers; /* bootstrap version */ unsigned int tp_vers; + unsigned int er_vers; /* expansion ROM version */ u8 api_vers[7]; unsigned short mtus[NMTUS]; @@ -731,6 +733,7 @@ struct adapter { u32 t4_bar0; struct pci_dev *pdev; struct device *pdev_dev; + const char *name; unsigned int mbox; unsigned int pf; unsigned int flags; @@ -1306,6 +1309,7 @@ int t4_fl_pkt_align(struct adapter *adap); unsigned int t4_flash_cfg_addr(struct adapter *adapter); int t4_check_fw_version(struct adapter *adap); int t4_get_fw_version(struct adapter *adapter, u32 *vers); +int t4_get_bs_version(struct adapter *adapter, u32 *vers); int t4_get_tp_version(struct adapter *adapter, u32 *vers); int t4_get_exprom_version(struct adapter *adapter, u32 *vers); int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a1e329ec24cd..b8dc7921b258 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3738,7 +3738,10 @@ static int adap_init0(struct adapter *adap) * is excessively mismatched relative to the driver.) */ t4_get_fw_version(adap, &adap->params.fw_vers); + t4_get_bs_version(adap, &adap->params.bs_vers); t4_get_tp_version(adap, &adap->params.tp_vers); + t4_get_exprom_version(adap, &adap->params.er_vers); + ret = t4_check_fw_version(adap); /* If firmware is too old (not supported by driver) force an update. */ if (ret) @@ -4652,6 +4655,68 @@ static void cxgb4_check_pcie_caps(struct adapter *adap) "suggested for optimal performance.\n"); } +/* Dump basic information about the adapter */ +static void print_adapter_info(struct adapter *adapter) +{ + /* Device information */ + dev_info(adapter->pdev_dev, "Chelsio %s rev %d\n", +adapter->params.vpd.id, +CHELSIO_CHIP_RELEASE(adapter->params.chip)); + dev_info(adapter->pdev_dev, "S/N: %s, P/N: %s\n", +adapter->params.vpd.sn, adapter->params.vpd.pn); + + /* Firmware Version */ + if (!adapter->params.fw_vers) + dev_warn(adapter->pdev_dev, "No firmware loaded\n"); + else + dev_info(adapter->pdev_dev, "Firmware version: %u.%u.%u.%u\n", +FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers), +FW_HDR_FW_VER_MINOR_G(adapter->params.fw_vers), +FW_HDR_FW_VER_MICRO_G(adapter->params.fw_vers), +FW_HDR_FW_VER_BUILD_G(adapter->params.fw_vers)); + + /* Bootstrap Firmware Version. (Some adapters don't have Bootstrap +* Firmware, so dev_info() is more appropriate here.) +*/ + if (!adapter->params.bs_vers) + dev_info(adapter->pdev_dev, "No bootstrap loaded\n"); + else + dev_info(adapter->pdev_dev, "Bootstrap version: %u.%u.%u.%u\n", +FW_HDR_FW_VER_MAJOR_G(adapter->params.bs_vers), +FW_HDR_FW_VER_MINOR_G(adapter->params.bs_vers), +FW_HDR_FW_VER_MICRO_G(adapter->params.bs_vers), +FW_HDR_FW_VER_BUILD_G(adapter->params.bs_vers)); + + /* TP Microcode Version */ + if (!adapter->params.tp_vers) + dev_warn(adapter->pdev_dev, "No TP Microcode loaded\n"); + else + dev_info(adapter->pdev_dev, +"TP Microcode version: %u.%u.%u.%u\n", +FW_HDR_FW_VER_MAJOR_G(adapter->params.tp_vers), +FW_HDR_FW_VER_MINOR_G(adapter->params.tp_vers), +
[PATCH net-next 8/8] cxgb4: Decode link down reason code obtained from firmware
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h| 1 + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c| 34 +++ drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 5 3 files changed, 40 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 911fe11d32c6..6af5242e6d21 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -396,6 +396,7 @@ struct link_config { unsigned char fc; /* actual link flow control */ unsigned char autoneg; /* autonegotiating? */ unsigned char link_ok; /* link up? */ + unsigned char link_down_rc; /* link down reason */ }; #define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index cf3efbf4a37a..7907d85efa4c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -7103,6 +7103,32 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, } /** + * t4_link_down_rc_str - return a string for a Link Down Reason Code + * @adap: the adapter + * @link_down_rc: Link Down Reason Code + * + * Returns a string representation of the Link Down Reason Code. + */ +static const char *t4_link_down_rc_str(unsigned char link_down_rc) +{ + static const char * const reason[] = { + "Link Down", + "Remote Fault", + "Auto-negotiation Failure", + "Reserved", + "Insufficient Airflow", + "Unable To Determine Reason", + "No RX Signal Detected", + "Reserved", + }; + + if (link_down_rc >= ARRAY_SIZE(reason)) + return "Bad Reason Code"; + + return reason[link_down_rc]; +} + +/** * t4_handle_get_port_info - process a FW reply message * @pi: the port info * @rpl: start of the FW message @@ -7142,6 +7168,14 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) } if (link_ok != lc->link_ok || speed != lc->speed || fc != lc->fc) { /* something changed */ + if (!link_ok && lc->link_ok) { + unsigned char rc = FW_PORT_CMD_LINKDNRC_G(stat); + + lc->link_down_rc = rc; + dev_warn(adap->pdev_dev, +"Port %d link down, reason: %s\n", +pi->port_id, t4_link_down_rc_str(rc)); + } lc->link_ok = link_ok; lc->speed = speed; lc->fc = fc; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 7ad6d4e75b2a..392d6644fdd8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -2510,6 +2510,11 @@ struct fw_port_cmd { #define FW_PORT_CMD_PTYPE_G(x) \ (((x) >> FW_PORT_CMD_PTYPE_S) & FW_PORT_CMD_PTYPE_M) +#define FW_PORT_CMD_LINKDNRC_S 5 +#define FW_PORT_CMD_LINKDNRC_M 0x7 +#define FW_PORT_CMD_LINKDNRC_G(x) \ + (((x) >> FW_PORT_CMD_LINKDNRC_S) & FW_PORT_CMD_LINKDNRC_M) + #define FW_PORT_CMD_MODTYPE_S 0 #define FW_PORT_CMD_MODTYPE_M 0x1f #define FW_PORT_CMD_MODTYPE_V(x) ((x) << FW_PORT_CMD_MODTYPE_S) -- 2.3.4
[PATCH net-next 5/8] cxgb4: Refactor t4_port_init function
Refactor t4_port_init() so that the core functionality is done by t4_init_portinfo() for a particular port. Also rename variables to sensible ones. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 2 + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 93 +- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 459775884cad..f69119bc5990 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1333,6 +1333,8 @@ int t4_init_sge_params(struct adapter *adapter); int t4_init_tp_params(struct adapter *adap); int t4_filter_field_shift(const struct adapter *adap, int filter_sel); int t4_init_rss_mode(struct adapter *adap, int mbox); +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); int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 2ced24fc569d..1e9323e3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -7668,61 +7668,74 @@ int t4_init_rss_mode(struct adapter *adap, int mbox) return 0; } -int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) +/** + * t4_init_portinfo - allocate a virtual interface amd initialize port_info + * @pi: the port_info + * @mbox: mailbox to use for the FW command + * @port: physical port associated with the VI + * @pf: the PF owning the VI + * @vf: the VF owning the VI + * @mac: the MAC address of the VI + * + * Allocates a virtual interface for the given physical port. If @mac is + * not %NULL it contains the MAC address of the VI as assigned by FW. + * @mac should be large enough to hold an Ethernet address. + * Returns < 0 on error. + */ +int t4_init_portinfo(struct port_info *pi, int mbox, +int port, int pf, int vf, u8 mac[]) { - u8 addr[6]; - int ret, i, j = 0; + int ret; struct fw_port_cmd c; - struct fw_rss_vi_config_cmd rvc; + unsigned int rss_size; memset(&c, 0, sizeof(c)); - memset(&rvc, 0, sizeof(rvc)); + c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | +FW_CMD_REQUEST_F | FW_CMD_READ_F | +FW_PORT_CMD_PORTID_V(port)); + c.action_to_len16 = cpu_to_be32( + FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | + FW_LEN16(c)); + ret = t4_wr_mbox(pi->adapter, mbox, &c, sizeof(c), &c); + if (ret) + return ret; + + ret = t4_alloc_vi(pi->adapter, mbox, port, pf, vf, 1, mac, &rss_size); + if (ret < 0) + return ret; + + pi->viid = ret; + pi->tx_chan = port; + pi->lport = port; + pi->rss_size = rss_size; + + ret = be32_to_cpu(c.u.info.lstatus_to_modtype); + pi->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP_F) ? + FW_PORT_CMD_MDIOADDR_G(ret) : -1; + pi->port_type = FW_PORT_CMD_PTYPE_G(ret); + pi->mod_type = FW_PORT_MOD_TYPE_NA; + + init_link_config(&pi->link_cfg, be16_to_cpu(c.u.info.pcap)); + return 0; +} + +int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) +{ + u8 addr[6]; + int ret, i, j = 0; for_each_port(adap, i) { - unsigned int rss_size; - struct port_info *p = adap2pinfo(adap, i); + struct port_info *pi = adap2pinfo(adap, i); while ((adap->params.portvec & (1 << j)) == 0) j++; - c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | -FW_CMD_REQUEST_F | FW_CMD_READ_F | -FW_PORT_CMD_PORTID_V(j)); - c.action_to_len16 = cpu_to_be32( - FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | - FW_LEN16(c)); - ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + ret = t4_init_portinfo(pi, mbox, j, pf, vf, addr); if (ret) return ret; - ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size); - if (ret < 0) - return ret; - - p->viid = ret; - p->tx_chan = j; - p->lport = j; - p->rss_size = rss_size; memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN)
[PATCH net-next 0/8] cxgb4: minor fixes, decode msgs and code refactor for few functions
Hi This patch series adds new routine to get adapter information and removes some redundant messages logged in dmesg. Fixes race while freeing tx descriptors. Decodes module type and link down reason codes obtained from firmware. Refactor port initialization and FW_PORT_CMD handling. Pass correct port id in DCB message handler to obtain netdev associated. This patch series has been created against net-next tree and includes patches on cxgb4 driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (8): cxgb4: add new routine to get adapter info cxgb4: Add llseek operation for flash debugfs entry cxgb4: Avoids race and deadlock while freeing tx descriptor cxgb4: Properly decode port module type cxgb4: Refactor t4_port_init function cxgb4: DCB message handler needs to use correct portid to netdev mapping cxgb4: Don't assume FW_PORT_CMD reply is always port info msg cxgb4: Decode link down reason code obtained from firmware drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 1 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 94 +++- drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 249 ++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 7 + drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 5 + 8 files changed, 281 insertions(+), 87 deletions(-) -- 2.3.4
[PATCH pci] pci: Add helper function to set VPD size
commit 104daa71b396 ("PCI: Determine actual VPD size on first access") introduced a regression in cxgb4 driver and used to fail in pci probe. The problem is stemming from the fact that the Chelsio adapters actually have two VPD structures stored in the VPD. An abbreviated on at Offset 0x0 and the complete VPD at Offset 0x400. The abbreviated one only contains the PN, SN and EC Keywords, while the complete VPD contains those plus various adapter constants contained in V0, V1, etc. And it also contains the Base Ethernet MAC Address in the "NA" Keyword which the cxgb4 driver needs when it can't contact the adapter firmware. (We don't have the "NA" Keywork in the VPD Structure at Offset 0x0 because that's not an allowed VPD Keyword in the PCI-E 3.0 specification.) With the new code, the computed size of the VPD is 0x200 and so our efforts to read the VPD at Offset 0x400 silently fails. We check the result of the read looking for a signature 0x82 byte but we're checking against random stack garbage. The fix is to add a PCI helper function to set the VPD size, so the driver can expicitly set the exact size of the VPD. Fixes commit 104daa71b396 ("PCI: Determine actual VPD size on first access") Signed-off-by: Casey Leedom Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 10 +++ drivers/pci/access.c | 42 ++ drivers/pci/pci.h | 1 + include/linux/pci.h| 1 + 4 files changed, 54 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index cc1736bece0f..2033159e26a5 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2557,6 +2557,7 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) } #define EEPROM_STAT_ADDR 0x7bfc +#define VPD_SIZE 0x800 #define VPD_BASE 0x400 #define VPD_BASE_OLD 0 #define VPD_LEN1024 @@ -2594,6 +2595,15 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p) if (!vpd) return -ENOMEM; + /* We have two VPD data structures stored in the adapter VPD area. +* By default, Linux calculates the size of the VPD area by traversing +* the first VPD area at offset 0x0, so we need to tell the OS what +* our real VPD size is. +*/ + ret = pci_set_size_vpd(adapter->pdev, VPD_SIZE); + if (ret < 0) + goto out; + /* Card information normally starts at VPD_BASE but early cards had * it at 0. */ diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 01b9d0a00abc..e69b3877bd37 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -275,6 +275,19 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void } EXPORT_SYMBOL(pci_write_vpd); +/** + * pci_set_size_vpd - Set size of Vital Product Data space + * @dev: pci device struct + * @len: size of vpd space + */ +ssize_t pci_set_size_vpd(struct pci_dev *dev, size_t len) +{ + if (!dev->vpd || !dev->vpd->ops) + return -ENODEV; + return dev->vpd->ops->set_size(dev, len); +} +EXPORT_SYMBOL(pci_set_size_vpd); + #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1) /** @@ -498,9 +511,23 @@ out: return ret ? ret : count; } +static ssize_t pci_vpd_set_size(struct pci_dev *dev, size_t len) +{ + struct pci_vpd *vpd = dev->vpd; + + if (len == 0 || len > PCI_VPD_MAX_SIZE) + return -EIO; + + vpd->valid = 1; + vpd->len = len; + + return 0; +} + static const struct pci_vpd_ops pci_vpd_ops = { .read = pci_vpd_read, .write = pci_vpd_write, + .set_size = pci_vpd_set_size, }; static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, @@ -533,9 +560,24 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, return ret; } +static ssize_t pci_vpd_f0_set_size(struct pci_dev *dev, size_t len) +{ + struct pci_dev *tdev = pci_get_slot(dev->bus, + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_set_size_vpd(tdev, len); + pci_dev_put(tdev); + return ret; +} + static const struct pci_vpd_ops pci_vpd_f0_ops = { .read = pci_vpd_f0_read, .write = pci_vpd_f0_write, + .set_size = pci_vpd_f0_set_size, }; int pci_vpd_init(struct pci_dev *dev) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d0fb93481573..8239d186f1ed 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -97,6 +97,7 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev)
[REGRESSION, bisect] pci: cxgb4 probe fails after commit 104daa71b3961434 ("PCI: Determine actual VPD size on first access")
Hi All, The following patch introduced a regression, causing cxgb4 driver to fail in PCIe probe. commit 104daa71b39614343929e1982170d5fcb0569bb5 Author: Hannes Reinecke Author: Hannes Reinecke Date: Mon Feb 15 09:42:01 2016 +0100 PCI: Determine actual VPD size on first access PCI-2.2 VPD entries have a maximum size of 32k, but might actually be smaller than that. To figure out the actual size one has to read the VPD area until the 'end marker' is reached. Per spec, reading outside of the VPD space is "not allowed." In practice, it may cause simple read errors or even crash the card. To make matters worse not every PCI card implements this properly, leaving us with no 'end' marker or even completely invalid data. Try to determine the size of the VPD data when it's first accessed. If no valid data can be read an I/O error will be returned when reading or writing the sysfs attribute. As the amount of VPD data is unknown initially the size of the sysfs attribute will always be set to '0'. [bhelgaas: changelog, use 0/1 (not false/true) for bitfield, tweak pci_vpd_pci22_read() error checking] Tested-by: Shane Seymour Tested-by: Babu Moger Signed-off-by: Hannes Reinecke Signed-off-by: Bjorn Helgaas Cc: Alexander Duyck The problem is stemming from the fact that the Chelsio adapters actually have two VPD structures stored in the VPD. An abbreviated on at Offset 0x0 and the complete VPD at Offset 0x400. The abbreviated one only contains the PN, SN and EC Keywords, while the complete VPD contains those plus various adapter constants contained in V0, V1, etc. And it also contains the Base Ethernet MAC Address in the "NA" Keyword which the cxgb4 driver needs when it can't contact the adapter firmware. (We don't have the "NA" Keywork in the VPD Structure at Offset 0x0 because that's not an allowed VPD Keyword in the PCI-E 3.0 specification.) With the new code, the computed size of the VPD is 0x200 and so our efforts to read the VPD at Offset 0x400 silently fails. We check the result of the read looking for a signature 0x82 byte but we're checking against random stack garbage. The end result is that the cxgb4 driver now fails the PCI-E Probe. Thanks, Hari
[PATCH net] cxgb4: Stop Rx Queues before freeing it up
Stop all Ethernet RX Queues before freeing up various Ingress/Egress Queues, etc. We were seeing cases of Ingress Queues not getting serviced during the shutdown process leading to Ingress Paths jamming up through the chip and blocking the shutdown effort itself. One such case involved the Firmware sending a "Flush Token" through the ULP-TX -> ULP-RX path for an Ethernet TX Queue being freed in order to make sure there weren't any remaining TX Work Requests in the pipeline. But the return path was stalled by Ingress Data unable to be delivered to the Host because those Ingress Queues were no longer being serviced. Based on original work by Casey Leedom Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 +++ drivers/net/ethernet/chelsio/cxgb4/sge.c | 20 +++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 33 ++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 984a3cc26f86..326d4009525e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1451,6 +1451,9 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 *valp); int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 val); +int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, + unsigned int vf, unsigned int iqtype, unsigned int iqid, + unsigned int fl0id, unsigned int fl1id); int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int iqtype, unsigned int iqid, unsigned int fl0id, unsigned int fl1id); diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 13b144bcf725..6278e5a74b74 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -2981,14 +2981,28 @@ void t4_free_ofld_rxqs(struct adapter *adap, int n, struct sge_ofld_rxq *q) void t4_free_sge_resources(struct adapter *adap) { int i; - struct sge_eth_rxq *eq = adap->sge.ethrxq; - struct sge_eth_txq *etq = adap->sge.ethtxq; + struct sge_eth_rxq *eq; + struct sge_eth_txq *etq; + + /* stop all Rx queues in order to start them draining */ + for (i = 0; i < adap->sge.ethqsets; i++) { + eq = &adap->sge.ethrxq[i]; + if (eq->rspq.desc) + t4_iq_stop(adap, adap->mbox, adap->pf, 0, + FW_IQ_TYPE_FL_INT_CAP, + eq->rspq.cntxt_id, + eq->fl.size ? eq->fl.cntxt_id : 0x, + 0x); + } /* clean up Ethernet Tx/Rx queues */ - for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) { + for (i = 0; i < adap->sge.ethqsets; i++) { + eq = &adap->sge.ethrxq[i]; if (eq->rspq.desc) free_rspq_fl(adap, &eq->rspq, eq->fl.size ? &eq->fl : NULL); + + etq = &adap->sge.ethtxq[i]; if (etq->q.desc) { t4_eth_eq_free(adap, adap->mbox, adap->pf, 0, etq->q.cntxt_id); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index cc1736bece0f..520ffcaef6d8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -6940,6 +6940,39 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, } /** + * t4_iq_stop - stop an ingress queue and its FLs + * @adap: the adapter + * @mbox: mailbox to use for the FW command + * @pf: the PF owning the queues + * @vf: the VF owning the queues + * @iqtype: the ingress queue type (FW_IQ_TYPE_FL_INT_CAP, etc.) + * @iqid: ingress queue id + * @fl0id: FL0 queue id or 0x if no attached FL0 + * @fl1id: FL1 queue id or 0x if no attached FL1 + * + * Stops an ingress queue and its associated FLs, if any. This causes + * any current or future data/messages destined for these queues to be + * tossed. + */ +int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, + unsigned int vf, unsigned int iqtype, unsigned int iqid, + unsigned int fl0id, unsigned int fl1id) +{ + struct fw_iq_cmd c; + + memset(&c, 0, sizeof(c)); + c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | +
[PATCHv2 net-next] cxgb4/cxgb4vf: Deprecate module parameter dflt_msg_enable
Message level can be set through ethtool, so deprecate module parameter which is used to set the same. Signed-off-by: Hariprasad Shenai --- V2: Fix grammar in module param description, based on review comment by Sergei Shtylyov drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 ++- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index d1e3f0997d6b..a1e329ec24cd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -168,7 +168,8 @@ MODULE_PARM_DESC(force_init, "Forcibly become Master PF and initialize adapter," static int dflt_msg_enable = DFLT_MSG_ENABLE; module_param(dflt_msg_enable, int, 0644); -MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap"); +MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap, " +"deprecated parameter"); /* * The driver uses the best interrupt scheme available on a platform in the diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 1cc8a7a69457..730fec73d5a6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -74,7 +74,8 @@ static int dflt_msg_enable = DFLT_MSG_ENABLE; module_param(dflt_msg_enable, int, 0644); MODULE_PARM_DESC(dflt_msg_enable, -"default adapter ethtool message level bitmap"); +"default adapter ethtool message level bitmap, " +"deprecated parameter"); /* * The driver uses the best interrupt scheme available on a platform in the -- 2.3.4
[PATCH net-next] cxgb4/cxgb4vf: Deprecate module parameter dflt_msg_enable
Message level can be set through ethtool, so deprecate module parameter which is used to set the same. Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 ++- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index d1e3f0997d6b..acefa35b7250 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -168,7 +168,8 @@ MODULE_PARM_DESC(force_init, "Forcibly become Master PF and initialize adapter," static int dflt_msg_enable = DFLT_MSG_ENABLE; module_param(dflt_msg_enable, int, 0644); -MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap"); +MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap," +"deprecated parameter"); /* * The driver uses the best interrupt scheme available on a platform in the diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 1cc8a7a69457..730fec73d5a6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -74,7 +74,8 @@ static int dflt_msg_enable = DFLT_MSG_ENABLE; module_param(dflt_msg_enable, int, 0644); MODULE_PARM_DESC(dflt_msg_enable, -"default adapter ethtool message level bitmap"); +"default adapter ethtool message level bitmap, " +"deprecated parameter"); /* * The driver uses the best interrupt scheme available on a platform in the -- 2.3.4
[PATCH net] cxgb4: Add pci device id for chelsio t520-cr adapter
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h | 1 + 1 file changed, 1 insertion(+) 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 06bc2d2e7a73..a2cdfc1261dc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -166,6 +166,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x5099), /* Custom 2x40G QSFP */ CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */ CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */ + CH_PCI_ID_TABLE_FENTRY(0x509c), /* Custom T520-CR*/ /* T6 adapters: */ -- 2.3.4
Re: [target-pending 00/12] cxgb4 patch series for cxgbit.ko
On Mon, Mar 14, 2016 at 22:29:11 -0700, Nicholas A. Bellinger wrote: > Hi Varun & Co, > > On Sun, 2016-03-13 at 19:49 +0530, Varun Prakash wrote: > > Hi Nicholas, > > > >I am posting cxgb4 patch series as > >suggested by you in following email thread > > > >http://www.spinics.net/lists/target-devel/msg12437.html > > > >This series consists of patches from > >initial cxgb4 series without any change. > > > > Thanks > > Varun > > > > Thanks for re-posting iscsi segment offload (ISO) prerequisites as a > stand-alone vxgb4 network driver series. > > This -v1 series has been in target-pending/for-next-merge for last > weeks, and encountered one conflict vs. net-next as reported by SFR: > > https://lkml.org/lkml/2016/2/29/34 > > That said, I'm still OK to merge via target-pending to enable post v4.6 > iscsi-target developments, as long as DaveM doesn't have an objection or > if he'd prefer to pick them up. > > As-is, they still need Acked-by's from the cxgb4 driver maintainer. > > Hariprasad, please give your review + ack. > The entire series looks good. Acked-by: Hariprasad Shenai
[PATCH net-next 0/4] cxgb4vf: Interrupt and queue configuration changes
Hi, This series fixes some issues and some changes in the queue and interrupt configuration for cxgb4vf driver. We need to enable interrupts before we register our network device, so that we don't loose link up interrupts. Allocate rx queues based on interrupt type. Set number of tx/rx queues in probe function only. Also adds check for some invalid configurations. This patch series has been created against net-next tree and includes patches on cxgb4vf driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (4): cxgb4vf: Enable interrupts before we register our network devices cxgb4vf: Configure queue based on resource and interrupt type cxgb4vf: Add a couple more checks for invalid provisioning configurations cxgb4vf : Set number of queues in pci probe only .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 221 +++- 1 files changed, 125 insertions(+), 96 deletions(-) -- 1.7.3
[PATCH net-next 2/4] cxgb4vf: Configure queue based on resource and interrupt type
The Queue Set Configuration code was always reserving room for a Forwarded interrupt Queue even in the cases where we weren't using it. Figure out how many Ports and Queue Sets we can support. This depends on knowing our Virtual Function Resources and may be called a second time if we fall back from MSI-X to MSI Interrupt Mode. This change fixes that problem. Signed-off-by: Hariprasad Shenai --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 165 +++- 1 files changed, 94 insertions(+), 71 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index fcafe34..17a3153 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2176,6 +2176,73 @@ static void cleanup_debugfs(struct adapter *adapter) /* nothing to do */ } +/* Figure out how many Ports and Queue Sets we can support. This depends on + * knowing our Virtual Function Resources and may be called a second time if + * we fall back from MSI-X to MSI Interrupt Mode. + */ +static void size_nports_qsets(struct adapter *adapter) +{ + struct vf_resources *vfres = &adapter->params.vfres; + unsigned int ethqsets, pmask_nports; + + /* The number of "ports" which we support is equal to the number of +* Virtual Interfaces with which we've been provisioned. +*/ + adapter->params.nports = vfres->nvi; + if (adapter->params.nports > MAX_NPORTS) { + dev_warn(adapter->pdev_dev, "only using %d of %d maximum" +" allowed virtual interfaces\n", MAX_NPORTS, +adapter->params.nports); + adapter->params.nports = MAX_NPORTS; + } + + /* We may have been provisioned with more VIs than the number of +* ports we're allowed to access (our Port Access Rights Mask). +* This is obviously a configuration conflict but we don't want to +* crash the kernel or anything silly just because of that. +*/ + pmask_nports = hweight32(adapter->params.vfres.pmask); + if (pmask_nports < adapter->params.nports) { + dev_warn(adapter->pdev_dev, "only using %d of %d provissioned" +" virtual interfaces; limited by Port Access Rights" +" mask %#x\n", pmask_nports, adapter->params.nports, +adapter->params.vfres.pmask); + adapter->params.nports = pmask_nports; + } + + /* We need to reserve an Ingress Queue for the Asynchronous Firmware +* Event Queue. And if we're using MSI Interrupts, we'll also need to +* reserve an Ingress Queue for a Forwarded Interrupts. +* +* The rest of the FL/Intr-capable ingress queues will be matched up +* one-for-one with Ethernet/Control egress queues in order to form +* "Queue Sets" which will be aportioned between the "ports". For +* each Queue Set, we'll need the ability to allocate two Egress +* Contexts -- one for the Ingress Queue Free List and one for the TX +* Ethernet Queue. +* +* Note that even if we're currently configured to use MSI-X +* Interrupts (module variable msi == MSI_MSIX) we may get downgraded +* to MSI Interrupts if we can't get enough MSI-X Interrupts. If that +* happens we'll need to adjust things later. +*/ + ethqsets = vfres->niqflint - 1 - (msi == MSI_MSI); + if (vfres->nethctrl != ethqsets) + ethqsets = min(vfres->nethctrl, ethqsets); + if (vfres->neq < ethqsets*2) + ethqsets = vfres->neq/2; + if (ethqsets > MAX_ETH_QSETS) + ethqsets = MAX_ETH_QSETS; + adapter->sge.max_ethqsets = ethqsets; + + if (adapter->sge.max_ethqsets < adapter->params.nports) { + dev_warn(adapter->pdev_dev, "only using %d of %d available" +" virtual interfaces (too few Queue Sets)\n", +adapter->sge.max_ethqsets, adapter->params.nports); + adapter->params.nports = adapter->sge.max_ethqsets; + } +} + /* * Perform early "adapter" initialization. This is where we discover what * adapter parameters we're going to be using and initialize basic adapter @@ -2183,10 +2250,8 @@ static void cleanup_debugfs(struct adapter *adapter) */ static int adap_init0(struct adapter *adapter) { - struct vf_resources *vfres = &adapter->params.vfres; struct sge_params *sge_params = &adapter->params.sge; struct sge *s = &adapter->sge; - uns
[PATCH net-next 4/4] cxgb4vf: Set number of queues in pci probe only
Signed-off-by: Hariprasad Shenai --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 5a3b883..1cc8a7a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -790,10 +790,6 @@ static int cxgb4vf_open(struct net_device *dev) /* * Note that this interface is up and start everything up ... */ - netif_set_real_num_tx_queues(dev, pi->nqsets); - err = netif_set_real_num_rx_queues(dev, pi->nqsets); - if (err) - goto err_unwind; err = link_start(dev); if (err) goto err_unwind; @@ -2831,10 +2827,14 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, * must register at least one net device. */ for_each_port(adapter, pidx) { + struct port_info *pi = netdev_priv(adapter->port[pidx]); netdev = adapter->port[pidx]; if (netdev == NULL) continue; + netif_set_real_num_tx_queues(netdev, pi->nqsets); + netif_set_real_num_rx_queues(netdev, pi->nqsets); + err = register_netdev(netdev); if (err) { dev_warn(&pdev->dev, "cannot register net device %s," -- 1.7.3
[PATCH net-next 3/4] cxgb4vf: Add a couple more checks for invalid provisioning configurations
Signed-off-by: Hariprasad Shenai --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 17a3153..5a3b883 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2361,6 +2361,11 @@ static int adap_init0(struct adapter *adapter) } /* Check for various parameter sanity issues */ + if (adapter->params.vfres.pmask == 0) { + dev_err(adapter->pdev_dev, "no port access configured\n" + "usable!\n"); + return -EINVAL; + } if (adapter->params.vfres.nvi == 0) { dev_err(adapter->pdev_dev, "no virtual interfaces configured/" "usable!\n"); -- 1.7.3
[PATCH net-next 1/4] cxgb4vf: Enable interrupts before we register our network devices
This avoids a race condition where a system that has network devices set up to be automatically configured and we get the first Port Link Status message from the firmware on the Asynchronous Firmware Event Queue before we've enabled interrupts. If that happens, we end up losing the interrupt and never realizing that the links has actually come up. Signed-off-by: Hariprasad Shenai --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 51 ++-- 1 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 91857b8..fcafe34 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2771,6 +2771,24 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, } } + /* See what interrupts we'll be using. If we've been configured to +* use MSI-X interrupts, try to enable them but fall back to using +* MSI interrupts if we can't enable MSI-X interrupts. If we can't +* get MSI interrupts we bail with the error. +*/ + if (msi == MSI_MSIX && enable_msix(adapter) == 0) + adapter->flags |= USING_MSIX; + else { + err = pci_enable_msi(pdev); + if (err) { + dev_err(&pdev->dev, "Unable to allocate %s interrupts;" + " err=%d\n", + msi == MSI_MSIX ? "MSI-X or MSI" : "MSI", err); + goto err_free_dev; + } + adapter->flags |= USING_MSI; + } + /* * The "card" is now ready to go. If any errors occur during device * registration we do not fail the whole "card" but rather proceed @@ -2793,7 +2811,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, } if (adapter->registered_device_map == 0) { dev_err(&pdev->dev, "could not register any net devices\n"); - goto err_free_dev; + goto err_disable_interrupts; } /* @@ -2811,25 +2829,6 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, } /* -* See what interrupts we'll be using. If we've been configured to -* use MSI-X interrupts, try to enable them but fall back to using -* MSI interrupts if we can't enable MSI-X interrupts. If we can't -* get MSI interrupts we bail with the error. -*/ - if (msi == MSI_MSIX && enable_msix(adapter) == 0) - adapter->flags |= USING_MSIX; - else { - err = pci_enable_msi(pdev); - if (err) { - dev_err(&pdev->dev, "Unable to allocate %s interrupts;" - " err=%d\n", - msi == MSI_MSIX ? "MSI-X or MSI" : "MSI", err); - goto err_free_debugfs; - } - adapter->flags |= USING_MSI; - } - - /* * Now that we know how many "ports" we have and what their types are, * and how many Queue Sets we can support, we can configure our queue * resources. @@ -2856,11 +2855,13 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, * Error recovery and exit code. Unwind state that's been created * so far and return the error. */ - -err_free_debugfs: - if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { - cleanup_debugfs(adapter); - debugfs_remove_recursive(adapter->debugfs_root); +err_disable_interrupts: + if (adapter->flags & USING_MSIX) { + pci_disable_msix(adapter->pdev); + adapter->flags &= ~USING_MSIX; + } else if (adapter->flags & USING_MSI) { + pci_disable_msi(adapter->pdev); + adapter->flags &= ~USING_MSI; } err_free_dev: -- 1.7.3
[PATCH net-next 3/5] cxgb4vf: Make sge init code more readable
Adds a new function t4vf_fl_pkt_align() and use the same in SGE initialization code to find out freelist packet alignment Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 40 ++-- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 1 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 55 ++ 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index ba6a4e3471f0..1ccd282949a5 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -2618,7 +2618,6 @@ int t4vf_sge_init(struct adapter *adapter) u32 fl0 = sge_params->sge_fl_buffer_size[0]; u32 fl1 = sge_params->sge_fl_buffer_size[1]; struct sge *s = &adapter->sge; - unsigned int ingpadboundary, ingpackboundary, ingpad_shift; /* * Start by vetting the basic SGE parameters which have been set up by @@ -2630,7 +2629,8 @@ int t4vf_sge_init(struct adapter *adapter) fl0, fl1); return -EINVAL; } - if ((sge_params->sge_control & RXPKTCPLMODE_F) == 0) { + if ((sge_params->sge_control & RXPKTCPLMODE_F) != + RXPKTCPLMODE_V(RXPKTCPLMODE_SPLIT_X)) { dev_err(adapter->pdev_dev, "bad SGE CPL MODE\n"); return -EINVAL; } @@ -2643,41 +2643,7 @@ int t4vf_sge_init(struct adapter *adapter) s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_F) ? 128 : 64); s->pktshift = PKTSHIFT_G(sge_params->sge_control); - - /* T4 uses a single control field to specify both the PCIe Padding and -* Packing Boundary. T5 introduced the ability to specify these -* separately. The actual Ingress Packet Data alignment boundary -* within Packed Buffer Mode is the maximum of these two -* specifications. (Note that it makes no real practical sense to -* have the Pading Boudary be larger than the Packing Boundary but you -* could set the chip up that way and, in fact, legacy T4 code would -* end doing this because it would initialize the Padding Boundary and -* leave the Packing Boundary initialized to 0 (16 bytes).) -* Padding Boundary values in T6 starts from 8B, -* where as it is 32B for T4 and T5. -*/ - if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) - ingpad_shift = INGPADBOUNDARY_SHIFT_X; - else - ingpad_shift = T6_INGPADBOUNDARY_SHIFT_X; - - ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_params->sge_control) + - ingpad_shift); - if (is_t4(adapter->params.chip)) { - s->fl_align = ingpadboundary; - } else { - /* T5 has a different interpretation of one of the PCIe Packing -* Boundary values. -*/ - ingpackboundary = INGPACKBOUNDARY_G(sge_params->sge_control2); - if (ingpackboundary == INGPACKBOUNDARY_16B_X) - ingpackboundary = 16; - else - ingpackboundary = 1 << (ingpackboundary + - INGPACKBOUNDARY_SHIFT_X); - - s->fl_align = max(ingpadboundary, ingpackboundary); - } + s->fl_align = t4vf_fl_pkt_align(adapter); /* A FL with <= fl_starve_thres buffers is starving and a periodic * timer will attempt to refill it. This needs to be larger than the diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 6ce302fe1a61..9b40a85cc1e4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -309,6 +309,7 @@ int t4vf_port_init(struct adapter *, int); int t4vf_fw_reset(struct adapter *); int t4vf_set_params(struct adapter *, unsigned int, const u32 *, const u32 *); +int t4vf_fl_pkt_align(struct adapter *adapter); enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS }; int t4vf_bar2_sge_qregs(struct adapter *adapter, unsigned int qid, diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 54220117dcba..fed83d88fc4e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -418,6 +418,61 @@ int t4vf_set_params(struct adapter *adapter, unsigned int nparams, } /** + * t4vf_fl_pkt_align - return the fl packet alignment + * @adapter: the adapter + * + * T4 has a single field to specify the packing and padding boundary. + * T5 onwards has separate fields f
[PATCH net-next 5/5] cxgb4vf: Remove dead functions collect_netdev_[um]c_list_addrs
Signed-off-by: Hariprasad Shenai --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 46 -- 1 file changed, 46 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 5d989e4c42dc..91857b81009e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -862,52 +862,6 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev) return ns; } -/* - * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting - * at a specified offset within the list, into an array of addrss pointers and - * return the number collected. - */ -static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev, - const u8 **addr, - unsigned int offset, - unsigned int maxaddrs) -{ - unsigned int index = 0; - unsigned int naddr = 0; - const struct netdev_hw_addr *ha; - - for_each_dev_addr(dev, ha) - if (index++ >= offset) { - addr[naddr++] = ha->addr; - if (naddr >= maxaddrs) - break; - } - return naddr; -} - -/* - * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting - * at a specified offset within the list, into an array of addrss pointers and - * return the number collected. - */ -static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev, - const u8 **addr, - unsigned int offset, - unsigned int maxaddrs) -{ - unsigned int index = 0; - unsigned int naddr = 0; - const struct netdev_hw_addr *ha; - - netdev_for_each_mc_addr(ha, dev) - if (index++ >= offset) { - addr[naddr++] = ha->addr; - if (naddr >= maxaddrs) - break; - } - return naddr; -} - static inline int cxgb4vf_set_addr_hash(struct port_info *pi) { struct adapter *adapter = pi->adapter; -- 2.3.4
[PATCH net-next 2/5] cxgb4/cxgb4vf: For T6 adapter, set FBMIN to 64 bytes
T4 and T5 hardware will not coalesce Free List PCI-E Fetch Requests if the Host Driver provides more Free List Pointers than the Fetch Burst Minimum value. So if we set FBMIN to 64 bytes and the Host Driver supplies 128 bytes of Free List Pointer data, the hardware will issue two 64-byte PCI-E Fetch Requests rather than a single coallesced 128-byte Fetch Request. T6 fixes this. So, for T4/T5 we set the FBMIN value to 128 Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 12 +++- drivers/net/ethernet/chelsio/cxgb4/t4_values.h | 1 + drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 13 - 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 22d972030927..deca4a2956cc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -2611,8 +2611,18 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, htonl(FW_IQ_CMD_FL0CNGCHMAP_V(cong) | FW_IQ_CMD_FL0CONGCIF_F | FW_IQ_CMD_FL0CONGEN_F); + /* In T6, for egress queue type FL there is internal overhead +* of 16B for header going into FLM module. Hence the maximum +* allowed burst size is 448 bytes. For T4/T5, the hardware +* doesn't coalesce fetch requests if more than 64 bytes of +* Free List pointers are provided, so we use a 128-byte Fetch +* Burst Minimum there (T6 implements coalescing so we can use +* the smaller 64-byte value there). +*/ c.fl0dcaen_to_fl0cidxfthresh = - htons(FW_IQ_CMD_FL0FBMIN_V(FETCHBURSTMIN_64B_X) | + htons(FW_IQ_CMD_FL0FBMIN_V(chip <= CHELSIO_T5 ? + FETCHBURSTMIN_128B_X : + FETCHBURSTMIN_64B_X) | FW_IQ_CMD_FL0FBMAX_V((chip <= CHELSIO_T5) ? FETCHBURSTMAX_512B_X : FETCHBURSTMAX_256B_X)); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_values.h b/drivers/net/ethernet/chelsio/cxgb4/t4_values.h index a5231fa771db..36cf3073ca37 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_values.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_values.h @@ -65,6 +65,7 @@ #define TIMERREG_COUNTER0_X0 #define FETCHBURSTMIN_64B_X2 +#define FETCHBURSTMIN_128B_X 3 #define FETCHBURSTMAX_256B_X 2 #define FETCHBURSTMAX_512B_X 3 diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 9772aad22bca..ba6a4e3471f0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -2300,9 +2300,20 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, FW_IQ_CMD_FL0HOSTFCMODE_V(SGE_HOSTFCMODE_NONE) | FW_IQ_CMD_FL0PACKEN_F | FW_IQ_CMD_FL0PADEN_F); + + /* In T6, for egress queue type FL there is internal overhead +* of 16B for header going into FLM module. Hence the maximum +* allowed burst size is 448 bytes. For T4/T5, the hardware +* doesn't coalesce fetch requests if more than 64 bytes of +* Free List pointers are provided, so we use a 128-byte Fetch +* Burst Minimum there (T6 implements coalescing so we can use +* the smaller 64-byte value there). +*/ cmd.fl0dcaen_to_fl0cidxfthresh = cpu_to_be16( - FW_IQ_CMD_FL0FBMIN_V(SGE_FETCHBURSTMIN_64B) | + FW_IQ_CMD_FL0FBMIN_V(chip <= CHELSIO_T5 ? +FETCHBURSTMIN_128B_X : +FETCHBURSTMIN_64B_X) | FW_IQ_CMD_FL0FBMAX_V((chip <= CHELSIO_T5) ? FETCHBURSTMAX_512B_X : FETCHBURSTMAX_256B_X)); -- 2.3.4
[PATCH net-next 1/5] cxgb4/cxgb4vf: Use fl capacity to check if fl needs to be replenished
Use freelist capacity instead of freelist size while checking, if freelist needs to be refilled Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index b4eb4680a27c..22d972030927 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -2226,7 +2226,7 @@ static int process_responses(struct sge_rspq *q, int budget) budget_left--; } - if (q->offset >= 0 && rxq->fl.size - rxq->fl.avail >= 16) + if (q->offset >= 0 && fl_cap(&rxq->fl) - rxq->fl.avail >= 16) __refill_fl(q->adap, &rxq->fl); return budget - budget_left; } diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 6528231d8a59..9772aad22bca 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -1864,7 +1864,7 @@ static int process_responses(struct sge_rspq *rspq, int budget) * for new buffer pointers, refill the Free List. */ if (rspq->offset >= 0 && - rxq->fl.size - rxq->fl.avail >= 2*FL_PER_EQ_UNIT) + fl_cap(&rxq->fl) - rxq->fl.avail >= 2*FL_PER_EQ_UNIT) __refill_fl(rspq->adapter, &rxq->fl); return budget - budget_left; } -- 2.3.4
[PATCH net-next 0/5] cxgb4/cxgb4vf: Cleanup and minor fixes
Hi This series sets FBMIN to 64 bytes for Chelsio's T6 series of adapters, check to replenish fl is revised, some code cleanup in cxgb4vf sge initialization code and removes dead code. This patch series has been created against net-next tree and includes patches on cxgb4 and cxgb4vf driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (5): cxgb4/cxgb4vf: Use fl capacity to check if fl needs to be replenished cxgb4/cxgb4vf: For T6 adapter, set FBMIN to 64 bytes cxgb4vf: Make sge init code more readable cxgb4vf: Remove redundant adapter ready check during probe cxgb4vf: Remove dead functions collect_netdev_[um]c_list_addrs drivers/net/ethernet/chelsio/cxgb4/sge.c | 14 +- drivers/net/ethernet/chelsio/cxgb4/t4_values.h | 1 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 56 -- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 55 +++-- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 1 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 55 + 6 files changed, 85 insertions(+), 97 deletions(-) -- 2.3.4
[PATCH net-next 4/5] cxgb4vf: Remove redundant adapter ready check during probe
Function t4vf_wait_dev_ready() is already called in t4vf_prep_adapter(), no need to call it again in adap_init0(). Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 8337514ababb..5d989e4c42dc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2237,16 +2237,6 @@ static int adap_init0(struct adapter *adapter) u32 param, val = 0; /* -* Wait for the device to become ready before proceeding ... -*/ - err = t4vf_wait_dev_ready(adapter); - if (err) { - dev_err(adapter->pdev_dev, "device didn't become ready:" - " err=%d\n", err); - return err; - } - - /* * Some environments do not properly handle PCIE FLRs -- e.g. in Linux * 2.6.31 and later we can't call pci_reset_function() in order to * issue an FLR because of a self- deadlock on the device semaphore. -- 2.3.4
[PATCH net-next 0/2] cxgb4: Use __dev_[um]c_[un]sync for MAC address syncing
Hi This patch series adds support to use __dev_uc_sync/__dev_mc_sync to add MAC address and __dev_uc_unsync/__dev_mc_unsync to delete MAC address. This patch series has been created against net-next tree and includes patches on cxgb4 and cxgb4vf driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (2): cxgb4: Use __dev_uc_sync/__dev_mc_sync to sync MAC address cxgb4vf: Use __dev_uc_sync/__dev_mc_sync to sync MAC address drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 27 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 138 - drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 92 +++--- drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 8 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 116 ++--- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 20 +++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 88 ++--- 7 files changed, 355 insertions(+), 134 deletions(-) -- 2.3.4
[PATCH net-next 2/2] cxgb4vf: Use __dev_uc_sync/__dev_mc_sync to sync MAC address
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 8 ++ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 116 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 20 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 88 +--- 4 files changed, 171 insertions(+), 61 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index 6049f70e110c..4a707c32d76f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h @@ -348,6 +348,11 @@ struct sge { #define for_each_ethrxq(sge, iter) \ for (iter = 0; iter < (sge)->ethqsets; iter++) +struct hash_mac_addr { + struct list_head list; + u8 addr[ETH_ALEN]; +}; + /* * Per-"adapter" (Virtual Function) information. */ @@ -381,6 +386,9 @@ struct adapter { /* various locks */ spinlock_t stats_lock; + + /* list of MAC addresses in MPS Hash */ + struct list_head mac_hlist; }; enum { /* adapter flags */ diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 0cfa5d72cafd..8337514ababb 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -741,6 +741,9 @@ static int adapter_up(struct adapter *adapter) */ enable_rx(adapter); t4vf_sge_start(adapter); + + /* Initialize hash mac addr list*/ + INIT_LIST_HEAD(&adapter->mac_hlist); return 0; } @@ -905,51 +908,74 @@ static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device return naddr; } -/* - * Configure the exact and hash address filters to handle a port's multicast - * and secondary unicast MAC addresses. - */ -static int set_addr_filters(const struct net_device *dev, bool sleep) +static inline int cxgb4vf_set_addr_hash(struct port_info *pi) { - u64 mhash = 0; - u64 uhash = 0; - bool free = true; - unsigned int offset, naddr; - const u8 *addr[7]; - int ret; - const struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; + u64 vec = 0; + bool ucast = false; + struct hash_mac_addr *entry; - /* first do the secondary unicast addresses */ - for (offset = 0; ; offset += naddr) { - naddr = collect_netdev_uc_list_addrs(dev, addr, offset, -ARRAY_SIZE(addr)); - if (naddr == 0) - break; + /* Calculate the hash vector for the updated list and program it */ + list_for_each_entry(entry, &adapter->mac_hlist, list) { + ucast |= is_unicast_ether_addr(entry->addr); + vec |= (1ULL << hash_mac_addr(entry->addr)); + } + return t4vf_set_addr_hash(adapter, pi->viid, ucast, vec, false); +} - ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, - naddr, addr, NULL, &uhash, sleep); - if (ret < 0) - return ret; +static int cxgb4vf_mac_sync(struct net_device *netdev, const u8 *mac_addr) +{ + struct port_info *pi = netdev_priv(netdev); + struct adapter *adapter = pi->adapter; + int ret; + u64 mhash = 0; + u64 uhash = 0; + bool free = false; + bool ucast = is_unicast_ether_addr(mac_addr); + const u8 *maclist[1] = {mac_addr}; + struct hash_mac_addr *new_entry; - free = false; + ret = t4vf_alloc_mac_filt(adapter, pi->viid, free, 1, maclist, + NULL, ucast ? &uhash : &mhash, false); + if (ret < 0) + goto out; + /* if hash != 0, then add the addr to hash addr list +* so on the end we will calculate the hash for the +* list and program it +*/ + if (uhash || mhash) { + new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC); + if (!new_entry) + return -ENOMEM; + ether_addr_copy(new_entry->addr, mac_addr); + list_add_tail(&new_entry->list, &adapter->mac_hlist); + ret = cxgb4vf_set_addr_hash(pi); } +out: + return ret < 0 ? ret : 0; +} - /* next set up the multicast addresses */ - for (offset = 0; ; offset += naddr) { - naddr = collect_netdev_mc_list_addrs(dev, addr, offset, -ARRAY_SIZE(addr)); - if (naddr == 0) - break; +static int cxgb4vf_mac_unsync(struct net_device *netdev, const u8 *mac_addr) +{ + struct port_info *pi = netdev_priv(netdev); +
[PATCH net-next 1/2] cxgb4: Use __dev_uc_sync/__dev_mc_sync to sync MAC address
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 27 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 138 ++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 92 +--- 3 files changed, 184 insertions(+), 73 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index ec6e849676c1..1dac6c6111bf 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -702,6 +702,11 @@ struct doorbell_stats { u32 db_full; }; +struct hash_mac_addr { + struct list_head list; + u8 addr[ETH_ALEN]; +}; + struct adapter { void __iomem *regs; void __iomem *bar2; @@ -740,6 +745,7 @@ struct adapter { void *uld_handle[CXGB4_ULD_MAX]; struct list_head list_node; struct list_head rcu_node; + struct list_head mac_hlist; /* list of MAC addresses in MPS Hash */ struct tid_info tids; void **tid_release_head; @@ -1207,6 +1213,24 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false); } +/** + * hash_mac_addr - return the hash value of a MAC address + * @addr: the 48-bit Ethernet MAC address + * + * Hashes a MAC address according to the hash function used by HW inexact + * (hash) address matching. + */ +static inline int hash_mac_addr(const u8 *addr) +{ + u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2]; + u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5]; + + a ^= b; + a ^= (a >> 12); + a ^= (a >> 6); + return a & 0x3f; +} + void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, unsigned int data_reg, const u32 *vals, unsigned int nregs, unsigned int start_idx); @@ -1389,6 +1413,9 @@ int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, unsigned int viid, bool free, unsigned int naddr, const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok); +int t4_free_mac_filt(struct adapter *adap, unsigned int mbox, +unsigned int viid, unsigned int naddr, +const u8 **addr, bool sleep_ok); int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, int idx, const u8 *addr, bool persist, bool add_smt); int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index b8a5fb0c32d4..adad73f7c8cd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -338,84 +338,108 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id) netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]); } +int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */ +module_param(dbfifo_int_thresh, int, 0644); +MODULE_PARM_DESC(dbfifo_int_thresh, "doorbell fifo interrupt threshold"); + /* - * Configure the exact and hash address filters to handle a port's multicast - * and secondary unicast MAC addresses. + * usecs to sleep while draining the dbfifo */ -static int set_addr_filters(const struct net_device *dev, bool sleep) +static int dbfifo_drain_delay = 1000; +module_param(dbfifo_drain_delay, int, 0644); +MODULE_PARM_DESC(dbfifo_drain_delay, +"usecs to sleep while draining the dbfifo"); + +static inline int cxgb4_set_addr_hash(struct port_info *pi) { + struct adapter *adap = pi->adapter; + u64 vec = 0; + bool ucast = false; + struct hash_mac_addr *entry; + + /* Calculate the hash vector for the updated list and program it */ + list_for_each_entry(entry, &adap->mac_hlist, list) { + ucast |= is_unicast_ether_addr(entry->addr); + vec |= (1ULL << hash_mac_addr(entry->addr)); + } + return t4_set_addr_hash(adap, adap->mbox, pi->viid, ucast, + vec, false); +} + +static int cxgb4_mac_sync(struct net_device *netdev, const u8 *mac_addr) +{ + struct port_info *pi = netdev_priv(netdev); + struct adapter *adap = pi->adapter; + int ret; u64 mhash = 0; u64 uhash = 0; - bool free = true; - u16 filt_idx[7]; - const u8 *addr[7]; - int ret, naddr = 0; - const struct netdev_hw_addr *ha; - int uc_cnt = netdev_uc_count(dev); - int mc_cnt = netdev_mc_count(dev); - const struct port_info *pi = netdev_priv(dev); - unsigned int mb = pi-&g
[PATCH] cxgb4: Add pci device id for chelsio t540 lom adapter
Signed-off-by: Hariprasad Shenai --- drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h | 1 + 1 file changed, 1 insertion(+) 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 a8dda635456d..06bc2d2e7a73 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -165,6 +165,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN CH_PCI_ID_TABLE_FENTRY(0x5098), /* Custom 2x40G QSFP */ CH_PCI_ID_TABLE_FENTRY(0x5099), /* Custom 2x40G QSFP */ CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */ + CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */ /* T6 adapters: */ -- 2.3.4
[PATCH for-next 3/3] cxgb4/iw_cxgb4: TOS support
This series provides support for iWARP applications to specify a TOS value and have that map to a VLAN Priority for iw_cxgb4 iWARP connections. In iw_cxgb4, when allocating an L2T entry, pass the skb_priority based on the tos value in the cm_id. Also pass the correct tos value during connection setup so the passive side gets the client's desired tos. When sending the FLOWC work request to FW, if the egress device is in a vlan, then use the vlan priority bits as the scheduling class. This allows associating RDMA connections with scheduling classes to provide traffic shaping per flow. Signed-off-by: Steve Wise Signed-off-by: Hariprasad Shenai --- drivers/infiniband/hw/cxgb4/cm.c | 51 ++- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 2 ++ drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 1 + 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index fe4e81b993d3..d159e168b786 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -485,12 +485,19 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) unsigned int flowclen = 80; struct fw_flowc_wr *flowc; int i; + u16 vlan = ep->l2t->vlan; + int nparams; + + if (vlan == CPL_L2T_VLAN_NONE) + nparams = 8; + else + nparams = 9; skb = get_skb(skb, flowclen, GFP_KERNEL); flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen); flowc->op_to_nparams = cpu_to_be32(FW_WR_OP_V(FW_FLOWC_WR) | - FW_FLOWC_WR_NPARAMS_V(8)); + FW_FLOWC_WR_NPARAMS_V(nparams)); flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(flowclen, 16)) | FW_WR_FLOWID_V(ep->hwtid)); @@ -511,9 +518,17 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) flowc->mnemval[6].val = cpu_to_be32(ep->snd_win); flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS; flowc->mnemval[7].val = cpu_to_be32(ep->emss); - /* Pad WR to 16 byte boundary */ - flowc->mnemval[8].mnemonic = 0; - flowc->mnemval[8].val = 0; + if (nparams == 9) { + u16 pri; + + pri = (vlan & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + flowc->mnemval[8].mnemonic = FW_FLOWC_MNEM_SCHEDCLASS; + flowc->mnemval[8].val = cpu_to_be32(pri); + } else { + /* Pad WR to 16 byte boundary */ + flowc->mnemval[8].mnemonic = 0; + flowc->mnemval[8].val = 0; + } for (i = 0; i < 9; i++) { flowc->mnemval[i].r4[0] = 0; flowc->mnemval[i].r4[1] = 0; @@ -710,7 +725,7 @@ static int send_connect(struct c4iw_ep *ep) L2T_IDX_V(ep->l2t->idx) | TX_CHAN_V(ep->tx_chan) | SMAC_SEL_V(ep->smac_idx) | - DSCP_V(ep->tos) | + DSCP_V(ep->tos >> 2) | ULP_MODE_V(ULP_MODE_TCPDDP) | RCV_BUFSIZ_V(win); opt2 = RX_CHANNEL_V(0) | @@ -1864,7 +1879,7 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) L2T_IDX_V(ep->l2t->idx) | TX_CHAN_V(ep->tx_chan) | SMAC_SEL_V(ep->smac_idx) | - DSCP_V(ep->tos) | + DSCP_V(ep->tos >> 2) | ULP_MODE_V(ULP_MODE_TCPDDP) | RCV_BUFSIZ_V(win)); req->tcb.opt2 = (__force __be32) (PACE_V(1) | @@ -1928,7 +1943,7 @@ static void set_tcp_window(struct c4iw_ep *ep, struct port_info *pi) static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, struct dst_entry *dst, struct c4iw_dev *cdev, -bool clear_mpa_v1, enum chip_type adapter_type) +bool clear_mpa_v1, enum chip_type adapter_type, u8 tos) { struct neighbour *n; int err, step; @@ -1958,7 +1973,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, goto out; } ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, - n, pdev, 0); + n, pdev, rt_tos2priority(tos)); if (!ep->l2t) goto out; ep->mtu = pdev->mtu; @@ -2041,7 +2056,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep) if (ep->com.cm_id->local_addr.ss_family == AF_INET) { ep->dst = find_route(ep->com.dev, laddr->sin_addr.s_addr, raddr->sin_addr.s_addr, laddr->sin_port, -raddr->
[PATCH for-next 0/3] Add TOS support and some cleanup
Hi, This series adds TOS support for iWARP and also does some cleanup to make code more readable. Patch series is created against infiniband tree and includes patches on iw_cxgb4 and cxgb4 driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. Thanks Hariprasad Shenai (3): iw_cxgb4: make queue allocation code more readable iw_cxgb4: remove false error log entry cxgb4/iw_cxgb4: TOS support drivers/infiniband/hw/cxgb4/cm.c | 54 +++--- drivers/infiniband/hw/cxgb4/qp.c | 81 ++- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 2 + drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 1 + 4 files changed, 80 insertions(+), 58 deletions(-) -- 2.3.4