i40e: print FCoE capability reported by the device function
[deliverable/linux.git] / drivers / net / ethernet / intel / i40e / i40e_common.c
index 6aea65dae5ed654b5da2e7a8885a02a92c75710d..44dc4b1f418ce139788472ca09ec11266fce4602 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -51,6 +51,7 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
                case I40E_DEV_ID_QSFP_B:
                case I40E_DEV_ID_QSFP_C:
                case I40E_DEV_ID_10G_BASE_T:
+               case I40E_DEV_ID_20G_KR2:
                        hw->mac.type = I40E_MAC_XL710;
                        break;
                case I40E_DEV_ID_VF:
@@ -85,46 +86,53 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
 {
        struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
        u16 len = le16_to_cpu(aq_desc->datalen);
-       u8 *aq_buffer = (u8 *)buffer;
-       u32 data[4];
-       u32 i = 0;
+       u8 *buf = (u8 *)buffer;
+       u16 i = 0;
 
        if ((!(mask & hw->debug_mask)) || (desc == NULL))
                return;
 
        i40e_debug(hw, mask,
                   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
-                  aq_desc->opcode, aq_desc->flags, aq_desc->datalen,
-                  aq_desc->retval);
+                  le16_to_cpu(aq_desc->opcode),
+                  le16_to_cpu(aq_desc->flags),
+                  le16_to_cpu(aq_desc->datalen),
+                  le16_to_cpu(aq_desc->retval));
        i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
-                  aq_desc->cookie_high, aq_desc->cookie_low);
+                  le32_to_cpu(aq_desc->cookie_high),
+                  le32_to_cpu(aq_desc->cookie_low));
        i40e_debug(hw, mask, "\tparam (0,1)  0x%08X 0x%08X\n",
-                  aq_desc->params.internal.param0,
-                  aq_desc->params.internal.param1);
+                  le32_to_cpu(aq_desc->params.internal.param0),
+                  le32_to_cpu(aq_desc->params.internal.param1));
        i40e_debug(hw, mask, "\taddr (h,l)   0x%08X 0x%08X\n",
-                  aq_desc->params.external.addr_high,
-                  aq_desc->params.external.addr_low);
+                  le32_to_cpu(aq_desc->params.external.addr_high),
+                  le32_to_cpu(aq_desc->params.external.addr_low));
 
        if ((buffer != NULL) && (aq_desc->datalen != 0)) {
-               memset(data, 0, sizeof(data));
                i40e_debug(hw, mask, "AQ CMD Buffer:\n");
                if (buf_len < len)
                        len = buf_len;
-               for (i = 0; i < len; i++) {
-                       data[((i % 16) / 4)] |=
-                               ((u32)aq_buffer[i]) << (8 * (i % 4));
-                       if ((i % 16) == 15) {
-                               i40e_debug(hw, mask,
-                                          "\t0x%04X  %08X %08X %08X %08X\n",
-                                          i - 15, data[0], data[1], data[2],
-                                          data[3]);
-                               memset(data, 0, sizeof(data));
-                       }
+               /* write the full 16-byte chunks */
+               for (i = 0; i < (len - 16); i += 16)
+                       i40e_debug(hw, mask,
+                                  "\t0x%04X  %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+                                  i, buf[i], buf[i + 1], buf[i + 2],
+                                  buf[i + 3], buf[i + 4], buf[i + 5],
+                                  buf[i + 6], buf[i + 7], buf[i + 8],
+                                  buf[i + 9], buf[i + 10], buf[i + 11],
+                                  buf[i + 12], buf[i + 13], buf[i + 14],
+                                  buf[i + 15]);
+               /* write whatever's left over without overrunning the buffer */
+               if (i < len) {
+                       char d_buf[80];
+                       int j = 0;
+
+                       memset(d_buf, 0, sizeof(d_buf));
+                       j += sprintf(d_buf, "\t0x%04X ", i);
+                       while (i < len)
+                               j += sprintf(&d_buf[j], " %02X", buf[i++]);
+                       i40e_debug(hw, mask, "%s\n", d_buf);
                }
-               if ((i % 16) != 0)
-                       i40e_debug(hw, mask, "\t0x%04X  %08X %08X %08X %08X\n",
-                                  i - (i % 16), data[0], data[1], data[2],
-                                  data[3]);
        }
 }
 
@@ -534,7 +542,6 @@ struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
        I40E_PTT_UNUSED_ENTRY(255)
 };
 
