Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • atlas-tdaq-felix/felix-versal-tools/flxnet-drivers
1 result
Show changes
......@@ -30,13 +30,6 @@
#define DRV_NAME "flxnet_dev"
/*
- disable tx and rx on the peers without "link" present
- it's possible to make TX queue circular buffer lockless
- user interrupts instead of timer; use NAPI
*/
struct mutex flxnet_mutex;
u32 message_level;
......@@ -211,19 +204,19 @@ struct flxnet_peer *find_peer_for_netdev(struct net_device *dev) {
}
// removes the peer from the network, assumes that peer_mutex is held
// removes the peer from the network
void flxnet_remove_peer(struct flxnet_peer *peer) {
int rv;
set_carrier(peer, false);
netif_stop_queue(peer->flxnet);
netif_carrier_off(peer->flxnet);
unregister_netdev(peer->flxnet);
free_netdev(peer->flxnet);
kfree(peer->tx_queue.packets);
if (message_level & NETIF_MSG_LINK)
pr_info("flxnet_dev: removing peer %p from the network\n", peer);
mutex_lock(&peer_mutex);
set_carrier(peer, false);
unregister_netdev(peer->flxnet);
free_netdev(peer->flxnet);
kfree(peer->tx_queue.packets);
rv = atomic_dec_return(&peer_count);
if (rv < 0) {
pr_err("flxnet_dev: BUG in %s: peer_count = %d, less than 0\n",
......@@ -233,50 +226,9 @@ void flxnet_remove_peer(struct flxnet_peer *peer) {
list_del(&peer->list_head);
kfree(peer);
mutex_unlock(&peer_mutex);
}
// mark as not reserved so that peer modules can be removed
//void flxnet_release_all_peers(void) {
// struct flxnet_peer *peer;
// struct flxnet_peer *tmp;
//
// mutex_lock(&peer_mutex);
// list_for_each_entry_safe(peer, tmp, &peers, list_head) {
// if (peer->reserved) {
// module_put(peer->owner);
// peer->reserved = false;
// } else {
// if (message_level & NETIF_MSG_DRV)
// pr_info("flxnet_dev: trying to release peer %p, which is not reserved, skipping\n", peer);
// }
// }
// mutex_unlock(&peer_mutex);
//}
// mark as reserved so that peer modules cannot be removed and iomem stay there
//void flxnet_reserve_all_peers(void) {
// struct flxnet_peer *peer;
// struct flxnet_peer *tmp;
//
// mutex_lock(&peer_mutex);
// list_for_each_entry_safe(peer, tmp, &peers, list_head) {
// if (!peer->reserved) {
// peer->reserved = try_module_get(peer->owner);
// if (!peer->reserved) {
// pr_err("flxnet_dev: failed to reserve peer %p, owner module is missing\n", peer);
// flxnet_remove_peer(peer);
// }
// } else {
// if (message_level & NETIF_MSG_DRV)
// pr_info("flxnet_dev: trying to reserve peer %p, which is already reserved, skipping\n", peer);
// }
// }
// mutex_unlock(&peer_mutex);
//}
static bool tx_queue_is_full(struct flxnet_peer *peer) {
bool rv;
unsigned long flags;
......@@ -579,7 +531,6 @@ static inline void check_carrier(struct flxnet_peer *peer) {
if (!netif_carrier_ok(peer->flxnet)) {
if (message_level & NETIF_MSG_IFUP)
pr_info("flxnet_dev: status carrier changed to %d\n", carrier);
netif_start_queue(peer->flxnet);
netif_carrier_on(peer->flxnet);
}
}
......@@ -587,7 +538,6 @@ static inline void check_carrier(struct flxnet_peer *peer) {
if (netif_carrier_ok(peer->flxnet)) {
if (message_level & NETIF_MSG_IFDOWN)
pr_info("flxnet_dev: status carrier changed to %d\n", carrier);
netif_stop_queue(peer->flxnet);
netif_carrier_off(peer->flxnet);
}
}
......@@ -605,7 +555,6 @@ void recv_timer_function(struct timer_list *timer_list) {
bool can_transmit_packets(struct flxnet_peer *peer) {
if (is_magic_correct(peer) && can_accept_block(peer)) {
mutex_unlock(&peer_mutex);
return true;
}
return false;
......@@ -712,8 +661,6 @@ int send_recv_thread(void *data) {
int open(struct net_device *dev) {
mutex_lock(&flxnet_mutex);
//flxnet_reserve_all_peers(); // reserve the modules that supplied the peers
tx_queue_reset(dev); // clear TX queue
// enable RX side
......@@ -733,7 +680,6 @@ int open(struct net_device *dev) {
if (message_level & NETIF_MSG_IFUP)
pr_info("flxnet_dev: start netif queue\n");
netif_start_queue(dev);
netif_carrier_on(dev);
mutex_unlock(&flxnet_mutex);
return 0;
......@@ -753,11 +699,8 @@ int stop(struct net_device *dev) {
if (message_level & NETIF_MSG_IFDOWN)
pr_info("flxnet_dev: stop netif queue\n");
netif_stop_queue(dev);
netif_carrier_off(dev);
tx_queue_reset(dev); // clear TX queue
//flxnet_release_all_peers(); // free the modules that supplied the peers
mutex_unlock(&flxnet_mutex);
return 0;
......@@ -1042,10 +985,12 @@ err_alloc_tx_queue:
}
// add a felix device to the network
// add a peer device to the network
struct flxnet_peer * flxnet_add_peer(void* __iomem base_address) {
struct flxnet_peer *peer;
pr_info("flxnet_dev: flxnet_add_peer %lX\n", (long unsigned int)base_address);
mutex_lock(&peer_mutex);
peer = kzalloc(sizeof(struct flxnet_peer), GFP_KERNEL);
if (IS_ERR(peer)) {
pr_err("flxnet_dev: can't allocate memory for struct flxnet_peer\n");
......@@ -1071,7 +1016,7 @@ struct flxnet_peer * flxnet_add_peer(void* __iomem base_address) {
if (message_level & NETIF_MSG_IFUP)
pr_info("flxnet_dev: status_carrier %d\n", status_carrier(peer));
list_add(&peers, &peer->list_head);
list_add(&peer->list_head, &peers);
atomic_inc(&peer_count);
mutex_unlock(&peer_mutex);
......@@ -1091,24 +1036,8 @@ int __init flxnet_dev_init(void) {
return 0;
}
// unregister the network device if necessary
void __exit flxnet_dev_exit(void) {
struct flxnet_peer *peer, *tmp;
if (!list_empty(&peers)) {
mutex_lock(&peer_mutex);
list_for_each_entry_safe(peer, tmp, &peers, list_head) {
netif_stop_queue(peer->flxnet);
netif_carrier_off(peer->flxnet);
unregister_netdev(peer->flxnet);
free_netdev(peer->flxnet);
kfree(peer->tx_queue.packets);
}
pr_info("flxnet_dev: unregistred network device\n");
}
pr_info("flxnet_dev: removing %s driver\n", DRV_NAME);
mutex_unlock(&peer_mutex);
mutex_destroy(&peer_mutex);
mutex_destroy(&flxnet_mutex);
}
......
......@@ -37,7 +37,6 @@ struct pcie_flx_serial_device {
struct pci_dev *pdev; // pci device struct from probe()
void __iomem *bar; // addresses for the relevant BAR
int bar_idx;
spinlock_t lock; // protects concurrent access
unsigned int flags;
struct flxnet_peer * peer;
......@@ -66,11 +65,16 @@ static int flxnet_pcie_init(void) {
// if a PCI device is found, a pointer to its device structure is returned
pdev = pci_get_device(0x10dc, 0x0427, pdev);
if (pdev == NULL) {
pr_info("flxnet_pcie: no pcie devices available\n");
return 0;
}
// pdev returns NULL when all the PCI devices are found and stops searching
while (pdev != NULL) {
pr_info("flxnet_pcie: found %s \n", pci_name(pdev));
rv = configure_pcie_device(pdev);
pci_dev_put(pdev);
if (rv < 0) {
pr_warn("flxnet_pcie: failed to configure %s\n", pci_name(pdev));
}
......@@ -84,6 +88,7 @@ static int flxnet_pcie_init(void) {
return rv;
}
// deconfigure pcie devices if necessary, remove module
static void flxnet_pcie_exit(void) {
......@@ -95,8 +100,9 @@ static void flxnet_pcie_exit(void) {
pr_info("flxnet_pcie: list not empty - deconfiguring PCIe devices\n");
list_for_each_entry_safe(fdev, tmp, &flx_devices, list_head) {
flxnet_remove_peer(fdev->peer);
list_del(&fdev->list_head);
deconfigure_device(fdev);
}
}
}
else {
pr_info("flxnet_pcie: list is empty - nothing to deconfigure\n");
......@@ -104,6 +110,7 @@ static void flxnet_pcie_exit(void) {
}
// configure a felix serial device
static int configure_pcie_device(struct pci_dev *pdev) {
int rv;
......@@ -120,7 +127,6 @@ static int configure_pcie_device(struct pci_dev *pdev) {
if (!fdev)
return -ENOMEM;
spin_lock_init(&fdev->lock);
fdev->magic = FLX_PCIE_MAGIC;
fdev->pdev = pdev;
fdev->bar_idx = bar_idx;
......@@ -132,6 +138,7 @@ static int configure_pcie_device(struct pci_dev *pdev) {
pr_err("flxnet_pcie: pci_enable_device() failed, %d\n", rv);
goto err_enable;
}
pci_dev_get(pdev);
// reserve the selected bar for this driver
pr_info("flxnet_pcie: reserving BAR memory\n");
......@@ -146,7 +153,8 @@ static int configure_pcie_device(struct pci_dev *pdev) {
rv = map_single_bar(fdev, bar_idx);
if (rv < 0) {
goto warn_nobar;
} else if (rv < MIN_MMAP_SIZE) {
}
else if (rv < MIN_MMAP_SIZE) {
pr_err("flxnet_pcie: mapped region is too small (%d bytes < %d)\n",
rv, MIN_MMAP_SIZE);
goto err_peer;
......@@ -161,6 +169,7 @@ static int configure_pcie_device(struct pci_dev *pdev) {
goto err_peer;
}
// device structure
list_add(&fdev->list_head, &flx_devices);
pr_info("flxnet_pcie: added peer to list flx_devices\n");
......@@ -207,20 +216,17 @@ static void deconfigure_device(struct pcie_flx_serial_device *fdev) {
if (!pdev) {
pr_err("flxnet_pcie: pci_dev ptr is NULL\n");
goto err_exit;
}
if (fdev->bar) {
pci_iounmap(pdev, fdev->bar);
} else {
pr_err("flxnet_pcie: BAR memory is not mapped\n");
pr_warn("flxnet_pcie: BAR memory is not mapped\n");
}
pci_dev_put(pdev);
pci_disable_device(pdev);
pci_release_region(pdev, bar_idx);
err_exit:
list_del(&fdev->list_head);
kfree(fdev);
}
......