#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <gpxe/pci.h>
#include <gpxe/io.h>
#include <gpxe/malloc.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
#include <gpxe/if_ether.h>
#include <gpxe/ethernet.h>
#include <gpxe/spi.h>
#include <gpxe/settings.h>
#include "phantom.h"
Go to the source code of this file.
Data Structures | |
| struct | phantom_descriptor_rings |
| A Phantom descriptor ring set. More... | |
| struct | phantom_create_rx_ctx_rqrsp |
| RX context creation request and response buffers. More... | |
| struct | phantom_create_tx_ctx_rqrsp |
| TX context creation request and response buffers. More... | |
| struct | phantom_nic |
| A Phantom NIC. More... | |
| union | phantom_clp_data |
| Phantom CLP data. More... | |
| struct | phantom_clp_setting |
| A Phantom CLP setting. More... | |
Defines | |
| #define | PHN_MAX_NUM_PORTS 8 |
| Maximum number of ports. | |
| #define | PHN_CMDPEG_INIT_TIMEOUT_SEC 50 |
| Maximum time to wait for command PEG to initialise. | |
| #define | PHN_RCVPEG_INIT_TIMEOUT_SEC 2 |
| Maximum time to wait for receive PEG to initialise. | |
| #define | PHN_ISSUE_CMD_TIMEOUT_MS 2000 |
| Maximum time to wait for firmware to accept a command. | |
| #define | PHN_TEST_MEM_TIMEOUT_MS 100 |
| Maximum time to wait for test memory. | |
| #define | PHN_CLP_CMD_TIMEOUT_MS 500 |
| Maximum time to wait for CLP command to be issued. | |
| #define | PHN_LINK_POLL_FREQUENCY 4096 |
| Link state poll frequency. | |
| #define | PHN_NUM_RDS 32 |
| Number of RX descriptors. | |
| #define | PHN_RDS_MAX_FILL 16 |
| RX maximum fill level. | |
| #define | PHN_RX_BUFSIZE |
| RX buffer size. | |
| #define | PHN_NUM_SDS 32 |
| Number of RX status descriptors. | |
| #define | PHN_NUM_CDS 8 |
| Number of TX descriptors. | |
| #define | PHN_CLP_TAG_MAGIC 0xc19c1900UL |
| Phantom CLP settings tag magic. | |
| #define | PHN_CLP_TAG_MAGIC_MASK 0xffffff00UL |
| Phantom CLP settings tag magic mask. | |
| #define | PHN_CLP_BLKSIZE ( sizeof ( union phantom_clp_data ) ) |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static unsigned long | phantom_crb_access_128m (struct phantom_nic *phantom, unsigned long reg) |
| Prepare for access to CRB register via 128MB BAR. | |
| static unsigned long | phantom_crb_access_32m (struct phantom_nic *phantom, unsigned long reg) |
| Prepare for access to CRB register via 32MB BAR. | |
| static unsigned long | phantom_crb_access_2m (struct phantom_nic *phantom, unsigned long reg) |
| Prepare for access to CRB register via 2MB BAR. | |
| static uint32_t | phantom_readl (struct phantom_nic *phantom, unsigned long reg) |
| Read from Phantom CRB register. | |
| static void | phantom_writel (struct phantom_nic *phantom, uint32_t value, unsigned long reg) |
| Write to Phantom CRB register. | |
| static void | phantom_write_hilo (struct phantom_nic *phantom, uint64_t value, unsigned long lo_offset, unsigned long hi_offset) |
| Write to Phantom CRB HI/LO register pair. | |
| static int | phantom_read_test_mem_block (struct phantom_nic *phantom, unsigned long offset, uint32_t buf[2]) |
| Read from Phantom test memory. | |
| static int | phantom_read_test_mem (struct phantom_nic *phantom, unsigned long offset) |
| Read single byte from Phantom test memory. | |
| static int | phantom_dmesg (struct phantom_nic *phantom, unsigned int log, unsigned int max_lines) |
| Dump Phantom firmware dmesg log. | |
| static void | phantom_dmesg_all (struct phantom_nic *phantom, unsigned int max_lines) |
| Dump Phantom firmware dmesg logs. | |
| static int | phantom_wait_for_cmd (struct phantom_nic *phantom) |
| Wait for firmware to accept command. | |
| static int | phantom_issue_cmd (struct phantom_nic *phantom, uint32_t command, uint32_t arg1, uint32_t arg2, uint32_t arg3) |
| Issue command to firmware. | |
| static int | phantom_issue_buf_cmd (struct phantom_nic *phantom, uint32_t command, void *buffer, size_t len) |
| Issue buffer-format command to firmware. | |
| static int | phantom_create_rx_ctx (struct phantom_nic *phantom) |
| Create Phantom RX context. | |
| static void | phantom_destroy_rx_ctx (struct phantom_nic *phantom) |
| Destroy Phantom RX context. | |
| static int | phantom_create_tx_ctx (struct phantom_nic *phantom) |
| Create Phantom TX context. | |
| static void | phantom_destroy_tx_ctx (struct phantom_nic *phantom) |
| Destroy Phantom TX context. | |
| static int | phantom_alloc_rds (struct phantom_nic *phantom) |
| Allocate Phantom RX descriptor. | |
| static void | phantom_post_rds (struct phantom_nic *phantom, struct phantom_rds *rds) |
| Post Phantom RX descriptor. | |
| static int | phantom_alloc_cds (struct phantom_nic *phantom) |
| Allocate Phantom TX descriptor. | |
| static void | phantom_post_cds (struct phantom_nic *phantom, union phantom_cds *cds) |
| Post Phantom TX descriptor. | |
| static int | phantom_update_macaddr (struct phantom_nic *phantom, const uint8_t *ll_addr, unsigned int opcode) |
| Add/remove MAC address. | |
| static int | phantom_add_macaddr (struct phantom_nic *phantom, const uint8_t *ll_addr) |
| Add MAC address. | |
| static int | phantom_del_macaddr (struct phantom_nic *phantom, const uint8_t *ll_addr) |
| Remove MAC address. | |
| static void | phantom_poll_link_state (struct net_device *netdev) |
| Poll link state. | |
| static void | phantom_refill_rx_ring (struct net_device *netdev) |
| Refill descriptor ring. | |
| static int | phantom_open (struct net_device *netdev) |
| Open NIC. | |
| static void | phantom_close (struct net_device *netdev) |
| Close NIC. | |
| static int | phantom_transmit (struct net_device *netdev, struct io_buffer *iobuf) |
| Transmit packet. | |
| static void | phantom_poll (struct net_device *netdev) |
| Poll for received packets. | |
| static void | phantom_irq (struct net_device *netdev, int enable) |
| Enable/disable interrupts. | |
| static int | phantom_clp_wait (struct phantom_nic *phantom) |
| Wait for Phantom CLP command to complete. | |
| static int | phantom_clp_cmd (struct phantom_nic *phantom, unsigned int port, unsigned int opcode, const void *data_in, void *data_out, size_t offset, size_t len) |
| Issue Phantom CLP command. | |
| static int | phantom_clp_store (struct phantom_nic *phantom, unsigned int port, unsigned int setting, const void *data, size_t len) |
| Store Phantom CLP setting. | |
| static int | phantom_clp_fetch (struct phantom_nic *phantom, unsigned int port, unsigned int setting, void *data, size_t len) |
| Fetch Phantom CLP setting. | |
| static unsigned int | phantom_clp_setting (struct phantom_nic *phantom, struct setting *setting) |
| Find Phantom CLP setting. | |
| static int | phantom_store_setting (struct settings *settings, struct setting *setting, const void *data, size_t len) |
| Store Phantom CLP setting. | |
| static int | phantom_fetch_setting (struct settings *settings, struct setting *setting, void *data, size_t len) |
| Fetch Phantom CLP setting. | |
| static int | phantom_map_crb (struct phantom_nic *phantom, struct pci_device *pci) |
| Map Phantom CRB window. | |
| static void | phantom_unhalt_pegs (struct phantom_nic *phantom) |
| Unhalt all PEGs. | |
| static int | phantom_init_cmdpeg (struct phantom_nic *phantom) |
| Initialise the Phantom command PEG. | |
| static void | phantom_get_macaddr (struct phantom_nic *phantom, uint8_t *hw_addr) |
| Read Phantom MAC address. | |
| static int | phantom_check_boot_enable (struct phantom_nic *phantom) |
| Check Phantom is enabled for boot. | |
| static int | phantom_init_rcvpeg (struct phantom_nic *phantom) |
| Initialise Phantom receive PEG. | |
| static int | phantom_probe (struct pci_device *pci, const struct pci_device_id *id __unused) |
| Probe PCI device. | |
| static void | phantom_remove (struct pci_device *pci) |
| Remove PCI device. | |
Variables | |
| static const unsigned long | phantom_irq_mask_reg [PHN_MAX_NUM_PORTS] |
| Interrupt mask registers. | |
| static const unsigned long | phantom_irq_status_reg [PHN_MAX_NUM_PORTS] |
| Interrupt status registers. | |
| static struct net_device_operations | phantom_operations |
| Phantom net device operations. | |
| static struct phantom_clp_setting | clp_settings [] |
| Phantom CLP settings. | |
| static struct settings_operations | phantom_settings_operations |
| Phantom CLP settings operations. | |
| static struct pci_device_id | phantom_nics [] |
| Phantom PCI IDs. | |
| struct pci_driver phantom_driver | __pci_driver |
| Phantom PCI driver. | |
Definition in file phantom.c.
| #define PHN_MAX_NUM_PORTS 8 |
| #define PHN_CMDPEG_INIT_TIMEOUT_SEC 50 |
Maximum time to wait for command PEG to initialise.
BUGxxxx
The command PEG will currently report initialisation complete only when at least one PHY has detected a link (so that the global PHY clock can be set to 10G/1G as appropriate). This can take a very, very long time.
A future firmware revision should decouple PHY initialisation from firmware initialisation, at which point the command PEG will report initialisation complete much earlier, and this timeout can be reduced.
Definition at line 64 of file phantom.c.
Referenced by phantom_init_cmdpeg().
| #define PHN_RCVPEG_INIT_TIMEOUT_SEC 2 |
Maximum time to wait for receive PEG to initialise.
Definition at line 67 of file phantom.c.
Referenced by phantom_init_rcvpeg().
| #define PHN_ISSUE_CMD_TIMEOUT_MS 2000 |
Maximum time to wait for firmware to accept a command.
Definition at line 70 of file phantom.c.
Referenced by phantom_wait_for_cmd().
| #define PHN_TEST_MEM_TIMEOUT_MS 100 |
Maximum time to wait for test memory.
Definition at line 73 of file phantom.c.
Referenced by phantom_read_test_mem_block().
| #define PHN_CLP_CMD_TIMEOUT_MS 500 |
Maximum time to wait for CLP command to be issued.
Definition at line 76 of file phantom.c.
Referenced by phantom_clp_wait().
| #define PHN_LINK_POLL_FREQUENCY 4096 |
Link state poll frequency.
The link state will be checked once in every N calls to poll().
Definition at line 82 of file phantom.c.
Referenced by phantom_poll().
| #define PHN_NUM_RDS 32 |
Number of RX descriptors.
Definition at line 85 of file phantom.c.
Referenced by phantom_alloc_rds(), phantom_create_rx_ctx(), phantom_poll(), phantom_post_rds(), and phantom_refill_rx_ring().
| #define PHN_RDS_MAX_FILL 16 |
RX maximum fill level.
Must be strictly less than PHN_NUM_RDS.
Definition at line 88 of file phantom.c.
Referenced by phantom_close(), and phantom_refill_rx_ring().
| #define PHN_RX_BUFSIZE |
Value:
( 32 /* max LL padding added by card */ + \ ETH_FRAME_LEN )
Definition at line 91 of file phantom.c.
Referenced by phantom_create_rx_ctx(), and phantom_refill_rx_ring().
| #define PHN_NUM_SDS 32 |
Number of RX status descriptors.
Definition at line 95 of file phantom.c.
Referenced by phantom_create_rx_ctx(), and phantom_poll().
| #define PHN_NUM_CDS 8 |
Number of TX descriptors.
Definition at line 98 of file phantom.c.
Referenced by phantom_alloc_cds(), phantom_close(), phantom_create_tx_ctx(), phantom_poll(), and phantom_post_cds().
| #define PHN_CLP_TAG_MAGIC 0xc19c1900UL |
Phantom CLP settings tag magic.
Definition at line 1459 of file phantom.c.
Referenced by phantom_clp_setting(), and phantom_probe().
| #define PHN_CLP_TAG_MAGIC_MASK 0xffffff00UL |
Phantom CLP settings tag magic mask.
Definition at line 1462 of file phantom.c.
Referenced by phantom_clp_setting().
| #define PHN_CLP_BLKSIZE ( sizeof ( union phantom_clp_data ) ) |
Definition at line 1483 of file phantom.c.
Referenced by phantom_clp_fetch(), and phantom_clp_store().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static unsigned long phantom_crb_access_128m | ( | struct phantom_nic * | phantom, | |
| unsigned long | reg | |||
| ) | [static] |
Prepare for access to CRB register via 128MB BAR.
| phantom | Phantom NIC | |
| reg | Register offset within abstract address space |
| offset | Register offset within PCI BAR0 |
Definition at line 236 of file phantom.c.
References assert, phantom_nic::bar0, phantom_nic::crb_window, offset, readl, UNM_128M_CRB_WINDOW, and writel.
Referenced by phantom_map_crb().
00237 { 00238 unsigned long offset = ( 0x6000000 + ( reg & 0x1ffffff ) ); 00239 uint32_t window = ( reg & 0x2000000 ); 00240 uint32_t verify_window; 00241 00242 if ( phantom->crb_window != window ) { 00243 00244 /* Write to the CRB window register */ 00245 writel ( window, phantom->bar0 + UNM_128M_CRB_WINDOW ); 00246 00247 /* Ensure that the write has reached the card */ 00248 verify_window = readl ( phantom->bar0 + UNM_128M_CRB_WINDOW ); 00249 assert ( verify_window == window ); 00250 00251 /* Record new window */ 00252 phantom->crb_window = window; 00253 } 00254 00255 return offset; 00256 }
| static unsigned long phantom_crb_access_32m | ( | struct phantom_nic * | phantom, | |
| unsigned long | reg | |||
| ) | [static] |
Prepare for access to CRB register via 32MB BAR.
| phantom | Phantom NIC | |
| reg | Register offset within abstract address space |
| offset | Register offset within PCI BAR0 |
Definition at line 265 of file phantom.c.
References assert, phantom_nic::bar0, phantom_nic::crb_window, offset, readl, UNM_32M_CRB_WINDOW, and writel.
Referenced by phantom_map_crb().
00266 { 00267 unsigned long offset = ( reg & 0x1ffffff ); 00268 uint32_t window = ( reg & 0x2000000 ); 00269 uint32_t verify_window; 00270 00271 if ( phantom->crb_window != window ) { 00272 00273 /* Write to the CRB window register */ 00274 writel ( window, phantom->bar0 + UNM_32M_CRB_WINDOW ); 00275 00276 /* Ensure that the write has reached the card */ 00277 verify_window = readl ( phantom->bar0 + UNM_32M_CRB_WINDOW ); 00278 assert ( verify_window == window ); 00279 00280 /* Record new window */ 00281 phantom->crb_window = window; 00282 } 00283 00284 return offset; 00285 }
| static unsigned long phantom_crb_access_2m | ( | struct phantom_nic * | phantom, | |
| unsigned long | reg | |||
| ) | [static] |
Prepare for access to CRB register via 2MB BAR.
| phantom | Phantom NIC | |
| reg | Register offset within abstract address space |
| offset | Register offset within PCI BAR0 |
Definition at line 294 of file phantom.c.
References assert, phantom_nic::bar0, phantom_nic::crb_window, offset, readl, UNM_2M_CRB_WINDOW, UNM_CRB_BLK, UNM_CRB_BLK_CAM, UNM_CRB_BLK_PCIE, UNM_CRB_BLK_PEG_0, UNM_CRB_BLK_PEG_1, UNM_CRB_BLK_PEG_2, UNM_CRB_BLK_PEG_3, UNM_CRB_BLK_PEG_4, UNM_CRB_BLK_ROMUSB, UNM_CRB_BLK_TEST, UNM_CRB_OFFSET, and writel.
Referenced by phantom_map_crb().
00295 { 00296 static const struct { 00297 uint8_t block; 00298 uint16_t window_hi; 00299 } reg_window_hi[] = { 00300 { UNM_CRB_BLK_PCIE, 0x773 }, 00301 { UNM_CRB_BLK_CAM, 0x416 }, 00302 { UNM_CRB_BLK_ROMUSB, 0x421 }, 00303 { UNM_CRB_BLK_TEST, 0x295 }, 00304 { UNM_CRB_BLK_PEG_0, 0x340 }, 00305 { UNM_CRB_BLK_PEG_1, 0x341 }, 00306 { UNM_CRB_BLK_PEG_2, 0x342 }, 00307 { UNM_CRB_BLK_PEG_3, 0x343 }, 00308 { UNM_CRB_BLK_PEG_4, 0x34b }, 00309 }; 00310 unsigned int block = UNM_CRB_BLK ( reg ); 00311 unsigned long offset = UNM_CRB_OFFSET ( reg ); 00312 uint32_t window; 00313 uint32_t verify_window; 00314 unsigned int i; 00315 00316 for ( i = 0 ; i < ( sizeof ( reg_window_hi ) / 00317 sizeof ( reg_window_hi[0] ) ) ; i++ ) { 00318 00319 if ( reg_window_hi[i].block != block ) 00320 continue; 00321 00322 window = ( ( reg_window_hi[i].window_hi << 20 ) | 00323 ( offset & 0x000f0000 ) ); 00324 00325 if ( phantom->crb_window != window ) { 00326 00327 /* Write to the CRB window register */ 00328 writel ( window, phantom->bar0 + UNM_2M_CRB_WINDOW ); 00329 00330 /* Ensure that the write has reached the card */ 00331 verify_window = readl ( phantom->bar0 + 00332 UNM_2M_CRB_WINDOW ); 00333 assert ( verify_window == window ); 00334 00335 /* Record new window */ 00336 phantom->crb_window = window; 00337 } 00338 00339 return ( 0x1e0000 + ( offset & 0xffff ) ); 00340 } 00341 00342 assert ( 0 ); 00343 return 0; 00344 }
| static uint32_t phantom_readl | ( | struct phantom_nic * | phantom, | |
| unsigned long | reg | |||
| ) | [static] |
Read from Phantom CRB register.
| phantom | Phantom NIC | |
| reg | Register offset within abstract address space |
| value | Register value |
Definition at line 353 of file phantom.c.
References phantom_nic::bar0, phantom_nic::crb_access, offset, and readl.
Referenced by phantom_check_boot_enable(), phantom_clp_cmd(), phantom_clp_wait(), phantom_dmesg(), phantom_get_macaddr(), phantom_init_cmdpeg(), phantom_init_rcvpeg(), phantom_poll(), phantom_poll_link_state(), phantom_read_test_mem_block(), phantom_unhalt_pegs(), and phantom_wait_for_cmd().
00354 { 00355 unsigned long offset; 00356 00357 offset = phantom->crb_access ( phantom, reg ); 00358 return readl ( phantom->bar0 + offset ); 00359 }
| static void phantom_writel | ( | struct phantom_nic * | phantom, | |
| uint32_t | value, | |||
| unsigned long | reg | |||
| ) | [static] |
Write to Phantom CRB register.
| phantom | Phantom NIC | |
| value | Register value | |
| reg | Register offset within abstract address space |
Definition at line 368 of file phantom.c.
References phantom_nic::bar0, phantom_nic::crb_access, offset, and writel.
Referenced by phantom_clp_cmd(), phantom_init_cmdpeg(), phantom_irq(), phantom_issue_cmd(), phantom_poll(), phantom_post_cds(), phantom_post_rds(), phantom_read_test_mem_block(), phantom_unhalt_pegs(), and phantom_write_hilo().
00369 { 00370 unsigned long offset; 00371 00372 offset = phantom->crb_access ( phantom, reg ); 00373 writel ( value, phantom->bar0 + offset ); 00374 }
| static void phantom_write_hilo | ( | struct phantom_nic * | phantom, | |
| uint64_t | value, | |||
| unsigned long | lo_offset, | |||
| unsigned long | hi_offset | |||
| ) | [inline, static] |
Write to Phantom CRB HI/LO register pair.
| phantom | Phantom NIC | |
| value | Register value | |
| lo_offset | LO register offset within CRB | |
| hi_offset | HI register offset within CRB |
Definition at line 384 of file phantom.c.
References phantom_writel().
Referenced by phantom_init_cmdpeg(), and phantom_read_test_mem_block().
00387 { 00388 uint32_t lo = ( value & 0xffffffffUL ); 00389 uint32_t hi = ( value >> 32 ); 00390 00391 phantom_writel ( phantom, lo, lo_offset ); 00392 phantom_writel ( phantom, hi, hi_offset ); 00393 }
| static int phantom_read_test_mem_block | ( | struct phantom_nic * | phantom, | |
| unsigned long | offset, | |||
| uint32_t | buf[2] | |||
| ) | [static] |
Read from Phantom test memory.
| phantom | Phantom NIC | |
| offset | Offset within test memory | |
| buf | 8-byte buffer to fill |
| rc | Return status code |
Definition at line 409 of file phantom.c.
References DBGC, ETIMEDOUT, mdelay(), phantom_readl(), phantom_write_hilo(), phantom_writel(), PHN_TEST_MEM_TIMEOUT_MS, UNM_TEST_ADDR_HI, UNM_TEST_ADDR_LO, UNM_TEST_CONTROL, UNM_TEST_CONTROL_BUSY, UNM_TEST_CONTROL_ENABLE, UNM_TEST_CONTROL_START, UNM_TEST_RDDATA_HI, and UNM_TEST_RDDATA_LO.
Referenced by phantom_read_test_mem().
00411 { 00412 unsigned int retries; 00413 uint32_t test_control; 00414 00415 phantom_write_hilo ( phantom, offset, UNM_TEST_ADDR_LO, 00416 UNM_TEST_ADDR_HI ); 00417 phantom_writel ( phantom, UNM_TEST_CONTROL_ENABLE, UNM_TEST_CONTROL ); 00418 phantom_writel ( phantom, 00419 ( UNM_TEST_CONTROL_ENABLE | UNM_TEST_CONTROL_START ), 00420 UNM_TEST_CONTROL ); 00421 00422 for ( retries = 0 ; retries < PHN_TEST_MEM_TIMEOUT_MS ; retries++ ) { 00423 test_control = phantom_readl ( phantom, UNM_TEST_CONTROL ); 00424 if ( ( test_control & UNM_TEST_CONTROL_BUSY ) == 0 ) { 00425 buf[0] = phantom_readl ( phantom, UNM_TEST_RDDATA_LO ); 00426 buf[1] = phantom_readl ( phantom, UNM_TEST_RDDATA_HI ); 00427 return 0; 00428 } 00429 mdelay ( 1 ); 00430 } 00431 00432 DBGC ( phantom, "Phantom %p timed out waiting for test memory\n", 00433 phantom ); 00434 return -ETIMEDOUT; 00435 }
| static int phantom_read_test_mem | ( | struct phantom_nic * | phantom, | |
| unsigned long | offset | |||
| ) | [static] |
Read single byte from Phantom test memory.
| phantom | Phantom NIC | |
| offset | Offset within test memory |
| byte | Byte read, or negative error |
Definition at line 444 of file phantom.c.
References phantom_read_test_mem_block().
Referenced by phantom_dmesg().
00445 { 00446 static union { 00447 uint8_t bytes[8]; 00448 uint32_t dwords[2]; 00449 } cache; 00450 static unsigned long cache_offset = -1UL; 00451 unsigned long sub_offset; 00452 int rc; 00453 00454 sub_offset = ( offset & ( sizeof ( cache ) - 1 ) ); 00455 offset = ( offset & ~( sizeof ( cache ) - 1 ) ); 00456 00457 if ( cache_offset != offset ) { 00458 if ( ( rc = phantom_read_test_mem_block ( phantom, offset, 00459 cache.dwords )) !=0 ) 00460 return rc; 00461 cache_offset = offset; 00462 } 00463 00464 return cache.bytes[sub_offset]; 00465 }
| static int phantom_dmesg | ( | struct phantom_nic * | phantom, | |
| unsigned int | log, | |||
| unsigned int | max_lines | |||
| ) | [static] |
Dump Phantom firmware dmesg log.
| phantom | Phantom NIC | |
| log | Log number | |
| max_lines | Maximum number of lines to show, or -1 to show all |
| rc | Return status code |
Definition at line 475 of file phantom.c.
References assert, DBG, DBG_LOG, DBGC, offset, phantom_read_test_mem(), phantom_readl(), UNM_CAM_RAM_DMESG_HEAD, UNM_CAM_RAM_DMESG_LEN, UNM_CAM_RAM_DMESG_SIG, UNM_CAM_RAM_DMESG_SIG_MAGIC, and UNM_CAM_RAM_DMESG_TAIL.
Referenced by phantom_dmesg_all().
00476 { 00477 uint32_t head; 00478 uint32_t tail; 00479 uint32_t len; 00480 uint32_t sig; 00481 uint32_t offset; 00482 int byte; 00483 00484 /* Optimise out for non-debug builds */ 00485 if ( ! DBG_LOG ) 00486 return 0; 00487 00488 /* Locate log */ 00489 head = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_HEAD ( log ) ); 00490 len = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_LEN ( log ) ); 00491 tail = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_TAIL ( log ) ); 00492 sig = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_SIG ( log ) ); 00493 DBGC ( phantom, "Phantom %p firmware dmesg buffer %d (%08x-%08x)\n", 00494 phantom, log, head, tail ); 00495 assert ( ( head & 0x07 ) == 0 ); 00496 if ( sig != UNM_CAM_RAM_DMESG_SIG_MAGIC ) { 00497 DBGC ( phantom, "Warning: bad signature %08x (want %08lx)\n", 00498 sig, UNM_CAM_RAM_DMESG_SIG_MAGIC ); 00499 } 00500 00501 /* Locate start of last (max_lines) lines */ 00502 for ( offset = tail ; offset > head ; offset-- ) { 00503 if ( ( byte = phantom_read_test_mem ( phantom, 00504 ( offset - 1 ) ) ) < 0 ) 00505 return byte; 00506 if ( ( byte == '\n' ) && ( max_lines-- == 0 ) ) 00507 break; 00508 } 00509 00510 /* Print lines */ 00511 for ( ; offset < tail ; offset++ ) { 00512 if ( ( byte = phantom_read_test_mem ( phantom, offset ) ) < 0 ) 00513 return byte; 00514 DBG ( "%c", byte ); 00515 } 00516 DBG ( "\n" ); 00517 return 0; 00518 }
| static void phantom_dmesg_all | ( | struct phantom_nic * | phantom, | |
| unsigned int | max_lines | |||
| ) | [static] |
Dump Phantom firmware dmesg logs.
| phantom | Phantom NIC | |
| max_lines | Maximum number of lines to show, or -1 to show all |
Definition at line 527 of file phantom.c.
References phantom_dmesg(), and UNM_CAM_RAM_NUM_DMESG_BUFFERS.
00527 { 00528 unsigned int i; 00529 00530 for ( i = 0 ; i < UNM_CAM_RAM_NUM_DMESG_BUFFERS ; i++ ) 00531 phantom_dmesg ( phantom, i, max_lines ); 00532 }
| static int phantom_wait_for_cmd | ( | struct phantom_nic * | phantom | ) | [static] |
Wait for firmware to accept command.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 546 of file phantom.c.
References DBGC, EIO, EPROTO, ETIMEDOUT, mdelay(), NX_CDRP_FORM_RSP, NX_CDRP_IS_RSP, NX_CDRP_RSP_FAIL, NX_CDRP_RSP_OK, NX_CDRP_RSP_TIMEOUT, phantom_readl(), PHN_ISSUE_CMD_TIMEOUT_MS, and UNM_NIC_REG_NX_CDRP.
Referenced by phantom_issue_cmd().
00546 { 00547 unsigned int retries; 00548 uint32_t cdrp; 00549 00550 for ( retries = 0 ; retries < PHN_ISSUE_CMD_TIMEOUT_MS ; retries++ ) { 00551 mdelay ( 1 ); 00552 cdrp = phantom_readl ( phantom, UNM_NIC_REG_NX_CDRP ); 00553 if ( NX_CDRP_IS_RSP ( cdrp ) ) { 00554 switch ( NX_CDRP_FORM_RSP ( cdrp ) ) { 00555 case NX_CDRP_RSP_OK: 00556 return 0; 00557 case NX_CDRP_RSP_FAIL: 00558 return -EIO; 00559 case NX_CDRP_RSP_TIMEOUT: 00560 return -ETIMEDOUT; 00561 default: 00562 return -EPROTO; 00563 } 00564 } 00565 } 00566 00567 DBGC ( phantom, "Phantom %p timed out waiting for firmware to accept " 00568 "command\n", phantom ); 00569 return -ETIMEDOUT; 00570 }
| static int phantom_issue_cmd | ( | struct phantom_nic * | phantom, | |
| uint32_t | command, | |||
| uint32_t | arg1, | |||
| uint32_t | arg2, | |||
| uint32_t | arg3 | |||
| ) | [static] |
Issue command to firmware.
| phantom | Phantom NIC | |
| command | Firmware command | |
| arg1 | Argument 1 | |
| arg2 | Argument 2 | |
| arg3 | Argument 3 |
| rc | Return status code |
Definition at line 582 of file phantom.c.
References DBGC, DBGC2, NX_CDRP_FORM_CMD, NX_CDRP_SIGNATURE_MAKE, NXHAL_VERSION, phantom_wait_for_cmd(), phantom_writel(), phantom_nic::port, strerror(), UNM_NIC_REG_NX_ARG1, UNM_NIC_REG_NX_ARG2, UNM_NIC_REG_NX_ARG3, UNM_NIC_REG_NX_CDRP, and UNM_NIC_REG_NX_SIGN.
Referenced by phantom_destroy_rx_ctx(), phantom_destroy_tx_ctx(), and phantom_issue_buf_cmd().
00584 { 00585 uint32_t signature; 00586 int rc; 00587 00588 /* Issue command */ 00589 signature = NX_CDRP_SIGNATURE_MAKE ( phantom->port, 00590 NXHAL_VERSION ); 00591 DBGC2 ( phantom, "Phantom %p issuing command %08x (%08x, %08x, " 00592 "%08x)\n", phantom, command, arg1, arg2, arg3 ); 00593 phantom_writel ( phantom, signature, UNM_NIC_REG_NX_SIGN ); 00594 phantom_writel ( phantom, arg1, UNM_NIC_REG_NX_ARG1 ); 00595 phantom_writel ( phantom, arg2, UNM_NIC_REG_NX_ARG2 ); 00596 phantom_writel ( phantom, arg3, UNM_NIC_REG_NX_ARG3 ); 00597 phantom_writel ( phantom, NX_CDRP_FORM_CMD ( command ), 00598 UNM_NIC_REG_NX_CDRP ); 00599 00600 /* Wait for command to be accepted */ 00601 if ( ( rc = phantom_wait_for_cmd ( phantom ) ) != 0 ) { 00602 DBGC ( phantom, "Phantom %p could not issue command: %s\n", 00603 phantom, strerror ( rc ) ); 00604 return rc; 00605 } 00606 00607 return 0; 00608 }
| static int phantom_issue_buf_cmd | ( | struct phantom_nic * | phantom, | |
| uint32_t | command, | |||
| void * | buffer, | |||
| size_t | len | |||
| ) | [static] |
Issue buffer-format command to firmware.
| phantom | Phantom NIC | |
| command | Firmware command | |
| buffer | Buffer to pass to firmware | |
| len | Length of buffer |
| rc | Return status code |
Definition at line 619 of file phantom.c.
References phantom_issue_cmd(), and virt_to_bus().
Referenced by phantom_create_rx_ctx(), and phantom_create_tx_ctx().
00621 { 00622 uint64_t physaddr; 00623 00624 physaddr = virt_to_bus ( buffer ); 00625 return phantom_issue_cmd ( phantom, command, ( physaddr >> 32 ), 00626 ( physaddr & 0xffffffffUL ), len ); 00627 }
| static int phantom_create_rx_ctx | ( | struct phantom_nic * | phantom | ) | [static] |
Create Phantom RX context.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 635 of file phantom.c.
References nx_hostrq_rds_ring_s::buff_size, nx_hostrq_rx_ctx_s::capabilities, phantom_create_rx_ctx_rqrsp::cardrsp, cpu_to_le16, cpu_to_le32, cpu_to_le64, DBGC, DBGC2_HDA, DBGC_HDA, phantom_nic::desc, ENOMEM, free_dma(), nx_hostrq_rx_ctx_s::host_int_crb_mode, nx_hostrq_sds_ring_s::host_phys_addr, nx_hostrq_rds_ring_s::host_phys_addr, nx_hostrq_rx_ctx_s::host_rds_crb_mode, nx_hostrq_rx_ctx_s::host_rsp_dma_addr, phantom_create_rx_ctx_rqrsp::hostrq, le16_to_cpu, le32_to_cpu, malloc_dma(), memset(), nx_hostrq_rx_ctx_s::num_rds_rings, nx_hostrq_rx_ctx_s::num_sds_rings, NX_CAP0_LEGACY_CONTEXT, NX_CAP0_LEGACY_MN, NX_CDRP_CMD_CREATE_RX_CTX, NX_HOST_INT_CRB_MODE_SHARED, NX_HOST_RDS_CRB_MODE_UNIQUE, NX_RDS_RING_TYPE_NORMAL, phantom_issue_buf_cmd(), PHN_NUM_RDS, PHN_NUM_SDS, PHN_RX_BUFSIZE, phantom_descriptor_rings::rds, phantom_create_rx_ctx_rqrsp::rds, phantom_nic::rds_producer_crb, nx_hostrq_rx_ctx_s::rds_ring_offset, nx_hostrq_rds_ring_s::ring_kind, nx_hostrq_sds_ring_s::ring_size, nx_hostrq_rds_ring_s::ring_size, phantom_nic::rx_context_id, phantom_create_rx_ctx_rqrsp::rx_ctx, phantom_descriptor_rings::sds, phantom_create_rx_ctx_rqrsp::sds, phantom_nic::sds_consumer_crb, phantom_nic::sds_irq_mask_crb, nx_hostrq_rx_ctx_s::sds_ring_offset, strerror(), UNM_CAM_RAM, UNM_DMA_BUFFER_ALIGN, and virt_to_bus().
Referenced by phantom_open().
00635 { 00636 struct phantom_create_rx_ctx_rqrsp *buf; 00637 int rc; 00638 00639 /* Allocate context creation buffer */ 00640 buf = malloc_dma ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN ); 00641 if ( ! buf ) { 00642 rc = -ENOMEM; 00643 goto out; 00644 } 00645 memset ( buf, 0, sizeof ( *buf ) ); 00646 00647 /* Prepare request */ 00648 buf->hostrq.rx_ctx.host_rsp_dma_addr = 00649 cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) ); 00650 buf->hostrq.rx_ctx.capabilities[0] = 00651 cpu_to_le32 ( NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN ); 00652 buf->hostrq.rx_ctx.host_int_crb_mode = 00653 cpu_to_le32 ( NX_HOST_INT_CRB_MODE_SHARED ); 00654 buf->hostrq.rx_ctx.host_rds_crb_mode = 00655 cpu_to_le32 ( NX_HOST_RDS_CRB_MODE_UNIQUE ); 00656 buf->hostrq.rx_ctx.rds_ring_offset = cpu_to_le32 ( 0 ); 00657 buf->hostrq.rx_ctx.sds_ring_offset = 00658 cpu_to_le32 ( sizeof ( buf->hostrq.rds ) ); 00659 buf->hostrq.rx_ctx.num_rds_rings = cpu_to_le16 ( 1 ); 00660 buf->hostrq.rx_ctx.num_sds_rings = cpu_to_le16 ( 1 ); 00661 buf->hostrq.rds.host_phys_addr = 00662 cpu_to_le64 ( virt_to_bus ( phantom->desc->rds ) ); 00663 buf->hostrq.rds.buff_size = cpu_to_le64 ( PHN_RX_BUFSIZE ); 00664 buf->hostrq.rds.ring_size = cpu_to_le32 ( PHN_NUM_RDS ); 00665 buf->hostrq.rds.ring_kind = cpu_to_le32 ( NX_RDS_RING_TYPE_NORMAL ); 00666 buf->hostrq.sds.host_phys_addr = 00667 cpu_to_le64 ( virt_to_bus ( phantom->desc->sds ) ); 00668 buf->hostrq.sds.ring_size = cpu_to_le32 ( PHN_NUM_SDS ); 00669 00670 DBGC ( phantom, "Phantom %p creating RX context\n", phantom ); 00671 DBGC2_HDA ( phantom, virt_to_bus ( &buf->hostrq ), 00672 &buf->hostrq, sizeof ( buf->hostrq ) ); 00673 00674 /* Issue request */ 00675 if ( ( rc = phantom_issue_buf_cmd ( phantom, 00676 NX_CDRP_CMD_CREATE_RX_CTX, 00677 &buf->hostrq, 00678 sizeof ( buf->hostrq ) ) ) != 0 ) { 00679 DBGC ( phantom, "Phantom %p could not create RX context: " 00680 "%s\n", phantom, strerror ( rc ) ); 00681 DBGC ( phantom, "Request:\n" ); 00682 DBGC_HDA ( phantom, virt_to_bus ( &buf->hostrq ), 00683 &buf->hostrq, sizeof ( buf->hostrq ) ); 00684 DBGC ( phantom, "Response:\n" ); 00685 DBGC_HDA ( phantom, virt_to_bus ( &buf->cardrsp ), 00686 &buf->cardrsp, sizeof ( buf->cardrsp ) ); 00687 goto out; 00688 } 00689 00690 /* Retrieve context parameters */ 00691 phantom->rx_context_id = 00692 le16_to_cpu ( buf->cardrsp.rx_ctx.context_id ); 00693 phantom->rds_producer_crb = 00694 ( UNM_CAM_RAM + 00695 le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ) ); 00696 phantom->sds_consumer_crb = 00697 ( UNM_CAM_RAM + 00698 le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ) ); 00699 phantom->sds_irq_mask_crb = 00700 ( UNM_CAM_RAM + 00701 le32_to_cpu ( buf->cardrsp.sds.interrupt_crb ) ); 00702 00703 DBGC ( phantom, "Phantom %p created RX context (id %04x, port phys " 00704 "%02x virt %02x)\n", phantom, phantom->rx_context_id, 00705 buf->cardrsp.rx_ctx.phys_port, buf->cardrsp.rx_ctx.virt_port ); 00706 DBGC2_HDA ( phantom, virt_to_bus ( &buf->cardrsp ), 00707 &buf->cardrsp, sizeof ( buf->cardrsp ) ); 00708 DBGC ( phantom, "Phantom %p RDS producer CRB is %08lx\n", 00709 phantom, phantom->rds_producer_crb ); 00710 DBGC ( phantom, "Phantom %p SDS consumer CRB is %08lx\n", 00711 phantom, phantom->sds_consumer_crb ); 00712 DBGC ( phantom, "Phantom %p SDS interrupt mask CRB is %08lx\n", 00713 phantom, phantom->sds_irq_mask_crb ); 00714 00715 out: 00716 free_dma ( buf, sizeof ( *buf ) ); 00717 return rc; 00718 }
| static void phantom_destroy_rx_ctx | ( | struct phantom_nic * | phantom | ) | [static] |
Destroy Phantom RX context.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 726 of file phantom.c.
References DBGC, NX_CDRP_CMD_DESTROY_RX_CTX, NX_DESTROY_CTX_RESET, phantom_issue_cmd(), phantom_nic::rds_consumer_idx, phantom_nic::rds_producer_crb, phantom_nic::rds_producer_idx, phantom_nic::rx_context_id, phantom_nic::sds_consumer_crb, phantom_nic::sds_consumer_idx, and strerror().
Referenced by phantom_close(), and phantom_open().
00726 { 00727 int rc; 00728 00729 DBGC ( phantom, "Phantom %p destroying RX context (id %04x)\n", 00730 phantom, phantom->rx_context_id ); 00731 00732 /* Issue request */ 00733 if ( ( rc = phantom_issue_cmd ( phantom, 00734 NX_CDRP_CMD_DESTROY_RX_CTX, 00735 phantom->rx_context_id, 00736 NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) { 00737 DBGC ( phantom, "Phantom %p could not destroy RX context: " 00738 "%s\n", phantom, strerror ( rc ) ); 00739 /* We're probably screwed */ 00740 return; 00741 } 00742 00743 /* Clear context parameters */ 00744 phantom->rx_context_id = 0; 00745 phantom->rds_producer_crb = 0; 00746 phantom->sds_consumer_crb = 0; 00747 00748 /* Reset software counters */ 00749 phantom->rds_producer_idx = 0; 00750 phantom->rds_consumer_idx = 0; 00751 phantom->sds_consumer_idx = 0; 00752 }
| static int phantom_create_tx_ctx | ( | struct phantom_nic * | phantom | ) | [static] |
Create Phantom TX context.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 760 of file phantom.c.
References nx_hostrq_tx_ctx_s::capabilities, phantom_create_tx_ctx_rqrsp::cardrsp, phantom_descriptor_rings::cds, phantom_nic::cds_producer_crb, nx_hostrq_tx_ctx_s::cds_ring, phantom_descriptor_rings::cmd_cons, nx_hostrq_tx_ctx_s::cmd_cons_dma_addr, cpu_to_le32, cpu_to_le64, DBGC, DBGC2_HDA, DBGC_HDA, phantom_nic::desc, ENOMEM, free_dma(), nx_hostrq_tx_ctx_s::host_int_crb_mode, nx_hostrq_cds_ring_s::host_phys_addr, nx_hostrq_tx_ctx_s::host_rsp_dma_addr, phantom_create_tx_ctx_rqrsp::hostrq, le16_to_cpu, le32_to_cpu, malloc_dma(), memset(), NX_CAP0_LEGACY_CONTEXT, NX_CAP0_LEGACY_MN, NX_CDRP_CMD_CREATE_TX_CTX, NX_HOST_INT_CRB_MODE_SHARED, phantom_issue_buf_cmd(), PHN_NUM_CDS, nx_hostrq_cds_ring_s::ring_size, strerror(), phantom_nic::tx_context_id, phantom_create_tx_ctx_rqrsp::tx_ctx, UNM_CAM_RAM, UNM_DMA_BUFFER_ALIGN, and virt_to_bus().
Referenced by phantom_open().
00760 { 00761 struct phantom_create_tx_ctx_rqrsp *buf; 00762 int rc; 00763 00764 /* Allocate context creation buffer */ 00765 buf = malloc_dma ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN ); 00766 if ( ! buf ) { 00767 rc = -ENOMEM; 00768 goto out; 00769 } 00770 memset ( buf, 0, sizeof ( *buf ) ); 00771 00772 /* Prepare request */ 00773 buf->hostrq.tx_ctx.host_rsp_dma_addr = 00774 cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) ); 00775 buf->hostrq.tx_ctx.cmd_cons_dma_addr = 00776 cpu_to_le64 ( virt_to_bus ( &phantom->desc->cmd_cons ) ); 00777 buf->hostrq.tx_ctx.capabilities[0] = 00778 cpu_to_le32 ( NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN ); 00779 buf->hostrq.tx_ctx.host_int_crb_mode = 00780 cpu_to_le32 ( NX_HOST_INT_CRB_MODE_SHARED ); 00781 buf->hostrq.tx_ctx.cds_ring.host_phys_addr = 00782 cpu_to_le64 ( virt_to_bus ( phantom->desc->cds ) ); 00783 buf->hostrq.tx_ctx.cds_ring.ring_size = cpu_to_le32 ( PHN_NUM_CDS ); 00784 00785 DBGC ( phantom, "Phantom %p creating TX context\n", phantom ); 00786 DBGC2_HDA ( phantom, virt_to_bus ( &buf->hostrq ), 00787 &buf->hostrq, sizeof ( buf->hostrq ) ); 00788 00789 /* Issue request */ 00790 if ( ( rc = phantom_issue_buf_cmd ( phantom, 00791 NX_CDRP_CMD_CREATE_TX_CTX, 00792 &buf->hostrq, 00793 sizeof ( buf->hostrq ) ) ) != 0 ) { 00794 DBGC ( phantom, "Phantom %p could not create TX context: " 00795 "%s\n", phantom, strerror ( rc ) ); 00796 DBGC ( phantom, "Request:\n" ); 00797 DBGC_HDA ( phantom, virt_to_bus ( &buf->hostrq ), 00798 &buf->hostrq, sizeof ( buf->hostrq ) ); 00799 DBGC ( phantom, "Response:\n" ); 00800 DBGC_HDA ( phantom, virt_to_bus ( &buf->cardrsp ), 00801 &buf->cardrsp, sizeof ( buf->cardrsp ) ); 00802 goto out; 00803 } 00804 00805 /* Retrieve context parameters */ 00806 phantom->tx_context_id = 00807 le16_to_cpu ( buf->cardrsp.tx_ctx.context_id ); 00808 phantom->cds_producer_crb = 00809 ( UNM_CAM_RAM + 00810 le32_to_cpu(buf->cardrsp.tx_ctx.cds_ring.host_producer_crb)); 00811 00812 DBGC ( phantom, "Phantom %p created TX context (id %04x, port phys " 00813 "%02x virt %02x)\n", phantom, phantom->tx_context_id, 00814 buf->cardrsp.tx_ctx.phys_port, buf->cardrsp.tx_ctx.virt_port ); 00815 DBGC2_HDA ( phantom, virt_to_bus ( &buf->cardrsp ), 00816 &buf->cardrsp, sizeof ( buf->cardrsp ) ); 00817 DBGC ( phantom, "Phantom %p CDS producer CRB is %08lx\n", 00818 phantom, phantom->cds_producer_crb ); 00819 00820 out: 00821 free_dma ( buf, sizeof ( *buf ) ); 00822 return rc; 00823 }
| static void phantom_destroy_tx_ctx | ( | struct phantom_nic * | phantom | ) | [static] |
Destroy Phantom TX context.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 831 of file phantom.c.
References phantom_nic::cds_consumer_idx, phantom_nic::cds_producer_crb, phantom_nic::cds_producer_idx, DBGC, NX_CDRP_CMD_DESTROY_TX_CTX, NX_DESTROY_CTX_RESET, phantom_issue_cmd(), strerror(), and phantom_nic::tx_context_id.
Referenced by phantom_close(), and phantom_open().
00831 { 00832 int rc; 00833 00834 DBGC ( phantom, "Phantom %p destroying TX context (id %04x)\n", 00835 phantom, phantom->tx_context_id ); 00836 00837 /* Issue request */ 00838 if ( ( rc = phantom_issue_cmd ( phantom, 00839 NX_CDRP_CMD_DESTROY_TX_CTX, 00840 phantom->tx_context_id, 00841 NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) { 00842 DBGC ( phantom, "Phantom %p could not destroy TX context: " 00843 "%s\n", phantom, strerror ( rc ) ); 00844 /* We're probably screwed */ 00845 return; 00846 } 00847 00848 /* Clear context parameters */ 00849 phantom->tx_context_id = 0; 00850 phantom->cds_producer_crb = 0; 00851 00852 /* Reset software counters */ 00853 phantom->cds_producer_idx = 0; 00854 phantom->cds_consumer_idx = 0; 00855 }
| static int phantom_alloc_rds | ( | struct phantom_nic * | phantom | ) | [static] |
Allocate Phantom RX descriptor.
| phantom | Phantom NIC |
| index | RX descriptor index, or negative error |
Definition at line 869 of file phantom.c.
References DBGC, ENOBUFS, PHN_NUM_RDS, phantom_nic::rds_consumer_idx, and phantom_nic::rds_producer_idx.
Referenced by phantom_refill_rx_ring().
00869 { 00870 unsigned int rds_producer_idx; 00871 unsigned int next_rds_producer_idx; 00872 00873 /* Check for space in the ring. RX descriptors are consumed 00874 * out of order, but they are *read* by the hardware in strict 00875 * order. We maintain a pessimistic consumer index, which is 00876 * guaranteed never to be an overestimate of the number of 00877 * descriptors read by the hardware. 00878 */ 00879 rds_producer_idx = phantom->rds_producer_idx; 00880 next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS ); 00881 if ( next_rds_producer_idx == phantom->rds_consumer_idx ) { 00882 DBGC ( phantom, "Phantom %p RDS ring full (index %d not " 00883 "consumed)\n", phantom, next_rds_producer_idx ); 00884 return -ENOBUFS; 00885 } 00886 00887 return rds_producer_idx; 00888 }
| static void phantom_post_rds | ( | struct phantom_nic * | phantom, | |
| struct phantom_rds * | rds | |||
| ) | [static] |
Post Phantom RX descriptor.
| phantom | Phantom NIC | |
| rds | RX descriptor |
Definition at line 896 of file phantom.c.
References DBGC2, DBGC2_HDA, phantom_nic::desc, entry, memcpy, NX_GET, phantom_writel(), PHN_NUM_RDS, phantom_descriptor_rings::rds, phantom_nic::rds_producer_crb, phantom_nic::rds_producer_idx, virt_to_bus(), and wmb.
Referenced by phantom_refill_rx_ring().
00897 { 00898 unsigned int rds_producer_idx; 00899 unsigned int next_rds_producer_idx; 00900 struct phantom_rds *entry; 00901 00902 /* Copy descriptor to ring */ 00903 rds_producer_idx = phantom->rds_producer_idx; 00904 entry = &phantom->desc->rds[rds_producer_idx]; 00905 memcpy ( entry, rds, sizeof ( *entry ) ); 00906 DBGC2 ( phantom, "Phantom %p posting RDS %ld (slot %d):\n", 00907 phantom, NX_GET ( rds, handle ), rds_producer_idx ); 00908 DBGC2_HDA ( phantom, virt_to_bus ( entry ), entry, sizeof ( *entry ) ); 00909 00910 /* Update producer index */ 00911 next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS ); 00912 phantom->rds_producer_idx = next_rds_producer_idx; 00913 wmb(); 00914 phantom_writel ( phantom, phantom->rds_producer_idx, 00915 phantom->rds_producer_crb ); 00916 }
| static int phantom_alloc_cds | ( | struct phantom_nic * | phantom | ) | [static] |
Allocate Phantom TX descriptor.
| phantom | Phantom NIC |
| index | TX descriptor index, or negative error |
Definition at line 924 of file phantom.c.
References phantom_nic::cds_consumer_idx, phantom_nic::cds_producer_idx, DBGC, ENOBUFS, and PHN_NUM_CDS.
Referenced by phantom_transmit(), and phantom_update_macaddr().
00924 { 00925 unsigned int cds_producer_idx; 00926 unsigned int next_cds_producer_idx; 00927 00928 /* Check for space in the ring. TX descriptors are consumed 00929 * in strict order, so we just check for a collision against 00930 * the consumer index. 00931 */ 00932 cds_producer_idx = phantom->cds_producer_idx; 00933 next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS ); 00934 if ( next_cds_producer_idx == phantom->cds_consumer_idx ) { 00935 DBGC ( phantom, "Phantom %p CDS ring full (index %d not " 00936 "consumed)\n", phantom, next_cds_producer_idx ); 00937 return -ENOBUFS; 00938 } 00939 00940 return cds_producer_idx; 00941 }
| static void phantom_post_cds | ( | struct phantom_nic * | phantom, | |
| union phantom_cds * | cds | |||
| ) | [static] |
Post Phantom TX descriptor.
| phantom | Phantom NIC | |
| cds | TX descriptor |
Definition at line 949 of file phantom.c.
References phantom_descriptor_rings::cds, phantom_nic::cds_producer_crb, phantom_nic::cds_producer_idx, DBGC2, DBGC2_HDA, phantom_nic::desc, entry, memcpy, phantom_writel(), PHN_NUM_CDS, virt_to_bus(), and wmb.
Referenced by phantom_transmit(), and phantom_update_macaddr().
00950 { 00951 unsigned int cds_producer_idx; 00952 unsigned int next_cds_producer_idx; 00953 union phantom_cds *entry; 00954 00955 /* Copy descriptor to ring */ 00956 cds_producer_idx = phantom->cds_producer_idx; 00957 entry = &phantom->desc->cds[cds_producer_idx]; 00958 memcpy ( entry, cds, sizeof ( *entry ) ); 00959 DBGC2 ( phantom, "Phantom %p posting CDS %d:\n", 00960 phantom, cds_producer_idx ); 00961 DBGC2_HDA ( phantom, virt_to_bus ( entry ), entry, sizeof ( *entry ) ); 00962 00963 /* Update producer index */ 00964 next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS ); 00965 phantom->cds_producer_idx = next_cds_producer_idx; 00966 wmb(); 00967 phantom_writel ( phantom, phantom->cds_producer_idx, 00968 phantom->cds_producer_crb ); 00969 }
| static int phantom_update_macaddr | ( | struct phantom_nic * | phantom, | |
| const uint8_t * | ll_addr, | |||
| unsigned int | opcode | |||
| ) | [static] |
Add/remove MAC address.
| phantom | Phantom NIC | |
| ll_addr | MAC address to add or remove | |
| opcode | MAC request opcode |
| rc | Return status code |
Definition at line 985 of file phantom.c.
References index, memset(), NX_FILL_1, NX_FILL_2, NX_FILL_7, phantom_alloc_cds(), phantom_post_cds(), phantom_nic::port, UNM_MAC_EVENT, and UNM_NIC_REQUEST.
Referenced by phantom_add_macaddr(), and phantom_del_macaddr().
00987 { 00988 union phantom_cds cds; 00989 int index; 00990 00991 /* Get descriptor ring entry */ 00992 index = phantom_alloc_cds ( phantom ); 00993 if ( index < 0 ) 00994 return index; 00995 00996 /* Fill descriptor ring entry */ 00997 memset ( &cds, 0, sizeof ( cds ) ); 00998 NX_FILL_1 ( &cds, 0, 00999 nic_request.common.opcode, UNM_NIC_REQUEST ); 01000 NX_FILL_2 ( &cds, 1, 01001 nic_request.header.opcode, UNM_MAC_EVENT, 01002 nic_request.header.context_id, phantom->port ); 01003 NX_FILL_7 ( &cds, 2, 01004 nic_request.body.mac_request.opcode, opcode, 01005 nic_request.body.mac_request.mac_addr_0, ll_addr[0], 01006 nic_request.body.mac_request.mac_addr_1, ll_addr[1], 01007 nic_request.body.mac_request.mac_addr_2, ll_addr[2], 01008 nic_request.body.mac_request.mac_addr_3, ll_addr[3], 01009 nic_request.body.mac_request.mac_addr_4, ll_addr[4], 01010 nic_request.body.mac_request.mac_addr_5, ll_addr[5] ); 01011 01012 /* Post descriptor */ 01013 phantom_post_cds ( phantom, &cds ); 01014 01015 return 0; 01016 }
| static int phantom_add_macaddr | ( | struct phantom_nic * | phantom, | |
| const uint8_t * | ll_addr | |||
| ) | [inline, static] |
Add MAC address.
| phantom | Phantom NIC | |
| ll_addr | MAC address to add or remove |
| rc | Return status code |
Definition at line 1025 of file phantom.c.
References DBGC, eth_ntoa(), phantom_update_macaddr(), and UNM_MAC_ADD.
Referenced by phantom_open().
01026 { 01027 01028 DBGC ( phantom, "Phantom %p adding MAC address %s\n", 01029 phantom, eth_ntoa ( ll_addr ) ); 01030 01031 return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_ADD ); 01032 }
| static int phantom_del_macaddr | ( | struct phantom_nic * | phantom, | |
| const uint8_t * | ll_addr | |||
| ) | [inline, static] |
Remove MAC address.
| phantom | Phantom NIC | |
| ll_addr | MAC address to add or remove |
| rc | Return status code |
Definition at line 1041 of file phantom.c.
References DBGC, eth_ntoa(), phantom_update_macaddr(), and UNM_MAC_DEL.
Referenced by phantom_close(), and phantom_open().
01042 { 01043 01044 DBGC ( phantom, "Phantom %p removing MAC address %s\n", 01045 phantom, eth_ntoa ( ll_addr ) ); 01046 01047 return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_DEL ); 01048 }
| static void phantom_poll_link_state | ( | struct net_device * | netdev | ) | [static] |
Poll link state.
| netdev | Network device |
Definition at line 1061 of file phantom.c.
References DBGC, phantom_nic::link_state, netdev_link_down(), netdev_link_up(), netdev_priv(), phantom_readl(), phantom_nic::port, UNM_NIC_REG_XG_STATE_P3, UNM_NIC_REG_XG_STATE_P3_LINK, UNM_NIC_REG_XG_STATE_P3_LINK_DOWN, and UNM_NIC_REG_XG_STATE_P3_LINK_UP.
Referenced by phantom_poll().
01061 { 01062 struct phantom_nic *phantom = netdev_priv ( netdev ); 01063 uint32_t xg_state_p3; 01064 unsigned int link; 01065 01066 /* Read link state */ 01067 xg_state_p3 = phantom_readl ( phantom, UNM_NIC_REG_XG_STATE_P3 ); 01068 01069 /* If there is no change, do nothing */ 01070 if ( phantom->link_state == xg_state_p3 ) 01071 return; 01072 01073 /* Record new link state */ 01074 DBGC ( phantom, "Phantom %p new link state %08x (was %08x)\n", 01075 phantom, xg_state_p3, phantom->link_state ); 01076 phantom->link_state = xg_state_p3; 01077 01078 /* Indicate link state to gPXE */ 01079 link = UNM_NIC_REG_XG_STATE_P3_LINK ( phantom->port, 01080 phantom->link_state ); 01081 switch ( link ) { 01082 case UNM_NIC_REG_XG_STATE_P3_LINK_UP: 01083 DBGC ( phantom, "Phantom %p link is up\n", phantom ); 01084 netdev_link_up ( netdev ); 01085 break; 01086 case UNM_NIC_REG_XG_STATE_P3_LINK_DOWN: 01087 DBGC ( phantom, "Phantom %p link is down\n", phantom ); 01088 netdev_link_down ( netdev ); 01089 break; 01090 default: 01091 DBGC ( phantom, "Phantom %p bad link state %d\n", 01092 phantom, link ); 01093 break; 01094 } 01095 }
| static void phantom_refill_rx_ring | ( | struct net_device * | netdev | ) | [static] |
Refill descriptor ring.
| netdev | Net device |
Definition at line 1108 of file phantom.c.
References alloc_iob(), assert, io_buffer::data, ENOMEM, index, iob_len(), memset(), netdev_priv(), netdev_rx_err(), NULL, NX_FILL_1, NX_FILL_2, phantom_alloc_rds(), phantom_post_rds(), PHN_NUM_RDS, PHN_RDS_MAX_FILL, PHN_RX_BUFSIZE, phantom_nic::rds_iobuf, and virt_to_bus().
Referenced by phantom_open(), and phantom_poll().
01108 { 01109 struct phantom_nic *phantom = netdev_priv ( netdev ); 01110 struct io_buffer *iobuf; 01111 struct phantom_rds rds; 01112 unsigned int handle; 01113 int index; 01114 01115 for ( handle = 0 ; handle < PHN_RDS_MAX_FILL ; handle++ ) { 01116 01117 /* Skip this index if the descriptor has not yet been 01118 * consumed. 01119 */ 01120 if ( phantom->rds_iobuf[handle] != NULL ) 01121 continue; 01122 01123 /* Allocate descriptor ring entry */ 01124 index = phantom_alloc_rds ( phantom ); 01125 assert ( PHN_RDS_MAX_FILL < PHN_NUM_RDS ); 01126 assert ( index >= 0 ); /* Guaranteed by MAX_FILL < NUM_RDS ) */ 01127 01128 /* Try to allocate an I/O buffer */ 01129 iobuf = alloc_iob ( PHN_RX_BUFSIZE ); 01130 if ( ! iobuf ) { 01131 /* Failure is non-fatal; we will retry later */ 01132 netdev_rx_err ( netdev, NULL, -ENOMEM ); 01133 break; 01134 } 01135 01136 /* Fill descriptor ring entry */ 01137 memset ( &rds, 0, sizeof ( rds ) ); 01138 NX_FILL_2 ( &rds, 0, 01139 handle, handle, 01140 length, iob_len ( iobuf ) ); 01141 NX_FILL_1 ( &rds, 1, 01142 dma_addr, virt_to_bus ( iobuf->data ) ); 01143 01144 /* Record I/O buffer */ 01145 assert ( phantom->rds_iobuf[handle] == NULL ); 01146 phantom->rds_iobuf[handle] = iobuf; 01147 01148 /* Post descriptor */ 01149 phantom_post_rds ( phantom, &rds ); 01150 } 01151 }
| static int phantom_open | ( | struct net_device * | netdev | ) | [static] |
Open NIC.
| netdev | Net device |
| rc | Return status code |
Definition at line 1159 of file phantom.c.
References phantom_nic::desc, ENOMEM, free_dma(), net_device::ll_addr, net_device::ll_broadcast, malloc_dma(), memset(), netdev_priv(), NULL, phantom_add_macaddr(), phantom_create_rx_ctx(), phantom_create_tx_ctx(), phantom_del_macaddr(), phantom_destroy_rx_ctx(), phantom_destroy_tx_ctx(), phantom_refill_rx_ring(), and UNM_DMA_BUFFER_ALIGN.
01159 { 01160 struct phantom_nic *phantom = netdev_priv ( netdev ); 01161 int rc; 01162 01163 /* Allocate and zero descriptor rings */ 01164 phantom->desc = malloc_dma ( sizeof ( *(phantom->desc) ), 01165 UNM_DMA_BUFFER_ALIGN ); 01166 if ( ! phantom->desc ) { 01167 rc = -ENOMEM; 01168 goto err_alloc_desc; 01169 } 01170 memset ( phantom->desc, 0, sizeof ( *(phantom->desc) ) ); 01171 01172 /* Create RX context */ 01173 if ( ( rc = phantom_create_rx_ctx ( phantom ) ) != 0 ) 01174 goto err_create_rx_ctx; 01175 01176 /* Create TX context */ 01177 if ( ( rc = phantom_create_tx_ctx ( phantom ) ) != 0 ) 01178 goto err_create_tx_ctx; 01179 01180 /* Fill the RX descriptor ring */ 01181 phantom_refill_rx_ring ( netdev ); 01182 01183 /* Add MAC addresses 01184 * 01185 * BUG5583 01186 * 01187 * We would like to be able to enable receiving all multicast 01188 * packets (or, failing that, promiscuous mode), but the 01189 * firmware doesn't currently support this. 01190 */ 01191 if ( ( rc = phantom_add_macaddr ( phantom, 01192 netdev->ll_broadcast ) ) != 0 ) 01193 goto err_add_macaddr_broadcast; 01194 if ( ( rc = phantom_add_macaddr ( phantom, 01195 netdev->ll_addr ) ) != 0 ) 01196 goto err_add_macaddr_unicast; 01197 01198 return 0; 01199 01200 phantom_del_macaddr ( phantom, netdev->ll_addr ); 01201 err_add_macaddr_unicast: 01202 phantom_del_macaddr ( phantom, netdev->ll_broadcast ); 01203 err_add_macaddr_broadcast: 01204 phantom_destroy_tx_ctx ( phantom ); 01205 err_create_tx_ctx: 01206 phantom_destroy_rx_ctx ( phantom ); 01207 err_create_rx_ctx: 01208 free_dma ( phantom->desc, sizeof ( *(phantom->desc) ) ); 01209 phantom->desc = NULL; 01210 err_alloc_desc: 01211 return rc; 01212 }
| static void phantom_close | ( | struct net_device * | netdev | ) | [static] |
Close NIC.
| netdev | Net device |
Definition at line 1219 of file phantom.c.
References phantom_nic::cds_iobuf, phantom_nic::desc, ECANCELED, free_dma(), free_iob(), net_device::ll_addr, net_device::ll_broadcast, netdev_priv(), netdev_tx_complete_err(), NULL, phantom_del_macaddr(), phantom_destroy_rx_ctx(), phantom_destroy_tx_ctx(), PHN_NUM_CDS, PHN_RDS_MAX_FILL, and phantom_nic::rds_iobuf.
01219 { 01220 struct phantom_nic *phantom = netdev_priv ( netdev ); 01221 struct io_buffer *iobuf; 01222 unsigned int i; 01223 01224 /* Shut down the port */ 01225 phantom_del_macaddr ( phantom, netdev->ll_addr ); 01226 phantom_del_macaddr ( phantom, netdev->ll_broadcast ); 01227 phantom_destroy_tx_ctx ( phantom ); 01228 phantom_destroy_rx_ctx ( phantom ); 01229 free_dma ( phantom->desc, sizeof ( *(phantom->desc) ) ); 01230 phantom->desc = NULL; 01231 01232 /* Flush any uncompleted descriptors */ 01233 for ( i = 0 ; i < PHN_RDS_MAX_FILL ; i++ ) { 01234 iobuf = phantom->rds_iobuf[i]; 01235 if ( iobuf ) { 01236 free_iob ( iobuf ); 01237 phantom->rds_iobuf[i] = NULL; 01238 } 01239 } 01240 for ( i = 0 ; i < PHN_NUM_CDS ; i++ ) { 01241 iobuf = phantom->cds_iobuf[i]; 01242 if ( iobuf ) { 01243 netdev_tx_complete_err ( netdev, iobuf, -ECANCELED ); 01244 phantom->cds_iobuf[i] = NULL; 01245 } 01246 } 01247 }
| static int phantom_transmit | ( | struct net_device * | netdev, | |
| struct io_buffer * | iobuf | |||
| ) | [static] |
Transmit packet.
| netdev | Network device | |
| iobuf | I/O buffer |
| rc | Return status code |
Definition at line 1256 of file phantom.c.
References assert, phantom_nic::cds_iobuf, io_buffer::data, index, iob_len(), memset(), netdev_priv(), NULL, NX_FILL_1, NX_FILL_2, NX_FILL_3, phantom_alloc_cds(), phantom_post_cds(), phantom_nic::port, UNM_TX_ETHER_PKT, and virt_to_bus().
01257 { 01258 struct phantom_nic *phantom = netdev_priv ( netdev ); 01259 union phantom_cds cds; 01260 int index; 01261 01262 /* Get descriptor ring entry */ 01263 index = phantom_alloc_cds ( phantom ); 01264 if ( index < 0 ) 01265 return index; 01266 01267 /* Fill descriptor ring entry */ 01268 memset ( &cds, 0, sizeof ( cds ) ); 01269 NX_FILL_3 ( &cds, 0, 01270 tx.opcode, UNM_TX_ETHER_PKT, 01271 tx.num_buffers, 1, 01272 tx.length, iob_len ( iobuf ) ); 01273 NX_FILL_2 ( &cds, 2, 01274 tx.port, phantom->port, 01275 tx.context_id, phantom->port ); 01276 NX_FILL_1 ( &cds, 4, 01277 tx.buffer1_dma_addr, virt_to_bus ( iobuf->data ) ); 01278 NX_FILL_1 ( &cds, 5, 01279 tx.buffer1_length, iob_len ( iobuf ) ); 01280 01281 /* Record I/O buffer */ 01282 assert ( phantom->cds_iobuf[index] == NULL ); 01283 phantom->cds_iobuf[index] = iobuf; 01284 01285 /* Post descriptor */ 01286 phantom_post_cds ( phantom, &cds ); 01287 01288 return 0; 01289 }
| static void phantom_poll | ( | struct net_device * | netdev | ) | [static] |
Poll for received packets.
| netdev | Network device |
Definition at line 1296 of file phantom.c.
References assert, phantom_nic::cds_consumer_idx, phantom_nic::cds_iobuf, phantom_descriptor_rings::cmd_cons, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, phantom_nic::desc, iob_pull, iob_put, le32_to_cpu, phantom_nic::link_poll_timer, memset(), netdev_priv(), netdev_rx(), netdev_tx_complete(), NULL, NX_GET, phantom_irq_status_reg, phantom_poll_link_state(), phantom_readl(), phantom_refill_rx_ring(), phantom_writel(), PHN_LINK_POLL_FREQUENCY, PHN_NUM_CDS, PHN_NUM_RDS, PHN_NUM_SDS, phantom_nic::port, phantom_nic::rds_consumer_idx, phantom_nic::rds_iobuf, phantom_descriptor_rings::sds, phantom_nic::sds_consumer_crb, phantom_nic::sds_consumer_idx, phantom_nic::sds_irq_enabled, UNM_PCIE_IRQ_STATE, UNM_PCIE_IRQ_STATE_TRIGGERED, UNM_PCIE_IRQ_STATUS_MAGIC, UNM_PCIE_IRQ_VECTOR, UNM_PCIE_IRQ_VECTOR_BIT, UNM_RXPKT_DESC, UNM_SYN_OFFLOAD, virt_to_bus(), and wmb.
01296 { 01297 struct phantom_nic *phantom = netdev_priv ( netdev ); 01298 struct io_buffer *iobuf; 01299 unsigned int irq_vector; 01300 unsigned int irq_state; 01301 unsigned int cds_consumer_idx; 01302 unsigned int raw_new_cds_consumer_idx; 01303 unsigned int new_cds_consumer_idx; 01304 unsigned int rds_consumer_idx; 01305 unsigned int sds_consumer_idx; 01306 struct phantom_sds *sds; 01307 unsigned int sds_handle; 01308 unsigned int sds_opcode; 01309 01310 /* Occasionally poll the link state */ 01311 if ( phantom->link_poll_timer-- == 0 ) { 01312 phantom_poll_link_state ( netdev ); 01313 /* Reset the link poll timer */ 01314 phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY; 01315 } 01316 01317 /* Check for interrupts */ 01318 if ( phantom->sds_irq_enabled ) { 01319 01320 /* Do nothing unless an interrupt is asserted */ 01321 irq_vector = phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR ); 01322 if ( ! ( irq_vector & UNM_PCIE_IRQ_VECTOR_BIT( phantom->port ))) 01323 return; 01324 01325 /* Do nothing unless interrupt state machine has stabilised */ 01326 irq_state = phantom_readl ( phantom, UNM_PCIE_IRQ_STATE ); 01327 if ( ! UNM_PCIE_IRQ_STATE_TRIGGERED ( irq_state ) ) 01328 return; 01329 01330 /* Acknowledge interrupt */ 01331 phantom_writel ( phantom, UNM_PCIE_IRQ_STATUS_MAGIC, 01332 phantom_irq_status_reg[phantom->port] ); 01333 phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR ); 01334 } 01335 01336 /* Check for TX completions */ 01337 cds_consumer_idx = phantom->cds_consumer_idx; 01338 raw_new_cds_consumer_idx = phantom->desc->cmd_cons; 01339 new_cds_consumer_idx = le32_to_cpu ( raw_new_cds_consumer_idx ); 01340 while ( cds_consumer_idx != new_cds_consumer_idx ) { 01341 DBGC2 ( phantom, "Phantom %p CDS %d complete\n", 01342 phantom, cds_consumer_idx ); 01343 /* Completions may be for commands other than TX, so 01344 * there may not always be an associated I/O buffer. 01345 */ 01346 if ( ( iobuf = phantom->cds_iobuf[cds_consumer_idx] ) ) { 01347 netdev_tx_complete ( netdev, iobuf ); 01348 phantom->cds_iobuf[cds_consumer_idx] = NULL; 01349 } 01350 cds_consumer_idx = ( ( cds_consumer_idx + 1 ) % PHN_NUM_CDS ); 01351 phantom->cds_consumer_idx = cds_consumer_idx; 01352 } 01353 01354 /* Check for received packets */ 01355 rds_consumer_idx = phantom->rds_consumer_idx; 01356 sds_consumer_idx = phantom->sds_consumer_idx; 01357 while ( 1 ) { 01358 sds = &phantom->desc->sds[sds_consumer_idx]; 01359 if ( NX_GET ( sds, owner ) == 0 ) 01360 break; 01361 01362 DBGC2 ( phantom, "Phantom %p SDS %d status:\n", 01363 phantom, sds_consumer_idx ); 01364 DBGC2_HDA ( phantom, virt_to_bus ( sds ), sds, sizeof (*sds) ); 01365 01366 /* Check received opcode */ 01367 sds_opcode = NX_GET ( sds, opcode ); 01368 if ( ( sds_opcode == UNM_RXPKT_DESC ) || 01369 ( sds_opcode == UNM_SYN_OFFLOAD ) ) { 01370 01371 /* Sanity check: ensure that all of the SDS 01372 * descriptor has been written. 01373 */ 01374 if ( NX_GET ( sds, total_length ) == 0 ) { 01375 DBGC ( phantom, "Phantom %p SDS %d " 01376 "incomplete; deferring\n", 01377 phantom, sds_consumer_idx ); 01378 /* Leave for next poll() */ 01379 break; 01380 } 01381 01382 /* Process received packet */ 01383 sds_handle = NX_GET ( sds, handle ); 01384 iobuf = phantom->rds_iobuf[sds_handle]; 01385 assert ( iobuf != NULL ); 01386 iob_put ( iobuf, NX_GET ( sds, total_length ) ); 01387 iob_pull ( iobuf, NX_GET ( sds, pkt_offset ) ); 01388 DBGC2 ( phantom, "Phantom %p RDS %d complete\n", 01389 phantom, sds_handle ); 01390 netdev_rx ( netdev, iobuf ); 01391 phantom->rds_iobuf[sds_handle] = NULL; 01392 01393 /* Update RDS consumer counter. This is a 01394 * lower bound for the number of descriptors 01395 * that have been read by the hardware, since 01396 * the hardware must have read at least one 01397 * descriptor for each completion that we 01398 * receive. 01399 */ 01400 rds_consumer_idx = 01401 ( ( rds_consumer_idx + 1 ) % PHN_NUM_RDS ); 01402 phantom->rds_consumer_idx = rds_consumer_idx; 01403 01404 } else { 01405 01406 DBGC ( phantom, "Phantom %p unexpected SDS opcode " 01407 "%02x\n", phantom, sds_opcode ); 01408 DBGC_HDA ( phantom, virt_to_bus ( sds ), 01409 sds, sizeof ( *sds ) ); 01410 } 01411 01412 /* Clear status descriptor */ 01413 memset ( sds, 0, sizeof ( *sds ) ); 01414 01415 /* Update SDS consumer index */ 01416 sds_consumer_idx = ( ( sds_consumer_idx + 1 ) % PHN_NUM_SDS ); 01417 phantom->sds_consumer_idx = sds_consumer_idx; 01418 wmb(); 01419 phantom_writel ( phantom, phantom->sds_consumer_idx, 01420 phantom->sds_consumer_crb ); 01421 } 01422 01423 /* Refill the RX descriptor ring */ 01424 phantom_refill_rx_ring ( netdev ); 01425 }
| static void phantom_irq | ( | struct net_device * | netdev, | |
| int | enable | |||
| ) | [static] |
Enable/disable interrupts.
| netdev | Network device | |
| enable | Interrupts should be enabled |
Definition at line 1433 of file phantom.c.
References netdev_priv(), phantom_irq_mask_reg, phantom_writel(), phantom_nic::port, phantom_nic::sds_irq_enabled, phantom_nic::sds_irq_mask_crb, and UNM_PCIE_IRQ_MASK_MAGIC.
01433 { 01434 struct phantom_nic *phantom = netdev_priv ( netdev ); 01435 01436 phantom_writel ( phantom, ( enable ? 1 : 0 ), 01437 phantom->sds_irq_mask_crb ); 01438 phantom_writel ( phantom, UNM_PCIE_IRQ_MASK_MAGIC, 01439 phantom_irq_mask_reg[phantom->port] ); 01440 phantom->sds_irq_enabled = enable; 01441 }
| static int phantom_clp_wait | ( | struct phantom_nic * | phantom | ) | [static] |
Wait for Phantom CLP command to complete.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 1491 of file phantom.c.
References DBGC, ETIMEDOUT, mdelay(), phantom_readl(), PHN_CLP_CMD_TIMEOUT_MS, UNM_CAM_RAM_CLP_STATUS, and UNM_CAM_RAM_CLP_STATUS_DONE.
Referenced by phantom_clp_cmd().
01491 { 01492 unsigned int retries; 01493 uint32_t status; 01494 01495 for ( retries = 0 ; retries < PHN_CLP_CMD_TIMEOUT_MS ; retries++ ) { 01496 status = phantom_readl ( phantom, UNM_CAM_RAM_CLP_STATUS ); 01497 if ( status & UNM_CAM_RAM_CLP_STATUS_DONE ) 01498 return 0; 01499 mdelay ( 1 ); 01500 } 01501 01502 DBGC ( phantom, "Phantom %p timed out waiting for CLP command\n", 01503 phantom ); 01504 return -ETIMEDOUT; 01505 }
| static int phantom_clp_cmd | ( | struct phantom_nic * | phantom, | |
| unsigned int | port, | |||
| unsigned int | opcode, | |||
| const void * | data_in, | |||
| void * | data_out, | |||
| size_t | offset, | |||
| size_t | len | |||
| ) | [static] |
Issue Phantom CLP command.
| phantom | Phantom NIC | |
| port | Virtual port number | |
| opcode | Opcode | |
| data_in | Data in, or NULL | |
| data_out | Data out, or NULL | |
| offset | Offset within data | |
| len | Data buffer length |
| len | Total transfer length (for reads), or negative error |
Definition at line 1519 of file phantom.c.
References assert, be32_to_cpu, phantom_clp_data::bytes, cpu_to_be32, DBGC, phantom_clp_data::dwords, EINVAL, EIO, phantom_clp_data::hi, index, phantom_clp_data::lo, mb(), memcpy, memset(), phantom_clp_wait(), phantom_readl(), phantom_writel(), UNM_CAM_RAM_CLP_COMMAND, UNM_CAM_RAM_CLP_DATA_HI, UNM_CAM_RAM_CLP_DATA_LO, UNM_CAM_RAM_CLP_STATUS, and UNM_CAM_RAM_CLP_STATUS_START.
Referenced by phantom_clp_fetch(), and phantom_clp_store().
01521 { 01522 union phantom_clp_data data; 01523 unsigned int index = ( offset / sizeof ( data ) ); 01524 unsigned int last = 0; 01525 size_t in_frag_len; 01526 uint8_t *in_frag; 01527 uint32_t command; 01528 uint32_t status; 01529 size_t read_len; 01530 unsigned int error; 01531 size_t out_frag_len; 01532 uint8_t *out_frag; 01533 int rc; 01534 01535 /* Sanity checks */ 01536 assert ( ( offset % sizeof ( data ) ) == 0 ); 01537 if ( len > 255 ) { 01538 DBGC ( phantom, "Phantom %p invalid CLP length %zd\n", 01539 phantom, len ); 01540 return -EINVAL; 01541 } 01542 01543 /* Check that CLP interface is ready */ 01544 if ( ( rc = phantom_clp_wait ( phantom ) ) != 0 ) 01545 return rc; 01546 01547 /* Copy data in */ 01548 memset ( &data, 0, sizeof ( data ) ); 01549 if ( data_in ) { 01550 assert ( offset < len ); 01551 in_frag_len = ( len - offset ); 01552 if ( in_frag_len > sizeof ( data ) ) { 01553 in_frag_len = sizeof ( data ); 01554 } else { 01555 last = 1; 01556 } 01557 in_frag = &data.bytes[ sizeof ( data ) - in_frag_len ]; 01558 memcpy ( in_frag, ( data_in + offset ), in_frag_len ); 01559 phantom_writel ( phantom, be32_to_cpu ( data.dwords.lo ), 01560 UNM_CAM_RAM_CLP_DATA_LO ); 01561 phantom_writel ( phantom, be32_to_cpu ( data.dwords.hi ), 01562 UNM_CAM_RAM_CLP_DATA_HI ); 01563 } 01564 01565 /* Issue CLP command */ 01566 command = ( ( index << 24 ) | ( ( data_in ? len : 0 ) << 16 ) | 01567 ( port << 8 ) | ( last << 7 ) | ( opcode << 0 ) ); 01568 phantom_writel ( phantom, command, UNM_CAM_RAM_CLP_COMMAND ); 01569 mb(); 01570 phantom_writel ( phantom, UNM_CAM_RAM_CLP_STATUS_START, 01571 UNM_CAM_RAM_CLP_STATUS ); 01572 01573 /* Wait for command to complete */ 01574 if ( ( rc = phantom_clp_wait ( phantom ) ) != 0 ) 01575 return rc; 01576 01577 /* Get command status */ 01578 status = phantom_readl ( phantom, UNM_CAM_RAM_CLP_STATUS ); 01579 read_len = ( ( status >> 16 ) & 0xff ); 01580 error = ( ( status >> 8 ) & 0xff ); 01581 if ( error ) { 01582 DBGC ( phantom, "Phantom %p CLP command error %02x\n", 01583 phantom, error ); 01584 return -EIO; 01585 } 01586 01587 /* Copy data out */ 01588 if ( data_out ) { 01589 data.dwords.lo = cpu_to_be32 ( phantom_readl ( phantom, 01590 UNM_CAM_RAM_CLP_DATA_LO ) ); 01591 data.dwords.hi = cpu_to_be32 ( phantom_readl ( phantom, 01592 UNM_CAM_RAM_CLP_DATA_HI ) ); 01593 out_frag_len = ( read_len - offset ); 01594 if ( out_frag_len > sizeof ( data ) ) 01595 out_frag_len = sizeof ( data ); 01596 out_frag = &data.bytes[ sizeof ( data ) - out_frag_len ]; 01597 if ( out_frag_len > ( len - offset ) ) 01598 out_frag_len = ( len - offset ); 01599 memcpy ( ( data_out + offset ), out_frag, out_frag_len ); 01600 } 01601 01602 return read_len; 01603 }
| static int phantom_clp_store | ( | struct phantom_nic * | phantom, | |
| unsigned int | port, | |||
| unsigned int | setting, | |||
| const void * | data, | |||
| size_t | len | |||
| ) | [static] |
Store Phantom CLP setting.
| phantom | Phantom NIC | |
| port | Virtual port number | |
| setting | Setting number | |
| data | Data buffer | |
| len | Length of data buffer |
| rc | Return status code |
Definition at line 1615 of file phantom.c.
References NULL, offset, phantom_clp_cmd(), and PHN_CLP_BLKSIZE.
Referenced by phantom_store_setting().
01617 { 01618 unsigned int opcode = setting; 01619 size_t offset; 01620 int rc; 01621 01622 for ( offset = 0 ; offset < len ; offset += PHN_CLP_BLKSIZE ) { 01623 if ( ( rc = phantom_clp_cmd ( phantom, port, opcode, data, 01624 NULL, offset, len ) ) < 0 ) 01625 return rc; 01626 } 01627 return 0; 01628 }
| static int phantom_clp_fetch | ( | struct phantom_nic * | phantom, | |
| unsigned int | port, | |||
| unsigned int | setting, | |||
| void * | data, | |||
| size_t | len | |||
| ) | [static] |
Fetch Phantom CLP setting.
| phantom | Phantom NIC | |
| port | Virtual port number | |
| setting | Setting number | |
| data | Data buffer | |
| len | Length of data buffer |
| len | Length of setting, or negative error |
Definition at line 1640 of file phantom.c.
References NULL, offset, phantom_clp_cmd(), and PHN_CLP_BLKSIZE.
Referenced by phantom_fetch_setting().
01641 { 01642 unsigned int opcode = ( setting + 1 ); 01643 size_t offset = 0; 01644 int read_len; 01645 01646 while ( 1 ) { 01647 read_len = phantom_clp_cmd ( phantom, port, opcode, NULL, 01648 data, offset, len ); 01649 if ( read_len < 0 ) 01650 return read_len; 01651 offset += PHN_CLP_BLKSIZE; 01652 if ( offset >= ( unsigned ) read_len ) 01653 break; 01654 if ( offset >= len ) 01655 break; 01656 } 01657 return read_len; 01658 }
| static unsigned int phantom_clp_setting | ( | struct phantom_nic * | phantom, | |
| struct setting * | setting | |||
| ) | [static] |
Find Phantom CLP setting.
Definition at line 1680 of file phantom.c.
References phantom_clp_setting::clp_setting, DBGC2, setting::name, PHN_CLP_TAG_MAGIC, PHN_CLP_TAG_MAGIC_MASK, phantom_clp_setting::setting, setting_cmp(), and setting::tag.
Referenced by phantom_fetch_setting(), and phantom_store_setting().
01680 { 01681 struct phantom_clp_setting *clp_setting; 01682 unsigned int i; 01683 01684 /* Search the list of explicitly-defined settings */ 01685 for ( i = 0 ; i < ( sizeof ( clp_settings ) / 01686 sizeof ( clp_settings[0] ) ) ; i++ ) { 01687 clp_setting = &clp_settings[i]; 01688 if ( setting_cmp ( setting, clp_setting->setting ) == 0 ) 01689 return clp_setting->clp_setting; 01690 } 01691 01692 /* Allow for use of numbered settings */ 01693 if ( ( setting->tag & PHN_CLP_TAG_MAGIC_MASK ) == PHN_CLP_TAG_MAGIC ) 01694 return ( setting->tag & ~PHN_CLP_TAG_MAGIC_MASK ); 01695 01696 DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n", 01697 phantom, setting->name ); 01698 01699 return 0; 01700 }
| static int phantom_store_setting | ( | struct settings * | settings, | |
| struct setting * | setting, | |||
| const void * | data, | |||
| size_t | len | |||
| ) | [static] |
Store Phantom CLP setting.
| settings | Settings block | |
| setting | Setting to store | |
| data | Setting data, or NULL to clear setting | |
| len | Length of setting data |
| rc | Return status code |
Definition at line 1711 of file phantom.c.
References container_of, DBGC, ENOTSUP, setting::name, phantom_clp_setting(), phantom_clp_store(), phantom_nic::port, and strerror().
01713 { 01714 struct phantom_nic *phantom = 01715 container_of ( settings, struct phantom_nic, settings ); 01716 unsigned int clp_setting; 01717 int rc; 01718 01719 /* Find Phantom setting equivalent to gPXE setting */ 01720 clp_setting = phantom_clp_setting ( phantom, setting ); 01721 if ( ! clp_setting ) 01722 return -ENOTSUP; 01723 01724 /* Store setting */ 01725 if ( ( rc = phantom_clp_store ( phantom, phantom->port, 01726 clp_setting, data, len ) ) != 0 ) { 01727 DBGC ( phantom, "Phantom %p could not store setting \"%s\": " 01728 "%s\n", phantom, setting->name, strerror ( rc ) ); 01729 return rc; 01730 } 01731 01732 return 0; 01733 }
| static int phantom_fetch_setting | ( | struct settings * | settings, | |
| struct setting * | setting, | |||
| void * | data, | |||
| size_t | len | |||
| ) | [static] |
Fetch Phantom CLP setting.
| settings | Settings block | |
| setting | Setting to fetch | |
| data | Buffer to fill with setting data | |
| len | Length of buffer |
| len | Length of setting data, or negative error |
Definition at line 1744 of file phantom.c.
References container_of, DBGC, ENOTSUP, setting::name, phantom_clp_fetch(), phantom_clp_setting(), phantom_nic::port, and strerror().
01746 { 01747 struct phantom_nic *phantom = 01748 container_of ( settings, struct phantom_nic, settings ); 01749 unsigned int clp_setting; 01750 int read_len; 01751 int rc; 01752 01753 /* Find Phantom setting equivalent to gPXE setting */ 01754 clp_setting = phantom_clp_setting ( phantom, setting ); 01755 if ( ! clp_setting ) 01756 return -ENOTSUP; 01757 01758 /* Fetch setting */ 01759 if ( ( read_len = phantom_clp_fetch ( phantom, phantom->port, 01760 clp_setting, data, len ) ) < 0 ){ 01761 rc = read_len; 01762 DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": " 01763 "%s\n", phantom, setting->name, strerror ( rc ) ); 01764 return rc; 01765 } 01766 01767 return read_len; 01768 }
| static int phantom_map_crb | ( | struct phantom_nic * | phantom, | |
| struct pci_device * | pci | |||
| ) | [static] |
Map Phantom CRB window.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 1788 of file phantom.c.
References phantom_nic::bar0, pci_device::bus, phantom_nic::crb_access, phantom_nic::crb_window, DBGC, pci_device::devfn, EINVAL, EIO, ioremap(), pci_bar_size(), pci_bar_start(), PCI_BASE_ADDRESS_0, PCI_FUNC, PCI_SLOT, phantom_crb_access_128m(), phantom_crb_access_2m(), and phantom_crb_access_32m().
Referenced by phantom_probe().
01789 { 01790 unsigned long bar0_start; 01791 unsigned long bar0_size; 01792 01793 bar0_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_0 ); 01794 bar0_size = pci_bar_size ( pci, PCI_BASE_ADDRESS_0 ); 01795 DBGC ( phantom, "Phantom %p is PCI %02x:%02x.%x with BAR0 at " 01796 "%08lx+%lx\n", phantom, pci->bus, PCI_SLOT ( pci->devfn ), 01797 PCI_FUNC ( pci->devfn ), bar0_start, bar0_size ); 01798 01799 if ( ! bar0_start ) { 01800 DBGC ( phantom, "Phantom %p BAR not assigned; ignoring\n", 01801 phantom ); 01802 return -EINVAL; 01803 } 01804 01805 switch ( bar0_size ) { 01806 case ( 128 * 1024 * 1024 ) : 01807 DBGC ( phantom, "Phantom %p has 128MB BAR\n", phantom ); 01808 phantom->crb_access = phantom_crb_access_128m; 01809 break; 01810 case ( 32 * 1024 * 1024 ) : 01811 DBGC ( phantom, "Phantom %p has 32MB BAR\n", phantom ); 01812 phantom->crb_access = phantom_crb_access_32m; 01813 break; 01814 case ( 2 * 1024 * 1024 ) : 01815 DBGC ( phantom, "Phantom %p has 2MB BAR\n", phantom ); 01816 phantom->crb_access = phantom_crb_access_2m; 01817 break; 01818 default: 01819 DBGC ( phantom, "Phantom %p has bad BAR size\n", phantom ); 01820 return -EINVAL; 01821 } 01822 01823 phantom->bar0 = ioremap ( bar0_start, bar0_size ); 01824 if ( ! phantom->bar0 ) { 01825 DBGC ( phantom, "Phantom %p could not map BAR0\n", phantom ); 01826 return -EIO; 01827 } 01828 01829 /* Mark current CRB window as invalid, so that the first 01830 * read/write will set the current window. 01831 */ 01832 phantom->crb_window = -1UL; 01833 01834 return 0; 01835 }
| static void phantom_unhalt_pegs | ( | struct phantom_nic * | phantom | ) | [static] |
Unhalt all PEGs.
| phantom | Phantom NIC |
Definition at line 1842 of file phantom.c.
References phantom_readl(), phantom_writel(), UNM_PEG_0_HALT_STATUS, UNM_PEG_1_HALT_STATUS, UNM_PEG_2_HALT_STATUS, UNM_PEG_3_HALT_STATUS, and UNM_PEG_4_HALT_STATUS.
Referenced by phantom_init_cmdpeg().
01842 { 01843 uint32_t halt_status; 01844 01845 halt_status = phantom_readl ( phantom, UNM_PEG_0_HALT_STATUS ); 01846 phantom_writel ( phantom, halt_status, UNM_PEG_0_HALT_STATUS ); 01847 halt_status = phantom_readl ( phantom, UNM_PEG_1_HALT_STATUS ); 01848 phantom_writel ( phantom, halt_status, UNM_PEG_1_HALT_STATUS ); 01849 halt_status = phantom_readl ( phantom, UNM_PEG_2_HALT_STATUS ); 01850 phantom_writel ( phantom, halt_status, UNM_PEG_2_HALT_STATUS ); 01851 halt_status = phantom_readl ( phantom, UNM_PEG_3_HALT_STATUS ); 01852 phantom_writel ( phantom, halt_status, UNM_PEG_3_HALT_STATUS ); 01853 halt_status = phantom_readl ( phantom, UNM_PEG_4_HALT_STATUS ); 01854 phantom_writel ( phantom, halt_status, UNM_PEG_4_HALT_STATUS ); 01855 }
| static int phantom_init_cmdpeg | ( | struct phantom_nic * | phantom | ) | [static] |
Initialise the Phantom command PEG.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 1863 of file phantom.c.
References DBGC, EIO, ETIMEDOUT, mdelay(), phantom_readl(), phantom_unhalt_pegs(), phantom_write_hilo(), phantom_writel(), PHN_CMDPEG_INIT_TIMEOUT_SEC, UNM_CAM_RAM_COLD_BOOT, UNM_CAM_RAM_COLD_BOOT_MAGIC, UNM_CAM_RAM_PORT_MODE_AUTO_NEG_1G, UNM_CAM_RAM_WOL_PORT_MODE, UNM_NIC_REG_CMDPEG_STATE, UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK, UNM_NIC_REG_CMDPEG_STATE_INITIALIZED, UNM_NIC_REG_DUMMY_BUF, UNM_NIC_REG_DUMMY_BUF_ADDR_HI, UNM_NIC_REG_DUMMY_BUF_ADDR_LO, UNM_NIC_REG_DUMMY_BUF_INIT, UNM_ROMUSB_GLB_PEGTUNE_DONE, UNM_ROMUSB_GLB_PEGTUNE_DONE_MAGIC, UNM_ROMUSB_GLB_SW_RESET, and UNM_ROMUSB_GLB_SW_RESET_MAGIC.
Referenced by phantom_probe().
01863 { 01864 uint32_t cold_boot; 01865 uint32_t sw_reset; 01866 unsigned int retries; 01867 uint32_t cmdpeg_state; 01868 uint32_t last_cmdpeg_state = 0; 01869 01870 /* Check for a previous initialisation. This could have 01871 * happened if, for example, the BIOS used the UNDI API to 01872 * drive the NIC prior to a full PXE boot. 01873 */ 01874 cmdpeg_state = phantom_readl ( phantom, UNM_NIC_REG_CMDPEG_STATE ); 01875 if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK ) { 01876 DBGC ( phantom, "Phantom %p command PEG already initialized\n", 01877 phantom ); 01878 /* Unhalt the PEGs. Previous firmware (e.g. BOFM) may 01879 * have halted the PEGs to prevent internal bus 01880 * collisions when the BIOS re-reads the expansion ROM. 01881 */ 01882 phantom_unhalt_pegs ( phantom ); 01883 return 0; 01884 } 01885 01886 /* If this was a cold boot, check that the hardware came up ok */ 01887 cold_boot = phantom_readl ( phantom, UNM_CAM_RAM_COLD_BOOT ); 01888 if ( cold_boot == UNM_CAM_RAM_COLD_BOOT_MAGIC ) { 01889 DBGC ( phantom, "Phantom %p coming up from cold boot\n", 01890 phantom ); 01891 sw_reset = phantom_readl ( phantom, UNM_ROMUSB_GLB_SW_RESET ); 01892 if ( sw_reset != UNM_ROMUSB_GLB_SW_RESET_MAGIC ) { 01893 DBGC ( phantom, "Phantom %p reset failed: %08x\n", 01894 phantom, sw_reset ); 01895 return -EIO; 01896 } 01897 } else { 01898 DBGC ( phantom, "Phantom %p coming up from warm boot " 01899 "(%08x)\n", phantom, cold_boot ); 01900 } 01901 /* Clear cold-boot flag */ 01902 phantom_writel ( phantom, 0, UNM_CAM_RAM_COLD_BOOT ); 01903 01904 /* Set port modes */ 01905 phantom_writel ( phantom, UNM_CAM_RAM_PORT_MODE_AUTO_NEG_1G, 01906 UNM_CAM_RAM_WOL_PORT_MODE ); 01907 01908 /* Pass dummy DMA area to card */ 01909 phantom_write_hilo ( phantom, 0, 01910 UNM_NIC_REG_DUMMY_BUF_ADDR_LO, 01911 UNM_NIC_REG_DUMMY_BUF_ADDR_HI ); 01912 phantom_writel ( phantom, UNM_NIC_REG_DUMMY_BUF_INIT, 01913 UNM_NIC_REG_DUMMY_BUF ); 01914 01915 /* Tell the hardware that tuning is complete */ 01916 phantom_writel ( phantom, UNM_ROMUSB_GLB_PEGTUNE_DONE_MAGIC, 01917 UNM_ROMUSB_GLB_PEGTUNE_DONE ); 01918 01919 /* Wait for command PEG to finish initialising */ 01920 DBGC ( phantom, "Phantom %p initialising command PEG (will take up to " 01921 "%d seconds)...\n", phantom, PHN_CMDPEG_INIT_TIMEOUT_SEC ); 01922 for ( retries = 0; retries < PHN_CMDPEG_INIT_TIMEOUT_SEC; retries++ ) { 01923 cmdpeg_state = phantom_readl ( phantom, 01924 UNM_NIC_REG_CMDPEG_STATE ); 01925 if ( cmdpeg_state != last_cmdpeg_state ) { 01926 DBGC ( phantom, "Phantom %p command PEG state is " 01927 "%08x after %d seconds...\n", 01928 phantom, cmdpeg_state, retries ); 01929 last_cmdpeg_state = cmdpeg_state; 01930 } 01931 if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZED ) { 01932 /* Acknowledge the PEG initialisation */ 01933 phantom_writel ( phantom, 01934 UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK, 01935 UNM_NIC_REG_CMDPEG_STATE ); 01936 return 0; 01937 } 01938 mdelay ( 1000 ); 01939 } 01940 01941 DBGC ( phantom, "Phantom %p timed out waiting for command PEG to " 01942 "initialise (status %08x)\n", phantom, cmdpeg_state ); 01943 return -ETIMEDOUT; 01944 }
| static void phantom_get_macaddr | ( | struct phantom_nic * | phantom, | |
| uint8_t * | hw_addr | |||
| ) | [static] |
Read Phantom MAC address.
| phanton_port | Phantom NIC | |
| hw_addr | Buffer to fill with MAC address |
Definition at line 1952 of file phantom.c.
References DBGC, ETH_ALEN, eth_ntoa(), offset, phantom_readl(), phantom_nic::port, and UNM_CAM_RAM_MAC_ADDRS.
Referenced by phantom_probe().
01953 { 01954 union { 01955 uint8_t mac_addr[2][ETH_ALEN]; 01956 uint32_t dwords[3]; 01957 } u; 01958 unsigned long offset; 01959 int i; 01960 01961 /* Read the three dwords that include this MAC address and one other */ 01962 offset = ( UNM_CAM_RAM_MAC_ADDRS + 01963 ( 12 * ( phantom->port / 2 ) ) ); 01964 for ( i = 0 ; i < 3 ; i++, offset += 4 ) { 01965 u.dwords[i] = phantom_readl ( phantom, offset ); 01966 } 01967 01968 /* Copy out the relevant MAC address */ 01969 for ( i = 0 ; i < ETH_ALEN ; i++ ) { 01970 hw_addr[ ETH_ALEN - i - 1 ] = 01971 u.mac_addr[ phantom->port & 1 ][i]; 01972 } 01973 DBGC ( phantom, "Phantom %p MAC address is %s\n", 01974 phantom, eth_ntoa ( hw_addr ) ); 01975 }
| static int phantom_check_boot_enable | ( | struct phantom_nic * | phantom | ) | [static] |
Check Phantom is enabled for boot.
| phanton_port | Phantom NIC |
| rc | Return status code |
Definition at line 1990 of file phantom.c.
References DBGC, ENOTSUP, phantom_readl(), phantom_nic::port, and UNM_CAM_RAM_BOOT_ENABLE.
Referenced by phantom_probe().
01990 { 01991 unsigned long boot_enable; 01992 01993 boot_enable = phantom_readl ( phantom, UNM_CAM_RAM_BOOT_ENABLE ); 01994 if ( ! ( boot_enable & ( 1 << phantom->port ) ) ) { 01995 DBGC ( phantom, "Phantom %p PXE boot is disabled\n", 01996 phantom ); 01997 return -ENOTSUP; 01998 } 01999 02000 return 0; 02001 }
| static int phantom_init_rcvpeg | ( | struct phantom_nic * | phantom | ) | [static] |
Initialise Phantom receive PEG.
| phantom | Phantom NIC |
| rc | Return status code |
Definition at line 2009 of file phantom.c.
References DBGC, ETIMEDOUT, mdelay(), phantom_readl(), PHN_RCVPEG_INIT_TIMEOUT_SEC, UNM_NIC_REG_RCVPEG_STATE, and UNM_NIC_REG_RCVPEG_STATE_INITIALIZED.
Referenced by phantom_probe().
02009 { 02010 unsigned int retries; 02011 uint32_t rcvpeg_state; 02012 uint32_t last_rcvpeg_state = 0; 02013 02014 DBGC ( phantom, "Phantom %p initialising receive PEG (will take up to " 02015 "%d seconds)...\n", phantom, PHN_RCVPEG_INIT_TIMEOUT_SEC ); 02016 for ( retries = 0; retries < PHN_RCVPEG_INIT_TIMEOUT_SEC; retries++ ) { 02017 rcvpeg_state = phantom_readl ( phantom, 02018 UNM_NIC_REG_RCVPEG_STATE ); 02019 if ( rcvpeg_state != last_rcvpeg_state ) { 02020 DBGC ( phantom, "Phantom %p receive PEG state is " 02021 "%08x after %d seconds...\n", 02022 phantom, rcvpeg_state, retries ); 02023 last_rcvpeg_state = rcvpeg_state; 02024 } 02025 if ( rcvpeg_state == UNM_NIC_REG_RCVPEG_STATE_INITIALIZED ) 02026 return 0; 02027 mdelay ( 1000 ); 02028 } 02029 02030 DBGC ( phantom, "Phantom %p timed out waiting for receive PEG to " 02031 "initialise (status %08x)\n", phantom, rcvpeg_state ); 02032 return -ETIMEDOUT; 02033 }
| static int phantom_probe | ( | struct pci_device * | pci, | |
| const struct pci_device_id *id | __unused | |||
| ) | [static] |
Probe PCI device.
| pci | PCI device | |
| id | PCI ID |
| rc | Return status code |
Definition at line 2042 of file phantom.c.
References adjust_pci_device(), alloc_etherdev(), assert, DBGC, pci_device::dev, net_device::dev, pci_device::devfn, ENOMEM, net_device::hw_addr, memset(), netdev, netdev_init(), netdev_nullify(), netdev_priv(), netdev_put(), netdev_settings(), PCI_DEVFN, PCI_FUNC, pci_read_config_dword(), pci_set_drvdata(), PCI_SLOT, pci_write_config_dword(), phantom_check_boot_enable(), phantom_get_macaddr(), phantom_init_cmdpeg(), phantom_init_rcvpeg(), phantom_map_crb(), PHN_CLP_TAG_MAGIC, PHN_MAX_NUM_PORTS, phantom_nic::port, net_device::refcnt, register_netdev(), register_settings(), phantom_nic::settings, settings_init(), strerror(), unregister_netdev(), and unregister_settings().
02043 { 02044 struct net_device *netdev; 02045 struct phantom_nic *phantom; 02046 struct settings *parent_settings; 02047 int rc; 02048 02049 /* Allocate Phantom device */ 02050 netdev = alloc_etherdev ( sizeof ( *phantom ) ); 02051 if ( ! netdev ) { 02052 rc = -ENOMEM; 02053 goto err_alloc_etherdev; 02054 } 02055 netdev_init ( netdev, &phantom_operations ); 02056 phantom = netdev_priv ( netdev ); 02057 pci_set_drvdata ( pci, netdev ); 02058 netdev->dev = &pci->dev; 02059 memset ( phantom, 0, sizeof ( *phantom ) ); 02060 phantom->port = PCI_FUNC ( pci->devfn ); 02061 assert ( phantom->port < PHN_MAX_NUM_PORTS ); 02062 settings_init ( &phantom->settings, 02063 &phantom_settings_operations, 02064 &netdev->refcnt, "clp", PHN_CLP_TAG_MAGIC ); 02065 02066 /* Fix up PCI device */ 02067 adjust_pci_device ( pci ); 02068 02069 /* Map CRB */ 02070 if ( ( rc = phantom_map_crb ( phantom, pci ) ) != 0 ) 02071 goto err_map_crb; 02072 02073 /* BUG5945 - need to hack PCI config space on P3 B1 silicon. 02074 * B2 will have this fixed; remove this hack when B1 is no 02075 * longer in use. 02076 */ 02077 if ( PCI_FUNC ( pci->devfn ) == 0 ) { 02078 unsigned int i; 02079 for ( i = 0 ; i < 8 ; i++ ) { 02080 uint32_t temp; 02081 pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), i ); 02082 pci_read_config_dword ( pci, 0xc8, &temp ); 02083 pci_read_config_dword ( pci, 0xc8, &temp ); 02084 pci_write_config_dword ( pci, 0xc8, 0xf1000 ); 02085 } 02086 pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), 0 ); 02087 } 02088 02089 /* Initialise the command PEG */ 02090 if ( ( rc = phantom_init_cmdpeg ( phantom ) ) != 0 ) 02091 goto err_init_cmdpeg; 02092 02093 /* Initialise the receive PEG */ 02094 if ( ( rc = phantom_init_rcvpeg ( phantom ) ) != 0 ) 02095 goto err_init_rcvpeg; 02096 02097 /* Read MAC addresses */ 02098 phantom_get_macaddr ( phantom, netdev->hw_addr ); 02099 02100 /* Skip if boot disabled on NIC */ 02101 if ( ( rc = phantom_check_boot_enable ( phantom ) ) != 0 ) 02102 goto err_check_boot_enable; 02103 02104 /* Register network devices */ 02105 if ( ( rc = register_netdev ( netdev ) ) != 0 ) { 02106 DBGC ( phantom, "Phantom %p could not register net device: " 02107 "%s\n", phantom, strerror ( rc ) ); 02108 goto err_register_netdev; 02109 } 02110 02111 /* Register settings blocks */ 02112 parent_settings = netdev_settings ( netdev ); 02113 if ( ( rc = register_settings ( &phantom->settings, 02114 parent_settings ) ) != 0 ) { 02115 DBGC ( phantom, "Phantom %p could not register settings: " 02116 "%s\n", phantom, strerror ( rc ) ); 02117 goto err_register_settings; 02118 } 02119 02120 return 0; 02121 02122 unregister_settings ( &phantom->settings ); 02123 err_register_settings: 02124 unregister_netdev ( netdev ); 02125 err_register_netdev: 02126 err_check_boot_enable: 02127 err_init_rcvpeg: 02128 err_init_cmdpeg: 02129 err_map_crb: 02130 netdev_nullify ( netdev ); 02131 netdev_put ( netdev ); 02132 err_alloc_etherdev: 02133 return rc; 02134 }
| static void phantom_remove | ( | struct pci_device * | pci | ) | [static] |
Remove PCI device.
| pci | PCI device |
Definition at line 2141 of file phantom.c.
References netdev, netdev_nullify(), netdev_priv(), netdev_put(), pci_get_drvdata(), phantom_nic::settings, unregister_netdev(), and unregister_settings().
02141 { 02142 struct net_device *netdev = pci_get_drvdata ( pci ); 02143 struct phantom_nic *phantom = netdev_priv ( netdev ); 02144 02145 unregister_settings ( &phantom->settings ); 02146 unregister_netdev ( netdev ); 02147 netdev_nullify ( netdev ); 02148 netdev_put ( netdev ); 02149 }
const unsigned long phantom_irq_mask_reg[PHN_MAX_NUM_PORTS] [static] |
Initial value:
{
UNM_PCIE_IRQ_MASK_F0,
UNM_PCIE_IRQ_MASK_F1,
UNM_PCIE_IRQ_MASK_F2,
UNM_PCIE_IRQ_MASK_F3,
UNM_PCIE_IRQ_MASK_F4,
UNM_PCIE_IRQ_MASK_F5,
UNM_PCIE_IRQ_MASK_F6,
UNM_PCIE_IRQ_MASK_F7,
}
Definition at line 200 of file phantom.c.
Referenced by phantom_irq().
const unsigned long phantom_irq_status_reg[PHN_MAX_NUM_PORTS] [static] |
Initial value:
{
UNM_PCIE_IRQ_STATUS_F0,
UNM_PCIE_IRQ_STATUS_F1,
UNM_PCIE_IRQ_STATUS_F2,
UNM_PCIE_IRQ_STATUS_F3,
UNM_PCIE_IRQ_STATUS_F4,
UNM_PCIE_IRQ_STATUS_F5,
UNM_PCIE_IRQ_STATUS_F6,
UNM_PCIE_IRQ_STATUS_F7,
}
Definition at line 212 of file phantom.c.
Referenced by phantom_poll().
struct net_device_operations phantom_operations [static] |
Initial value:
{
.open = phantom_open,
.close = phantom_close,
.transmit = phantom_transmit,
.poll = phantom_poll,
.irq = phantom_irq,
}
struct phantom_clp_setting clp_settings[] [static] |
struct settings_operations phantom_settings_operations [static] |
Initial value:
{
.store = phantom_store_setting,
.fetch = phantom_fetch_setting,
}
struct pci_device_id phantom_nics[] [static] |
| struct pci_driver phantom_driver __pci_driver |
Initial value:
{
.ids = phantom_nics,
.id_count = ( sizeof ( phantom_nics ) / sizeof ( phantom_nics[0] ) ),
.probe = phantom_probe,
.remove = phantom_remove,
}
1.5.7.1