-
 /**
  * i40e_init_shared_code - Initialize the shared code
  * @hw: pointer to hardware structure
@@ -685,7 +692,7 @@ i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
 /**
  * i40e_pre_tx_queue_cfg - pre tx queue configure
  * @hw: pointer to the HW structure
- * @queue: target pf queue index
+ * @queue: target PF queue index
  * @enable: state change request
  *
  * Handles hw requirement to indicate intention to enable
@@ -827,12 +834,15 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
        case I40E_PHY_TYPE_10GBASE_CR1:
        case I40E_PHY_TYPE_40GBASE_CR4:
        case I40E_PHY_TYPE_10GBASE_SFPP_CU:
+       case I40E_PHY_TYPE_40GBASE_AOC:
+       case I40E_PHY_TYPE_10GBASE_AOC:
                media = I40E_MEDIA_TYPE_DA;
                break;
        case I40E_PHY_TYPE_1000BASE_KX:
        case I40E_PHY_TYPE_10GBASE_KX4:
        case I40E_PHY_TYPE_10GBASE_KR:
        case I40E_PHY_TYPE_40GBASE_KR4:
+       case I40E_PHY_TYPE_20GBASE_KR2:
                media = I40E_MEDIA_TYPE_BACKPLANE;
                break;
        case I40E_PHY_TYPE_SGMII:
@@ -849,7 +859,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
 }
 
 #define I40E_PF_RESET_WAIT_COUNT_A0    200
-#define I40E_PF_RESET_WAIT_COUNT       110
+#define I40E_PF_RESET_WAIT_COUNT       200
 /**
  * i40e_pf_reset - Reset the PF
  * @hw: pointer to the hardware structure
@@ -947,7 +957,7 @@ void i40e_clear_hw(struct i40e_hw *hw)
        u32 val;
        u32 eol = 0x7ff;
 
-       /* get number of interrupts, queues, and vfs */
+       /* get number of interrupts, queues, and VFs */
        val = rd32(hw, I40E_GLPCI_CNF2);
        num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
                     I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
@@ -1076,8 +1086,11 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
        return gpio_val;
 }
 
-#define I40E_LED0 22
+#define I40E_COMBINED_ACTIVITY 0xA
+#define I40E_FILTER_ACTIVITY 0xE
 #define I40E_LINK_ACTIVITY 0xC
