Skip to content

Commit

Permalink
Merge branch 'qlcnic-next'
Browse files Browse the repository at this point in the history
Rajesh Borundia says:

====================
qlcnic: SR-IOV and FW-dump enhancements

This patch series contain following enhancements.

* SR-IOV enhancements:
 - Allow SR-IOV VF's to probe in hypervisor. SR-IOV VF can be
   uplinked to bridge/macvtap device with this change.
 - Commands from VF are processed in process context
   as it may sleep during PF-VF communication. Earlier
   we use to process qlcnic_sriov_vf_set_multi function in
   process context but now we process individual commands.
 - As SR-IOV VF's can be uplinked to bridge/macvtap device
   support mac-learning to allow communication through
   embedded switch.

* FW-dump enhancement:
 - Support to collect RDMEM section of firmware dump using
   PEX DMA method for 82xx series adapter.

* Changes in v2:
 - Removed unnecessary cast from void pointer to something
   else and verified this issue in entire patch series as
   per David Miller's suggestion.

Please apply this series to net-next.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 9, 2014
2 parents a3ab3c1 + 27a4041 commit fe6f397
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 203 deletions.
18 changes: 15 additions & 3 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@

#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3
#define _QLCNIC_LINUX_SUBVERSION 58
#define QLCNIC_LINUX_VERSIONID "5.3.58"
#define _QLCNIC_LINUX_SUBVERSION 59
#define QLCNIC_LINUX_VERSIONID "5.3.59"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
Expand Down Expand Up @@ -1019,6 +1019,8 @@ struct qlcnic_ipaddr {
#define QLCNIC_DEL_VXLAN_PORT 0x200000
#endif

#define QLCNIC_VLAN_FILTERING 0x800000

#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
#define QLCNIC_IS_TSO_CAPABLE(adapter) \
Expand Down Expand Up @@ -1693,7 +1695,7 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *);
int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
void qlcnic_set_netdev_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *);
void qlcnic_sriov_vf_schedule_multi(struct net_device *);
void qlcnic_sriov_vf_set_multi(struct net_device *);
int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8);
int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *,
u16 *);
Expand Down Expand Up @@ -2355,6 +2357,16 @@ static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter)
return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false;
}

static inline bool qlcnic_sriov_check(struct qlcnic_adapter *adapter)
{
bool status;

status = (qlcnic_sriov_pf_check(adapter) ||
qlcnic_sriov_vf_check(adapter)) ? true : false;

return status;
}

static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
{
if (qlcnic_84xx_check(adapter))
Expand Down
31 changes: 10 additions & 21 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -3037,19 +3037,18 @@ void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
}

int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
u32 *data, u32 count)
{
int i, j, ret = 0;
u32 temp;
int err = 0;

/* Check alignment */
if (addr & 0xF)
return -EIO;

mutex_lock(&adapter->ahw->mem_lock);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0);
qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);

for (i = 0; i < count; i++, addr += 16) {
if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
Expand All @@ -3060,26 +3059,16 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
return -EIO;
}

qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
QLCNIC_TA_WRITE_ENABLE);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
QLCNIC_TA_WRITE_START);
qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);

for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err);
if (err == -EIO) {
mutex_unlock(&adapter->ahw->mem_lock);
return err;
}
temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);

if ((temp & TA_CTL_BUSY) == 0)
break;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *);
void qlcnic_83xx_napi_enable(struct qlcnic_adapter *);
void qlcnic_83xx_napi_disable(struct qlcnic_adapter *);
int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32);
void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
int qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
int qlcnic_ind_rd(struct qlcnic_adapter *, u32);
int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *);
int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *,
Expand Down Expand Up @@ -617,7 +617,6 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32);
int qlcnic_83xx_lock_driver(struct qlcnic_adapter *);
void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *);
int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *);
int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *);
int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int);
int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
Expand Down Expand Up @@ -659,4 +658,5 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *);
u32 qlcnic_83xx_get_cap_size(void *, int);
void qlcnic_83xx_set_sys_info(void *, int, u32);
void qlcnic_83xx_store_cap_mask(void *, u32);
int qlcnic_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
#endif
12 changes: 6 additions & 6 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1363,8 +1363,8 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter)
return ret;
}
/* 16 byte write to MS memory */
ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache,
size / 16);
ret = qlcnic_ms_mem_write128(adapter, dest, (u32 *)p_cache,
size / 16);
if (ret) {
vfree(p_cache);
return ret;
Expand All @@ -1389,8 +1389,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
p_cache = (u32 *)fw->data;
addr = (u64)dest;

ret = qlcnic_83xx_ms_mem_write128(adapter, addr,
p_cache, size / 16);
ret = qlcnic_ms_mem_write128(adapter, addr,
p_cache, size / 16);
if (ret) {
dev_err(&adapter->pdev->dev, "MS memory write failed\n");
release_firmware(fw);
Expand All @@ -1405,8 +1405,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
data[i] = fw->data[size + i];
for (; i < 16; i++)
data[i] = 0;
ret = qlcnic_83xx_ms_mem_write128(adapter, addr,
(u32 *)data, 1);
ret = qlcnic_ms_mem_write128(adapter, addr,
(u32 *)data, 1);
if (ret) {
dev_err(&adapter->pdev->dev,
"MS memory write failed\n");
Expand Down
32 changes: 11 additions & 21 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,16 @@ int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
return data;
}

void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
int qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
{
int ret = 0;

if (qlcnic_82xx_check(adapter))
qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data);
else
qlcnic_83xx_wrt_reg_indirect(adapter, addr, data);
ret = qlcnic_83xx_wrt_reg_indirect(adapter, addr, data);

return ret;
}

static int
Expand Down Expand Up @@ -567,28 +571,14 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
void qlcnic_set_multi(struct net_device *netdev)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_mac_vlan_list *cur;
struct netdev_hw_addr *ha;
size_t temp;

if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
return;
if (qlcnic_sriov_vf_check(adapter)) {
if (!netdev_mc_empty(netdev)) {
netdev_for_each_mc_addr(ha, netdev) {
temp = sizeof(struct qlcnic_mac_vlan_list);
cur = kzalloc(temp, GFP_ATOMIC);
if (cur == NULL)
break;
memcpy(cur->mac_addr,
ha->addr, ETH_ALEN);
list_add_tail(&cur->list, &adapter->vf_mc_list);
}
}
qlcnic_sriov_vf_schedule_multi(adapter->netdev);
return;
}
__qlcnic_set_multi(netdev, 0);

if (qlcnic_sriov_vf_check(adapter))
qlcnic_sriov_vf_set_multi(netdev);
else
__qlcnic_set_multi(netdev, 0);
}

