]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.xen/sfc-external-sram
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.xen / sfc-external-sram
diff --git a/src/patches/suse-2.6.27.31/patches.xen/sfc-external-sram b/src/patches/suse-2.6.27.31/patches.xen/sfc-external-sram
new file mode 100644 (file)
index 0000000..6baf31d
--- /dev/null
@@ -0,0 +1,302 @@
+From: Kieran Mansley <kmansley@solarflare.com>
+Subject: enable access to Falcon's external SRAM
+References: bnc#489105
+
+Include ability to reference external SRAM on Solarflare Falcon NICs to
+allow event queues to be accessed by virtualised guests.  
+
+Acked-by: bphilips@novell.com
+
+--- sle11-2009-04-09.orig/drivers/net/sfc/falcon.c     2009-03-30 15:58:20.000000000 +0200
++++ sle11-2009-04-09/drivers/net/sfc/falcon.c  2009-03-30 15:58:59.000000000 +0200
+@@ -36,12 +36,18 @@
+ /**
+  * struct falcon_nic_data - Falcon NIC state
++ * @sram_cfg: SRAM configuration value
++ * @tx_dc_base: Base address in SRAM of TX queue descriptor caches
++ * @rx_dc_base: Base address in SRAM of RX queue descriptor caches
+  * @next_buffer_table: First available buffer table id
+  * @resources: Resource information for driverlink client
+  * @pci_dev2: The secondary PCI device if present
+  * @i2c_data: Operations and state for I2C bit-bashing algorithm
+  */
+ struct falcon_nic_data {
++      int sram_cfg;
++      unsigned tx_dc_base;
++      unsigned rx_dc_base;
+ #ifndef CONFIG_SFC_DRIVERLINK
+       unsigned next_buffer_table;
+ #else
+@@ -69,11 +75,11 @@ static int disable_dma_stats;
+  */
+ #define TX_DC_ENTRIES 16
+ #define TX_DC_ENTRIES_ORDER 0
+-#define TX_DC_BASE 0x130000
++#define TX_DC_INTERNAL_BASE 0x130000
+ #define RX_DC_ENTRIES 64
+ #define RX_DC_ENTRIES_ORDER 2
+-#define RX_DC_BASE 0x100000
++#define RX_DC_INTERNAL_BASE 0x100000
+ /* RX FIFO XOFF watermark
+  *
+@@ -454,9 +460,17 @@ void falcon_push_buffers(struct efx_tx_q
+ int falcon_probe_tx(struct efx_tx_queue *tx_queue)
+ {
+       struct efx_nic *efx = tx_queue->efx;
+-      return falcon_alloc_special_buffer(efx, &tx_queue->txd,
+-                                         FALCON_TXD_RING_SIZE *
+-                                         sizeof(efx_qword_t));
++      int rc = falcon_alloc_special_buffer(efx, &tx_queue->txd,
++                                          FALCON_TXD_RING_SIZE *
++                                          sizeof(efx_qword_t));
++#ifdef CONFIG_SFC_DRIVERLINK
++      if (rc == 0) {
++              struct falcon_nic_data *nic_data = efx->nic_data;
++              nic_data->resources.txq_min = max(nic_data->resources.txq_min,
++                                                (unsigned)tx_queue->queue + 1);
++      }
++#endif
++      return rc;
+ }
+ int falcon_init_tx(struct efx_tx_queue *tx_queue)
+@@ -643,9 +657,17 @@ void falcon_notify_rx_desc(struct efx_rx
+ int falcon_probe_rx(struct efx_rx_queue *rx_queue)
+ {
+       struct efx_nic *efx = rx_queue->efx;
+-      return falcon_alloc_special_buffer(efx, &rx_queue->rxd,
+-                                         FALCON_RXD_RING_SIZE *
+-                                         sizeof(efx_qword_t));
++      int rc = falcon_alloc_special_buffer(efx, &rx_queue->rxd,
++                                          FALCON_RXD_RING_SIZE *
++                                          sizeof(efx_qword_t));
++#ifdef CONFIG_SFC_DRIVERLINK
++      if (rc == 0) {
++              struct falcon_nic_data *nic_data = efx->nic_data;
++              nic_data->resources.rxq_min = max(nic_data->resources.rxq_min,
++                                                (unsigned)rx_queue->queue + 1);
++      }
++#endif
++      return rc;
+ }
+ int falcon_init_rx(struct efx_rx_queue *rx_queue)
+@@ -1276,9 +1298,18 @@ int falcon_probe_eventq(struct efx_chann
+ {
+       struct efx_nic *efx = channel->efx;
+       unsigned int evq_size;
++      int rc;
+       evq_size = FALCON_EVQ_SIZE * sizeof(efx_qword_t);
+-      return falcon_alloc_special_buffer(efx, &channel->eventq, evq_size);
++      rc = falcon_alloc_special_buffer(efx, &channel->eventq, evq_size);
++#ifdef CONFIG_SFC_DRIVERLINK
++      if (rc == 0) {
++              struct falcon_nic_data *nic_data = efx->nic_data;
++              nic_data->resources.evq_int_min = max(nic_data->resources.evq_int_min,
++                                                    (unsigned)channel->evqnum + 1);
++      }
++#endif
++      return rc;
+ }
+ int falcon_init_eventq(struct efx_channel *channel)
+@@ -2285,19 +2316,22 @@ fail5:
+  */
+ static int falcon_reset_sram(struct efx_nic *efx)
+ {
++      struct falcon_nic_data *nic_data = efx->nic_data;
+       efx_oword_t srm_cfg_reg_ker, gpio_cfg_reg_ker;
+-      int count;
++      int count, onchip, sram_cfg_val;
+       /* Set the SRAM wake/sleep GPIO appropriately. */
++      onchip = (nic_data->sram_cfg == SRM_NB_BSZ_ONCHIP_ONLY);
+       falcon_read(efx, &gpio_cfg_reg_ker, GPIO_CTL_REG_KER);
+       EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OEN, 1);
+-      EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OUT, 1);
++      EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OUT, onchip);
+       falcon_write(efx, &gpio_cfg_reg_ker, GPIO_CTL_REG_KER);
+       /* Initiate SRAM reset */
++      sram_cfg_val = onchip ? 0 : nic_data->sram_cfg;
+       EFX_POPULATE_OWORD_2(srm_cfg_reg_ker,
+                            SRAM_OOB_BT_INIT_EN, 1,
+-                           SRM_NUM_BANKS_AND_BANK_SIZE, 0);
++                           SRM_NUM_BANKS_AND_BANK_SIZE, sram_cfg_val);
+       falcon_write(efx, &srm_cfg_reg_ker, SRM_CFG_REG_KER);
+       /* Wait for SRAM reset to complete */
+@@ -2324,12 +2358,14 @@ static int falcon_reset_sram(struct efx_
+ /* Extract non-volatile configuration */
+ static int falcon_probe_nvconfig(struct efx_nic *efx)
+ {
++      struct falcon_nic_data *nic_data = efx->nic_data;
+       struct falcon_nvconfig *nvconfig;
+       efx_oword_t nic_stat;
+       int device_id;
+       unsigned addr_len;
+       size_t offset, len;
+       int magic_num, struct_ver, board_rev;
++      bool onchip_sram;
+       int rc;
+       /* Find the boot device. */
+@@ -2370,18 +2406,41 @@ static int falcon_probe_nvconfig(struct 
+               efx->phy_type = PHY_TYPE_NONE;
+               efx->mii.phy_id = PHY_ADDR_INVALID;
+               board_rev = 0;
++              onchip_sram = true;
+       } else {
+               struct falcon_nvconfig_board_v2 *v2 = &nvconfig->board_v2;
+               efx->phy_type = v2->port0_phy_type;
+               efx->mii.phy_id = v2->port0_phy_addr;
+               board_rev = le16_to_cpu(v2->board_revision);
++#ifdef CONFIG_SFC_DRIVERLINK
++              onchip_sram = EFX_OWORD_FIELD(nvconfig->nic_stat_reg,
++                                            ONCHIP_SRAM);
++#else
++              /* We have no use for external SRAM */
++              onchip_sram = true;
++#endif
+       }
+       EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id);
+       efx_set_board_info(efx, board_rev);
++      /* Read the SRAM configuration.  The register is initialised
++       * automatically but might may been reset since boot.
++       */
++      if (onchip_sram) {
++              nic_data->sram_cfg = SRM_NB_BSZ_ONCHIP_ONLY;
++      } else {
++              nic_data->sram_cfg =
++                      EFX_OWORD_FIELD(nvconfig->srm_cfg_reg,
++                                      SRM_NUM_BANKS_AND_BANK_SIZE);
++              WARN_ON(nic_data->sram_cfg == SRM_NB_BSZ_RESERVED);
++              /* Replace invalid setting with the smallest defaults */
++              if (nic_data->sram_cfg == SRM_NB_BSZ_DEFAULT)
++                      nic_data->sram_cfg = SRM_NB_BSZ_1BANKS_2M;
++      }
++
+  out:
+       kfree(nvconfig);
+       return rc;
+@@ -2392,9 +2451,9 @@ static int falcon_probe_nvconfig(struct 
+  * should live. */
+ static int falcon_dimension_resources(struct efx_nic *efx)
+ {
++      struct falcon_nic_data *nic_data = efx->nic_data;
+ #ifdef CONFIG_SFC_DRIVERLINK
+       unsigned internal_dcs_entries;
+-      struct falcon_nic_data *nic_data = efx->nic_data;
+       struct efx_dl_falcon_resources *res = &nic_data->resources;
+       /* Fill out the driverlink resource list */
+@@ -2427,16 +2486,64 @@ static int falcon_dimension_resources(st
+               break;
+       }
+-      /* Internal SRAM only for now */
+-      res->rxq_lim = internal_dcs_entries / RX_DC_ENTRIES;
+-      res->txq_lim = internal_dcs_entries / TX_DC_ENTRIES;
+-      res->buffer_table_lim = 8192;
++      if (nic_data->sram_cfg == SRM_NB_BSZ_ONCHIP_ONLY) {
++              res->rxq_lim = internal_dcs_entries / RX_DC_ENTRIES;
++              res->txq_lim = internal_dcs_entries / TX_DC_ENTRIES;
++              res->buffer_table_lim = 8192;
++              nic_data->tx_dc_base = TX_DC_INTERNAL_BASE;
++              nic_data->rx_dc_base = RX_DC_INTERNAL_BASE;
++      } else {
++              unsigned sram_bytes, vnic_bytes, max_vnics, n_vnics, dcs;
++
++              /* Determine how much SRAM we have to play with.  We have
++               * to fit buffer table and descriptor caches in.
++               */
++              switch (nic_data->sram_cfg) {
++              case SRM_NB_BSZ_1BANKS_2M:
++              default:
++                      sram_bytes = 2 * 1024 * 1024;
++                      break;
++              case SRM_NB_BSZ_1BANKS_4M:
++              case SRM_NB_BSZ_2BANKS_4M:
++                      sram_bytes = 4 * 1024 * 1024;
++                      break;
++              case SRM_NB_BSZ_1BANKS_8M:
++              case SRM_NB_BSZ_2BANKS_8M:
++                      sram_bytes = 8 * 1024 * 1024;
++                      break;
++              case SRM_NB_BSZ_2BANKS_16M:
++                      sram_bytes = 16 * 1024 * 1024;
++                      break;
++              }
++              /* For each VNIC allow at least 512 buffer table entries
++               * and descriptor cache for an rxq and txq.  Buffer table
++               * space for evqs and dmaqs is relatively trivial, so not
++               * considered in this calculation.
++               */
++              vnic_bytes = 512 * 8 + RX_DC_ENTRIES * 8 + TX_DC_ENTRIES * 8;
++              max_vnics = sram_bytes / vnic_bytes;
++              for (n_vnics = 1; n_vnics < res->evq_timer_min + max_vnics;)
++                      n_vnics *= 2;
++              res->rxq_lim = n_vnics;
++              res->txq_lim = n_vnics;
++
++              dcs = n_vnics * TX_DC_ENTRIES * 8;
++              nic_data->tx_dc_base = sram_bytes - dcs;
++              dcs = n_vnics * RX_DC_ENTRIES * 8;
++              nic_data->rx_dc_base = nic_data->tx_dc_base - dcs;
++              res->buffer_table_lim = nic_data->rx_dc_base / 8;
++      }
+       if (FALCON_IS_DUAL_FUNC(efx))
+               res->flags |= EFX_DL_FALCON_DUAL_FUNC;
+       if (EFX_INT_MODE_USE_MSI(efx))
+               res->flags |= EFX_DL_FALCON_USE_MSI;
++#else
++      /* We ignore external SRAM */
++      EFX_BUG_ON_PARANOID(nic_data->sram_cfg != SRM_NB_BSZ_ONCHIP_ONLY);
++      nic_data->tx_dc_base = TX_DC_INTERNAL_BASE;
++      nic_data->rx_dc_base = RX_DC_INTERNAL_BASE;
+ #endif
+       return 0;
+@@ -2586,6 +2693,7 @@ int falcon_probe_nic(struct efx_nic *efx
+  */
+ int falcon_init_nic(struct efx_nic *efx)
+ {
++      struct falcon_nic_data *nic_data = efx->nic_data;
+       efx_oword_t temp;
+       unsigned thresh;
+       int rc;
+@@ -2599,9 +2707,10 @@ int falcon_init_nic(struct efx_nic *efx)
+                                  ADR_REGION3, (3 << 16));
+       falcon_write(efx, &temp, ADR_REGION_REG_KER);
+-      /* Use on-chip SRAM */
++      /* Use on-chip SRAM if wanted. */
+       falcon_read(efx, &temp, NIC_STAT_REG);
+-      EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1);
++      EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM,
++                          nic_data->sram_cfg == SRM_NB_BSZ_ONCHIP_ONLY);
+       falcon_write(efx, &temp, NIC_STAT_REG);
+       /* Set buffer table mode */
+@@ -2613,9 +2722,9 @@ int falcon_init_nic(struct efx_nic *efx)
+               return rc;
+       /* Set positions of descriptor caches in SRAM. */
+-      EFX_POPULATE_OWORD_1(temp, SRM_TX_DC_BASE_ADR, TX_DC_BASE / 8);
++      EFX_POPULATE_OWORD_1(temp, SRM_TX_DC_BASE_ADR, nic_data->tx_dc_base / 8);
+       falcon_write(efx, &temp, SRM_TX_DC_CFG_REG_KER);
+-      EFX_POPULATE_OWORD_1(temp, SRM_RX_DC_BASE_ADR, RX_DC_BASE / 8);
++      EFX_POPULATE_OWORD_1(temp, SRM_RX_DC_BASE_ADR, nic_data->rx_dc_base / 8);
+       falcon_write(efx, &temp, SRM_RX_DC_CFG_REG_KER);
+       /* Set TX descriptor cache size. */