+#define I40E_MAC_ACTIVITY 0xD
+#define I40E_LED0 22
 
 /**
  * i40e_led_get - return current on/off mode
@@ -1090,6 +1103,7 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
  **/
 u32 i40e_led_get(struct i40e_hw *hw)
 {
+       u32 current_mode = 0;
        u32 mode = 0;
        int i;
 
@@ -1102,6 +1116,20 @@ u32 i40e_led_get(struct i40e_hw *hw)
                if (!gpio_val)
                        continue;
 
+               /* ignore gpio LED src mode entries related to the activity
+                * LEDs
+                */
+               current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
+                               >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
+               switch (current_mode) {
+               case I40E_COMBINED_ACTIVITY:
+               case I40E_FILTER_ACTIVITY:
+               case I40E_MAC_ACTIVITY:
+                       continue;
+               default:
+                       break;
+               }
+
                mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
                        I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;
                break;
@@ -1121,6 +1149,7 @@ u32 i40e_led_get(struct i40e_hw *hw)
  **/
 void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
 {
+       u32 current_mode = 0;
        int i;
 
        if (mode & 0xfffffff0)
@@ -1135,6 +1164,20 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
                if (!gpio_val)
                        continue;
 
+               /* ignore gpio LED src mode entries related to the activity
+                * LEDs
+                */
+               current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
+                               >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
+               switch (current_mode) {
+               case I40E_COMBINED_ACTIVITY:
+               case I40E_FILTER_ACTIVITY:
+               case I40E_MAC_ACTIVITY:
+                       continue;
+               default:
+                       break;
+               }
+
                gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
                /* this & is a bit of paranoia, but serves as a range check */
                gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
@@ -1298,14 +1341,14 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
                        *aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
        }
        /* Update the link info */
-       status = i40e_update_link_info(hw, true);
+       status = i40e_aq_get_link_info(hw, true, NULL, NULL);
        if (status) {
                /* Wait a little bit (on 40G cards it sometimes takes a really
                 * long time for link to come back from the atomic reset)
                 * and try once more
                 */
                msleep(1000);
-               status = i40e_update_link_info(hw, true);
+               status = i40e_aq_get_link_info(hw, true, NULL, NULL);
        }
        if (status)
                *aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
@@ -1441,6 +1484,10 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
        else
                hw_link_info->lse_enable = false;
 
+       if ((hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
+            hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
+               hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
+
        /* save link status information */
        if (link)
                *link = *hw_link_info;
@@ -1452,35 +1499,6 @@ aq_get_link_info_exit:
        return status;
 }
 
-/**
- * i40e_update_link_info
- * @hw: pointer to the hw struct
- * @enable_lse: enable/disable LinkStatusEvent reporting
- *
- * Returns the link status of the adapter
- **/
-i40e_status i40e_update_link_info(struct i40e_hw *hw, bool enable_lse)
-{
-       struct i40e_aq_get_phy_abilities_resp abilities;
-       i40e_status status;
-
-       status = i40e_aq_get_link_info(hw, enable_lse, NULL, NULL);
-       if (status)
-               return status;
-
-       status = i40e_aq_get_phy_capabilities(hw, false, false,
-                                             &abilities, NULL);
-       if (status)
-               return status;
-
-       if (abilities.abilities & I40E_AQ_PHY_AN_ENABLED)
-               hw->phy.link_info.an_enabled = true;
-       else
-               hw->phy.link_info.an_enabled = false;
-
-       return status;
-}
-
 /**
  * i40e_aq_set_phy_int_mask
  * @hw: pointer to the hw struct
@@ -1760,6 +1778,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
  * @hw: pointer to the hw struct
  * @fw_major_version: firmware major version
  * @fw_minor_version: firmware minor version
+ * @fw_build: firmware build number
  * @api_major_version: major queue version
  * @api_minor_version: minor queue version
  * @cmd_details: pointer to command details structure or NULL
@@ -1768,6 +1787,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
  **/
 i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
                                u16 *fw_major_version, u16 *fw_minor_version,
+                               u32 *fw_build,
                                u16 *api_major_version, u16 *api_minor_version,
                                struct i40e_asq_cmd_details *cmd_details)
 {
@@ -1781,13 +1801,15 @@ i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        if (!status) {
-               if (fw_major_version != NULL)
+               if (fw_major_version)
                        *fw_major_version = le16_to_cpu(resp->fw_major);
-               if (fw_minor_version != NULL)
+               if (fw_minor_version)
                        *fw_minor_version = le16_to_cpu(resp->fw_minor);
-               if (api_major_version != NULL)
+               if (fw_build)
+                       *fw_build = le32_to_cpu(resp->fw_build);
+               if (api_major_version)
                        *api_major_version = le16_to_cpu(resp->api_major);
-               if (api_minor_version != NULL)
+               if (api_minor_version)
                        *api_minor_version = le16_to_cpu(resp->api_minor);
        }
 
@@ -1817,7 +1839,7 @@ i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
 
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version);
 
-       desc.flags |= cpu_to_le16(I40E_AQ_FLAG_SI);
+       desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
        cmd->driver_major_ver = dv->major_version;
        cmd->driver_minor_ver = dv->minor_version;
        cmd->driver_build_ver = dv->build_version;
@@ -1997,7 +2019,7 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
        if (count == 0 || !mv_list || !hw)
                return I40E_ERR_PARAM;
 
-       buf_size = count * sizeof(struct i40e_aqc_add_macvlan_element_data);
+       buf_size = count * sizeof(*mv_list);
 
        /* prep the rest of the request */
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
@@ -2039,7 +2061,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
        if (count == 0 || !mv_list || !hw)
                return I40E_ERR_PARAM;
 
-       buf_size = count * sizeof(struct i40e_aqc_remove_macvlan_element_data);
+       buf_size = count * sizeof(*mv_list);
 
        /* prep the rest of the request */
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
@@ -2061,7 +2083,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
 /**
  * i40e_aq_send_msg_to_vf
  * @hw: pointer to the hardware structure
- * @vfid: vf id to send msg
+ * @vfid: VF id to send msg
  * @v_opcode: opcodes for VF-PF communication
  * @v_retval: return error code
  * @msg: pointer to the msg buffer
@@ -2106,7 +2128,7 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
  * Read the register using the admin queue commands
  **/
 i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
-                               u32  reg_addr, u64 *reg_val,
+                               u32 reg_addr, u64 *reg_val,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
@@ -2117,17 +2139,15 @@ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
        if (reg_val == NULL)
                return I40E_ERR_PARAM;
 
-       i40e_fill_default_direct_cmd_desc(&desc,
-                                         i40e_aqc_opc_debug_read_reg);
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
 
        cmd_resp->address = cpu_to_le32(reg_addr);
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        if (!status) {
-               *reg_val = ((u64)cmd_resp->value_high << 32) |
-                           (u64)cmd_resp->value_low;
-               *reg_val = le64_to_cpu(*reg_val);
+               *reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) |
+                          (u64)le32_to_cpu(cmd_resp->value_low);
        }
 
        return status;