int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
Expand Down
12 changes: 4 additions & 8 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,20 +313,16 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
u16 vlan_id = 0;
u8 hindex, hval;

if (!qlcnic_sriov_pf_check(adapter)) {
if (ether_addr_equal(phdr->h_source, adapter->mac_addr))
return;
} else {
if (ether_addr_equal(phdr->h_source, adapter->mac_addr))
return;

if (adapter->flags & QLCNIC_VLAN_FILTERING) {
if (protocol == ETH_P_8021Q) {
vh = (struct vlan_ethhdr *)skb->data;
vlan_id = ntohs(vh->h_vlan_TCI);
} else if (vlan_tx_tag_present(skb)) {
vlan_id = vlan_tx_tag_get(skb);
}

if (ether_addr_equal(phdr->h_source, adapter->mac_addr) &&
!vlan_id)
return;
}

memcpy(&src_addr, phdr->h_source, ETH_ALEN);
Expand Down
25 changes: 15 additions & 10 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,8 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
if (!adapter->fdb_mac_learn)
return ndo_dflt_fdb_del(ndm, tb, netdev, addr);

if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_sriov_check(adapter)) {
if (is_unicast_ether_addr(addr)) {
err = dev_uc_del(netdev, addr);
if (!err)
Expand All @@ -402,7 +403,8 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
if (!adapter->fdb_mac_learn)
return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags);

if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) &&
!qlcnic_sriov_check(adapter)) {
pr_info("%s: FDB e-switch is not enabled\n", __func__);
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -432,7 +434,8 @@ static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb,
if (!adapter->fdb_mac_learn)
return ndo_dflt_fdb_dump(skb, ncb, netdev, idx);

if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_sriov_check(adapter))
idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx);

return idx;
Expand Down Expand Up @@ -1917,8 +1920,6 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state))
return;

if (qlcnic_sriov_vf_check(adapter))
qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc);
smp_mb();
netif_carrier_off(netdev);
adapter->ahw->linkup = 0;
Expand All @@ -1930,6 +1931,8 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_delete_lb_filters(adapter);

qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE);
if (qlcnic_sriov_vf_check(adapter))
qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc);

qlcnic_napi_disable(adapter);

Expand Down Expand Up @@ -2398,9 +2401,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int err, pci_using_dac = -1;
char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */

if (pdev->is_virtfn)
return -ENODEV;

err = pci_enable_device(pdev);
if (err)
return err;
Expand Down Expand Up @@ -2680,9 +2680,9 @@ static void qlcnic_remove(struct pci_dev *pdev)
return;

netdev = adapter->netdev;
qlcnic_sriov_pf_disable(adapter);

qlcnic_cancel_idc_work(adapter);
qlcnic_sriov_pf_disable(adapter);
ahw = adapter->ahw;

unregister_netdev(netdev);
Expand Down Expand Up @@ -2812,6 +2812,8 @@ static int qlcnic_close(struct net_device *netdev)
return 0;
}

#define QLCNIC_VF_LB_BUCKET_SIZE 1

void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter)
{
void *head;
Expand All @@ -2827,7 +2829,10 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter)
spin_lock_init(&adapter->mac_learn_lock);
spin_lock_init(&adapter->rx_mac_learn_lock);

if (qlcnic_82xx_check(adapter)) {
if (qlcnic_sriov_vf_check(adapter)) {
filter_size = QLCNIC_83XX_SRIOV_VF_MAX_MAC - 1;
adapter->fhash.fbucket_size = QLCNIC_VF_LB_BUCKET_SIZE;
} else if (qlcnic_82xx_check(adapter)) {
filter_size = QLCNIC_LB_MAX_FILTERS;
adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE;
} else {
Expand Down
Loading

0 comments on commit fe6f397

Please sign in to comment.