diff options
author | Vipul Pandya <vipul@chelsio.com> | 2012-09-25 22:39:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-09-27 17:55:50 -0400 |
commit | 636f9d371f70f22961fd598fe18380057518ca31 (patch) | |
tree | 27d411e800f6ba779be7c07b803ab55393791338 /drivers/net/ethernet/chelsio/cxgb4 | |
parent | 52367a763d8046190754ab43743e42638564a2d1 (diff) |
cxgb4: Add support for T4 configuration file
Starting with T4 firmware version 1.3.11.0 the firmware now supports device
configuration via a Firmware Configuration File. The Firmware Configuration
File was primarily developed in order to centralize all of the configuration,
resource allocation, etc. for Unified Wire operation where multiple
Physical / Virtual Function Drivers would be using a T4 adapter simultaneously.
The Firmware Configuration file can live in three locations as shown below
in order of precedence.
1) User defined configuration file: /lib/firmware/cxgb4/t4-config.txt
2) Factory Default configuration file written to FLASH within
the manufacturing process.
3) Hardwired driver configuration.
Signed-off-by: Jay Hernandez <jay@chelsio.com>
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/chelsio/cxgb4')
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 570 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 392 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 37 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 37 |
6 files changed, 920 insertions, 133 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index ae040cf255a4..777cbb4f62bb 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -211,6 +211,9 @@ struct tp_err_stats { | |||
211 | struct tp_params { | 211 | struct tp_params { |
212 | unsigned int ntxchan; /* # of Tx channels */ | 212 | unsigned int ntxchan; /* # of Tx channels */ |
213 | unsigned int tre; /* log2 of core clocks per TP tick */ | 213 | unsigned int tre; /* log2 of core clocks per TP tick */ |
214 | |||
215 | uint32_t dack_re; /* DACK timer resolution */ | ||
216 | unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */ | ||
214 | }; | 217 | }; |
215 | 218 | ||
216 | struct vpd_params { | 219 | struct vpd_params { |
@@ -519,6 +522,8 @@ struct adapter { | |||
519 | struct net_device *port[MAX_NPORTS]; | 522 | struct net_device *port[MAX_NPORTS]; |
520 | u8 chan_map[NCHAN]; /* channel -> port map */ | 523 | u8 chan_map[NCHAN]; /* channel -> port map */ |
521 | 524 | ||
525 | unsigned int l2t_start; | ||
526 | unsigned int l2t_end; | ||
522 | struct l2t_data *l2t; | 527 | struct l2t_data *l2t; |
523 | void *uld_handle[CXGB4_ULD_MAX]; | 528 | void *uld_handle[CXGB4_ULD_MAX]; |
524 | struct list_head list_node; | 529 | struct list_head list_node; |
@@ -683,7 +688,9 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port); | |||
683 | int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, | 688 | int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, |
684 | __be32 *buf); | 689 | __be32 *buf); |
685 | int t4_seeprom_wp(struct adapter *adapter, bool enable); | 690 | int t4_seeprom_wp(struct adapter *adapter, bool enable); |
691 | int get_vpd_params(struct adapter *adapter, struct vpd_params *p); | ||
686 | int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); | 692 | int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); |
693 | unsigned int t4_flash_cfg_addr(struct adapter *adapter); | ||
687 | int t4_check_fw_version(struct adapter *adapter); | 694 | int t4_check_fw_version(struct adapter *adapter); |
688 | int t4_prep_adapter(struct adapter *adapter); | 695 | int t4_prep_adapter(struct adapter *adapter); |
689 | int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); | 696 | int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); |
@@ -698,6 +705,8 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, | |||
698 | 705 | ||
699 | void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); | 706 | void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); |
700 | void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); | 707 | void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); |
708 | void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr, | ||
709 | unsigned int mask, unsigned int val); | ||
701 | void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, | 710 | void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, |
702 | struct tp_tcp_stats *v6); | 711 | struct tp_tcp_stats *v6); |
703 | void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, | 712 | void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, |
@@ -713,6 +722,12 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, | |||
713 | int t4_fw_bye(struct adapter *adap, unsigned int mbox); | 722 | int t4_fw_bye(struct adapter *adap, unsigned int mbox); |
714 | int t4_early_init(struct adapter *adap, unsigned int mbox); | 723 | int t4_early_init(struct adapter *adap, unsigned int mbox); |
715 | int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset); | 724 | int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset); |
725 | int t4_fw_config_file(struct adapter *adap, unsigned int mbox, | ||
726 | unsigned int mtype, unsigned int maddr, | ||
727 | u32 *finiver, u32 *finicsum, u32 *cfcsum); | ||
728 | int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, | ||
729 | unsigned int cache_line_size); | ||
730 | int t4_fw_initialize(struct adapter *adap, unsigned int mbox); | ||
716 | int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, | 731 | int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, |
717 | unsigned int vf, unsigned int nparams, const u32 *params, | 732 | unsigned int vf, unsigned int nparams, const u32 *params, |
718 | u32 *val); | 733 | u32 *val); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 34d510dd56a8..cb3e663c30dc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -193,6 +193,7 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { | |||
193 | }; | 193 | }; |
194 | 194 | ||
195 | #define FW_FNAME "cxgb4/t4fw.bin" | 195 | #define FW_FNAME "cxgb4/t4fw.bin" |
196 | #define FW_CFNAME "cxgb4/t4-config.txt" | ||
196 | 197 | ||
197 | MODULE_DESCRIPTION(DRV_DESC); | 198 | MODULE_DESCRIPTION(DRV_DESC); |
198 | MODULE_AUTHOR("Chelsio Communications"); | 199 | MODULE_AUTHOR("Chelsio Communications"); |
@@ -201,6 +202,17 @@ MODULE_VERSION(DRV_VERSION); | |||
201 | MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); | 202 | MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); |
202 | MODULE_FIRMWARE(FW_FNAME); | 203 | MODULE_FIRMWARE(FW_FNAME); |
203 | 204 | ||
205 | /* | ||
206 | * Normally we're willing to become the firmware's Master PF but will be happy | ||
207 | * if another PF has already become the Master and initialized the adapter. | ||
208 | * Setting "force_init" will cause this driver to forcibly establish itself as | ||
209 | * the Master PF and initialize the adapter. | ||
210 | */ | ||
211 | static uint force_init; | ||
212 | |||
213 | module_param(force_init, uint, 0644); | ||
214 | MODULE_PARM_DESC(force_init, "Forcibly become Master PF and initialize adapter"); | ||
215 | |||
204 | static int dflt_msg_enable = DFLT_MSG_ENABLE; | 216 | static int dflt_msg_enable = DFLT_MSG_ENABLE; |
205 | 217 | ||
206 | module_param(dflt_msg_enable, int, 0644); | 218 | module_param(dflt_msg_enable, int, 0644); |
@@ -236,6 +248,20 @@ module_param_array(intr_cnt, uint, NULL, 0644); | |||
236 | MODULE_PARM_DESC(intr_cnt, | 248 | MODULE_PARM_DESC(intr_cnt, |
237 | "thresholds 1..3 for queue interrupt packet counters"); | 249 | "thresholds 1..3 for queue interrupt packet counters"); |
238 | 250 | ||
251 | /* | ||
252 | * Normally we tell the chip to deliver Ingress Packets into our DMA buffers | ||
253 | * offset by 2 bytes in order to have the IP headers line up on 4-byte | ||
254 | * boundaries. This is a requirement for many architectures which will throw | ||
255 | * a machine check fault if an attempt is made to access one of the 4-byte IP | ||
256 | * header fields on a non-4-byte boundary. And it's a major performance issue | ||
257 | * even on some architectures which allow it like some implementations of the | ||
258 | * x86 ISA. However, some architectures don't mind this and for some very | ||
259 | * edge-case performance sensitive applications (like forwarding large volumes | ||
260 | * of small packets), setting this DMA offset to 0 will decrease the number of | ||
261 | * PCI-E Bus transfers enough to measurably affect performance. | ||
262 | */ | ||
263 | static int rx_dma_offset = 2; | ||
264 | |||
239 | static bool vf_acls; | 265 | static bool vf_acls; |
240 | 266 | ||
241 | #ifdef CONFIG_PCI_IOV | 267 | #ifdef CONFIG_PCI_IOV |
@@ -3076,6 +3102,10 @@ static void setup_memwin(struct adapter *adap) | |||
3076 | t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2), | 3102 | t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2), |
3077 | (bar0 + MEMWIN2_BASE) | BIR(0) | | 3103 | (bar0 + MEMWIN2_BASE) | BIR(0) | |
3078 | WINDOW(ilog2(MEMWIN2_APERTURE) - 10)); | 3104 | WINDOW(ilog2(MEMWIN2_APERTURE) - 10)); |
3105 | } | ||
3106 | |||
3107 | static void setup_memwin_rdma(struct adapter *adap) | ||
3108 | { | ||
3079 | if (adap->vres.ocq.size) { | 3109 | if (adap->vres.ocq.size) { |
3080 | unsigned int start, sz_kb; | 3110 | unsigned int start, sz_kb; |
3081 | 3111 | ||
@@ -3155,6 +3185,232 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) | |||
3155 | 3185 | ||
3156 | /* | 3186 | /* |
3157 | * Phase 0 of initialization: contact FW, obtain config, perform basic init. | 3187 | * Phase 0 of initialization: contact FW, obtain config, perform basic init. |
3188 | * | ||
3189 | * If the firmware we're dealing with has Configuration File support, then | ||
3190 | * we use that to perform all configuration | ||
3191 | */ | ||
3192 | |||
3193 | /* | ||
3194 | * Tweak configuration based on module parameters, etc. Most of these have | ||
3195 | * defaults assigned to them by Firmware Configuration Files (if we're using | ||
3196 | * them) but need to be explicitly set if we're using hard-coded | ||
3197 | * initialization. But even in the case of using Firmware Configuration | ||
3198 | * Files, we'd like to expose the ability to change these via module | ||
3199 | * parameters so these are essentially common tweaks/settings for | ||
3200 | * Configuration Files and hard-coded initialization ... | ||
3201 | */ | ||
3202 | static int adap_init0_tweaks(struct adapter *adapter) | ||
3203 | { | ||
3204 | /* | ||
3205 | * Fix up various Host-Dependent Parameters like Page Size, Cache | ||
3206 | * Line Size, etc. The firmware default is for a 4KB Page Size and | ||
3207 | * 64B Cache Line Size ... | ||
3208 | */ | ||
3209 | t4_fixup_host_params(adapter, PAGE_SIZE, L1_CACHE_BYTES); | ||
3210 | |||
3211 | /* | ||
3212 | * Process module parameters which affect early initialization. | ||
3213 | */ | ||
3214 | if (rx_dma_offset != 2 && rx_dma_offset != 0) { | ||
3215 | dev_err(&adapter->pdev->dev, | ||
3216 | "Ignoring illegal rx_dma_offset=%d, using 2\n", | ||
3217 | rx_dma_offset); | ||
3218 | rx_dma_offset = 2; | ||
3219 | } | ||
3220 | t4_set_reg_field(adapter, SGE_CONTROL, | ||
3221 | PKTSHIFT_MASK, | ||
3222 | PKTSHIFT(rx_dma_offset)); | ||
3223 | |||
3224 | /* | ||
3225 | * Don't include the "IP Pseudo Header" in CPL_RX_PKT checksums: Linux | ||
3226 | * adds the pseudo header itself. | ||
3227 | */ | ||
3228 | t4_tp_wr_bits_indirect(adapter, TP_INGRESS_CONFIG, | ||
3229 | CSUM_HAS_PSEUDO_HDR, 0); | ||
3230 | |||
3231 | return 0; | ||
3232 | } | ||
3233 | |||
3234 | /* | ||
3235 | * Attempt to initialize the adapter via a Firmware Configuration File. | ||
3236 | */ | ||
3237 | static int adap_init0_config(struct adapter *adapter, int reset) | ||
3238 | { | ||
3239 | struct fw_caps_config_cmd caps_cmd; | ||
3240 | const struct firmware *cf; | ||
3241 | unsigned long mtype = 0, maddr = 0; | ||
3242 | u32 finiver, finicsum, cfcsum; | ||
3243 | int ret, using_flash; | ||
3244 | |||
3245 | /* | ||
3246 | * Reset device if necessary. | ||
3247 | */ | ||
3248 | if (reset) { | ||
3249 | ret = t4_fw_reset(adapter, adapter->mbox, | ||
3250 | PIORSTMODE | PIORST); | ||
3251 | if (ret < 0) | ||
3252 | goto bye; | ||
3253 | } | ||
3254 | |||
3255 | /* | ||
3256 | * If we have a T4 configuration file under /lib/firmware/cxgb4/, | ||
3257 | * then use that. Otherwise, use the configuration file stored | ||
3258 | * in the adapter flash ... | ||
3259 | */ | ||
3260 | ret = request_firmware(&cf, FW_CFNAME, adapter->pdev_dev); | ||
3261 | if (ret < 0) { | ||
3262 | using_flash = 1; | ||
3263 | mtype = FW_MEMTYPE_CF_FLASH; | ||
3264 | maddr = t4_flash_cfg_addr(adapter); | ||
3265 | } else { | ||
3266 | u32 params[7], val[7]; | ||
3267 | |||
3268 | using_flash = 0; | ||
3269 | if (cf->size >= FLASH_CFG_MAX_SIZE) | ||
3270 | ret = -ENOMEM; | ||
3271 | else { | ||
3272 | params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | | ||
3273 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CF)); | ||
3274 | ret = t4_query_params(adapter, adapter->mbox, | ||
3275 | adapter->fn, 0, 1, params, val); | ||
3276 | if (ret == 0) { | ||
3277 | /* | ||
3278 | * For t4_memory_write() below addresses and | ||
3279 | * sizes have to be in terms of multiples of 4 | ||
3280 | * bytes. So, if the Configuration File isn't | ||
3281 | * a multiple of 4 bytes in length we'll have | ||
3282 | * to write that out separately since we can't | ||
3283 | * guarantee that the bytes following the | ||
3284 | * residual byte in the buffer returned by | ||
3285 | * request_firmware() are zeroed out ... | ||
3286 | */ | ||
3287 | size_t resid = cf->size & 0x3; | ||
3288 | size_t size = cf->size & ~0x3; | ||
3289 | __be32 *data = (__be32 *)cf->data; | ||
3290 | |||
3291 | mtype = FW_PARAMS_PARAM_Y_GET(val[0]); | ||
3292 | maddr = FW_PARAMS_PARAM_Z_GET(val[0]) << 16; | ||
3293 | |||
3294 | ret = t4_memory_write(adapter, mtype, maddr, | ||
3295 | size, data); | ||
3296 | if (ret == 0 && resid != 0) { | ||
3297 | union { | ||
3298 | __be32 word; | ||
3299 | char buf[4]; | ||
3300 | } last; | ||
3301 | int i; | ||
3302 | |||
3303 | last.word = data[size >> 2]; | ||
3304 | for (i = resid; i < 4; i++) | ||
3305 | last.buf[i] = 0; | ||
3306 | ret = t4_memory_write(adapter, mtype, | ||
3307 | maddr + size, | ||
3308 | 4, &last.word); | ||
3309 | } | ||
3310 | } | ||
3311 | } | ||
3312 | |||
3313 | release_firmware(cf); | ||
3314 | if (ret) | ||
3315 | goto bye; | ||
3316 | } | ||
3317 | |||
3318 | /* | ||
3319 | * Issue a Capability Configuration command to the firmware to get it | ||
3320 | * to parse the Configuration File. We don't use t4_fw_config_file() | ||
3321 | * because we want the ability to modify various features after we've | ||
3322 | * processed the configuration file ... | ||
3323 | */ | ||
3324 | memset(&caps_cmd, 0, sizeof(caps_cmd)); | ||
3325 | caps_cmd.op_to_write = | ||
3326 | htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
3327 | FW_CMD_REQUEST | | ||
3328 | FW_CMD_READ); | ||
3329 | caps_cmd.retval_len16 = | ||
3330 | htonl(FW_CAPS_CONFIG_CMD_CFVALID | | ||
3331 | FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | | ||
3332 | FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) | | ||
3333 | FW_LEN16(caps_cmd)); | ||
3334 | ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), | ||
3335 | &caps_cmd); | ||
3336 | if (ret < 0) | ||
3337 | goto bye; | ||
3338 | |||
3339 | finiver = ntohl(caps_cmd.finiver); | ||
3340 | finicsum = ntohl(caps_cmd.finicsum); | ||
3341 | cfcsum = ntohl(caps_cmd.cfcsum); | ||
3342 | if (finicsum != cfcsum) | ||
3343 | dev_warn(adapter->pdev_dev, "Configuration File checksum "\ | ||
3344 | "mismatch: [fini] csum=%#x, computed csum=%#x\n", | ||
3345 | finicsum, cfcsum); | ||
3346 | |||
3347 | /* | ||
3348 | * If we're a pure NIC driver then disable all offloading facilities. | ||
3349 | * This will allow the firmware to optimize aspects of the hardware | ||
3350 | * configuration which will result in improved performance. | ||
3351 | */ | ||
3352 | caps_cmd.ofldcaps = 0; | ||
3353 | caps_cmd.iscsicaps = 0; | ||
3354 | caps_cmd.rdmacaps = 0; | ||
3355 | caps_cmd.fcoecaps = 0; | ||
3356 | |||
3357 | /* | ||
3358 | * And now tell the firmware to use the configuration we just loaded. | ||
3359 | */ | ||
3360 | caps_cmd.op_to_write = | ||
3361 | htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
3362 | FW_CMD_REQUEST | | ||
3363 | FW_CMD_WRITE); | ||
3364 | caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); | ||
3365 | ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), | ||
3366 | NULL); | ||
3367 | if (ret < 0) | ||
3368 | goto bye; | ||
3369 | |||
3370 | /* | ||
3371 | * Tweak configuration based on system architecture, module | ||
3372 | * parameters, etc. | ||
3373 | */ | ||
3374 | ret = adap_init0_tweaks(adapter); | ||
3375 | if (ret < 0) | ||
3376 | goto bye; | ||
3377 | |||
3378 | /* | ||
3379 | * And finally tell the firmware to initialize itself using the | ||
3380 | * parameters from the Configuration File. | ||
3381 | */ | ||
3382 | ret = t4_fw_initialize(adapter, adapter->mbox); | ||
3383 | if (ret < 0) | ||
3384 | goto bye; | ||
3385 | |||
3386 | /* | ||
3387 | * Return successfully and note that we're operating with parameters | ||
3388 | * not supplied by the driver, rather than from hard-wired | ||
3389 | * initialization constants burried in the driver. | ||
3390 | */ | ||
3391 | adapter->flags |= USING_SOFT_PARAMS; | ||
3392 | dev_info(adapter->pdev_dev, "Successfully configured using Firmware "\ | ||
3393 | "Configuration File %s, version %#x, computed checksum %#x\n", | ||
3394 | (using_flash | ||
3395 | ? "in device FLASH" | ||
3396 | : "/lib/firmware/" FW_CFNAME), | ||
3397 | finiver, cfcsum); | ||
3398 | return 0; | ||
3399 | |||
3400 | /* | ||
3401 | * Something bad happened. Return the error ... (If the "error" | ||
3402 | * is that there's no Configuration File on the adapter we don't | ||
3403 | * want to issue a warning since this is fairly common.) | ||
3404 | */ | ||
3405 | bye: | ||
3406 | if (ret != -ENOENT) | ||
3407 | dev_warn(adapter->pdev_dev, "Configuration file error %d\n", | ||
3408 | -ret); | ||
3409 | return ret; | ||
3410 | } | ||
3411 | |||
3412 | /* | ||
3413 | * Phase 0 of initialization: contact FW, obtain config, perform basic init. | ||
3158 | */ | 3414 | */ |
3159 | static int adap_init0(struct adapter *adap) | 3415 | static int adap_init0(struct adapter *adap) |
3160 | { | 3416 | { |
@@ -3162,72 +3418,197 @@ static int adap_init0(struct adapter *adap) | |||
3162 | u32 v, port_vec; | 3418 | u32 v, port_vec; |
3163 | enum dev_state state; | 3419 | enum dev_state state; |
3164 | u32 params[7], val[7]; | 3420 | u32 params[7], val[7]; |
3165 | struct fw_caps_config_cmd c; | 3421 | int reset = 1, j; |
3166 | 3422 | ||
3167 | ret = t4_check_fw_version(adap); | 3423 | /* |
3168 | if (ret == -EINVAL || ret > 0) { | 3424 | * Contact FW, advertising Master capability (and potentially forcing |
3169 | if (upgrade_fw(adap) >= 0) /* recache FW version */ | 3425 | * ourselves as the Master PF if our module parameter force_init is |
3170 | ret = t4_check_fw_version(adap); | 3426 | * set). |
3171 | } | 3427 | */ |
3172 | if (ret < 0) | 3428 | ret = t4_fw_hello(adap, adap->mbox, adap->fn, |
3173 | return ret; | 3429 | force_init ? MASTER_MUST : MASTER_MAY, |
3174 | 3430 | &state); | |
3175 | /* contact FW, request master */ | ||
3176 | ret = t4_fw_hello(adap, adap->fn, adap->fn, MASTER_MUST, &state); | ||
3177 | if (ret < 0) { | 3431 | if (ret < 0) { |
3178 | dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", | 3432 | dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", |
3179 | ret); | 3433 | ret); |
3180 | return ret; | 3434 | return ret; |
3181 | } | 3435 | } |
3436 | if (ret == adap->mbox) | ||
3437 | adap->flags |= MASTER_PF; | ||
3438 | if (force_init && state == DEV_STATE_INIT) | ||
3439 | state = DEV_STATE_UNINIT; | ||
3182 | 3440 | ||
3183 | /* reset device */ | 3441 | /* |
3184 | ret = t4_fw_reset(adap, adap->fn, PIORSTMODE | PIORST); | 3442 | * If we're the Master PF Driver and the device is uninitialized, |
3185 | if (ret < 0) | 3443 | * then let's consider upgrading the firmware ... (We always want |
3186 | goto bye; | 3444 | * to check the firmware version number in order to A. get it for |
3187 | 3445 | * later reporting and B. to warn if the currently loaded firmware | |
3188 | for (v = 0; v < SGE_NTIMERS - 1; v++) | 3446 | * is excessively mismatched relative to the driver.) |
3189 | adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL); | 3447 | */ |
3190 | adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL; | 3448 | ret = t4_check_fw_version(adap); |
3191 | adap->sge.counter_val[0] = 1; | 3449 | if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) { |
3192 | for (v = 1; v < SGE_NCOUNTERS; v++) | 3450 | if (ret == -EINVAL || ret > 0) { |
3193 | adap->sge.counter_val[v] = min(intr_cnt[v - 1], | 3451 | if (upgrade_fw(adap) >= 0) { |
3194 | THRESHOLD_3_MASK); | 3452 | /* |
3195 | #define FW_PARAM_DEV(param) \ | 3453 | * Note that the chip was reset as part of the |
3196 | (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ | 3454 | * firmware upgrade so we don't reset it again |
3197 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) | 3455 | * below and grab the new firmware version. |
3456 | */ | ||
3457 | reset = 0; | ||
3458 | ret = t4_check_fw_version(adap); | ||
3459 | } | ||
3460 | } | ||
3461 | if (ret < 0) | ||
3462 | return ret; | ||
3463 | } | ||
3198 | 3464 | ||
3199 | params[0] = FW_PARAM_DEV(CCLK); | 3465 | /* |
3200 | ret = t4_query_params(adap, adap->fn, adap->fn, 0, 1, params, val); | 3466 | * Grab VPD parameters. This should be done after we establish a |
3467 | * connection to the firmware since some of the VPD parameters | ||
3468 | * (notably the Core Clock frequency) are retrieved via requests to | ||
3469 | * the firmware. On the other hand, we need these fairly early on | ||
3470 | * so we do this right after getting ahold of the firmware. | ||
3471 | */ | ||
3472 | ret = get_vpd_params(adap, &adap->params.vpd); | ||
3201 | if (ret < 0) | 3473 | if (ret < 0) |
3202 | goto bye; | 3474 | goto bye; |
3203 | adap->params.vpd.cclk = val[0]; | ||
3204 | 3475 | ||
3205 | ret = adap_init1(adap, &c); | 3476 | /* |
3477 | * Find out what ports are available to us. | ||
3478 | */ | ||
3479 | v = | ||
3480 | FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | | ||
3481 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_PORTVEC); | ||
3482 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 1, &v, &port_vec); | ||
3206 | if (ret < 0) | 3483 | if (ret < 0) |
3207 | goto bye; | 3484 | goto bye; |
3208 | 3485 | ||
3486 | adap->params.nports = hweight32(port_vec); | ||
3487 | adap->params.portvec = port_vec; | ||
3488 | |||
3489 | /* | ||
3490 | * If the firmware is initialized already (and we're not forcing a | ||
3491 | * master initialization), note that we're living with existing | ||
3492 | * adapter parameters. Otherwise, it's time to try initializing the | ||
3493 | * adapter ... | ||
3494 | */ | ||
3495 | if (state == DEV_STATE_INIT) { | ||
3496 | dev_info(adap->pdev_dev, "Coming up as %s: "\ | ||
3497 | "Adapter already initialized\n", | ||
3498 | adap->flags & MASTER_PF ? "MASTER" : "SLAVE"); | ||
3499 | adap->flags |= USING_SOFT_PARAMS; | ||
3500 | } else { | ||
3501 | dev_info(adap->pdev_dev, "Coming up as MASTER: "\ | ||
3502 | "Initializing adapter\n"); | ||
3503 | /* | ||
3504 | * Find out whether we're dealing with a version of | ||
3505 | * the firmware which has configuration file support. | ||
3506 | */ | ||
3507 | params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | | ||
3508 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CF)); | ||
3509 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 1, | ||
3510 | params, val); | ||
3511 | |||
3512 | /* | ||
3513 | * If the firmware doesn't support Configuration | ||
3514 | * Files warn user and exit, | ||
3515 | */ | ||
3516 | if (ret < 0) | ||
3517 | dev_warn(adap->pdev_dev, "Firmware doesn't support "\ | ||
3518 | "configuration file.\n"); | ||
3519 | else { | ||
3520 | /* | ||
3521 | * The firmware provides us with a memory | ||
3522 | * buffer where we can load a Configuration | ||
3523 | * File from the host if we want to override | ||
3524 | * the Configuration File in flash. | ||
3525 | */ | ||
3526 | |||
3527 | ret = adap_init0_config(adap, reset); | ||
3528 | if (ret == -ENOENT) { | ||
3529 | dev_info(adap->pdev_dev, | ||
3530 | "No Configuration File present " | ||
3531 | "on adapter.\n"); | ||
3532 | } | ||
3533 | } | ||
3534 | if (ret < 0) { | ||
3535 | dev_err(adap->pdev_dev, | ||
3536 | "could not initialize adapter, error %d\n", | ||
3537 | -ret); | ||
3538 | goto bye; | ||
3539 | } | ||
3540 | } | ||
3541 | |||
3542 | /* | ||
3543 | * If we're living with non-hard-coded parameters (either from a | ||
3544 | * Firmware Configuration File or values programmed by a different PF | ||
3545 | * Driver), give the SGE code a chance to pull in anything that it | ||
3546 | * needs ... Note that this must be called after we retrieve our VPD | ||
3547 | * parameters in order to know how to convert core ticks to seconds. | ||
3548 | */ | ||
3549 | if (adap->flags & USING_SOFT_PARAMS) { | ||
3550 | ret = t4_sge_init(adap); | ||
3551 | if (ret < 0) | ||
3552 | goto bye; | ||
3553 | } | ||
3554 | |||
3555 | /* | ||
3556 | * Grab some of our basic fundamental operating parameters. | ||
3557 | */ | ||
3558 | #define FW_PARAM_DEV(param) \ | ||
3559 | (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ | ||
3560 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) | ||
3561 | |||
3209 | #define FW_PARAM_PFVF(param) \ | 3562 | #define FW_PARAM_PFVF(param) \ |
3210 | (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ | 3563 | FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ |
3211 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param) | \ | 3564 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param)| \ |
3212 | FW_PARAMS_PARAM_Y(adap->fn)) | 3565 | FW_PARAMS_PARAM_Y(0) | \ |
3566 | FW_PARAMS_PARAM_Z(0) | ||
3213 | 3567 | ||
3214 | params[0] = FW_PARAM_DEV(PORTVEC); | 3568 | params[0] = FW_PARAM_PFVF(EQ_START); |
3215 | params[1] = FW_PARAM_PFVF(L2T_START); | 3569 | params[1] = FW_PARAM_PFVF(L2T_START); |
3216 | params[2] = FW_PARAM_PFVF(L2T_END); | 3570 | params[2] = FW_PARAM_PFVF(L2T_END); |
3217 | params[3] = FW_PARAM_PFVF(FILTER_START); | 3571 | params[3] = FW_PARAM_PFVF(FILTER_START); |
3218 | params[4] = FW_PARAM_PFVF(FILTER_END); | 3572 | params[4] = FW_PARAM_PFVF(FILTER_END); |
3219 | params[5] = FW_PARAM_PFVF(IQFLINT_START); | 3573 | params[5] = FW_PARAM_PFVF(IQFLINT_START); |
3220 | params[6] = FW_PARAM_PFVF(EQ_START); | 3574 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 6, params, val); |
3221 | ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val); | ||
3222 | if (ret < 0) | 3575 | if (ret < 0) |
3223 | goto bye; | 3576 | goto bye; |
3224 | port_vec = val[0]; | 3577 | adap->sge.egr_start = val[0]; |
3578 | adap->l2t_start = val[1]; | ||
3579 | adap->l2t_end = val[2]; | ||
3225 | adap->tids.ftid_base = val[3]; | 3580 | adap->tids.ftid_base = val[3]; |
3226 | adap->tids.nftids = val[4] - val[3] + 1; | 3581 | adap->tids.nftids = val[4] - val[3] + 1; |
3227 | adap->sge.ingr_start = val[5]; | 3582 | adap->sge.ingr_start = val[5]; |
3228 | adap->sge.egr_start = val[6]; | ||
3229 | 3583 | ||
3230 | if (c.ofldcaps) { | 3584 | /* query params related to active filter region */ |
3585 | params[0] = FW_PARAM_PFVF(ACTIVE_FILTER_START); | ||
3586 | params[1] = FW_PARAM_PFVF(ACTIVE_FILTER_END); | ||
3587 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val); | ||
3588 | /* If Active filter size is set we enable establishing | ||
3589 | * offload connection through firmware work request | ||
3590 | */ | ||
3591 | if ((val[0] != val[1]) && (ret >= 0)) { | ||
3592 | adap->flags |= FW_OFLD_CONN; | ||
3593 | adap->tids.aftid_base = val[0]; | ||
3594 | adap->tids.aftid_end = val[1]; | ||
3595 | } | ||
3596 | |||
3597 | #ifdef CONFIG_CHELSIO_T4_OFFLOAD | ||
3598 | /* | ||
3599 | * Get device capabilities so we can determine what resources we need | ||
3600 | * to manage. | ||
3601 | */ | ||
3602 | memset(&caps_cmd, 0, sizeof(caps_cmd)); | ||
3603 | caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
3604 | F_FW_CMD_REQUEST | F_FW_CMD_READ); | ||
3605 | caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); | ||
3606 | ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), | ||
3607 | &caps_cmd); | ||
3608 | if (ret < 0) | ||
3609 | goto bye; | ||
3610 | |||
3611 | if (caps_cmd.toecaps) { | ||
3231 | /* query offload-related parameters */ | 3612 | /* query offload-related parameters */ |
3232 | params[0] = FW_PARAM_DEV(NTID); | 3613 | params[0] = FW_PARAM_DEV(NTID); |
3233 | params[1] = FW_PARAM_PFVF(SERVER_START); | 3614 | params[1] = FW_PARAM_PFVF(SERVER_START); |
@@ -3235,28 +3616,55 @@ static int adap_init0(struct adapter *adap) | |||
3235 | params[3] = FW_PARAM_PFVF(TDDP_START); | 3616 | params[3] = FW_PARAM_PFVF(TDDP_START); |
3236 | params[4] = FW_PARAM_PFVF(TDDP_END); | 3617 | params[4] = FW_PARAM_PFVF(TDDP_END); |
3237 | params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); | 3618 | params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); |
3238 | ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, | 3619 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 6, |
3239 | val); | 3620 | params, val); |
3240 | if (ret < 0) | 3621 | if (ret < 0) |
3241 | goto bye; | 3622 | goto bye; |
3242 | adap->tids.ntids = val[0]; | 3623 | adap->tids.ntids = val[0]; |
3243 | adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS); | 3624 | adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS); |
3244 | adap->tids.stid_base = val[1]; | 3625 | adap->tids.stid_base = val[1]; |
3245 | adap->tids.nstids = val[2] - val[1] + 1; | 3626 | adap->tids.nstids = val[2] - val[1] + 1; |
3627 | /* | ||
3628 | * Setup server filter region. Divide the availble filter | ||
3629 | * region into two parts. Regular filters get 1/3rd and server | ||
3630 | * filters get 2/3rd part. This is only enabled if workarond | ||
3631 | * path is enabled. | ||
3632 | * 1. For regular filters. | ||
3633 | * 2. Server filter: This are special filters which are used | ||
3634 | * to redirect SYN packets to offload queue. | ||
3635 | */ | ||
3636 | if (adap->flags & FW_OFLD_CONN && !is_bypass(adap)) { | ||
3637 | adap->tids.sftid_base = adap->tids.ftid_base + | ||
3638 | DIV_ROUND_UP(adap->tids.nftids, 3); | ||
3639 | adap->tids.nsftids = adap->tids.nftids - | ||
3640 | DIV_ROUND_UP(adap->tids.nftids, 3); | ||
3641 | adap->tids.nftids = adap->tids.sftid_base - | ||
3642 | adap->tids.ftid_base; | ||
3643 | } | ||
3246 | adap->vres.ddp.start = val[3]; | 3644 | adap->vres.ddp.start = val[3]; |
3247 | adap->vres.ddp.size = val[4] - val[3] + 1; | 3645 | adap->vres.ddp.size = val[4] - val[3] + 1; |
3248 | adap->params.ofldq_wr_cred = val[5]; | 3646 | adap->params.ofldq_wr_cred = val[5]; |
3647 | |||
3648 | params[0] = FW_PARAM_PFVF(ETHOFLD_START); | ||
3649 | params[1] = FW_PARAM_PFVF(ETHOFLD_END); | ||
3650 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, | ||
3651 | params, val); | ||
3652 | if ((val[0] != val[1]) && (ret >= 0)) { | ||
3653 | adap->tids.uotid_base = val[0]; | ||
3654 | adap->tids.nuotids = val[1] - val[0] + 1; | ||
3655 | } | ||
3656 | |||
3249 | adap->params.offload = 1; | 3657 | adap->params.offload = 1; |
3250 | } | 3658 | } |
3251 | if (c.rdmacaps) { | 3659 | if (caps_cmd.rdmacaps) { |
3252 | params[0] = FW_PARAM_PFVF(STAG_START); | 3660 | params[0] = FW_PARAM_PFVF(STAG_START); |
3253 | params[1] = FW_PARAM_PFVF(STAG_END); | 3661 | params[1] = FW_PARAM_PFVF(STAG_END); |
3254 | params[2] = FW_PARAM_PFVF(RQ_START); | 3662 | params[2] = FW_PARAM_PFVF(RQ_START); |
3255 | params[3] = FW_PARAM_PFVF(RQ_END); | 3663 | params[3] = FW_PARAM_PFVF(RQ_END); |
3256 | params[4] = FW_PARAM_PFVF(PBL_START); | 3664 | params[4] = FW_PARAM_PFVF(PBL_START); |
3257 | params[5] = FW_PARAM_PFVF(PBL_END); | 3665 | params[5] = FW_PARAM_PFVF(PBL_END); |
3258 | ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, | 3666 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 6, |
3259 | val); | 3667 | params, val); |
3260 | if (ret < 0) | 3668 | if (ret < 0) |
3261 | goto bye; | 3669 | goto bye; |
3262 | adap->vres.stag.start = val[0]; | 3670 | adap->vres.stag.start = val[0]; |
@@ -3272,8 +3680,7 @@ static int adap_init0(struct adapter *adap) | |||
3272 | params[3] = FW_PARAM_PFVF(CQ_END); | 3680 | params[3] = FW_PARAM_PFVF(CQ_END); |
3273 | params[4] = FW_PARAM_PFVF(OCQ_START); | 3681 | params[4] = FW_PARAM_PFVF(OCQ_START); |
3274 | params[5] = FW_PARAM_PFVF(OCQ_END); | 3682 | params[5] = FW_PARAM_PFVF(OCQ_END); |
3275 | ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, | 3683 | ret = t4_query_params(adap, 0, 0, 0, 6, params, val); |
3276 | val); | ||
3277 | if (ret < 0) | 3684 | if (ret < 0) |
3278 | goto bye; | 3685 | goto bye; |
3279 | adap->vres.qp.start = val[0]; | 3686 | adap->vres.qp.start = val[0]; |
@@ -3283,11 +3690,11 @@ static int adap_init0(struct adapter *adap) | |||
3283 | adap->vres.ocq.start = val[4]; | 3690 | adap->vres.ocq.start = val[4]; |
3284 | adap->vres.ocq.size = val[5] - val[4] + 1; | 3691 | adap->vres.ocq.size = val[5] - val[4] + 1; |
3285 | } | 3692 | } |
3286 | if (c.iscsicaps) { | 3693 | if (caps_cmd.iscsicaps) { |
3287 | params[0] = FW_PARAM_PFVF(ISCSI_START); | 3694 | params[0] = FW_PARAM_PFVF(ISCSI_START); |
3288 | params[1] = FW_PARAM_PFVF(ISCSI_END); | 3695 | params[1] = FW_PARAM_PFVF(ISCSI_END); |
3289 | ret = t4_query_params(adap, adap->fn, adap->fn, 0, 2, params, | 3696 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, |
3290 | val); | 3697 | params, val); |
3291 | if (ret < 0) | 3698 | if (ret < 0) |
3292 | goto bye; | 3699 | goto bye; |
3293 | adap->vres.iscsi.start = val[0]; | 3700 | adap->vres.iscsi.start = val[0]; |
@@ -3295,63 +3702,33 @@ static int adap_init0(struct adapter *adap) | |||
3295 | } | 3702 | } |
3296 | #undef FW_PARAM_PFVF | 3703 | #undef FW_PARAM_PFVF |
3297 | #undef FW_PARAM_DEV | 3704 | #undef FW_PARAM_DEV |
3705 | #endif /* CONFIG_CHELSIO_T4_OFFLOAD */ | ||
3298 | 3706 | ||
3299 | adap->params.nports = hweight32(port_vec); | 3707 | /* |
3300 | adap->params.portvec = port_vec; | 3708 | * These are finalized by FW initialization, load their values now. |
3301 | adap->flags |= FW_OK; | 3709 | */ |
3302 | |||
3303 | /* These are finalized by FW initialization, load their values now */ | ||
3304 | v = t4_read_reg(adap, TP_TIMER_RESOLUTION); | 3710 | v = t4_read_reg(adap, TP_TIMER_RESOLUTION); |
3305 | adap->params.tp.tre = TIMERRESOLUTION_GET(v); | 3711 | adap->params.tp.tre = TIMERRESOLUTION_GET(v); |
3712 | adap->params.tp.dack_re = DELAYEDACKRESOLUTION_GET(v); | ||
3306 | t4_read_mtu_tbl(adap, adap->params.mtus, NULL); | 3713 | t4_read_mtu_tbl(adap, adap->params.mtus, NULL); |
3307 | t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, | 3714 | t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, |
3308 | adap->params.b_wnd); | 3715 | adap->params.b_wnd); |
3309 | 3716 | ||
3310 | #ifdef CONFIG_PCI_IOV | 3717 | /* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */ |
3311 | /* | 3718 | for (j = 0; j < NCHAN; j++) |
3312 | * Provision resource limits for Virtual Functions. We currently | 3719 | adap->params.tp.tx_modq[j] = j; |
3313 | * grant them all the same static resource limits except for the Port | ||
3314 | * Access Rights Mask which we're assigning based on the PF. All of | ||
3315 | * the static provisioning stuff for both the PF and VF really needs | ||
3316 | * to be managed in a persistent manner for each device which the | ||
3317 | * firmware controls. | ||
3318 | */ | ||
3319 | { | ||
3320 | int pf, vf; | ||
3321 | |||
3322 | for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) { | ||
3323 | if (num_vf[pf] <= 0) | ||
3324 | continue; | ||
3325 | |||
3326 | /* VF numbering starts at 1! */ | ||
3327 | for (vf = 1; vf <= num_vf[pf]; vf++) { | ||
3328 | ret = t4_cfg_pfvf(adap, adap->fn, pf, vf, | ||
3329 | VFRES_NEQ, VFRES_NETHCTRL, | ||
3330 | VFRES_NIQFLINT, VFRES_NIQ, | ||
3331 | VFRES_TC, VFRES_NVI, | ||
3332 | FW_PFVF_CMD_CMASK_MASK, | ||
3333 | pfvfres_pmask(adap, pf, vf), | ||
3334 | VFRES_NEXACTF, | ||
3335 | VFRES_R_CAPS, VFRES_WX_CAPS); | ||
3336 | if (ret < 0) | ||
3337 | dev_warn(adap->pdev_dev, "failed to " | ||
3338 | "provision pf/vf=%d/%d; " | ||
3339 | "err=%d\n", pf, vf, ret); | ||
3340 | } | ||
3341 | } | ||
3342 | } | ||
3343 | #endif | ||
3344 | 3720 | ||
3345 | setup_memwin(adap); | 3721 | adap->flags |= FW_OK; |
3346 | return 0; | 3722 | return 0; |
3347 | 3723 | ||
3348 | /* | 3724 | /* |
3349 | * If a command timed out or failed with EIO FW does not operate within | 3725 | * Something bad happened. If a command timed out or failed with EIO |
3350 | * its spec or something catastrophic happened to HW/FW, stop issuing | 3726 | * FW does not operate within its spec or something catastrophic |
3351 | * commands. | 3727 | * happened to HW/FW, stop issuing commands. |
3352 | */ | 3728 | */ |
3353 | bye: if (ret != -ETIMEDOUT && ret != -EIO) | 3729 | bye: |
3354 | t4_fw_bye(adap, adap->fn); | 3730 | if (ret != -ETIMEDOUT && ret != -EIO) |
3731 | t4_fw_bye(adap, adap->mbox); | ||
3355 | return ret; | 3732 | return ret; |
3356 | } | 3733 | } |
3357 | 3734 | ||
@@ -3814,7 +4191,9 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3814 | err = t4_prep_adapter(adapter); | 4191 | err = t4_prep_adapter(adapter); |
3815 | if (err) | 4192 | if (err) |
3816 | goto out_unmap_bar; | 4193 | goto out_unmap_bar; |
4194 | setup_memwin(adapter); | ||
3817 | err = adap_init0(adapter); | 4195 | err = adap_init0(adapter); |
4196 | setup_memwin_rdma(adapter); | ||
3818 | if (err) | 4197 | if (err) |
3819 | goto out_unmap_bar; | 4198 | goto out_unmap_bar; |
3820 | 4199 | ||
@@ -3956,8 +4335,11 @@ static void __devexit remove_one(struct pci_dev *pdev) | |||
3956 | { | 4335 | { |
3957 | struct adapter *adapter = pci_get_drvdata(pdev); | 4336 | struct adapter *adapter = pci_get_drvdata(pdev); |
3958 | 4337 | ||
4338 | #ifdef CONFIG_PCI_IOV | ||
3959 | pci_disable_sriov(pdev); | 4339 | pci_disable_sriov(pdev); |
3960 | 4340 | ||
4341 | #endif | ||
4342 | |||
3961 | if (adapter) { | 4343 | if (adapter) { |
3962 | int i; | 4344 | int i; |
3963 | 4345 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index d79980c5fc63..1b899fea1a91 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | |||
@@ -100,6 +100,8 @@ struct tid_info { | |||
100 | 100 | ||
101 | unsigned int nftids; | 101 | unsigned int nftids; |
102 | unsigned int ftid_base; | 102 | unsigned int ftid_base; |
103 | unsigned int aftid_base; | ||
104 | unsigned int aftid_end; | ||
103 | 105 | ||
104 | spinlock_t atid_lock ____cacheline_aligned_in_smp; | 106 | spinlock_t atid_lock ____cacheline_aligned_in_smp; |
105 | union aopen_entry *afree; | 107 | union aopen_entry *afree; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 259d0dcb0089..419432d42049 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -492,8 +492,9 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable) | |||
492 | * | 492 | * |
493 | * Reads card parameters stored in VPD EEPROM. | 493 | * Reads card parameters stored in VPD EEPROM. |
494 | */ | 494 | */ |
495 | static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | 495 | int get_vpd_params(struct adapter *adapter, struct vpd_params *p) |
496 | { | 496 | { |
497 | u32 cclk_param, cclk_val; | ||
497 | int i, ret; | 498 | int i, ret; |
498 | int ec, sn; | 499 | int ec, sn; |
499 | u8 vpd[VPD_LEN], csum; | 500 | u8 vpd[VPD_LEN], csum; |
@@ -555,6 +556,19 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
555 | i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); | 556 | i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); |
556 | memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); | 557 | memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); |
557 | strim(p->sn); | 558 | strim(p->sn); |
559 | |||
560 | /* | ||
561 | * Ask firmware for the Core Clock since it knows how to translate the | ||
562 | * Reference Clock ('V2') VPD field into a Core Clock value ... | ||
563 | */ | ||
564 | cclk_param = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | | ||
565 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); | ||
566 | ret = t4_query_params(adapter, adapter->mbox, 0, 0, | ||
567 | 1, &cclk_param, &cclk_val); | ||
568 | if (ret) | ||
569 | return ret; | ||
570 | p->cclk = cclk_val; | ||
571 | |||
558 | return 0; | 572 | return 0; |
559 | } | 573 | } |
560 | 574 | ||
@@ -855,6 +869,77 @@ static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end) | |||
855 | } | 869 | } |
856 | 870 | ||
857 | /** | 871 | /** |
872 | * t4_flash_cfg_addr - return the address of the flash configuration file | ||
873 | * @adapter: the adapter | ||
874 | * | ||
875 | * Return the address within the flash where the Firmware Configuration | ||
876 | * File is stored. | ||
877 | */ | ||
878 | unsigned int t4_flash_cfg_addr(struct adapter *adapter) | ||
879 | { | ||
880 | if (adapter->params.sf_size == 0x100000) | ||
881 | return FLASH_FPGA_CFG_START; | ||
882 | else | ||
883 | return FLASH_CFG_START; | ||
884 | } | ||
885 | |||
886 | /** | ||
887 | * t4_load_cfg - download config file | ||
888 | * @adap: the adapter | ||
889 | * @cfg_data: the cfg text file to write | ||
890 | * @size: text file size | ||
891 | * | ||
892 | * Write the supplied config text file to the card's serial flash. | ||
893 | */ | ||
894 | int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) | ||
895 | { | ||
896 | int ret, i, n; | ||
897 | unsigned int addr; | ||
898 | unsigned int flash_cfg_start_sec; | ||
899 | unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec; | ||
900 | |||
901 | addr = t4_flash_cfg_addr(adap); | ||
902 | flash_cfg_start_sec = addr / SF_SEC_SIZE; | ||
903 | |||
904 | if (size > FLASH_CFG_MAX_SIZE) { | ||
905 | dev_err(adap->pdev_dev, "cfg file too large, max is %u bytes\n", | ||
906 | FLASH_CFG_MAX_SIZE); | ||
907 | return -EFBIG; | ||
908 | } | ||
909 | |||
910 | i = DIV_ROUND_UP(FLASH_CFG_MAX_SIZE, /* # of sectors spanned */ | ||
911 | sf_sec_size); | ||
912 | ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec, | ||
913 | flash_cfg_start_sec + i - 1); | ||
914 | /* | ||
915 | * If size == 0 then we're simply erasing the FLASH sectors associated | ||
916 | * with the on-adapter Firmware Configuration File. | ||
917 | */ | ||
918 | if (ret || size == 0) | ||
919 | goto out; | ||
920 | |||
921 | /* this will write to the flash up to SF_PAGE_SIZE at a time */ | ||
922 | for (i = 0; i < size; i += SF_PAGE_SIZE) { | ||
923 | if ((size - i) < SF_PAGE_SIZE) | ||
924 | n = size - i; | ||
925 | else | ||
926 | n = SF_PAGE_SIZE; | ||
927 | ret = t4_write_flash(adap, addr, n, cfg_data); | ||
928 | if (ret) | ||
929 | goto out; | ||
930 | |||
931 | addr += SF_PAGE_SIZE; | ||
932 | cfg_data += SF_PAGE_SIZE; | ||
933 | } | ||
934 | |||
935 | out: | ||
936 | if (ret) | ||
937 | dev_err(adap->pdev_dev, "config file %s failed %d\n", | ||
938 | (size == 0 ? "clear" : "download"), ret); | ||
939 | return ret; | ||
940 | } | ||
941 | |||
942 | /** | ||
858 | * t4_load_fw - download firmware | 943 | * t4_load_fw - download firmware |
859 | * @adap: the adapter | 944 | * @adap: the adapter |
860 | * @fw_data: the firmware image to write | 945 | * @fw_data: the firmware image to write |
@@ -1854,6 +1939,23 @@ void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log) | |||
1854 | } | 1939 | } |
1855 | 1940 | ||
1856 | /** | 1941 | /** |
1942 | * t4_tp_wr_bits_indirect - set/clear bits in an indirect TP register | ||
1943 | * @adap: the adapter | ||
1944 | * @addr: the indirect TP register address | ||
1945 | * @mask: specifies the field within the register to modify | ||
1946 | * @val: new value for the field | ||
1947 | * | ||
1948 | * Sets a field of an indirect TP register to the given value. | ||
1949 | */ | ||
1950 | void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr, | ||
1951 | unsigned int mask, unsigned int val) | ||
1952 | { | ||
1953 | t4_write_reg(adap, TP_PIO_ADDR, addr); | ||
1954 | val |= t4_read_reg(adap, TP_PIO_DATA) & ~mask; | ||
1955 | t4_write_reg(adap, TP_PIO_DATA, val); | ||
1956 | } | ||
1957 | |||
1958 | /** | ||
1857 | * init_cong_ctrl - initialize congestion control parameters | 1959 | * init_cong_ctrl - initialize congestion control parameters |
1858 | * @a: the alpha values for congestion control | 1960 | * @a: the alpha values for congestion control |
1859 | * @b: the beta values for congestion control | 1961 | * @b: the beta values for congestion control |
@@ -2137,9 +2239,9 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, | |||
2137 | struct fw_ldst_cmd c; | 2239 | struct fw_ldst_cmd c; |
2138 | 2240 | ||
2139 | memset(&c, 0, sizeof(c)); | 2241 | memset(&c, 0, sizeof(c)); |
2140 | c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST | | 2242 | c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST | |
2141 | F_FW_CMD_WRITE | | 2243 | FW_CMD_WRITE | |
2142 | V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE)); | 2244 | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE)); |
2143 | c.cycles_to_len16 = htonl(FW_LEN16(c)); | 2245 | c.cycles_to_len16 = htonl(FW_LEN16(c)); |
2144 | c.u.addrval.addr = htonl(addr); | 2246 | c.u.addrval.addr = htonl(addr); |
2145 | c.u.addrval.val = htonl(val); | 2247 | c.u.addrval.val = htonl(val); |
@@ -2239,39 +2341,129 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, | |||
2239 | } | 2341 | } |
2240 | 2342 | ||
2241 | /** | 2343 | /** |
2242 | * t4_fw_hello - establish communication with FW | 2344 | * t4_fw_hello - establish communication with FW |
2243 | * @adap: the adapter | 2345 | * @adap: the adapter |
2244 | * @mbox: mailbox to use for the FW command | 2346 | * @mbox: mailbox to use for the FW command |
2245 | * @evt_mbox: mailbox to receive async FW events | 2347 | * @evt_mbox: mailbox to receive async FW events |
2246 | * @master: specifies the caller's willingness to be the device master | 2348 | * @master: specifies the caller's willingness to be the device master |
2247 | * @state: returns the current device state | 2349 | * @state: returns the current device state (if non-NULL) |
2248 | * | 2350 | * |
2249 | * Issues a command to establish communication with FW. | 2351 | * Issues a command to establish communication with FW. Returns either |
2352 | * an error (negative integer) or the mailbox of the Master PF. | ||
2250 | */ | 2353 | */ |
2251 | int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, | 2354 | int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, |
2252 | enum dev_master master, enum dev_state *state) | 2355 | enum dev_master master, enum dev_state *state) |
2253 | { | 2356 | { |
2254 | int ret; | 2357 | int ret; |
2255 | struct fw_hello_cmd c; | 2358 | struct fw_hello_cmd c; |
2359 | u32 v; | ||
2360 | unsigned int master_mbox; | ||
2361 | int retries = FW_CMD_HELLO_RETRIES; | ||
2256 | 2362 | ||
2363 | retry: | ||
2364 | memset(&c, 0, sizeof(c)); | ||
2257 | INIT_CMD(c, HELLO, WRITE); | 2365 | INIT_CMD(c, HELLO, WRITE); |
2258 | c.err_to_mbasyncnot = htonl( | 2366 | c.err_to_mbasyncnot = htonl( |
2259 | FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) | | 2367 | FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) | |
2260 | FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) | | 2368 | FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) | |
2261 | FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : 0xff) | | 2369 | FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : |
2262 | FW_HELLO_CMD_MBASYNCNOT(evt_mbox)); | 2370 | FW_HELLO_CMD_MBMASTER_MASK) | |
2371 | FW_HELLO_CMD_MBASYNCNOT(evt_mbox) | | ||
2372 | FW_HELLO_CMD_STAGE(fw_hello_cmd_stage_os) | | ||
2373 | FW_HELLO_CMD_CLEARINIT); | ||
2263 | 2374 | ||
2375 | /* | ||
2376 | * Issue the HELLO command to the firmware. If it's not successful | ||
2377 | * but indicates that we got a "busy" or "timeout" condition, retry | ||
2378 | * the HELLO until we exhaust our retry limit. | ||
2379 | */ | ||
2264 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | 2380 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); |
2265 | if (ret == 0 && state) { | 2381 | if (ret < 0) { |
2266 | u32 v = ntohl(c.err_to_mbasyncnot); | 2382 | if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) |
2267 | if (v & FW_HELLO_CMD_INIT) | 2383 | goto retry; |
2268 | *state = DEV_STATE_INIT; | 2384 | return ret; |
2269 | else if (v & FW_HELLO_CMD_ERR) | 2385 | } |
2386 | |||
2387 | v = ntohl(c.err_to_mbasyncnot); | ||
2388 | master_mbox = FW_HELLO_CMD_MBMASTER_GET(v); | ||
2389 | if (state) { | ||
2390 | if (v & FW_HELLO_CMD_ERR) | ||
2270 | *state = DEV_STATE_ERR; | 2391 | *state = DEV_STATE_ERR; |
2392 | else if (v & FW_HELLO_CMD_INIT) | ||
2393 | *state = DEV_STATE_INIT; | ||
2271 | else | 2394 | else |
2272 | *state = DEV_STATE_UNINIT; | 2395 | *state = DEV_STATE_UNINIT; |
2273 | } | 2396 | } |
2274 | return ret; | 2397 | |
2398 | /* | ||
2399 | * If we're not the Master PF then we need to wait around for the | ||
2400 | * Master PF Driver to finish setting up the adapter. | ||
2401 | * | ||
2402 | * Note that we also do this wait if we're a non-Master-capable PF and | ||
2403 | * there is no current Master PF; a Master PF may show up momentarily | ||
2404 | * and we wouldn't want to fail pointlessly. (This can happen when an | ||
2405 | * OS loads lots of different drivers rapidly at the same time). In | ||
2406 | * this case, the Master PF returned by the firmware will be | ||
2407 | * FW_PCIE_FW_MASTER_MASK so the test below will work ... | ||
2408 | */ | ||
2409 | if ((v & (FW_HELLO_CMD_ERR|FW_HELLO_CMD_INIT)) == 0 && | ||
2410 | master_mbox != mbox) { | ||
2411 | int waiting = FW_CMD_HELLO_TIMEOUT; | ||
2412 | |||
2413 | /* | ||
2414 | * Wait for the firmware to either indicate an error or | ||
2415 | * initialized state. If we see either of these we bail out | ||
2416 | * and report the issue to the caller. If we exhaust the | ||
2417 | * "hello timeout" and we haven't exhausted our retries, try | ||
2418 | * again. Otherwise bail with a timeout error. | ||
2419 | */ | ||
2420 | for (;;) { | ||
2421 | u32 pcie_fw; | ||
2422 | |||
2423 | msleep(50); | ||
2424 | waiting -= 50; | ||
2425 | |||
2426 | /* | ||
2427 | * If neither Error nor Initialialized are indicated | ||
2428 | * by the firmware keep waiting till we exaust our | ||
2429 | * timeout ... and then retry if we haven't exhausted | ||
2430 | * our retries ... | ||
2431 | */ | ||
2432 | pcie_fw = t4_read_reg(adap, MA_PCIE_FW); | ||
2433 | if (!(pcie_fw & (FW_PCIE_FW_ERR|FW_PCIE_FW_INIT))) { | ||
2434 | if (waiting <= 0) { | ||
2435 | if (retries-- > 0) | ||
2436 | goto retry; | ||
2437 | |||
2438 | return -ETIMEDOUT; | ||
2439 | } | ||
2440 | continue; | ||
2441 | } | ||
2442 | |||
2443 | /* | ||
2444 | * We either have an Error or Initialized condition | ||
2445 | * report errors preferentially. | ||
2446 | */ | ||
2447 | if (state) { | ||
2448 | if (pcie_fw & FW_PCIE_FW_ERR) | ||
2449 | *state = DEV_STATE_ERR; | ||
2450 | else if (pcie_fw & FW_PCIE_FW_INIT) | ||
2451 | *state = DEV_STATE_INIT; | ||
2452 | } | ||
2453 | |||
2454 | /* | ||
2455 | * If we arrived before a Master PF was selected and | ||
2456 | * there's not a valid Master PF, grab its identity | ||
2457 | * for our caller. | ||
2458 | */ | ||
2459 | if (master_mbox == FW_PCIE_FW_MASTER_MASK && | ||
2460 | (pcie_fw & FW_PCIE_FW_MASTER_VLD)) | ||
2461 | master_mbox = FW_PCIE_FW_MASTER_GET(pcie_fw); | ||
2462 | break; | ||
2463 | } | ||
2464 | } | ||
2465 | |||
2466 | return master_mbox; | ||
2275 | } | 2467 | } |
2276 | 2468 | ||
2277 | /** | 2469 | /** |
@@ -2323,6 +2515,163 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) | |||
2323 | } | 2515 | } |
2324 | 2516 | ||
2325 | /** | 2517 | /** |
2518 | * t4_fw_config_file - setup an adapter via a Configuration File | ||
2519 | * @adap: the adapter | ||
2520 | * @mbox: mailbox to use for the FW command | ||
2521 | * @mtype: the memory type where the Configuration File is located | ||
2522 | * @maddr: the memory address where the Configuration File is located | ||
2523 | * @finiver: return value for CF [fini] version | ||
2524 | * @finicsum: return value for CF [fini] checksum | ||
2525 | * @cfcsum: return value for CF computed checksum | ||
2526 | * | ||
2527 | * Issue a command to get the firmware to process the Configuration | ||
2528 | * File located at the specified mtype/maddress. If the Configuration | ||
2529 | * File is processed successfully and return value pointers are | ||
2530 | * provided, the Configuration File "[fini] section version and | ||
2531 | * checksum values will be returned along with the computed checksum. | ||
2532 | * It's up to the caller to decide how it wants to respond to the | ||
2533 | * checksums not matching but it recommended that a prominant warning | ||
2534 | * be emitted in order to help people rapidly identify changed or | ||
2535 | * corrupted Configuration Files. | ||
2536 | * | ||
2537 | * Also note that it's possible to modify things like "niccaps", | ||
2538 | * "toecaps",etc. between processing the Configuration File and telling | ||
2539 | * the firmware to use the new configuration. Callers which want to | ||
2540 | * do this will need to "hand-roll" their own CAPS_CONFIGS commands for | ||
2541 | * Configuration Files if they want to do this. | ||
2542 | */ | ||
2543 | int t4_fw_config_file(struct adapter *adap, unsigned int mbox, | ||
2544 | unsigned int mtype, unsigned int maddr, | ||
2545 | u32 *finiver, u32 *finicsum, u32 *cfcsum) | ||
2546 | { | ||
2547 | struct fw_caps_config_cmd caps_cmd; | ||
2548 | int ret; | ||
2549 | |||
2550 | /* | ||
2551 | * Tell the firmware to process the indicated Configuration File. | ||
2552 | * If there are no errors and the caller has provided return value | ||
2553 | * pointers for the [fini] section version, checksum and computed | ||
2554 | * checksum, pass those back to the caller. | ||
2555 | */ | ||
2556 | memset(&caps_cmd, 0, sizeof(caps_cmd)); | ||
2557 | caps_cmd.op_to_write = | ||
2558 | htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
2559 | FW_CMD_REQUEST | | ||
2560 | FW_CMD_READ); | ||
2561 | caps_cmd.retval_len16 = | ||
2562 | htonl(FW_CAPS_CONFIG_CMD_CFVALID | | ||
2563 | FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | | ||
2564 | FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) | | ||
2565 | FW_LEN16(caps_cmd)); | ||
2566 | ret = t4_wr_mbox(adap, mbox, &caps_cmd, sizeof(caps_cmd), &caps_cmd); | ||
2567 | if (ret < 0) | ||
2568 | return ret; | ||
2569 | |||
2570 | if (finiver) | ||
2571 | *finiver = ntohl(caps_cmd.finiver); | ||
2572 | if (finicsum) | ||
2573 | *finicsum = ntohl(caps_cmd.finicsum); | ||
2574 | if (cfcsum) | ||
2575 | *cfcsum = ntohl(caps_cmd.cfcsum); | ||
2576 | |||
2577 | /* | ||
2578 | * And now tell the firmware to use the configuration we just loaded. | ||
2579 | */ | ||
2580 | caps_cmd.op_to_write = | ||
2581 | htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
2582 | FW_CMD_REQUEST | | ||
2583 | FW_CMD_WRITE); | ||
2584 | caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); | ||
2585 | return t4_wr_mbox(adap, mbox, &caps_cmd, sizeof(caps_cmd), NULL); | ||
2586 | } | ||
2587 | |||
2588 | /** | ||
2589 | * t4_fixup_host_params - fix up host-dependent parameters | ||
2590 | * @adap: the adapter | ||
2591 | * @page_size: the host's Base Page Size | ||
2592 | * @cache_line_size: the host's Cache Line Size | ||
2593 | * | ||
2594 | * Various registers in T4 contain values which are dependent on the | ||
2595 | * host's Base Page and Cache Line Sizes. This function will fix all of | ||
2596 | * those registers with the appropriate values as passed in ... | ||
2597 | */ | ||
2598 | int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, | ||
2599 | unsigned int cache_line_size) | ||
2600 | { | ||
2601 | unsigned int page_shift = fls(page_size) - 1; | ||
2602 | unsigned int sge_hps = page_shift - 10; | ||
2603 | unsigned int stat_len = cache_line_size > 64 ? 128 : 64; | ||
2604 | unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size; | ||
2605 | unsigned int fl_align_log = fls(fl_align) - 1; | ||
2606 | |||
2607 | t4_write_reg(adap, SGE_HOST_PAGE_SIZE, | ||
2608 | HOSTPAGESIZEPF0(sge_hps) | | ||
2609 | HOSTPAGESIZEPF1(sge_hps) | | ||
2610 | HOSTPAGESIZEPF2(sge_hps) | | ||
2611 | HOSTPAGESIZEPF3(sge_hps) | | ||
2612 | HOSTPAGESIZEPF4(sge_hps) | | ||
2613 | HOSTPAGESIZEPF5(sge_hps) | | ||
2614 | HOSTPAGESIZEPF6(sge_hps) | | ||
2615 | HOSTPAGESIZEPF7(sge_hps)); | ||
2616 | |||
2617 | t4_set_reg_field(adap, SGE_CONTROL, | ||
2618 | INGPADBOUNDARY(INGPADBOUNDARY_MASK) | | ||
2619 | EGRSTATUSPAGESIZE_MASK, | ||
2620 | INGPADBOUNDARY(fl_align_log - 5) | | ||
2621 | EGRSTATUSPAGESIZE(stat_len != 64)); | ||
2622 | |||
2623 | /* | ||
2624 | * Adjust various SGE Free List Host Buffer Sizes. | ||
2625 | * | ||
2626 | * This is something of a crock since we're using fixed indices into | ||
2627 | * the array which are also known by the sge.c code and the T4 | ||
2628 | * Firmware Configuration File. We need to come up with a much better | ||
2629 | * approach to managing this array. For now, the first four entries | ||
2630 | * are: | ||
2631 | * | ||
2632 | * 0: Host Page Size | ||
2633 | * 1: 64KB | ||
2634 | * 2: Buffer size corresponding to 1500 byte MTU (unpacked mode) | ||
2635 | * 3: Buffer size corresponding to 9000 byte MTU (unpacked mode) | ||
2636 | * | ||
2637 | * For the single-MTU buffers in unpacked mode we need to include | ||
2638 | * space for the SGE Control Packet Shift, 14 byte Ethernet header, | ||
2639 | * possible 4 byte VLAN tag, all rounded up to the next Ingress Packet | ||
2640 | * Padding boundry. All of these are accommodated in the Factory | ||
2641 | * Default Firmware Configuration File but we need to adjust it for | ||
2642 | * this host's cache line size. | ||
2643 | */ | ||
2644 | t4_write_reg(adap, SGE_FL_BUFFER_SIZE0, page_size); | ||
2645 | t4_write_reg(adap, SGE_FL_BUFFER_SIZE2, | ||
2646 | (t4_read_reg(adap, SGE_FL_BUFFER_SIZE2) + fl_align-1) | ||
2647 | & ~(fl_align-1)); | ||
2648 | t4_write_reg(adap, SGE_FL_BUFFER_SIZE3, | ||
2649 | (t4_read_reg(adap, SGE_FL_BUFFER_SIZE3) + fl_align-1) | ||
2650 | & ~(fl_align-1)); | ||
2651 | |||
2652 | t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(page_shift - 12)); | ||
2653 | |||
2654 | return 0; | ||
2655 | } | ||
2656 | |||
2657 | /** | ||
2658 | * t4_fw_initialize - ask FW to initialize the device | ||
2659 | * @adap: the adapter | ||
2660 | * @mbox: mailbox to use for the FW command | ||
2661 | * | ||
2662 | * Issues a command to FW to partially initialize the device. This | ||
2663 | * performs initialization that generally doesn't depend on user input. | ||
2664 | */ | ||
2665 | int t4_fw_initialize(struct adapter *adap, unsigned int mbox) | ||
2666 | { | ||
2667 | struct fw_initialize_cmd c; | ||
2668 | |||
2669 | memset(&c, 0, sizeof(c)); | ||
2670 | INIT_CMD(c, INITIALIZE, WRITE); | ||
2671 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2672 | } | ||
2673 | |||
2674 | /** | ||
2326 | * t4_query_params - query FW or device parameters | 2675 | * t4_query_params - query FW or device parameters |
2327 | * @adap: the adapter | 2676 | * @adap: the adapter |
2328 | * @mbox: mailbox to use for the FW command | 2677 | * @mbox: mailbox to use for the FW command |
@@ -2974,10 +3323,6 @@ int __devinit t4_prep_adapter(struct adapter *adapter) | |||
2974 | return ret; | 3323 | return ret; |
2975 | } | 3324 | } |
2976 | 3325 | ||
2977 | ret = get_vpd_params(adapter, &adapter->params.vpd); | ||
2978 | if (ret < 0) | ||
2979 | return ret; | ||
2980 | |||
2981 | init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); | 3326 | init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); |
2982 | 3327 | ||
2983 | /* | 3328 | /* |
@@ -2985,6 +3330,7 @@ int __devinit t4_prep_adapter(struct adapter *adapter) | |||
2985 | */ | 3330 | */ |
2986 | adapter->params.nports = 1; | 3331 | adapter->params.nports = 1; |
2987 | adapter->params.portvec = 1; | 3332 | adapter->params.portvec = 1; |
3333 | adapter->params.vpd.cclk = 50000; | ||
2988 | return 0; | 3334 | return 0; |
2989 | } | 3335 | } |
2990 | 3336 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 2767ca6dbe99..779b23f8f591 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | |||
@@ -115,6 +115,35 @@ | |||
115 | #define GLOBALENABLE 0x00000001U | 115 | #define GLOBALENABLE 0x00000001U |
116 | 116 | ||
117 | #define SGE_HOST_PAGE_SIZE 0x100c | 117 | #define SGE_HOST_PAGE_SIZE 0x100c |
118 | |||
119 | #define HOSTPAGESIZEPF7_MASK 0x0000000fU | ||
120 | #define HOSTPAGESIZEPF7_SHIFT 28 | ||
121 | #define HOSTPAGESIZEPF7(x) ((x) << HOSTPAGESIZEPF7_SHIFT) | ||
122 | |||
123 | #define HOSTPAGESIZEPF6_MASK 0x0000000fU | ||
124 | #define HOSTPAGESIZEPF6_SHIFT 24 | ||
125 | #define HOSTPAGESIZEPF6(x) ((x) << HOSTPAGESIZEPF6_SHIFT) | ||
126 | |||
127 | #define HOSTPAGESIZEPF5_MASK 0x0000000fU | ||
128 | #define HOSTPAGESIZEPF5_SHIFT 20 | ||
129 | #define HOSTPAGESIZEPF5(x) ((x) << HOSTPAGESIZEPF5_SHIFT) | ||
130 | |||
131 | #define HOSTPAGESIZEPF4_MASK 0x0000000fU | ||
132 | #define HOSTPAGESIZEPF4_SHIFT 16 | ||
133 | #define HOSTPAGESIZEPF4(x) ((x) << HOSTPAGESIZEPF4_SHIFT) | ||
134 | |||
135 | #define HOSTPAGESIZEPF3_MASK 0x0000000fU | ||
136 | #define HOSTPAGESIZEPF3_SHIFT 12 | ||
137 | #define HOSTPAGESIZEPF3(x) ((x) << HOSTPAGESIZEPF3_SHIFT) | ||
138 | |||
139 | #define HOSTPAGESIZEPF2_MASK 0x0000000fU | ||
140 | #define HOSTPAGESIZEPF2_SHIFT 8 | ||
141 | #define HOSTPAGESIZEPF2(x) ((x) << HOSTPAGESIZEPF2_SHIFT) | ||
142 | |||
143 | #define HOSTPAGESIZEPF1_MASK 0x0000000fU | ||
144 | #define HOSTPAGESIZEPF1_SHIFT 4 | ||
145 | #define HOSTPAGESIZEPF1(x) ((x) << HOSTPAGESIZEPF1_SHIFT) | ||
146 | |||
118 | #define HOSTPAGESIZEPF0_MASK 0x0000000fU | 147 | #define HOSTPAGESIZEPF0_MASK 0x0000000fU |
119 | #define HOSTPAGESIZEPF0_SHIFT 0 | 148 | #define HOSTPAGESIZEPF0_SHIFT 0 |
120 | #define HOSTPAGESIZEPF0(x) ((x) << HOSTPAGESIZEPF0_SHIFT) | 149 | #define HOSTPAGESIZEPF0(x) ((x) << HOSTPAGESIZEPF0_SHIFT) |
@@ -162,6 +191,8 @@ | |||
162 | #define SGE_INT_ENABLE3 0x1040 | 191 | #define SGE_INT_ENABLE3 0x1040 |
163 | #define SGE_FL_BUFFER_SIZE0 0x1044 | 192 | #define SGE_FL_BUFFER_SIZE0 0x1044 |
164 | #define SGE_FL_BUFFER_SIZE1 0x1048 | 193 | #define SGE_FL_BUFFER_SIZE1 0x1048 |
194 | #define SGE_FL_BUFFER_SIZE2 0x104c | ||
195 | #define SGE_FL_BUFFER_SIZE3 0x1050 | ||
165 | #define SGE_INGRESS_RX_THRESHOLD 0x10a0 | 196 | #define SGE_INGRESS_RX_THRESHOLD 0x10a0 |
166 | #define THRESHOLD_0_MASK 0x3f000000U | 197 | #define THRESHOLD_0_MASK 0x3f000000U |
167 | #define THRESHOLD_0_SHIFT 24 | 198 | #define THRESHOLD_0_SHIFT 24 |
@@ -367,7 +398,7 @@ | |||
367 | #define MEM_WRAP_CLIENT_NUM_MASK 0x0000000fU | 398 | #define MEM_WRAP_CLIENT_NUM_MASK 0x0000000fU |
368 | #define MEM_WRAP_CLIENT_NUM_SHIFT 0 | 399 | #define MEM_WRAP_CLIENT_NUM_SHIFT 0 |
369 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) | 400 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) |
370 | 401 | #define MA_PCIE_FW 0x30b8 | |
371 | #define MA_PARITY_ERROR_STATUS 0x77f4 | 402 | #define MA_PARITY_ERROR_STATUS 0x77f4 |
372 | 403 | ||
373 | #define EDC_0_BASE_ADDR 0x7900 | 404 | #define EDC_0_BASE_ADDR 0x7900 |
@@ -469,6 +500,10 @@ | |||
469 | #define TIMERRESOLUTION_MASK 0x00ff0000U | 500 | #define TIMERRESOLUTION_MASK 0x00ff0000U |
470 | #define TIMERRESOLUTION_SHIFT 16 | 501 | #define TIMERRESOLUTION_SHIFT 16 |
471 | #define TIMERRESOLUTION_GET(x) (((x) & TIMERRESOLUTION_MASK) >> TIMERRESOLUTION_SHIFT) | 502 | #define TIMERRESOLUTION_GET(x) (((x) & TIMERRESOLUTION_MASK) >> TIMERRESOLUTION_SHIFT) |
503 | #define DELAYEDACKRESOLUTION_MASK 0x000000ffU | ||
504 | #define DELAYEDACKRESOLUTION_SHIFT 0 | ||
505 | #define DELAYEDACKRESOLUTION_GET(x) \ | ||
506 | (((x) & DELAYEDACKRESOLUTION_MASK) >> DELAYEDACKRESOLUTION_SHIFT) | ||
472 | 507 | ||
473 | #define TP_SHIFT_CNT 0x7dc0 | 508 | #define TP_SHIFT_CNT 0x7dc0 |
474 | 509 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 94e3484b7d93..3f85019106fa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
@@ -155,6 +155,17 @@ struct fw_eth_tx_pkt_vm_wr { | |||
155 | 155 | ||
156 | #define FW_CMD_MAX_TIMEOUT 3000 | 156 | #define FW_CMD_MAX_TIMEOUT 3000 |
157 | 157 | ||
158 | /* | ||
159 | * If a host driver does a HELLO and discovers that there's already a MASTER | ||
160 | * selected, we may have to wait for that MASTER to finish issuing RESET, | ||
161 | * configuration and INITIALIZE commands. Also, there's a possibility that | ||
162 | * our own HELLO may get lost if it happens right as the MASTER is issuign a | ||
163 | * RESET command, so we need to be willing to make a few retries of our HELLO. | ||
164 | */ | ||
165 | #define FW_CMD_HELLO_TIMEOUT (3 * FW_CMD_MAX_TIMEOUT) | ||
166 | #define FW_CMD_HELLO_RETRIES 3 | ||
167 | |||
168 | |||
158 | enum fw_cmd_opcodes { | 169 | enum fw_cmd_opcodes { |
159 | FW_LDST_CMD = 0x01, | 170 | FW_LDST_CMD = 0x01, |
160 | FW_RESET_CMD = 0x03, | 171 | FW_RESET_CMD = 0x03, |
@@ -307,6 +318,10 @@ struct fw_reset_cmd { | |||
307 | __be32 r3; | 318 | __be32 r3; |
308 | }; | 319 | }; |
309 | 320 | ||
321 | enum fw_hellow_cmd { | ||
322 | fw_hello_cmd_stage_os = 0x0 | ||
323 | }; | ||
324 | |||
310 | struct fw_hello_cmd { | 325 | struct fw_hello_cmd { |
311 | __be32 op_to_write; | 326 | __be32 op_to_write; |
312 | __be32 retval_len16; | 327 | __be32 retval_len16; |
@@ -315,8 +330,14 @@ struct fw_hello_cmd { | |||
315 | #define FW_HELLO_CMD_INIT (1U << 30) | 330 | #define FW_HELLO_CMD_INIT (1U << 30) |
316 | #define FW_HELLO_CMD_MASTERDIS(x) ((x) << 29) | 331 | #define FW_HELLO_CMD_MASTERDIS(x) ((x) << 29) |
317 | #define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28) | 332 | #define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28) |
318 | #define FW_HELLO_CMD_MBMASTER(x) ((x) << 24) | 333 | #define FW_HELLO_CMD_MBMASTER_MASK 0xfU |
334 | #define FW_HELLO_CMD_MBMASTER_SHIFT 24 | ||
335 | #define FW_HELLO_CMD_MBMASTER(x) ((x) << FW_HELLO_CMD_MBMASTER_SHIFT) | ||
336 | #define FW_HELLO_CMD_MBMASTER_GET(x) \ | ||
337 | (((x) >> FW_HELLO_CMD_MBMASTER_SHIFT) & FW_HELLO_CMD_MBMASTER_MASK) | ||
319 | #define FW_HELLO_CMD_MBASYNCNOT(x) ((x) << 20) | 338 | #define FW_HELLO_CMD_MBASYNCNOT(x) ((x) << 20) |
339 | #define FW_HELLO_CMD_STAGE(x) ((x) << 17) | ||
340 | #define FW_HELLO_CMD_CLEARINIT (1U << 16) | ||
320 | __be32 fwrev; | 341 | __be32 fwrev; |
321 | }; | 342 | }; |
322 | 343 | ||
@@ -1654,18 +1675,4 @@ struct fw_hdr { | |||
1654 | #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) | 1675 | #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) |
1655 | #define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff) | 1676 | #define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff) |
1656 | 1677 | ||
1657 | #define S_FW_CMD_OP 24 | ||
1658 | #define V_FW_CMD_OP(x) ((x) << S_FW_CMD_OP) | ||
1659 | |||
1660 | #define S_FW_CMD_REQUEST 23 | ||
1661 | #define V_FW_CMD_REQUEST(x) ((x) << S_FW_CMD_REQUEST) | ||
1662 | #define F_FW_CMD_REQUEST V_FW_CMD_REQUEST(1U) | ||
1663 | |||
1664 | #define S_FW_CMD_WRITE 21 | ||
1665 | #define V_FW_CMD_WRITE(x) ((x) << S_FW_CMD_WRITE) | ||
1666 | #define F_FW_CMD_WRITE V_FW_CMD_WRITE(1U) | ||
1667 | |||
1668 | #define S_FW_LDST_CMD_ADDRSPACE 0 | ||
1669 | #define V_FW_LDST_CMD_ADDRSPACE(x) ((x) << S_FW_LDST_CMD_ADDRSPACE) | ||
1670 | |||
1671 | #endif /* _T4FW_INTERFACE_H_ */ | 1678 | #endif /* _T4FW_INTERFACE_H_ */ |