@@ -2526,6 +2546,9 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                }
        }
 
+       if (p->fcoe)
+               i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
+
        /* Software override ensuring FCoE is disabled if npar or mfp
         * mode because it is not supported in these modes.
         */
@@ -3376,6 +3399,47 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
        return status;
 }
 
+/**
+ * i40e_aq_alternate_read
+ * @hw: pointer to the hardware structure
+ * @reg_addr0: address of first dword to be read
+ * @reg_val0: pointer for data read from 'reg_addr0'
+ * @reg_addr1: address of second dword to be read
+ * @reg_val1: pointer for data read from 'reg_addr1'
+ *
+ * Read one or two dwords from alternate structure. Fields are indicated
+ * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
+ * is not passed then only register at 'reg_addr0' is read.
+ *
+ **/
+static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
+                                         u32 reg_addr0, u32 *reg_val0,
+                                         u32 reg_addr1, u32 *reg_val1)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_alternate_write *cmd_resp =
+               (struct i40e_aqc_alternate_write *)&desc.params.raw;
+       i40e_status status;
+
+       if (!reg_val0)
+               return I40E_ERR_PARAM;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
+       cmd_resp->address0 = cpu_to_le32(reg_addr0);
+       cmd_resp->address1 = cpu_to_le32(reg_addr1);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
+
+       if (!status) {
+               *reg_val0 = le32_to_cpu(cmd_resp->data0);
+
+               if (reg_val1)
+                       *reg_val1 = le32_to_cpu(cmd_resp->data1);
+       }
+
+       return status;
+}
+
 /**
  * i40e_aq_resume_port_tx
  * @hw: pointer to the hardware structure
@@ -3440,3 +3504,79 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
                break;
        }
 }
+
+/**
+ * i40e_read_bw_from_alt_ram
+ * @hw: pointer to the hardware structure
+ * @max_bw: pointer for max_bw read
+ * @min_bw: pointer for min_bw read
+ * @min_valid: pointer for bool that is true if min_bw is a valid value
+ * @max_valid: pointer for bool that is true if max_bw is a valid value
+ *
+ * Read bw from the alternate ram for the given pf
+ **/
+i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
+                                     u32 *max_bw, u32 *min_bw,
+                                     bool *min_valid, bool *max_valid)
+{
+       i40e_status status;
+       u32 max_bw_addr, min_bw_addr;
+
+       /* Calculate the address of the min/max bw registers */
+       max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
+                     I40E_ALT_STRUCT_MAX_BW_OFFSET +
+                     (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
+       min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
+                     I40E_ALT_STRUCT_MIN_BW_OFFSET +
+                     (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
+
+       /* Read the bandwidths from alt ram */
+       status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
+                                       min_bw_addr, min_bw);
+
+       if (*min_bw & I40E_ALT_BW_VALID_MASK)
+               *min_valid = true;
+       else
+               *min_valid = false;
+
+       if (*max_bw & I40E_ALT_BW_VALID_MASK)
+               *max_valid = true;
+       else
+               *max_valid = false;
+
+       return status;
+}
+
+/**
+ * i40e_aq_configure_partition_bw
+ * @hw: pointer to the hardware structure
+ * @bw_data: Buffer holding valid pfs and bw limits
+ * @cmd_details: pointer to command details
+ *
+ * Configure partitions guaranteed/max bw
+ **/
+i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
+                       struct i40e_aqc_configure_partition_bw_data *bw_data,
+                       struct i40e_asq_cmd_details *cmd_details)
+{
+       i40e_status status;
+       struct i40e_aq_desc desc;
+       u16 bwd_size = sizeof(*bw_data);
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_configure_partition_bw);
+
+       /* Indirect command */
+       desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
+       desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
+
+       if (bwd_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+
+       desc.datalen = cpu_to_le16(bwd_size);
+
+       status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size,
+                                      cmd_details);
+
+       return status;
+}
This page took 0.032575 seconds and 5 git commands to generate.