#define QLC_SKIP_INACTIVE_PCI_REGS     7
 #define QLC_MAX_LEGACY_FUNC_SUPP       8
 
+/* 83xx Module type */
+#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM      0x1 /* 10GBase-LRM */
+#define QLC_83XX_MODULE_FIBRE_10GBASE_LR       0x2 /* 10GBase-LR */
+#define QLC_83XX_MODULE_FIBRE_10GBASE_SR       0x3 /* 10GBase-SR */
+#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP     0x4 /* 10GE passive
+                                                    * copper(compliant)
+                                                    */
+#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP      0x5 /* 10GE active limiting
+                                                    * copper(compliant)
+                                                    */
+#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP      0x6 /* 10GE passive copper
+                                                    * (legacy, best effort)
+                                                    */
+#define QLC_83XX_MODULE_FIBRE_1000BASE_SX      0x7 /* 1000Base-SX */
+#define QLC_83XX_MODULE_FIBRE_1000BASE_LX      0x8 /* 1000Base-LX */
+#define QLC_83XX_MODULE_FIBRE_1000BASE_CX      0x9 /* 1000Base-CX */
+#define QLC_83XX_MODULE_TP_1000BASE_T          0xa /* 1000Base-T*/
+#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP      0xb /* 1GE passive copper
+                                                    * (legacy, best effort)
+                                                    */
+#define QLC_83XX_MODULE_UNKNOWN                        0xf /* Unknown module type */
+
+/* Port types */
+#define QLC_83XX_10_CAPABLE     BIT_8
+#define QLC_83XX_100_CAPABLE    BIT_9
+#define QLC_83XX_1G_CAPABLE     BIT_10
+#define QLC_83XX_10G_CAPABLE    BIT_11
+#define QLC_83XX_AUTONEG_ENABLE         BIT_15
+
 static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
        {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
        {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
 
 int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
 {
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
        int status;
 
        status = qlcnic_83xx_get_port_config(adapter);
                dev_err(&adapter->pdev->dev,
                        "Get Port Info failed\n");
        } else {
-               if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
-                       adapter->ahw->port_type = QLCNIC_XGBE;
-               else
-                       adapter->ahw->port_type = QLCNIC_GBE;
 
-               if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
-                       adapter->ahw->link_autoneg = AUTONEG_ENABLE;
+               if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
+                       ahw->port_type = QLCNIC_XGBE;
+               } else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
+                          ahw->port_config & QLC_83XX_100_CAPABLE ||
+                          ahw->port_config & QLC_83XX_1G_CAPABLE) {
+                       ahw->port_type = QLCNIC_GBE;
+               } else {
+                       ahw->port_type = QLCNIC_XGBE;
+               }
+
+               if (QLC_83XX_AUTONEG(ahw->port_config))
+                       ahw->link_autoneg = AUTONEG_ENABLE;
+
        }
        return status;
 }
                        break;
                }
                config = cmd.rsp.arg[3];
-               if (QLC_83XX_SFP_PRESENT(config)) {
-                       switch (ahw->module_type) {
-                       case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
-                       case LINKEVENT_MODULE_OPTICAL_SRLR:
-                       case LINKEVENT_MODULE_OPTICAL_LRM:
-                       case LINKEVENT_MODULE_OPTICAL_SFP_1G:
-                               ahw->supported_type = PORT_FIBRE;
-                               break;
-                       case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
-                       case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
-                       case LINKEVENT_MODULE_TWINAX:
-                               ahw->supported_type = PORT_TP;
-                               break;
-                       default:
-                               ahw->supported_type = PORT_OTHER;
-                       }
+               switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
+               case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
+               case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
+               case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
+                       ahw->supported_type = PORT_FIBRE;
+                       ahw->port_type = QLCNIC_XGBE;
+                       break;
+               case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
+               case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
+               case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
+                       ahw->supported_type = PORT_FIBRE;
+                       ahw->port_type = QLCNIC_GBE;
+                       break;
+               case QLC_83XX_MODULE_TP_1000BASE_T:
+                       ahw->supported_type = PORT_TP;
+                       ahw->port_type = QLCNIC_GBE;
+                       break;
+               case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
+               case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
+               case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
+               case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
+                       ahw->supported_type = PORT_DA;
+                       ahw->port_type = QLCNIC_XGBE;
+                       break;
+               default:
+                       ahw->supported_type = PORT_OTHER;
+                       ahw->port_type = QLCNIC_XGBE;
                }
                if (config & 1)
                        err = 1;
 int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
                             struct ethtool_cmd *ecmd)
 {
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
        u32 config = 0;
        int status = 0;
-       struct qlcnic_hardware_context *ahw = adapter->ahw;
 
        if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
                /* Get port configuration info */
                ecmd->autoneg = AUTONEG_DISABLE;
        }
 
