aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2015-02-06 03:52:12 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-02-25 00:28:11 -0500
commitf4492db16df8a027cebc209c3905cbe421b53d3a (patch)
treea7d7e9cb5f066d6cc1961187f0ed610d96aa1d6a /drivers/net/ethernet
parent2bc7ee8ac5439efec66fa20a8dc01c0a2b5af739 (diff)
i40e: Add NPAR BW get and set functions
We need to be able to get, set and commit permanently the NPAR partition BW configuration through configfs. These are necessary precursor functions for that feature. Also update the copyright year. Change-ID: I9d5ca160a9288145f1dd2042994028679fff55f3 Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Tested-by: Jim Young <james.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c117
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c129
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h8
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h13
5 files changed, 273 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index eb6307edbdd4..713e20e6a29e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -385,6 +385,9 @@ struct i40e_pf {
385 bool ptp_tx; 385 bool ptp_tx;
386 bool ptp_rx; 386 bool ptp_rx;
387 u16 rss_table_size; 387 u16 rss_table_size;
388 /* These are only valid in NPAR modes */
389 u32 npar_max_bw;
390 u32 npar_min_bw;
388}; 391};
389 392
390struct i40e_mac_filter { 393struct i40e_mac_filter {
@@ -732,4 +735,8 @@ int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
732int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr); 735int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
733void i40e_ptp_init(struct i40e_pf *pf); 736void i40e_ptp_init(struct i40e_pf *pf);
734void i40e_ptp_stop(struct i40e_pf *pf); 737void i40e_ptp_stop(struct i40e_pf *pf);
738
739i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf);
740i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf);
741i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf);
735#endif /* _I40E_H_ */ 742#endif /* _I40E_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 6d630a03a13d..b7f506360fc1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -3354,6 +3354,47 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
3354} 3354}
3355 3355
3356/** 3356/**
3357 * i40e_aq_alternate_read
3358 * @hw: pointer to the hardware structure
3359 * @reg_addr0: address of first dword to be read
3360 * @reg_val0: pointer for data read from 'reg_addr0'
3361 * @reg_addr1: address of second dword to be read
3362 * @reg_val1: pointer for data read from 'reg_addr1'
3363 *
3364 * Read one or two dwords from alternate structure. Fields are indicated
3365 * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
3366 * is not passed then only register at 'reg_addr0' is read.
3367 *
3368 **/
3369i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
3370 u32 reg_addr0, u32 *reg_val0,
3371 u32 reg_addr1, u32 *reg_val1)
3372{
3373 struct i40e_aq_desc desc;
3374 struct i40e_aqc_alternate_write *cmd_resp =
3375 (struct i40e_aqc_alternate_write *)&desc.params.raw;
3376 i40e_status status;
3377
3378 if (!reg_val0)
3379 return I40E_ERR_PARAM;
3380
3381 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
3382 cmd_resp->address0 = cpu_to_le32(reg_addr0);
3383 cmd_resp->address1 = cpu_to_le32(reg_addr1);
3384
3385 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
3386
3387 if (!status) {
3388 *reg_val0 = le32_to_cpu(cmd_resp->data0);
3389
3390 if (reg_val1)
3391 *reg_val1 = le32_to_cpu(cmd_resp->data1);
3392 }
3393
3394 return status;
3395}
3396
3397/**
3357 * i40e_aq_resume_port_tx 3398 * i40e_aq_resume_port_tx
3358 * @hw: pointer to the hardware structure 3399 * @hw: pointer to the hardware structure
3359 * @cmd_details: pointer to command details structure or NULL 3400 * @cmd_details: pointer to command details structure or NULL
@@ -3417,3 +3458,79 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
3417 break; 3458 break;
3418 } 3459 }
3419} 3460}
3461
3462/**
3463 * i40e_read_bw_from_alt_ram
3464 * @hw: pointer to the hardware structure
3465 * @max_bw: pointer for max_bw read
3466 * @min_bw: pointer for min_bw read
3467 * @min_valid: pointer for bool that is true if min_bw is a valid value
3468 * @max_valid: pointer for bool that is true if max_bw is a valid value
3469 *
3470 * Read bw from the alternate ram for the given pf
3471 **/
3472i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
3473 u32 *max_bw, u32 *min_bw,
3474 bool *min_valid, bool *max_valid)
3475{
3476 i40e_status status;
3477 u32 max_bw_addr, min_bw_addr;
3478
3479 /* Calculate the address of the min/max bw registers */
3480 max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
3481 I40E_ALT_STRUCT_MAX_BW_OFFSET +
3482 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
3483 min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
3484 I40E_ALT_STRUCT_MIN_BW_OFFSET +
3485 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
3486
3487 /* Read the bandwidths from alt ram */
3488 status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
3489 min_bw_addr, min_bw);
3490
3491 if (*min_bw & I40E_ALT_BW_VALID_MASK)
3492 *min_valid = true;
3493 else
3494 *min_valid = false;
3495
3496 if (*max_bw & I40E_ALT_BW_VALID_MASK)
3497 *max_valid = true;
3498 else
3499 *max_valid = false;
3500
3501 return status;
3502}
3503
3504/**
3505 * i40e_aq_configure_partition_bw
3506 * @hw: pointer to the hardware structure
3507 * @bw_data: Buffer holding valid pfs and bw limits
3508 * @cmd_details: pointer to command details
3509 *
3510 * Configure partitions guaranteed/max bw
3511 **/
3512i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
3513 struct i40e_aqc_configure_partition_bw_data *bw_data,
3514 struct i40e_asq_cmd_details *cmd_details)
3515{
3516 i40e_status status;
3517 struct i40e_aq_desc desc;
3518 u16 bwd_size = sizeof(*bw_data);
3519
3520 i40e_fill_default_direct_cmd_desc(&desc,
3521 i40e_aqc_opc_configure_partition_bw);
3522
3523 /* Indirect command */
3524 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3525 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
3526
3527 if (bwd_size > I40E_AQ_LARGE_BUF)
3528 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3529
3530 desc.datalen = cpu_to_le16(bwd_size);
3531
3532 status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size,
3533 cmd_details);
3534
3535 return status;
3536}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index a8824c785b5a..e3e48c3ae24a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7254,6 +7254,128 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
7254} 7254}
7255 7255
7256/** 7256/**
7257 * i40e_get_npar_bw_setting - Retrieve BW settings for this PF partition
7258 * @pf: board private structure
7259 **/
7260i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf)
7261{
7262 i40e_status status;
7263 bool min_valid, max_valid;
7264 u32 max_bw, min_bw;
7265
7266 status = i40e_read_bw_from_alt_ram(&pf->hw, &max_bw, &min_bw,
7267 &min_valid, &max_valid);
7268
7269 if (!status) {
7270 if (min_valid)
7271 pf->npar_min_bw = min_bw;
7272 if (max_valid)
7273 pf->npar_max_bw = max_bw;
7274 }
7275
7276 return status;
7277}
7278
7279/**
7280 * i40e_set_npar_bw_setting - Set BW settings for this PF partition
7281 * @pf: board private structure
7282 **/
7283i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf)
7284{
7285 struct i40e_aqc_configure_partition_bw_data bw_data;
7286 i40e_status status;
7287
7288 /* Set the valid bit for this pf */
7289 bw_data.pf_valid_bits = cpu_to_le16(1 << pf->hw.pf_id);
7290 bw_data.max_bw[pf->hw.pf_id] = pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK;
7291 bw_data.min_bw[pf->hw.pf_id] = pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK;
7292
7293 /* Set the new bandwidths */
7294 status = i40e_aq_configure_partition_bw(&pf->hw, &bw_data, NULL);
7295
7296 return status;
7297}
7298
7299/**
7300 * i40e_commit_npar_bw_setting - Commit BW settings for this PF partition
7301 * @pf: board private structure
7302 **/
7303i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf)
7304{
7305 /* Commit temporary BW setting to permanent NVM image */
7306 enum i40e_admin_queue_err last_aq_status;
7307 i40e_status ret;
7308 u16 nvm_word;
7309
7310 if (pf->hw.partition_id != 1) {
7311 dev_info(&pf->pdev->dev,
7312 "Commit BW only works on partition 1! This is partition %d",
7313 pf->hw.partition_id);
7314 ret = I40E_NOT_SUPPORTED;
7315 goto bw_commit_out;
7316 }
7317
7318 /* Acquire NVM for read access */
7319 ret = i40e_acquire_nvm(&pf->hw, I40E_RESOURCE_READ);
7320 last_aq_status = pf->hw.aq.asq_last_status;
7321 if (ret) {
7322 dev_info(&pf->pdev->dev,
7323 "Cannot acquire NVM for read access, err %d: aq_err %d\n",
7324 ret, last_aq_status);
7325 goto bw_commit_out;
7326 }
7327
7328 /* Read word 0x10 of NVM - SW compatibility word 1 */
7329 ret = i40e_aq_read_nvm(&pf->hw,
7330 I40E_SR_NVM_CONTROL_WORD,
7331 0x10, sizeof(nvm_word), &nvm_word,
7332 false, NULL);
7333 /* Save off last admin queue command status before releasing
7334 * the NVM
7335 */
7336 last_aq_status = pf->hw.aq.asq_last_status;
7337 i40e_release_nvm(&pf->hw);
7338 if (ret) {
7339 dev_info(&pf->pdev->dev, "NVM read error, err %d aq_err %d\n",
7340 ret, last_aq_status);
7341 goto bw_commit_out;
7342 }
7343
7344 /* Wait a bit for NVM release to complete */
7345 msleep(50);
7346
7347 /* Acquire NVM for write access */
7348 ret = i40e_acquire_nvm(&pf->hw, I40E_RESOURCE_WRITE);
7349 last_aq_status = pf->hw.aq.asq_last_status;
7350 if (ret) {
7351 dev_info(&pf->pdev->dev,
7352 "Cannot acquire NVM for write access, err %d: aq_err %d\n",
7353 ret, last_aq_status);
7354 goto bw_commit_out;
7355 }
7356 /* Write it back out unchanged to initiate update NVM,
7357 * which will force a write of the shadow (alt) RAM to
7358 * the NVM - thus storing the bandwidth values permanently.
7359 */
7360 ret = i40e_aq_update_nvm(&pf->hw,
7361 I40E_SR_NVM_CONTROL_WORD,
7362 0x10, sizeof(nvm_word),
7363 &nvm_word, true, NULL);
7364 /* Save off last admin queue command status before releasing
7365 * the NVM
7366 */
7367 last_aq_status = pf->hw.aq.asq_last_status;
7368 i40e_release_nvm(&pf->hw);
7369 if (ret)
7370 dev_info(&pf->pdev->dev,
7371 "BW settings NOT SAVED, err %d aq_err %d\n",
7372 ret, last_aq_status);
7373bw_commit_out:
7374
7375 return ret;
7376}
7377
7378/**
7257 * i40e_sw_init - Initialize general software structures (struct i40e_pf) 7379 * i40e_sw_init - Initialize general software structures (struct i40e_pf)
7258 * @pf: board private structure to initialize 7380 * @pf: board private structure to initialize
7259 * 7381 *
@@ -7306,6 +7428,13 @@ static int i40e_sw_init(struct i40e_pf *pf)
7306 if (pf->hw.func_caps.npar_enable || pf->hw.func_caps.mfp_mode_1) { 7428 if (pf->hw.func_caps.npar_enable || pf->hw.func_caps.mfp_mode_1) {
7307 pf->flags |= I40E_FLAG_MFP_ENABLED; 7429 pf->flags |= I40E_FLAG_MFP_ENABLED;
7308 dev_info(&pf->pdev->dev, "MFP mode Enabled\n"); 7430 dev_info(&pf->pdev->dev, "MFP mode Enabled\n");
7431 if (i40e_get_npar_bw_setting(pf))
7432 dev_warn(&pf->pdev->dev,
7433 "Could not get NPAR bw settings\n");
7434 else
7435 dev_info(&pf->pdev->dev,
7436 "Min BW = %8.8x, Max BW = %8.8x\n",
7437 pf->npar_min_bw, pf->npar_max_bw);
7309 } 7438 }
7310 7439
7311 /* FW/NVM is not yet fixed in this regard */ 7440 /* FW/NVM is not yet fixed in this regard */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index 1247a45603a8..8cab460865f5 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -1,7 +1,7 @@
1/******************************************************************************* 1/*******************************************************************************
2 * 2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver 3 * Intel Ethernet Controller XL710 Family Linux Driver
4 * Copyright(c) 2013 - 2014 Intel Corporation. 4 * Copyright(c) 2013 - 2015 Intel Corporation.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -246,6 +246,12 @@ void i40e_clear_hw(struct i40e_hw *hw);
246void i40e_clear_pxe_mode(struct i40e_hw *hw); 246void i40e_clear_pxe_mode(struct i40e_hw *hw);
247bool i40e_get_link_status(struct i40e_hw *hw); 247bool i40e_get_link_status(struct i40e_hw *hw);
248i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr); 248i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
249i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
250 u32 *max_bw, u32 *min_bw, bool *min_valid,
251 bool *max_valid);
252i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
253 struct i40e_aqc_configure_partition_bw_data *bw_data,
254 struct i40e_asq_cmd_details *cmd_details);
249i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr); 255i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
250i40e_status i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num, 256i40e_status i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
251 u32 pba_num_size); 257 u32 pba_num_size);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 17f1647ab1d6..90069396bb28 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -1401,6 +1401,19 @@ struct i40e_lldp_variables {
1401 u16 crc8; 1401 u16 crc8;
1402}; 1402};
1403 1403
1404/* Offsets into Alternate Ram */
1405#define I40E_ALT_STRUCT_FIRST_PF_OFFSET 0 /* in dwords */
1406#define I40E_ALT_STRUCT_DWORDS_PER_PF 64 /* in dwords */
1407#define I40E_ALT_STRUCT_OUTER_VLAN_TAG_OFFSET 0xD /* in dwords */
1408#define I40E_ALT_STRUCT_USER_PRIORITY_OFFSET 0xC /* in dwords */
1409#define I40E_ALT_STRUCT_MIN_BW_OFFSET 0xE /* in dwords */
1410#define I40E_ALT_STRUCT_MAX_BW_OFFSET 0xF /* in dwords */
1411
1412/* Alternate Ram Bandwidth Masks */
1413#define I40E_ALT_BW_VALUE_MASK 0xFF
1414#define I40E_ALT_BW_RELATIVE_MASK 0x40000000
1415#define I40E_ALT_BW_VALID_MASK 0x80000000
1416
1404/* RSS Hash Table Size */ 1417/* RSS Hash Table Size */
1405#define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000 1418#define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000
1406#endif /* _I40E_TYPE_H_ */ 1419#endif /* _I40E_TYPE_H_ */