Skip to content

Commit

Permalink
igc: Add support for PF
Browse files Browse the repository at this point in the history
This patch adds the basic defines and structures needed by the PF for
operation. With this it is possible to bring up the interface,
but without being able to configure any of the filters on
the interface itself.
Add skeleton for a function pointers.

Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Sasha Neftin authored and Jeff Kirsher committed Oct 17, 2018
1 parent d89f884 commit 146740f
Show file tree
Hide file tree
Showing 9 changed files with 442 additions and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/igc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@

obj-$(CONFIG_IGC) += igc.o

igc-objs := igc_main.o
igc-objs := igc_main.o igc_mac.o
13 changes: 13 additions & 0 deletions drivers/net/ethernet/intel/igc/igc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,21 @@
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>

#include "igc_hw.h"

/* main */
extern char igc_driver_name[];
extern char igc_driver_version[];

/* Board specific private data structure */
struct igc_adapter {
u8 __iomem *io_addr;

/* OS defined structs */
struct pci_dev *pdev;

/* structs defined in igc_hw.h */
struct igc_hw hw;
};

#endif /* _IGC_H_ */
30 changes: 30 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_defines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018 Intel Corporation */

#ifndef _IGC_DEFINES_H_
#define _IGC_DEFINES_H_

/* PCI Bus Info */
#define PCIE_DEVICE_CONTROL2 0x28
#define PCIE_DEVICE_CONTROL2_16ms 0x0005

/* Error Codes */
#define IGC_SUCCESS 0
#define IGC_ERR_NVM 1
#define IGC_ERR_PHY 2
#define IGC_ERR_CONFIG 3
#define IGC_ERR_PARAM 4
#define IGC_ERR_MAC_INIT 5
#define IGC_ERR_RESET 9

/* Device Status */
#define IGC_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
#define IGC_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
#define IGC_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
#define IGC_STATUS_FUNC_SHIFT 2
#define IGC_STATUS_FUNC_1 0x00000004 /* Function 1 */
#define IGC_STATUS_TXOFF 0x00000010 /* transmission paused */
#define IGC_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define IGC_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */

#endif /* _IGC_DEFINES_H_ */
82 changes: 82 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,89 @@
#ifndef _IGC_HW_H_
#define _IGC_HW_H_

#include <linux/types.h>
#include <linux/if_ether.h>
#include "igc_regs.h"
#include "igc_defines.h"
#include "igc_mac.h"
#include "igc_i225.h"

#define IGC_DEV_ID_I225_LM 0x15F2
#define IGC_DEV_ID_I225_V 0x15F3

/* Function pointers for the MAC. */
struct igc_mac_operations {
};

enum igc_mac_type {
igc_undefined = 0,
igc_i225,
igc_num_macs /* List is 1-based, so subtract 1 for true count. */
};

enum igc_phy_type {
igc_phy_unknown = 0,
igc_phy_none,
igc_phy_i225,
};

struct igc_mac_info {
struct igc_mac_operations ops;

u8 addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN];

enum igc_mac_type type;

u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 tx_packet_delta;
u32 txcw;

u16 mta_reg_count;
u16 uta_reg_count;

u16 rar_entry_count;

u8 forced_speed_duplex;

bool adaptive_ifs;
bool has_fwsm;
bool arc_subsystem_valid;

bool autoneg;
bool autoneg_failed;
};

struct igc_bus_info {
u16 func;
u16 pci_cmd_word;
};

struct igc_hw {
void *back;

u8 __iomem *hw_addr;
unsigned long io_base;

struct igc_mac_info mac;

struct igc_bus_info bus;

u16 device_id;
u16 subsystem_vendor_id;
u16 subsystem_device_id;
u16 vendor_id;

u8 revision_id;
};

s32 igc_read_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value);
s32 igc_write_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value);
void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value);
void igc_write_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value);

#endif /* _IGC_HW_H_ */
10 changes: 10 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_i225.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018 Intel Corporation */

#ifndef _IGC_I225_H_
#define _IGC_I225_H_

s32 igc_acquire_swfw_sync_i225(struct igc_hw *hw, u16 mask);
void igc_release_swfw_sync_i225(struct igc_hw *hw, u16 mask);

#endif
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_mac.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018 Intel Corporation */

#include <linux/pci.h>
#include "igc_hw.h"
11 changes: 11 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_mac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018 Intel Corporation */

#ifndef _IGC_MAC_H_
#define _IGC_MAC_H_

#ifndef IGC_REMOVED
#define IGC_REMOVED(a) (0)
#endif /* IGC_REMOVED */

#endif
98 changes: 98 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,69 @@ static const struct pci_device_id igc_pci_tbl[] = {

MODULE_DEVICE_TABLE(pci, igc_pci_tbl);

/* forward declaration */
static int igc_sw_init(struct igc_adapter *);

/* PCIe configuration access */
void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value)
{
struct igc_adapter *adapter = hw->back;

pci_read_config_word(adapter->pdev, reg, value);
}

void igc_write_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value)
{
struct igc_adapter *adapter = hw->back;

pci_write_config_word(adapter->pdev, reg, *value);
}

s32 igc_read_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value)
{
struct igc_adapter *adapter = hw->back;
u16 cap_offset;

cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
if (!cap_offset)
return -IGC_ERR_CONFIG;

pci_read_config_word(adapter->pdev, cap_offset + reg, value);

return IGC_SUCCESS;
}

s32 igc_write_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value)
{
struct igc_adapter *adapter = hw->back;
u16 cap_offset;

cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
if (!cap_offset)
return -IGC_ERR_CONFIG;

pci_write_config_word(adapter->pdev, cap_offset + reg, *value);

return IGC_SUCCESS;
}

u32 igc_rd32(struct igc_hw *hw, u32 reg)
{
u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr);
u32 value = 0;

if (IGC_REMOVED(hw_addr))
return ~value;

value = readl(&hw_addr[reg]);

/* reads should not return all F's */
if (!(~value) && (!reg || !(~readl(hw_addr))))
hw->hw_addr = NULL;

return value;
}

/**
* igc_probe - Device Initialization Routine
* @pdev: PCI device information struct
Expand All @@ -44,6 +107,7 @@ MODULE_DEVICE_TABLE(pci, igc_pci_tbl);
static int igc_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct igc_adapter *adapter;
int err, pci_using_dac;

err = pci_enable_device_mem(pdev);
Expand Down Expand Up @@ -78,8 +142,15 @@ static int igc_probe(struct pci_dev *pdev,

pci_set_master(pdev);
err = pci_save_state(pdev);

/* setup the private structure */
err = igc_sw_init(adapter);
if (err)
goto err_sw_init;

return 0;

err_sw_init:
err_pci_reg:
err_dma:
pci_disable_device(pdev);
Expand Down Expand Up @@ -110,6 +181,33 @@ static struct pci_driver igc_driver = {
.remove = igc_remove,
};

/**
* igc_sw_init - Initialize general software structures (struct igc_adapter)
* @adapter: board private structure to initialize
*
* igc_sw_init initializes the Adapter private data structure.
* Fields are initialized based on PCI device information and
* OS network device settings (MTU size).
*/
static int igc_sw_init(struct igc_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct igc_hw *hw = &adapter->hw;

/* PCI config space info */

hw->vendor_id = pdev->vendor;
hw->device_id = pdev->device;
hw->subsystem_vendor_id = pdev->subsystem_vendor;
hw->subsystem_device_id = pdev->subsystem_device;

pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);

pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);

return 0;
}

/**
* igc_init_module - Driver Registration Routine
*
Expand Down
Loading

0 comments on commit 146740f

Please sign in to comment.