-       if (ahw->port_type == QLCNIC_XGBE) {
-               ecmd->supported = SUPPORTED_10000baseT_Full;
-               ecmd->advertising = ADVERTISED_10000baseT_Full;
+       ecmd->supported = (SUPPORTED_10baseT_Full |
+                          SUPPORTED_100baseT_Full |
+                          SUPPORTED_1000baseT_Full |
+                          SUPPORTED_10000baseT_Full |
+                          SUPPORTED_Autoneg);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               if (ahw->port_config & QLC_83XX_10_CAPABLE)
+                       ecmd->advertising |= SUPPORTED_10baseT_Full;
+               if (ahw->port_config & QLC_83XX_100_CAPABLE)
+                       ecmd->advertising |= SUPPORTED_100baseT_Full;
+               if (ahw->port_config & QLC_83XX_1G_CAPABLE)
+                       ecmd->advertising |= SUPPORTED_1000baseT_Full;
+               if (ahw->port_config & QLC_83XX_10G_CAPABLE)
+                       ecmd->advertising |= SUPPORTED_10000baseT_Full;
+               if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
+                       ecmd->advertising |= ADVERTISED_Autoneg;
        } else {
-               ecmd->supported = (SUPPORTED_10baseT_Half |
-                                  SUPPORTED_10baseT_Full |
-                                  SUPPORTED_100baseT_Half |
-                                  SUPPORTED_100baseT_Full |
-                                  SUPPORTED_1000baseT_Half |
-                                  SUPPORTED_1000baseT_Full);
-               ecmd->advertising = (ADVERTISED_100baseT_Half |
-                                    ADVERTISED_100baseT_Full |
-                                    ADVERTISED_1000baseT_Half |
-                                    ADVERTISED_1000baseT_Full);
+               switch (ahw->link_speed) {
+               case SPEED_10:
+                       ecmd->advertising = SUPPORTED_10baseT_Full;
+                       break;
+               case SPEED_100:
+                       ecmd->advertising = SUPPORTED_100baseT_Full;
+                       break;
+               case SPEED_1000:
+                       ecmd->advertising = SUPPORTED_1000baseT_Full;
+                       break;
+               case SPEED_10000:
+                       ecmd->advertising = SUPPORTED_10000baseT_Full;
+                       break;
+               default:
+                       break;
+               }
+
        }
 
        switch (ahw->supported_type) {
                ecmd->port = PORT_TP;
                ecmd->transceiver = XCVR_INTERNAL;
                break;
+       case PORT_DA:
+               ecmd->supported |= SUPPORTED_FIBRE;
+               ecmd->advertising |= ADVERTISED_FIBRE;
+               ecmd->port = PORT_DA;
+               ecmd->transceiver = XCVR_EXTERNAL;
+               break;
        default:
                ecmd->supported |= SUPPORTED_FIBRE;
                ecmd->advertising |= ADVERTISED_FIBRE;
 int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
                             struct ethtool_cmd *ecmd)
 {
-       int status = 0;
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
        u32 config = adapter->ahw->port_config;
+       int status = 0;
 
-       if (ecmd->autoneg)
-               adapter->ahw->port_config |= BIT_15;
-
-       switch (ethtool_cmd_speed(ecmd)) {
-       case SPEED_10:
-               adapter->ahw->port_config |= BIT_8;
-               break;
-       case SPEED_100:
-               adapter->ahw->port_config |= BIT_9;
-               break;
-       case SPEED_1000:
-               adapter->ahw->port_config |= BIT_10;
-               break;
-       case SPEED_10000:
-               adapter->ahw->port_config |= BIT_11;
-               break;
-       default:
-               return -EINVAL;
+       /* 83xx devices do not support Half duplex */
+       if (ecmd->duplex == DUPLEX_HALF) {
+                       netdev_info(adapter->netdev,
+                                   "Half duplex mode not supported\n");
+                       return -EINVAL;
        }
 
+       if (ecmd->autoneg) {
+               ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
+               ahw->port_config |= (QLC_83XX_100_CAPABLE |
+                                    QLC_83XX_1G_CAPABLE |
+                                    QLC_83XX_10G_CAPABLE);
+       } else { /* force speed */
+               ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
+               switch (ethtool_cmd_speed(ecmd)) {
+               case SPEED_10:
+                       ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
+                                             QLC_83XX_1G_CAPABLE |
+                                             QLC_83XX_10G_CAPABLE);
+                       ahw->port_config |= QLC_83XX_10_CAPABLE;
+                       break;
+               case SPEED_100:
+                       ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
+                                             QLC_83XX_1G_CAPABLE |
+                                             QLC_83XX_10G_CAPABLE);
+                       ahw->port_config |= QLC_83XX_100_CAPABLE;
+                       break;
+               case SPEED_1000:
+                       ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
+                                             QLC_83XX_100_CAPABLE |
+                                             QLC_83XX_10G_CAPABLE);
+                       ahw->port_config |= QLC_83XX_1G_CAPABLE;
+                       break;
+               case SPEED_10000:
+                       ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
+                                             QLC_83XX_100_CAPABLE |
+                                             QLC_83XX_1G_CAPABLE);
+                       ahw->port_config |= QLC_83XX_10G_CAPABLE;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
        status = qlcnic_83xx_set_port_config(adapter);
        if (status) {
-               dev_info(&adapter->pdev->dev,
-                        "Failed to Set Link Speed and autoneg.\n");
-               adapter->ahw->port_config = config;
+               netdev_info(adapter->netdev,
+                           "Failed to Set Link Speed and autoneg.\n");
+               ahw->port_config = config;
        }
+
        return status;
 }