diff options
Diffstat (limited to 'drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c')
| -rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 137 |
1 files changed, 98 insertions, 39 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a22cf932ca35..d92995138f7e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -920,7 +920,7 @@ static void quiesce_rx(struct adapter *adap) | |||
| 920 | { | 920 | { |
| 921 | int i; | 921 | int i; |
| 922 | 922 | ||
| 923 | for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) { | 923 | for (i = 0; i < adap->sge.ingr_sz; i++) { |
| 924 | struct sge_rspq *q = adap->sge.ingr_map[i]; | 924 | struct sge_rspq *q = adap->sge.ingr_map[i]; |
| 925 | 925 | ||
| 926 | if (q && q->handler) { | 926 | if (q && q->handler) { |
| @@ -934,6 +934,21 @@ static void quiesce_rx(struct adapter *adap) | |||
| 934 | } | 934 | } |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | /* Disable interrupt and napi handler */ | ||
| 938 | static void disable_interrupts(struct adapter *adap) | ||
| 939 | { | ||
| 940 | if (adap->flags & FULL_INIT_DONE) { | ||
| 941 | t4_intr_disable(adap); | ||
| 942 | if (adap->flags & USING_MSIX) { | ||
| 943 | free_msix_queue_irqs(adap); | ||
| 944 | free_irq(adap->msix_info[0].vec, adap); | ||
| 945 | } else { | ||
| 946 | free_irq(adap->pdev->irq, adap); | ||
| 947 | } | ||
| 948 | quiesce_rx(adap); | ||
| 949 | } | ||
| 950 | } | ||
| 951 | |||
| 937 | /* | 952 | /* |
| 938 | * Enable NAPI scheduling and interrupt generation for all Rx queues. | 953 | * Enable NAPI scheduling and interrupt generation for all Rx queues. |
| 939 | */ | 954 | */ |
| @@ -941,7 +956,7 @@ static void enable_rx(struct adapter *adap) | |||
| 941 | { | 956 | { |
| 942 | int i; | 957 | int i; |
| 943 | 958 | ||
| 944 | for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) { | 959 | for (i = 0; i < adap->sge.ingr_sz; i++) { |
| 945 | struct sge_rspq *q = adap->sge.ingr_map[i]; | 960 | struct sge_rspq *q = adap->sge.ingr_map[i]; |
| 946 | 961 | ||
| 947 | if (!q) | 962 | if (!q) |
| @@ -970,8 +985,8 @@ static int setup_sge_queues(struct adapter *adap) | |||
| 970 | int err, msi_idx, i, j; | 985 | int err, msi_idx, i, j; |
| 971 | struct sge *s = &adap->sge; | 986 | struct sge *s = &adap->sge; |
| 972 | 987 | ||
| 973 | bitmap_zero(s->starving_fl, MAX_EGRQ); | 988 | bitmap_zero(s->starving_fl, s->egr_sz); |
| 974 | bitmap_zero(s->txq_maperr, MAX_EGRQ); | 989 | bitmap_zero(s->txq_maperr, s->egr_sz); |
| 975 | 990 | ||
| 976 | if (adap->flags & USING_MSIX) | 991 | if (adap->flags & USING_MSIX) |
| 977 | msi_idx = 1; /* vector 0 is for non-queue interrupts */ | 992 | msi_idx = 1; /* vector 0 is for non-queue interrupts */ |
| @@ -983,6 +998,19 @@ static int setup_sge_queues(struct adapter *adap) | |||
| 983 | msi_idx = -((int)s->intrq.abs_id + 1); | 998 | msi_idx = -((int)s->intrq.abs_id + 1); |
| 984 | } | 999 | } |
| 985 | 1000 | ||
| 1001 | /* NOTE: If you add/delete any Ingress/Egress Queue allocations in here, | ||
| 1002 | * don't forget to update the following which need to be | ||
| 1003 | * synchronized to and changes here. | ||
| 1004 | * | ||
| 1005 | * 1. The calculations of MAX_INGQ in cxgb4.h. | ||
| 1006 | * | ||
| 1007 | * 2. Update enable_msix/name_msix_vecs/request_msix_queue_irqs | ||
| 1008 | * to accommodate any new/deleted Ingress Queues | ||
| 1009 | * which need MSI-X Vectors. | ||
| 1010 | * | ||
| 1011 | * 3. Update sge_qinfo_show() to include information on the | ||
| 1012 | * new/deleted queues. | ||
| 1013 | */ | ||
| 986 | err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0], | 1014 | err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0], |
| 987 | msi_idx, NULL, fwevtq_handler); | 1015 | msi_idx, NULL, fwevtq_handler); |
| 988 | if (err) { | 1016 | if (err) { |
| @@ -4244,19 +4272,12 @@ static int cxgb_up(struct adapter *adap) | |||
| 4244 | 4272 | ||
| 4245 | static void cxgb_down(struct adapter *adapter) | 4273 | static void cxgb_down(struct adapter *adapter) |
| 4246 | { | 4274 | { |
| 4247 | t4_intr_disable(adapter); | ||
| 4248 | cancel_work_sync(&adapter->tid_release_task); | 4275 | cancel_work_sync(&adapter->tid_release_task); |
| 4249 | cancel_work_sync(&adapter->db_full_task); | 4276 | cancel_work_sync(&adapter->db_full_task); |
| 4250 | cancel_work_sync(&adapter->db_drop_task); | 4277 | cancel_work_sync(&adapter->db_drop_task); |
| 4251 | adapter->tid_release_task_busy = false; | 4278 | adapter->tid_release_task_busy = false; |
| 4252 | adapter->tid_release_head = NULL; | 4279 | adapter->tid_release_head = NULL; |
| 4253 | 4280 | ||
| 4254 | if (adapter->flags & USING_MSIX) { | ||
| 4255 | free_msix_queue_irqs(adapter); | ||
| 4256 | free_irq(adapter->msix_info[0].vec, adapter); | ||
| 4257 | } else | ||
| 4258 | free_irq(adapter->pdev->irq, adapter); | ||
| 4259 | quiesce_rx(adapter); | ||
| 4260 | t4_sge_stop(adapter); | 4281 | t4_sge_stop(adapter); |
| 4261 | t4_free_sge_resources(adapter); | 4282 | t4_free_sge_resources(adapter); |
| 4262 | adapter->flags &= ~FULL_INIT_DONE; | 4283 | adapter->flags &= ~FULL_INIT_DONE; |
| @@ -4733,8 +4754,9 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) | |||
| 4733 | if (ret < 0) | 4754 | if (ret < 0) |
| 4734 | return ret; | 4755 | return ret; |
| 4735 | 4756 | ||
| 4736 | ret = t4_cfg_pfvf(adap, adap->fn, adap->fn, 0, MAX_EGRQ, 64, MAX_INGQ, | 4757 | ret = t4_cfg_pfvf(adap, adap->fn, adap->fn, 0, adap->sge.egr_sz, 64, |
| 4737 | 0, 0, 4, 0xf, 0xf, 16, FW_CMD_CAP_PF, FW_CMD_CAP_PF); | 4758 | MAX_INGQ, 0, 0, 4, 0xf, 0xf, 16, FW_CMD_CAP_PF, |
| 4759 | FW_CMD_CAP_PF); | ||
| 4738 | if (ret < 0) | 4760 | if (ret < 0) |
| 4739 | return ret; | 4761 | return ret; |
| 4740 | 4762 | ||
| @@ -5088,10 +5110,15 @@ static int adap_init0(struct adapter *adap) | |||
| 5088 | enum dev_state state; | 5110 | enum dev_state state; |
| 5089 | u32 params[7], val[7]; | 5111 | u32 params[7], val[7]; |
| 5090 | struct fw_caps_config_cmd caps_cmd; | 5112 | struct fw_caps_config_cmd caps_cmd; |
| 5091 | struct fw_devlog_cmd devlog_cmd; | ||
| 5092 | u32 devlog_meminfo; | ||
| 5093 | int reset = 1; | 5113 | int reset = 1; |
| 5094 | 5114 | ||
| 5115 | /* Grab Firmware Device Log parameters as early as possible so we have | ||
| 5116 | * access to it for debugging, etc. | ||
| 5117 | */ | ||
| 5118 | ret = t4_init_devlog_params(adap); | ||
| 5119 | if (ret < 0) | ||
| 5120 | return ret; | ||
| 5121 | |||
| 5095 | /* Contact FW, advertising Master capability */ | 5122 | /* Contact FW, advertising Master capability */ |
| 5096 | ret = t4_fw_hello(adap, adap->mbox, adap->mbox, MASTER_MAY, &state); | 5123 | ret = t4_fw_hello(adap, adap->mbox, adap->mbox, MASTER_MAY, &state); |
| 5097 | if (ret < 0) { | 5124 | if (ret < 0) { |
| @@ -5169,30 +5196,6 @@ static int adap_init0(struct adapter *adap) | |||
| 5169 | if (ret < 0) | 5196 | if (ret < 0) |
| 5170 | goto bye; | 5197 | goto bye; |
| 5171 | 5198 | ||
| 5172 | /* Read firmware device log parameters. We really need to find a way | ||
| 5173 | * to get these parameters initialized with some default values (which | ||
| 5174 | * are likely to be correct) for the case where we either don't | ||
| 5175 | * attache to the firmware or it's crashed when we probe the adapter. | ||
| 5176 | * That way we'll still be able to perform early firmware startup | ||
| 5177 | * debugging ... If the request to get the Firmware's Device Log | ||
| 5178 | * parameters fails, we'll live so we don't make that a fatal error. | ||
| 5179 | */ | ||
| 5180 | memset(&devlog_cmd, 0, sizeof(devlog_cmd)); | ||
| 5181 | devlog_cmd.op_to_write = htonl(FW_CMD_OP_V(FW_DEVLOG_CMD) | | ||
| 5182 | FW_CMD_REQUEST_F | FW_CMD_READ_F); | ||
| 5183 | devlog_cmd.retval_len16 = htonl(FW_LEN16(devlog_cmd)); | ||
| 5184 | ret = t4_wr_mbox(adap, adap->mbox, &devlog_cmd, sizeof(devlog_cmd), | ||
| 5185 | &devlog_cmd); | ||
| 5186 | if (ret == 0) { | ||
| 5187 | devlog_meminfo = | ||
| 5188 | ntohl(devlog_cmd.memtype_devlog_memaddr16_devlog); | ||
| 5189 | adap->params.devlog.memtype = | ||
| 5190 | FW_DEVLOG_CMD_MEMTYPE_DEVLOG_G(devlog_meminfo); | ||
| 5191 | adap->params.devlog.start = | ||
| 5192 | FW_DEVLOG_CMD_MEMADDR16_DEVLOG_G(devlog_meminfo) << 4; | ||
| 5193 | adap->params.devlog.size = ntohl(devlog_cmd.memsize_devlog); | ||
| 5194 | } | ||
| 5195 | |||
| 5196 | /* | 5199 | /* |
| 5197 | * Find out what ports are available to us. Note that we need to do | 5200 | * Find out what ports are available to us. Note that we need to do |
| 5198 | * this before calling adap_init0_no_config() since it needs nports | 5201 | * this before calling adap_init0_no_config() since it needs nports |
| @@ -5293,6 +5296,51 @@ static int adap_init0(struct adapter *adap) | |||
| 5293 | adap->tids.nftids = val[4] - val[3] + 1; | 5296 | adap->tids.nftids = val[4] - val[3] + 1; |
| 5294 | adap->sge.ingr_start = val[5]; | 5297 | adap->sge.ingr_start = val[5]; |
| 5295 | 5298 | ||
| 5299 | /* qids (ingress/egress) returned from firmware can be anywhere | ||
| 5300 | * in the range from EQ(IQFLINT)_START to EQ(IQFLINT)_END. | ||
| 5301 | * Hence driver needs to allocate memory for this range to | ||
| 5302 | * store the queue info. Get the highest IQFLINT/EQ index returned | ||
| 5303 | * in FW_EQ_*_CMD.alloc command. | ||
| 5304 | */ | ||
| 5305 | params[0] = FW_PARAM_PFVF(EQ_END); | ||
| 5306 | params[1] = FW_PARAM_PFVF(IQFLINT_END); | ||
| 5307 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val); | ||
| 5308 | if (ret < 0) | ||
| 5309 | goto bye; | ||
| 5310 | adap->sge.egr_sz = val[0] - adap->sge.egr_start + 1; | ||
| 5311 | adap->sge.ingr_sz = val[1] - adap->sge.ingr_start + 1; | ||
| 5312 | |||
| 5313 | adap->sge.egr_map = kcalloc(adap->sge.egr_sz, | ||
| 5314 | sizeof(*adap->sge.egr_map), GFP_KERNEL); | ||
| 5315 | if (!adap->sge.egr_map) { | ||
| 5316 | ret = -ENOMEM; | ||
| 5317 | goto bye; | ||
| 5318 | } | ||
| 5319 | |||
| 5320 | adap->sge.ingr_map = kcalloc(adap->sge.ingr_sz, | ||
| 5321 | sizeof(*adap->sge.ingr_map), GFP_KERNEL); | ||
| 5322 | if (!adap->sge.ingr_map) { | ||
| 5323 | ret = -ENOMEM; | ||
| 5324 | goto bye; | ||
| 5325 | } | ||
| 5326 | |||
| 5327 | /* Allocate the memory for the vaious egress queue bitmaps | ||
| 5328 | * ie starving_fl and txq_maperr. | ||
| 5329 | */ | ||
| 5330 | adap->sge.starving_fl = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz), | ||
| 5331 | sizeof(long), GFP_KERNEL); | ||
| 5332 | if (!adap->sge.starving_fl) { | ||
| 5333 | ret = -ENOMEM; | ||
| 5334 | goto bye; | ||
| 5335 | } | ||
| 5336 | |||
| 5337 | adap->sge.txq_maperr = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz), | ||
| 5338 | sizeof(long), GFP_KERNEL); | ||
| 5339 | if (!adap->sge.txq_maperr) { | ||
| 5340 | ret = -ENOMEM; | ||
| 5341 | goto bye; | ||
| 5342 | } | ||
| 5343 | |||
| 5296 | params[0] = FW_PARAM_PFVF(CLIP_START); | 5344 | params[0] = FW_PARAM_PFVF(CLIP_START); |
| 5297 | params[1] = FW_PARAM_PFVF(CLIP_END); | 5345 | params[1] = FW_PARAM_PFVF(CLIP_END); |
| 5298 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val); | 5346 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val); |
| @@ -5501,6 +5549,10 @@ static int adap_init0(struct adapter *adap) | |||
| 5501 | * happened to HW/FW, stop issuing commands. | 5549 | * happened to HW/FW, stop issuing commands. |
| 5502 | */ | 5550 | */ |
| 5503 | bye: | 5551 | bye: |
| 5552 | kfree(adap->sge.egr_map); | ||
| 5553 | kfree(adap->sge.ingr_map); | ||
| 5554 | kfree(adap->sge.starving_fl); | ||
| 5555 | kfree(adap->sge.txq_maperr); | ||
| 5504 | if (ret != -ETIMEDOUT && ret != -EIO) | 5556 | if (ret != -ETIMEDOUT && ret != -EIO) |
| 5505 | t4_fw_bye(adap, adap->mbox); | 5557 | t4_fw_bye(adap, adap->mbox); |
| 5506 | return ret; | 5558 | return ret; |
| @@ -5528,6 +5580,7 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev, | |||
| 5528 | netif_carrier_off(dev); | 5580 | netif_carrier_off(dev); |
| 5529 | } | 5581 | } |
| 5530 | spin_unlock(&adap->stats_lock); | 5582 | spin_unlock(&adap->stats_lock); |
| 5583 | disable_interrupts(adap); | ||
| 5531 | if (adap->flags & FULL_INIT_DONE) | 5584 | if (adap->flags & FULL_INIT_DONE) |
| 5532 | cxgb_down(adap); | 5585 | cxgb_down(adap); |
| 5533 | rtnl_unlock(); | 5586 | rtnl_unlock(); |
| @@ -5912,6 +5965,10 @@ static void free_some_resources(struct adapter *adapter) | |||
| 5912 | 5965 | ||
| 5913 | t4_free_mem(adapter->l2t); | 5966 | t4_free_mem(adapter->l2t); |
| 5914 | t4_free_mem(adapter->tids.tid_tab); | 5967 | t4_free_mem(adapter->tids.tid_tab); |
| 5968 | kfree(adapter->sge.egr_map); | ||
| 5969 | kfree(adapter->sge.ingr_map); | ||
| 5970 | kfree(adapter->sge.starving_fl); | ||
| 5971 | kfree(adapter->sge.txq_maperr); | ||
| 5915 | disable_msi(adapter); | 5972 | disable_msi(adapter); |
| 5916 | 5973 | ||
| 5917 | for_each_port(adapter, i) | 5974 | for_each_port(adapter, i) |
| @@ -6237,6 +6294,8 @@ static void remove_one(struct pci_dev *pdev) | |||
| 6237 | if (is_offload(adapter)) | 6294 | if (is_offload(adapter)) |
| 6238 | detach_ulds(adapter); | 6295 | detach_ulds(adapter); |
| 6239 | 6296 | ||
| 6297 | disable_interrupts(adapter); | ||
| 6298 | |||
| 6240 | for_each_port(adapter, i) | 6299 | for_each_port(adapter, i) |
| 6241 | if (adapter->port[i]->reg_state == NETREG_REGISTERED) | 6300 | if (adapter->port[i]->reg_state == NETREG_REGISTERED) |
| 6242 | unregister_netdev(adapter->port[i]); | 6301 | unregister_netdev(adapter->port[i]); |
