net: aquantia: Cleanup pci functions module
Driver contained a dead code of maintaining multiple pci port instances. That will never be used since for each pci function a separate NIC instance is created. Simplify this, making pci module only responsible for pci resource management. NIC initialization is also simplified accordingly. Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
8fcb98f462
Коммит
23ee07ad3c
|
@ -31,7 +31,6 @@ struct aq_hw_caps_s {
|
|||
u32 vecs;
|
||||
u32 mtu;
|
||||
u32 mac_regs_count;
|
||||
u8 ports;
|
||||
u8 msix_irqs;
|
||||
u8 tcs;
|
||||
u8 rxd_alignment;
|
||||
|
|
|
@ -43,14 +43,9 @@ struct net_device *aq_ndev_alloc(void)
|
|||
|
||||
static int aq_ndev_open(struct net_device *ndev)
|
||||
{
|
||||
struct aq_nic_s *aq_nic = NULL;
|
||||
int err = 0;
|
||||
struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
||||
|
||||
aq_nic = aq_nic_alloc_hot(ndev);
|
||||
if (!aq_nic) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
err = aq_nic_init(aq_nic);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
@ -73,7 +68,6 @@ static int aq_ndev_close(struct net_device *ndev)
|
|||
if (err < 0)
|
||||
goto err_exit;
|
||||
aq_nic_deinit(aq_nic);
|
||||
aq_nic_free_hot_resources(aq_nic);
|
||||
|
||||
err_exit:
|
||||
return err;
|
||||
|
@ -145,15 +139,13 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev)
|
|||
|
||||
err = aq_nic_set_packet_filter(aq_nic, ndev->flags);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
return;
|
||||
|
||||
if (netdev_mc_count(ndev)) {
|
||||
err = aq_nic_set_multicast_list(aq_nic, ndev);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
return;
|
||||
}
|
||||
|
||||
err_exit:;
|
||||
}
|
||||
|
||||
static const struct net_device_ops aq_ndev_ops = {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "aq_vec.h"
|
||||
#include "aq_hw.h"
|
||||
#include "aq_pci_func.h"
|
||||
#include "aq_main.h"
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
@ -61,17 +60,13 @@ static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
|
|||
rss_params->indirection_table[i] = i & (num_rss_queues - 1);
|
||||
}
|
||||
|
||||
/* Fills aq_nic_cfg with valid defaults */
|
||||
static void aq_nic_cfg_init_defaults(struct aq_nic_s *self)
|
||||
/* Checks hw_caps and 'corrects' aq_nic_cfg in runtime */
|
||||
void aq_nic_cfg_start(struct aq_nic_s *self)
|
||||
{
|
||||
struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
|
||||
|
||||
cfg->vecs = AQ_CFG_VECS_DEF;
|
||||
cfg->tcs = AQ_CFG_TCS_DEF;
|
||||
|
||||
cfg->rxds = AQ_CFG_RXDS_DEF;
|
||||
cfg->txds = AQ_CFG_TXDS_DEF;
|
||||
|
||||
cfg->is_polling = AQ_CFG_IS_POLLING_DEF;
|
||||
|
||||
cfg->itr = aq_itr;
|
||||
|
@ -92,19 +87,13 @@ static void aq_nic_cfg_init_defaults(struct aq_nic_s *self)
|
|||
cfg->vlan_id = 0U;
|
||||
|
||||
aq_nic_rss_init(self, cfg->num_rss_queues);
|
||||
}
|
||||
|
||||
/* Checks hw_caps and 'corrects' aq_nic_cfg in runtime */
|
||||
int aq_nic_cfg_start(struct aq_nic_s *self)
|
||||
{
|
||||
struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
|
||||
|
||||
/*descriptors */
|
||||
cfg->rxds = min(cfg->rxds, cfg->aq_hw_caps->rxds);
|
||||
cfg->txds = min(cfg->txds, cfg->aq_hw_caps->txds);
|
||||
cfg->rxds = min(cfg->aq_hw_caps->rxds, AQ_CFG_RXDS_DEF);
|
||||
cfg->txds = min(cfg->aq_hw_caps->txds, AQ_CFG_TXDS_DEF);
|
||||
|
||||
/*rss rings */
|
||||
cfg->vecs = min(cfg->vecs, cfg->aq_hw_caps->vecs);
|
||||
cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF);
|
||||
cfg->vecs = min(cfg->vecs, num_online_cpus());
|
||||
/* cfg->vecs should be power of 2 for RSS */
|
||||
if (cfg->vecs >= 8U)
|
||||
|
@ -118,7 +107,7 @@ int aq_nic_cfg_start(struct aq_nic_s *self)
|
|||
|
||||
cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF);
|
||||
|
||||
cfg->irq_type = aq_pci_func_get_irq_type(self->aq_pci_func);
|
||||
cfg->irq_type = aq_pci_func_get_irq_type(self);
|
||||
|
||||
if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) ||
|
||||
(cfg->aq_hw_caps->vecs == 1U) ||
|
||||
|
@ -129,7 +118,6 @@ int aq_nic_cfg_start(struct aq_nic_s *self)
|
|||
|
||||
cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
|
||||
cfg->hw_features = cfg->aq_hw_caps->hw_features;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aq_nic_update_link_status(struct aq_nic_s *self)
|
||||
|
@ -203,50 +191,6 @@ static void aq_nic_polling_timer_cb(struct timer_list *t)
|
|||
AQ_CFG_POLLING_TIMER_INTERVAL);
|
||||
}
|
||||
|
||||
struct aq_nic_s *aq_nic_alloc_cold(struct pci_dev *pdev,
|
||||
struct aq_pci_func_s *aq_pci_func,
|
||||
unsigned int port,
|
||||
const struct aq_hw_ops *aq_hw_ops,
|
||||
const struct aq_hw_caps_s *aq_hw_caps)
|
||||
{
|
||||
struct net_device *ndev = NULL;
|
||||
struct aq_nic_s *self = NULL;
|
||||
int err = 0;
|
||||
|
||||
ndev = aq_ndev_alloc();
|
||||
if (!ndev) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
self = netdev_priv(ndev);
|
||||
|
||||
SET_NETDEV_DEV(ndev, &pdev->dev);
|
||||
|
||||
ndev->if_port = port;
|
||||
self->ndev = ndev;
|
||||
|
||||
self->aq_pci_func = aq_pci_func;
|
||||
|
||||
self->aq_hw_ops = aq_hw_ops;
|
||||
self->aq_nic_cfg.aq_hw_caps = aq_hw_caps;
|
||||
self->aq_hw->aq_nic_cfg = &self->aq_nic_cfg;
|
||||
self->port = (u8)port;
|
||||
|
||||
self->aq_hw = self->aq_hw_ops->create(aq_pci_func, self->port);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
aq_nic_cfg_init_defaults(self);
|
||||
|
||||
err_exit:
|
||||
if (err < 0) {
|
||||
aq_nic_free_hot_resources(self);
|
||||
self = NULL;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
int aq_nic_ndev_register(struct aq_nic_s *self)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -255,9 +199,10 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
|
|||
err = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
err = self->aq_hw_ops->hw_get_mac_permanent(self->aq_hw,
|
||||
self->ndev->dev_addr);
|
||||
if (err < 0)
|
||||
if (err)
|
||||
goto err_exit;
|
||||
|
||||
#if defined(AQ_CFG_MAC_ADDR_PERMANENT)
|
||||
|
@ -268,19 +213,29 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
|
|||
}
|
||||
#endif
|
||||
|
||||
for (self->aq_vecs = 0; self->aq_vecs < aq_nic_get_cfg(self)->vecs;
|
||||
self->aq_vecs++) {
|
||||
self->aq_vec[self->aq_vecs] =
|
||||
aq_vec_alloc(self, self->aq_vecs, aq_nic_get_cfg(self));
|
||||
if (!self->aq_vec[self->aq_vecs]) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
netif_carrier_off(self->ndev);
|
||||
|
||||
netif_tx_disable(self->ndev);
|
||||
|
||||
err = register_netdev(self->ndev);
|
||||
if (err < 0)
|
||||
if (err)
|
||||
goto err_exit;
|
||||
|
||||
err_exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
int aq_nic_ndev_init(struct aq_nic_s *self)
|
||||
void aq_nic_ndev_init(struct aq_nic_s *self)
|
||||
{
|
||||
const struct aq_hw_caps_s *aq_hw_caps = self->aq_nic_cfg.aq_hw_caps;
|
||||
struct aq_nic_cfg_s *aq_nic_cfg = &self->aq_nic_cfg;
|
||||
|
@ -291,60 +246,6 @@ int aq_nic_ndev_init(struct aq_nic_s *self)
|
|||
self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
|
||||
self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aq_nic_ndev_free(struct aq_nic_s *self)
|
||||
{
|
||||
if (!self->ndev)
|
||||
goto err_exit;
|
||||
|
||||
if (self->ndev->reg_state == NETREG_REGISTERED)
|
||||
unregister_netdev(self->ndev);
|
||||
|
||||
if (self->aq_hw)
|
||||
self->aq_hw_ops->destroy(self->aq_hw);
|
||||
|
||||
free_netdev(self->ndev);
|
||||
|
||||
err_exit:;
|
||||
}
|
||||
|
||||
struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev)
|
||||
{
|
||||
struct aq_nic_s *self = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (!ndev) {
|
||||
err = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
self = netdev_priv(ndev);
|
||||
|
||||
if (!self) {
|
||||
err = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
if (netif_running(ndev))
|
||||
netif_tx_disable(ndev);
|
||||
netif_carrier_off(self->ndev);
|
||||
|
||||
for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs;
|
||||
self->aq_vecs++) {
|
||||
self->aq_vec[self->aq_vecs] =
|
||||
aq_vec_alloc(self, self->aq_vecs, &self->aq_nic_cfg);
|
||||
if (!self->aq_vec[self->aq_vecs]) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
err_exit:
|
||||
if (err < 0) {
|
||||
aq_nic_free_hot_resources(self);
|
||||
self = NULL;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
|
||||
|
@ -370,7 +271,7 @@ int aq_nic_init(struct aq_nic_s *self)
|
|||
goto err_exit;
|
||||
|
||||
err = self->aq_hw_ops->hw_init(self->aq_hw,
|
||||
aq_nic_get_ndev(self)->dev_addr);
|
||||
aq_nic_get_ndev(self)->dev_addr);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
|
@ -378,6 +279,8 @@ int aq_nic_init(struct aq_nic_s *self)
|
|||
self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
|
||||
aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw);
|
||||
|
||||
netif_carrier_off(self->ndev);
|
||||
|
||||
err_exit:
|
||||
return err;
|
||||
}
|
||||
|
@ -424,9 +327,9 @@ int aq_nic_start(struct aq_nic_s *self)
|
|||
} else {
|
||||
for (i = 0U, aq_vec = self->aq_vec[0];
|
||||
self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
|
||||
err = aq_pci_func_alloc_irq(self->aq_pci_func, i,
|
||||
err = aq_pci_func_alloc_irq(self, i,
|
||||
self->ndev->name, aq_vec,
|
||||
aq_vec_get_affinity_mask(aq_vec));
|
||||
aq_vec_get_affinity_mask(aq_vec));
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
}
|
||||
|
@ -617,8 +520,7 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
|
|||
|
||||
if (likely(frags)) {
|
||||
err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
|
||||
ring,
|
||||
frags);
|
||||
ring, frags);
|
||||
if (err >= 0) {
|
||||
++ring->stats.tx.packets;
|
||||
ring->stats.tx.bytes += skb->len;
|
||||
|
@ -674,7 +576,7 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
|
|||
self->packet_filter |= IFF_ALLMULTI;
|
||||
self->aq_nic_cfg.mc_list_count = 0;
|
||||
return self->aq_hw_ops->hw_packet_filter_set(self->aq_hw,
|
||||
self->packet_filter);
|
||||
self->packet_filter);
|
||||
} else {
|
||||
return self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
|
||||
self->mc_list.ar,
|
||||
|
@ -757,7 +659,6 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
|
|||
i++;
|
||||
|
||||
data += i;
|
||||
count = 0U;
|
||||
|
||||
for (i = 0U, aq_vec = self->aq_vec[0];
|
||||
aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
|
||||
|
@ -937,7 +838,7 @@ int aq_nic_stop(struct aq_nic_s *self)
|
|||
if (self->aq_nic_cfg.is_polling)
|
||||
del_timer_sync(&self->polling_timer);
|
||||
else
|
||||
aq_pci_func_free_irqs(self->aq_pci_func);
|
||||
aq_pci_func_free_irqs(self);
|
||||
|
||||
for (i = 0U, aq_vec = self->aq_vec[0];
|
||||
self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
|
||||
|
@ -968,7 +869,7 @@ void aq_nic_deinit(struct aq_nic_s *self)
|
|||
err_exit:;
|
||||
}
|
||||
|
||||
void aq_nic_free_hot_resources(struct aq_nic_s *self)
|
||||
void aq_nic_free_vectors(struct aq_nic_s *self)
|
||||
{
|
||||
unsigned int i = 0U;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "aq_hw.h"
|
||||
|
||||
struct aq_ring_s;
|
||||
struct aq_pci_func_s;
|
||||
struct aq_hw_ops;
|
||||
struct aq_fw_s;
|
||||
struct aq_vec_s;
|
||||
|
@ -64,7 +63,6 @@ struct aq_nic_s {
|
|||
struct aq_ring_s *aq_ring_tx[AQ_CFG_VECS_MAX * AQ_CFG_TCS_MAX];
|
||||
struct aq_hw_s *aq_hw;
|
||||
struct net_device *ndev;
|
||||
struct aq_pci_func_s *aq_pci_func;
|
||||
unsigned int aq_vecs;
|
||||
unsigned int packet_filter;
|
||||
unsigned int power_state;
|
||||
|
@ -88,19 +86,13 @@ static inline struct device *aq_nic_get_dev(struct aq_nic_s *self)
|
|||
return self->ndev->dev.parent;
|
||||
}
|
||||
|
||||
struct aq_nic_s *aq_nic_alloc_cold(struct pci_dev *pdev,
|
||||
struct aq_pci_func_s *aq_pci_func,
|
||||
unsigned int port,
|
||||
const struct aq_hw_ops *aq_hw_ops,
|
||||
const struct aq_hw_caps_s *aq_hw_caps);
|
||||
int aq_nic_ndev_init(struct aq_nic_s *self);
|
||||
void aq_nic_ndev_init(struct aq_nic_s *self);
|
||||
struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev);
|
||||
void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
|
||||
struct aq_ring_s *ring);
|
||||
struct device *aq_nic_get_dev(struct aq_nic_s *self);
|
||||
struct net_device *aq_nic_get_ndev(struct aq_nic_s *self);
|
||||
int aq_nic_init(struct aq_nic_s *self);
|
||||
int aq_nic_cfg_start(struct aq_nic_s *self);
|
||||
void aq_nic_cfg_start(struct aq_nic_s *self);
|
||||
int aq_nic_ndev_register(struct aq_nic_s *self);
|
||||
void aq_nic_ndev_free(struct aq_nic_s *self);
|
||||
int aq_nic_start(struct aq_nic_s *self);
|
||||
|
@ -111,6 +103,7 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data);
|
|||
int aq_nic_stop(struct aq_nic_s *self);
|
||||
void aq_nic_deinit(struct aq_nic_s *self);
|
||||
void aq_nic_free_hot_resources(struct aq_nic_s *self);
|
||||
void aq_nic_free_vectors(struct aq_nic_s *self);
|
||||
int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu);
|
||||
int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev);
|
||||
int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags);
|
||||
|
|
|
@ -12,27 +12,14 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "aq_pci_func.h"
|
||||
#include "aq_main.h"
|
||||
#include "aq_nic.h"
|
||||
#include "aq_vec.h"
|
||||
#include "aq_hw.h"
|
||||
#include "aq_pci_func.h"
|
||||
#include "hw_atl/hw_atl_a0.h"
|
||||
#include "hw_atl/hw_atl_b0.h"
|
||||
|
||||
struct aq_pci_func_s {
|
||||
struct pci_dev *pdev;
|
||||
struct aq_nic_s *port[AQ_CFG_PCI_FUNC_PORTS];
|
||||
void __iomem *mmio;
|
||||
void *aq_vec[AQ_CFG_PCI_FUNC_MSIX_IRQS];
|
||||
resource_size_t mmio_pa;
|
||||
unsigned int msix_entry_mask;
|
||||
unsigned int ports;
|
||||
bool is_pci_enabled;
|
||||
bool is_regions;
|
||||
bool is_pci_using_dac;
|
||||
struct aq_hw_caps_s aq_hw_caps;
|
||||
};
|
||||
|
||||
static const struct pci_device_id aq_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_0001), },
|
||||
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_D100), },
|
||||
|
@ -118,156 +105,39 @@ static int aq_pci_probe_get_hw_by_id(struct pci_dev *pdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct aq_pci_func_s *aq_pci_func_alloc(const struct aq_hw_ops *aq_hw_ops,
|
||||
const struct aq_hw_caps_s *aq_hw_caps,
|
||||
struct pci_dev *pdev)
|
||||
{
|
||||
struct aq_pci_func_s *self = NULL;
|
||||
int err = 0;
|
||||
unsigned int port = 0U;
|
||||
|
||||
if (!aq_hw_ops) {
|
||||
err = -EFAULT;
|
||||
goto err_exit;
|
||||
}
|
||||
self = kzalloc(sizeof(*self), GFP_KERNEL);
|
||||
if (!self) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, self);
|
||||
self->pdev = pdev;
|
||||
self->aq_hw_caps = *aq_hw_caps;
|
||||
|
||||
self->ports = self->aq_hw_caps.ports;
|
||||
|
||||
for (port = 0; port < self->ports; ++port) {
|
||||
struct aq_nic_s *aq_nic = aq_nic_alloc_cold(pdev, self,
|
||||
port, aq_hw_ops,
|
||||
aq_hw_caps);
|
||||
|
||||
if (!aq_nic) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
self->port[port] = aq_nic;
|
||||
}
|
||||
|
||||
err_exit:
|
||||
if (err < 0) {
|
||||
if (self)
|
||||
aq_pci_func_free(self);
|
||||
self = NULL;
|
||||
}
|
||||
|
||||
(void)err;
|
||||
return self;
|
||||
}
|
||||
|
||||
int aq_pci_func_init(struct aq_pci_func_s *self)
|
||||
int aq_pci_func_init(struct pci_dev *pdev)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int bar = 0U;
|
||||
unsigned int port = 0U;
|
||||
unsigned int numvecs = 0U;
|
||||
|
||||
err = pci_enable_device(self->pdev);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
self->is_pci_enabled = true;
|
||||
|
||||
err = pci_set_dma_mask(self->pdev, DMA_BIT_MASK(64));
|
||||
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||
if (!err) {
|
||||
err = pci_set_consistent_dma_mask(self->pdev, DMA_BIT_MASK(64));
|
||||
self->is_pci_using_dac = 1;
|
||||
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||
|
||||
}
|
||||
if (err) {
|
||||
err = pci_set_dma_mask(self->pdev, DMA_BIT_MASK(32));
|
||||
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
if (!err)
|
||||
err = pci_set_consistent_dma_mask(self->pdev,
|
||||
err = pci_set_consistent_dma_mask(pdev,
|
||||
DMA_BIT_MASK(32));
|
||||
self->is_pci_using_dac = 0;
|
||||
}
|
||||
if (err != 0) {
|
||||
err = -ENOSR;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
err = pci_request_regions(self->pdev, AQ_CFG_DRV_NAME "_mmio");
|
||||
err = pci_request_regions(pdev, AQ_CFG_DRV_NAME "_mmio");
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
self->is_regions = true;
|
||||
pci_set_master(pdev);
|
||||
|
||||
pci_set_master(self->pdev);
|
||||
|
||||
for (bar = 0; bar < 4; ++bar) {
|
||||
if (IORESOURCE_MEM & pci_resource_flags(self->pdev, bar)) {
|
||||
resource_size_t reg_sz;
|
||||
|
||||
self->mmio_pa = pci_resource_start(self->pdev, bar);
|
||||
if (self->mmio_pa == 0U) {
|
||||
err = -EIO;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
reg_sz = pci_resource_len(self->pdev, bar);
|
||||
if ((reg_sz <= 24 /*ATL_REGS_SIZE*/)) {
|
||||
err = -EIO;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
self->mmio = ioremap_nocache(self->mmio_pa, reg_sz);
|
||||
if (!self->mmio) {
|
||||
err = -EIO;
|
||||
goto err_exit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
numvecs = min((u8)AQ_CFG_VECS_DEF, self->aq_hw_caps.msix_irqs);
|
||||
numvecs = min(numvecs, num_online_cpus());
|
||||
|
||||
/* enable interrupts */
|
||||
#if !AQ_CFG_FORCE_LEGACY_INT
|
||||
err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs, PCI_IRQ_MSIX);
|
||||
|
||||
if (err < 0) {
|
||||
err = pci_alloc_irq_vectors(self->pdev, 1, 1,
|
||||
PCI_IRQ_MSI | PCI_IRQ_LEGACY);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
}
|
||||
#endif /* AQ_CFG_FORCE_LEGACY_INT */
|
||||
|
||||
/* net device init */
|
||||
for (port = 0; port < self->ports; ++port) {
|
||||
if (!self->port[port])
|
||||
continue;
|
||||
|
||||
err = aq_nic_cfg_start(self->port[port]);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
err = aq_nic_ndev_init(self->port[port]);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
err = aq_nic_ndev_register(self->port[port]);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_exit:
|
||||
if (err < 0)
|
||||
aq_pci_func_deinit(self);
|
||||
return err;
|
||||
}
|
||||
|
||||
int aq_pci_func_alloc_irq(struct aq_pci_func_s *self, unsigned int i,
|
||||
int aq_pci_func_alloc_irq(struct aq_nic_s *self, unsigned int i,
|
||||
char *name, void *aq_vec, cpumask_t *affinity_mask)
|
||||
{
|
||||
struct pci_dev *pdev = self->pdev;
|
||||
|
@ -288,11 +158,10 @@ int aq_pci_func_alloc_irq(struct aq_pci_func_s *self, unsigned int i,
|
|||
irq_set_affinity_hint(pci_irq_vector(pdev, i),
|
||||
affinity_mask);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void aq_pci_func_free_irqs(struct aq_pci_func_s *self)
|
||||
void aq_pci_func_free_irqs(struct aq_nic_s *self)
|
||||
{
|
||||
struct pci_dev *pdev = self->pdev;
|
||||
unsigned int i = 0U;
|
||||
|
@ -308,12 +177,7 @@ void aq_pci_func_free_irqs(struct aq_pci_func_s *self)
|
|||
}
|
||||
}
|
||||
|
||||
void __iomem *aq_pci_func_get_mmio(struct aq_pci_func_s *self)
|
||||
{
|
||||
return self->mmio;
|
||||
}
|
||||
|
||||
unsigned int aq_pci_func_get_irq_type(struct aq_pci_func_s *self)
|
||||
unsigned int aq_pci_func_get_irq_type(struct aq_nic_s *self)
|
||||
{
|
||||
if (self->pdev->msix_enabled)
|
||||
return AQ_HW_IRQ_MSIX;
|
||||
|
@ -322,118 +186,148 @@ unsigned int aq_pci_func_get_irq_type(struct aq_pci_func_s *self)
|
|||
return AQ_HW_IRQ_LEGACY;
|
||||
}
|
||||
|
||||
void aq_pci_func_deinit(struct aq_pci_func_s *self)
|
||||
static void aq_pci_free_irq_vectors(struct aq_nic_s *self)
|
||||
{
|
||||
if (!self)
|
||||
goto err_exit;
|
||||
|
||||
aq_pci_func_free_irqs(self);
|
||||
pci_free_irq_vectors(self->pdev);
|
||||
|
||||
if (self->is_regions)
|
||||
pci_release_regions(self->pdev);
|
||||
|
||||
if (self->is_pci_enabled)
|
||||
pci_disable_device(self->pdev);
|
||||
|
||||
err_exit:;
|
||||
}
|
||||
|
||||
void aq_pci_func_free(struct aq_pci_func_s *self)
|
||||
{
|
||||
unsigned int port = 0U;
|
||||
|
||||
if (!self)
|
||||
goto err_exit;
|
||||
|
||||
for (port = 0; port < self->ports; ++port) {
|
||||
if (!self->port[port])
|
||||
continue;
|
||||
|
||||
aq_nic_ndev_free(self->port[port]);
|
||||
}
|
||||
|
||||
if (self->mmio)
|
||||
iounmap(self->mmio);
|
||||
|
||||
kfree(self);
|
||||
|
||||
err_exit:;
|
||||
}
|
||||
|
||||
int aq_pci_func_change_pm_state(struct aq_pci_func_s *self,
|
||||
pm_message_t *pm_msg)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int port = 0U;
|
||||
|
||||
if (!self) {
|
||||
err = -EFAULT;
|
||||
goto err_exit;
|
||||
}
|
||||
for (port = 0; port < self->ports; ++port) {
|
||||
if (!self->port[port])
|
||||
continue;
|
||||
|
||||
(void)aq_nic_change_pm_state(self->port[port], pm_msg);
|
||||
}
|
||||
|
||||
err_exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aq_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
const struct aq_hw_ops *aq_hw_ops = NULL;
|
||||
const struct aq_hw_caps_s *aq_hw_caps = NULL;
|
||||
struct aq_pci_func_s *aq_pci_func = NULL;
|
||||
struct aq_nic_s *self = NULL;
|
||||
int err = 0;
|
||||
struct net_device *ndev;
|
||||
resource_size_t mmio_pa;
|
||||
u32 bar;
|
||||
u32 numvecs;
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
err = aq_pci_probe_get_hw_by_id(pdev, &aq_hw_ops, &aq_hw_caps);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
aq_pci_func = aq_pci_func_alloc(aq_hw_ops, aq_hw_caps, pdev);
|
||||
if (!aq_pci_func) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
err = aq_pci_func_init(aq_pci_func);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err_exit:
|
||||
if (err < 0) {
|
||||
if (aq_pci_func)
|
||||
aq_pci_func_free(aq_pci_func);
|
||||
err = aq_pci_func_init(pdev);
|
||||
if (err)
|
||||
goto err_pci_func;
|
||||
|
||||
ndev = aq_ndev_alloc();
|
||||
if (!ndev)
|
||||
goto err_ndev;
|
||||
|
||||
self = netdev_priv(ndev);
|
||||
self->pdev = pdev;
|
||||
SET_NETDEV_DEV(ndev, &pdev->dev);
|
||||
pci_set_drvdata(pdev, self);
|
||||
|
||||
err = aq_pci_probe_get_hw_by_id(pdev, &self->aq_hw_ops,
|
||||
&aq_nic_get_cfg(self)->aq_hw_caps);
|
||||
if (err)
|
||||
goto err_ioremap;
|
||||
|
||||
self->aq_hw = kzalloc(sizeof(*self->aq_hw), GFP_KERNEL);
|
||||
self->aq_hw->aq_nic_cfg = aq_nic_get_cfg(self);
|
||||
|
||||
for (bar = 0; bar < 4; ++bar) {
|
||||
if (IORESOURCE_MEM & pci_resource_flags(pdev, bar)) {
|
||||
resource_size_t reg_sz;
|
||||
|
||||
mmio_pa = pci_resource_start(pdev, bar);
|
||||
if (mmio_pa == 0U) {
|
||||
err = -EIO;
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
reg_sz = pci_resource_len(pdev, bar);
|
||||
if ((reg_sz <= 24 /*ATL_REGS_SIZE*/)) {
|
||||
err = -EIO;
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
self->aq_hw->mmio = ioremap_nocache(mmio_pa, reg_sz);
|
||||
if (!self->aq_hw->mmio) {
|
||||
err = -EIO;
|
||||
goto err_ioremap;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bar == 4) {
|
||||
err = -EIO;
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
numvecs = min((u8)AQ_CFG_VECS_DEF,
|
||||
aq_nic_get_cfg(self)->aq_hw_caps->msix_irqs);
|
||||
numvecs = min(numvecs, num_online_cpus());
|
||||
/*enable interrupts */
|
||||
#if !AQ_CFG_FORCE_LEGACY_INT
|
||||
err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs,
|
||||
PCI_IRQ_MSIX);
|
||||
|
||||
if (err < 0) {
|
||||
err = pci_alloc_irq_vectors(self->pdev, 1, 1,
|
||||
PCI_IRQ_MSI | PCI_IRQ_LEGACY);
|
||||
if (err < 0)
|
||||
goto err_hwinit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* net device init */
|
||||
aq_nic_cfg_start(self);
|
||||
|
||||
aq_nic_ndev_init(self);
|
||||
|
||||
err = aq_nic_ndev_register(self);
|
||||
if (err < 0)
|
||||
goto err_register;
|
||||
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
aq_nic_free_vectors(self);
|
||||
aq_pci_free_irq_vectors(self);
|
||||
err_hwinit:
|
||||
iounmap(self->aq_hw->mmio);
|
||||
err_ioremap:
|
||||
free_netdev(ndev);
|
||||
err_pci_func:
|
||||
pci_release_regions(pdev);
|
||||
err_ndev:
|
||||
pci_disable_device(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void aq_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct aq_pci_func_s *aq_pci_func = pci_get_drvdata(pdev);
|
||||
struct aq_nic_s *self = pci_get_drvdata(pdev);
|
||||
|
||||
aq_pci_func_deinit(aq_pci_func);
|
||||
aq_pci_func_free(aq_pci_func);
|
||||
if (self->ndev) {
|
||||
if (self->ndev->reg_state == NETREG_REGISTERED)
|
||||
unregister_netdev(self->ndev);
|
||||
aq_nic_free_vectors(self);
|
||||
aq_pci_free_irq_vectors(self);
|
||||
iounmap(self->aq_hw->mmio);
|
||||
kfree(self->aq_hw);
|
||||
pci_release_regions(pdev);
|
||||
free_netdev(self->ndev);
|
||||
}
|
||||
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg)
|
||||
{
|
||||
struct aq_pci_func_s *aq_pci_func = pci_get_drvdata(pdev);
|
||||
struct aq_nic_s *self = pci_get_drvdata(pdev);
|
||||
|
||||
return aq_pci_func_change_pm_state(aq_pci_func, &pm_msg);
|
||||
return aq_nic_change_pm_state(self, &pm_msg);
|
||||
}
|
||||
|
||||
static int aq_pci_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct aq_pci_func_s *aq_pci_func = pci_get_drvdata(pdev);
|
||||
struct aq_nic_s *self = pci_get_drvdata(pdev);
|
||||
pm_message_t pm_msg = PMSG_RESTORE;
|
||||
|
||||
return aq_pci_func_change_pm_state(aq_pci_func, &pm_msg);
|
||||
return aq_nic_change_pm_state(self, &pm_msg);
|
||||
}
|
||||
|
||||
static struct pci_driver aq_pci_ops = {
|
||||
|
|
|
@ -22,17 +22,11 @@ struct aq_board_revision_s {
|
|||
const struct aq_hw_caps_s *caps;
|
||||
};
|
||||
|
||||
int aq_pci_func_init(struct aq_pci_func_s *self);
|
||||
int aq_pci_func_alloc_irq(struct aq_pci_func_s *self, unsigned int i,
|
||||
int aq_pci_func_init(struct pci_dev *pdev);
|
||||
int aq_pci_func_alloc_irq(struct aq_nic_s *self, unsigned int i,
|
||||
char *name, void *aq_vec,
|
||||
cpumask_t *affinity_mask);
|
||||
void aq_pci_func_free_irqs(struct aq_pci_func_s *self);
|
||||
int aq_pci_func_start(struct aq_pci_func_s *self);
|
||||
void __iomem *aq_pci_func_get_mmio(struct aq_pci_func_s *self);
|
||||
unsigned int aq_pci_func_get_irq_type(struct aq_pci_func_s *self);
|
||||
void aq_pci_func_deinit(struct aq_pci_func_s *self);
|
||||
void aq_pci_func_free(struct aq_pci_func_s *self);
|
||||
int aq_pci_func_change_pm_state(struct aq_pci_func_s *self,
|
||||
pm_message_t *pm_msg);
|
||||
void aq_pci_func_free_irqs(struct aq_nic_s *self);
|
||||
unsigned int aq_pci_func_get_irq_type(struct aq_nic_s *self);
|
||||
|
||||
#endif /* AQ_PCI_FUNC_H */
|
||||
|
|
|
@ -369,8 +369,6 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
|
|||
u32 l = 0U;
|
||||
u32 mac_addr[2];
|
||||
|
||||
self->mmio = aq_pci_func_get_mmio(self->aq_pci_func);
|
||||
|
||||
hw_atl_utils_hw_chip_features_init(self,
|
||||
&self->chip_features);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче