FILE
rnpgbe_main.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 2020 - 2025 Mucse Corporation. */ 3 4#include <linux/pci.h> 5#include <net/rtnetlink.h> 6#include <linux/etherdevice.h> 7 8#include "rnpgbe.h" 9#include "rnpgbe_hw.h" 10#include "rnpgbe_mbx_fw.h" 11 12static const char rnpgbe_driver_name[] = "rnpgbe"; 13 14/* rnpgbe_pci_tbl - PCI Device ID Table 15 * 16 * { PCI_VDEVICE(Vendor ID, Device ID), 17 * private_data (used for different hw chip) } 18 */ 19static struct pci_device_id rnpgbe_pci_tbl[] = { 20 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N210), board_n210 }, 21 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N210L), board_n210 }, 22 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N500_DUAL_PORT), board_n500 }, 23 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N500_QUAD_PORT), board_n500 }, 24 /* required last entry */ 25 {0, }, 26}; 27 28/** 29 * rnpgbe_open - Called when a network interface is made active 30 * @netdev: network interface device structure 31 * 32 * The open entry point is called when a network interface is made 33 * active by the system (IFF_UP). 34 * 35 * Return: 0 36 **/ 37static int rnpgbe_open(struct net_device *netdev) 38{ 39 return 0; 40} 41 42/** 43 * rnpgbe_close - Disables a network interface 44 * @netdev: network interface device structure 45 * 46 * The close entry point is called when an interface is de-activated 47 * by the OS. 48 * 49 * Return: 0, this is not allowed to fail 50 **/ 51static int rnpgbe_close(struct net_device *netdev) 52{ 53 return 0; 54} 55 56/** 57 * rnpgbe_xmit_frame - Send a skb to driver 58 * @skb: skb structure to be sent 59 * @netdev: network interface device structure 60 * 61 * Return: NETDEV_TX_OK 62 **/ 63static netdev_tx_t rnpgbe_xmit_frame(struct sk_buff *skb, 64 struct net_device *netdev) 65{ 66 struct mucse *mucse = netdev_priv(netdev); 67 68 dev_kfree_skb_any(skb); 69 mucse->stats.tx_dropped++; 70 71 return NETDEV_TX_OK; 72} 73 74static const struct net_device_ops rnpgbe_netdev_ops = { 75 .ndo_open = rnpgbe_open, 76 .ndo_stop = rnpgbe_close, 77 .ndo_start_xmit = rnpgbe_xmit_frame, 78}; 79 80/** 81 * rnpgbe_add_adapter - Add netdev for this pci_dev 82 * @pdev: PCI device information structure 83 * @board_type: board type 84 * 85 * rnpgbe_add_adapter initializes a netdev for this pci_dev 86 * structure. Initializes Bar map, private structure, and a 87 * hardware reset occur. 88 * 89 * Return: 0 on success, negative errno on failure 90 **/ 91static int rnpgbe_add_adapter(struct pci_dev *pdev, 92 int board_type) 93{ 94 struct net_device *netdev; 95 u8 perm_addr[ETH_ALEN]; 96 void __iomem *hw_addr; 97 struct mucse *mucse; 98 struct mucse_hw *hw; 99 int err, err_notify; 100 101 netdev = alloc_etherdev_mq(sizeof(struct mucse), RNPGBE_MAX_QUEUES); 102 if (!netdev) 103 return -ENOMEM; 104 105 SET_NETDEV_DEV(netdev, &pdev->dev); 106 mucse = netdev_priv(netdev); 107 mucse->netdev = netdev; 108 mucse->pdev = pdev; 109 pci_set_drvdata(pdev, mucse); 110 111 hw = &mucse->hw; 112 hw_addr = devm_ioremap(&pdev->dev, 113 pci_resource_start(pdev, 2), 114 pci_resource_len(pdev, 2)); 115 if (!hw_addr) { 116 err = -EIO; 117 goto err_free_net; 118 } 119 120 hw->hw_addr = hw_addr; 121 hw->pdev = pdev; 122 123 err = rnpgbe_init_hw(hw, board_type); 124 if (err) { 125 dev_err(&pdev->dev, "Init hw err %d\n", err); 126 goto err_free_net; 127 } 128 /* Step 1: Send power-up notification to firmware (no response expected) 129 * This informs firmware to initialize hardware power state, but 130 * firmware only acknowledges receipt without returning data. Must be 131 * done before synchronization as firmware may be in low-power idle 132 * state initially. 133 */ 134 err_notify = rnpgbe_send_notify(hw, true, mucse_fw_powerup); 135 if (err_notify) { 136 dev_warn(&pdev->dev, "Send powerup to hw failed %d\n", 137 err_notify); 138 dev_warn(&pdev->dev, "Maybe low performance\n"); 139 } 140 /* Step 2: Synchronize mailbox communication with firmware (requires 141 * response) After power-up, confirm firmware is ready to process 142 * requests with responses. This ensures subsequent request/response 143 * interactions work reliably. 144 */ 145 err = mucse_mbx_sync_fw(hw); 146 if (err) { 147 dev_err(&pdev->dev, "Sync fw failed! %d\n", err); 148 goto err_powerdown; 149 } 150 151 netdev->netdev_ops = &rnpgbe_netdev_ops; 152 err = rnpgbe_reset_hw(hw); 153 if (err) { 154 dev_err(&pdev->dev, "Hw reset failed %d\n", err); 155 goto err_powerdown; 156 } 157 158 err = rnpgbe_get_permanent_mac(hw, perm_addr); 159 if (!err) { 160 eth_hw_addr_set(netdev, perm_addr); 161 } else if (err == -EINVAL) { 162 dev_warn(&pdev->dev, "Using random MAC\n"); 163 eth_hw_addr_random(netdev); 164 } else if (err) { 165 dev_err(&pdev->dev, "get perm_addr failed %d\n", err); 166 goto err_powerdown; 167 } 168 169 err = register_netdev(netdev); 170 if (err) 171 goto err_powerdown; 172 173 return 0; 174err_powerdown: 175 /* notify powerdown only powerup ok */ 176 if (!err_notify) { 177 err_notify = rnpgbe_send_notify(hw, false, mucse_fw_powerup); 178 if (err_notify) 179 dev_warn(&pdev->dev, "Send powerdown to hw failed %d\n", 180 err_notify); 181 } 182err_free_net: 183 free_netdev(netdev); 184 return err; 185} 186 187/** 188 * rnpgbe_probe - Device initialization routine 189 * @pdev: PCI device information struct 190 * @id: entry in rnpgbe_pci_tbl 191 * 192 * rnpgbe_probe initializes a PF adapter identified by a pci_dev 193 * structure. 194 * 195 * Return: 0 on success, negative errno on failure 196 **/ 197static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id) 198{ 199 int board_type = id->driver_data; 200 int err; 201 202 err = pci_enable_device_mem(pdev); 203 if (err) 204 return err; 205 206 err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(56)); 207 if (err) { 208 dev_err(&pdev->dev, 209 "No usable DMA configuration, aborting %d\n", err); 210 goto err_disable_dev; 211 } 212 213 err = pci_request_mem_regions(pdev, rnpgbe_driver_name); 214 if (err) { 215 dev_err(&pdev->dev, 216 "pci_request_selected_regions failed %d\n", err); 217 goto err_disable_dev; 218 } 219 220 pci_set_master(pdev); 221 err = pci_save_state(pdev); 222 if (err) { 223 dev_err(&pdev->dev, "pci_save_state failed %d\n", err); 224 goto err_free_regions; 225 } 226 227 err = rnpgbe_add_adapter(pdev, board_type); 228 if (err) 229 goto err_free_regions; 230 231 return 0; 232err_free_regions: 233 pci_release_mem_regions(pdev); 234err_disable_dev: 235 pci_disable_device(pdev); 236 return err; 237} 238 239/** 240 * rnpgbe_rm_adapter - Remove netdev for this mucse structure 241 * @pdev: PCI device information struct 242 * 243 * rnpgbe_rm_adapter remove a netdev for this mucse structure 244 **/ 245static void rnpgbe_rm_adapter(struct pci_dev *pdev) 246{ 247 struct mucse *mucse = pci_get_drvdata(pdev); 248 struct mucse_hw *hw = &mucse->hw; 249 struct net_device *netdev; 250 int err; 251 252 if (!mucse) 253 return; 254 netdev = mucse->netdev; 255 unregister_netdev(netdev); 256 err = rnpgbe_send_notify(hw, false, mucse_fw_powerup); 257 if (err) 258 dev_warn(&pdev->dev, "Send powerdown to hw failed %d\n", err); 259 free_netdev(netdev); 260} 261 262/** 263 * rnpgbe_remove - Device removal routine 264 * @pdev: PCI device information struct 265 * 266 * rnpgbe_remove is called by the PCI subsystem to alert the driver 267 * that it should release a PCI device. This could be caused by a 268 * Hot-Plug event, or because the driver is going to be removed from 269 * memory. 270 **/ 271static void rnpgbe_remove(struct pci_dev *pdev) 272{ 273 rnpgbe_rm_adapter(pdev); 274 pci_release_mem_regions(pdev); 275 pci_disable_device(pdev); 276} 277 278/** 279 * rnpgbe_dev_shutdown - Device shutdown routine 280 * @pdev: PCI device information struct 281 **/ 282static void rnpgbe_dev_shutdown(struct pci_dev *pdev) 283{ 284 struct mucse *mucse = pci_get_drvdata(pdev); 285 struct net_device *netdev = mucse->netdev; 286 287 rtnl_lock(); 288 netif_device_detach(netdev); 289 if (netif_running(netdev)) 290 rnpgbe_close(netdev); 291 rtnl_unlock(); 292 pci_disable_device(pdev); 293} 294 295/** 296 * rnpgbe_shutdown - Device shutdown routine 297 * @pdev: PCI device information struct 298 * 299 * rnpgbe_shutdown is called by the PCI subsystem to alert the driver 300 * that os shutdown. Device should setup wakeup state here. 301 **/ 302static void rnpgbe_shutdown(struct pci_dev *pdev) 303{ 304 rnpgbe_dev_shutdown(pdev); 305} 306 307static struct pci_driver rnpgbe_driver = { 308 .name = rnpgbe_driver_name, 309 .id_table = rnpgbe_pci_tbl, 310 .probe = rnpgbe_probe, 311 .remove = rnpgbe_remove, 312 .shutdown = rnpgbe_shutdown, 313}; 314 315module_pci_driver(rnpgbe_driver); 316 317MODULE_DEVICE_TABLE(pci, rnpgbe_pci_tbl); 318MODULE_AUTHOR("Yibo Dong, <dong100@mucse.com>"); 319MODULE_DESCRIPTION("Mucse(R) 1 Gigabit PCI Express Network Driver"); 320MODULE_LICENSE("GPL");
~/
Read-only file preview.