From 900a659687aa6349e52f7b1e3f922b77afe89b90 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Fri, 18 Jun 2010 10:05:27 +0000 Subject: cxgb4: dynamically determine flash size and FW image location Handle the larger flash memories on newer boards: - get the size and number of sectors by probing the flash - writes and erases can take longer, adjust the timeouts for these operations - the FW image can be at different locations depending on flash size, find its location dynamically as well. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/cxgb4/cxgb4.h') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index dd1770e075e..bfa136622f1 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -219,6 +219,10 @@ struct adapter_params { struct vpd_params vpd; struct pci_params pci; + unsigned int sf_size; /* serial flash size in bytes */ + unsigned int sf_nsec; /* # of flash sectors */ + unsigned int sf_fw_start; /* start of FW image in flash */ + unsigned int fw_vers; unsigned int tp_vers; u8 api_vers[7]; -- cgit v1.2.3-70-g09d2 From 204dc3c0b1bea10a7d811970fd41ceabaef31267 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Fri, 18 Jun 2010 10:05:29 +0000 Subject: cxgb4: implement EEH Implement the pci_error_handlers methods for EEH. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 + drivers/net/cxgb4/cxgb4_main.c | 108 ++++++++++++++++++++++++++++++++++++++++- drivers/net/cxgb4/l2t.c | 7 +++ drivers/net/cxgb4/t4_hw.c | 11 ++++- 4 files changed, 124 insertions(+), 3 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4.h') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index bfa136622f1..5e37c1e67fe 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -650,6 +650,7 @@ void t4_intr_disable(struct adapter *adapter); void t4_intr_clear(struct adapter *adapter); int t4_slow_intr_handler(struct adapter *adapter); +int t4_wait_dev_ready(struct adapter *adap); int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc); int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port); diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 60f6ea05167..baf4f0a3136 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2483,6 +2483,7 @@ static void cxgb_down(struct adapter *adapter) t4_intr_disable(adapter); cancel_work_sync(&adapter->tid_release_task); adapter->tid_release_task_busy = false; + adapter->tid_release_head = NULL; if (adapter->flags & USING_MSIX) { free_msix_queue_irqs(adapter); @@ -2907,6 +2908,108 @@ bye: if (ret != -ETIMEDOUT && ret != -EIO) return ret; } +/* EEH callbacks */ + +static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + int i; + struct adapter *adap = pci_get_drvdata(pdev); + + if (!adap) + goto out; + + rtnl_lock(); + adap->flags &= ~FW_OK; + notify_ulds(adap, CXGB4_STATE_START_RECOVERY); + for_each_port(adap, i) { + struct net_device *dev = adap->port[i]; + + netif_device_detach(dev); + netif_carrier_off(dev); + } + if (adap->flags & FULL_INIT_DONE) + cxgb_down(adap); + rtnl_unlock(); + pci_disable_device(pdev); +out: return state == pci_channel_io_perm_failure ? + PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev) +{ + int i, ret; + struct fw_caps_config_cmd c; + struct adapter *adap = pci_get_drvdata(pdev); + + if (!adap) { + pci_restore_state(pdev); + pci_save_state(pdev); + return PCI_ERS_RESULT_RECOVERED; + } + + if (pci_enable_device(pdev)) { + dev_err(&pdev->dev, "cannot reenable PCI device after reset\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + + pci_set_master(pdev); + pci_restore_state(pdev); + pci_save_state(pdev); + pci_cleanup_aer_uncorrect_error_status(pdev); + + if (t4_wait_dev_ready(adap) < 0) + return PCI_ERS_RESULT_DISCONNECT; + if (t4_fw_hello(adap, 0, 0, MASTER_MUST, NULL)) + return PCI_ERS_RESULT_DISCONNECT; + adap->flags |= FW_OK; + if (adap_init1(adap, &c)) + return PCI_ERS_RESULT_DISCONNECT; + + for_each_port(adap, i) { + struct port_info *p = adap2pinfo(adap, i); + + ret = t4_alloc_vi(adap, 0, p->tx_chan, 0, 0, 1, NULL, NULL); + if (ret < 0) + return PCI_ERS_RESULT_DISCONNECT; + p->viid = ret; + p->xact_addr_filt = -1; + } + + t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, + adap->params.b_wnd); + if (cxgb_up(adap)) + return PCI_ERS_RESULT_DISCONNECT; + return PCI_ERS_RESULT_RECOVERED; +} + +static void eeh_resume(struct pci_dev *pdev) +{ + int i; + struct adapter *adap = pci_get_drvdata(pdev); + + if (!adap) + return; + + rtnl_lock(); + for_each_port(adap, i) { + struct net_device *dev = adap->port[i]; + + if (netif_running(dev)) { + link_start(dev); + cxgb_set_rxmode(dev); + } + netif_device_attach(dev); + } + rtnl_unlock(); +} + +static struct pci_error_handlers cxgb4_eeh = { + .error_detected = eeh_err_detected, + .slot_reset = eeh_slot_reset, + .resume = eeh_resume, +}; + static inline bool is_10g_port(const struct link_config *lc) { return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; @@ -3154,8 +3257,10 @@ static int __devinit init_one(struct pci_dev *pdev, /* We control everything through PF 0 */ func = PCI_FUNC(pdev->devfn); - if (func > 0) + if (func > 0) { + pci_save_state(pdev); /* to restore SR-IOV later */ goto sriov; + } err = pci_enable_device(pdev); if (err) { @@ -3396,6 +3501,7 @@ static struct pci_driver cxgb4_driver = { .id_table = cxgb4_pci_tbl, .probe = init_one, .remove = __devexit_p(remove_one), + .err_handler = &cxgb4_eeh, }; static int __init cxgb4_init_module(void) diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c index 9f96724a133..5b990d24cca 100644 --- a/drivers/net/cxgb4/l2t.c +++ b/drivers/net/cxgb4/l2t.c @@ -310,6 +310,13 @@ static void t4_l2e_free(struct l2t_entry *e) neigh_release(e->neigh); e->neigh = NULL; } + while (e->arpq_head) { + struct sk_buff *skb = e->arpq_head; + + e->arpq_head = skb->next; + kfree(skb); + } + e->arpq_tail = NULL; } spin_unlock_bh(&e->lock); diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index 5c81c558ce6..0c8a84a258f 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -221,6 +221,13 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, if ((size & 15) || size > MBOX_LEN) return -EINVAL; + /* + * If the device is off-line, as in EEH, commands will time out. + * Fail them early so we don't waste time waiting. + */ + if (adap->pdev->error_state != pci_channel_io_normal) + return -EIO; + v = MBOWNER_GET(t4_read_reg(adap, ctl_reg)); for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++) v = MBOWNER_GET(t4_read_reg(adap, ctl_reg)); @@ -3045,7 +3052,7 @@ static void __devinit init_link_config(struct link_config *lc, } } -static int __devinit wait_dev_ready(struct adapter *adap) +int t4_wait_dev_ready(struct adapter *adap) { if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff) return 0; @@ -3093,7 +3100,7 @@ int __devinit t4_prep_adapter(struct adapter *adapter) { int ret; - ret = wait_dev_ready(adapter); + ret = t4_wait_dev_ready(adapter); if (ret < 0) return ret; -- cgit v1.2.3-70-g09d2 From 20c0da65d72598ced2bfd4d4ca9a5aca1c93f5b9 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Fri, 18 Jun 2010 10:05:35 +0000 Subject: cxgb4: minor cleanup Remove an unused flag and replace couple constants with enums. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 - drivers/net/cxgb4/cxgb4_main.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4.h') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 5e37c1e67fe..62804bb4022 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -309,7 +309,6 @@ enum { /* adapter flags */ FULL_INIT_DONE = (1 << 0), USING_MSI = (1 << 1), USING_MSIX = (1 << 2), - QUEUES_BOUND = (1 << 3), FW_OK = (1 << 4), }; diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 352c7709012..27f65b501a0 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2758,8 +2758,8 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) if (ret < 0) return ret; - ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16, - FW_CMD_CAP_PF, FW_CMD_CAP_PF); + ret = t4_cfg_pfvf(adap, 0, 0, 0, MAX_EGRQ, 64, MAX_INGQ, 0, 0, 4, + 0xf, 0xf, 16, FW_CMD_CAP_PF, FW_CMD_CAP_PF); if (ret < 0) return ret; -- cgit v1.2.3-70-g09d2 From 671b0060d82984a566f2e75ffd166a9b61c6da7d Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Sun, 11 Jul 2010 12:01:17 +0000 Subject: cxgb4: add user manipulation of the RSS table Implement the get_rxnfc, get_rxfh_indir, and set_rxfh_indir ethtool methods for user manipulation of the RSS table. Besides the methods themselves the rest of the changes here store, initialize, and write the table contents. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 + drivers/net/cxgb4/cxgb4_main.c | 113 +++++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 16 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4.h') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 62804bb4022..a614eb5d85d 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -295,6 +295,7 @@ struct port_info { u8 nqsets; /* # of qsets */ u8 first_qset; /* index of first qset */ struct link_config link_cfg; + u16 *rss; }; /* port_info.rx_offload flags */ diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 653bb546edd..61d43130eff 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -596,31 +596,48 @@ static void free_msix_queue_irqs(struct adapter *adap) free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq); } +/** + * write_rss - write the RSS table for a given port + * @pi: the port + * @queues: array of queue indices for RSS + * + * Sets up the portion of the HW RSS table for the port's VI to distribute + * packets to the Rx queues in @queues. + */ +static int write_rss(const struct port_info *pi, const u16 *queues) +{ + u16 *rss; + int i, err; + const struct sge_eth_rxq *q = &pi->adapter->sge.ethrxq[pi->first_qset]; + + rss = kmalloc(pi->rss_size * sizeof(u16), GFP_KERNEL); + if (!rss) + return -ENOMEM; + + /* map the queue indices to queue ids */ + for (i = 0; i < pi->rss_size; i++, queues++) + rss[i] = q[*queues].rspq.abs_id; + + err = t4_config_rss_range(pi->adapter, 0, pi->viid, 0, pi->rss_size, + rss, pi->rss_size); + kfree(rss); + return err; +} + /** * setup_rss - configure RSS * @adap: the adapter * - * Sets up RSS to distribute packets to multiple receive queues. We - * configure the RSS CPU lookup table to distribute to the number of HW - * receive queues, and the response queue lookup table to narrow that - * down to the response queues actually configured for each port. - * We always configure the RSS mapping for all ports since the mapping - * table has plenty of entries. + * Sets up RSS for each port. */ static int setup_rss(struct adapter *adap) { - int i, j, err; - u16 rss[MAX_ETH_QSETS]; + int i, err; for_each_port(adap, i) { const struct port_info *pi = adap2pinfo(adap, i); - const struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; - - for (j = 0; j < pi->nqsets; j++) - rss[j] = q[j].rspq.abs_id; - err = t4_config_rss_range(adap, 0, pi->viid, 0, pi->rss_size, - rss, pi->nqsets); + err = write_rss(pi, pi->rss); if (err) return err; } @@ -1802,6 +1819,46 @@ static int set_flags(struct net_device *dev, u32 flags) return ethtool_op_set_flags(dev, flags, ETH_FLAG_RXHASH); } +static int get_rss_table(struct net_device *dev, struct ethtool_rxfh_indir *p) +{ + const struct port_info *pi = netdev_priv(dev); + unsigned int n = min_t(unsigned int, p->size, pi->rss_size); + + p->size = pi->rss_size; + while (n--) + p->ring_index[n] = pi->rss[n]; + return 0; +} + +static int set_rss_table(struct net_device *dev, + const struct ethtool_rxfh_indir *p) +{ + unsigned int i; + struct port_info *pi = netdev_priv(dev); + + if (p->size != pi->rss_size) + return -EINVAL; + for (i = 0; i < p->size; i++) + if (p->ring_index[i] >= pi->nqsets) + return -EINVAL; + for (i = 0; i < p->size; i++) + pi->rss[i] = p->ring_index[i]; + if (pi->adapter->flags & FULL_INIT_DONE) + return write_rss(pi, pi->rss); + return 0; +} + +static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, + void *rules) +{ + switch (info->cmd) { + case ETHTOOL_GRXRINGS: + info->data = netdev2pinfo(dev)->nqsets; + return 0; + } + return -EOPNOTSUPP; +} + static struct ethtool_ops cxgb_ethtool_ops = { .get_settings = get_settings, .set_settings = set_settings, @@ -1833,6 +1890,9 @@ static struct ethtool_ops cxgb_ethtool_ops = { .set_wol = set_wol, .set_tso = set_tso, .set_flags = set_flags, + .get_rxnfc = get_rxnfc, + .get_rxfh_indir = get_rss_table, + .set_rxfh_indir = set_rss_table, .flash_device = set_flash, }; @@ -3318,6 +3378,22 @@ static int __devinit enable_msix(struct adapter *adap) #undef EXTRA_VECS +static int __devinit init_rss(struct adapter *adap) +{ + unsigned int i, j; + + for_each_port(adap, i) { + struct port_info *pi = adap2pinfo(adap, i); + + pi->rss = kcalloc(pi->rss_size, sizeof(u16), GFP_KERNEL); + if (!pi->rss) + return -ENOMEM; + for (j = 0; j < pi->rss_size; j++) + pi->rss[j] = j % pi->nqsets; + } + return 0; +} + static void __devinit print_port_info(struct adapter *adap) { static const char *base[] = { @@ -3380,9 +3456,10 @@ static void free_some_resources(struct adapter *adapter) disable_msi(adapter); for_each_port(adapter, i) - if (adapter->port[i]) + if (adapter->port[i]) { + kfree(adap2pinfo(adapter, i)->rss); free_netdev(adapter->port[i]); - + } if (adapter->flags & FW_OK) t4_fw_bye(adapter, 0); } @@ -3536,6 +3613,10 @@ static int __devinit init_one(struct pci_dev *pdev, else if (msi > 0 && pci_enable_msi(pdev) == 0) adapter->flags |= USING_MSI; + err = init_rss(adapter); + if (err) + goto out_free_dev; + /* * The card is now ready to go. If any errors occur during device * registration we do not fail the whole card but rather proceed only -- cgit v1.2.3-70-g09d2 From f796564a5fd7be1a4597b66e2a516c18685641df Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Sun, 11 Jul 2010 12:01:18 +0000 Subject: cxgb4: implement the ETHTOOL_GRXFH command Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 + drivers/net/cxgb4/cxgb4_main.c | 54 +++++++++++++++++++++++++++++++++++++++++- drivers/net/cxgb4/t4_hw.c | 11 +++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) (limited to 'drivers/net/cxgb4/cxgb4.h') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index a614eb5d85d..4769c1c58e8 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -294,6 +294,7 @@ struct port_info { u8 rx_offload; /* CSO, etc */ u8 nqsets; /* # of qsets */ u8 first_qset; /* index of first qset */ + u8 rss_mode; struct link_config link_cfg; u16 *rss; }; diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 61d43130eff..110843c5fde 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -1851,9 +1851,61 @@ static int set_rss_table(struct net_device *dev, static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, void *rules) { + const struct port_info *pi = netdev_priv(dev); + switch (info->cmd) { + case ETHTOOL_GRXFH: { + unsigned int v = pi->rss_mode; + + info->data = 0; + switch (info->flow_type) { + case TCP_V4_FLOW: + if (v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case UDP_V4_FLOW: + if ((v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) && + (v & FW_RSS_VI_CONFIG_CMD_UDPEN)) + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case IPV4_FLOW: + if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + if (v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case UDP_V6_FLOW: + if ((v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) && + (v & FW_RSS_VI_CONFIG_CMD_UDPEN)) + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case IPV6_FLOW: + if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + } + return 0; + } case ETHTOOL_GRXRINGS: - info->data = netdev2pinfo(dev)->nqsets; + info->data = pi->nqsets; return 0; } return -EOPNOTSUPP; diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index 3e63d1487f5..ab46797623b 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -3133,8 +3133,10 @@ int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf) u8 addr[6]; int ret, i, j = 0; struct fw_port_cmd c; + struct fw_rss_vi_config_cmd rvc; memset(&c, 0, sizeof(c)); + memset(&rvc, 0, sizeof(rvc)); for_each_port(adap, i) { unsigned int rss_size; @@ -3171,6 +3173,15 @@ int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf) p->port_type = FW_PORT_CMD_PTYPE_GET(ret); p->mod_type = FW_PORT_MOD_TYPE_NA; + rvc.op_to_viid = htonl(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) | + FW_CMD_REQUEST | FW_CMD_READ | + FW_RSS_VI_CONFIG_CMD_VIID(p->viid)); + rvc.retval_len16 = htonl(FW_LEN16(rvc)); + ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc); + if (ret) + return ret; + p->rss_mode = ntohl(rvc.u.basicvirtual.defaultq_to_udpen); + init_link_config(&p->link_cfg, ntohs(c.u.info.pcap)); j++; } -- cgit v1.2.3-70-g09d2 From 060e0c752b5047ee691120b75df4c16743981e50 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 2 Aug 2010 13:19:21 +0000 Subject: cxgb4: support running the driver on PCI functions besides 0 Add support for running the driver on any PCI function. Mostly this entails replacing a constant 0 in a number of calls with the variable function number. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 3 +- drivers/net/cxgb4/cxgb4_main.c | 128 +++++++++++++++++++++++------------------ drivers/net/cxgb4/sge.c | 38 +++++++----- 3 files changed, 97 insertions(+), 72 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4.h') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 4769c1c58e8..6e562c0dad7 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -482,7 +482,8 @@ struct adapter { struct pci_dev *pdev; struct device *pdev_dev; unsigned long registered_device_map; - unsigned long flags; + unsigned int fn; + unsigned int flags; const char *name; int msg_enable; diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index e80d4a5e9fa..5d5ea822731 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -171,10 +171,10 @@ enum { NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) -#define CH_DEVICE(devid) { PCI_VDEVICE(CHELSIO, devid), 0 } +#define CH_DEVICE(devid, data) { PCI_VDEVICE(CHELSIO, devid), (data) } static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { - CH_DEVICE(0xa000), /* PE10K */ + CH_DEVICE(0xa000, 0), /* PE10K */ { 0, } }; @@ -314,12 +314,13 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) 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->adapter->fn; /* first do the secondary unicast addresses */ netdev_for_each_uc_addr(ha, dev) { addr[naddr++] = ha->addr; if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { - ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free, + ret = t4_alloc_mac_filt(pi->adapter, mb, pi->viid, free, naddr, addr, filt_idx, &uhash, sleep); if (ret < 0) return ret; @@ -333,7 +334,7 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) netdev_for_each_mc_addr(ha, dev) { addr[naddr++] = ha->addr; if (--mc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { - ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free, + ret = t4_alloc_mac_filt(pi->adapter, mb, pi->viid, free, naddr, addr, filt_idx, &mhash, sleep); if (ret < 0) return ret; @@ -343,7 +344,7 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) } } - return t4_set_addr_hash(pi->adapter, 0, pi->viid, uhash != 0, + return t4_set_addr_hash(pi->adapter, mb, pi->viid, uhash != 0, uhash | mhash, sleep); } @@ -358,7 +359,7 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) ret = set_addr_filters(dev, sleep_ok); if (ret == 0) - ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu, + ret = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, mtu, (dev->flags & IFF_PROMISC) ? 1 : 0, (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, -1, sleep_ok); @@ -375,15 +376,16 @@ static int link_start(struct net_device *dev) { int ret; struct port_info *pi = netdev_priv(dev); + unsigned int mb = pi->adapter->fn; /* * We do not set address filters and promiscuity here, the stack does * that step explicitly. */ - ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1, + ret = t4_set_rxmode(pi->adapter, mb, pi->viid, dev->mtu, -1, -1, -1, pi->vlan_grp != NULL, true); if (ret == 0) { - ret = t4_change_mac(pi->adapter, 0, pi->viid, + ret = t4_change_mac(pi->adapter, mb, pi->viid, pi->xact_addr_filt, dev->dev_addr, true, true); if (ret >= 0) { @@ -392,9 +394,10 @@ static int link_start(struct net_device *dev) } } if (ret == 0) - ret = t4_link_start(pi->adapter, 0, pi->tx_chan, &pi->link_cfg); + ret = t4_link_start(pi->adapter, mb, pi->tx_chan, + &pi->link_cfg); if (ret == 0) - ret = t4_enable_vi(pi->adapter, 0, pi->viid, true, true); + ret = t4_enable_vi(pi->adapter, mb, pi->viid, true, true); return ret; } @@ -618,8 +621,8 @@ static int write_rss(const struct port_info *pi, const u16 *queues) for (i = 0; i < pi->rss_size; i++, queues++) rss[i] = q[*queues].rspq.abs_id; - err = t4_config_rss_range(pi->adapter, 0, pi->viid, 0, pi->rss_size, - rss, pi->rss_size); + err = t4_config_rss_range(pi->adapter, pi->adapter->fn, pi->viid, 0, + pi->rss_size, rss, pi->rss_size); kfree(rss); return err; } @@ -1307,16 +1310,18 @@ static int restart_autoneg(struct net_device *dev) return -EAGAIN; if (p->link_cfg.autoneg != AUTONEG_ENABLE) return -EINVAL; - t4_restart_aneg(p->adapter, 0, p->tx_chan); + t4_restart_aneg(p->adapter, p->adapter->fn, p->tx_chan); return 0; } static int identify_port(struct net_device *dev, u32 data) { + struct adapter *adap = netdev2adap(dev); + if (data == 0) data = 2; /* default to 2 seconds */ - return t4_identify_port(netdev2adap(dev), 0, netdev2pinfo(dev)->viid, + return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, data * 5); } @@ -1456,7 +1461,8 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) lc->autoneg = cmd->autoneg; if (netif_running(dev)) - return t4_link_start(p->adapter, 0, p->tx_chan, lc); + return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, + lc); return 0; } @@ -1488,7 +1494,8 @@ static int set_pauseparam(struct net_device *dev, if (epause->tx_pause) lc->requested_fc |= PAUSE_TX; if (netif_running(dev)) - return t4_link_start(p->adapter, 0, p->tx_chan, lc); + return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, + lc); return 0; } @@ -1620,7 +1627,8 @@ static int set_rxq_intr_params(struct adapter *adap, struct sge_rspq *q, v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) | FW_PARAMS_PARAM_YZ(q->cntxt_id); - err = t4_set_params(adap, 0, 0, 0, 1, &v, &new_idx); + err = t4_set_params(adap, adap->fn, adap->fn, 0, 1, &v, + &new_idx); if (err) return err; } @@ -2496,9 +2504,11 @@ static void uld_attach(struct adapter *adap, unsigned int uld) lli.adapter_type = adap->params.rev; lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2)); lli.udb_density = 1 << QUEUESPERPAGEPF0_GET( - t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF)); + t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >> + (adap->fn * 4)); lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( - t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF)); + t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >> + (adap->fn * 4)); lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); lli.fw_vers = adap->params.fw_vers; @@ -2715,7 +2725,7 @@ static int cxgb_close(struct net_device *dev) netif_tx_stop_all_queues(dev); netif_carrier_off(dev); - return t4_enable_vi(adapter, 0, pi->viid, false, false); + return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false); } static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, @@ -2762,6 +2772,7 @@ static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { + unsigned int mbox; int ret = 0, prtad, devad; struct port_info *pi = netdev_priv(dev); struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data; @@ -2784,11 +2795,12 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) } else return -EINVAL; + mbox = pi->adapter->fn; if (cmd == SIOCGMIIREG) - ret = t4_mdio_rd(pi->adapter, 0, prtad, devad, + ret = t4_mdio_rd(pi->adapter, mbox, prtad, devad, data->reg_num, &data->val_out); else - ret = t4_mdio_wr(pi->adapter, 0, prtad, devad, + ret = t4_mdio_wr(pi->adapter, mbox, prtad, devad, data->reg_num, data->val_in); break; default: @@ -2810,8 +2822,8 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */ return -EINVAL; - ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1, -1, - true); + ret = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, new_mtu, -1, + -1, -1, -1, true); if (!ret) dev->mtu = new_mtu; return ret; @@ -2826,8 +2838,8 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; - ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt, - addr->sa_data, true, true); + ret = t4_change_mac(pi->adapter, pi->adapter->fn, pi->viid, + pi->xact_addr_filt, addr->sa_data, true, true); if (ret < 0) return ret; @@ -2841,8 +2853,8 @@ static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) struct port_info *pi = netdev_priv(dev); pi->vlan_grp = grp; - t4_set_rxmode(pi->adapter, 0, pi->viid, -1, -1, -1, -1, grp != NULL, - true); + t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1, -1, -1, -1, + grp != NULL, true); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -2926,7 +2938,7 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | FW_CMD_REQUEST | FW_CMD_READ); c->retval_len16 = htonl(FW_LEN16(*c)); - ret = t4_wr_mbox(adap, 0, c, sizeof(*c), c); + ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), c); if (ret < 0) return ret; @@ -2942,36 +2954,33 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) } c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | FW_CMD_REQUEST | FW_CMD_WRITE); - ret = t4_wr_mbox(adap, 0, c, sizeof(*c), NULL); + ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), NULL); if (ret < 0) return ret; - ret = t4_config_glbl_rss(adap, 0, + ret = t4_config_glbl_rss(adap, adap->fn, FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL, FW_RSS_GLB_CONFIG_CMD_TNLMAPEN | FW_RSS_GLB_CONFIG_CMD_TNLALLLKP); if (ret < 0) return ret; - ret = t4_cfg_pfvf(adap, 0, 0, 0, MAX_EGRQ, 64, MAX_INGQ, 0, 0, 4, - 0xf, 0xf, 16, FW_CMD_CAP_PF, FW_CMD_CAP_PF); + ret = t4_cfg_pfvf(adap, adap->fn, adap->fn, 0, MAX_EGRQ, 64, MAX_INGQ, + 0, 0, 4, 0xf, 0xf, 16, FW_CMD_CAP_PF, FW_CMD_CAP_PF); if (ret < 0) return ret; t4_sge_init(adap); - /* get basic stuff going */ - ret = t4_early_init(adap, 0); - if (ret < 0) - return ret; - /* tweak some settings */ t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849); t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12)); t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG); v = t4_read_reg(adap, TP_PIO_DATA); t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR); - return 0; + + /* get basic stuff going */ + return t4_early_init(adap, adap->fn); } /* @@ -2999,7 +3008,7 @@ static int adap_init0(struct adapter *adap) return ret; /* contact FW, request master */ - ret = t4_fw_hello(adap, 0, 0, MASTER_MUST, &state); + ret = t4_fw_hello(adap, adap->fn, adap->fn, MASTER_MUST, &state); if (ret < 0) { dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", ret); @@ -3007,7 +3016,7 @@ static int adap_init0(struct adapter *adap) } /* reset device */ - ret = t4_fw_reset(adap, 0, PIORSTMODE | PIORST); + ret = t4_fw_reset(adap, adap->fn, PIORSTMODE | PIORST); if (ret < 0) goto bye; @@ -3023,7 +3032,7 @@ static int adap_init0(struct adapter *adap) FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) params[0] = FW_PARAM_DEV(CCLK); - ret = t4_query_params(adap, 0, 0, 0, 1, params, val); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 1, params, val); if (ret < 0) goto bye; adap->params.vpd.cclk = val[0]; @@ -3034,14 +3043,15 @@ static int adap_init0(struct adapter *adap) #define FW_PARAM_PFVF(param) \ (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param)) + FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param) | \ + FW_PARAMS_PARAM_Y(adap->fn)) params[0] = FW_PARAM_DEV(PORTVEC); params[1] = FW_PARAM_PFVF(L2T_START); params[2] = FW_PARAM_PFVF(L2T_END); params[3] = FW_PARAM_PFVF(FILTER_START); params[4] = FW_PARAM_PFVF(FILTER_END); - ret = t4_query_params(adap, 0, 0, 0, 5, params, val); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 5, params, val); if (ret < 0) goto bye; port_vec = val[0]; @@ -3056,7 +3066,8 @@ static int adap_init0(struct adapter *adap) params[3] = FW_PARAM_PFVF(TDDP_START); params[4] = FW_PARAM_PFVF(TDDP_END); params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); - ret = t4_query_params(adap, 0, 0, 0, 6, params, val); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, + val); if (ret < 0) goto bye; adap->tids.ntids = val[0]; @@ -3075,7 +3086,8 @@ static int adap_init0(struct adapter *adap) params[3] = FW_PARAM_PFVF(RQ_END); params[4] = FW_PARAM_PFVF(PBL_START); params[5] = FW_PARAM_PFVF(PBL_END); - ret = t4_query_params(adap, 0, 0, 0, 6, params, val); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, + val); if (ret < 0) goto bye; adap->vres.stag.start = val[0]; @@ -3091,7 +3103,8 @@ static int adap_init0(struct adapter *adap) params[3] = FW_PARAM_PFVF(CQ_END); params[4] = FW_PARAM_PFVF(OCQ_START); params[5] = FW_PARAM_PFVF(OCQ_END); - ret = t4_query_params(adap, 0, 0, 0, 6, params, val); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, + val); if (ret < 0) goto bye; adap->vres.qp.start = val[0]; @@ -3104,7 +3117,8 @@ static int adap_init0(struct adapter *adap) if (c.iscsicaps) { params[0] = FW_PARAM_PFVF(ISCSI_START); params[1] = FW_PARAM_PFVF(ISCSI_END); - ret = t4_query_params(adap, 0, 0, 0, 2, params, val); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 2, params, + val); if (ret < 0) goto bye; adap->vres.iscsi.start = val[0]; @@ -3142,7 +3156,7 @@ static int adap_init0(struct adapter *adap) /* VF numbering starts at 1! */ for (vf = 1; vf <= num_vf[pf]; vf++) { - ret = t4_cfg_pfvf(adap, 0, pf, vf, + ret = t4_cfg_pfvf(adap, adap->fn, pf, vf, VFRES_NEQ, VFRES_NETHCTRL, VFRES_NIQFLINT, VFRES_NIQ, VFRES_TC, VFRES_NVI, @@ -3168,7 +3182,7 @@ static int adap_init0(struct adapter *adap) * commands. */ bye: if (ret != -ETIMEDOUT && ret != -EIO) - t4_fw_bye(adap, 0); + t4_fw_bye(adap, adap->fn); return ret; } @@ -3224,7 +3238,7 @@ static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev) if (t4_wait_dev_ready(adap) < 0) return PCI_ERS_RESULT_DISCONNECT; - if (t4_fw_hello(adap, 0, 0, MASTER_MUST, NULL)) + if (t4_fw_hello(adap, adap->fn, adap->fn, MASTER_MUST, NULL)) return PCI_ERS_RESULT_DISCONNECT; adap->flags |= FW_OK; if (adap_init1(adap, &c)) @@ -3233,7 +3247,8 @@ static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev) for_each_port(adap, i) { struct port_info *p = adap2pinfo(adap, i); - ret = t4_alloc_vi(adap, 0, p->tx_chan, 0, 0, 1, NULL, NULL); + ret = t4_alloc_vi(adap, adap->fn, p->tx_chan, adap->fn, 0, 1, + NULL, NULL); if (ret < 0) return PCI_ERS_RESULT_DISCONNECT; p->viid = ret; @@ -3538,7 +3553,7 @@ static void free_some_resources(struct adapter *adapter) free_netdev(adapter->port[i]); } if (adapter->flags & FW_OK) - t4_fw_bye(adapter, 0); + t4_fw_bye(adapter, adapter->fn); } #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ @@ -3561,9 +3576,9 @@ static int __devinit init_one(struct pci_dev *pdev, return err; } - /* We control everything through PF 0 */ + /* We control everything through one PF */ func = PCI_FUNC(pdev->devfn); - if (func > 0) { + if (func != ent->driver_data) { pci_save_state(pdev); /* to restore SR-IOV later */ goto sriov; } @@ -3609,6 +3624,7 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->pdev = pdev; adapter->pdev_dev = &pdev->dev; + adapter->fn = func; adapter->name = pci_name(pdev); adapter->msg_enable = dflt_msg_enable; memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); @@ -3660,7 +3676,7 @@ static int __devinit init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, adapter); if (adapter->flags & FW_OK) { - err = t4_port_init(adapter, 0, 0, 0); + err = t4_port_init(adapter, func, func, 0); if (err) goto out_free_dev; } diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 5cacfc7c53a..bf38cfc5756 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -1999,7 +1999,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | FW_CMD_WRITE | FW_CMD_EXEC | - FW_IQ_CMD_PFN(0) | FW_IQ_CMD_VFN(0)); + FW_IQ_CMD_PFN(adap->fn) | FW_IQ_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) | FW_LEN16(c)); c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) | @@ -2031,7 +2031,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, c.fl0addr = cpu_to_be64(fl->addr); } - ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); + ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); if (ret) goto err; @@ -2110,7 +2110,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST | FW_CMD_WRITE | FW_CMD_EXEC | - FW_EQ_ETH_CMD_PFN(0) | FW_EQ_ETH_CMD_VFN(0)); + FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); @@ -2123,7 +2123,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, FW_EQ_ETH_CMD_EQSIZE(nentries)); c.eqaddr = cpu_to_be64(txq->q.phys_addr); - ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); + ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); if (ret) { kfree(txq->q.sdesc); txq->q.sdesc = NULL; @@ -2160,7 +2160,8 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST | FW_CMD_WRITE | FW_CMD_EXEC | - FW_EQ_CTRL_CMD_PFN(0) | FW_EQ_CTRL_CMD_VFN(0)); + FW_EQ_CTRL_CMD_PFN(adap->fn) | + FW_EQ_CTRL_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC | FW_EQ_CTRL_CMD_EQSTART | FW_LEN16(c)); c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID(cmplqid)); @@ -2174,7 +2175,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, FW_EQ_CTRL_CMD_EQSIZE(nentries)); c.eqaddr = cpu_to_be64(txq->q.phys_addr); - ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); + ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); if (ret) { dma_free_coherent(adap->pdev_dev, nentries * sizeof(struct tx_desc), @@ -2210,7 +2211,8 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST | FW_CMD_WRITE | FW_CMD_EXEC | - FW_EQ_OFLD_CMD_PFN(0) | FW_EQ_OFLD_CMD_VFN(0)); + FW_EQ_OFLD_CMD_PFN(adap->fn) | + FW_EQ_OFLD_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC | FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c)); c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) | @@ -2222,7 +2224,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, FW_EQ_OFLD_CMD_EQSIZE(nentries)); c.eqaddr = cpu_to_be64(txq->q.phys_addr); - ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); + ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); if (ret) { kfree(txq->q.sdesc); txq->q.sdesc = NULL; @@ -2258,8 +2260,8 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; adap->sge.ingr_map[rq->cntxt_id] = NULL; - t4_iq_free(adap, 0, 0, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id, - 0xffff); + t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP, + rq->cntxt_id, fl_id, 0xffff); dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, rq->desc, rq->phys_addr); netif_napi_del(&rq->napi); @@ -2296,7 +2298,8 @@ void t4_free_sge_resources(struct adapter *adap) if (eq->rspq.desc) free_rspq_fl(adap, &eq->rspq, &eq->fl); if (etq->q.desc) { - t4_eth_eq_free(adap, 0, 0, 0, etq->q.cntxt_id); + t4_eth_eq_free(adap, adap->fn, adap->fn, 0, + etq->q.cntxt_id); free_tx_desc(adap, &etq->q, etq->q.in_use, true); kfree(etq->q.sdesc); free_txq(adap, &etq->q); @@ -2319,7 +2322,8 @@ void t4_free_sge_resources(struct adapter *adap) if (q->q.desc) { tasklet_kill(&q->qresume_tsk); - t4_ofld_eq_free(adap, 0, 0, 0, q->q.cntxt_id); + t4_ofld_eq_free(adap, adap->fn, adap->fn, 0, + q->q.cntxt_id); free_tx_desc(adap, &q->q, q->q.in_use, false); kfree(q->q.sdesc); __skb_queue_purge(&q->sendq); @@ -2333,7 +2337,8 @@ void t4_free_sge_resources(struct adapter *adap) if (cq->q.desc) { tasklet_kill(&cq->qresume_tsk); - t4_ctrl_eq_free(adap, 0, 0, 0, cq->q.cntxt_id); + t4_ctrl_eq_free(adap, adap->fn, adap->fn, 0, + cq->q.cntxt_id); __skb_queue_purge(&cq->sendq); free_txq(adap, &cq->q); } @@ -2401,6 +2406,7 @@ void t4_sge_stop(struct adapter *adap) */ void t4_sge_init(struct adapter *adap) { + unsigned int i, v; struct sge *s = &adap->sge; unsigned int fl_align_log = ilog2(FL_ALIGN); @@ -2409,8 +2415,10 @@ void t4_sge_init(struct adapter *adap) INGPADBOUNDARY(fl_align_log - 5) | PKTSHIFT(2) | RXPKTCPLMODE | (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0)); - t4_set_reg_field(adap, SGE_HOST_PAGE_SIZE, HOSTPAGESIZEPF0_MASK, - HOSTPAGESIZEPF0(PAGE_SHIFT - 10)); + + for (i = v = 0; i < 32; i += 4) + v |= (PAGE_SHIFT - 10) << i; + t4_write_reg(adap, SGE_HOST_PAGE_SIZE, v); t4_write_reg(adap, SGE_FL_BUFFER_SIZE0, PAGE_SIZE); #if FL_PG_ORDER > 0 t4_write_reg(adap, SGE_FL_BUFFER_SIZE1, PAGE_SIZE << FL_PG_ORDER); -- cgit v1.2.3-70-g09d2