Commit 487042af authored by Himanshu Madhani's avatar Himanshu Madhani Committed by David S. Miller

qlcnic: Implement GET_LED_STATUS command for 82xx adapter.

o GET_LED_STATUS command will be used by driver to get
  current beacon state from 82xx adapter.
o Refactored qlcnic_store_beacon() to split 8200 and 8300
  specific calls.
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarShahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 099907fa
...@@ -815,6 +815,7 @@ struct qlcnic_mac_list_s { ...@@ -815,6 +815,7 @@ struct qlcnic_mac_list_s {
#define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG BIT_2 #define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG BIT_2
#define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3 #define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3
#define QLCNIC_FW_CAPABILITY_2_OCBB BIT_5 #define QLCNIC_FW_CAPABILITY_2_OCBB BIT_5
#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7
/* module types */ /* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1 #define LINKEVENT_MODULE_NOT_PRESENT 1
...@@ -912,6 +913,9 @@ struct qlcnic_ipaddr { ...@@ -912,6 +913,9 @@ struct qlcnic_ipaddr {
#define QLCNIC_IS_TSO_CAPABLE(adapter) \ #define QLCNIC_IS_TSO_CAPABLE(adapter) \
((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
#define QLCNIC_BEACON_EANBLE 0xC
#define QLCNIC_BEACON_DISABLE 0xD
#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4 #define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
#define QLCNIC_MSIX_TBL_SPACE 8192 #define QLCNIC_MSIX_TBL_SPACE 8192
#define QLCNIC_PCI_REG_MSIX_TBL 0x44 #define QLCNIC_PCI_REG_MSIX_TBL 0x44
...@@ -1543,6 +1547,7 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *); ...@@ -1543,6 +1547,7 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *);
int qlcnic_reset_npar_config(struct qlcnic_adapter *); int qlcnic_reset_npar_config(struct qlcnic_adapter *);
int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *);
void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
int qlcnic_get_beacon_state(struct qlcnic_adapter *, u8 *);
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
int qlcnic_read_mac_addr(struct qlcnic_adapter *); int qlcnic_read_mac_addr(struct qlcnic_adapter *);
int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
......
...@@ -37,6 +37,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_mbx_tbl[] = { ...@@ -37,6 +37,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_mbx_tbl[] = {
{QLCNIC_CMD_TEMP_SIZE, 4, 4}, {QLCNIC_CMD_TEMP_SIZE, 4, 4},
{QLCNIC_CMD_GET_TEMP_HDR, 4, 1}, {QLCNIC_CMD_GET_TEMP_HDR, 4, 1},
{QLCNIC_CMD_SET_DRV_VER, 4, 1}, {QLCNIC_CMD_SET_DRV_VER, 4, 1},
{QLCNIC_CMD_GET_LED_STATUS, 4, 2},
}; };
static inline u32 qlcnic_get_cmd_signature(struct qlcnic_hardware_context *ahw) static inline u32 qlcnic_get_cmd_signature(struct qlcnic_hardware_context *ahw)
......
...@@ -1503,6 +1503,21 @@ int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) ...@@ -1503,6 +1503,21 @@ int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
return rv; return rv;
} }
int qlcnic_get_beacon_state(struct qlcnic_adapter *adapter, u8 *h_state)
{
struct qlcnic_cmd_args cmd;
int err;
err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_STATUS);
if (!err) {
err = qlcnic_issue_cmd(adapter, &cmd);
if (!err)
*h_state = cmd.rsp.arg[1];
}
qlcnic_free_mbx_args(&cmd);
return err;
}
void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter) void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter)
{ {
void __iomem *msix_base_addr; void __iomem *msix_base_addr;
......
...@@ -87,6 +87,7 @@ enum qlcnic_regs { ...@@ -87,6 +87,7 @@ enum qlcnic_regs {
#define QLCNIC_CMD_CONFIG_VPORT 0x32 #define QLCNIC_CMD_CONFIG_VPORT 0x32
#define QLCNIC_CMD_GET_MAC_STATS 0x37 #define QLCNIC_CMD_GET_MAC_STATS 0x37
#define QLCNIC_CMD_SET_DRV_VER 0x38 #define QLCNIC_CMD_SET_DRV_VER 0x38
#define QLCNIC_CMD_GET_LED_STATUS 0x3C
#define QLCNIC_CMD_CONFIGURE_RSS 0x41 #define QLCNIC_CMD_CONFIGURE_RSS 0x41
#define QLCNIC_CMD_CONFIG_INTR_COAL 0x43 #define QLCNIC_CMD_CONFIG_INTR_COAL 0x43
#define QLCNIC_CMD_CONFIGURE_LED 0x44 #define QLCNIC_CMD_CONFIGURE_LED 0x44
......
...@@ -114,57 +114,51 @@ static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon, ...@@ -114,57 +114,51 @@ static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
return 0; return 0;
} }
static ssize_t qlcnic_store_beacon(struct device *dev, static int qlcnic_83xx_store_beacon(struct qlcnic_adapter *adapter,
struct device_attribute *attr, const char *buf, size_t len)
const char *buf, size_t len)
{ {
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int err, max_sds_rings = adapter->max_sds_rings;
u16 beacon;
u8 b_state, b_rate;
unsigned long h_beacon; unsigned long h_beacon;
int err;
if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { if (test_bit(__QLCNIC_RESETTING, &adapter->state))
dev_warn(dev, return -EIO;
"LED test not supported in non privileged mode\n");
return -EOPNOTSUPP;
}
if (qlcnic_83xx_check(adapter) && if (kstrtoul(buf, 2, &h_beacon))
!test_bit(__QLCNIC_RESETTING, &adapter->state)) { return -EINVAL;
if (kstrtoul(buf, 2, &h_beacon))
return -EINVAL;
if (ahw->beacon_state == h_beacon) if (ahw->beacon_state == h_beacon)
return len; return len;
rtnl_lock(); rtnl_lock();
if (!ahw->beacon_state) { if (!ahw->beacon_state) {
if (test_and_set_bit(__QLCNIC_LED_ENABLE, if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
&adapter->state)) { rtnl_unlock();
rtnl_unlock(); return -EBUSY;
return -EBUSY;
}
}
if (h_beacon) {
err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
if (err)
goto beacon_err;
} else {
err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
if (err)
goto beacon_err;
} }
/* set the current beacon state */ }
if (h_beacon)
err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
else
err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
if (!err)
ahw->beacon_state = h_beacon; ahw->beacon_state = h_beacon;
beacon_err:
if (!ahw->beacon_state)
clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
rtnl_unlock(); if (!ahw->beacon_state)
return len; clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
}
rtnl_unlock();
return len;
}
static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter,
const char *buf, size_t len)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
int err, max_sds_rings = adapter->max_sds_rings;
u16 beacon;
u8 h_beacon_state, b_state, b_rate;
if (len != sizeof(u16)) if (len != sizeof(u16))
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
...@@ -174,16 +168,29 @@ static ssize_t qlcnic_store_beacon(struct device *dev, ...@@ -174,16 +168,29 @@ static ssize_t qlcnic_store_beacon(struct device *dev,
if (err) if (err)
return err; return err;
if (adapter->ahw->beacon_state == b_state) if ((ahw->capabilities2 & QLCNIC_FW_CAPABILITY_2_BEACON)) {
err = qlcnic_get_beacon_state(adapter, &h_beacon_state);
if (!err) {
dev_info(&adapter->pdev->dev,
"Failed to get current beacon state\n");
} else {
if (h_beacon_state == QLCNIC_BEACON_DISABLE)
ahw->beacon_state = 0;
else if (h_beacon_state == QLCNIC_BEACON_EANBLE)
ahw->beacon_state = 2;
}
}
if (ahw->beacon_state == b_state)
return len; return len;
rtnl_lock(); rtnl_lock();
if (!ahw->beacon_state) {
if (!adapter->ahw->beacon_state)
if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) { if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
rtnl_unlock(); rtnl_unlock();
return -EBUSY; return -EBUSY;
} }
}
if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
err = -EIO; err = -EIO;
...@@ -206,14 +213,37 @@ static ssize_t qlcnic_store_beacon(struct device *dev, ...@@ -206,14 +213,37 @@ static ssize_t qlcnic_store_beacon(struct device *dev,
if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
qlcnic_diag_free_res(adapter->netdev, max_sds_rings); qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
out: out:
if (!adapter->ahw->beacon_state) if (!ahw->beacon_state)
clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
rtnl_unlock(); rtnl_unlock();
return err; return err;
} }
static ssize_t qlcnic_store_beacon(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
int err = 0;
if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
dev_warn(dev,
"LED test not supported in non privileged mode\n");
return -EOPNOTSUPP;
}
if (qlcnic_82xx_check(adapter))
err = qlcnic_82xx_store_beacon(adapter, buf, len);
else if (qlcnic_83xx_check(adapter))
err = qlcnic_83xx_store_beacon(adapter, buf, len);
else
return -EIO;
return err;
}
static ssize_t qlcnic_show_beacon(struct device *dev, static ssize_t qlcnic_show_beacon(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment